Remove binkw

This commit is contained in:
Guus Waals 2025-06-07 01:05:41 +08:00
parent a8143e6ac0
commit e6c8d527bc
8 changed files with 182 additions and 126 deletions

View File

@ -1,22 +1,25 @@
function(setup_target TARGET DBG_MODE) function(setup_target TARGET DBG_MODE)
add_executable(${TARGET} set(SOURCES
r3/main.cxx r3/main.cxx
r3/binders/stub.cxx r3/binders/stub.cxx
gh_global.cxx gh_global.cxx)
)
if(DBG_MODE)
add_library(${TARGET} SHARED ${SOURCES})
else()
add_executable(${TARGET} ${SOURCES})
set_target_properties(
${TARGET} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
endif()
target_compile_features(${TARGET} PUBLIC cxx_std_20) target_compile_features(${TARGET} PUBLIC cxx_std_20)
target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
set_target_properties(
${TARGET} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
if(WIN32 AND R3_32BIT) if(WIN32 AND R3_32BIT)
target_link_libraries(${TARGET} PRIVATE target_link_libraries(${TARGET} PRIVATE
binkw32 binkw32
d3d8
dinput8 dinput8
) )
endif() endif()
@ -25,10 +28,12 @@ function(setup_target TARGET DBG_MODE)
R3_GAME_DATA_DIR=\"${GAME_DATA_DIR}\" R3_GAME_DATA_DIR=\"${GAME_DATA_DIR}\"
) )
get_filename_component(R3_DATA_SEGMENT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/gh_datasegment.bin" ABSOLUTE) if(NOT DBG_MODE)
target_compile_definitions(${TARGET} PRIVATE get_filename_component(R3_DATA_SEGMENT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/gh_datasegment.bin" ABSOLUTE)
R3_DATA_SEGMENT_FILE=\"${R3_DATA_SEGMENT_FILE}\" target_compile_definitions(${TARGET} PRIVATE
) R3_DATA_SEGMENT_FILE=\"${R3_DATA_SEGMENT_FILE}\"
)
endif()
target_compile_definitions(${TARGET} PRIVATE target_compile_definitions(${TARGET} PRIVATE
_CRT_SECURE_NO_WARNINGS=1 _CRT_SECURE_NO_WARNINGS=1
@ -50,7 +55,7 @@ function(setup_target TARGET DBG_MODE)
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
target_compile_definitions(${TARGET} PRIVATE MSVC=1) target_compile_definitions(${TARGET} PRIVATE MSVC=1)
# Disable SAFESEH on Windows # Disable SAFESEH on Windows
if(WIN32) if(WIN32)
target_link_options(${TARGET} PRIVATE /SAFESEH:NO) target_link_options(${TARGET} PRIVATE /SAFESEH:NO)
@ -63,11 +68,9 @@ function(setup_target TARGET DBG_MODE)
# Ignore -Wmicrosoft-cast # Ignore -Wmicrosoft-cast
target_compile_options(${TARGET} PRIVATE -Wno-microsoft-cast) target_compile_options(${TARGET} PRIVATE -Wno-microsoft-cast)
# Disable SAFESEH on Windows with Clang # Disable safeseh
if(WIN32) # target_link_options(${TARGET} PRIVATE -Wl,/SAFESEH:NO)
target_link_options(${TARGET} PRIVATE -Wl,/SAFESEH:NO)
endif()
endif() endif()
# Automatically re-run CMake if any gh_*.cxx files change # Automatically re-run CMake if any gh_*.cxx files change
@ -95,12 +98,6 @@ function(setup_target TARGET DBG_MODE)
r3/binders/dbg_mem.cxx r3/binders/dbg_mem.cxx
) )
target_compile_definitions(game_dbg PRIVATE RE_DBG_INJECTED=1) target_compile_definitions(game_dbg PRIVATE RE_DBG_INJECTED=1)
# We load the original binary at it's original location, so offset the base address
target_link_options(${TARGET} PRIVATE
-Wl,/BASE:0x20000000
-Wl,/DYNAMICBASE:NO
)
target_link_libraries(${TARGET} PRIVATE target_link_libraries(${TARGET} PRIVATE
DbgHelp DbgHelp
hooker hooker
@ -117,10 +114,6 @@ function(setup_target TARGET DBG_MODE)
) )
target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_sources(${TARGET} PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/hooks.def
)
else() else()
target_sources(${TARGET} PRIVATE target_sources(${TARGET} PRIVATE
r3/binders/static_mem.cxx r3/binders/static_mem.cxx

View File

@ -1,18 +1,30 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!! // AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h> #include <r3/binders/auto.h>
#include <gh_global.h> #include <gh_global.h>
extern "C" { extern "C" {
undefined FUN_00496ac0(void); // 00496ac0 // FUN_00496ac0 // cdecl undefined FUN_00496ac0(void); // 00496ac0 // FUN_00496ac0 // cdecl
undefined FUN_00470b00(void); // 00470b00 // FUN_00470b00 // cdecl undefined FUN_00470b00(void); // 00470b00 // FUN_00470b00 // cdecl
undefined FUN_00484ea0(undefined4 param_1); // 00484ea0 // FUN_00484ea0 // cdecl undefined FUN_00484ea0(undefined4 param_1); // 00484ea0 // FUN_00484ea0 // cdecl
using FnD3Create8 = IDirect3D8 *(__stdcall *)(UINT);
static FnD3Create8 init_d3d_function() {
HMODULE hModule = LoadLibrary("d3d8.dll");
if (hModule != NULL) {
return (FnD3Create8)GetProcAddress(hModule, "Direct3DCreate8");
}
return nullptr;
}
// 0046f870 // 0046f870
/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */ /* WARNING: Globals starting with '_' overlap smaller symbols at the same
* address */
/* WARNING: Enum "_D3DFORMAT": Some values do not have unique names */ /* WARNING: Enum "_D3DFORMAT": Some values do not have unique names */
undefined4 gfx_init(HWND hwnd,int param_2,UINT param_3,UINT param_4,int param_5) undefined4 gfx_init(HWND hwnd, int param_2, UINT param_3, UINT param_4,
int param_5)
{ {
undefined4 *puVar1; undefined4 *puVar1;
@ -23,7 +35,7 @@ undefined4 gfx_init(HWND hwnd,int param_2,UINT param_3,UINT param_4,int param_5)
D3DDISPLAYMODE DStack_54; D3DDISPLAYMODE DStack_54;
D3DDISPLAYMODE displayMode; D3DDISPLAYMODE displayMode;
D3DPRESENT_PARAMETERS DStack_34; D3DPRESENT_PARAMETERS DStack_34;
puVar1 = &DAT_007eaf60; puVar1 = &DAT_007eaf60;
for (iVar3 = 0x13; iVar3 != 0; iVar3 = iVar3 + -1) { for (iVar3 = 0x13; iVar3 != 0; iVar3 = iVar3 + -1) {
*puVar1 = 0; *puVar1 = 0;
@ -53,17 +65,18 @@ undefined4 gfx_init(HWND hwnd,int param_2,UINT param_3,UINT param_4,int param_5)
if (param_5 == 0) { if (param_5 == 0) {
param_5 = g_GLI_bitdepth0; param_5 = g_GLI_bitdepth0;
} }
} } else {
else {
DWORD_005e6c20 = param_3; DWORD_005e6c20 = param_3;
DWORD_005e6c24 = param_4; DWORD_005e6c24 = param_4;
DAT_005e6c28 = param_5; DAT_005e6c28 = param_5;
} }
gfx_d3d = Direct3DCreate8(0xdc);
static FnD3Create8 fn_Direct3DCreate8 = init_d3d_function();
gfx_d3d = fn_Direct3DCreate8(0xdc);
if (gfx_d3d == (IDirect3D8 *)0x0) { if (gfx_d3d == (IDirect3D8 *)0x0) {
return 1; return 1;
} }
HVar2 = (*gfx_d3d->lpVtbl->GetAdapterDisplayMode)(gfx_d3d,0,&displayMode); HVar2 = (*gfx_d3d->lpVtbl->GetAdapterDisplayMode)(gfx_d3d, 0, &displayMode);
if (HVar2 < 0) { if (HVar2 < 0) {
return 1; return 1;
} }
@ -79,14 +92,12 @@ undefined4 gfx_init(HWND hwnd,int param_2,UINT param_3,UINT param_4,int param_5)
param_5 = FUN_00484ea0(displayMode.Format); param_5 = FUN_00484ea0(displayMode.Format);
AdapterFormat = displayMode.Format; AdapterFormat = displayMode.Format;
DAT_005e6c28 = param_5; DAT_005e6c28 = param_5;
} } else {
else {
DStack_34.SwapEffect = D3DSWAPEFFECT_FLIP; DStack_34.SwapEffect = D3DSWAPEFFECT_FLIP;
if (param_5 == 0x10) { if (param_5 == 0x10) {
DStack_34.BackBufferFormat = D3DFMT_R5G6B5; DStack_34.BackBufferFormat = D3DFMT_R5G6B5;
AdapterFormat = D3DFMT_R5G6B5; AdapterFormat = D3DFMT_R5G6B5;
} } else {
else {
DStack_34.BackBufferFormat = D3DFMT_A8R8G8B8; DStack_34.BackBufferFormat = D3DFMT_A8R8G8B8;
AdapterFormat = D3DFMT_X8R8G8B8; AdapterFormat = D3DFMT_X8R8G8B8;
} }
@ -98,17 +109,17 @@ undefined4 gfx_init(HWND hwnd,int param_2,UINT param_3,UINT param_4,int param_5)
DStack_34.FullScreen_RefreshRateInHz = 0; DStack_34.FullScreen_RefreshRateInHz = 0;
DStack_34.BackBufferWidth = param_3; DStack_34.BackBufferWidth = param_3;
if (0x10 < param_5) { if (0x10 < param_5) {
HVar2 = (*gfx_d3d->lpVtbl->CheckDeviceFormat) HVar2 = (*gfx_d3d->lpVtbl->CheckDeviceFormat)(
(gfx_d3d,g_GLI_adapter,D3DDEVTYPE_HAL,AdapterFormat,2,D3DRTYPE_SURFACE, gfx_d3d, g_GLI_adapter, D3DDEVTYPE_HAL, AdapterFormat, 2,
D3DFMT_D24S8); D3DRTYPE_SURFACE, D3DFMT_D24S8);
if (HVar2 == 0) { if (HVar2 == 0) {
DStack_34.AutoDepthStencilFormat = D3DFMT_D24S8; DStack_34.AutoDepthStencilFormat = D3DFMT_D24S8;
DAT_0063be50 = 1; DAT_0063be50 = 1;
goto LAB_0046fa6f; goto LAB_0046fa6f;
} }
HVar2 = (*gfx_d3d->lpVtbl->CheckDeviceFormat) HVar2 = (*gfx_d3d->lpVtbl->CheckDeviceFormat)(
(gfx_d3d,g_GLI_adapter,D3DDEVTYPE_HAL,AdapterFormat,2,D3DRTYPE_SURFACE, gfx_d3d, g_GLI_adapter, D3DDEVTYPE_HAL, AdapterFormat, 2,
D3DFMT_D32); D3DRTYPE_SURFACE, D3DFMT_D32);
DAT_0063be50 = 0; DAT_0063be50 = 0;
if (HVar2 == 0) { if (HVar2 == 0) {
DStack_34.AutoDepthStencilFormat = D3DFMT_D32; DStack_34.AutoDepthStencilFormat = D3DFMT_D32;
@ -117,49 +128,57 @@ undefined4 gfx_init(HWND hwnd,int param_2,UINT param_3,UINT param_4,int param_5)
} }
DAT_0063be50 = 0; DAT_0063be50 = 0;
DStack_34.AutoDepthStencilFormat = D3DFMT_D16; DStack_34.AutoDepthStencilFormat = D3DFMT_D16;
(*gfx_d3d->lpVtbl->CheckDeviceFormat) (*gfx_d3d->lpVtbl->CheckDeviceFormat)(gfx_d3d, g_GLI_adapter, D3DDEVTYPE_HAL,
(gfx_d3d,g_GLI_adapter,D3DDEVTYPE_HAL,AdapterFormat,2,D3DRTYPE_SURFACE,D3DFMT_D16); AdapterFormat, 2, D3DRTYPE_SURFACE,
D3DFMT_D16);
LAB_0046fa6f: LAB_0046fa6f:
DStack_34.Flags = 1; DStack_34.Flags = 1;
if (g_GLI_tnl == '\0') { if (g_GLI_tnl == '\0') {
HVar2 = (*gfx_d3d->lpVtbl->CreateDevice) HVar2 =
(gfx_d3d,g_GLI_adapter,D3DDEVTYPE_HAL,hwnd,0x24,&DStack_34,&gfx_device); (*gfx_d3d->lpVtbl->CreateDevice)(gfx_d3d, g_GLI_adapter, D3DDEVTYPE_HAL,
hwnd, 0x24, &DStack_34, &gfx_device);
if (HVar2 < 0) { if (HVar2 < 0) {
return 1; return 1;
} }
} } else {
else { HVar2 =
HVar2 = (*gfx_d3d->lpVtbl->CreateDevice) (*gfx_d3d->lpVtbl->CreateDevice)(gfx_d3d, g_GLI_adapter, D3DDEVTYPE_HAL,
(gfx_d3d,g_GLI_adapter,D3DDEVTYPE_HAL,hwnd,0x44,&DStack_34,&gfx_device); hwnd, 0x44, &DStack_34, &gfx_device);
if ((HVar2 < 0) && if ((HVar2 < 0) && (HVar2 = (*gfx_d3d->lpVtbl->CreateDevice)(
(HVar2 = (*gfx_d3d->lpVtbl->CreateDevice) gfx_d3d, g_GLI_adapter, D3DDEVTYPE_HAL, hwnd, 0x24,
(gfx_d3d,g_GLI_adapter,D3DDEVTYPE_HAL,hwnd,0x24,&DStack_34,&gfx_device), &DStack_34, &gfx_device),
HVar2 < 0)) { HVar2 < 0)) {
return 1; return 1;
} }
} }
(*gfx_device->lpVtbl->SetRenderState)(gfx_device,D3DRS_NORMALIZENORMALS,0); (*gfx_device->lpVtbl->SetRenderState)(gfx_device, D3DRS_NORMALIZENORMALS, 0);
DAT_007eafa4 = 0; DAT_007eafa4 = 0;
(*gfx_device->lpVtbl->SetRenderState)(gfx_device,D3DRS_ZENABLE,1); (*gfx_device->lpVtbl->SetRenderState)(gfx_device, D3DRS_ZENABLE, 1);
DAT_007eafa0 = 1; DAT_007eafa0 = 1;
(*gfx_device->lpVtbl->SetRenderState)(gfx_device,D3DRS_ZFUNC,4); (*gfx_device->lpVtbl->SetRenderState)(gfx_device, D3DRS_ZFUNC, 4);
DAT_007eaf7c = 4; DAT_007eaf7c = 4;
(*gfx_device->lpVtbl->SetRenderState)(gfx_device,D3DRS_DITHERENABLE,1); (*gfx_device->lpVtbl->SetRenderState)(gfx_device, D3DRS_DITHERENABLE, 1);
(*gfx_device->lpVtbl->SetRenderState)(gfx_device,D3DRS_SPECULARENABLE,0); (*gfx_device->lpVtbl->SetRenderState)(gfx_device, D3DRS_SPECULARENABLE, 0);
(*gfx_device->lpVtbl->SetRenderState)(gfx_device,D3DRS_CULLMODE,1); (*gfx_device->lpVtbl->SetRenderState)(gfx_device, D3DRS_CULLMODE, 1);
(*gfx_device->lpVtbl->SetTextureStageState)(gfx_device,0,D3DTSS_COLORARG1,2); (*gfx_device->lpVtbl->SetTextureStageState)(gfx_device, 0, D3DTSS_COLORARG1,
(*gfx_device->lpVtbl->SetTextureStageState)(gfx_device,0,D3DTSS_COLORARG2,0); 2);
(*gfx_device->lpVtbl->SetTextureStageState)(gfx_device,0,D3DTSS_COLOROP,4); (*gfx_device->lpVtbl->SetTextureStageState)(gfx_device, 0, D3DTSS_COLORARG2,
(*gfx_device->lpVtbl->SetTextureStageState)(gfx_device,0,D3DTSS_MINFILTER,2); 0);
(*gfx_device->lpVtbl->SetTextureStageState)(gfx_device,0,D3DTSS_MAGFILTER,2); (*gfx_device->lpVtbl->SetTextureStageState)(gfx_device, 0, D3DTSS_COLOROP, 4);
(*gfx_device->lpVtbl->SetTextureStageState)(gfx_device,1,D3DTSS_MINFILTER,2); (*gfx_device->lpVtbl->SetTextureStageState)(gfx_device, 0, D3DTSS_MINFILTER,
(*gfx_device->lpVtbl->SetTextureStageState)(gfx_device,1,D3DTSS_MAGFILTER,2); 2);
(*gfx_device->lpVtbl->SetTextureStageState)(gfx_device, 0, D3DTSS_MAGFILTER,
2);
(*gfx_device->lpVtbl->SetTextureStageState)(gfx_device, 1, D3DTSS_MINFILTER,
2);
(*gfx_device->lpVtbl->SetTextureStageState)(gfx_device, 1, D3DTSS_MAGFILTER,
2);
FUN_00470b00(); FUN_00470b00();
(*gfx_device->lpVtbl->SetRenderState)(gfx_device,D3DRS_ALPHATESTENABLE,0); (*gfx_device->lpVtbl->SetRenderState)(gfx_device, D3DRS_ALPHATESTENABLE, 0);
(*gfx_device->lpVtbl->SetRenderState)(gfx_device,D3DRS_ALPHAFUNC,7); (*gfx_device->lpVtbl->SetRenderState)(gfx_device, D3DRS_ALPHAFUNC, 7);
(*gfx_device->lpVtbl->SetRenderState)(gfx_device,D3DRS_ALPHAREF,0xc0); (*gfx_device->lpVtbl->SetRenderState)(gfx_device, D3DRS_ALPHAREF, 0xc0);
(*gfx_device->lpVtbl->SetRenderState)(gfx_device,D3DRS_CLIPPING,1); (*gfx_device->lpVtbl->SetRenderState)(gfx_device, D3DRS_CLIPPING, 1);
(*gfx_device->lpVtbl->SetRenderState)(gfx_device,D3DRS_LIGHTING,0); (*gfx_device->lpVtbl->SetRenderState)(gfx_device, D3DRS_LIGHTING, 0);
DAT_007eafcc = 0x3f800000; DAT_007eafcc = 0x3f800000;
DAT_007eafc8 = 0x3f800000; DAT_007eafc8 = 0x3f800000;
DAT_007eafc4 = 0x3f800000; DAT_007eafc4 = 0x3f800000;
@ -173,13 +192,14 @@ LAB_0046fa6f:
DAT_007eaff0 = 0; DAT_007eaff0 = 0;
DAT_007eaffc = 0x3f800000; DAT_007eaffc = 0x3f800000;
DAT_007eb000 = 0; DAT_007eb000 = 0;
(*gfx_device->lpVtbl->SetMaterial)(gfx_device,(D3DMATERIAL8 *)&DAT_007eafc0); (*gfx_device->lpVtbl->SetMaterial)(gfx_device, (D3DMATERIAL8 *)&DAT_007eafc0);
(*gfx_device->lpVtbl->SetRenderState)(gfx_device,D3DRS_FOGVERTEXMODE,3); (*gfx_device->lpVtbl->SetRenderState)(gfx_device, D3DRS_FOGVERTEXMODE, 3);
if ((g_startOfGfxStruct.d3dSurface != (IDirect3DSurface8 *)0x0) || if ((g_startOfGfxStruct.d3dSurface != (IDirect3DSurface8 *)0x0) ||
(HVar2 = (*gfx_device->lpVtbl->GetBackBuffer) (HVar2 = (*gfx_device->lpVtbl->GetBackBuffer)(
(gfx_device,0,D3DBACKBUFFER_TYPE_MONO,&g_startOfGfxStruct.d3dSurface), gfx_device, 0, D3DBACKBUFFER_TYPE_MONO,
HVar2 == 0)) { &g_startOfGfxStruct.d3dSurface),
(*gfx_device->lpVtbl->GetDisplayMode)(gfx_device,&DStack_54); HVar2 == 0)) {
(*gfx_device->lpVtbl->GetDisplayMode)(gfx_device, &DStack_54);
DStack_54.Height = 0; DStack_54.Height = 0;
DStack_54.Width = DStack_54.RefreshRate; DStack_54.Width = DStack_54.RefreshRate;
g_perfCounterRate = (float)DStack_54.RefreshRate; g_perfCounterRate = (float)DStack_54.RefreshRate;
@ -187,6 +207,4 @@ LAB_0046fa6f:
} }
return 0; return 0;
} }
} }

View File

@ -4,13 +4,13 @@
#include <gh_global.h> #include <gh_global.h>
extern "C" { extern "C" {
undefined r3_module_big_init(void); // 00443f10 // r3_module_big_init undefined r3_module1_init(void); // 0043e630 // r3_module1_init // cdecl
undefined r3_module1_init(void); // 0043e630 // r3_module1_init byte Erm_fn_ucInitErrMsg(void); // 0043e1d0 // Erm_fn_ucInitErrMsg // stdcall
byte Erm_fn_ucInitErrMsg(void); // 0043e1d0 // Erm_fn_ucInitErrMsg undefined r3_module_big_init(void); // 00443f10 // r3_module_big_init // cdecl
undefined Mmg_fn_vFirstInitMmgModule(undefined1 ucMaxNbChannel); // 0043f830 // Mmg_fn_vFirstInitMmgModule undefined Mmg_fn_vFirstInitMmgModule(undefined1 ucMaxNbChannel); // 0043f830 // Mmg_fn_vFirstInitMmgModule // stdcall
// 00401000 // 00401000
void r3_initAllModules(void) void __cdecl r3_initAllModules(void)
{ {
char cVar1; char cVar1;

View File

@ -31,19 +31,16 @@ struct R3Bin {
R3Bin() { loadOriginal(); } R3Bin() { loadOriginal(); }
void loadOriginal() { void loadOriginal() {
// This assumes we're using the Rayman3 patched launcher as the exe
module = GetModuleHandle(nullptr);
SPDLOG_DEBUG("Loading original binary"); SPDLOG_DEBUG("Loading original binary");
auto &config = getDefaultConfig(); auto &config = getDefaultConfig();
std::string path = config.gameRootDir + "/Rayman3.exe";
module = LoadLibraryA(path.c_str());
if (!module)
throw std::runtime_error("Failed to load original binary");
fixupImports(module);
g_gh_translationOffset = translationOffset = g_gh_translationOffset = translationOffset =
uintptr_t(module) - GH_BASE_ADDR; uintptr_t(module) - GH_BASE_ADDR;
if (g_gh_translationOffset != 0)
throw std::runtime_error("Somehow the binary failed to load at the correct base address");
std::string msg = std::string msg =
fmt::format("Rayman3.exe Base address: 0x{:x}\n", uintptr_t(module)); fmt::format("Rayman3.exe Base address: 0x{:x}\n", uintptr_t(module));
@ -54,7 +51,6 @@ struct R3Bin {
OutputDebugStringA(msg.c_str()); OutputDebugStringA(msg.c_str());
// Now we have to relocate the module to the new base address // Now we have to relocate the module to the new base address
relocateModule();
patchFunctions(); patchFunctions();
} }
@ -202,7 +198,6 @@ struct R3Bin {
#define HOOK_S3(addr, name) HOOK(addr, name) #define HOOK_S3(addr, name) HOOK(addr, name)
#define HOOK_S4(addr, name) HOOK(addr, name) #define HOOK_S4(addr, name) HOOK(addr, name)
#define HOOK_S5(addr, name) HOOK(addr, name) #define HOOK_S5(addr, name) HOOK(addr, name)
#include "hooks.def" #include "hooks.def"
} }

View File

@ -1,5 +1,6 @@
#include <windows.h> #include <windows.h>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <stdexcept> #include <stdexcept>
#include <stdio.h> #include <stdio.h>
#include <r3/binders/stub.h> #include <r3/binders/stub.h>
@ -21,15 +22,18 @@ void gh_pre_main(void);
extern "C" int r3_main(HINSTANCE hInstance, HINSTANCE hPrevInstance, extern "C" int r3_main(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR *cmdline, int showCmd); LPSTR *cmdline, int showCmd);
int mainImpl(int argc, char **argv) {
std::shared_ptr<spdlog::logger> logger = spdlog::stderr_color_mt("game_re");
spdlog::set_default_logger(logger);
int main(int argc, char **argv) { SPDLOG_INFO("Starting Reman 3: The hooded ones");
CLI::App app("Reman 3: The hooded ones"); CLI::App app("Reman 3: The hooded ones");
std::string log_level = "info"; std::string log_level = "info";
app.add_option("-l,--log-level", log_level, "Log level"); app.add_option("-l,--log-level", log_level, "Log level");
CLI11_PARSE(app, argc, argv); CLI11_PARSE(app, argc, argv);
auto log_level_enum = magic_enum::enum_cast<spdlog::level::level_enum>(log_level); auto log_level_enum =
magic_enum::enum_cast<spdlog::level::level_enum>(log_level);
if (log_level_enum.has_value()) { if (log_level_enum.has_value()) {
spdlog::set_level(log_level_enum.value()); spdlog::set_level(log_level_enum.value());
} else { } else {
@ -45,9 +49,59 @@ int main(int argc, char **argv) {
gh_init_data_segment(); gh_init_data_segment();
#endif #endif
r3_main(GetModuleHandle(NULL), NULL, argv, SW_SHOW); r3_main(GetModuleHandle(NULL), NULL, (char **)argv, SW_SHOW);
} catch (const std::exception &e) { } catch (const std::exception &e) {
SPDLOG_ERROR("Unhandled exception: {}", e.what()); SPDLOG_ERROR("Unhandled exception: {}", e.what());
} }
return 0; return 0;
} }
#if RE_DBG_INJECTED
static void setupWindowsStdErrLogging() {
// Check if stderr is redirected
HANDLE stderrHandle = GetStdHandle(STD_ERROR_HANDLE);
DWORD handleType = GetFileType(stderrHandle);
bool isRedirected = (handleType != FILE_TYPE_UNKNOWN);
if (!isRedirected && AttachConsole(ATTACH_PARENT_PROCESS)) {
freopen("CONOUT$", "wb", stderr);
HANDLE conOut = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);
DWORD mode{};
if (GetConsoleMode(conOut, &mode))
SetConsoleMode(conOut, mode | ENABLE_VIRTUAL_TERMINAL_INPUT);
SetStdHandle(STD_ERROR_HANDLE, conOut);
}
}
extern "C" int __declspec(dllexport) __cdecl re_dbg_attached(
const char *cmdLine_) {
auto split = CLI::detail::split_program_name(cmdLine_);
auto cmdLine = std::move(split.second);
cmdLine =
CLI::detail::find_and_modify(cmdLine, "=", CLI::detail::escape_detect);
auto args = CLI::detail::split_up(std::move(cmdLine));
// Remove arguments to Rayman3p launcher
args.erase(args.begin());
// Remove empty
args.erase(std::remove(args.begin(), args.end(), std::string{}), args.end());
std::vector<char *> args_c{split.first.data()};
for (auto &arg : args) {
args_c.push_back(arg.data());
}
args_c.push_back(nullptr);
// Attach process console
setupWindowsStdErrLogging();
try {
return mainImpl(args_c.size() - 1, args_c.data());
} catch (...) {
SPDLOG_ERROR("Unhandled exception in re_dbg_attached");
return 1;
}
}
#else
int main(int argc, char **argv) { return mainImpl(argc, argv); }
#endif

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerCommand>C:\Projects\R3\game\Rayman3p.exe</LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommandArguments>$(TargetPath)</LocalDebuggerCommandArguments>
</PropertyGroup>
</Project>

View File

@ -62,14 +62,17 @@ extern "C" __cdecl void ref() {
goto fail; goto fail;
} }
// Successfully loaded DLL auto fn = (int (*)(const char *))GetProcAddress(hModule, "re_dbg_attached");
MessageBoxA(NULL, "DLL loaded successfully", "Success", if (fn == NULL) {
MB_OK | MB_ICONINFORMATION); MessageBoxA(NULL, "Failed to get function address", "Error",
MB_OK | MB_ICONERROR);
goto fail;
}
fn(cmdLine);
// Free the library
FreeLibrary(hModule); FreeLibrary(hModule);
return;
fail: fail:
ExitProcess(1); ExitProcess(1);
} }

View File

@ -8,21 +8,6 @@ if(WIN32)
IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/bink/binkw32.lib IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/bink/binkw32.lib
) )
# Copy to output dir
if(CMAKE_CONFIGURATION_TYPES)
# Multi-config generators (MSVC, Xcode, etc.)
set(BINK_DST ${CMAKE_BINARY_DIR}/bin/$<CONFIG>/binkw32.dll)
else()
# Single-config generators (Make, Ninja, etc.)
set(BINK_DST ${CMAKE_BINARY_DIR}/bin/binkw32.dll)
endif()
add_custom_command(
OUTPUT ${BINK_DST}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/third_party/bink/binkw32.dll ${BINK_DST}
)
add_custom_target(copy_binkw32 ALL DEPENDS ${BINK_DST})
add_dependencies(binkw32_imp copy_binkw32)
add_library(binkw32 INTERFACE) add_library(binkw32 INTERFACE)
target_link_libraries(binkw32 INTERFACE binkw32_imp) target_link_libraries(binkw32 INTERFACE binkw32_imp)