From db65c2bddb09cbe45fc5f04f1c892f3198dfca56 Mon Sep 17 00:00:00 2001 From: CoChiefResident <5812282+CoChiefResident@users.noreply.github.com> Date: Mon, 11 Aug 2025 21:52:59 +0200 Subject: [PATCH] feature: Add command line option to skip force set of current directory to executable path --- .../GameEngine/Include/Common/GlobalData.h | 4 +++ .../GameEngine/Source/Common/CommandLine.cpp | 10 +++++++ .../GameEngine/Source/Common/GlobalData.cpp | 1 + Generals/Code/Main/WinMain.cpp | 28 +++++++++++-------- .../GameEngine/Include/Common/GlobalData.h | 4 +++ .../GameEngine/Source/Common/CommandLine.cpp | 10 +++++++ .../GameEngine/Source/Common/GlobalData.cpp | 1 + GeneralsMD/Code/Main/WinMain.cpp | 27 ++++++++++-------- 8 files changed, 61 insertions(+), 24 deletions(-) diff --git a/Generals/Code/GameEngine/Include/Common/GlobalData.h b/Generals/Code/GameEngine/Include/Common/GlobalData.h index 4b0314497c..fad0a355b9 100644 --- a/Generals/Code/GameEngine/Include/Common/GlobalData.h +++ b/Generals/Code/GameEngine/Include/Common/GlobalData.h @@ -121,6 +121,10 @@ class GlobalData : public SubsystemInterface // Run game without graphics, input or audio. Bool m_headless; + // TheSuperHackers @feature 11/08/2025 + // On startup change the current working directory to the executable's location. + Bool m_changeCurrentWorkingDirectoryToExecutablePath; + Bool m_windowed; Int m_xResolution; Int m_yResolution; diff --git a/Generals/Code/GameEngine/Source/Common/CommandLine.cpp b/Generals/Code/GameEngine/Source/Common/CommandLine.cpp index 19678a6744..9d929f4132 100644 --- a/Generals/Code/GameEngine/Source/Common/CommandLine.cpp +++ b/Generals/Code/GameEngine/Source/Common/CommandLine.cpp @@ -458,6 +458,12 @@ Int parseJobs(char *args[], int num) return 1; } +Int parseCwd(char* args[], int num) +{ + TheWritableGlobalData->m_changeCurrentWorkingDirectoryToExecutablePath = FALSE; + return 1; +} + Int parseXRes(char *args[], int num) { if (num > 1) @@ -1163,6 +1169,10 @@ static CommandLineParam paramsForStartup[] = // (If you have 4 cores, call it with -jobs 4) // If you do not call this, all replays will be simulated in sequence in the same process. { "-jobs", parseJobs }, + + // TheSuperHackers @feature 11/08/2025 + // Use current working directory as provided by the OS. + { "-cwd", parseCwd }, }; // These Params are parsed during Engine Init before INI data is loaded diff --git a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp index 8c07362066..4e8c0ced7f 100644 --- a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp @@ -613,6 +613,7 @@ GlobalData::GlobalData() m_framesPerSecondLimit = 0; m_chipSetType = 0; m_headless = FALSE; + m_changeCurrentWorkingDirectoryToExecutablePath = TRUE; m_windowed = 0; m_xResolution = 800; m_yResolution = 600; diff --git a/Generals/Code/Main/WinMain.cpp b/Generals/Code/Main/WinMain.cpp index ae8697232d..c9f747c4a5 100644 --- a/Generals/Code/Main/WinMain.cpp +++ b/Generals/Code/Main/WinMain.cpp @@ -764,21 +764,26 @@ Int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, // initialize the memory manager early initMemoryManager(); - - /// @todo remove this force set of working directory later - Char buffer[ _MAX_PATH ]; - GetModuleFileName( NULL, buffer, sizeof( buffer ) ); - Char *pEnd = buffer + strlen( buffer ); - while( pEnd != buffer ) + + CommandLine::parseCommandLineForStartup(); + + if (TheGlobalData->m_changeCurrentWorkingDirectoryToExecutablePath) { - if( *pEnd == '\\' ) + /// @todo remove this force set of working directory later + Char buffer[ _MAX_PATH ]; + GetModuleFileName( NULL, buffer, sizeof( buffer ) ); + Char *pEnd = buffer + strlen( buffer ); + while( pEnd != buffer ) { - *pEnd = 0; - break; + if( *pEnd == '\\' ) + { + *pEnd = 0; + break; + } + pEnd--; } - pEnd--; + ::SetCurrentDirectory(buffer); } - ::SetCurrentDirectory(buffer); #ifdef RTS_DEBUG @@ -799,7 +804,6 @@ Int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, // Force to be loaded from a file, not a resource so same exe can be used in germany and retail. gLoadScreenBitmap = (HBITMAP)LoadImage(hInstance, "Install_Final.bmp", IMAGE_BITMAP, 0, 0, LR_SHARED|LR_LOADFROMFILE); - CommandLine::parseCommandLineForStartup(); // register windows class and create application window if(!TheGlobalData->m_headless && initializeAppWindows(hInstance, nCmdShow, TheGlobalData->m_windowed) == false) diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h index ed3bbcc1d1..199bffe159 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h @@ -124,6 +124,10 @@ class GlobalData : public SubsystemInterface // Run game without graphics, input or audio. Bool m_headless; + // TheSuperHackers @feature 11/08/2025 + // On startup change the current working directory to the executable's location. + Bool m_changeCurrentWorkingDirectoryToExecutablePath; + Bool m_windowed; Int m_xResolution; Int m_yResolution; diff --git a/GeneralsMD/Code/GameEngine/Source/Common/CommandLine.cpp b/GeneralsMD/Code/GameEngine/Source/Common/CommandLine.cpp index 19678a6744..9d929f4132 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/CommandLine.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/CommandLine.cpp @@ -458,6 +458,12 @@ Int parseJobs(char *args[], int num) return 1; } +Int parseCwd(char* args[], int num) +{ + TheWritableGlobalData->m_changeCurrentWorkingDirectoryToExecutablePath = FALSE; + return 1; +} + Int parseXRes(char *args[], int num) { if (num > 1) @@ -1163,6 +1169,10 @@ static CommandLineParam paramsForStartup[] = // (If you have 4 cores, call it with -jobs 4) // If you do not call this, all replays will be simulated in sequence in the same process. { "-jobs", parseJobs }, + + // TheSuperHackers @feature 11/08/2025 + // Use current working directory as provided by the OS. + { "-cwd", parseCwd }, }; // These Params are parsed during Engine Init before INI data is loaded diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp index ed0d16e478..7b61de9317 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp @@ -618,6 +618,7 @@ GlobalData::GlobalData() m_framesPerSecondLimit = 0; m_chipSetType = 0; m_headless = FALSE; + m_changeCurrentWorkingDirectoryToExecutablePath = TRUE; m_windowed = 0; m_xResolution = 800; m_yResolution = 600; diff --git a/GeneralsMD/Code/Main/WinMain.cpp b/GeneralsMD/Code/Main/WinMain.cpp index ee6ca68825..6a5c26f113 100644 --- a/GeneralsMD/Code/Main/WinMain.cpp +++ b/GeneralsMD/Code/Main/WinMain.cpp @@ -792,20 +792,25 @@ Int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, // initialize the memory manager early initMemoryManager(); - /// @todo remove this force set of working directory later - Char buffer[ _MAX_PATH ]; - GetModuleFileName( NULL, buffer, sizeof( buffer ) ); - Char *pEnd = buffer + strlen( buffer ); - while( pEnd != buffer ) + CommandLine::parseCommandLineForStartup(); + + if (TheGlobalData->m_changeCurrentWorkingDirectoryToExecutablePath) { - if( *pEnd == '\\' ) + /// @todo remove this force set of working directory later + Char buffer[ _MAX_PATH ]; + GetModuleFileName( NULL, buffer, sizeof( buffer ) ); + Char *pEnd = buffer + strlen( buffer ); + while( pEnd != buffer ) { - *pEnd = 0; - break; + if( *pEnd == '\\' ) + { + *pEnd = 0; + break; + } + pEnd--; } - pEnd--; + ::SetCurrentDirectory(buffer); } - ::SetCurrentDirectory(buffer); #ifdef RTS_DEBUG @@ -846,8 +851,6 @@ Int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, gLoadScreenBitmap = (HBITMAP)LoadImage(hInstance, "Install_Final.bmp", IMAGE_BITMAP, 0, 0, LR_SHARED|LR_LOADFROMFILE); #endif - CommandLine::parseCommandLineForStartup(); - // register windows class and create application window if(!TheGlobalData->m_headless && initializeAppWindows(hInstance, nCmdShow, TheGlobalData->m_windowed) == false) return exitcode;