diff --git a/CMakeLists.txt b/CMakeLists.txt index 639e45f24..03efb8eb1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -232,6 +232,7 @@ endif() add_subdirectory(deps/baseconfig EXCLUDE_FROM_ALL) if(ICU_FOUND) + target_link_libraries(base PRIVATE ICU::data ICU::i18n ICU::io ICU::tu ICU::uc) target_compile_definitions(base PRIVATE -DBUILD_WITH_ICU) endif() diff --git a/deps/baseconfig/CMakeLists.txt b/deps/baseconfig/CMakeLists.txt index 4ec0ec8ee..428ae8978 100644 --- a/deps/baseconfig/CMakeLists.txt +++ b/deps/baseconfig/CMakeLists.txt @@ -155,7 +155,7 @@ endif() # We don't need to link anything if we have win32 threads. Affects MinGW builds primarily. if(CMAKE_USE_PTHREADS_INIT AND NOT CMAKE_USE_WIN32_THREADS_INIT) - target_link_libraries(base Threads::Threads) + target_link_libraries(base PRIVATE Threads::Threads) endif() # Check for best macro that expands to current function name. diff --git a/deps/baseconfig/src/unichar.h b/deps/baseconfig/src/unichar.h index de4c57952..80bc4f03e 100644 --- a/deps/baseconfig/src/unichar.h +++ b/deps/baseconfig/src/unichar.h @@ -15,6 +15,7 @@ #ifndef BASE_UNICHAR_H #define BASE_UNICHAR_H #include +#include #ifdef U_CHAR #error U_CHAR has been defined before @@ -22,6 +23,7 @@ #ifdef BUILD_WITH_ICU #include +#include typedef UChar unichar_t; #define U_CHAR(str) (u##str) #elif defined _WIN32 diff --git a/src/game/client/fxlist.cpp b/src/game/client/fxlist.cpp index b14f85c41..7ec4a12b9 100644 --- a/src/game/client/fxlist.cpp +++ b/src/game/client/fxlist.cpp @@ -47,6 +47,14 @@ static const FieldParse s_theFXListFieldParse[] = { { "TerrainScorch", reinterpret_cast(PICK_ADDRESS(0x004CAC80, 0x00760F20)) /*&TerrainScorchFXNugget::Parse */, nullptr, 0 }, { "ParticleSystem", reinterpret_cast(PICK_ADDRESS(0x004CAE10, 0x00761350)) /*&ParticleSystemFXNugget::Parse */, nullptr, 0 }, { "FXListAtBonePos", reinterpret_cast(PICK_ADDRESS(0x004CB8E0, 0x00761D00)) /*&FXListAtBonePosFXNugget::Parse */, nullptr, 0 }, +#else // DUMMIES + // { "RayEffect", &RayEffectFXNugget::Parse, nullptr, 0 }, + { "Tracer", &TracerFXNugget::Parse, nullptr, 0 }, + { "LightPulse", &LightPulseFXNugget::Parse, nullptr, 0 }, + { "ViewShake", &ViewShakeFXNugget::Parse, nullptr, 0 }, + { "TerrainScorch", &TerrainScorchFXNugget::Parse, nullptr, 0 }, + { "ParticleSystem", &ParticleSystemFXNugget::Parse, nullptr, 0 }, + { "FXListAtBonePos", &FXListAtBonePosFXNugget::Parse, nullptr, 0 }, #endif { nullptr, nullptr, nullptr, 0 }, }; @@ -132,3 +140,167 @@ void SoundFXNugget::Parse(INI *ini, void *formal, void *, const void *) ini->Init_From_INI(nugget, _fieldParse); reinterpret_cast(formal)->Add_FXNugget(nugget); } + +void TracerFXNugget::Do_FX_Pos( + const Coord3D *primary, const Matrix3D *primary_mtx, float primary_speed, const Coord3D *secondary, float radius) const +{ + captainslog_dbgassert(false, "TracerFXNugget::Do_FX_Pos not implemented!"); +} + +void TracerFXNugget::Do_FX_Obj(const Object *primary, const Object *secondary) const +{ + captainslog_dbgassert(false, "TracerFXNugget::Do_FX_Obj not implemented!"); +} + +void TracerFXNugget::Parse(INI *ini, void *formal, void *, const void *) +{ + static const FieldParse _fieldParse[] = { + { "DecayAt", &INI::Parse_Int, nullptr, offsetof(TracerFXNugget, m_decayAt) }, + { "Length", &INI::Parse_Int, nullptr, offsetof(TracerFXNugget, m_length) }, + { "Width", &INI::Parse_Real, nullptr, offsetof(TracerFXNugget, m_width) }, + { "Color", &INI::Parse_RGB_Color, nullptr, offsetof(TracerFXNugget, m_color) }, + { "Speed", &INI::Parse_Int, nullptr, offsetof(TracerFXNugget, speed) }, + { "Probability", &INI::Parse_Real, nullptr, offsetof(TracerFXNugget, probability) }, + { nullptr, nullptr, nullptr, 0 }, + }; + + TracerFXNugget *nugget = new TracerFXNugget{}; + ini->Init_From_INI(nugget, _fieldParse); + reinterpret_cast(formal)->Add_FXNugget(nugget); +} + +void LightPulseFXNugget::Do_FX_Pos( + const Coord3D *primary, const Matrix3D *primary_mtx, float primary_speed, const Coord3D *secondary, float radius) const +{ + captainslog_dbgassert(false, "LightPulseFXNugget::Do_FX_Pos not implemented!"); +} + +void LightPulseFXNugget::Do_FX_Obj(const Object *primary, const Object *secondary) const +{ + captainslog_dbgassert(false, "LightPulseFXNugget::Do_FX_Obj not implemented!"); +} + +void LightPulseFXNugget::Parse(INI *ini, void *formal, void *, const void *) +{ + static const FieldParse _fieldParse[] = { + { "Color", &INI::Parse_RGB_Color, nullptr, offsetof(LightPulseFXNugget, m_color) }, + { "Radius", &INI::Parse_Int, nullptr, offsetof(LightPulseFXNugget, m_radius) }, + { "RadiusAsPercentOfObjectSize", + &INI::Parse_Percent_To_Real, + nullptr, + offsetof(LightPulseFXNugget, m_radiusAsPercentOfObjectSize) }, + { "IncreaseTime", &INI::Parse_Int, nullptr, offsetof(LightPulseFXNugget, m_increaseTime) }, + { "DecreaseTime", &INI::Parse_Int, nullptr, offsetof(LightPulseFXNugget, m_decreaseTime) }, + { nullptr, nullptr, nullptr, 0 }, + }; + + LightPulseFXNugget *nugget = new LightPulseFXNugget{}; + ini->Init_From_INI(nugget, _fieldParse); + reinterpret_cast(formal)->Add_FXNugget(nugget); +} + +void ViewShakeFXNugget::Do_FX_Pos( + const Coord3D *primary, const Matrix3D *primary_mtx, float primary_speed, const Coord3D *secondary, float radius) const +{ + captainslog_dbgassert(false, "ViewShakeFXNugget::Do_FX_Pos not implemented!"); +} + +void ViewShakeFXNugget::Do_FX_Obj(const Object *primary, const Object *secondary) const +{ + captainslog_dbgassert(false, "ViewShakeFXNugget::Do_FX_Obj not implemented!"); +} + +void ViewShakeFXNugget::Parse(INI *ini, void *formal, void *, const void *) +{ + static const FieldParse _fieldParse[] = { + { "Type", &INI::Parse_Index_List, g_shakeIntensityNames, offsetof(ViewShakeFXNugget, m_type) }, + { nullptr, nullptr, nullptr, 0 }, + }; + + ViewShakeFXNugget *nugget = new ViewShakeFXNugget{}; + ini->Init_From_INI(nugget, _fieldParse); + reinterpret_cast(formal)->Add_FXNugget(nugget); +} + +void TerrainScorchFXNugget::Do_FX_Pos( + const Coord3D *primary, const Matrix3D *primary_mtx, float primary_speed, const Coord3D *secondary, float radius) const +{ + captainslog_dbgassert(false, "TerrainScorchFXNugget::Do_FX_Pos not implemented!"); +} + +void TerrainScorchFXNugget::Do_FX_Obj(const Object *primary, const Object *secondary) const +{ + captainslog_dbgassert(false, "TerrainScorchFXNugget::Do_FX_Obj not implemented!"); +} + +void TerrainScorchFXNugget::Parse(INI *ini, void *formal, void *, const void *) +{ + static const FieldParse _fieldParse[] = { + { "Type", &INI::Parse_AsciiString, nullptr, offsetof(TerrainScorchFXNugget, m_type) }, + { "Radius", &INI::Parse_Int, nullptr, offsetof(TerrainScorchFXNugget, m_radius) }, + { nullptr, nullptr, nullptr, 0 }, + }; + + TerrainScorchFXNugget *nugget = new TerrainScorchFXNugget{}; + ini->Init_From_INI(nugget, _fieldParse); + reinterpret_cast(formal)->Add_FXNugget(nugget); +} + +void ParticleSystemFXNugget::Do_FX_Pos( + const Coord3D *primary, const Matrix3D *primary_mtx, float primary_speed, const Coord3D *secondary, float radius) const +{ + captainslog_dbgassert(false, "ParticleSystemFXNugget::Do_FX_Pos not implemented!"); +} + +void ParticleSystemFXNugget::Do_FX_Obj(const Object *primary, const Object *secondary) const +{ + captainslog_dbgassert(false, "ParticleSystemFXNugget::Do_FX_Obj not implemented!"); +} + +void ParticleSystemFXNugget::Parse(INI *ini, void *formal, void *, const void *) +{ + static const FieldParse _fieldParse[] = { + { "Name", &INI::Parse_AsciiString, nullptr, offsetof(ParticleSystemFXNugget, m_sysName) }, + { "Count", &INI::Parse_Int, nullptr, offsetof(ParticleSystemFXNugget, m_count) }, + { "Radius", &GameClientRandomVariable::Parse, nullptr, offsetof(ParticleSystemFXNugget, m_radius) }, + { "InitialDelay", &GameClientRandomVariable::Parse, nullptr, offsetof(ParticleSystemFXNugget, m_initialDelay) }, + { "AttachToObject", &INI::Parse_Bool, nullptr, offsetof(ParticleSystemFXNugget, m_attachToObject) }, + { "Offset", &INI::Parse_Coord3D, nullptr, offsetof(ParticleSystemFXNugget, m_offset) }, + { "Height", &GameClientRandomVariable::Parse, nullptr, offsetof(ParticleSystemFXNugget, m_height) }, + { "OrientToObject", &INI::Parse_Bool, nullptr, offsetof(ParticleSystemFXNugget, m_orientToObject) }, + { "RotateY", &INI::Parse_Angle_Real, nullptr, offsetof(ParticleSystemFXNugget, m_rotateY) }, + { "Ricochet", &INI::Parse_Bool, nullptr, offsetof(ParticleSystemFXNugget, m_ricochet) }, + { "CreateAtGroundHeight", &INI::Parse_Bool, nullptr, offsetof(ParticleSystemFXNugget, m_createAtGroundHeight) }, + { "UseCallersRadius", &INI::Parse_Bool, nullptr, offsetof(ParticleSystemFXNugget, m_useCallersRadius) }, + { nullptr, nullptr, nullptr, 0 }, + }; + + ParticleSystemFXNugget *nugget = new ParticleSystemFXNugget{}; + ini->Init_From_INI(nugget, _fieldParse); + reinterpret_cast(formal)->Add_FXNugget(nugget); +} + +void FXListAtBonePosFXNugget::Do_FX_Pos( + const Coord3D *primary, const Matrix3D *primary_mtx, float primary_speed, const Coord3D *secondary, float radius) const +{ + captainslog_dbgassert(false, "FXListAtBonePosFXNugget::Do_FX_Pos not implemented!"); +} + +void FXListAtBonePosFXNugget::Do_FX_Obj(const Object *primary, const Object *secondary) const +{ + captainslog_dbgassert(false, "FXListAtBonePosFXNugget::Do_FX_Obj not implemented!"); +} + +void FXListAtBonePosFXNugget::Parse(INI *ini, void *formal, void *, const void *) +{ + static const FieldParse _fieldParse[] = { + { "FX", &FXList::Parse, nullptr, offsetof(FXListAtBonePosFXNugget, m_fx) }, + { "BoneName", &INI::Parse_AsciiString, nullptr, offsetof(FXListAtBonePosFXNugget, m_boneName) }, + { "OrientToBone", &INI::Parse_Bool, nullptr, offsetof(FXListAtBonePosFXNugget, m_orientToBone) }, + { nullptr, nullptr, nullptr, 0 }, + }; + + FXListAtBonePosFXNugget *nugget = new FXListAtBonePosFXNugget{}; + ini->Init_From_INI(nugget, _fieldParse); + reinterpret_cast(formal)->Add_FXNugget(nugget); +} \ No newline at end of file diff --git a/src/game/client/fxlist.h b/src/game/client/fxlist.h index d890fac78..057477f45 100644 --- a/src/game/client/fxlist.h +++ b/src/game/client/fxlist.h @@ -15,7 +15,10 @@ #pragma once #include "always.h" +#include "color.h" +#include "coord.h" #include "namekeygenerator.h" +#include "randomvalue.h" #include "rtsutils.h" #include "subsysteminterface.h" #include @@ -36,7 +39,7 @@ class FXNugget : public MemoryPoolObject IMPLEMENT_ABSTRACT_POOL(FXNugget); public: - virtual ~FXNugget(){}; + virtual ~FXNugget() {}; virtual void Do_FX_Pos(const Coord3D *primary, const Matrix3D *primary_mtx, float primary_speed, @@ -103,8 +106,8 @@ class SoundFXNugget : public FXNugget IMPLEMENT_POOL(SoundFXNugget); public: - SoundFXNugget(){}; - virtual ~SoundFXNugget() override{}; + SoundFXNugget() {}; + virtual ~SoundFXNugget() override {}; virtual void Do_FX_Pos(const Coord3D *primary, const Matrix3D *primary_mtx, @@ -118,3 +121,152 @@ class SoundFXNugget : public FXNugget private: Utf8String m_soundName; }; + +class TracerFXNugget : public FXNugget +{ + IMPLEMENT_POOL(TracerFXNugget); + +public: + TracerFXNugget() {}; + virtual ~TracerFXNugget() override {}; + + virtual void Do_FX_Pos(const Coord3D *primary, + const Matrix3D *primary_mtx, + float primary_speed, + const Coord3D *secondary, + float radius) const override; + virtual void Do_FX_Obj(const Object *primary, const Object *secondary) const override; + + static void Parse(INI *ini, void *formal, void *, const void *); + +private: + int m_decayAt; + int m_length; + float m_width; + RGBColor m_color; + int speed; + float probability; +}; + +class LightPulseFXNugget : public FXNugget +{ + IMPLEMENT_POOL(LightPulseFXNugget); + +public: + LightPulseFXNugget() : m_radiusAsPercentOfObjectSize(0.0f) {}; + virtual ~LightPulseFXNugget() override {}; + + virtual void Do_FX_Pos(const Coord3D *primary, + const Matrix3D *primary_mtx, + float primary_speed, + const Coord3D *secondary, + float radius) const override; + virtual void Do_FX_Obj(const Object *primary, const Object *secondary) const override; + + static void Parse(INI *ini, void *formal, void *, const void *); + +private: + RGBColor m_color; + int m_radius; + float m_radiusAsPercentOfObjectSize; + int m_increaseTime; + int m_decreaseTime; +}; + +class ViewShakeFXNugget : public FXNugget +{ + IMPLEMENT_POOL(ViewShakeFXNugget); + +public: + ViewShakeFXNugget() {}; + virtual ~ViewShakeFXNugget() override {}; + + virtual void Do_FX_Pos(const Coord3D *primary, + const Matrix3D *primary_mtx, + float primary_speed, + const Coord3D *secondary, + float radius) const override; + virtual void Do_FX_Obj(const Object *primary, const Object *secondary) const override; + + static void Parse(INI *ini, void *formal, void *, const void *); + +private: + ShakeIntensities m_type; +}; + +class TerrainScorchFXNugget : public FXNugget +{ + IMPLEMENT_POOL(TerrainScorchFXNugget); + +public: + TerrainScorchFXNugget() {}; + virtual ~TerrainScorchFXNugget() override {}; + + virtual void Do_FX_Pos(const Coord3D *primary, + const Matrix3D *primary_mtx, + float primary_speed, + const Coord3D *secondary, + float radius) const override; + virtual void Do_FX_Obj(const Object *primary, const Object *secondary) const override; + + static void Parse(INI *ini, void *formal, void *, const void *); + +private: + Utf8String m_type; + int m_radius; +}; + +class ParticleSystemFXNugget : public FXNugget +{ + IMPLEMENT_POOL(ParticleSystemFXNugget); + +public: + ParticleSystemFXNugget() {}; + virtual ~ParticleSystemFXNugget() override {}; + + virtual void Do_FX_Pos(const Coord3D *primary, + const Matrix3D *primary_mtx, + float primary_speed, + const Coord3D *secondary, + float radius) const override; + virtual void Do_FX_Obj(const Object *primary, const Object *secondary) const override; + + static void Parse(INI *ini, void *formal, void *, const void *); + +private: + Utf8String m_sysName; + int m_count; + GameClientRandomVariable m_radius; + Coord3D m_offset; + GameClientRandomVariable m_height; + bool m_attachToObject; + GameClientRandomVariable m_initialDelay; + bool m_orientToObject; + float m_rotateY; + bool m_ricochet; + bool m_createAtGroundHeight; + bool m_useCallersRadius; +}; + +struct FXListAtBonePosFXNugget : public FXNugget +{ + IMPLEMENT_POOL(FXListAtBonePosFXNugget); + +public: + FXListAtBonePosFXNugget() {}; + virtual ~FXListAtBonePosFXNugget() override {}; + + virtual void Do_FX_Pos(const Coord3D *primary, + const Matrix3D *primary_mtx, + float primary_speed, + const Coord3D *secondary, + float radius) const override; + virtual void Do_FX_Obj(const Object *primary, const Object *secondary) const override; + + static void Parse(INI *ini, void *formal, void *, const void *); + +private: + FXList *m_fx; + Utf8String m_boneName; + bool m_orientToBone; +}; \ No newline at end of file diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 84c8a1edf..aba334979 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -710,7 +710,7 @@ void GameClient::Preload_Assets(TimeOfDayType tod) g_theControlBar->Preload_Assets(tod); g_theParticleSystemManager->Preload_Assets(tod); - char *preload_textures[39]; + const char *preload_textures[39]; preload_textures[0] = "ptspruce01.tga"; preload_textures[1] = "exrktflame.tga"; preload_textures[2] = "cvlimo3_d2.tga"; diff --git a/src/game/common/gameengine.cpp b/src/game/common/gameengine.cpp index c10e1f1d2..c57fcee51 100644 --- a/src/game/common/gameengine.cpp +++ b/src/game/common/gameengine.cpp @@ -278,13 +278,6 @@ void GameEngine::Real_Init(int argc, char *argv[]) // textures are DDS in the release build anyhow. //} - // We don't support most after this -#ifndef GAME_DLL -#pragma message("SKIPPING NOT YET SUPPORTED SUBSYSTEMS !!!") - captainslog_info("Skipping not yet supported subsystems"); - return; -#endif - ini.Load("Data/INI/Default/Water.ini", INI_LOAD_OVERWRITE, &xfer); ini.Load("Data/INI/Water.ini", INI_LOAD_OVERWRITE, &xfer); ini.Load("Data/INI/Default/Weather.ini", INI_LOAD_OVERWRITE, &xfer); @@ -375,12 +368,14 @@ void GameEngine::Real_Init(int argc, char *argv[]) Init_Subsystem( g_theFXListStore, "TheFXListStore", new FXListStore, &xfer, "Data/INI/Default/FXList.ini", "Data/INI/FXList.ini"); Init_Subsystem(g_theWeaponStore, "TheWeaponStore", new WeaponStore, &xfer, nullptr, "Data/INI/Weapon.ini"); +#ifdef GAME_DLL Init_Subsystem(g_theObjectCreationListStore, "TheObjectCreationListStore", new ObjectCreationListStore, &xfer, "Data/INI/Default/ObjectCreationList.ini", "Data/INI/ObjectCreationList.ini"); +#endif Init_Subsystem(g_theLocomotorStore, "TheLocomotorStore", new LocomotorStore, &xfer, nullptr, "Data/INI/Locomotor.ini"); Init_Subsystem(g_theSpecialPowerStore, "TheSpecialPowerStore", @@ -397,7 +392,6 @@ void GameEngine::Real_Init(int argc, char *argv[]) "----------------------------------------------------------------------------After TheBuildAssistant = %f seconds ", 0.0f); // TODO processor frequency stuff #endif - Init_Subsystem(g_theThingFactory, "TheThingFactory", new ThingFactory, @@ -410,14 +404,12 @@ void GameEngine::Real_Init(int argc, char *argv[]) "----------------------------------------------------------------------------After TheThingFactory = %f seconds ", 0.0f); // TODO processor frequency stuff #endif - Init_Subsystem(g_theUpgradeCenter, "TheUpgradeCenter", new UpgradeCenter, &xfer, "Data/INI/Default/Upgrade.ini", "Data/INI/Upgrade.ini"); - Init_Subsystem(g_theGameClient, "TheGameClient", Create_Game_Client()); #ifdef GAME_DEBUG_STRUCTS captainslog_debug( diff --git a/src/game/common/system/asciistring.cpp b/src/game/common/system/asciistring.cpp index 31400fa06..bee3198c9 100644 --- a/src/game/common/system/asciistring.cpp +++ b/src/game/common/system/asciistring.cpp @@ -389,6 +389,27 @@ void Utf8String::To_Lower() Set(buf); } +/** + * Converts this string to upper case + */ +void Utf8String::To_Upper() +{ + // Size specifically matches original code for compatibility. + char buf[MAX_TO_LOWER_BUF_LEN]; + + if (m_data == nullptr) { + return; + } + + strcpy(buf, Peek()); + + for (char *c = buf; *c != '\0'; ++c) { + *c = toupper(*c); + } + + Set(buf); +} + /** * @brief Convert any windows path separators to posix ('\' to '/'). */ diff --git a/src/game/common/system/asciistring.h b/src/game/common/system/asciistring.h index 30fca0541..5d847e588 100644 --- a/src/game/common/system/asciistring.h +++ b/src/game/common/system/asciistring.h @@ -126,6 +126,7 @@ class Utf8String void Trim(); void To_Lower(); + void To_Upper(); // Not in original code. void Remove_Last_Char(); void Format(const char *format, ...); diff --git a/src/game/common/system/registryget.cpp b/src/game/common/system/registryget.cpp index 2e191efd2..159dcdd82 100644 --- a/src/game/common/system/registryget.cpp +++ b/src/game/common/system/registryget.cpp @@ -90,7 +90,18 @@ bool Get_String_From_Registry(Utf8String subkey, Utf8String value, Utf8String &d return success; #else - return false; + Utf8String key = "CNC_ZH_"; + key += value; + key.To_Upper(); + captainslog_info( + "Get_String_From_Registry (environment) - looking in %s for key %s\n", key.Str(), value.Str()); + const char *env_value = getenv(key.Str()); + bool success = env_value != nullptr; + if (success) { + destination = env_value; + } + + return success; #endif } @@ -108,7 +119,18 @@ bool Get_String_From_Generals_Registry(Utf8String subkey, Utf8String value, Utf8 return success; #else - return false; + Utf8String key = "CNC_GEN_"; + key += value; + key.To_Upper(); + captainslog_info( + "Get_String_From_Generals_Registry (environment) - looking in %s for key %s\n", key.Str(), value.Str()); + const char *env_value = getenv(key.Str()); + bool success = env_value != nullptr; + if (success) { + destination = env_value; + } + + return success; #endif } diff --git a/src/game/common/thing/modulefactory.cpp b/src/game/common/thing/modulefactory.cpp index 7fed4472e..f2c3e96b7 100644 --- a/src/game/common/thing/modulefactory.cpp +++ b/src/game/common/thing/modulefactory.cpp @@ -79,6 +79,10 @@ const ModuleFactory::ModuleTemplate *ModuleFactory::Find_Module_Template(const U return &it->second; } + if (name == "InactiveBody") { + return nullptr; + } + captainslog_dbgassert(0, "Module name '%s' not found", name.Str()); return nullptr; } diff --git a/src/game/common/thing/thingtemplate.cpp b/src/game/common/thing/thingtemplate.cpp index 98ae9e409..8fcd3da3c 100644 --- a/src/game/common/thing/thingtemplate.cpp +++ b/src/game/common/thing/thingtemplate.cpp @@ -727,7 +727,7 @@ void ThingTemplate::Parse_Module_Name(INI *ini, void *instance, void *store, con if (data == 999) { data = 0; mask = g_theModuleFactory->Find_Module_Interface_Mask(name, MODULE_DEFAULT); - captainslog_relassert((mask & MODULEINTERFACE_BODY) != 0, CODE_06, "Only Body allowed here"); + // captainslog_relassert((mask & MODULEINTERFACE_BODY) != 0, CODE_06, "Only Body allowed here"); } else { mask = g_theModuleFactory->Find_Module_Interface_Mask(name, (ModuleType)data); captainslog_relassert((mask & MODULEINTERFACE_BODY) == 0, CODE_06, "No Body allowed here"); @@ -769,6 +769,10 @@ void ThingTemplate::Parse_Module_Name(INI *ini, void *instance, void *store, con ModuleData *m = g_theModuleFactory->New_Module_Data_From_INI(ini, name, (ModuleType)data, tag_name); + if (m == nullptr) { + return; + } + if (m->Is_AI_Module_Data()) { info->Clear_Ai_Module_Info(); } diff --git a/src/game/main.cpp b/src/game/main.cpp index dc69a87ce..5f4b46b01 100644 --- a/src/game/main.cpp +++ b/src/game/main.cpp @@ -109,8 +109,17 @@ bool g_noBorder = false; /** * @brief Sets the working directory, some code currently expects data to be in this directory. */ -inline void Set_Working_Directory() +inline void Set_Working_Directory(int argc, char **argv) { + const char *workdir = nullptr; + for (int i = 0; i < argc && i < 20; ++i) { + // DEBUG_LOG("Argument %d was %s\n", i, argv[i]); + + if (strcasecmp(argv[i], "-workdir") == 0) { + ++i; + workdir = argv[i]; + } + } #if defined(PLATFORM_WINDOWS) char path[MAX_PATH]; @@ -127,9 +136,13 @@ inline void Set_Working_Directory() #elif defined(PLATFORM_LINUX) // posix otherwise, really just linux currently // TODO /proc/curproc/file for FreeBSD /proc/self/path/a.out Solaris - char path[PATH_MAX]; - readlink("/proc/self/exe", path, PATH_MAX); - chdir(dirname(path)); + if (workdir == nullptr) { + char path[PATH_MAX]; + readlink("/proc/self/exe", path, PATH_MAX); + chdir(dirname(path)); + } else { + chdir(workdir); + } #elif defined(PLATFORM_OSX) // osx otherwise char path[PATH_MAX]; @@ -652,7 +665,7 @@ int main(int argc, char **argv) // Set working directory to the exe directory. // DEBUG_LOG("Setting working directory.\n"); - Set_Working_Directory(); + Set_Working_Directory(argc, argv); Check_Windowed(argc, argv); diff --git a/src/platform/sdl2/sdl2gameengine.cpp b/src/platform/sdl2/sdl2gameengine.cpp index f7291bfdd..0ab21b6c2 100644 --- a/src/platform/sdl2/sdl2gameengine.cpp +++ b/src/platform/sdl2/sdl2gameengine.cpp @@ -19,7 +19,10 @@ #include "sdl2keybd.h" #include "sdl2mouse.h" #include "w3dfunctionlexicon.h" +#include "w3dgameclient.h" +#include "w3dgamelogic.h" #include "w3dmodulefactory.h" +#include "w3dparticlesys.h" #include "win32bigfilesystem.h" #include "win32localfilesystem.h" @@ -27,6 +30,10 @@ #include "stdlocalfilesystem.h" #endif +#ifdef BUILD_WITH_OPENAL +#include "alaudiomanager.h" +#endif + SDL_Window *g_applicationWindow = nullptr; namespace Thyme @@ -123,12 +130,12 @@ ArchiveFileSystem *SDL2GameEngine::Create_Archive_File_System() GameLogic *SDL2GameEngine::Create_Game_Logic() { - return nullptr; + return new W3DGameLogic; } GameClient *SDL2GameEngine::Create_Game_Client() { - return nullptr; + return new W3DGameClient(); } ModuleFactory *SDL2GameEngine::Create_Module_Factory() @@ -158,12 +165,16 @@ WebBrowser *SDL2GameEngine::Create_Web_Browser() ParticleSystemManager *SDL2GameEngine::Create_Particle_System_Manager() { - return nullptr; + return new W3DParticleSystemManager(); } AudioManager *SDL2GameEngine::Create_Audio_Manager() { +#ifdef BUILD_WITH_OPENAL + return new Thyme::ALAudioManager; +#else return nullptr; +#endif } NetworkInterface *SDL2GameEngine::Create_Network() diff --git a/src/w3d/renderer/dx8wrapper.cpp b/src/w3d/renderer/dx8wrapper.cpp index 6436f944a..aba0b816f 100644 --- a/src/w3d/renderer/dx8wrapper.cpp +++ b/src/w3d/renderer/dx8wrapper.cpp @@ -844,7 +844,7 @@ bool DX8Wrapper::Set_Render_Device( captainslog_warn("Reset/Create_Device done, reset_device=%d, restore_assets=%d", reset_device, restore_assets); return res; #else - return false; + return true; #endif }