diff --git a/CMakeLists.txt b/CMakeLists.txt index 9260aa12..2136ce95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,7 @@ function(file_dependent_read_list FILE LIST) set(${LIST} "${TEMP_LIST}" PARENT_SCOPE) endfunction() -project ("OpenSHC") +project ("OpenSHC" LANGUAGES C CXX ASM_MASM) # Name of exe and dll should be the same set(OPEN_SHC_NAME "OpenSHC") @@ -158,9 +158,11 @@ target_file_copy_if_different(OpenSHC.exe.runnable "${CRUSADER_DIR}/Mss32.dll" " target_file_copy_if_different(OpenSHC.exe.runnable "${CRUSADER_DIR}/shfolder.dll" "$/shfolder.dll") +# Add the asm file containing the game symbols as reference +set(GAME_SYMBOLS_FILE ${CMAKE_SOURCE_DIR}/src/symbols/game.asm) # Create the OpenSHC.dll target, should not require the game -add_library(OpenSHC.dll SHARED src/entry.cpp ${CORE_SOURCES} ${OPENSHC_SOURCES}) +add_library(OpenSHC.dll SHARED src/entry.cpp ${CORE_SOURCES} ${OPENSHC_SOURCES} ${GAME_SYMBOLS_FILE}) 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 REIMPLEMENTED_CRT=0) diff --git a/src/precomp/StructResolver.h b/src/precomp/StructResolver.h index 9383dbe4..1634fcb6 100644 --- a/src/precomp/StructResolver.h +++ b/src/precomp/StructResolver.h @@ -7,6 +7,10 @@ struct StructResolver { private: template struct Instance; + template struct Extern { + static T instance; + }; + template struct InternalResolver; template struct InternalResolver { static T* const ptr; @@ -39,7 +43,8 @@ struct StructResolver { }; template -T* const StructResolver::InternalResolver::ptr = reinterpret_cast(gameAddress); +T* const StructResolver::InternalResolver::ptr + = &StructResolver::Extern::instance; template T* const StructResolver::InternalResolver::ptr @@ -57,6 +62,13 @@ StructResolver::Resolver::Initializer::Initializer( initialize(AddressUsageKeeper::initialized, isImplemented, gameAddress, Ptr::ptr, getTypeName()); } +// TODO: rather then adding a template to hold the ref which would require a long mangled name, +// if we have a generatable name, we use a macro to define an extern C and use this instead. +// In this case, the asm file only needs to be touched if the general constract of the address changes +// and should we only ever use the addresses of the globals, this might be never. +// However, if filtered and generated names are required, maybe it could also be possible to create a generator for +// the more complicated mangled names? Any general type change would need to also adept the ASM file. + #define MACRO_STRUCT_RESOLVER(STRUCT_TYPE, IMPLEMENTED, GAME_ADDRESS) \ template struct StructResolver::Resolver; \ typedef StructResolver::Resolver::Ptr diff --git a/src/symbols/game.asm b/src/symbols/game.asm new file mode 100644 index 00000000..477975e9 --- /dev/null +++ b/src/symbols/game.asm @@ -0,0 +1,10 @@ +.386 +.model flat + +PUBLIC ?instance@?$Extern@USoundEffectsHelperData1@Audio@OpenSHC@@$0NPDHPA@@StructResolver@@2USoundEffectsHelperData1@Audio@OpenSHC@@A + +_TEXT SEGMENT +?instance@?$Extern@USoundEffectsHelperData1@Audio@OpenSHC@@$0NPDHPA@@StructResolver@@2USoundEffectsHelperData1@Audio@OpenSHC@@A EQU 00DF37F0h +_TEXT ENDS + +END