diff --git a/neo/CMakeLists.txt b/neo/CMakeLists.txt index b95fc3cb..c8eba3da 100644 --- a/neo/CMakeLists.txt +++ b/neo/CMakeLists.txt @@ -74,7 +74,15 @@ elseif(cpu MATCHES "i.86") endif() if(MSVC AND CMAKE_CL_64) - set(cpu "amd64") + set(cpu "x86_64") +endif() + +add_definitions(-DD3_ARCH="${cpu}" -DD3_SIZEOFPTR=${CMAKE_SIZEOF_VOID_P}) + +if(cpu STREQUAL "x86_64" AND NOT CMAKE_SIZEOF_VOID_P EQUAL 8) + # TODO: same for arm64? PPC64? + message(SEND_ERROR "CMake thinks sizeof(void*) == 4, but that the target CPU is x86_64!") + message(FATAL_ERROR "If you're building in a 32bit chroot on a 64bit host, switch to it with 'linux32 chroot' or at least call cmake with linux32 (or your OSs equivalent)!") endif() # target os @@ -84,6 +92,8 @@ else() string(TOLOWER "${CMAKE_SYSTEM_NAME}" os) endif() +add_definitions(-DD3_OSTYPE="${os}") + # build type if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "RelWithDebInfo") @@ -230,7 +240,7 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang") if(cpu STREQUAL "x86_64") add_compile_options(-arch x86_64 -mmacosx-version-min=10.9) set(ldflags "${ldflags} -arch x86_64 -mmacosx-version-min=10.9") - elseif(cpu STREQUAL "arm64") + elseif(cpu STREQUAL "arm64") add_compile_options(-arch arm64 -mmacosx-version-min=11.0) set(ldflags "${ldflags} -arch arm64 -mmacosx-version-min=11.0") elseif(cpu STREQUAL "x86") diff --git a/neo/d3xp/Game_local.cpp b/neo/d3xp/Game_local.cpp index 6ffb61b1..08aaf9bf 100644 --- a/neo/d3xp/Game_local.cpp +++ b/neo/d3xp/Game_local.cpp @@ -26,6 +26,8 @@ If you have questions concerning this license or the applicable additional terms =========================================================================== */ +#include + #include "sys/platform.h" #include "idlib/LangDict.h" #include "idlib/Timer.h" @@ -505,6 +507,15 @@ void idGameLocal::SaveGame( idFile *f ) { savegame.WriteBuildNumber( BUILD_NUMBER ); + // DG: add some more information to savegame to make future quirks easier + savegame.WriteInt( INTERNAL_SAVEGAME_VERSION ); // to be independent of BUILD_NUMBER + savegame.WriteString( D3_OSTYPE ); // operating system - from CMake + savegame.WriteString( D3_ARCH ); // CPU architecture (e.g. "x86" or "x86_64") - from CMake + savegame.WriteString( ENGINE_VERSION ); + savegame.WriteShort( (short)sizeof(void*) ); // tells us if it's from a 32bit (4) or 64bit system (8) + savegame.WriteShort( SDL_BYTEORDER ) ; // SDL_LIL_ENDIAN or SDL_BIG_ENDIAN + // DG end + // go through all entities and threads and add them to the object list for( i = 0; i < MAX_GENTITIES; i++ ) { ent = entities[i]; @@ -1360,6 +1371,36 @@ bool idGameLocal::InitFromSaveGame( const char *mapName, idRenderWorld *renderWo savegame.ReadBuildNumber(); + // DG: I enhanced the information in savegames a bit for dhewm3 1.5.1 + // for which I bumped th BUILD_NUMBER to 1305 + if( savegame.GetBuildNumber() >= 1305 ) + { + savegame.ReadInternalSavegameVersion(); + if( savegame.GetInternalSavegameVersion() > INTERNAL_SAVEGAME_VERSION ) { + Warning( "Savegame from newer dhewm3 version, don't know how to load! (its version is %d, only up to %d supported)", + savegame.GetInternalSavegameVersion(), INTERNAL_SAVEGAME_VERSION ); + return false; + } + idStr osType; + idStr cpuArch; + idStr engineVersion; + short ptrSize = 0; + short byteorder = 0; + savegame.ReadString( osType ); // operating system the savegame was crated on (written from D3_OSTYPE) + savegame.ReadString( cpuArch ); // written from D3_ARCH (which is set in CMake), like "x86" or "x86_64" + savegame.ReadString( engineVersion ); // written from ENGINE_VERSION + savegame.ReadShort( ptrSize ); // sizeof(void*) of system that created the savegame, 4 on 32bit systems, 8 on 64bit systems + savegame.ReadShort( byteorder ); // SDL_LIL_ENDIAN or SDL_BIG_ENDIAN + + Printf( "Savegame was created by %s on %s %s. BuildNumber was %d, savegameversion %d\n", + engineVersion.c_str(), osType.c_str(), cpuArch.c_str(), savegame.GetBuildNumber(), + savegame.GetInternalSavegameVersion() ); + + // right now I have no further use for this information, but in the future + // it can be used for quirks for (then-) old savegames + } + // DG end + // Create the list of all objects in the game savegame.CreateObjects(); diff --git a/neo/d3xp/Game_local.h b/neo/d3xp/Game_local.h index cb229cd9..acd4fff0 100644 --- a/neo/d3xp/Game_local.h +++ b/neo/d3xp/Game_local.h @@ -512,6 +512,7 @@ public: private: const static int INITIAL_SPAWN_COUNT = 1; + const static int INTERNAL_SAVEGAME_VERSION = 1; // DG: added this for >= 1305 savegames idStr mapFileName; // name of the map, empty string if no map loaded idMapFile * mapFile; // will be NULL during the game unless in-game editing is used diff --git a/neo/d3xp/gamesys/SaveGame.cpp b/neo/d3xp/gamesys/SaveGame.cpp index 2dd04a66..83414a91 100644 --- a/neo/d3xp/gamesys/SaveGame.cpp +++ b/neo/d3xp/gamesys/SaveGame.cpp @@ -785,6 +785,7 @@ idRestoreGame::RestoreGame */ idRestoreGame::idRestoreGame( idFile *savefile ) { file = savefile; + internalSavegameVersion = 0; } /* diff --git a/neo/d3xp/gamesys/SaveGame.h b/neo/d3xp/gamesys/SaveGame.h index 4b0927f4..b7816597 100644 --- a/neo/d3xp/gamesys/SaveGame.h +++ b/neo/d3xp/gamesys/SaveGame.h @@ -158,8 +158,23 @@ public: // Used to retrieve the saved game buildNumber from within class Restore methods int GetBuildNumber( void ); + // DG: added these methods, internalSavegameVersion makes us independent of the global BUILD_NUMBER + void ReadInternalSavegameVersion( void ) + { + ReadInt( internalSavegameVersion ); + } + + // if it's 0, this is from a GetBuildNumber() < 1305 savegame + // otherwise, compare it to idGameLocal::INTERNAL_SAVEGAME_VERSION + int GetInternalSavegameVersion( void ) const + { + return internalSavegameVersion; + } + // DG end + private: int buildNumber; + int internalSavegameVersion; // DG added this idFile * file; diff --git a/neo/framework/Common.cpp b/neo/framework/Common.cpp index 87d9df69..d0bda134 100644 --- a/neo/framework/Common.cpp +++ b/neo/framework/Common.cpp @@ -2837,6 +2837,24 @@ static bool checkForHelp(int argc, char **argv) return false; } +#ifdef UINTPTR_MAX // DG: make sure D3_SIZEOFPTR is consistent with reality + +#if D3_SIZEOFPTR == 4 + #if UINTPTR_MAX != 0xFFFFFFFFUL + #error "CMake assumes that we're building for a 32bit architecture, but UINTPTR_MAX doesn't match!" + #endif +#elif D3_SIZEOFPTR == 8 + #if UINTPTR_MAX != 18446744073709551615ULL + #error "CMake assumes that we're building for a 64bit architecture, but UINTPTR_MAX doesn't match!" + #endif +#else + // Hello future person with a 128bit(?) CPU, I hope the future doesn't suck too much and that you don't still use CMake. + // Also, please adapt this check and send a pull request (or whatever way we have to send patches in the future) + #error "D3_SIZEOFPTR should really be 4 (for 32bit targets) or 8 (for 64bit targets), what kind of machine is this?!" +#endif + +#endif // UINTPTR_MAX defined + /* ================= idCommonLocal::Init @@ -2844,6 +2862,12 @@ idCommonLocal::Init */ void idCommonLocal::Init( int argc, char **argv ) { + // in case UINTPTR_MAX isn't defined (or wrong), do a runtime check at startup + if ( D3_SIZEOFPTR != sizeof(void*) ) { + Sys_Error( "Something went wrong in your build: CMake assumed that sizeof(void*) == %d but in reality it's %d!\n", + (int)D3_SIZEOFPTR, (int)sizeof(void*) ); + } + if(checkForHelp(argc, argv)) { // game has been started with --help (or similar), usage message has been shown => quit diff --git a/neo/framework/Licensee.h b/neo/framework/Licensee.h index dcf75071..f9b4c8c1 100644 --- a/neo/framework/Licensee.h +++ b/neo/framework/Licensee.h @@ -41,12 +41,12 @@ If you have questions concerning this license or the applicable additional terms #define GAME_NAME "dhewm 3" // appears on window titles and errors #endif -#define ENGINE_VERSION "dhewm3 1.5.1rc2" // printed in console +#define ENGINE_VERSION "dhewm3 1.5.1rc3" // printed in console #ifdef ID_REPRODUCIBLE_BUILD // for reproducible builds we hardcode values that would otherwise come from __DATE__ and __TIME__ // NOTE: remember to update esp. the date for (pre-) releases and RCs and the like - #define ID__DATE__ "Jul 21 2020" + #define ID__DATE__ "Feb 06 2021" #define ID__TIME__ "13:37:42" #else // not reproducible build, use __DATE__ and __TIME__ macros diff --git a/neo/game/Game_local.cpp b/neo/game/Game_local.cpp index d99901cb..ef820d66 100644 --- a/neo/game/Game_local.cpp +++ b/neo/game/Game_local.cpp @@ -26,6 +26,8 @@ If you have questions concerning this license or the applicable additional terms =========================================================================== */ +#include + #include "sys/platform.h" #include "idlib/LangDict.h" #include "idlib/Timer.h" @@ -447,9 +449,14 @@ void idGameLocal::SaveGame( idFile *f ) { savegame.WriteBuildNumber( BUILD_NUMBER ); - // DG: TODO: write other things (maybe internal savegame version so I don't have to bump BUILD_NUMBER AGAIN) - // and OS, architecture etc, see #344 - // TODO: adjust InitFromSavegame() accordingly! + // DG: add some more information to savegame to make future quirks easier + savegame.WriteInt( INTERNAL_SAVEGAME_VERSION ); // to be independent of BUILD_NUMBER + savegame.WriteString( D3_OSTYPE ); // operating system - from CMake + savegame.WriteString( D3_ARCH ); // CPU architecture (e.g. "x86" or "x86_64") - from CMake + savegame.WriteString( ENGINE_VERSION ); + savegame.WriteShort( (short)sizeof(void*) ); // tells us if it's from a 32bit (4) or 64bit system (8) + savegame.WriteShort( SDL_BYTEORDER ) ; // SDL_LIL_ENDIAN or SDL_BIG_ENDIAN + // DG end // go through all entities and threads and add them to the object list for( i = 0; i < MAX_GENTITIES; i++ ) { @@ -1244,11 +1251,35 @@ bool idGameLocal::InitFromSaveGame( const char *mapName, idRenderWorld *renderWo savegame.ReadBuildNumber(); - - if(savegame.GetBuildNumber() >= 1305) + // DG: I enhanced the information in savegames a bit for dhewm3 1.5.1 + // for which I bumped th BUILD_NUMBER to 1305 + if( savegame.GetBuildNumber() >= 1305 ) { - // TODO: read stuff additionally written in SaveGame() + savegame.ReadInternalSavegameVersion(); + if( savegame.GetInternalSavegameVersion() > INTERNAL_SAVEGAME_VERSION ) { + Warning( "Savegame from newer dhewm3 version, don't know how to load! (its version is %d, only up to %d supported)", + savegame.GetInternalSavegameVersion(), INTERNAL_SAVEGAME_VERSION ); + return false; + } + idStr osType; + idStr cpuArch; + idStr engineVersion; + short ptrSize = 0; + short byteorder = 0; + savegame.ReadString( osType ); // operating system the savegame was crated on (written from D3_OSTYPE) + savegame.ReadString( cpuArch ); // written from D3_ARCH (which is set in CMake), like "x86" or "x86_64" + savegame.ReadString( engineVersion ); // written from ENGINE_VERSION + savegame.ReadShort( ptrSize ); // sizeof(void*) of system that created the savegame, 4 on 32bit systems, 8 on 64bit systems + savegame.ReadShort( byteorder ); // SDL_LIL_ENDIAN or SDL_BIG_ENDIAN + + Printf( "Savegame was created by %s on %s %s. BuildNumber was %d, savegameversion %d\n", + engineVersion.c_str(), osType.c_str(), cpuArch.c_str(), savegame.GetBuildNumber(), + savegame.GetInternalSavegameVersion() ); + + // right now I have no further use for this information, but in the future + // it can be used for quirks for (then-) old savegames } + // DG end // Create the list of all objects in the game savegame.CreateObjects(); diff --git a/neo/game/Game_local.h b/neo/game/Game_local.h index 1f724434..df7456d1 100644 --- a/neo/game/Game_local.h +++ b/neo/game/Game_local.h @@ -450,6 +450,7 @@ public: private: const static int INITIAL_SPAWN_COUNT = 1; + const static int INTERNAL_SAVEGAME_VERSION = 1; // DG: added this for >= 1305 savegames idStr mapFileName; // name of the map, empty string if no map loaded idMapFile * mapFile; // will be NULL during the game unless in-game editing is used diff --git a/neo/game/gamesys/SaveGame.cpp b/neo/game/gamesys/SaveGame.cpp index e0b70c9d..7dceafeb 100644 --- a/neo/game/gamesys/SaveGame.cpp +++ b/neo/game/gamesys/SaveGame.cpp @@ -780,6 +780,7 @@ idRestoreGame::RestoreGame */ idRestoreGame::idRestoreGame( idFile *savefile ) { file = savefile; + internalSavegameVersion = 0; } /* diff --git a/neo/game/gamesys/SaveGame.h b/neo/game/gamesys/SaveGame.h index 4b0927f4..b7816597 100644 --- a/neo/game/gamesys/SaveGame.h +++ b/neo/game/gamesys/SaveGame.h @@ -158,8 +158,23 @@ public: // Used to retrieve the saved game buildNumber from within class Restore methods int GetBuildNumber( void ); + // DG: added these methods, internalSavegameVersion makes us independent of the global BUILD_NUMBER + void ReadInternalSavegameVersion( void ) + { + ReadInt( internalSavegameVersion ); + } + + // if it's 0, this is from a GetBuildNumber() < 1305 savegame + // otherwise, compare it to idGameLocal::INTERNAL_SAVEGAME_VERSION + int GetInternalSavegameVersion( void ) const + { + return internalSavegameVersion; + } + // DG end + private: int buildNumber; + int internalSavegameVersion; // DG added this idFile * file;