d3d9exhook: refactor d3d9ex hook from sdvxhook2 to shared library

This commit is contained in:
Will Xyen
2019-11-30 09:59:12 -05:00
parent 51a697659b
commit ddd7853810
14 changed files with 240 additions and 221 deletions

View File

@@ -15,6 +15,7 @@ libs_sdvxhook2 := \
acioemu \
bio2emu \
camhook \
d3d9exhook \
sdvxio \
hook \
hooklib \
@@ -26,6 +27,4 @@ src_sdvxhook2 := \
acio.c \
bi2a.c \
dllmain.c \
d3d9.c \
config-gfx.c \
config-io.c \

View File

@@ -1,96 +0,0 @@
#include <string.h>
#include "cconfig/cconfig-util.h"
#include "sdvxhook2/config-gfx.h"
#include "util/log.h"
#define SDVXHOOK2_CONFIG_GFX_FRAMED_KEY "gfx.framed"
#define SDVXHOOK2_CONFIG_GFX_WINDOWED_KEY "gfx.windowed"
#define SDVXHOOK2_CONFIG_GFX_WINDOW_WIDTH_KEY "gfx.window_width"
#define SDVXHOOK2_CONFIG_GFX_WINDOW_HEIGHT_KEY "gfx.window_height"
#define SDVXHOOK2_CONFIG_GFX_DEFAULT_FRAMED_VALUE false
#define SDVXHOOK2_CONFIG_GFX_DEFAULT_WINDOWED_VALUE false
#define SDVXHOOK2_CONFIG_GFX_DEFAULT_WINDOW_WIDTH_VALUE -1
#define SDVXHOOK2_CONFIG_GFX_DEFAULT_WINDOW_HEIGHT_VALUE -1
void sdvxhook2_config_gfx_init(struct cconfig *config)
{
cconfig_util_set_bool(
config,
SDVXHOOK2_CONFIG_GFX_FRAMED_KEY,
SDVXHOOK2_CONFIG_GFX_DEFAULT_FRAMED_VALUE,
"Run the game in a framed window (requires windowed option)");
cconfig_util_set_bool(
config,
SDVXHOOK2_CONFIG_GFX_WINDOWED_KEY,
SDVXHOOK2_CONFIG_GFX_DEFAULT_WINDOWED_VALUE,
"Run the game windowed");
cconfig_util_set_int(
config,
SDVXHOOK2_CONFIG_GFX_WINDOW_WIDTH_KEY,
SDVXHOOK2_CONFIG_GFX_DEFAULT_WINDOW_WIDTH_VALUE,
"Windowed width, -1 for default size");
cconfig_util_set_int(
config,
SDVXHOOK2_CONFIG_GFX_WINDOW_HEIGHT_KEY,
SDVXHOOK2_CONFIG_GFX_DEFAULT_WINDOW_HEIGHT_VALUE,
"Windowed height, -1 for default size");
}
void sdvxhook2_config_gfx_get(
struct sdvxhook2_config_gfx *config_gfx, struct cconfig *config)
{
if (!cconfig_util_get_bool(
config,
SDVXHOOK2_CONFIG_GFX_FRAMED_KEY,
&config_gfx->framed,
SDVXHOOK2_CONFIG_GFX_DEFAULT_FRAMED_VALUE)) {
log_warning(
"Invalid value for key '%s' specified, fallback "
"to default '%d'",
SDVXHOOK2_CONFIG_GFX_FRAMED_KEY,
SDVXHOOK2_CONFIG_GFX_DEFAULT_FRAMED_VALUE);
}
if (!cconfig_util_get_bool(
config,
SDVXHOOK2_CONFIG_GFX_WINDOWED_KEY,
&config_gfx->windowed,
SDVXHOOK2_CONFIG_GFX_DEFAULT_WINDOWED_VALUE)) {
log_warning(
"Invalid value for key '%s' specified, fallback "
"to default '%d'",
SDVXHOOK2_CONFIG_GFX_WINDOWED_KEY,
SDVXHOOK2_CONFIG_GFX_DEFAULT_WINDOWED_VALUE);
}
if (!cconfig_util_get_int(
config,
SDVXHOOK2_CONFIG_GFX_WINDOW_WIDTH_KEY,
&config_gfx->window_width,
SDVXHOOK2_CONFIG_GFX_DEFAULT_WINDOW_WIDTH_VALUE)) {
log_warning(
"Invalid value for key '%s' specified, fallback "
"to default '%d'",
SDVXHOOK2_CONFIG_GFX_WINDOW_WIDTH_KEY,
SDVXHOOK2_CONFIG_GFX_DEFAULT_WINDOW_WIDTH_VALUE);
}
if (!cconfig_util_get_int(
config,
SDVXHOOK2_CONFIG_GFX_WINDOW_HEIGHT_KEY,
&config_gfx->window_height,
SDVXHOOK2_CONFIG_GFX_DEFAULT_WINDOW_HEIGHT_VALUE)) {
log_warning(
"Invalid value for key '%s' specified, fallback "
"to default '%d'",
SDVXHOOK2_CONFIG_GFX_WINDOW_HEIGHT_KEY,
SDVXHOOK2_CONFIG_GFX_DEFAULT_WINDOW_HEIGHT_VALUE);
}
}

View File

@@ -1,18 +0,0 @@
#ifndef SDVXHOOK2_CONFIG_GFX_H
#define SDVXHOOK2_CONFIG_GFX_H
#include "cconfig/cconfig.h"
struct sdvxhook2_config_gfx {
bool framed;
bool windowed;
int32_t window_width;
int32_t window_height;
};
void sdvxhook2_config_gfx_init(struct cconfig *config);
void sdvxhook2_config_gfx_get(
struct sdvxhook2_config_gfx *config_gfx, struct cconfig *config);
#endif

View File

@@ -1,314 +0,0 @@
#define LOG_MODULE "d3d9-hook"
#include <d3d9.h>
#include <d3dx9core.h>
#include <windows.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "hook/com-proxy.h"
#include "hook/table.h"
#include "sdvxhook2/d3d9.h"
#include "util/defs.h"
#include "util/log.h"
#include "util/str.h"
#include "util/time.h"
/* ------------------------------------------------------------------------- */
// thanks to Felix for reminding Xyen to hook 9Ex instead of 9
static HWND STDCALL my_CreateWindowExA(
DWORD dwExStyle,
LPCSTR lpClassName,
LPCSTR lpWindowName,
DWORD dwStyle,
int X,
int Y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam);
static HRESULT STDCALL my_CreateDeviceEx(
IDirect3D9Ex *self,
UINT adapter,
D3DDEVTYPE type,
HWND hwnd,
DWORD flags,
D3DPRESENT_PARAMETERS *pp,
D3DDISPLAYMODEEX *fdm,
IDirect3DDevice9Ex **pdev);
static HRESULT STDCALL my_Direct3DCreate9Ex(UINT sdk_ver, IDirect3D9Ex **api);
static BOOL STDCALL my_EnumDisplayDevicesA(
const char *dev_name, DWORD dev_num, DISPLAY_DEVICEA *info, DWORD flags);
static BOOL STDCALL
my_MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint);
static void calc_win_size_with_framed(
HWND hwnd, DWORD x, DWORD y, DWORD width, DWORD height, LPWINDOWPOS wp);
static HWND(STDCALL *real_CreateWindowExA)(
DWORD dwExStyle,
LPCSTR lpClassName,
LPCSTR lpWindowName,
DWORD dwStyle,
int X,
int Y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam);
static HRESULT(STDCALL *real_Direct3DCreate9Ex)(
UINT sdk_ver, IDirect3D9Ex **api);
static BOOL(STDCALL *real_EnumDisplayDevicesA)(
const char *dev_name, DWORD dev_num, DISPLAY_DEVICEA *info, DWORD flags);
static BOOL(STDCALL *real_MoveWindow)(
HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint);
/* ------------------------------------------------------------------------- */
static char d3d9_pci_id[32];
static bool d3d9_windowed;
static int32_t d3d9_window_width = -1;
static int32_t d3d9_window_height = -1;
static bool d3d9_window_framed;
/* ------------------------------------------------------------------------- */
static const struct hook_symbol d3d9_hook_syms[] = {
{.name = "Direct3DCreate9Ex",
.patch = my_Direct3DCreate9Ex,
.link = (void **) &real_Direct3DCreate9Ex},
};
static const struct hook_symbol d3d9_hook_user32_syms[] = {
{.name = "EnumDisplayDevicesA",
.patch = my_EnumDisplayDevicesA,
.link = (void **) &real_EnumDisplayDevicesA},
{.name = "CreateWindowExA",
.patch = my_CreateWindowExA,
.link = (void **) &real_CreateWindowExA},
{.name = "MoveWindow",
.patch = my_MoveWindow,
.link = (void **) &real_MoveWindow},
};
/* ------------------------------------------------------------------------- */
static HWND STDCALL my_CreateWindowExA(
DWORD dwExStyle,
LPCSTR lpClassName,
LPCSTR lpWindowName,
DWORD dwStyle,
int X,
int Y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam)
{
if (d3d9_windowed && d3d9_window_framed) {
/* use a different style */
dwStyle |= WS_OVERLAPPEDWINDOW;
/* also show mouse cursor */
ShowCursor(TRUE);
}
HWND hwnd = real_CreateWindowExA(
dwExStyle,
lpClassName,
lpWindowName,
dwStyle,
X,
Y,
nWidth,
nHeight,
hWndParent,
hMenu,
hInstance,
lpParam);
return hwnd;
}
static BOOL STDCALL
my_MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint)
{
if (d3d9_windowed && d3d9_window_framed) {
/* we have to adjust the window size, because the window needs to be a
slightly bigger than the rendering resolution (window caption and
stuff is included in the window size) */
if (d3d9_window_width != -1 && d3d9_window_height != -1) {
log_misc(
"Overriding window size from %dx%d with %dx%d",
nWidth,
nHeight,
d3d9_window_width,
d3d9_window_height);
nWidth = d3d9_window_width;
nHeight = d3d9_window_height;
}
WINDOWPOS wp;
calc_win_size_with_framed(hWnd, X, Y, nWidth, nHeight, &wp);
SetWindowPos(hWnd, 0, wp.x, wp.y, wp.cx, wp.cy, 0);
X = wp.x;
Y = wp.y;
nWidth = wp.cx;
nHeight = wp.cy;
}
BOOL result = real_MoveWindow(hWnd, X, Y, nWidth, nHeight, bRepaint);
return result;
}
static HRESULT STDCALL my_CreateDeviceEx(
IDirect3D9Ex *self,
UINT adapter,
D3DDEVTYPE type,
HWND hwnd,
DWORD flags,
D3DPRESENT_PARAMETERS *pp,
D3DDISPLAYMODEEX *fdm,
IDirect3DDevice9Ex **pdev)
{
IDirect3D9Ex *real = COM_PROXY_UNWRAP(self);
HRESULT hr;
if (d3d9_windowed) {
fdm = NULL;
pp->Windowed = TRUE;
pp->FullScreen_RefreshRateInHz = 0;
}
hr = IDirect3D9Ex_CreateDeviceEx(
real, adapter, type, hwnd, flags, pp, fdm, pdev);
// TODO stuff
return hr;
}
static HRESULT STDCALL my_Direct3DCreate9Ex(UINT sdk_ver, IDirect3D9Ex **api)
{
HRESULT hr;
IDirect3D9ExVtbl *api_vtbl;
struct com_proxy *api_proxy;
IDirect3D9Ex *api_;
log_info("Direct3DCreate9Ex hook hit");
hr = real_Direct3DCreate9Ex(sdk_ver, api);
api_ = *api;
api_proxy = com_proxy_wrap(api_, sizeof(*api_->lpVtbl));
api_vtbl = api_proxy->vptr;
api_vtbl->CreateDeviceEx = my_CreateDeviceEx;
*api = (IDirect3D9Ex *) api_proxy;
return hr;
}
static BOOL STDCALL my_EnumDisplayDevicesA(
const char *dev_name, DWORD dev_num, DISPLAY_DEVICEA *info, DWORD flags)
{
BOOL ok;
ok = real_EnumDisplayDevicesA(dev_name, dev_num, info, flags);
if (ok && d3d9_pci_id[0] != '\0') {
/* Apparently Konami didn't read the "Not Used" message in the MSDN
docs for DISPLAY_DEVICE */
log_misc("Replacing device ID %s with %s", info->DeviceID, d3d9_pci_id);
str_cpy(info->DeviceID, sizeof(info->DeviceID), d3d9_pci_id);
}
return ok;
}
void d3d9_hook_init(void)
{
hook_table_apply(
NULL, "d3d9.dll", d3d9_hook_syms, lengthof(d3d9_hook_syms));
hook_table_apply(
NULL,
"user32.dll",
d3d9_hook_user32_syms,
lengthof(d3d9_hook_user32_syms));
log_info("Inserted graphics hooks");
}
void d3d9_set_windowed(bool framed, int32_t width, int32_t height)
{
d3d9_windowed = true;
d3d9_window_framed = framed;
d3d9_window_width = width;
d3d9_window_height = height;
}
/* ------------------------------------------------------------------------- */
static void calc_win_size_with_framed(
HWND hwnd, DWORD x, DWORD y, DWORD width, DWORD height, LPWINDOWPOS wp)
{
/* taken from dxwnd */
RECT rect;
DWORD style;
int max_x, max_y;
HMENU menu;
rect.left = x;
rect.top = y;
max_x = width;
max_y = height;
rect.right = x + max_x;
rect.bottom = y + max_y;
style = GetWindowLong(hwnd, GWL_STYLE);
menu = GetMenu(hwnd);
AdjustWindowRect(&rect, style, (menu != NULL));
/* shift down-right so that the border is visible
and also update the iPosX,iPosY upper-left coordinates
of the client area */
if (rect.left < 0) {
rect.right -= rect.left;
rect.left = 0;
}
if (rect.top < 0) {
rect.bottom -= rect.top;
rect.top = 0;
}
wp->x = rect.left;
wp->y = rect.top;
wp->cx = rect.right - rect.left;
wp->cy = rect.bottom - rect.top;
}

View File

@@ -1,29 +0,0 @@
#ifndef SDVXHOOK2_D3D9_H
#define SDVXHOOK2_D3D9_H
#include <stdint.h>
/**
* Hook some d3d9 functions to patch gfx related stuff
* like enabling window mode.
*/
void d3d9_hook_init(void);
/**
* Set the game to window mode.
*
* @param framed True to add a window frame and make the window
* movable, resizable, minizable. False for no frame.
*/
void d3d9_set_windowed(bool framed, int32_t width, int32_t height);
/**
* Set a framerate limit for the rendering loop.
*
* Use this if the game won't sync up properly with vsync enabled.
*
* @limit Number of frames to limit the rendering loop to
*/
void d3d9_set_frame_rate_limit(int limit);
#endif

View File

@@ -19,13 +19,14 @@
#include "sdvxhook2/acio.h"
#include "sdvxhook2/bi2a.h"
#include "sdvxhook2/config-gfx.h"
#include "sdvxhook2/config-io.h"
#include "sdvxhook2/d3d9.h"
#include "camhook/cam.h"
#include "camhook/config-cam.h"
#include "d3d9exhook/config-gfx.h"
#include "d3d9exhook/d3d9ex.h"
#include "imports/avs.h"
#include "util/log.h"
@@ -45,7 +46,7 @@ static const irp_handler_t sdvxhook_handlers[] = {
struct sdvxhook2_config_io config_io;
struct camhook_config_cam config_cam;
struct sdvxhook2_config_gfx config_gfx;
struct d3d9exhook_config_gfx config_gfx;
static struct bio2emu_port bio2_emu = {
.port = "COM4",
@@ -62,7 +63,7 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
config = cconfig_init();
sdvxhook2_config_io_init(config);
sdvxhook2_config_gfx_init(config);
d3d9exhook_config_gfx_init(config);
camhook_config_cam_init(config, 1);
if (!cconfig_hook_config_init(
@@ -74,20 +75,15 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
}
sdvxhook2_config_io_get(&config_io, config);
sdvxhook2_config_gfx_get(&config_gfx, config);
camhook_config_cam_get(&config_cam, config, 1);
d3d9exhook_config_gfx_get(&config_gfx, config);
cconfig_finit(config);
log_info(SDVXHOOK2_INFO_HEADER);
log_info("Initializing sdvxhook2...");
if (config_gfx.windowed) {
d3d9_set_windowed(
config_gfx.framed,
config_gfx.window_width,
config_gfx.window_height);
}
d3d9ex_configure(&config_gfx);
/* Start up sdvxio.DLL */
if (!config_io.disable_bio2_emu) {
@@ -173,7 +169,7 @@ BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
acp_hook_init();
adapter_hook_init();
d3d9_hook_init();
d3d9ex_hook_init();
end:
return TRUE;