[apm3] hook video loading, bug fixes

This commit is contained in:
2025-07-27 19:20:36 +02:00
parent bb01e131e9
commit ec00a83d6b
10 changed files with 170 additions and 37 deletions

View File

@ -95,7 +95,6 @@ static void dll_hook_insert_hooks(HMODULE target) {
static HMODULE WINAPI hook_LoadLibraryExW(const wchar_t *name, HANDLE hFile, DWORD dwFlags) static HMODULE WINAPI hook_LoadLibraryExW(const wchar_t *name, HANDLE hFile, DWORD dwFlags)
{ {
// dprintf("Unity: LoadLibraryExW %ls\n", name);
return hook_LoadLibraryW(name); return hook_LoadLibraryW(name);
} }
@ -157,11 +156,6 @@ static HMODULE WINAPI hook_LoadLibraryW(const wchar_t *name)
if (hook_load_callback != NULL){ if (hook_load_callback != NULL){
hook_load_callback(result, target_module); hook_load_callback(result, target_module);
} }
// Not needed?
// serial_hook_apply_hooks(result);
// Unity will crash during option loading when we hook this twice
// iohook_apply_hooks(result);
} }
} }

View File

@ -122,6 +122,10 @@ enable=1
; is not cut off. ; is not cut off.
delay=1 delay=1
[video]
; Enables VFS (C:\Mount\Option) path rewrite for AVProVideo.
enable=1
; ----------------------------------------------------------------------------- ; -----------------------------------------------------------------------------
; Custom IO settings ; Custom IO settings
; ----------------------------------------------------------------------------- ; -----------------------------------------------------------------------------

View File

@ -93,6 +93,10 @@ void mount_config_load(struct mount_config *cfg, const wchar_t *filename) {
cfg->delay = GetPrivateProfileIntW(L"mount", L"delay", 1, filename); cfg->delay = GetPrivateProfileIntW(L"mount", L"delay", 1, filename);
} }
void video_config_load(struct video_config *cfg, const wchar_t *filename) {
cfg->enable = GetPrivateProfileIntW(L"video", L"enable", 1, filename);
}
void apm3_hook_config_load( void apm3_hook_config_load(
struct apm3_hook_config *cfg, struct apm3_hook_config *cfg,
const wchar_t *filename) const wchar_t *filename)
@ -110,4 +114,5 @@ void apm3_hook_config_load(
apm3_dll_config_load(&cfg->dll, filename); apm3_dll_config_load(&cfg->dll, filename);
unity_config_load(&cfg->unity, filename); unity_config_load(&cfg->unity, filename);
mount_config_load(&cfg->mount, filename); mount_config_load(&cfg->mount, filename);
video_config_load(&cfg->video, filename);
} }

View File

@ -11,16 +11,13 @@
#include "gfxhook/config.h" #include "gfxhook/config.h"
#include "apm3hook/apm3-dll.h" #include "apm3-dll.h"
#include "mount.h"
#include "video.h"
#include "platform/config.h" #include "platform/config.h"
#include "unityhook/config.h" #include "unityhook/config.h"
struct mount_config {
bool enable;
bool delay;
};
struct apm3_hook_config { struct apm3_hook_config {
struct platform_config platform; struct platform_config platform;
struct aime_config aime; struct aime_config aime;
@ -32,6 +29,7 @@ struct apm3_hook_config {
struct apm3_dll_config dll; struct apm3_dll_config dll;
struct unity_config unity; struct unity_config unity;
struct mount_config mount; struct mount_config mount;
struct video_config video;
}; };
void apm3_dll_config_load( void apm3_dll_config_load(

View File

@ -16,6 +16,7 @@
#include "config.h" #include "config.h"
#include "io4.h" #include "io4.h"
#include "mount.h" #include "mount.h"
#include "video.h"
#include "hook/iohook.h" #include "hook/iohook.h"
#include "hook/process.h" #include "hook/process.h"
@ -52,9 +53,7 @@ void unity_hook_callback(HMODULE hmodule, const wchar_t* p) {
iohook_apply_hooks(hmodule); iohook_apply_hooks(hmodule);
} }
} }
security_hook_insert_hooks(hmodule);
touch_hook_insert_hooks(hmodule); touch_hook_insert_hooks(hmodule);
// mount_hook_apply_hooks(&apm3_hook_cfg.mount, hmodule);
} }
static DWORD CALLBACK apm3_pre_startup(void) static DWORD CALLBACK apm3_pre_startup(void)
@ -73,8 +72,21 @@ static DWORD CALLBACK apm3_pre_startup(void)
touch_screen_hook_init(&apm3_hook_cfg.touch, apm3_hook_mod); touch_screen_hook_init(&apm3_hook_cfg.touch, apm3_hook_mod);
serial_hook_init(); serial_hook_init();
/* Hook external DLL APIs */
mount_hook_init(&apm3_hook_cfg.platform.vfs, &apm3_hook_cfg.mount);
av_pro_video_hook_init(&apm3_hook_cfg.video);
/* Initialize emulation hooks */ /* Initialize emulation hooks */
struct dipsw_config new_dipsw_config[8] = {
{L"LAN Install", L"Server", L"Client"},
};
// Set the system dip switch configuration
memcpy(apm3_hook_cfg.platform.system.dipsw_config, new_dipsw_config,
sizeof(new_dipsw_config));
hr = platform_hook_init( hr = platform_hook_init(
&apm3_hook_cfg.platform, &apm3_hook_cfg.platform,
"SDEM", "SDEM",
@ -117,20 +129,6 @@ static DWORD CALLBACK apm3_pre_startup(void)
goto fail; goto fail;
} }
hr = security_hook_init();
if (FAILED(hr)) {
goto fail;
}
touch_screen_hook_init(&apm3_hook_cfg.touch, apm3_hook_mod);
mount_hook_init(&apm3_hook_cfg.platform.vfs, &apm3_hook_cfg.mount);
security_hook_insert_hooks(NULL);
mount_hook_apply_hooks(NULL);
unity_hook_init(&apm3_hook_cfg.unity, apm3_hook_mod, unity_hook_callback); unity_hook_init(&apm3_hook_cfg.unity, apm3_hook_mod, unity_hook_callback);
/* Initialize debug helpers */ /* Initialize debug helpers */

View File

@ -28,5 +28,7 @@ shared_library(
'io4.h', 'io4.h',
'mount.c', 'mount.c',
'mount.h', 'mount.h',
'video.c',
'video.h',
], ],
) )

View File

@ -62,15 +62,17 @@ void mount_hook_init(struct vfs_config* vfs_cfg, struct mount_config* mount_cfg)
return; return;
} }
dprintf("Mount: Hook enabled\n"); mount_hook_apply_hooks(NULL);
dprintf("Mount: hook enabled\n");
} }
void mount_hook_apply_hooks(HMODULE module) { void mount_hook_apply_hooks(HMODULE target) {
if (!mcfg->enable) { proc_addr_table_push(
return; target,
} "apmmount.dll",
mount_hooks,
proc_addr_table_push(module, "apmmount.dll", mount_hooks, _countof(mount_hooks)); _countof(mount_hooks));
} }

View File

@ -1,7 +1,12 @@
#pragma once #pragma once
#include "board/aime-dll.h" #include "board/aime-dll.h"
#include "config.h" #include "platform/vfs.h"
void mount_hook_apply_hooks(HMODULE module); struct mount_config {
bool enable;
bool delay;
};
void mount_hook_apply_hooks(HMODULE target);
void mount_hook_init(struct vfs_config* vfs_cfg, struct mount_config* mount_cfg); void mount_hook_init(struct vfs_config* vfs_cfg, struct mount_config* mount_cfg);

115
games/apm3hook/video.c Normal file
View File

@ -0,0 +1,115 @@
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include "video.h"
#include "hook/procaddr.h"
#include "hooklib/dll.h"
#include "hooklib/path.h"
#include "util/dprintf.h"
static void* WINAPI hook_OpenSource(
void* instance,
const wchar_t* path,
int videoApiIndex,
bool useHardwareDecoding,
bool generateTextureMips,
bool hintAlphaChannel,
bool useLowLatency,
const wchar_t* forceAudioOutputDeviceName,
bool useUnityAudio,
bool forceResample,
int sampleRate,
const wchar_t** preferredFilter,
uint32_t numFilters,
int audioChannelMode,
uint32_t sourceSampleRate,
uint32_t sourceChannels
);
static void* (WINAPI *next_OpenSource)(
void* instance,
const wchar_t* path,
int videoApiIndex,
bool useHardwareDecoding,
bool generateTextureMips,
bool hintAlphaChannel,
bool useLowLatency,
const wchar_t* forceAudioOutputDeviceName,
bool useUnityAudio,
bool forceResample,
int sampleRate,
const wchar_t** preferredFilter,
uint32_t numFilters,
int audioChannelMode,
uint32_t sourceSampleRate,
uint32_t sourceChannels
);
static const struct hook_symbol av_pro_video_syms[] = {
{
.name = "OpenSource",
.patch = hook_OpenSource,
.link = (void **) &next_OpenSource,
}
};
void av_pro_video_hook_init(struct video_config* video_cfg)
{
assert(video_cfg != NULL);
if (!video_cfg->enable) {
return;
}
av_pro_video_hook_insert_hooks(NULL);
dprintf("Video: hook enabled.\n");
}
void av_pro_video_hook_insert_hooks(HMODULE target)
{
proc_addr_table_push(
target,
"AVProVideo.dll",
av_pro_video_syms,
_countof(av_pro_video_syms));
}
static void* WINAPI hook_OpenSource(
void* instance,
const wchar_t* path,
int videoApiIndex,
bool useHardwareDecoding,
bool generateTextureMips,
bool hintAlphaChannel,
bool useLowLatency,
const wchar_t* forceAudioOutputDeviceName,
bool useUnityAudio,
bool forceResample,
int sampleRate,
const wchar_t** preferredFilter,
uint32_t numFilters,
int audioChannelMode,
uint32_t sourceSampleRate,
uint32_t sourceChannels
) {
wchar_t *trans;
BOOL ok;
ok = path_transform_w(&trans, path);
if (!ok) {
dprintf("AVProVideo: Path transformation error\n");
return NULL;
}
return next_OpenSource(
instance, trans ? trans : path, videoApiIndex, useHardwareDecoding, generateTextureMips,
hintAlphaChannel, useLowLatency, forceAudioOutputDeviceName, useUnityAudio,
forceResample, sampleRate, preferredFilter, numFilters, audioChannelMode,
sourceSampleRate, sourceChannels);
}

10
games/apm3hook/video.h Normal file
View File

@ -0,0 +1,10 @@
#pragma once
#include <windows.h>
struct video_config {
bool enable;
};
void av_pro_video_hook_init(struct video_config* video_cfg);
void av_pro_video_hook_insert_hooks(HMODULE target);