diff --git a/neo/framework/Common.cpp b/neo/framework/Common.cpp index ad3a1865..842c81e7 100644 --- a/neo/framework/Common.cpp +++ b/neo/framework/Common.cpp @@ -52,6 +52,7 @@ If you have questions concerning this license or the applicable additional terms #include "framework/Common.h" #include "GameCallbacks_local.h" +#include "Session_local.h" // DG: For FT_IsDemo/isDemo() hack #define MAX_PRINT_MSG_SIZE 4096 #define MAX_WARNING_LIST 256 @@ -3238,6 +3239,11 @@ bool idCommonLocal::SetCallback(idCommon::CallbackType cbt, idCommon::FunctionPo } } +static bool isDemo(void) +{ + return sessLocal.IsDemoVersion(); +} + // returns true if that function is available in this version of dhewm3 // *out_fnptr will be the function (you'll have to cast it probably) // *out_userArg will be an argument you have to pass to the function, if appropriate (else NULL) @@ -3251,11 +3257,18 @@ bool idCommonLocal::GetAdditionalFunction(idCommon::FunctionType ft, idCommon::F Warning("Called idCommon::GetAdditionalFunction() with out_fnptr == NULL!\n"); return false; } - *out_fnptr = NULL; + switch(ft) + { + case idCommon::FT_IsDemo: + *out_fnptr = (idCommon::FunctionPointer)isDemo; + // don't set *out_userArg, this function takes no arguments + return true; - // NOTE: this doesn't do anything yet, but allows to later add ugly mod-specific hacks without breaking the Game interface - - return false; + default: + *out_fnptr = NULL; + Warning("Called idCommon::SetCallback() with unknown FunctionType %d!\n", ft); + return false; + } } diff --git a/neo/framework/Common.h b/neo/framework/Common.h index b556e4bd..c0400bb4 100644 --- a/neo/framework/Common.h +++ b/neo/framework/Common.h @@ -243,10 +243,7 @@ public: * * Similar to SetCallback() I've also added GetAdditionalFunction() to get a function pointer * from dhewm3 that Mods can call (and that's not exported via the normal interface classes). - * Right now GetAdditionalFunction() will always just return false and do nothing, but if - * some Mod needs some specific function in the future, it could be implemented with - * GetAdditionalFunction() - again without breaking the game API and ABI for all the other - * Mods that don't need that function. + * Right now it's only used for a Doom3 Demo specific hack only relevant for base.dll (not for Mods) */ typedef void* (*FunctionPointer)(void*); // needs to be cast to/from real type! @@ -264,13 +261,15 @@ public: virtual bool SetCallback(CallbackType cbt, FunctionPointer cb, void* userArg) = 0; enum FunctionType { - // None yet.. + // the function's signature is bool fn(void) - no arguments. + // it returns true if we're currently running the doom3 demo + // not relevant for mods, only for game/ aka base.dll/base.so/... + FT_IsDemo = 1, }; // returns true if that function is available in this version of dhewm3 // *out_fnptr will be the function (you'll have to cast it probably) // *out_userArg will be an argument you have to pass to the function, if appropriate (else NULL) - // NOTE: this doesn't do anything yet, but allows to add ugly mod-specific hacks without breaking the Game interface virtual bool GetAdditionalFunction(FunctionType ft, FunctionPointer* out_fnptr, void** out_userArg) = 0; }; diff --git a/neo/framework/Session.cpp b/neo/framework/Session.cpp index e60f9e85..73585a2e 100644 --- a/neo/framework/Session.cpp +++ b/neo/framework/Session.cpp @@ -2895,7 +2895,7 @@ void idSessionLocal::Init() { guiMainMenu = uiManager->FindGui( "guis/mainmenu.gui", true, false, true ); if (!guiMainMenu) { guiMainMenu = uiManager->FindGui( "guis/demo_mainmenu.gui", true, false, true ); - demoversion = true; + demoversion = (guiMainMenu != NULL); } guiMainMenu_MapList = uiManager->AllocListGUI(); guiMainMenu_MapList->Config( guiMainMenu, "mapList" ); diff --git a/neo/framework/Session.h b/neo/framework/Session.h index c6f86ab3..f94081a9 100644 --- a/neo/framework/Session.h +++ b/neo/framework/Session.h @@ -165,9 +165,6 @@ public: idDemoFile * readDemo; idDemoFile * writeDemo; int renderdemoVersion; - -public: - bool demoversion; }; extern idSession * session; diff --git a/neo/framework/Session_local.h b/neo/framework/Session_local.h index 0273af2b..c96aa763 100644 --- a/neo/framework/Session_local.h +++ b/neo/framework/Session_local.h @@ -343,6 +343,12 @@ public: void SetMainMenuSkin( void ); void SetPbMenuGuiVars( void ); + // DG: true if running the Demo version of Doom3 (for FT_IsDemo, see Common.h) + bool IsDemoVersion() + { + return demoversion; + } + private: bool BoxDialogSanityCheck( void ); void EmitGameAuth( void ); @@ -366,6 +372,8 @@ private: bool authWaitBox; idStr authMsg; + + bool demoversion; // DG: true if running the Demo version of Doom3, for FT_IsDemo (see Common.h) }; extern idSessionLocal sessLocal; diff --git a/neo/game/Game_local.cpp b/neo/game/Game_local.cpp index 524bc5d8..41f11767 100644 --- a/neo/game/Game_local.cpp +++ b/neo/game/Game_local.cpp @@ -254,6 +254,20 @@ void idGameLocal::Clear( void ) { memset( lagometer, 0, sizeof( lagometer ) ); } + +// DG: hack to support the Demo version of Doom3 +// NOTE: I couldn't just make this a global bool variable that's initialized +// in idGameLocal::Init(), because we decide whether it's the demo +// after loading and initializing the game DLL (when loading the main menu) +static bool (*isDemoFnPtr)(void) = NULL; +bool IsDoom3DemoVersion() +{ + bool ret = isDemoFnPtr ? isDemoFnPtr() : false; + return ret; +} + + + /* =========== idGameLocal::Init @@ -330,6 +344,10 @@ void idGameLocal::Init( void ) { gamestate = GAMESTATE_NOMAP; Printf( "...%d aas types\n", aasList.Num() ); + + + // DG: hack to support the Demo version of Doom3 + common->GetAdditionalFunction(idCommon::FT_IsDemo, (idCommon::FunctionPointer*)&isDemoFnPtr, NULL); } /* diff --git a/neo/game/Weapon.cpp b/neo/game/Weapon.cpp index d3f2e9b6..f21a2fe9 100644 --- a/neo/game/Weapon.cpp +++ b/neo/game/Weapon.cpp @@ -40,6 +40,8 @@ If you have questions concerning this license or the applicable additional terms #include "Weapon.h" +extern bool IsDoom3DemoVersion(); // DG: hack to support the Demo version of Doom3 + /*********************************************************************** idWeapon @@ -399,7 +401,7 @@ void idWeapon::Restore( idRestoreGame *savefile ) { WEAPON_RELOAD.LinkTo( scriptObject, "WEAPON_RELOAD" ); WEAPON_NETRELOAD.LinkTo( scriptObject, "WEAPON_NETRELOAD" ); WEAPON_NETENDRELOAD.LinkTo( scriptObject, "WEAPON_NETENDRELOAD" ); - if (!session->demoversion) + if (!IsDoom3DemoVersion()) // the demo assets don't support WEAPON_NETFIRING WEAPON_NETFIRING.LinkTo( scriptObject, "WEAPON_NETFIRING" ); WEAPON_RAISEWEAPON.LinkTo( scriptObject, "WEAPON_RAISEWEAPON" ); WEAPON_LOWERWEAPON.LinkTo( scriptObject, "WEAPON_LOWERWEAPON" ); @@ -554,7 +556,7 @@ void idWeapon::Clear( void ) { WEAPON_RELOAD.Unlink(); WEAPON_NETRELOAD.Unlink(); WEAPON_NETENDRELOAD.Unlink(); - if (!session->demoversion) + if (WEAPON_NETFIRING.IsLinked()) WEAPON_NETFIRING.Unlink(); WEAPON_RAISEWEAPON.Unlink(); WEAPON_LOWERWEAPON.Unlink(); @@ -998,7 +1000,7 @@ void idWeapon::GetWeaponDef( const char *objectname, int ammoinclip ) { WEAPON_RELOAD.LinkTo( scriptObject, "WEAPON_RELOAD" ); WEAPON_NETRELOAD.LinkTo( scriptObject, "WEAPON_NETRELOAD" ); WEAPON_NETENDRELOAD.LinkTo( scriptObject, "WEAPON_NETENDRELOAD" ); - if (!session->demoversion) + if (!IsDoom3DemoVersion()) // the demo assets don't support WEAPON_NETFIRING WEAPON_NETFIRING.LinkTo( scriptObject, "WEAPON_NETFIRING" ); WEAPON_RAISEWEAPON.LinkTo( scriptObject, "WEAPON_RAISEWEAPON" ); WEAPON_LOWERWEAPON.LinkTo( scriptObject, "WEAPON_LOWERWEAPON" ); @@ -2023,7 +2025,8 @@ void idWeapon::EnterCinematic( void ) { WEAPON_RELOAD = false; WEAPON_NETRELOAD = false; WEAPON_NETENDRELOAD = false; - WEAPON_NETFIRING = false; + if(WEAPON_NETFIRING.IsLinked()) + WEAPON_NETFIRING = false; WEAPON_RAISEWEAPON = false; WEAPON_LOWERWEAPON = false; }