From b17c5c248185a2db5f07e514c9061c9e84db0f58 Mon Sep 17 00:00:00 2001 From: Carl Kenner Date: Sat, 25 May 2019 17:02:42 +0930 Subject: [PATCH 01/15] Fix build error in VS 2017, credit to @valkarion --- neo/idlib/sys/sys_types.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/neo/idlib/sys/sys_types.h b/neo/idlib/sys/sys_types.h index e49551a6f..42ead17ec 100644 --- a/neo/idlib/sys/sys_types.h +++ b/neo/idlib/sys/sys_types.h @@ -98,7 +98,11 @@ struct idNullPtr idNullPtr() : value( 0 ) { } // implicit conversion to all pointer types - template operator T1* () const +#if defined(_MSC_VER) && _MSC_VER >= 1910 + template constexpr operator T1* () const +#else + template operator T1* () const +#endif { return 0; } From 6d238450e92ae441d28df40b1e42bfdd3045a688 Mon Sep 17 00:00:00 2001 From: Carl Kenner Date: Sat, 25 May 2019 17:23:53 +0930 Subject: [PATCH 02/15] Fix ATL attribute deprecation warning spam on VS2017 --- neo/CMakeLists.txt | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/neo/CMakeLists.txt b/neo/CMakeLists.txt index 93cb137bb..701ee49c3 100644 --- a/neo/CMakeLists.txt +++ b/neo/CMakeLists.txt @@ -110,6 +110,11 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang") elseif(MSVC) + # the warnings are used for every profile anyway, so put them in a variable + # 4267 is for warning about converting size_t to smaller types (eg. int) + # 4467 is for VS2017 spamming: warning C4467: usage of ATL attributes is deprecated + set(my_warn_flags "/wd4267 /wd4467") + # Multiprocessor support for compiling # /MP @@ -152,15 +157,15 @@ elseif(MSVC) # set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MP ${WINRT_OPTIONS}") # set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /MP /Oi /Oy ${WINRT_OPTIONS}") # else() - set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /D _DEBUG /MP /MTd") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MP /Oi /Oy /MT /wd4267") - set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /MP /Oi /MTd /wd4267") - set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} /MP /Oi /Oy /MT /wd4267") + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /D _DEBUG /MP /MTd ${my_warn_flags}") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MP /Oi /Oy /MT ${my_warn_flags}") + set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /MP /Oi /MTd ${my_warn_flags}") + set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} /MP /Oi /Oy /MT ${my_warn_flags}") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MP /MTd") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MP /Oi /Oy /MT /wd4267") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MP /MTd /wd4267") - set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /MP /Oi /Oy /MT /wd4267") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MP /MTd ${my_warn_flags}") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MP /Oi /Oy /MT ${my_warn_flags}") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MP /MTd ${my_warn_flags}") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /MP /Oi /Oy /MT ${my_warn_flags}") # RB: without /SAFESEH:NO we can't link against ffmpeg libs and VS2013 or we have to build our own # libs for newer compilers From 7c94cea72a54db80134594625f485187d0c09f4c Mon Sep 17 00:00:00 2001 From: Carl Kenner Date: Sun, 26 May 2019 17:32:05 +0930 Subject: [PATCH 03/15] Add .clang-format specification for automatic formatting in Visual Studio 2017. It's impossible to get this exactly right due to limitations in Clang-Format and in Visual Studio, so only use this for automatic formatting as you type and for formatting the selection with Ctrl+K+F. Do not clang-format the entire file. --- doomclassic/.clang-format | 111 +++++++++++++++++++++++++++++++++++++ neo/.clang-format | 113 ++++++++++++++++++++++++++++++++++++++ neo/libs/.clang-format | 3 + 3 files changed, 227 insertions(+) create mode 100644 doomclassic/.clang-format create mode 100644 neo/.clang-format create mode 100644 neo/libs/.clang-format diff --git a/doomclassic/.clang-format b/doomclassic/.clang-format new file mode 100644 index 000000000..b1cd4286d --- /dev/null +++ b/doomclassic/.clang-format @@ -0,0 +1,111 @@ +--- +# Doom 1 coding style + +Language: Cpp +Standard: Auto +DisableFormat: false + +IndentWidth: 4 +TabWidth: 4 +UseTab: ForContinuationAndIndentation +IndentCaseLabels: false +AccessModifierOffset: -4 +IndentWrappedFunctionNames: false +NamespaceIndentation: All +ContinuationIndentWidth: 4 + +SpaceBeforeParens: ControlStatements +SpacesInParentheses: false +SpacesInCStyleCastParentheses: false +SpaceInEmptyParentheses: false +SpacesInContainerLiterals: false +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: false +#SpaceBeforeCpp11BracedList: false + +SpaceBeforeAssignmentOperators: true +#SpaceAfterLogicalNot: false +SpacesBeforeTrailingComments: 1 + +BreakBeforeBraces: Custom +BraceWrapping: + IndentBraces: false # always + AfterClass: true # always + AfterEnum: true # 6 out of 61 are wrong + AfterUnion: false # 1 out of 6 is wrong + AfterStruct: true # most of the time + AfterFunction: true # most of the time + AfterNamespace: false # 2 out of 6 are wrong + BeforeElse: false # about 50/50 so use the style I prefer + AfterControlStatement: false # a mixture so use the style I prefer + BeforeCatch: true # never used + AfterObjCDeclaration: false # never used + +ColumnLimit: 100 + +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignTrailingComments: false + +#SpaceBeforeInheritanceColon: true +#SpaceBeforeCtorInitializerColon: true +#AllowAllConstructorInitializersOnNextLine: true +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 + +AllowAllParametersOfDeclarationOnNextLine: false +#AllowAllArgumentsOnNextLine: false +AllowShortBlocksOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: true +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: true + + +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +#AlwaysBreakTemplateDeclarations: MultiLine +AlwaysBreakTemplateDeclarations: false +BinPackArguments: true +BinPackParameters: true +BreakBeforeTernaryOperators: false + +DerivePointerAlignment: true +PointerAlignment: Left + +SortIncludes: false +SortUsingDeclarations: false +ReflowComments: false +MaxEmptyLinesToKeep: 3 +KeepEmptyLinesAtTheStartOfBlocks: true + +CommentPragmas: '^ IWYU pragma:' +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IncludeCategories: + - Regex: '^\<[^Q][^/.>]*\>' + Priority: -2 + - Regex: '^\<' + Priority: -1 + - Regex: '^\"' + Priority: 0 +MacroBlockBegin: '' +MacroBlockEnd: '' +ObjCBlockIndentWidth: 4 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 150 + +# inconsistent +#SpacesInSquareBrackets: false +#SpacesInAngles: false +#AlignConsecutiveDeclarations: false +#AlignEscapedNewlinesLeft: false +#AlignOperands: false +#BreakBeforeBinaryOperators: None +... diff --git a/neo/.clang-format b/neo/.clang-format new file mode 100644 index 000000000..e80430ace --- /dev/null +++ b/neo/.clang-format @@ -0,0 +1,113 @@ +--- +# Doom 3 coding style + +Language: Cpp +Standard: Auto +DisableFormat: false + +IndentWidth: 4 +TabWidth: 4 +UseTab: Always +IndentCaseLabels: true +AccessModifierOffset: -4 +IndentWrappedFunctionNames: false +NamespaceIndentation: None +ContinuationIndentWidth: 4 + +SpaceBeforeParens: false +SpacesInParentheses: true +SpacesInCStyleCastParentheses: true +SpaceInEmptyParentheses: false +SpacesInContainerLiterals: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: false +#SpaceBeforeCpp11BracedList: false + +SpaceBeforeAssignmentOperators: true +#SpaceAfterLogicalNot: false +#SpacesBeforeTrailingComments: 1 + +BreakBeforeBraces: Custom +BraceWrapping: + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false + +ColumnLimit: 160 + +AlignAfterOpenBracket: Align +AlignTrailingComments: true + +#SpaceBeforeInheritanceColon: true +#SpaceBeforeCtorInitializerColon: true +#AllowAllConstructorInitializersOnNextLine: true +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 + +AllowAllParametersOfDeclarationOnNextLine: false +#AllowAllArgumentsOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false + + +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +#AlwaysBreakTemplateDeclarations: MultiLine +AlwaysBreakTemplateDeclarations: false +BinPackArguments: true +BinPackParameters: true +BreakBeforeTernaryOperators: false + +DerivePointerAlignment: false +PointerAlignment: Left + +SortIncludes: false +SortUsingDeclarations: false +ReflowComments: false +MaxEmptyLinesToKeep: 3 +KeepEmptyLinesAtTheStartOfBlocks: true + +BreakConstructorInitializersBeforeComma: false +CommentPragmas: '^ IWYU pragma:' +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IncludeCategories: + - Regex: '^\<[^Q][^/.>]*\>' + Priority: -2 + - Regex: '^\<' + Priority: -1 + - Regex: '^\"' + Priority: 0 +MacroBlockBegin: '' +MacroBlockEnd: '' +NamespaceIndentation: None +ObjCBlockIndentWidth: 4 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 150 + +# inconsistent +SpacesInSquareBrackets: true +#SpacesInAngles: false +#AlignConsecutiveAssignments: false +#AlignConsecutiveDeclarations: false +#AlignEscapedNewlinesLeft: false +#AlignOperands: false +#BreakBeforeBinaryOperators: None +... diff --git a/neo/libs/.clang-format b/neo/libs/.clang-format new file mode 100644 index 000000000..57fe428dc --- /dev/null +++ b/neo/libs/.clang-format @@ -0,0 +1,3 @@ +--- +DisableFormat: true +... From dcfed76fe20445e40a7c1d428a16375708fdc7ce Mon Sep 17 00:00:00 2001 From: CarlKenner Date: Mon, 20 May 2019 15:42:25 +0930 Subject: [PATCH 04/15] Fix CMake files for Visual Studio 2013 --- neo/cmake-vs2013-32bit-openal.bat | 2 +- neo/cmake-vs2013-32bit.bat | 2 +- neo/cmake-vs2013-64bit.bat | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/neo/cmake-vs2013-32bit-openal.bat b/neo/cmake-vs2013-32bit-openal.bat index a185f45a9..d90983f9e 100644 --- a/neo/cmake-vs2013-32bit-openal.bat +++ b/neo/cmake-vs2013-32bit-openal.bat @@ -2,5 +2,5 @@ cd .. del /s /q build mkdir build cd build -cmake -G "Visual Studio 12" -DCMAKE_INSTALL_PREFIX=../bin/win8-32 -DOPENAL=ON ../neo +cmake -G "Visual Studio 12 2013" -DCMAKE_INSTALL_PREFIX=../bin/win8-32 -DOPENAL=ON ../neo pause \ No newline at end of file diff --git a/neo/cmake-vs2013-32bit.bat b/neo/cmake-vs2013-32bit.bat index 2f5fe1bb9..cfce4465e 100644 --- a/neo/cmake-vs2013-32bit.bat +++ b/neo/cmake-vs2013-32bit.bat @@ -2,5 +2,5 @@ cd .. del /s /q build mkdir build cd build -cmake -G "Visual Studio 12" -DCMAKE_INSTALL_PREFIX=../bin/win8-32 ../neo +cmake -G "Visual Studio 12 2013" -DCMAKE_INSTALL_PREFIX=../bin/win8-32 ../neo pause \ No newline at end of file diff --git a/neo/cmake-vs2013-64bit.bat b/neo/cmake-vs2013-64bit.bat index e20a0421f..b9470b097 100644 --- a/neo/cmake-vs2013-64bit.bat +++ b/neo/cmake-vs2013-64bit.bat @@ -2,5 +2,5 @@ cd .. del /s /q build mkdir build cd build -cmake -G "Visual Studio 12 Win64" -DCMAKE_INSTALL_PREFIX=../bin/win8-64 ../neo +cmake -G "Visual Studio 12 2013 Win64" -DCMAKE_INSTALL_PREFIX=../bin/win8-64 ../neo pause \ No newline at end of file From 92e7ed7e37a0ad39fd34d6a39aeec4e46b38e22a Mon Sep 17 00:00:00 2001 From: CarlKenner Date: Mon, 20 May 2019 22:56:15 +0930 Subject: [PATCH 05/15] Fix loading games from vanilla Doom 3 BFG. isRBDoom is now a number: 0 = Fully Possessed, 1 = RB Doom 3 BFG, 2 = vanilla Doom 3 BFG --- neo/d3xp/Entity.cpp | 17 +- neo/d3xp/Game_local.cpp | 11 + neo/d3xp/menus/MenuScreen_Shell_Load.cpp | 5 +- neo/d3xp/menus/MenuWidget_Shell_SaveInfo.cpp | 4 +- neo/framework/Common.h | 2 +- neo/framework/Common_dialog.cpp | 2 +- neo/framework/Common_load.cpp | 10 +- neo/framework/Common_local.h | 2 +- neo/sys/common/savegame.cpp | 227 +++++++------------ neo/sys/sys_savegame.cpp | 2 +- neo/sys/sys_savegame.h | 3 +- neo/sys/sys_session.h | 2 +- neo/sys/sys_session_local.h | 2 +- neo/sys/sys_session_savegames.cpp | 4 +- neo/sys/sys_session_savegames.h | 2 +- 15 files changed, 132 insertions(+), 163 deletions(-) diff --git a/neo/d3xp/Entity.cpp b/neo/d3xp/Entity.cpp index d5da747e7..eeb1c8e48 100644 --- a/neo/d3xp/Entity.cpp +++ b/neo/d3xp/Entity.cpp @@ -805,8 +805,15 @@ void idEntity::Restore( idRestoreGame* savefile ) // spawnNode and activeNode are restored by gameLocal savefile->ReadDict( &spawnArgs ); savefile->ReadString( name ); - if ( name == "vrTeleportTarget" && gameLocal.FindEntity("vrTeleportTarget") ) - SetName( "vrTeleportTarget2" ); + char* duplicate_names[5] = { "vrTeleportTarget", "player1_weapon_left", "player1_weapon_right", "player1_weapon_left_worldmodel", "player1_weapon_right_worldmodel" }; + bool isDuplicate = false; + for( int i = 0; i < 5; i++ ) + { + if( name == duplicate_names[i] && gameLocal.FindEntity( name.c_str() ) ) + isDuplicate = true; + } + if( isDuplicate ) + SetName( name + "2" ); else SetName( name ); @@ -3607,7 +3614,11 @@ idEntity::RemoveContactEntity */ void idEntity::RemoveContactEntity( idEntity* ent ) { - GetPhysics()->RemoveContactEntity( ent ); + idPhysics* physicsPtr = GetPhysics(); + if( physicsPtr ) // prevent crash when physics is NULL + { + physicsPtr->RemoveContactEntity( ent ); + } } diff --git a/neo/d3xp/Game_local.cpp b/neo/d3xp/Game_local.cpp index efe98dc57..690191d29 100644 --- a/neo/d3xp/Game_local.cpp +++ b/neo/d3xp/Game_local.cpp @@ -1661,6 +1661,17 @@ bool idGameLocal::InitFromSaveGame( const char* mapName, idRenderWorld* renderWo { idPlayer *player = GetLocalPlayer(); player->InitTeleportTarget(); + idEntity *duplicate; + char* duplicate_names[4] = { "player1_weapon_left2", "player1_weapon_right2", "player1_weapon_left_worldmodel2", "player1_weapon_right_worldmodel2" }; + for( int i = 0; i < 4; i++ ) + { + if ( duplicate = gameLocal.FindEntity( duplicate_names[i] ) ) + { + common->Warning( "Loading game which had a duplicate player1_weapon_left/right (this is normal)." ); + duplicate->PostEventMS( &EV_Remove, 0 ); + } + } + // if we autosaved while teleporting QuakeCon style, stop the QuakeCon style effect if (player->noclip)// && player->playerView.bfgVision) { diff --git a/neo/d3xp/menus/MenuScreen_Shell_Load.cpp b/neo/d3xp/menus/MenuScreen_Shell_Load.cpp index beb2bbbde..5bf005a80 100644 --- a/neo/d3xp/menus/MenuScreen_Shell_Load.cpp +++ b/neo/d3xp/menus/MenuScreen_Shell_Load.cpp @@ -388,7 +388,7 @@ void idMenuScreen_Shell_Load::LoadGame( int index ) class idSWFScriptFunction_LoadDialog : public idSWFScriptFunction_RefCounted { public: - idSWFScriptFunction_LoadDialog( gameDialogMessages_t _msg, bool _accept, const char* _name, bool isRBDoom3 ) + idSWFScriptFunction_LoadDialog( gameDialogMessages_t _msg, bool _accept, const char* _name, uint8 isRBDoom3 ) { msg = _msg; accept = _accept; @@ -407,7 +407,8 @@ void idMenuScreen_Shell_Load::LoadGame( int index ) } private: gameDialogMessages_t msg; - bool accept, isRBDoom; + bool accept; + uint8 isRBDoom; const char* name; }; diff --git a/neo/d3xp/menus/MenuWidget_Shell_SaveInfo.cpp b/neo/d3xp/menus/MenuWidget_Shell_SaveInfo.cpp index 710d98ae5..505d472c7 100644 --- a/neo/d3xp/menus/MenuWidget_Shell_SaveInfo.cpp +++ b/neo/d3xp/menus/MenuWidget_Shell_SaveInfo.cpp @@ -67,8 +67,10 @@ void idMenuWidget_Shell_SaveInfo::Update() if( loadIndex >= 0 && sortedSaves.Num() != 0 && loadIndex < sortedSaves.Num() ) { const idSaveGameDetails& details = sortedSaves[ loadIndex ]; - if (details.isRBDoom) + if( details.isRBDoom == 1 ) info.Append( "RB Doom 3 BFG - " ); + else if( details.isRBDoom == 2 ) + info.Append( "Doom 3 BFG - " ); info.Append( details.slotName ); info.Append( "\n" ); diff --git a/neo/framework/Common.h b/neo/framework/Common.h index 689ac8003..30a87fdee 100644 --- a/neo/framework/Common.h +++ b/neo/framework/Common.h @@ -301,7 +301,7 @@ class idCommon // Processes the given event. virtual bool ProcessEvent( const sysEvent_t* event ) = 0; - virtual bool LoadGame( const char* saveName, bool isRBDoom ) = 0; + virtual bool LoadGame( const char* saveName, uint8 isRBDoom ) = 0; virtual bool SaveGame( const char* saveName ) = 0; virtual idDemoFile* ReadDemo() = 0; diff --git a/neo/framework/Common_dialog.cpp b/neo/framework/Common_dialog.cpp index e3ac99b0b..f74f8197f 100644 --- a/neo/framework/Common_dialog.cpp +++ b/neo/framework/Common_dialog.cpp @@ -1365,7 +1365,7 @@ idStr idCommonDialog::GetDialogMsg( gameDialogMessages_t msg, idStr& message, id } case GDM_ERROR_LOADING_SAVEGAME: { - message = "#str_dlg_error_loading_savegame"; + message = "#str_dlg_error_loading_savegame"; // There was an error loading your game. break; } case GDM_ERROR_SAVING_SAVEGAME: diff --git a/neo/framework/Common_load.cpp b/neo/framework/Common_load.cpp index e9afbc9b3..75df23de8 100644 --- a/neo/framework/Common_load.cpp +++ b/neo/framework/Common_load.cpp @@ -1060,7 +1060,7 @@ bool idCommonLocal::SaveGame( const char* saveName ) gameDetails.descriptors.Set( SAVEGAME_DETAIL_FIELD_LANGUAGE, sys_lang.GetString() ); gameDetails.descriptors.SetInt( SAVEGAME_DETAIL_FIELD_CHECKSUM, ( int )gameDetails.descriptors.Checksum() ); - gameDetails.isRBDoom = false; // Carl + gameDetails.isRBDoom = 0; // Carl: Fully Possessed gameDetails.slotName = saveName; ScrubSaveGameFileName( gameDetails.slotName ); @@ -1113,7 +1113,7 @@ bool idCommonLocal::SaveGame( const char* saveName ) idCommonLocal::LoadGame =============== */ -bool idCommonLocal::LoadGame( const char* saveName, bool isRBDoom ) +bool idCommonLocal::LoadGame( const char* saveName, uint8 isRBDoom ) { // Koz begin // Koz fixme do this right. @@ -1320,6 +1320,7 @@ void idCommonLocal::OnLoadCompleted( idSaveLoadParms& parms ) { if( !HandleCommonErrors( parms ) ) { + // There was an error loading your game. common->Dialog().AddDialog( GDM_ERROR_LOADING_SAVEGAME, DIALOG_CONTINUE, NULL, NULL, false ); } } @@ -1440,7 +1441,10 @@ LoadGame_f CONSOLE_COMMAND_SHIP( loadGame, "loads a game", idCmdSystem::ArgCompletion_SaveGame ) { console->Close(); - commonLocal.LoadGame( ( args.Argc() > 1 ) ? args.Argv( 1 ) : "quick", ( args.Argc() > 2 ) && idStr::Cmp( args.Argv( 2 ), "0" )!=0 ); + uint8 isRBDoom = 0; // Default to loading game from Fully Possessed + if( args.Argc() > 2 ) + isRBDoom = (uint8)atoi( args.Argv( 2 ) ); + commonLocal.LoadGame( ( args.Argc() > 1 ) ? args.Argv( 1 ) : "quick", isRBDoom ); // Koz vr_headingBeamMode.SetModified(); diff --git a/neo/framework/Common_local.h b/neo/framework/Common_local.h index 144522b01..9dc26cea9 100644 --- a/neo/framework/Common_local.h +++ b/neo/framework/Common_local.h @@ -192,7 +192,7 @@ class idCommonLocal : public idCommon virtual bool ProcessEvent( const sysEvent_t* event ); - virtual bool LoadGame( const char* saveName, bool RBDoom ); + virtual bool LoadGame( const char* saveName, uint8 RBDoom ); virtual bool SaveGame( const char* saveName ); virtual int ButtonState( int key ); diff --git a/neo/sys/common/savegame.cpp b/neo/sys/common/savegame.cpp index d0396a4ee..ecbb3984a 100644 --- a/neo/sys/common/savegame.cpp +++ b/neo/sys/common/savegame.cpp @@ -308,13 +308,18 @@ idSessionLocal::LoadGame int idSaveGameThread::Load() { idSaveLoadParms* callback = data.saveLoadParms; - idStr saveFolder = "savegame"; + idStr saveFolder = "savegame"; // Fully Possessed - if( callback->description.isRBDoom ) + if( callback->description.isRBDoom == 1 ) // RB Doom { saveFolder = Sys_DefaultSavePath(); saveFolder = saveFolder.Left(saveFolder.Length() - strlen(SAVE_PATH)) + "\\id Software\\RBDOOM 3 BFG\\base\\savegame"; } + else if( callback->description.isRBDoom == 2 ) // vanilla Doom 3 BFG Edition (Official Steam or GOG version) + { + saveFolder = Sys_DefaultSavePath(); + saveFolder = saveFolder.Left(saveFolder.Length() - strlen(SAVE_PATH)) + "\\id Software\\DOOM 3 BFG\\base\\savegame"; + } saveFolder.AppendPath(callback->directory); @@ -476,170 +481,104 @@ int idSaveGameThread::Enumerate() callback->detailList.Clear(); int ret = ERROR_SUCCESS; - if( fileSystem->IsFolder( saveFolder, "fs_savePath" ) == FOLDER_YES ) - { - idFileList* files = fileSystem->ListFilesTree( saveFolder, SAVEGAME_DETAILS_FILENAME ); - const idStrList& fileList = files->GetList(); - - for( int i = 0; i < fileList.Num() && !callback->cancelled; i++ ) + bool saveGameFolderFound = false; + for( uint8 loadFromRBDoomType = 0; loadFromRBDoomType <= 2; loadFromRBDoomType++ ) + { + idStr RBDoomFolder = Sys_DefaultSavePath(); + if( loadFromRBDoomType == 0 ) + RBDoomFolder = fileSystem->RelativePathToOSPath( "savegame", "fs_savePath" ); + else if( loadFromRBDoomType == 1 ) + RBDoomFolder = RBDoomFolder.Left(RBDoomFolder.Length() - strlen(SAVE_PATH)) + "\\id Software\\RBDOOM 3 BFG\\base\\savegame"; + else + RBDoomFolder = RBDoomFolder.Left(RBDoomFolder.Length() - strlen(SAVE_PATH)) + "\\id Software\\DOOM 3 BFG\\base\\savegame"; + if (!callback->cancelled && Sys_IsFolder(RBDoomFolder) == FOLDER_YES) { - idSaveGameDetails* details = callback->detailList.Alloc(); - // We have more folders on disk than we have room in our save detail list, stop trying to read them in and continue with what we have - if( details == NULL ) - { - break; - } - details->isRBDoom = false; + saveGameFolderFound = true; + idStrList fileList; + Sys_ListFiles(RBDoomFolder, "/", fileList); + // append "/" + SAVEGAME_DETAILS_FILENAME - idStr directory = fileList[i]; - - idFile* file = fileSystem->OpenFileRead( directory.c_str() ); - - if( file != NULL ) + for( int i = 0; i < fileList.Num() && !callback->cancelled; i++ ) { - // Read the DETAIL file for the enumerated data - if( callback->mode & SAVEGAME_MBF_READ_DETAILS ) + if (fileList[i] == "." || fileList[i] == "..") { - if( !SavegameReadDetailsFromFile( file, *details ) ) - { - details->damaged = true; - ret = -1; - } + continue; } -#ifdef _WIN32 // DG: unification of win32 and posix savagame code - // Use the date from the directory - WIN32_FILE_ATTRIBUTE_DATA attrData; - BOOL attrRet = GetFileAttributesEx( file->GetFullPath(), GetFileExInfoStandard, &attrData ); - delete file; - if( attrRet == TRUE ) + + idSaveGameDetails* details = callback->detailList.Alloc(); + // We have more folders on disk than we have room in our save detail list, stop trying to read them in and continue with what we have + if (details == NULL) { - FILETIME lastWriteTime = attrData.ftLastWriteTime; - const ULONGLONG second = 10000000L; // One second = 10,000,000 * 100 nsec - SYSTEMTIME base_st = { 1970, 1, 0, 1, 0, 0, 0, 0 }; - ULARGE_INTEGER itime; - FILETIME base_ft; - BOOL success = SystemTimeToFileTime( &base_st, &base_ft ); - - itime.QuadPart = ( ( ULARGE_INTEGER* )&lastWriteTime )->QuadPart; - if( success ) - { - itime.QuadPart -= ( ( ULARGE_INTEGER* )&base_ft )->QuadPart; - } - else - { - // Hard coded number of 100-nanosecond units from 1/1/1601 to 1/1/1970 - itime.QuadPart -= 116444736000000000LL; - } - itime.QuadPart /= second; - details->date = itime.QuadPart; + break; } -#else - // DG: just use the idFile object's timestamp - the windows code gets file attributes and - // other complicated stuff like that.. I'm wonderin what that was good for.. this seems to work. - details->date = file->Timestamp(); -#endif // DG end - } - else - { - details->damaged = true; - } - - // populate the game details struct - directory = directory.StripFilename(); - details->slotName = directory.c_str() + saveFolder.Length() + 1; // Strip off the prefix too -// JDC: I hit this all the time assert( fileSystem->IsFolder( directory.c_str(), "fs_savePath" ) == FOLDER_YES ); - } - fileSystem->FreeFileList( files ); - } - else - { - callback->errorCode = SAVEGAME_E_FOLDER_NOT_FOUND; - ret = -3; - } - - idStr RBDoomFolder = Sys_DefaultSavePath(); - RBDoomFolder = RBDoomFolder.Left(RBDoomFolder.Length() - strlen(SAVE_PATH)) + "\\id Software\\RBDOOM 3 BFG\\base\\savegame"; - if (!callback->cancelled && Sys_IsFolder(RBDoomFolder) == FOLDER_YES) - { - idStrList fileList; - Sys_ListFiles(RBDoomFolder, "/", fileList); - // append "/" + SAVEGAME_DETAILS_FILENAME - - for (int i = 0; i < fileList.Num() && !callback->cancelled; i++) - { - if (fileList[i] == "." || fileList[i] == "..") - { - continue; - } - - idSaveGameDetails* details = callback->detailList.Alloc(); - // We have more folders on disk than we have room in our save detail list, stop trying to read them in and continue with what we have - if (details == NULL) - { - break; - } - details->isRBDoom = true; + details->isRBDoom = loadFromRBDoomType; - idStr directory = fileList[i] + "/" + SAVEGAME_DETAILS_FILENAME; + idStr directory = fileList[i] + "/" + SAVEGAME_DETAILS_FILENAME; - idFile* file = fileSystem->OpenExplicitFileRead((RBDoomFolder+ "/" + directory).c_str()); + idFile* file = fileSystem->OpenExplicitFileRead( ( RBDoomFolder + "/" + directory ).c_str() ); - if (file != NULL) - { - // Read the DETAIL file for the enumerated data - if (callback->mode & SAVEGAME_MBF_READ_DETAILS) + if( file != NULL ) { - if (!SavegameReadDetailsFromFile(file, *details)) + // Read the DETAIL file for the enumerated data + if( callback->mode & SAVEGAME_MBF_READ_DETAILS ) { - details->damaged = true; - ret = -1; + if( !SavegameReadDetailsFromFile( file, *details ) ) + { + details->damaged = true; + ret = -1; + } } - } #ifdef _WIN32 // DG: unification of win32 and posix savagame code - // Use the date from the directory - WIN32_FILE_ATTRIBUTE_DATA attrData; - BOOL attrRet = GetFileAttributesEx(file->GetFullPath(), GetFileExInfoStandard, &attrData); - delete file; - if (attrRet == TRUE) - { - FILETIME lastWriteTime = attrData.ftLastWriteTime; - const ULONGLONG second = 10000000L; // One second = 10,000,000 * 100 nsec - SYSTEMTIME base_st = { 1970, 1, 0, 1, 0, 0, 0, 0 }; - ULARGE_INTEGER itime; - FILETIME base_ft; - BOOL success = SystemTimeToFileTime(&base_st, &base_ft); - - itime.QuadPart = ((ULARGE_INTEGER*)&lastWriteTime)->QuadPart; - if (success) + // Use the date from the directory + WIN32_FILE_ATTRIBUTE_DATA attrData; + BOOL attrRet = GetFileAttributesEx( file->GetFullPath(), GetFileExInfoStandard, &attrData ); + delete file; + if( attrRet == TRUE ) { - itime.QuadPart -= ((ULARGE_INTEGER*)&base_ft)->QuadPart; + FILETIME lastWriteTime = attrData.ftLastWriteTime; + const ULONGLONG second = 10000000L; // One second = 10,000,000 * 100 nsec + SYSTEMTIME base_st = { 1970, 1, 0, 1, 0, 0, 0, 0 }; + ULARGE_INTEGER itime; + FILETIME base_ft; + BOOL success = SystemTimeToFileTime( &base_st, &base_ft ); + + itime.QuadPart = ( ( ULARGE_INTEGER* )&lastWriteTime )->QuadPart; + if( success ) + { + itime.QuadPart -= ( ( ULARGE_INTEGER* )&base_ft )->QuadPart; + } + else + { + // Hard coded number of 100-nanosecond units from 1/1/1601 to 1/1/1970 + itime.QuadPart -= 116444736000000000LL; + } + itime.QuadPart /= second; + details->date = itime.QuadPart; } - else - { - // Hard coded number of 100-nanosecond units from 1/1/1601 to 1/1/1970 - itime.QuadPart -= 116444736000000000LL; - } - itime.QuadPart /= second; - details->date = itime.QuadPart; - } #else - // DG: just use the idFile object's timestamp - the windows code gets file attributes and - // other complicated stuff like that.. I'm wonderin what that was good for.. this seems to work. - details->date = file->Timestamp(); + // DG: just use the idFile object's timestamp - the windows code gets file attributes and + // other complicated stuff like that.. I'm wonderin what that was good for.. this seems to work. + details->date = file->Timestamp(); #endif // DG end - } - else - { - details->damaged = true; - } + } + else + { + details->damaged = true; + } - // populate the game details struct - directory = directory.StripFilename(); - details->slotName = directory.c_str(); // Strip off the prefix too - // JDC: I hit this all the time assert( fileSystem->IsFolder( directory.c_str(), "fs_savePath" ) == FOLDER_YES ); + // populate the game details struct + directory = directory.StripFilename(); + details->slotName = directory.c_str(); // Strip off the prefix too +// JDC: I hit this all the time assert( fileSystem->IsFolder( directory.c_str(), "fs_savePath" ) == FOLDER_YES ); + } } } + if( !saveGameFolderFound ) + { + callback->errorCode = SAVEGAME_E_FOLDER_NOT_FOUND; + ret = -3; + } if( data.saveLoadParms->cancelled ) { data.saveLoadParms->errorCode = SAVEGAME_E_CANCELLED; diff --git a/neo/sys/sys_savegame.cpp b/neo/sys/sys_savegame.cpp index acb45fef9..e4de07dcf 100644 --- a/neo/sys/sys_savegame.cpp +++ b/neo/sys/sys_savegame.cpp @@ -247,7 +247,7 @@ void idSaveGameDetails::Clear() { descriptors.Clear(); damaged = false; - isRBDoom = false; // Carl + isRBDoom = 0; // Carl: Fully Possessed date = 0; slotName[0] = '\0'; } diff --git a/neo/sys/sys_savegame.h b/neo/sys/sys_savegame.h index 9f7daf17e..6ed59c736 100644 --- a/neo/sys/sys_savegame.h +++ b/neo/sys/sys_savegame.h @@ -203,7 +203,8 @@ class idSaveGameDetails public: idDict descriptors; // [in] Descriptors available to be shown on the save/load screen. Each game can define their own, e.g. Difficulty, level, map, score, time. - bool damaged, isRBDoom; // [out] + bool damaged; // [out] + uint8 isRBDoom; // [out] time_t date; // [out] read from the filesystem, not set by client idStrStatic< MAX_FOLDER_NAME_LENGTH > slotName; // [out] folder/slot name, e.g. AUTOSAVE }; diff --git a/neo/sys/sys_session.h b/neo/sys/sys_session.h index fae4245d0..645d6693e 100644 --- a/neo/sys/sys_session.h +++ b/neo/sys/sys_session.h @@ -614,7 +614,7 @@ class idSession //===================================================================================================== virtual saveGameHandle_t SaveGameSync( const char* name, const saveFileEntryList_t& files, const idSaveGameDetails& description ) = 0; virtual saveGameHandle_t SaveGameAsync( const char* name, const saveFileEntryList_t& files, const idSaveGameDetails& description ) = 0; - virtual saveGameHandle_t LoadGameSync( const char* name, saveFileEntryList_t& files, bool isRBDoom ) = 0; + virtual saveGameHandle_t LoadGameSync( const char* name, saveFileEntryList_t& files, uint8 isRBDoom ) = 0; virtual saveGameHandle_t EnumerateSaveGamesSync() = 0; virtual saveGameHandle_t EnumerateSaveGamesAsync() = 0; virtual saveGameHandle_t DeleteSaveGameSync( const char* name ) = 0; diff --git a/neo/sys/sys_session_local.h b/neo/sys/sys_session_local.h index ddcf52c08..c47b4baf6 100644 --- a/neo/sys/sys_session_local.h +++ b/neo/sys/sys_session_local.h @@ -548,7 +548,7 @@ class idSessionLocal : public idSession //===================================================================================================== virtual saveGameHandle_t SaveGameSync( const char* name, const saveFileEntryList_t& files, const idSaveGameDetails& description ); virtual saveGameHandle_t SaveGameAsync( const char* name, const saveFileEntryList_t& files, const idSaveGameDetails& description ); - virtual saveGameHandle_t LoadGameSync( const char* name, saveFileEntryList_t& files, bool isRBDoom ); + virtual saveGameHandle_t LoadGameSync( const char* name, saveFileEntryList_t& files, uint8 isRBDoom ); virtual saveGameHandle_t EnumerateSaveGamesSync(); virtual saveGameHandle_t EnumerateSaveGamesAsync(); virtual saveGameHandle_t DeleteSaveGameSync( const char* name ); diff --git a/neo/sys/sys_session_savegames.cpp b/neo/sys/sys_session_savegames.cpp index 485f32ede..d27f61965 100644 --- a/neo/sys/sys_session_savegames.cpp +++ b/neo/sys/sys_session_savegames.cpp @@ -53,7 +53,7 @@ idSaveGameProcessorLoadFiles idSaveGameProcessorLoadFiles::InitLoadFiles ======================== */ -bool idSaveGameProcessorLoadFiles::InitLoadFiles( const char* folder_, bool isRBDoom, const saveFileEntryList_t& files, idSaveGameManager::packageType_t type ) +bool idSaveGameProcessorLoadFiles::InitLoadFiles( const char* folder_, uint8 isRBDoom, const saveFileEntryList_t& files, idSaveGameManager::packageType_t type ) { if( !idSaveGameProcessor::Init() ) { @@ -353,7 +353,7 @@ idSessionLocal::LoadGameSync We still want to use the savegame manager because we could have file system operations in flight and need to ======================== */ -saveGameHandle_t idSessionLocal::LoadGameSync( const char* name, saveFileEntryList_t& files, bool isRBDoom ) +saveGameHandle_t idSessionLocal::LoadGameSync( const char* name, saveFileEntryList_t& files, uint8 isRBDoom ) { idSaveLoadParms& parms = processorLoadFiles->GetParmsNonConst(); saveGameHandle_t handle = 0; diff --git a/neo/sys/sys_session_savegames.h b/neo/sys/sys_session_savegames.h index 66e25b883..1419ab15c 100644 --- a/neo/sys/sys_session_savegames.h +++ b/neo/sys/sys_session_savegames.h @@ -38,7 +38,7 @@ class idSaveGameProcessorLoadFiles : public idSaveGameProcessor public: DEFINE_CLASS( idSaveGameProcessorLoadFiles ); - virtual bool InitLoadFiles( const char* folder, bool isRBDoom, + virtual bool InitLoadFiles( const char* folder, uint8 isRBDoom, const saveFileEntryList_t& files, idSaveGameManager::packageType_t type = idSaveGameManager::PACKAGE_GAME ); virtual bool Process(); From 182f41b624834658453be68fe1089a39ea4477ff Mon Sep 17 00:00:00 2001 From: CarlKenner Date: Mon, 20 May 2019 23:06:13 +0930 Subject: [PATCH 06/15] Because we can load games from 3 places now, MAX_SAVEGAMES = 3 x 16 = 48 --- neo/sys/sys_savegame.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neo/sys/sys_savegame.h b/neo/sys/sys_savegame.h index 6ed59c736..d8eb97835 100644 --- a/neo/sys/sys_savegame.h +++ b/neo/sys/sys_savegame.h @@ -39,7 +39,7 @@ If you have questions concerning this license or the applicable additional terms #define DEFINE_CLASS( x ) virtual const char * Name() const { return #x; } -#define MAX_SAVEGAMES 32 +#define MAX_SAVEGAMES 48 #define MAX_FILES_WITHIN_SAVEGAME 10 #define MIN_SAVEGAME_SIZE_BYTES ( 4 * 1024 * 1024 ) #define MAX_SAVEGAME_STRING_TABLE_SIZE 400 * 1024 // 400 kB max string table size From 215e836ee0ad68a8ee844aa6f598d027f20171e7 Mon Sep 17 00:00:00 2001 From: CarlKenner Date: Mon, 20 May 2019 23:09:36 +0930 Subject: [PATCH 07/15] Fixed error message so it doesn't crash in Visual C++ 2013. --- neo/d3xp/gamesys/Event.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/neo/d3xp/gamesys/Event.cpp b/neo/d3xp/gamesys/Event.cpp index 66506529f..3108eb743 100644 --- a/neo/d3xp/gamesys/Event.cpp +++ b/neo/d3xp/gamesys/Event.cpp @@ -1013,8 +1013,8 @@ void idEvent::Restore( idRestoreGame* savefile ) savefile->ReadInt( argsize ); if( argsize != ( int )event->eventdef->GetArgSize() ) { - // RB: fixed wrong formatting - savefile->Error( "idEvent::Restore: arg size (%zd) doesn't match saved arg size(%zd) on event '%s'", event->eventdef->GetArgSize(), argsize, event->eventdef->GetName() ); + // RB: fixed wrong formatting // Carl: fixed RB's wrong formatting + savefile->Error( "idEvent::Restore: arg size (%d) doesn't match saved arg size(%d) on event '%s'", (int)event->eventdef->GetArgSize(), (int)argsize, event->eventdef->GetName() ); // RB end } if( argsize ) From 42a07e852e02de4346af877d5cad8c619594e77c Mon Sep 17 00:00:00 2001 From: CarlKenner Date: Tue, 21 May 2019 02:00:02 +0930 Subject: [PATCH 08/15] Start loading files from 32bit on 64bit and vice versa. --- neo/d3xp/gamesys/Event.cpp | 140 ++++++++++++++++++++++++++++++++----- neo/d3xp/gamesys/Event.h | 19 ++++- 2 files changed, 141 insertions(+), 18 deletions(-) diff --git a/neo/d3xp/gamesys/Event.cpp b/neo/d3xp/gamesys/Event.cpp index 3108eb743..0a92d92b0 100644 --- a/neo/d3xp/gamesys/Event.cpp +++ b/neo/d3xp/gamesys/Event.cpp @@ -91,49 +91,62 @@ idEventDef::idEventDef( const char* command, const char* formatspec, char return // make sure the format for the args is valid, calculate the formatspecindex, and the offsets for each arg bits = 0; argsize = 0; + argsize_32 = 0; + argsize_64 = 0; memset( argOffset, 0, sizeof( argOffset ) ); for( i = 0; i < numargs; i++ ) { argOffset[ i ] = argsize; - switch( formatspec[ i ] ) +#if defined(__x86_64__) || defined(_WIN64) + argOffset2[ i ] = argsize_32; +#else + argOffset2[ i ] = argsize_64; +#endif + switch (formatspec[i]) { case D_EVENT_FLOAT : bits |= 1 << i; // RB: 64 bit fix, changed sizeof( float ) to sizeof( intptr_t ) argsize += sizeof( intptr_t ); // RB end + argsize_32 += 4; + argsize_64 += 8; break; case D_EVENT_INTEGER : // RB: 64 bit fix, changed sizeof( int ) to sizeof( intptr_t ) argsize += sizeof( intptr_t ); // RB end + argsize_32 += 4; + argsize_64 += 8; break; case D_EVENT_VECTOR : // RB: 64 bit fix, changed sizeof( idVec3 ) to E_EVENT_SIZEOF_VEC argsize += E_EVENT_SIZEOF_VEC; // RB end + argsize_32 += 12; + argsize_64 += 16; break; case D_EVENT_STRING : argsize += MAX_STRING_LEN; + argsize_32 += MAX_STRING_LEN; + argsize_64 += MAX_STRING_LEN; break; case D_EVENT_ENTITY : + case D_EVENT_ENTITY_NULL: // RB: 64 bit fix, sizeof( idEntityPtr ) to sizeof( intptr_t ) argsize += sizeof( intptr_t ); // RB end - break; - - case D_EVENT_ENTITY_NULL : - // RB: 64 bit fix, sizeof( idEntityPtr ) to sizeof( intptr_t ) - argsize += sizeof( intptr_t ); - // RB end + argsize_32 += 4; + argsize_64 += 8; break; case D_EVENT_TRACE : argsize += sizeof( trace_t ) + MAX_STRING_LEN + sizeof( bool ); + argsize_64 += 249; break; default : @@ -973,7 +986,9 @@ void idEvent::Restore( idRestoreGame* savefile ) // RB: for missing D_EVENT_STRING idStr s; // RB end - + bool convertFrom32Bit = false; + bool convertFrom64Bit = false; + savefile->ReadInt( num ); for( i = 0; i < num; i++ ) @@ -1011,15 +1026,26 @@ void idEvent::Restore( idRestoreGame* savefile ) // read the args savefile->ReadInt( argsize ); - if( argsize != ( int )event->eventdef->GetArgSize() ) + if( argsize != (int)event->eventdef->GetArgSize() ) { +#if defined(__x86_64__) || defined(_WIN64) + // Carl: loading 32 bit file on 64 bit + if( argsize == event->eventdef->argsize_32 ) + convertFrom32Bit = true; + else +#else + // Carl: loading 64 bit file on 32 bit + if( argsize == event->eventdef->argsize_64 ) + convertFrom64Bit = true; + else +#endif // RB: fixed wrong formatting // Carl: fixed RB's wrong formatting - savefile->Error( "idEvent::Restore: arg size (%d) doesn't match saved arg size(%d) on event '%s'", (int)event->eventdef->GetArgSize(), (int)argsize, event->eventdef->GetName() ); + savefile->Error( "idEvent::Restore: arg size (%d) doesn't match saved arg size(%d) on event '%s'", (int)event->eventdef->GetArgSize(), (int)argsize, event->eventdef->GetName() ); // RB end } if( argsize ) { - event->data = eventDataAllocator.Alloc( argsize ); + event->data = eventDataAllocator.Alloc( (int)event->eventdef->GetArgSize() ); format = event->eventdef->GetArgFormat(); assert( format ); for( j = 0, size = 0; j < event->eventdef->GetNumArgs(); ++j ) @@ -1083,7 +1109,7 @@ void idEvent::Restore( idRestoreGame* savefile ) break; } } - assert( size == ( int )event->eventdef->GetArgSize() ); + //assert( size == ( int )event->eventdef->GetArgSize() ); } else { @@ -1129,14 +1155,96 @@ void idEvent::Restore( idRestoreGame* savefile ) // read the args savefile->ReadInt( argsize ); - if( argsize != ( int )event->eventdef->GetArgSize() ) +#if defined(__x86_64__) || defined(_WIN64) + // Carl: loading 32 bit file on 64 bit + if( argsize == event->eventdef->argsize_32 ) + convertFrom32Bit = true; + else +#else + // Carl: loading 64 bit file on 32 bit + if( argsize == event->eventdef->argsize_64 ) + convertFrom64Bit = true; + else +#endif + if( argsize != (int)event->eventdef->GetArgSize() ) { - savefile->Error( "idEvent::Restore: arg size (%d) doesn't match saved arg size(%d) on event '%s'", event->eventdef->GetArgSize(), argsize, event->eventdef->GetName() ); + savefile->Error( "idEvent::Restore(2): arg size (%d) doesn't match saved arg size(%d) on event '%s'", (int)event->eventdef->GetArgSize(), (int)argsize, event->eventdef->GetName() ); } if( argsize ) { - event->data = eventDataAllocator.Alloc( argsize ); - savefile->Read( event->data, argsize ); + event->data = eventDataAllocator.Alloc( (int)event->eventdef->GetArgSize() ); + if( convertFrom32Bit ) + { + // Normally, we just read the entire parameter list straight into memory, which means everything is little-endian, + // which is why we use raw Read(ptr, size) methods. + format = event->eventdef->GetArgFormat(); + for( j = 0, size = 0; j < event->eventdef->GetNumArgs(); ++j ) + { + dataPtr = &event->data[event->eventdef->GetArgOffset( j )]; + switch( format[j] ) + { + case D_EVENT_FLOAT: + case D_EVENT_INTEGER: + case D_EVENT_ENTITY: + case D_EVENT_ENTITY_NULL: + savefile->Read( reinterpret_cast(dataPtr), 4 ); + break; + case D_EVENT_VECTOR: + savefile->Read( reinterpret_cast(dataPtr), 12 ); + break; + case D_EVENT_STRING: + savefile->Read( reinterpret_cast(dataPtr), 128 ); + break; + case D_EVENT_TRACE: + savefile->ReadBool( *reinterpret_cast(dataPtr) ); + //trace_t& t = *reinterpret_cast(dataPtr + sizeof( bool )); // todo: make sure the size matches + savefile->Read( reinterpret_cast(dataPtr + 1), 120 ); + savefile->Read( reinterpret_cast(dataPtr + 1 + 120 ), 128 ); + break; + default: + break; + } + } + + } + else if( convertFrom64Bit ) + { + int32 temp; + format = event->eventdef->GetArgFormat(); + for( j = 0, size = 0; j < event->eventdef->GetNumArgs(); ++j ) + { + dataPtr = &event->data[event->eventdef->GetArgOffset( j )]; + switch( format[j] ) + { + case D_EVENT_FLOAT: + case D_EVENT_INTEGER: + case D_EVENT_ENTITY: + case D_EVENT_ENTITY_NULL: + savefile->Read( reinterpret_cast(dataPtr), 4 ); + savefile->ReadInt( temp ); + break; + case D_EVENT_VECTOR: + savefile->Read( reinterpret_cast(dataPtr), 12 ); + savefile->ReadInt( temp ); + break; + case D_EVENT_STRING: + savefile->Read( reinterpret_cast(dataPtr), 128 ); + break; + case D_EVENT_TRACE: + savefile->ReadBool( *reinterpret_cast(dataPtr) ); + //trace_t& t = *reinterpret_cast(dataPtr + sizeof( bool )); // todo: make sure the size matches + savefile->Read( reinterpret_cast(dataPtr + 1), 120 ); + savefile->Read( reinterpret_cast(dataPtr + 1 + 120), 128 ); + break; + default: + break; + } + } + } + else + { + savefile->Read( event->data, argsize ); + } } else { diff --git a/neo/d3xp/gamesys/Event.h b/neo/d3xp/gamesys/Event.h index a306832dc..282caa5d1 100644 --- a/neo/d3xp/gamesys/Event.h +++ b/neo/d3xp/gamesys/Event.h @@ -64,8 +64,11 @@ class idEventDef unsigned int formatspecIndex; int returnType; int numargs; - size_t argsize; +public: + size_t argsize, argsize_32, argsize_64; int argOffset[ D_EVENT_MAXARGS ]; + int argOffset2[ D_EVENT_MAXARGS ]; +private: int eventnum; const idEventDef* next; @@ -83,7 +86,8 @@ class idEventDef int GetNumArgs() const; size_t GetArgSize() const; int GetArgOffset( int arg ) const; - + int GetArgOffset2( int arg ) const; + static int NumEventCommands(); static const idEventDef* GetEventCommand( int eventnum ); static const idEventDef* FindEvent( const char* name ); @@ -216,6 +220,17 @@ ID_INLINE int idEventDef::GetArgOffset( int arg ) const return argOffset[ arg ]; } +/* +================ +idEventDef::GetArgOffset2 +================ +*/ +ID_INLINE int idEventDef::GetArgOffset2(int arg) const +{ + assert((arg >= 0) && (arg < D_EVENT_MAXARGS)); + return argOffset2[arg]; +} + /* ================ idEventDef::GetEventNum From 2e7abd6d5b0457651e3ec2aedf31e6a006a20f86 Mon Sep 17 00:00:00 2001 From: CarlKenner Date: Tue, 21 May 2019 18:06:26 +0930 Subject: [PATCH 09/15] Fix loading events with Trace arguments. --- neo/d3xp/gamesys/Event.cpp | 118 ++++++++++++++++++++++++++++++------- neo/d3xp/gamesys/Event.h | 29 ++++----- 2 files changed, 110 insertions(+), 37 deletions(-) diff --git a/neo/d3xp/gamesys/Event.cpp b/neo/d3xp/gamesys/Event.cpp index 0a92d92b0..44bf5d9a3 100644 --- a/neo/d3xp/gamesys/Event.cpp +++ b/neo/d3xp/gamesys/Event.cpp @@ -79,7 +79,7 @@ idEventDef::idEventDef( const char* command, const char* formatspec, char return this->formatspec = formatspec; this->returnType = returnType; - numargs = strlen( formatspec ); + numargs = (int)strlen( formatspec ); assert( numargs <= D_EVENT_MAXARGS ); if( numargs > D_EVENT_MAXARGS ) { @@ -91,17 +91,15 @@ idEventDef::idEventDef( const char* command, const char* formatspec, char return // make sure the format for the args is valid, calculate the formatspecindex, and the offsets for each arg bits = 0; argsize = 0; +#ifdef IS64BIT argsize_32 = 0; +#else argsize_64 = 0; +#endif memset( argOffset, 0, sizeof( argOffset ) ); for( i = 0; i < numargs; i++ ) { - argOffset[ i ] = argsize; -#if defined(__x86_64__) || defined(_WIN64) - argOffset2[ i ] = argsize_32; -#else - argOffset2[ i ] = argsize_64; -#endif + argOffset[ i ] = (int)argsize; switch (formatspec[i]) { case D_EVENT_FLOAT : @@ -109,30 +107,42 @@ idEventDef::idEventDef( const char* command, const char* formatspec, char return // RB: 64 bit fix, changed sizeof( float ) to sizeof( intptr_t ) argsize += sizeof( intptr_t ); // RB end +#ifdef IS64BIT argsize_32 += 4; +#else argsize_64 += 8; +#endif break; case D_EVENT_INTEGER : // RB: 64 bit fix, changed sizeof( int ) to sizeof( intptr_t ) argsize += sizeof( intptr_t ); // RB end +#ifdef IS64BIT argsize_32 += 4; +#else argsize_64 += 8; +#endif break; case D_EVENT_VECTOR : // RB: 64 bit fix, changed sizeof( idVec3 ) to E_EVENT_SIZEOF_VEC argsize += E_EVENT_SIZEOF_VEC; // RB end +#ifdef IS64BIT argsize_32 += 12; +#else argsize_64 += 16; +#endif break; case D_EVENT_STRING : argsize += MAX_STRING_LEN; +#ifdef IS64BIT argsize_32 += MAX_STRING_LEN; +#else argsize_64 += MAX_STRING_LEN; +#endif break; case D_EVENT_ENTITY : @@ -140,14 +150,40 @@ idEventDef::idEventDef( const char* command, const char* formatspec, char return // RB: 64 bit fix, sizeof( idEntityPtr ) to sizeof( intptr_t ) argsize += sizeof( intptr_t ); // RB end +#ifdef IS64BIT argsize_32 += 4; +#else argsize_64 += 8; +#endif break; case D_EVENT_TRACE : + { + // Carl Debug +#if 0 + trace_t t; + size_t a = (char*)&t.endpos - (char*)&t; // 4 // 4 + size_t b = (char*)&t.endAxis - (char*)&t; // 16 // 16 + size_t c = (char*)&t.c - (char*)&t; // 52 // 56 + size_t d = (char*)&t.c.point - (char*)&t; // 56 // 60 + size_t e = (char*)&t.c.normal - (char*)&t; // 68 // 72 + size_t f = (char*)&t.c.dist - (char*)&t; // 80 // 84 + size_t g = (char*)&t.c.contents - (char*)&t; // 84 // 88 + size_t h = (char*)&t.c.material - (char*)&t; // 88 // 96 + size_t i = (char*)&t.c.modelFeature - (char*)&t; // 92 // 104 + size_t j = (char*)&t.c.id - (char*)&t; // 104 // 116 + size_t s = sizeof( t.c ); // 56 // 64 + size_t s2 = sizeof( t.c.material ); // 4 // 8 +#endif + argsize += sizeof( trace_t ) + MAX_STRING_LEN + sizeof( bool ); - argsize_64 += 249; +#ifdef IS64BIT + argsize_32 += 1 + 108 + 128; +#else + argsize_64 += 1 + 120 + 128; +#endif break; + } default : eventError = true; @@ -305,7 +341,7 @@ idEvent* idEvent::Alloc( const idEventDef* evdef, int numargs, va_list args ) size = evdef->GetArgSize(); if( size ) { - ev->data = eventDataAllocator.Alloc( size ); + ev->data = eventDataAllocator.Alloc( (int)size ); memset( ev->data, 0, size ); } else @@ -885,7 +921,7 @@ void idEvent::Save( idSaveGame* savefile ) savefile->WriteString( event->eventdef->GetName() ); savefile->WriteString( event->typeinfo->classname ); savefile->WriteObject( event->object ); - savefile->WriteInt( event->eventdef->GetArgSize() ); + savefile->WriteInt( (int)event->eventdef->GetArgSize() ); format = event->eventdef->GetArgFormat(); for( i = 0, size = 0; i < event->eventdef->GetNumArgs(); ++i ) { @@ -963,8 +999,8 @@ void idEvent::Save( idSaveGame* savefile ) savefile->WriteString( event->eventdef->GetName() ); savefile->WriteString( event->typeinfo->classname ); savefile->WriteObject( event->object ); - savefile->WriteInt( event->eventdef->GetArgSize() ); - savefile->Write( event->data, event->eventdef->GetArgSize() ); + savefile->WriteInt( (int)event->eventdef->GetArgSize() ); + savefile->Write( event->data, (int)event->eventdef->GetArgSize() ); event = event->eventNode.Next(); } @@ -1028,7 +1064,7 @@ void idEvent::Restore( idRestoreGame* savefile ) savefile->ReadInt( argsize ); if( argsize != (int)event->eventdef->GetArgSize() ) { -#if defined(__x86_64__) || defined(_WIN64) +#ifdef IS64BIT // Carl: loading 32 bit file on 64 bit if( argsize == event->eventdef->argsize_32 ) convertFrom32Bit = true; @@ -1155,7 +1191,7 @@ void idEvent::Restore( idRestoreGame* savefile ) // read the args savefile->ReadInt( argsize ); -#if defined(__x86_64__) || defined(_WIN64) +#ifdef IS64BIT // Carl: loading 32 bit file on 64 bit if( argsize == event->eventdef->argsize_32 ) convertFrom32Bit = true; @@ -1173,6 +1209,7 @@ void idEvent::Restore( idRestoreGame* savefile ) if( argsize ) { event->data = eventDataAllocator.Alloc( (int)event->eventdef->GetArgSize() ); +#ifdef IS64BIT if( convertFrom32Bit ) { // Normally, we just read the entire parameter list straight into memory, which means everything is little-endian, @@ -1196,18 +1233,33 @@ void idEvent::Restore( idRestoreGame* savefile ) savefile->Read( reinterpret_cast(dataPtr), 128 ); break; case D_EVENT_TRACE: + { savefile->ReadBool( *reinterpret_cast(dataPtr) ); - //trace_t& t = *reinterpret_cast(dataPtr + sizeof( bool )); // todo: make sure the size matches - savefile->Read( reinterpret_cast(dataPtr + 1), 120 ); - savefile->Read( reinterpret_cast(dataPtr + 1 + 120 ), 128 ); + trace_t& t = *reinterpret_cast(dataPtr + sizeof( bool )); + memset( &t, 0, sizeof( t ) ); + savefile->Read( reinterpret_cast(&t), 4 ); + savefile->Read( reinterpret_cast(&t.endpos), 3 * 4 ); + savefile->Read( reinterpret_cast(&t.endAxis), 9 * 4 ); + savefile->Read( reinterpret_cast(&t.c), 4 ); + savefile->Read( reinterpret_cast(&t.c.point), 3 * 4 ); + savefile->Read( reinterpret_cast(&t.c.normal), 3 * 4 ); + savefile->Read( reinterpret_cast(&t.c.dist), 4 ); + savefile->Read( reinterpret_cast(&t.c.contents), 4 ); + // Carl: We are loading a 4-byte pointer into an 8-byte slot, but we only care if it's NULL or not. + // The fast event queue never uses the material pointer directly, it just checks if it's NULL. + savefile->Read( reinterpret_cast(&t.c.material), 4 ); + savefile->Read( reinterpret_cast(&t.c.modelFeature), 4 * 4 ); + savefile->Read( reinterpret_cast(dataPtr + 1 + 120), 128 ); break; + } default: break; } } } - else if( convertFrom64Bit ) +#else + if( convertFrom64Bit ) { int32 temp; format = event->eventdef->GetArgFormat(); @@ -1231,16 +1283,40 @@ void idEvent::Restore( idRestoreGame* savefile ) savefile->Read( reinterpret_cast(dataPtr), 128 ); break; case D_EVENT_TRACE: + { savefile->ReadBool( *reinterpret_cast(dataPtr) ); - //trace_t& t = *reinterpret_cast(dataPtr + sizeof( bool )); // todo: make sure the size matches - savefile->Read( reinterpret_cast(dataPtr + 1), 120 ); - savefile->Read( reinterpret_cast(dataPtr + 1 + 120), 128 ); + trace_t& t = *reinterpret_cast(dataPtr + sizeof( bool )); + memset( &t, 0, sizeof( t ) ); + savefile->Read( reinterpret_cast(&t), 4 ); + savefile->Read( reinterpret_cast(&t.endpos), 3 * 4 ); + savefile->Read( reinterpret_cast(&t.endAxis), 9 * 4 ); + int32 padding; + savefile->ReadInt( padding ); // There were 4 bytes of padding here on 64 bit + savefile->Read( reinterpret_cast(&t.c), 4 ); + savefile->Read( reinterpret_cast(&t.c.point), 3 * 4 ); + savefile->Read( reinterpret_cast(&t.c.normal), 3 * 4 ); + savefile->Read( reinterpret_cast(&t.c.dist), 4 ); + savefile->Read( reinterpret_cast(&t.c.contents), 4 ); + savefile->ReadInt( padding ); // t.c.contents was 8 bytes long on 64 bit + // Carl: In the fast event queue, material is NOT a real pointer. + // We only care whether the whole 8 saved bytes of material are NULL, which means our 4-byte pointer must be NULL, + // or if either part of the 8 bytes is not null, then our 4-byte pointer must be not NULL. + savefile->Read( reinterpret_cast(&t.c.material), 4 ); + if( t.c.material == NULL ) + savefile->Read( reinterpret_cast(&t.c.material), 4 ); // overwrite our NULL in case the other half isn't NULL + else + savefile->ReadInt( padding ); // Don't overwrite our non-null 4-bytes with something that might be NULL + savefile->Read( reinterpret_cast(&t.c.modelFeature), 4 * 4 ); + savefile->Read( reinterpret_cast(dataPtr + 1 + 108), 128 ); + break; + } break; default: break; } } } +#endif else { savefile->Read( event->data, argsize ); diff --git a/neo/d3xp/gamesys/Event.h b/neo/d3xp/gamesys/Event.h index 282caa5d1..aea7820e2 100644 --- a/neo/d3xp/gamesys/Event.h +++ b/neo/d3xp/gamesys/Event.h @@ -34,11 +34,17 @@ Event are used for scheduling tasks and for linking script commands. #ifndef __SYS_EVENT_H__ #define __SYS_EVENT_H__ +// Carl: For loading 32bit saved games on 64bit and vice versa +#if defined(__x86_64__) || defined(_WIN64) +#define IS64BIT +#endif + #define D_EVENT_MAXARGS 8 // if changed, enable the CREATE_EVENT_CODE define in Event.cpp to generate switch statement for idClass::ProcessEventArgPtr. // running the game will then generate c:\doom\base\events.txt, the contents of which should be copied into the switch statement. // RB: from dhewm3 // stack size of idVec3, aligned to native pointer size +// Carl: This is 12 on 32-bit and 16 on 64-bit #define E_EVENT_SIZEOF_VEC ((sizeof(idVec3) + (sizeof(intptr_t) - 1)) & ~(sizeof(intptr_t) - 1)) // RB end @@ -64,11 +70,13 @@ class idEventDef unsigned int formatspecIndex; int returnType; int numargs; -public: - size_t argsize, argsize_32, argsize_64; + size_t argsize; +#ifdef IS64BIT + size_t argsize_32; +#else + size_t argsize_64; +#endif int argOffset[ D_EVENT_MAXARGS ]; - int argOffset2[ D_EVENT_MAXARGS ]; -private: int eventnum; const idEventDef* next; @@ -86,11 +94,11 @@ class idEventDef int GetNumArgs() const; size_t GetArgSize() const; int GetArgOffset( int arg ) const; - int GetArgOffset2( int arg ) const; static int NumEventCommands(); static const idEventDef* GetEventCommand( int eventnum ); static const idEventDef* FindEvent( const char* name ); + friend class idEvent; }; class idSaveGame; @@ -220,17 +228,6 @@ ID_INLINE int idEventDef::GetArgOffset( int arg ) const return argOffset[ arg ]; } -/* -================ -idEventDef::GetArgOffset2 -================ -*/ -ID_INLINE int idEventDef::GetArgOffset2(int arg) const -{ - assert((arg >= 0) && (arg < D_EVENT_MAXARGS)); - return argOffset2[arg]; -} - /* ================ idEventDef::GetEventNum From d1e721d2c4f594b51270cf292ac6e25fb90e3f4c Mon Sep 17 00:00:00 2001 From: CarlKenner Date: Tue, 21 May 2019 18:07:42 +0930 Subject: [PATCH 10/15] Fix loading games from other mods with extra _light entities. --- neo/d3xp/Game_local.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/neo/d3xp/Game_local.cpp b/neo/d3xp/Game_local.cpp index 690191d29..d235c006e 100644 --- a/neo/d3xp/Game_local.cpp +++ b/neo/d3xp/Game_local.cpp @@ -4153,9 +4153,26 @@ void idGameLocal::AddEntityToHash( const char* name, idEntity* ent ) { if( FindEntity( name ) ) { - Error( "Multiple entities named '%s'", name ); + // Carl: When loading saved games from other mods, we sometimes need to reset scripts. + // The reset scripts for some monsters end up creating a _light entity that was already created. + // For now, handle that by renaming the duplicate then deleting it. + // This mostly happens with Erebus levels. + idStr n( name ); + if( n.Right( 6 ) == "_light" ) + { + n = n + '2'; + entityHash.Add( entityHash.GenerateKey( n.c_str(), true ), ent->entityNumber ); + ent->PostEventMS( &EV_Remove, 0 ); + } + else + { + Error( "Multiple entities named '%s'", name ); + } + } + else + { + entityHash.Add( entityHash.GenerateKey( name, true ), ent->entityNumber ); } - entityHash.Add( entityHash.GenerateKey( name, true ), ent->entityNumber ); } /* From 54e10de0bc070120be21c02e97f62e063d31950e Mon Sep 17 00:00:00 2001 From: CarlKenner Date: Wed, 22 May 2019 15:16:53 +0930 Subject: [PATCH 11/15] Fix serious view-height bug when not in VR (which made it unplayable). Also add some commented-out debugging for view position. And fix the size_t warnings in console.cpp (the strings we display are always less than 2GB long). --- neo/d3xp/Actor.h | 4 ++-- neo/d3xp/Player.cpp | 13 ++++++++++- neo/framework/Console.cpp | 48 +++++++++++++++++++++++++++++++-------- 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/neo/d3xp/Actor.h b/neo/d3xp/Actor.h index c5f88eb40..f7e44d24c 100644 --- a/neo/d3xp/Actor.h +++ b/neo/d3xp/Actor.h @@ -120,7 +120,8 @@ class idActor : public idAFEntity_Gibbable idLinkList enemyNode; // node linked into an entity's enemy list for quick lookups of who is attacking him idLinkList enemyList; // list of characters that have targeted the player as their enemy - + friend class idConsoleLocal; + public: idActor(); virtual ~idActor(); @@ -302,7 +303,6 @@ class idActor : public idAFEntity_Gibbable void SetupHead(); public: void PlayFootStepSound(); - private: void Event_EnableEyeFocus(); void Event_DisableEyeFocus(); diff --git a/neo/d3xp/Player.cpp b/neo/d3xp/Player.cpp index 0964b952e..fcd6d893c 100644 --- a/neo/d3xp/Player.cpp +++ b/neo/d3xp/Player.cpp @@ -18299,7 +18299,7 @@ void idPlayer::CalculateRenderView() cineYawOffset = 0.0f; } - + // if we're not in a projected cutscene if (!(gameLocal.inCinematic && vr_cinematics.GetInteger() == 2 && vr_flicksyncCharacter.GetInteger() == 0)) { @@ -18461,6 +18461,17 @@ void idPlayer::CalculateRenderView() } } + else // Carl: not VR + { + idVec3 origin = renderView->vieworg; + // if we're not in a cutscene + if( !gameLocal.inCinematic ) + { + // Used to force the user's head down when there's a low ceiling + commonVr->uncrouchedHMDViewOrigin = origin; + commonVr->uncrouchedHMDViewOrigin.z -= commonVr->headHeightDiff; + } + } } /* diff --git a/neo/framework/Console.cpp b/neo/framework/Console.cpp index 43503bc76..fbe0d71a0 100644 --- a/neo/framework/Console.cpp +++ b/neo/framework/Console.cpp @@ -254,7 +254,7 @@ float idConsoleLocal::DrawFPS( float y ) fps = ( fps + 500 ) / 1000; const char* s = va( "%ifps", fps ); - int w = strlen( s ) * BIGCHAR_WIDTH; + int w = (int)strlen( s ) * BIGCHAR_WIDTH; renderSystem->DrawBigStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, s, colorWhite, true ); } @@ -263,7 +263,35 @@ float idConsoleLocal::DrawFPS( float y ) // DG: "com_showFPS 2" means: show FPS only, like in classic doom3 if( com_showFPS.GetInteger() == 2 ) - { + { +#if 0 + if( gameLocal.GetLocalPlayer() && gameLocal.GetLocalPlayer()->GetPhysics() ) + { + idPlayer* player = gameLocal.GetLocalPlayer(); + y += SMALLCHAR_HEIGHT + 4; + idStr s; + s.Format( "%d %d %d", (int)player->GetPhysics()->GetOrigin().x, (int)player->GetPhysics()->GetOrigin().y, (int)player->GetPhysics()->GetOrigin().z ); + int w = s.LengthWithoutColors() * SMALLCHAR_WIDTH; + renderSystem->DrawSmallStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, s.c_str(), colorYellow, false ); + y += SMALLCHAR_HEIGHT + 4; + s.Format( "%d %d %d", (int)player->firstPersonViewOrigin.x, (int)player->firstPersonViewOrigin.y, (int)player->firstPersonViewOrigin.z ); + w = s.LengthWithoutColors() * SMALLCHAR_WIDTH; + renderSystem->DrawSmallStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, s.c_str(), colorGreen, false ); + y += SMALLCHAR_HEIGHT + 4; + s.Format( "%d", (int)(player->firstPersonViewOrigin.z - player->GetPhysics()->GetOrigin().z ) ); + w = s.LengthWithoutColors() * SMALLCHAR_WIDTH; + renderSystem->DrawSmallStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, s.c_str(), colorRed, false ); + y += SMALLCHAR_HEIGHT + 4; + s.Format( "%d %d %d", (int)player->eyeOffset.x, (int)player->eyeOffset.y, (int)player->eyeOffset.z ); + w = s.LengthWithoutColors() * SMALLCHAR_WIDTH; + renderSystem->DrawSmallStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, s.c_str(), colorBlue, false ); + y += SMALLCHAR_HEIGHT + 4; + s.Format( "%d", (int)commonVr->headHeightDiff ); + w = s.LengthWithoutColors() * SMALLCHAR_WIDTH; + renderSystem->DrawSmallStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, s.c_str(), colorCyan, false ); + y += SMALLCHAR_HEIGHT + 4; + } +#endif return y; } // DG end @@ -349,7 +377,7 @@ void idConsoleLocal::DrawFlicksync( float& leftY, float& centerY ) if ( inFlicksync ) { const char* s = va("SCORE: %i", Flicksync_Score); - int w = strlen(s) * BIGCHAR_WIDTH; + int w = (int)strlen(s) * BIGCHAR_WIDTH; renderSystem->DrawBigStringExt(LOCALSAFE_LEFT + (LOCALSAFE_WIDTH - w + 4) * 0.5f, idMath::Ftoi(centerY) + 2, s, colorWhite, true); centerY += BIGCHAR_HEIGHT + 4; } @@ -358,7 +386,7 @@ void idConsoleLocal::DrawFlicksync( float& leftY, float& centerY ) // Make score less intrusive during normal play between cutscenes idVec4 color = idVec4( 0.5f, 0.5f, 0.5f, 0.5f ); const char* s = va("%i", Flicksync_Score); - int w = strlen(s) * SMALLCHAR_WIDTH; + int w = (int)strlen(s) * SMALLCHAR_WIDTH; renderSystem->DrawSmallStringExt(LOCALSAFE_LEFT + (LOCALSAFE_WIDTH - w + 4) * 0.5f, idMath::Ftoi(centerY) + 2, s, colorWhite, true); centerY += SMALLCHAR_HEIGHT + 4; } @@ -372,14 +400,14 @@ void idConsoleLocal::DrawFlicksync( float& leftY, float& centerY ) if (Flicksync_complete) { const char* s = "FLICKSYNC COMPLETE"; - int w = strlen(s) * BIGCHAR_WIDTH; + int w = (int)strlen(s) * BIGCHAR_WIDTH; renderSystem->DrawBigStringExt(LOCALSAFE_LEFT + (LOCALSAFE_WIDTH - w + 4) * 0.5f, idMath::Ftoi(centerY) + 2, s, colorGreen, true); centerY += BIGCHAR_HEIGHT + 4; } else if (Flicksync_GameOver) { const char* s = "GAME OVER"; - int w = strlen(s) * BIGCHAR_WIDTH; + int w = (int)strlen(s) * BIGCHAR_WIDTH; renderSystem->DrawBigStringExt(LOCALSAFE_LEFT + (LOCALSAFE_WIDTH - w + 4) * 0.5f, idMath::Ftoi(centerY) + 2, s, colorRed, true); centerY += BIGCHAR_HEIGHT + 4; } @@ -402,7 +430,7 @@ void idConsoleLocal::DrawFlicksync( float& leftY, float& centerY ) if (Flicksync_FailsInARow == 2) { const char* s = "FINAL WARNING"; - int w = strlen(s) * BIGCHAR_WIDTH; + int w = (int)strlen(s) * BIGCHAR_WIDTH; renderSystem->DrawBigStringExt(LOCALSAFE_LEFT + (LOCALSAFE_WIDTH - w + 4) * 0.5f, idMath::Ftoi(centerY) + 2, s, color, true); centerY += BIGCHAR_HEIGHT + 4; } @@ -472,7 +500,7 @@ void idConsoleLocal::DrawFlicksync( float& leftY, float& centerY ) } { const char* s = "FINAL DIALOGUE WARNING!"; - int w = strlen(s) * SMALLCHAR_WIDTH; + int w = (int)strlen(s) * SMALLCHAR_WIDTH; static int flash = 0; flash++; if (flash > 20) @@ -853,7 +881,7 @@ void idConsoleLocal::Dump( const char* fileName ) buffer[x + 1] = '\r'; buffer[x + 2] = '\n'; buffer[x + 3] = 0; - f->Write( buffer, strlen( buffer ) ); + f->Write( buffer, (int)strlen( buffer ) ); } fileSystem->CloseFile( f ); @@ -1385,7 +1413,7 @@ void idConsoleLocal::DrawInput() if( consoleField.GetAutoCompleteLength() != 0 ) { - autoCompleteLength = strlen( consoleField.GetBuffer() ) - consoleField.GetAutoCompleteLength(); + autoCompleteLength = (int)strlen( consoleField.GetBuffer() ) - consoleField.GetAutoCompleteLength(); if( autoCompleteLength > 0 ) { From 32a0e8562b26a447c68532302c3bbd35dcceddca Mon Sep 17 00:00:00 2001 From: CarlKenner Date: Wed, 22 May 2019 15:52:28 +0930 Subject: [PATCH 12/15] Fix mouse pitch when not in VR. --- neo/framework/UsercmdGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neo/framework/UsercmdGen.cpp b/neo/framework/UsercmdGen.cpp index ad453936d..4673450c7 100644 --- a/neo/framework/UsercmdGen.cpp +++ b/neo/framework/UsercmdGen.cpp @@ -603,7 +603,7 @@ void idUsercmdGenLocal::MouseMove() pitchdelta = m_pitch.GetFloat() * in_mouseSpeed.GetFloat() * (in_mouseInvertLook.GetBool() ? -my : my); // Koz begin add mouse control here - if ( vr_enable.GetBool() ) + if( commonVr->hasHMD && vr_enable.GetBool() ) { // update the independent weapon angles and return any view changes based on current aim mode commonVr->CalcAimMove( yawdelta, pitchdelta ); From 7cbdd5ebe3039808317212a81784d0bda5746d88 Mon Sep 17 00:00:00 2001 From: CarlKenner Date: Thu, 23 May 2019 15:12:26 +0930 Subject: [PATCH 13/15] Fix crash in 3D options menu (also crashes in steam version). --- neo/d3xp/menus/MenuScreen_Shell_Stereoscopics.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/neo/d3xp/menus/MenuScreen_Shell_Stereoscopics.cpp b/neo/d3xp/menus/MenuScreen_Shell_Stereoscopics.cpp index 9c46b5828..d72dcb235 100644 --- a/neo/d3xp/menus/MenuScreen_Shell_Stereoscopics.cpp +++ b/neo/d3xp/menus/MenuScreen_Shell_Stereoscopics.cpp @@ -42,7 +42,11 @@ static const char* stereoRender_enable_text[] = "#str_swf_stereo_top_and_bottom", "#str_swf_stereo_side_by_side_full", "#str_swf_stereo_interlaced", - "#str_swf_stereo_quad" + "#str_swf_stereo_quad", + "STEREO3D_HDMI_720", + "STEREO3D_HMD", + "8", + "9" }; static const int NUM_STEREO_ENABLE = sizeof( stereoRender_enable_text ) / sizeof( stereoRender_enable_text[0] ); From 6803c249955ae205881abb705f20d06cad20e4cf Mon Sep 17 00:00:00 2001 From: CarlKenner Date: Thu, 23 May 2019 15:22:03 +0930 Subject: [PATCH 14/15] Fix showing weapon hand and body when not in VR. For now, always draw the laser sight if enabled in the options. Fix bug calling CalculateHideRise for both hands. Fix some warnings about size_t. Add commented out debugging in console. --- neo/d3xp/Player.cpp | 16 +++++++-------- neo/d3xp/Weapon.cpp | 6 +++--- neo/framework/Console.cpp | 43 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/neo/d3xp/Player.cpp b/neo/d3xp/Player.cpp index fcd6d893c..5b10eb374 100644 --- a/neo/d3xp/Player.cpp +++ b/neo/d3xp/Player.cpp @@ -1073,7 +1073,7 @@ bool idInventory::Give( idPlayer* owner, const idDict& spawnArgs, const char* st } else { - len = strlen( pos ); + len = (int)strlen( pos ); } idStr weaponName( pos, 0, len ); @@ -1364,7 +1364,7 @@ void idInventory::InitRechargeAmmo( idPlayer* owner ) while( kv ) { idStr key = kv->GetKey(); - idStr ammoname = key.Right( key.Length() - strlen( "ammorecharge_" ) ); + idStr ammoname = key.Right( key.Length() - (int)strlen( "ammorecharge_" ) ); int ammoType = AmmoIndexForAmmoClass( ammoname ); rechargeAmmo[ammoType].ammo = ( atof( kv->GetValue().c_str() ) * 1000 ); strcpy( rechargeAmmo[ammoType].ammoName, ammoname ); @@ -13507,7 +13507,7 @@ void idPlayer::UpdateLaserSight( int hand ) showTeleport = showTeleport && !AI_DEAD && !gameLocal.inCinematic && !Flicksync_InCutscene && !game->IsPDAOpen(); // check if lasersight should be hidden - if ( !IsGameStereoRendered() || + if ( //!IsGameStereoRendered() || !hands[hand].laserSightActive || // Koz allow user to toggle lasersight. sightMode == -1 || !weapon->ShowCrosshair() || @@ -13590,7 +13590,7 @@ void idPlayer::UpdateLaserSight( int hand ) hands[hand].laserSightRenderEntity.shaderParms[SHADERPARM_BEAM_WIDTH] = g_laserSightWidth.GetFloat(); - if ( IsGameStereoRendered() && hands[hand].laserSightHandle == -1 ) + if ( /*IsGameStereoRendered() &&*/ hands[hand].laserSightHandle == -1 ) { hands[hand].laserSightHandle = gameRenderWorld->AddEntityDef( &hands[hand].laserSightRenderEntity ); } @@ -13744,7 +13744,7 @@ void idPlayer::UpdateLaserSight( int hand ) } oldTeleport = showTeleport; - if ( IsGameStereoRendered() && hands[hand].crosshairHandle == -1 ) + if ( /*IsGameStereoRendered() &&*/ hands[hand].crosshairHandle == -1 ) { hands[hand].crosshairHandle = gameRenderWorld->AddEntityDef( &hands[hand].crosshairEntity ); } @@ -16748,7 +16748,7 @@ Calculate the bobbing position of the view weapon void idPlayer::CalculateViewWeaponPos( int hand, idVec3& origin, idMat3& axis ) { - if ( game->isVR ) + if ( game->isVR || true ) { CalculateViewWeaponPosVR( hand, origin, axis ); return; @@ -16822,9 +16822,7 @@ void idPlayer::CalculateViewWeaponPos( int hand, idVec3& origin, idMat3& axis ) axis = scaledMat * viewAxis; - for( int h = 0; h < 2; h++ ) - hands[ h ].weapon->CalculateHideRise( origin, axis ); // Koz - + hands[ hand ].weapon->CalculateHideRise( origin, axis ); // Koz } void DebugCross( idVec3 origin, idMat3 axis, idVec4 color ) diff --git a/neo/d3xp/Weapon.cpp b/neo/d3xp/Weapon.cpp index 5e908a78b..03452a2da 100644 --- a/neo/d3xp/Weapon.cpp +++ b/neo/d3xp/Weapon.cpp @@ -806,7 +806,7 @@ void idWeapon::Restore( idRestoreGame* savefile ) else { // Koz get jointhandles for hand attachers - if (game->isVR) + if (game->isVR || true) { weaponHandAttacher[0] = animator.GetJointHandle("RhandAttacher"); if (weaponHandAttacher[0] != INVALID_JOINT) @@ -1287,7 +1287,7 @@ void idWeapon::GetWeaponDef( const char* objectname, int ammoinclip ) // Koz get jointhandles for hand attachers - if ( game->isVR ) + if ( game->isVR || true ) { weaponHandAttacher[0] = animator.GetJointHandle( "RhandAttacher" ); if ( weaponHandAttacher[0] != INVALID_JOINT ) @@ -3543,7 +3543,7 @@ void idWeapon::PresentWeapon( bool showViewModel, int hand ) // in VR don't suppress drawing the player's body // also show the viewmodel - if ( game->isVR ) + if ( game->isVR || true ) { if ( (hide && disabled) ) // hide the weapon if in a cinematic { diff --git a/neo/framework/Console.cpp b/neo/framework/Console.cpp index fbe0d71a0..e50b1e6f9 100644 --- a/neo/framework/Console.cpp +++ b/neo/framework/Console.cpp @@ -267,11 +267,12 @@ float idConsoleLocal::DrawFPS( float y ) #if 0 if( gameLocal.GetLocalPlayer() && gameLocal.GetLocalPlayer()->GetPhysics() ) { + idStr s; + int w; idPlayer* player = gameLocal.GetLocalPlayer(); y += SMALLCHAR_HEIGHT + 4; - idStr s; s.Format( "%d %d %d", (int)player->GetPhysics()->GetOrigin().x, (int)player->GetPhysics()->GetOrigin().y, (int)player->GetPhysics()->GetOrigin().z ); - int w = s.LengthWithoutColors() * SMALLCHAR_WIDTH; + w = s.LengthWithoutColors() * SMALLCHAR_WIDTH; renderSystem->DrawSmallStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, s.c_str(), colorYellow, false ); y += SMALLCHAR_HEIGHT + 4; s.Format( "%d %d %d", (int)player->firstPersonViewOrigin.x, (int)player->firstPersonViewOrigin.y, (int)player->firstPersonViewOrigin.z ); @@ -291,6 +292,44 @@ float idConsoleLocal::DrawFPS( float y ) renderSystem->DrawSmallStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, s.c_str(), colorCyan, false ); y += SMALLCHAR_HEIGHT + 4; } +#endif +#if 0 + if( gameLocal.GetLocalPlayer() && gameLocal.GetLocalPlayer()->GetPhysics() && gameLocal.GetLocalPlayer()->hands[0].weapon ) + { + idStr s; + int w; + idPlayer* player = gameLocal.GetLocalPlayer(); + idPlayerHand* hand = &player->hands[0]; + idWeapon* weapon = hand->weapon; + y += SMALLCHAR_HEIGHT + 4; + // Red: Head View + s.Format( "eye: %d %d %d", (int)player->firstPersonViewOrigin.x, (int)player->firstPersonViewOrigin.y, (int)player->firstPersonViewOrigin.z ); + w = s.LengthWithoutColors() * SMALLCHAR_WIDTH; + renderSystem->DrawSmallStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, s.c_str(), colorGreen, false ); + y += SMALLCHAR_HEIGHT + 4; + s.Format( "eye: %d %d %d", (int)player->GetEyePosition().x, (int)player->GetEyePosition().y, (int)player->GetEyePosition().z ); + w = s.LengthWithoutColors() * SMALLCHAR_WIDTH; + renderSystem->DrawSmallStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, s.c_str(), colorBlue, false ); + y += SMALLCHAR_HEIGHT + 4; + s.Format( "weap: %d %d %d", (int)weapon->GetPhysics()->GetOrigin().x, (int)weapon->GetPhysics()->GetOrigin().y, (int)weapon->GetPhysics()->GetOrigin().z ); + w = s.LengthWithoutColors() * SMALLCHAR_WIDTH; + renderSystem->DrawSmallStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, s.c_str(), colorYellow, false ); + y += SMALLCHAR_HEIGHT + 4; + s.Format( "hand: %d %d %d", (int)hand->handOrigin.x, (int)hand->handOrigin.y, (int)hand->handOrigin.z ); + w = s.LengthWithoutColors() * SMALLCHAR_WIDTH; + renderSystem->DrawSmallStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, s.c_str(), colorRed, false ); + y += SMALLCHAR_HEIGHT + 4; + /* + s.Format( "%d %d %d", (int)player->eyeOffset.x, (int)player->eyeOffset.y, (int)player->eyeOffset.z ); + w = s.LengthWithoutColors() * SMALLCHAR_WIDTH; + renderSystem->DrawSmallStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, s.c_str(), colorBlue, false ); + y += SMALLCHAR_HEIGHT + 4; + s.Format( "%d", (int)commonVr->headHeightDiff ); + w = s.LengthWithoutColors() * SMALLCHAR_WIDTH; + renderSystem->DrawSmallStringExt( LOCALSAFE_RIGHT - w, idMath::Ftoi( y ) + 2, s.c_str(), colorCyan, false ); + y += SMALLCHAR_HEIGHT + 4; + */ + } #endif return y; } From 343c4ad6943730eef0f0c2325e2549275b6440b7 Mon Sep 17 00:00:00 2001 From: CarlKenner Date: Thu, 23 May 2019 22:27:04 +0930 Subject: [PATCH 15/15] Fix weapon when not in VR, and add independent aiming. New in_independentAim cvar controls independent aiming when not in VR. Known issue: Independent aim outside VR doesn't currently work with GUIs. Note that the flashlight is still glitchy when not in VR. --- neo/d3xp/Player.cpp | 13 ++++++++++++- neo/d3xp/Weapon.cpp | 5 ++++- neo/framework/UsercmdGen.cpp | 24 +++++++++++++++++++----- neo/vr/Vr.cpp | 6 +++--- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/neo/d3xp/Player.cpp b/neo/d3xp/Player.cpp index 5b10eb374..894787b0f 100644 --- a/neo/d3xp/Player.cpp +++ b/neo/d3xp/Player.cpp @@ -110,6 +110,7 @@ idAngles pdaAngle2( 0, 0, 76.5); idAngles pdaAngle3( 0, 0, 0); extern idCVar g_useWeaponDepthHack; +extern idCVar in_independentAim; /* @@ -16954,7 +16955,17 @@ void idPlayer::CalculateViewWeaponPosVR( int hand, idVec3 &origin, idMat3 &axis angQuat = idAngles( commonVr->independentWeaponPitch, commonVr->independentWeaponYaw, 0 ).ToQuat(); idQuat gunAxis = angQuat; - gunAxis *= bodyAxis.ToQuat(); + if( game->isVR || in_independentAim.GetInteger() ) + { + gunAxis *= bodyAxis.ToQuat(); + } + else + { + idMat3 headAxis = idAngles( viewAngles.pitch, viewAngles.yaw, 0.0f ).ToMat3(); + gunAxis *= headAxis.ToQuat(); + commonVr->independentWeaponPitch = 0; + commonVr->independentWeaponYaw = 0; + } newAx = gunAxis.ToMat3(); int flip = vr_weaponHand.GetInteger() == 0 ? 1 : -1; diff --git a/neo/d3xp/Weapon.cpp b/neo/d3xp/Weapon.cpp index 03452a2da..9d7041d65 100644 --- a/neo/d3xp/Weapon.cpp +++ b/neo/d3xp/Weapon.cpp @@ -163,6 +163,7 @@ idCVar g_useWeaponDepthHack( "g_useWeaponDepthHack", "0", CVAR_BOOL | CVAR_GAME idCVar g_weaponShadows( "g_weaponShadows", "1", CVAR_BOOL | CVAR_GAME | CVAR_ARCHIVE, "Cast shadows from weapons" ); // Koz extern idCVar cg_predictedSpawn_debug; +extern idCVar in_independentAim; /*********************************************************************** @@ -4848,7 +4849,8 @@ idWeapon::GetProjectileLaunchOriginAndAxis void idWeapon::GetProjectileLaunchOriginAndAxis( idVec3& origin, idMat3& axis ) { assert( owner != NULL ); - if ( game->isVR ) + // Carl: in VR, or when using independent aim, we fire from the weapon model itself + if( game->isVR || in_independentAim.GetInteger() ) { static weapon_t curWeap = WEAPON_NONE; @@ -4886,6 +4888,7 @@ void idWeapon::GetProjectileLaunchOriginAndAxis( idVec3& origin, idMat3& axis ) return; } + // Carl: When not in VR, we usually fire from our eyes (the centre of the screen) // calculate the muzzle position if( barrelJointView != INVALID_JOINT && projectileDict.GetBool( "launchFromBarrel" ) ) { diff --git a/neo/framework/UsercmdGen.cpp b/neo/framework/UsercmdGen.cpp index 4673450c7..c68d154ff 100644 --- a/neo/framework/UsercmdGen.cpp +++ b/neo/framework/UsercmdGen.cpp @@ -63,6 +63,8 @@ idCVar vr_joyCurves( "vr_joyCurves", "0", CVAR_ARCHIVE | CVAR_INTEGER, "Joy powe idCVar vr_joyCurveSensitivity( "vr_joyCurveSensitivity", "9", CVAR_ARCHIVE | CVAR_FLOAT, "Sensitivity val 0 - 9\n" ); idCVar vr_joyCurveLin( "vr_joyCurveLin", "4", CVAR_ARCHIVE | CVAR_FLOAT, "Linear point for joyCurves\n sens < lin = power curve\n, sens = lin = linear\n, sens > lin = frac power curve.\n" ); +// Carl: Non-VR-mode independent weapon control +idCVar in_independentAim( "in_independentAim", "0", CVAR_ARCHIVE | CVAR_INTEGER, "Independent weapon aim. 0 = normal look/aim, 1 = mouse aims weapon, 2 = keys aim weapon, 3 = both aim weapon", 0, 3 ); /* @@ -477,11 +479,23 @@ void idUsercmdGenLocal::AdjustAngles() if ( !game->isVR ) { - viewangles[YAW] -= speed * in_yawSpeed.GetFloat() * ButtonState( UB_LOOKRIGHT ); - viewangles[YAW] += speed * in_yawSpeed.GetFloat() * ButtonState( UB_LOOKLEFT ); + if( in_independentAim.GetInteger() & 2 ) + { + float yawdelta, pitchdelta; + yawdelta = speed * in_yawSpeed.GetFloat() * ( ButtonState( UB_LOOKLEFT ) - ButtonState( UB_LOOKRIGHT ) ); + pitchdelta = speed * in_pitchSpeed.GetFloat() * ( ButtonState( UB_LOOKDOWN ) - ButtonState( UB_LOOKUP ) ); + commonVr->CalcAimMove( yawdelta, pitchdelta ); // update the independent weapon angles and return any movement changes. + viewangles[YAW] += yawdelta; + viewangles[PITCH] += pitchdelta; + } + else + { + viewangles[YAW] -= speed * in_yawSpeed.GetFloat() * ButtonState( UB_LOOKRIGHT ); + viewangles[YAW] += speed * in_yawSpeed.GetFloat() * ButtonState( UB_LOOKLEFT ); - viewangles[PITCH] -= speed * in_pitchSpeed.GetFloat() * ButtonState( UB_LOOKUP ); - viewangles[PITCH] += speed * in_pitchSpeed.GetFloat() * ButtonState( UB_LOOKDOWN ); + viewangles[PITCH] -= speed * in_pitchSpeed.GetFloat() * ButtonState( UB_LOOKUP ); + viewangles[PITCH] += speed * in_pitchSpeed.GetFloat() * ButtonState( UB_LOOKDOWN ); + } } else // Koz add independent weapon aiming { @@ -603,7 +617,7 @@ void idUsercmdGenLocal::MouseMove() pitchdelta = m_pitch.GetFloat() * in_mouseSpeed.GetFloat() * (in_mouseInvertLook.GetBool() ? -my : my); // Koz begin add mouse control here - if( commonVr->hasHMD && vr_enable.GetBool() ) + if( ( commonVr->hasHMD && vr_enable.GetBool() ) || in_independentAim.GetInteger() & 1 ) { // update the independent weapon angles and return any view changes based on current aim mode commonVr->CalcAimMove( yawdelta, pitchdelta ); diff --git a/neo/vr/Vr.cpp b/neo/vr/Vr.cpp index e0573db8e..88d2754f6 100644 --- a/neo/vr/Vr.cpp +++ b/neo/vr/Vr.cpp @@ -56,9 +56,9 @@ idCVar vr_forward_keyhole( "vr_forward_keyhole", "11.25", CVAR_FLOAT | CVAR_ARCH idCVar vr_PDAfixLocation( "vr_PDAfixLocation", "0", CVAR_BOOL | CVAR_ARCHIVE | CVAR_GAME, "Fix PDA position in space in front of player\n instead of holding in hand." ); -idCVar vr_weaponPivotOffsetForward( "vr_weaponPivotOffsetForward", "3", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "" ); -idCVar vr_weaponPivotOffsetHorizontal( "vr_weaponPivotOffsetHorizontal", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "" ); -idCVar vr_weaponPivotOffsetVertical( "vr_weaponPivotOffsetVertical", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "" ); +idCVar vr_weaponPivotOffsetForward( "vr_weaponPivotOffsetForward", "4", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "" ); +idCVar vr_weaponPivotOffsetHorizontal( "vr_weaponPivotOffsetHorizontal", "-4", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "" ); +idCVar vr_weaponPivotOffsetVertical( "vr_weaponPivotOffsetVertical", "-12", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "" ); idCVar vr_weaponPivotForearmLength( "vr_weaponPivotForearmLength", "16", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "" ); idCVar vr_guiScale( "vr_guiScale", "1", CVAR_FLOAT | CVAR_RENDERER | CVAR_ARCHIVE, "scale reduction factor for full screen menu/pda scale in VR", 0.0001f, 1.0f ); // Koz allow scaling of full screen guis/pda