diff --git a/CMakeLists.txt b/CMakeLists.txt index 5dae0b6..bf476b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,9 @@ message("CMAKE_CXX_FLAGS_RELWITHDEBINFO is ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") # Handled by path, but explicitly included to support IntelliSense include_directories(${CMAKE_SOURCE_DIR}/MSVC1400/VC/include ${CMAKE_SOURCE_DIR}/MSVC1400/VC/PlatformSDK/Include) +# Handle Windows dependencies that need explicit linking +link_libraries(winmm) + # Handle dependencies without source files include_directories(${CMAKE_SOURCE_DIR}/dependencies/recreated/include) link_directories(${CMAKE_SOURCE_DIR}/dependencies/recreated/lib) diff --git a/README.md b/README.md index 06d6853..123e8d4 100644 --- a/README.md +++ b/README.md @@ -47,11 +47,8 @@ Because the original game was compiled using an old compiler, you have to compil git clone --recursive https://github.com/sourcehold/OpenSHC.git ``` - Should NET Framework 3.5 be required, it can be easily installed on Windows 11 by running `mt.exe` (from the MSVC1400 repo), Windows 11 will ask to install the right version. -2. Install the needed Python dependencies, mainly `reccmp` for binary comparison - ```sh - python -m pip install -r requirements.txt - ``` -3. Create a softlink to the original game executable with the name `_original` by running [softlink.bat](softlink.bat). It will request the full path to the game folder. +2. Create a softlink to the original game executable with the name `_original` by running [softlink.bat](softlink.bat). It will request the full path to the game folder. +3. Setup the needed Python environment to run `reccmp` for binary comparison by running [setup.bat](reccmp/setup.bat) in the reccmp folder. ### Development The build can be run using the dev tools of the preferred IDE or via the build scripts. Regardless, a CMake installation is required. @@ -69,7 +66,7 @@ If the scripts are preferred, the following triggers a build using the scripts: ``` 5. Compare a function byte by byte to check compilation: ```sh - reccmp-reccmp --target STRONGHOLDCRUSADER --verbose 0x401000 + reccmp/run reccmp-reccmp --target STRONGHOLDCRUSADER --verbose 0x401000 ``` Note that any code needs to be formatted properly using the provided `clang-format`. The way to do so it up to the developer. Many IDEs support it out of the box. diff --git a/cmake/core-sources.txt b/cmake/core-sources.txt index e9f61df..e82acb9 100644 --- a/cmake/core-sources.txt +++ b/cmake/core-sources.txt @@ -2,4 +2,3 @@ src/core/MainImplementation.cpp src/core/Resolver.cpp src/core/ViewportRenderState.cpp src/core/entry.cpp -src/core/windowslib.cpp diff --git a/compare.bat b/compare.bat deleted file mode 100644 index ae857b0..0000000 --- a/compare.bat +++ /dev/null @@ -1 +0,0 @@ -reccmp-reccmp --paths "C:\Program Files (x86)\Steam\steamapps\common\Stronghold Crusader Extreme\Stronghold Crusader.exe" build-RelWithDebInfo\StrongholdCrusader.exe build-RelWithDebInfo\StrongholdCrusader.pdb . %1 %2 \ No newline at end of file diff --git a/reccmp-build.yml b/reccmp-build.yml deleted file mode 100644 index af42a4a..0000000 --- a/reccmp-build.yml +++ /dev/null @@ -1,5 +0,0 @@ -project: C:\Users\Gynt\Projects\sourcehold\openshc -targets: - STRONGHOLDCRUSADER: - path: build-RelWithDebInfo\StrongholdCrusader.exe - pdb: build-RelWithDebInfo\StrongholdCrusader.pdb diff --git a/reccmp-user.yml b/reccmp-user.yml deleted file mode 100644 index 654a8d3..0000000 --- a/reccmp-user.yml +++ /dev/null @@ -1,3 +0,0 @@ -targets: - STRONGHOLDCRUSADER: - path: StrongholdCrusader.exe diff --git a/reccmp/reccmp-build.yml b/reccmp/reccmp-build.yml new file mode 100644 index 0000000..2639031 --- /dev/null +++ b/reccmp/reccmp-build.yml @@ -0,0 +1,5 @@ +project: . +targets: + STRONGHOLDCRUSADER: + path: ../build-RelWithDebInfo/OpenSHC.exe + pdb: ../build-RelWithDebInfo/OpenSHC.pdb diff --git a/reccmp-project.yml b/reccmp/reccmp-project.yml similarity index 68% rename from reccmp-project.yml rename to reccmp/reccmp-project.yml index 3cefa7a..1239c3c 100644 --- a/reccmp-project.yml +++ b/reccmp/reccmp-project.yml @@ -1,12 +1,14 @@ targets: STRONGHOLDCRUSADER: - filename: StrongholdCrusader.exe - source_root: . + filename: Stronghold Crusader.exe + source_root: ../src hash: sha256: 3bb0a8c1e72331b3a30a5aa93ed94beca0081b476b04c1960e26d5b45387ac5a + data_sources: [] ghidra: ignore_types: [] ignore_functions: [] name_substitutions: [] + allow_hash_mismatch: false report: ignore_functions: [] diff --git a/reccmp/reccmp-user.yml b/reccmp/reccmp-user.yml new file mode 100644 index 0000000..b2dc870 --- /dev/null +++ b/reccmp/reccmp-user.yml @@ -0,0 +1,3 @@ +targets: + STRONGHOLDCRUSADER: + path: ../_original/Stronghold Crusader.exe diff --git a/requirements.txt b/reccmp/requirements.txt similarity index 100% rename from requirements.txt rename to reccmp/requirements.txt diff --git a/reccmp/run.bat b/reccmp/run.bat new file mode 100644 index 0000000..e59cfe2 --- /dev/null +++ b/reccmp/run.bat @@ -0,0 +1,89 @@ +@echo off +setlocal + +:: === Configuration === +set "VENV_DIR=.venv" +set "ENV_ACTIVE=0" +set "CMD_EXIT_CODE=0" + +:: -------------------------------------------- +:: Change working directory to script location +:: -------------------------------------------- +cd /d "%~dp0" || ( + echo [ERROR] Failed to set working directory to script location. + call :Cleanup + exit /b 1 +) + +:: -------------------------------------------- +:: Check arguments +:: -------------------------------------------- +if "%~1"=="" ( + echo [ERROR] No command provided. + echo Usage: %~nx0 command [args...] + call :Cleanup + exit /b 1 +) + +:: -------------------------------------------- +:: Check virtual environment exists +:: -------------------------------------------- +if not exist "%VENV_DIR%\Scripts\activate.bat" ( + echo [ERROR] Virtual environment not found: %VENV_DIR% + echo Please run the setup script first. + call :Cleanup + exit /b 1 +) + +:: -------------------------------------------- +:: Prevent double-activation +:: -------------------------------------------- +if /i "%VIRTUAL_ENV%"=="%CD%\%VENV_DIR%" ( + echo [ERROR] Already running inside the target virtual environment. + call :Cleanup + exit /b 1 +) + +:: -------------------------------------------- +:: Activate virtual environment +:: -------------------------------------------- +call "%VENV_DIR%\Scripts\activate.bat" +if /i not "%VIRTUAL_ENV%"=="%CD%\%VENV_DIR%" ( + echo [ERROR] Failed to activate virtual environment. + call :Cleanup + exit /b 1 +) + +set "ENV_ACTIVE=1" +echo [OK] Virtual environment activated. + +:: -------------------------------------------- +:: Run provided command +:: -------------------------------------------- +echo [INFO] Running command: %* +cmd /c %* +set "CMD_EXIT_CODE=%ERRORLEVEL%" +if %CMD_EXIT_CODE% neq 0 ( + echo [ERROR] Command failed with exit code %CMD_EXIT_CODE%. + call :Cleanup + exit /b %CMD_EXIT_CODE% +) + +:: -------------------------------------------- +:: Cleanup +:: -------------------------------------------- +call :Cleanup + +echo [SUCCESS] Command completed successfully. +exit /b 0 + +:: -------------------------------------------- +:: Cleanup function +:: -------------------------------------------- +:Cleanup +if "%ENV_ACTIVE%"=="1" ( + deactivate + set "ENV_ACTIVE=0" + echo [OK] Virtual environment deactivated. +) +exit /b 0 diff --git a/reccmp/setup.bat b/reccmp/setup.bat new file mode 100644 index 0000000..934f06b --- /dev/null +++ b/reccmp/setup.bat @@ -0,0 +1,94 @@ +@echo off +setlocal + +:: === Configuration === +set "VENV_DIR=.venv" +set "REQ_FILE=requirements.txt" +set "ENV_ACTIVE=0" + +:: --- Change working directory to the folder where the script is located --- +cd /d "%~dp0" || ( + echo [ERROR] Failed to set working directory to script location: %~dp0 + call :Cleanup + exit /b 1 +) + +:: -------------------------------------------- +:: Check if not running in own env +:: -------------------------------------------- +if /i "%VIRTUAL_ENV%"=="%CD%\%VENV_DIR%" ( + echo [ERROR] This script is already running inside the target virtual environment. + exit /b 1 +) + +:: -------------------------------------------- +:: Check for Python installation +:: -------------------------------------------- +python --version >nul 2>&1 +if %errorlevel% neq 0 ( + echo [ERROR] Python is not installed or not in PATH. + call :Cleanup + exit /b 1 +) +echo [OK] Python is available. + +:: -------------------------------------------- +:: Create virtual environment +:: -------------------------------------------- +echo Creating virtual environment in "%VENV_DIR%"... +python -m venv "%VENV_DIR%" +if %errorlevel% neq 0 ( + echo [ERROR] Failed to create virtual environment. + call :Cleanup + exit /b 1 +) + +:: -------------------------------------------- +:: Activate virtual environment +:: -------------------------------------------- +call "%VENV_DIR%\Scripts\activate.bat" +if /i not "%VIRTUAL_ENV%"=="%CD%\%VENV_DIR%" ( + echo [ERROR] Failed to activate virtual environment. + call :Cleanup + exit /b 1 +) +set "ENV_ACTIVE=1" +echo [OK] Virtual environment activated. + +:: -------------------------------------------- +:: Install requirements +:: -------------------------------------------- +if not exist "%REQ_FILE%" ( + echo [ERROR] Requirements file not found: %REQ_FILE% + call :Cleanup + exit /b 1 +) + +echo Installing packages from "%REQ_FILE%"... +pip install -r "%REQ_FILE%" +if %errorlevel% neq 0 ( + echo [ERROR] Failed to install packages. + call :Cleanup + exit /b 1 +) +echo [OK] All packages installed successfully. + +:: -------------------------------------------- +:: Normal cleanup +:: -------------------------------------------- +call :Cleanup + +echo [SUCCESS] Setup complete. +endlocal +exit /b 0 + +:: -------------------------------------------- +:: Cleanup function +:: -------------------------------------------- +:Cleanup +if "%ENV_ACTIVE%"=="1" ( + deactivate + set "ENV_ACTIVE=0" + echo [OK] Virtual environment deactivated. +) +exit /b 0 diff --git a/src/core/ViewportRenderState.cpp b/src/core/ViewportRenderState.cpp index cb69806..62970ef 100644 --- a/src/core/ViewportRenderState.cpp +++ b/src/core/ViewportRenderState.cpp @@ -1,7 +1,7 @@ #include "ViewportRenderState.h" #include "ViewportRenderState.func.h" -#include "windowslib.h" +#include "mmsystem.h" ViewportRenderState::ViewportRenderState() { MACRO_CALL_MEMBER(ViewportRenderState_Func::_constructor_, this)(); } diff --git a/src/core/ViewportRenderState.h b/src/core/ViewportRenderState.h index c3507d0..fbb1d32 100644 --- a/src/core/ViewportRenderState.h +++ b/src/core/ViewportRenderState.h @@ -93,24 +93,17 @@ struct ViewportRenderState { ViewportRenderState(); - // FUNCTION: STRONGHOLDCRUSADER 0x004e1fa0 ViewportRenderState* _constructor_(); - // FUNCTION: STRONGHOLDCRUSADER 0x00401000 BOOL xyAreValid(uint x, uint y); - // FUNCTION: STRONGHOLDCRUSADER 0x00401040 int translateXYToTile(int x, int y); - // FUNCTION: STRONGHOLDCRUSADER 0x004092e0 int meth_0x4092e0(int param_1, int param_2); - // FUNCTION: STRONGHOLDCRUSADER 0x004e5dd0 void setupMouseTileXY(); - // FUNCTION: STRONGHOLDCRUSADER 0x004e5d80 void setupMouseTileXY2(); - // FUNCTION: STRONGHOLDCRUSADER 0x004e5a90 void meth_0x4e5a90(); }; diff --git a/src/core/windowslib.cpp b/src/core/windowslib.cpp deleted file mode 100644 index 493addc..0000000 --- a/src/core/windowslib.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "windowslib.h" - -// LIB: STRONGHOLDCRUSADER -DWORD __stdcall timeGetTime() { return 0; } diff --git a/src/core/windowslib.h b/src/core/windowslib.h deleted file mode 100644 index 362a416..0000000 --- a/src/core/windowslib.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -DWORD __stdcall timeGetTime();