forked from Hay1tsme/segatools
[apm3] hook video loading, bug fixes
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
# Segatools
|
# Segatools
|
||||||
|
|
||||||
Version: `2025-07-20`
|
Version: `2025-07-27`
|
||||||
|
|
||||||
Loaders and hardware emulators for SEGA games that run on the Nu and ALLS platforms.
|
Loaders and hardware emulators for SEGA games that run on the Nu and ALLS platforms.
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
dist/apm3/segatools.ini
vendored
4
dist/apm3/segatools.ini
vendored
@ -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
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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(
|
||||||
|
@ -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 */
|
||||||
|
@ -28,5 +28,7 @@ shared_library(
|
|||||||
'io4.h',
|
'io4.h',
|
||||||
'mount.c',
|
'mount.c',
|
||||||
'mount.h',
|
'mount.h',
|
||||||
|
'video.c',
|
||||||
|
'video.h',
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
115
games/apm3hook/video.c
Normal 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
10
games/apm3hook/video.h
Normal 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);
|
Reference in New Issue
Block a user