Rigs of Rods 2023.09
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
ContentManager.cpp
Go to the documentation of this file.
1/*
2 This source file is part of Rigs of Rods
3 Copyright 2005-2012 Pierre-Michel Ricordel
4 Copyright 2007-2012 Thomas Fischer
5 Copyright 2013-2018 Petr Ohlidal
6
7 For more information, see http://www.rigsofrods.org/
8
9 Rigs of Rods is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 3, as
11 published by the Free Software Foundation.
12
13 Rigs of Rods is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "ContentManager.h"
23
24
25#include <Overlay/OgreOverlayManager.h>
26#include <Overlay/OgreOverlay.h>
27#include <Plugins/ParticleFX/OgreBoxEmitterFactory.h>
28
29
30#include "Application.h"
32#include "ErrorUtils.h"
33#include "SoundScriptManager.h"
34#include "SkinFileFormat.h"
35#include "Language.h"
36#include "PlatformUtils.h"
37
38#include "CacheSystem.h"
39
41
42// Removed by Skybon as part of OGRE 1.9 port
43// Disabling temporarily for 1.8.1 as well. ~ only_a_ptr, 2015-11
44// TODO: Study the system, then re-enable or remove entirely.
45//#include "OgreBoxEmitterFactory.h"
46
47#ifdef USE_ANGELSCRIPT
50#endif // USE_ANGELSCRIPT
51
52#include "Utils.h"
53
54#include <OgreFileSystem.h>
55#include <regex>
56#include <rapidjson/stringbuffer.h>
57#include <rapidjson/writer.h>
58#include <sstream>
59#include <OgreMeshLodGenerator.h>
60
61using namespace Ogre;
62using namespace RoR;
63
64// ================================================================================
65// Static variables
66// ================================================================================
67
68#define DECLARE_RESOURCE_PACK(_FIELD_, _NAME_, _RESOURCE_GROUP_) \
69 const ContentManager::ResourcePack ContentManager::ResourcePack::_FIELD_(_NAME_, _RESOURCE_GROUP_);
70
71DECLARE_RESOURCE_PACK( OGRE_CORE, "OgreCore", "OgreCoreRG");
72DECLARE_RESOURCE_PACK( WALLPAPERS, "wallpapers", "Wallpapers");
73DECLARE_RESOURCE_PACK( AIRFOILS, "airfoils", "AirfoilsRG");
74DECLARE_RESOURCE_PACK( CAELUM, "caelum", "CaelumRG");
75DECLARE_RESOURCE_PACK( CUBEMAPS, "cubemaps", "CubemapsRG");
76DECLARE_RESOURCE_PACK( DASHBOARDS, "dashboards", "DashboardsRG");
77DECLARE_RESOURCE_PACK( FAMICONS, "famicons", "FamiconsRG");
78DECLARE_RESOURCE_PACK( FLAGS, "flags", "FlagsRG");
79DECLARE_RESOURCE_PACK( FONTS, "fonts", "FontsRG");
80DECLARE_RESOURCE_PACK( HYDRAX, "hydrax", "HydraxRG");
81DECLARE_RESOURCE_PACK( ICONS, "icons", "IconsRG");
82DECLARE_RESOURCE_PACK( MATERIALS, "materials", "MaterialsRG");
83DECLARE_RESOURCE_PACK( MESHES, "meshes", "MeshesRG");
84DECLARE_RESOURCE_PACK( MYGUI, "mygui", "MyGuiRG");
85DECLARE_RESOURCE_PACK( OVERLAYS, "overlays", "OverlaysRG");
86DECLARE_RESOURCE_PACK( PAGED, "paged", "PagedRG");
87DECLARE_RESOURCE_PACK( PARTICLES, "particles", "ParticlesRG");
88DECLARE_RESOURCE_PACK( PSSM, "pssm", "PssmRG");
89DECLARE_RESOURCE_PACK( RTSHADER, "rtshader", "RtShaderRG");
90DECLARE_RESOURCE_PACK( SCRIPTS, "scripts", "ScriptsRG");
91DECLARE_RESOURCE_PACK( SOUNDS, "sounds", "SoundsRG");
92DECLARE_RESOURCE_PACK( TEXTURES, "textures", "TexturesRG");
93DECLARE_RESOURCE_PACK( SKYX, "SkyX", "SkyXRG");
94
95// ================================================================================
96// Functions
97// ================================================================================
98
99void ContentManager::AddResourcePack(ResourcePack const& resource_pack, std::string const& override_rgn)
100{
101 Ogre::ResourceGroupManager& rgm = Ogre::ResourceGroupManager::getSingleton();
102
103 Ogre::String rg_name;
104 if (!override_rgn.empty()) // Custom RG defined?
105 {
106 rg_name = override_rgn;
107 }
108 else // Use default RG
109 {
110 if (rgm.resourceGroupExists(resource_pack.resource_group_name)) // Already loaded?
111 {
112 return; // Nothing to do, nothing to report
113 }
114 rg_name = resource_pack.resource_group_name;
115 }
116
117 std::stringstream log_msg;
118 log_msg << "[RoR|ContentManager] Loading resource pack \"" << resource_pack.name << "\" to group \"" << rg_name << "\"";
119 std::string dir_path = PathCombine(App::sys_resources_dir->getStr(), resource_pack.name);
120 std::string zip_path = dir_path + ".zip";
121 if (FileExists(zip_path))
122 {
123 log_msg << " (ZIP archive)";
124 LOG(log_msg.str());
125 rgm.addResourceLocation(zip_path, "Zip", rg_name);
126 }
127 else
128 {
129 if (FolderExists(dir_path))
130 {
131 log_msg << " (directory)";
132 LOG(log_msg.str());
133 rgm.addResourceLocation(dir_path, "FileSystem", rg_name);
134 }
135 else
136 {
137 log_msg << " failed, data not found.";
138 throw std::runtime_error(log_msg.str());
139 }
140 }
141
142 if (override_rgn.empty()) // Only init the default RG
143 {
144 rgm.initialiseResourceGroup(rg_name);
145 }
146}
147
149{
150 ResourceGroupManager::getSingleton().addResourceLocation(
151 App::sys_config_dir->getStr(), "FileSystem", RGN_CONFIG, /*recursive=*/false, /*readOnly=*/false);
152 ResourceGroupManager::getSingleton().addResourceLocation(
153 App::sys_savegames_dir->getStr(), "FileSystem", RGN_SAVEGAMES, /*recursive=*/false, /*readOnly=*/false);
154 ResourceGroupManager::getSingleton().addResourceLocation(
155 App::sys_scripts_dir->getStr(), "FileSystem", RGN_SCRIPTS, /*recursive:*/false, /*readonly:*/false);
156 ResourceGroupManager::getSingleton().addResourceLocation(
157 App::sys_logs_dir->getStr(), "FileSystem", RGN_LOGS, /*recursive:*/false, /*readonly:*/false);
158
159 Ogre::ScriptCompilerManager::getSingleton().setListener(this);
160
161 // Initialize "managed materials" first
162 // These are base materials referenced by user content
163 // They must be initialized before any content is loaded,
164 // otherwise material links are unresolved and loading ends with an exception
166
167 // set listener if none has already been set
168 if (!Ogre::ResourceGroupManager::getSingleton().getLoadingListener())
169 Ogre::ResourceGroupManager::getSingleton().setLoadingListener(this);
170
171 // by default, display everything in the depth map
172 Ogre::MovableObject::setDefaultVisibilityFlags(DEPTHMAP_ENABLED);
173
174
177
178
179#ifdef _WIN32
180 // TODO: FIX UNDER LINUX!
181 // register particle classes
182 LOG("RoR|ContentManager: Registering Particle Box Emitter");
183 ParticleSystemRendererFactory* mParticleSystemRendererFact = OGRE_NEW ShaderParticleRendererFactory();
184 ParticleSystemManager::getSingleton().addRendererFactory(mParticleSystemRendererFact);
185
186 // Removed by Skybon as part of OGRE 1.9 port
187 // Disabling temporarily for 1.8.1 as well. ~ only_a_ptr, 2015-11
188 //ParticleEmitterFactory *mParticleEmitterFact = OGRE_NEW BoxEmitterFactory();
189 //ParticleSystemManager::getSingleton().addEmitterFactory(mParticleEmitterFact);
190
191#endif // _WIN32
192
193#ifdef USE_ANGELSCRIPT
194 // FireExtinguisherAffector
195 ParticleAffectorFactory* pAffFact = OGRE_NEW FireExtinguisherAffectorFactory();
196 ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact);
197
198 // ExtinguishableFireAffector
199 pAffFact = OGRE_NEW ExtinguishableFireAffectorFactory();
200 ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact);
201#endif // USE_ANGELSCRIPT
202
203 // sound is a bit special as we mark the base sounds so we don't clear them accidentally later on
204#ifdef USE_OPENAL
205 LOG("RoR|ContentManager: Creating Sound Manager");
208#endif // USE_OPENAL
209
211
212 // streams path, to be processed later by the cache system
213 LOG("RoR|ContentManager: Loading filesystems");
214
215 LOG("RoR|ContentManager: Registering colored text overlay factory");
217 OverlayManager::getSingleton().addOverlayElementFactory(pCT);
218
219 // set default mipmap level (NB some APIs ignore this)
220 if (TextureManager::getSingletonPtr())
221 TextureManager::getSingleton().setDefaultNumMipmaps(5);
222
223 TextureFilterOptions tfo = TFO_NONE;
224 switch (App::gfx_texture_filter->getEnum<GfxTexFilter>())
225 {
226 case GfxTexFilter::ANISOTROPIC: tfo = TFO_ANISOTROPIC; break;
227 case GfxTexFilter::TRILINEAR: tfo = TFO_TRILINEAR; break;
228 case GfxTexFilter::BILINEAR: tfo = TFO_BILINEAR; break;
229 case GfxTexFilter::NONE: tfo = TFO_NONE; break;
230 }
231 MaterialManager::getSingleton().setDefaultAnisotropy(Math::Clamp(App::gfx_anisotropy->getInt(), 1, 16));
232 MaterialManager::getSingleton().setDefaultTextureFiltering(tfo);
233
234 // load all resources now, so the zip files are also initiated
235 LOG("RoR|ContentManager: Calling initialiseAllResourceGroups()");
236 try
237 {
238 ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
239 }
240 catch (Ogre::Exception& e)
241 {
242 LOG("RoR|ContentManager: catched error while initializing Resource groups: " + e.getFullDescription());
243 }
244#ifdef USE_OPENAL
246#endif // USE_OPENAL
247
248 new Ogre::MeshLodGenerator();
249}
250
252{
253 // Sets up RGN_CONTENT which encompasses all mods, scans it for changes and deletes it again.
254 // IMPORTANT NOTE ON 'readOnly' FLAG:
255 // We need mods in subdirs to be writable for the Tuning menu to work.
256 // Apart from `Resources` and resource groups, OGRE also keeps `Archives` in `ArchiveManager`
257 // These aren't unloaded on destroying resource groups, and keep a 'readOnly' flag (defaults to true).
258 // Upon loading/creating new resource groups, OGRE complains (=assert on Debug, exception on Release) if the submitted flag doesn't match.
259 // It's possible to manually unload archives to reset the flag, but for simplicity we just always load subdirs as 'writable', even during modcache update.
260 // ------------------------------------------------------------------------------------------
261
262 ResourceGroupManager::getSingleton().addResourceLocation(
263 App::sys_cache_dir->getStr(), "FileSystem", RGN_CACHE, /*recursive=*/false, /*readOnly=*/false);
264 ResourceGroupManager::getSingleton().addResourceLocation(
265 App::sys_thumbnails_dir->getStr(), "FileSystem", RGN_THUMBNAILS, /*recursive=*/false, /*readOnly=*/false);
266 ResourceGroupManager::getSingleton().addResourceLocation(
267 App::sys_repo_attachments_dir->getStr(), "FileSystem", RGN_REPO_ATTACHMENTS, /*recursive=*/false, /*readOnly=*/false);
268
269 // Add top-level ZIPs/directories to RGN_CONTENT (non-recursive)
270
271 if (!App::app_extra_mod_path->getStr().empty())
272 {
273 std::string extra_mod_path = App::app_extra_mod_path->getStr();
274 ResourceGroupManager::getSingleton().addResourceLocation(extra_mod_path , "FileSystem", RGN_CONTENT);
275 }
276 for (const std::string& dirname : App::GetCacheSystem()->GetContentDirs())
277 {
278 ResourceGroupManager::getSingleton().addResourceLocation(PathCombine(App::sys_user_dir->getStr(), dirname), "FileSystem", RGN_CONTENT);
279 }
280 ResourceGroupManager::getSingleton().addResourceLocation(PathCombine(App::sys_process_dir->getStr(), "content") , "FileSystem", RGN_CONTENT);
281 std::string objects = PathCombine("resources", "beamobjects.zip");
282 ResourceGroupManager::getSingleton().addResourceLocation(PathCombine(App::sys_process_dir->getStr(), objects) , "Zip" , RGN_CONTENT);
283 std::string dashboards = PathCombine("resources", "dashboards.zip");
284 ResourceGroupManager::getSingleton().addResourceLocation(PathCombine(App::sys_process_dir->getStr(), dashboards), "Zip", RGN_CONTENT);
285 std::string gadgets = PathCombine("resources", "gadgets.zip");
286 ResourceGroupManager::getSingleton().addResourceLocation(PathCombine(App::sys_process_dir->getStr(), gadgets), "Zip", RGN_CONTENT);
287
288 // Create RGN_TEMP in recursive mode to find all subdirectories.
289
290 ResourceGroupManager::getSingleton().createResourceGroup(RGN_TEMP, false);
291 if (!App::app_extra_mod_path->getStr().empty())
292 {
293 std::string extra_mod_path = App::app_extra_mod_path->getStr();
294 ResourceGroupManager::getSingleton().addResourceLocation(extra_mod_path , "FileSystem", RGN_TEMP, true);
295 }
296 for (const std::string& dirname : App::GetCacheSystem()->GetContentDirs())
297 {
298 ResourceGroupManager::getSingleton().addResourceLocation(PathCombine(App::sys_user_dir->getStr(), dirname), "FileSystem", RGN_TEMP, true);
299 }
300 ResourceGroupManager::getSingleton().addResourceLocation(PathCombine(App::sys_process_dir->getStr(), "content") , "FileSystem", RGN_TEMP, true);
301
302 // Traverse RGN_TEMP and add all subdirectories to RGN_CONTENT.
303 // (TBD: why not just make RGN_CONTENT itself recursive? -- ohlidalp, 10/2023)
304
305 FileInfoListPtr dirs = ResourceGroupManager::getSingleton().findResourceFileInfo(RGN_TEMP, "*", /*dirs:*/true);
306 for (const auto& dir_fileinfo : *dirs)
307 {
308 if (!dir_fileinfo.archive)
309 continue;
310 String fullpath = PathCombine(dir_fileinfo.archive->getName(), dir_fileinfo.filename);
311 ResourceGroupManager::getSingleton().addResourceLocation(fullpath, "FileSystem", RGN_CONTENT, /*recursive:*/false, /*readonly:*/false);
312 }
313 ResourceGroupManager::getSingleton().destroyResourceGroup(RGN_TEMP);
314
315 // Traverse RGN_CONTENT and detect updates
316
317 if (validity == CacheValidity::UNKNOWN)
318 {
319 validity = App::GetCacheSystem()->EvaluateCacheValidity(); // Must be called while RGN_CONTENT is alive.
320 }
322
323 ResourceGroupManager::getSingleton().destroyResourceGroup(RGN_CONTENT);
324
325}
326
327Ogre::DataStreamPtr ContentManager::resourceLoading(const Ogre::String& name, const Ogre::String& group, Ogre::Resource* resource)
328{
329 return Ogre::DataStreamPtr();
330}
331
332void ContentManager::resourceStreamOpened(const Ogre::String& name, const Ogre::String& group, Ogre::Resource* resource, Ogre::DataStreamPtr& dataStream)
333{
334}
335
336bool ContentManager::resourceCollision(Ogre::Resource* resource, Ogre::ResourceManager* resourceManager)
337{
338 // RoR loads each resource bundle (see CacheSystem.h for info)
339 // into dedicated resource group outside the global pool [see CacheSystem::LoadResource()]
340 // This means resource collision is pretty much content creator's fault, with 2 exceptions:
341 // * asset packs (introduced 2024) are mixed into the requesting mod's resource group.
342 // * bundled resources (e.g. beamobjects.zip) are also mixed into the mod's resource group.
343 RoR::LogFormat("[RoR|ContentManager] Skipping resource with duplicate name: '%s' (origin: '%s')",
344 resource->getName().c_str(), resource->getOrigin().c_str());
345 return false; // Instruct OGRE to drop the new resource and keep the original.
346}
347
348bool ContentManager::handleEvent(ScriptCompiler *compiler, ScriptCompilerEvent *evt, void *retval)
349{
350 if (evt->mType == CreateMaterialScriptCompilerEvent::eventType)
351 {
352 // Workaround for OGRE script compiler not properly checking that material name is not empty.
353 // See https://github.com/RigsOfRods/rigs-of-rods/issues/2349
354 auto* matEvent = static_cast<CreateMaterialScriptCompilerEvent*>(evt);
355 if (matEvent->mName.empty())
356 {
357 RoR::LogFormat("[RoR] Got malformed material (empty name) from file: '%s' - forcing OGRE to fail loading.",
358 matEvent->mFile.c_str());
359 // Report "handled" but create nothing -> OGRE will interrupt the loading
360 // with message "failed to find or create material" [in MaterialTranslator::translate()]
361 return true;
362 }
363 }
364 else if (evt->mType == CreateParticleSystemScriptCompilerEvent::eventType)
365 {
366 // Workaround for OGRE ignoring resource groups when registering particle templates
367 // See https://github.com/RigsOfRods/rigs-of-rods/pull/2398
368 auto* particleEvent = static_cast<CreateParticleSystemScriptCompilerEvent*>(evt);
369 if (Ogre::ParticleSystemManager::getSingleton().getTemplate(particleEvent->mName) != nullptr)
370 {
371 // Duplicate name -> OGRE would throw exception and fail initializing whole resource group
372 RoR::LogFormat("[RoR] Duplicate particle system name '%s' in file: '%s' - forcing OGRE to fail loading.",
373 particleEvent->mName.c_str(), particleEvent->mFile.c_str());
374 return true; // Instruct OGRE to skip the particle system
375 }
376 }
377
378 return false; // Report "not handled"
379}
380
381void ContentManager::InitManagedMaterials(std::string const & rg_name)
382{
383 Ogre::String managed_materials_dir = PathCombine(App::sys_resources_dir->getStr(), "managed_materials");
384
385 //Dirty, needs to be improved
386 if (App::gfx_shadow_type->getEnum<GfxShadowType>() == GfxShadowType::PSSM)
387 {
388 if (rg_name == RGN_MANAGED_MATS) // Only load shared resources on startup
389 {
390 ResourceGroupManager::getSingleton().addResourceLocation(PathCombine(managed_materials_dir, "shadows/pssm/on/shared"), "FileSystem", rg_name);
391 }
392 ResourceGroupManager::getSingleton().addResourceLocation(PathCombine(managed_materials_dir, "shadows/pssm/on"), "FileSystem", rg_name);
393 }
394 else
395 {
396 ResourceGroupManager::getSingleton().addResourceLocation(PathCombine(managed_materials_dir,"shadows/pssm/off"), "FileSystem", rg_name);
397 }
398
399 ResourceGroupManager::getSingleton().addResourceLocation(PathCombine(managed_materials_dir, "texture"), "FileSystem", rg_name);
400
401 // Last
402 ResourceGroupManager::getSingleton().addResourceLocation(managed_materials_dir, "FileSystem", rg_name);
403
404 if (rg_name == RGN_MANAGED_MATS) // Only initialize the global resource group
405 ResourceGroupManager::getSingleton().initialiseResourceGroup(rg_name);
406}
407
435
437{
438 std::stringstream buf;
439
440 auto dir_list = Ogre::ResourceGroupManager::getSingleton().listResourceFileInfo(RGN_CONTENT, true);
441 for (auto dir: *dir_list)
442 {
443 buf << dir.filename << std::endl;
444 }
445
446 // Any filename + listed extensions, ignore case
447 std::regex file_whitelist("^.\\.(airplane|boat|car|fixed|load|machine|skin|terrn2|train|truck)$", std::regex::icase);
448
449 auto file_list = Ogre::ResourceGroupManager::getSingleton().listResourceFileInfo(RGN_CONTENT, false);
450 for (auto file: *file_list)
451 {
452 if ((file.archive != nullptr) || std::regex_match(file.filename, file_whitelist))
453 {
454 buf << file.filename << std::endl;
455 }
456 }
457
458 return buf.str();
459}
460
461bool ContentManager::LoadAndParseJson(std::string const& filename, std::string const& rg_name, rapidjson::Document& j_doc)
462{
463 try
464 {
465 Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(filename, rg_name);
466 Ogre::String json_str = stream->getAsString();
467 rapidjson::MemoryStream j_stream(json_str.data(), json_str.length());
468 j_doc.ParseStream<rapidjson::kParseNanAndInfFlag>(j_stream);
469 }
470 catch (Ogre::FileNotFoundException)
471 {
472 return false; // Error already logged by OGRE
473 }
474 catch (std::exception& e)
475 {
476 RoR::LogFormat("[RoR] Failed to open or read json file '%s' (resource group '%s'), message: '%s'",
477 filename.c_str(), rg_name.c_str(), e.what());
478 return false;
479 }
480
481 if (j_doc.HasParseError())
482 {
483 RoR::LogFormat("[RoR] Error parsing JSON file '%s' (resource group '%s')",
484 filename.c_str(), rg_name.c_str());
485 return false;
486 }
487
488 return true;
489}
490
491bool ContentManager::SerializeAndWriteJson(std::string const& filename, std::string const& rg_name, rapidjson::Document& j_doc)
492{
493 // Serialize JSON to string
494 rapidjson::StringBuffer buffer;
495 rapidjson::Writer<rapidjson::StringBuffer, rapidjson::UTF8<>, rapidjson::UTF8<>,
496 rapidjson::CrtAllocator, rapidjson::kWriteNanAndInfFlag>
497 writer(buffer);
498 j_doc.Accept(writer);
499
500 // Write JSON to file
501 try
502 {
503 Ogre::DataStreamPtr stream
504 = Ogre::ResourceGroupManager::getSingleton().createResource(
505 filename, rg_name, /*overwrite=*/true);
506 size_t written = stream->write(buffer.GetString(), buffer.GetSize());
507 if (written < buffer.GetSize())
508 {
509 RoR::LogFormat("[RoR] Error writing JSON file '%s' (resource group '%s'), ",
510 "only written %u out of %u bytes!",
511 filename.c_str(), rg_name.c_str(), written, buffer.GetSize());
512 return false;
513 }
514 return true;
515 }
516 catch (std::exception& e)
517 {
518 RoR::LogFormat("[RoR] Error writing JSON file '%s' (resource group '%s'), message: '%s'",
519 filename.c_str(), rg_name.c_str(), e.what());
520 return false;
521 }
522}
523
524bool ContentManager::DeleteDiskFile(std::string const& filename, std::string const& rg_name)
525{
526 try
527 {
528 Ogre::ResourceGroupManager::getSingleton().deleteResource(filename, rg_name);
529 return true;
530 }
531 catch (std::exception& e)
532 {
533 RoR::LogFormat("[RoR|ModCache] Error deleting file '%s' (resource group '%s'), message: '%s'",
534 filename.c_str(), rg_name.c_str(), e.what());
535 return false;
536 }
537}
538
Central state/object manager and communications hub.
#define RGN_TEMP
Definition Application.h:45
#define RGN_CONTENT
Definition Application.h:50
#define RGN_REPO_ATTACHMENTS
Definition Application.h:48
#define RGN_CONFIG
Definition Application.h:49
#define RGN_MANAGED_MATS
Definition Application.h:52
#define RGN_THUMBNAILS
Definition Application.h:47
void LOG(const char *msg)
Legacy alias - formerly a macro.
#define RGN_CACHE
Definition Application.h:46
#define RGN_SCRIPTS
Definition Application.h:53
#define RGN_LOGS
Definition Application.h:54
#define RGN_SAVEGAMES
Definition Application.h:51
A database of user-installed content alias 'mods' (vehicles, terrains...)
#define DECLARE_RESOURCE_PACK(_FIELD_, _NAME_, _RESOURCE_GROUP_)
Platform-specific utilities. We use narrow UTF-8 encoded strings as paths. Inspired by http://utf8eve...
Factory for creating TextAreaOverlayElement instances.
Factory class for DeflectorPlaneAffector.
Factory class for DeflectorPlaneAffector.
Factory class for ShaderParticleRenderer.
std::string const & getStr() const
Definition CVar.h:95
CacheValidity EvaluateCacheValidity()
const std::vector< std::string > & GetContentDirs() const
void LoadModCache(CacheValidity validity)
bool resourceCollision(Ogre::Resource *resource, Ogre::ResourceManager *resourceManager) override
Ogre::DataStreamPtr resourceLoading(const Ogre::String &name, const Ogre::String &group, Ogre::Resource *resource) override
void AddResourcePack(ResourcePack const &resource_pack, std::string const &override_rgn="")
Loads resources if not already loaded.
bool handleEvent(Ogre::ScriptCompiler *compiler, Ogre::ScriptCompilerEvent *evt, void *retval) override
bool DeleteDiskFile(std::string const &filename, std::string const &rg_name)
bool LoadAndParseJson(std::string const &filename, std::string const &rg_name, rapidjson::Document &j_doc)
bool SerializeAndWriteJson(std::string const &filename, std::string const &rg_name, rapidjson::Document &j_doc)
void resourceStreamOpened(const Ogre::String &name, const Ogre::String &group, Ogre::Resource *resource, Ogre::DataStreamPtr &dataStream) override
void InitModCache(CacheValidity validity)
std::string ListAllUserContent()
Used by ModCache for quick detection of added/removed content.
void LoadGameplayResources()
Checks GVar settings and loads required resources.
void InitManagedMaterials(std::string const &rg_name)
void setLoadingBaseSounds(bool value)
bool FolderExists(const char *path)
Path must be UTF-8 encoded.
std::string PathCombine(std::string a, std::string b)
bool FileExists(const char *path)
Path must be UTF-8 encoded.
CVar * gfx_sky_mode
CVar * sys_repo_attachments_dir
CVar * gfx_water_mode
CVar * sys_logs_dir
CVar * gfx_anisotropy
SoundScriptManager * GetSoundScriptManager()
CVar * sys_config_dir
CVar * sys_savegames_dir
CVar * sys_user_dir
CVar * sys_cache_dir
CVar * gfx_vegetation_mode
CacheSystem * GetCacheSystem()
CVar * gfx_texture_filter
CVar * sys_resources_dir
void CreateSoundScriptManager()
CVar * sys_scripts_dir
CVar * sys_thumbnails_dir
CVar * app_extra_mod_path
CVar * gfx_shadow_type
CVar * sys_process_dir
CacheValidity
void LogFormat(const char *format,...)
Improved logging utility. Uses fixed 2Kb buffer.
@ CAELUM
Caelum (best looking, slower)
@ SKYX
SkyX (best looking, slower)
@ DEPTHMAP_ENABLED
static const ResourcePack HYDRAX
static const ResourcePack DASHBOARDS
static const ResourcePack OVERLAYS
static const ResourcePack PARTICLES
static const ResourcePack TEXTURES
static const ResourcePack MESHES
static const ResourcePack SOUNDS
static const ResourcePack MYGUI
static const ResourcePack AIRFOILS
static const ResourcePack SKYX
static const ResourcePack CAELUM
static const ResourcePack FAMICONS
static const ResourcePack MATERIALS
static const ResourcePack PAGED