Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/_original",
// Note: build currently set target, so if this is the exe, nothing will change
"preLaunchTask": "CMake: build",
"preLaunchTask": "CMake: Prepare OpenSHC.dll Debug",
}
]
}
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
"editor.rulers": [
120
],
"cmake.useCMakePresets": "always",
"cmake.useVsDeveloperEnvironment": "never",
"files.associations": {
"*.inl": "cpp",
"iostream": "cpp",
Expand Down
15 changes: 15 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "cmake",
"label": "CMake: Prepare OpenSHC.dll Debug",
"command": "build",
"targets": [
"OpenSHC.dll.deploy"
],
"preset": "Debug",
"group": "build"
}
]
}
71 changes: 40 additions & 31 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@
cmake_minimum_required (VERSION 3.21)

function(file_add_depends FILE)
message(STATUS "Add file system dependency: ${FILE}")
if(EXISTS "${FILE}")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${FILE}) # generally watches for changes
cmake_parse_arguments(ADDITIONAL_ARGS "EXISTENCE_ONLY" "" "" ${ARGN})

if(ADDITIONAL_ARGS_EXISTENCE_ONLY)
message(STATUS "Add file system dependency on existence: ${FILE}")
file(GLOB _ CONFIGURE_DEPENDS "${FILE}")
else()
file(GLOB _ CONFIGURE_DEPENDS ${FILE}) # trick to trigger reconfigure if the file comes into existence
message(STATUS "Add file system dependency: ${FILE}")
if(EXISTS "${FILE}")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${FILE}")
else()
# Trigger reconfigure if the file comes into existence
file(GLOB _ CONFIGURE_DEPENDS "${FILE}")
endif()
endif()
endfunction()

Expand Down Expand Up @@ -123,64 +131,65 @@ else()
endif()


# Add source to this project's executable.
# Create the OpenSHC.exe target, should not require the game
add_executable(OpenSHC.exe WIN32 src/entry.cpp ${CORE_SOURCES} ${OPENSHC_SOURCES})
set_target_properties(OpenSHC.exe PROPERTIES OUTPUT_NAME ${OPEN_SHC_NAME})
set_target_properties(OpenSHC.exe PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/EXE")
target_compile_definitions(OpenSHC.exe PRIVATE OPEN_SHC_EXE)
target_precompile_headers(OpenSHC.exe PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${PCH_FILE}>)



# Create custom target that pulls in the required dependencies to run the exe
# NOTE: There seems to be an issue with our naming here, causing the depends to look for "OpenSHC.exe.exe" instead
add_custom_target(OpenSHC.exe.runnable DEPENDS OpenSHC.exe.exe)

# Checks if a binkw32_real is present and uses this instead
file_add_depends("${CRUSADER_DIR}/binkw32_real.dll")
if(EXISTS "${CRUSADER_DIR}/binkw32_real.dll")
target_file_copy_if_different(OpenSHC.exe "${CRUSADER_DIR}/binkw32_real.dll" "$<TARGET_FILE_DIR:OpenSHC.exe>/binkw32.dll")
target_file_copy_if_different(OpenSHC.exe.runnable "${CRUSADER_DIR}/binkw32_real.dll" "$<TARGET_FILE_DIR:OpenSHC.exe>/binkw32.dll")
else()
target_file_copy_if_different(OpenSHC.exe "${CRUSADER_DIR}/binkw32.dll" "$<TARGET_FILE_DIR:OpenSHC.exe>/binkw32.dll")
target_file_copy_if_different(OpenSHC.exe.runnable "${CRUSADER_DIR}/binkw32.dll" "$<TARGET_FILE_DIR:OpenSHC.exe>/binkw32.dll")
endif()
target_file_copy_if_different(OpenSHC.exe "${CRUSADER_DIR}/Mss32.dll" "$<TARGET_FILE_DIR:OpenSHC.exe>/Mss32.dll")
target_file_copy_if_different(OpenSHC.exe.runnable "${CRUSADER_DIR}/Mss32.dll" "$<TARGET_FILE_DIR:OpenSHC.exe>/Mss32.dll")

# shfolder is a normal windows lib, however, the game needs to work with the games version, so we still copy it
# it should be checked later if the compiler emits a shfolder.dll on its own or if it statically links, which we do not want
target_file_copy_if_different(OpenSHC.exe "${CRUSADER_DIR}/shfolder.dll" "$<TARGET_FILE_DIR:OpenSHC.exe>/shfolder.dll")
target_file_copy_if_different(OpenSHC.exe.runnable "${CRUSADER_DIR}/shfolder.dll" "$<TARGET_FILE_DIR:OpenSHC.exe>/shfolder.dll")



# Place the dll and its pdb in the OpenSHC module folder for live testing
set(OPEN_SHC_DLL_DEST "${CRUSADER_DIR}/ucp/modules/${OPEN_SHC_NAME}-${OPEN_SHC_VERSION}" CACHE PATH "Path for OpenSHC.dll and OpenSHC.pdb")

add_library(OpenSHC.dll SHARED src/entry.cpp ${CORE_SOURCES} ${OPENSHC_SOURCES})
set_target_properties(OpenSHC.dll PROPERTIES OUTPUT_NAME ${OPEN_SHC_NAME})
set_target_properties(OpenSHC.dll PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/DLL")
target_compile_definitions(OpenSHC.dll PRIVATE OPEN_SHC_DLL)
target_precompile_headers(OpenSHC.dll PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${PCH_FILE}>)

# Using module folder as runtime output to properly place the dll and other libs
set_target_properties(OpenSHC.dll PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${OPEN_SHC_DLL_DEST})


# Create custom target that deploys the DLL and the required UCP files to the modules folder
add_custom_target(OpenSHC.dll.deploy DEPENDS OpenSHC.dll)
set(OPEN_SHC_DLL_DEST "${CRUSADER_DIR}/ucp/modules/${OPEN_SHC_NAME}-${OPEN_SHC_VERSION}")

# Ensure the module folder exists
file(MAKE_DIRECTORY ${OPEN_SHC_DLL_DEST})
file_add_depends("${OPEN_SHC_DLL_DEST}")

# This strange workaround does ensure that the module folder is generated and that a config change regenerates the dll.
# It "only" costs a file creation and a compare minimum while not changing the actual source. Found no other way.
set(BUILD_TRIGGER_FILE "${OPEN_SHC_DLL_DEST}/buildtrigger.c")
add_custom_target(
OpenSHC.dll.trigger
BYPRODUCTS ${BUILD_TRIGGER_FILE}
COMMAND ${CMAKE_COMMAND} -E echo "// $<CONFIG>" > ${BUILD_TRIGGER_FILE}.tmp
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${BUILD_TRIGGER_FILE}.tmp ${BUILD_TRIGGER_FILE}
COMMAND ${CMAKE_COMMAND} -E remove ${BUILD_TRIGGER_FILE}.tmp
VERBATIM
add_custom_command(TARGET OpenSHC.dll.deploy POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory "${OPEN_SHC_DLL_DEST}"
)
target_sources(OpenSHC.dll PRIVATE ${BUILD_TRIGGER_FILE})
add_dependencies(OpenSHC.dll OpenSHC.dll.trigger)

# Copy exe and pdb is possible
target_file_copy_if_different(OpenSHC.dll.deploy "$<TARGET_FILE:OpenSHC.dll>" "${OPEN_SHC_DLL_DEST}/$<TARGET_FILE_NAME:OpenSHC.dll>")
target_file_copy_if_different(OpenSHC.dll.deploy "$<TARGET_PDB_FILE:OpenSHC.dll>" "${OPEN_SHC_DLL_DEST}/$<TARGET_PDB_FILE_NAME:OpenSHC.dll>")

# Copy ucp definition files
file_dependent_read_list("${CMAKE_SOURCE_DIR}/cmake/ucp-definition.txt" UCP_DEFINITION)
foreach(FILE IN LISTS UCP_DEFINITION)
get_filename_component(DIR "${FILE}" DIRECTORY)
if (DIR)
add_custom_command(TARGET OpenSHC.dll POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory "${OPEN_SHC_DLL_DEST}/${DIR}"
set(DEST_FILE_DIR "${OPEN_SHC_DLL_DEST}/${DIR}")
add_custom_command(TARGET OpenSHC.dll.deploy POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory "${DEST_FILE_DIR}"
)
endif()
target_file_copy_if_different(OpenSHC.dll "${CMAKE_SOURCE_DIR}/ucp/${FILE}" "${OPEN_SHC_DLL_DEST}/${FILE}")
target_file_copy_if_different(OpenSHC.dll.deploy "${CMAKE_SOURCE_DIR}/ucp/${FILE}" "${DEST_FILE_DIR}/${FILE}")
endforeach()
10 changes: 3 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,8 @@ Extending this files name in any way, like `openshc-sources.txt.local.bak`, will

The file `build.bat` exists for convenience. If you want more control, you can specify the following cmake options.

##### Output folder of dll

Use `cmake --preset RelWithDebInfo -D OPEN_SHC_DLL_DEST=.\build-RelWithDebInfo\dll` to specify the destination folder for the .dll and .pdb files in favor of the default.

Note this setting will remain present even if you remove the `-D` option later from the command. To actually clear this configuration, use `cmake --preset RelWithDebInfo --fresh`.

##### Building

Build using `cmake --build --preset RelWithDebInfo --target OpenSHC.dll`
Build using `cmake --build --preset RelWithDebInfo --target OpenSHC.dll` will create the dll in `build-RelWithDebInfo/DLL`.
Build using `cmake --build --preset RelWithDebInfo --target OpenSHC.exe` will create the exe in `build-RelWithDebInfo/EXE`.
Build using `cmake --build --preset RelWithDebInfo --target OpenSHC.dll.deploy` will prepare the modules folder in the UCP setup of the bound SHC.
5 changes: 5 additions & 0 deletions reccmp/reccmp-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
project: .
targets:
STRONGHOLDCRUSADER:
path: ../build-RelWithDebInfo/EXE/OpenSHC.exe
pdb: ../build-RelWithDebInfo/EXE/OpenSHC.pdb
2 changes: 1 addition & 1 deletion src/core/MainImplementation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ int WINAPI Main::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCm
MACRO_CALL_MEMBER(ViewportRenderState_Func::setupMouseTileXY2, ViewportRenderState_Struct::ptr)();
MACRO_CALL_MEMBER(ViewportRenderState_Func::meth_0x4e5a90, ViewportRenderState_Struct::ptr)();

const HBINK bink = BinkOpen("..\\_original\\binks\\abbot_angry.bik", BINKNOSKIP);
const HBINK bink = BinkOpen("..\\..\\_original\\binks\\abbot_angry.bik", BINKNOSKIP);
std::cout << bink->Width << " " << bink->Height << " " << bink->Frames << " " << bink->FrameNum << std::endl;
BinkClose(bink);

Expand Down