segatools/mu3hook/dllmain.c
beerpsi 4041844ea9 mai2/mu3/cm: Integrate UnityDoorstop with segatools (#11)
[UnityDoorstop](https://github.com/NeighTools/UnityDoorstop) is a tool to execute managed code (.NET DLLs) before Unity does, useful for modding frameworks such as BepInEx.

This PR integrates parts of its code into segatools, so loading BepInEx is as simple as adding 2 lines to `segatools.ini`:
```ini
[unity]
targetAssembly=BepInEx\core\BepInEx.Preloader.dll
```

This PR also factors out the Unity path redirection hooks to its own module.

Reviewed-on: Dniel97/segatools#11
Co-authored-by: beerpsi <beerpsi@duck.com>
Co-committed-by: beerpsi <beerpsi@duck.com>
2024-04-15 19:30:28 +00:00

137 lines
2.7 KiB
C

#include <windows.h>
#include <stdlib.h>
#include "board/sg-reader.h"
#include "board/vfd.h"
#include "gfxhook/d3d9.h"
#include "gfxhook/d3d11.h"
#include "gfxhook/dxgi.h"
#include "gfxhook/gfx.h"
#include "hook/process.h"
#include "hooklib/dvd.h"
#include "hooklib/serial.h"
#include "hooklib/spike.h"
#include "mu3hook/config.h"
#include "mu3hook/io4.h"
#include "mu3hook/mu3-dll.h"
#include "platform/platform.h"
#include "unityhook/config.h"
#include "unityhook/hook.h"
#include "util/dprintf.h"
static HMODULE mu3_hook_mod;
static process_entry_t mu3_startup;
static struct mu3_hook_config mu3_hook_cfg;
static DWORD CALLBACK mu3_pre_startup(void)
{
HRESULT hr;
dprintf("--- Begin mu3_pre_startup ---\n");
/* Load config */
mu3_hook_config_load(&mu3_hook_cfg, L".\\segatools.ini");
/* Hook Win32 APIs */
dvd_hook_init(&mu3_hook_cfg.dvd, mu3_hook_mod);
gfx_hook_init(&mu3_hook_cfg.gfx);
gfx_d3d9_hook_init(&mu3_hook_cfg.gfx, mu3_hook_mod);
gfx_d3d11_hook_init(&mu3_hook_cfg.gfx, mu3_hook_mod);
gfx_dxgi_hook_init(&mu3_hook_cfg.gfx, mu3_hook_mod);
serial_hook_init();
/* Initialize emulation hooks */
hr = platform_hook_init(
&mu3_hook_cfg.platform,
"SDDT",
"ACA1",
mu3_hook_mod);
if (FAILED(hr)) {
goto fail;
}
/*
// Does not work, Unity moment
hr = led15093_hook_init(&mu3_hook_cfg.led15093, 3, 1, 1, 2);
if (FAILED(hr)) {
return hr;
}
*/
hr = sg_reader_hook_init(&mu3_hook_cfg.aime, 1, 1, mu3_hook_mod);
if (FAILED(hr)) {
goto fail;
}
hr = vfd_hook_init(&mu3_hook_cfg.vfd, 2);
if (FAILED(hr)) {
goto fail;
}
hr = mu3_dll_init(&mu3_hook_cfg.dll, mu3_hook_mod);
if (FAILED(hr)) {
goto fail;
}
hr = mu3_io4_hook_init(&mu3_hook_cfg.io4);
if (FAILED(hr)) {
goto fail;
}
/* Initialize Unity native plugin DLL hooks
There seems to be an issue with other DLL hooks if `LoadLibraryW` is
hooked earlier in the `mu3hook` initialization. */
unity_hook_init(&mu3_hook_cfg.unity, mu3_hook_mod);
/* Initialize debug helpers */
spike_hook_init(L".\\segatools.ini");
dprintf("--- End mu3_pre_startup ---\n");
/* Jump to EXE start address */
return mu3_startup();
fail:
ExitProcess(EXIT_FAILURE);
}
BOOL WINAPI DllMain(HMODULE mod, DWORD cause, void *ctx)
{
HRESULT hr;
if (cause != DLL_PROCESS_ATTACH) {
return TRUE;
}
mu3_hook_mod = mod;
hr = process_hijack_startup(mu3_pre_startup, &mu3_startup);
if (!SUCCEEDED(hr)) {
dprintf("Failed to hijack process startup: %x\n", (int) hr);
}
return SUCCEEDED(hr);
}