Refactor d3d9

This commit is contained in:
QCDLZCLW3K
2022-05-30 02:00:49 +00:00
committed by 33c17f40
parent d4a03bcd05
commit bdf62988e7
12 changed files with 282 additions and 498 deletions
+4 -4
View File
@@ -11,16 +11,16 @@ eamuse.eamid=0101020304050607086F
security.mcode=GQHDXUAA security.mcode=GQHDXUAA
# Emulate P3IO COM4 and its downstream devices. Uses the Windows COM4 port when disabled. # Emulate P3IO COM4 and its downstream devices. Uses the Windows COM4 port when disabled.
ddrhookx.use_com4_emu=true ddrhook1.use_com4_emu=true
# SD cabinet mode # SD cabinet mode
ddrhookx.standard_def=false ddrhook1.standard_def=false
# Use 15 kHz monitor mode # Use 15 kHz monitor mode
ddrhookx.use_15khz=false ddrhook1.use_15khz=false
# Specify path for USB memory data # Specify path for USB memory data
ddrhookx.usbmem_path=usbmem ddrhook1.usbmem_path=usbmem
# Run the game windowed # Run the game windowed
gfx.windowed=false gfx.windowed=false
+4 -4
View File
@@ -11,16 +11,16 @@ eamuse.eamid=0101020304050607086F
security.mcode=GQHDXJAA security.mcode=GQHDXJAA
# Emulate P3IO COM4 and its downstream devices. Uses the Windows COM4 port when disabled. # Emulate P3IO COM4 and its downstream devices. Uses the Windows COM4 port when disabled.
ddrhookx.use_com4_emu=true ddrhook1.use_com4_emu=true
# SD cabinet mode # SD cabinet mode
ddrhookx.standard_def=false ddrhook1.standard_def=false
# Use 15 kHz monitor mode # Use 15 kHz monitor mode
ddrhookx.use_15khz=false ddrhook1.use_15khz=false
# Specify path for USB memory data # Specify path for USB memory data
ddrhookx.usbmem_path=usbmem ddrhook1.usbmem_path=usbmem
# Run the game windowed # Run the game windowed
gfx.windowed=false gfx.windowed=false
+219 -53
View File
@@ -1,88 +1,146 @@
// TODO: Fix gray arrows on NVIDIA cards (also applies to X3)
#define LOG_MODULE "gfx-hook"
#include <d3d9.h> #include <d3d9.h>
#include <d3dx9core.h>
#include <windows.h> #include <windows.h>
#include <math.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "hook/com-proxy.h" #include "hook/com-proxy.h"
#include "hook/table.h" #include "hook/table.h"
#include "ddrhook-util/gfx.h"
#include "util/defs.h" #include "util/defs.h"
#include "util/log.h" #include "util/log.h"
#include "util/str.h"
#include "util/time.h"
static HRESULT STDCALL my_CreateDevice( static LONG(STDCALL *real_ChangeDisplaySettingsExA)(
IDirect3D9 *self, char *dev_name, DEVMODE *dev_mode, HWND hwnd, DWORD flags, void *param);
UINT adapter, static LONG(STDCALL *real_SetWindowLongW)(
D3DDEVTYPE type, HWND hWnd, int nIndex, LONG dwNewLong);
HWND hwnd, static BOOL(STDCALL *real_SetWindowPos)(
DWORD flags, HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags);
D3DPRESENT_PARAMETERS *pp,
IDirect3DDevice9 **pdev);
static IDirect3D9 *STDCALL my_Direct3DCreate9(UINT sdk_ver); static LONG STDCALL my_ChangeDisplaySettingsExA(
char *dev_name, DEVMODE *dev_mode, HWND hwnd, DWORD flags, void *param);
static IDirect3D9 *(STDCALL *real_Direct3DCreate9)(UINT sdk_ver); static LONG STDCALL my_SetWindowLongW(HWND hWnd, int nIndex, LONG dwNewLong);
static BOOL STDCALL my_SetWindowPos(
HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags);
static bool gfx_windowed; static bool gfx_windowed;
static const struct hook_symbol gfx_d3d9_hook_syms[] = { static const struct hook_symbol misc_user32_syms[] = {
{ {
.name = "Direct3DCreate9", .name = "ChangeDisplaySettingsExA",
.patch = my_Direct3DCreate9, .patch = my_ChangeDisplaySettingsExA,
.link = (void **) &real_Direct3DCreate9, .link = (void **) &real_ChangeDisplaySettingsExA,
},
{
.name = "SetWindowLongW",
.patch = my_SetWindowLongW,
.link = (void **) &real_SetWindowLongW,
},
{
.name = "SetWindowPos",
.patch = my_SetWindowPos,
.link = (void **) &real_SetWindowPos,
}, },
}; };
static HRESULT STDCALL my_CreateDevice( /* ------------------------------------------------------------------------- */
IDirect3D9 *self,
UINT adapter, void gfx_d3d9_calc_win_size_with_framed(
D3DDEVTYPE type, HWND hwnd, DWORD x, DWORD y, DWORD width, DWORD height, LPWINDOWPOS wp)
HWND hwnd,
DWORD flags,
D3DPRESENT_PARAMETERS *pp,
IDirect3DDevice9 **pdev)
{ {
IDirect3D9 *real; /* taken from dxwnd */
RECT rect;
DWORD style;
int max_x, max_y;
HMENU menu;
real = com_proxy_downcast(self)->real; rect.left = x;
rect.top = y;
max_x = width;
max_y = height;
rect.right = x + max_x;
rect.bottom = y + max_y;
if (gfx_windowed) { style = GetWindowLong(hwnd, GWL_STYLE);
pp->Windowed = TRUE; menu = GetMenu(hwnd);
pp->FullScreen_RefreshRateInHz = 0; 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;
} }
return IDirect3D9_CreateDevice(real, adapter, type, hwnd, flags, pp, pdev); if (rect.top < 0) {
} rect.bottom -= rect.top;
rect.top = 0;
static IDirect3D9 *STDCALL my_Direct3DCreate9(UINT sdk_ver)
{
IDirect3D9 *api;
IDirect3D9Vtbl *api_vtbl;
struct com_proxy *api_proxy;
HRESULT hr;
log_info("Direct3DCreate9 hook hit");
api = real_Direct3DCreate9(sdk_ver);
hr = com_proxy_wrap(&api_proxy, api, sizeof(*api->lpVtbl));
if (hr != S_OK) {
log_fatal("Wrapping com proxy failed: %08lx", hr);
} }
api_vtbl = api_proxy->vptr; wp->x = rect.left;
wp->y = rect.top;
api_vtbl->CreateDevice = my_CreateDevice; wp->cx = rect.right - rect.left;
wp->cy = rect.bottom - rect.top;
return (IDirect3D9 *) api_proxy;
} }
/* ------------------------------------------------------------------------- */
static LONG STDCALL my_ChangeDisplaySettingsExA(
char *dev_name, DEVMODE *dev_mode, HWND hwnd, DWORD flags, void *param)
{
if (gfx_get_windowed()) {
return DISP_CHANGE_SUCCESSFUL;
}
return real_ChangeDisplaySettingsExA(
dev_name, dev_mode, hwnd, flags, param);
}
static LONG STDCALL my_SetWindowLongW(HWND hWnd, int nIndex, LONG dwNewLong)
{
if (gfx_get_windowed() && nIndex == GWL_STYLE) {
dwNewLong |= WS_OVERLAPPEDWINDOW;
}
return real_SetWindowLongW(hWnd, nIndex, dwNewLong);
}
static BOOL STDCALL my_SetWindowPos(
HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags)
{
if (gfx_get_windowed()) {
WINDOWPOS wp;
gfx_d3d9_calc_win_size_with_framed(hWnd, X, Y, cx, cy, &wp);
return real_SetWindowPos(
hWnd, hWndInsertAfter, wp.x, wp.y, wp.cx, wp.cy, uFlags);
}
return real_SetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags);
}
/* ------------------------------------------------------------------------- */
void gfx_insert_hooks(HMODULE target) void gfx_insert_hooks(HMODULE target)
{ {
hook_table_apply( hook_table_apply(
target, "d3d9.dll", gfx_d3d9_hook_syms, lengthof(gfx_d3d9_hook_syms)); target, "user32.dll", misc_user32_syms, lengthof(misc_user32_syms));
log_info("Inserted graphics hooks"); log_info("Initialized d3d9 hooks");
} }
bool gfx_get_windowed(void) bool gfx_get_windowed(void)
@@ -94,3 +152,111 @@ void gfx_set_windowed(void)
{ {
gfx_windowed = true; gfx_windowed = true;
} }
/* ------------------------------------------------------------------------- */
static void gfx_d3d9_patch_window(struct hook_d3d9_irp *irp)
{
log_assert(irp);
log_assert(irp->op == HOOK_D3D9_IRP_OP_CREATE_WINDOW_EX);
if (gfx_get_windowed()) {
/* use a different style */
irp->args.create_window_ex.style |= WS_OVERLAPPEDWINDOW;
/* also show mouse cursor */
ShowCursor(TRUE);
}
}
static void
gfx_d3d9_fix_window_size_and_pos(struct hook_d3d9_irp *irp)
{
log_assert(irp);
log_assert(irp->op == HOOK_D3D9_IRP_OP_CREATE_WINDOW_EX);
if (gfx_get_windowed()) {
/* 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) */
WINDOWPOS wp;
gfx_d3d9_calc_win_size_with_framed(
irp->args.create_window_ex.result,
irp->args.create_window_ex.x,
irp->args.create_window_ex.y,
irp->args.create_window_ex.width,
irp->args.create_window_ex.height,
&wp);
SetWindowPos(
irp->args.create_window_ex.result, 0, wp.x, wp.y, wp.cx, wp.cy, 0);
irp->args.create_window_ex.x = wp.x;
irp->args.create_window_ex.y = wp.y;
irp->args.create_window_ex.width = wp.cx;
irp->args.create_window_ex.height = wp.cy;
}
}
static void gfx_d3d9_create_device_apply_window_mode(
struct hook_d3d9_irp *irp)
{
log_assert(irp);
log_assert(irp->op == HOOK_D3D9_IRP_OP_CTX_CREATE_DEVICE);
D3DPRESENT_PARAMETERS *pp = irp->args.ctx_create_device.pp;
if (gfx_get_windowed()) {
pp->Windowed = TRUE;
pp->FullScreen_RefreshRateInHz = 0;
}
}
static void gfx_d3d9_reset_apply_window_mode(
struct hook_d3d9_irp *irp)
{
log_assert(irp);
log_assert(irp->op == HOOK_D3D9_IRP_OP_DEV_RESET);
D3DPRESENT_PARAMETERS *pp = irp->args.dev_reset.pp;
if (gfx_get_windowed()) {
pp->Windowed = TRUE;
pp->FullScreen_RefreshRateInHz = 0;
}
}
HRESULT
gfx_d3d9_irp_handler(struct hook_d3d9_irp *irp)
{
HRESULT hr;
log_assert(irp);
switch (irp->op) {
case HOOK_D3D9_IRP_OP_CREATE_WINDOW_EX:
gfx_d3d9_patch_window(irp);
hr = hook_d3d9_irp_invoke_next(irp);
if (hr == S_OK) {
gfx_d3d9_fix_window_size_and_pos(irp);
}
return hr;
case HOOK_D3D9_IRP_OP_CTX_CREATE_DEVICE:
gfx_d3d9_create_device_apply_window_mode(irp);
hr = hook_d3d9_irp_invoke_next(irp);
return hr;
case HOOK_D3D9_IRP_OP_DEV_RESET:
gfx_d3d9_reset_apply_window_mode(irp);
hr = hook_d3d9_irp_invoke_next(irp);
return hr;
default:
return hook_d3d9_irp_invoke_next(irp);
}
log_fatal("Illegal state");
}
+15 -5
View File
@@ -1,12 +1,22 @@
#ifndef DDRHOOK_UTIL_GFX_H #ifndef DDRHOOK1_D3D9_H
#define DDRHOOK_UTIL_GFX_H #define DDRHOOK1_D3D9_H
#include <windows.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#include "hook/d3d9.h"
struct ddrhook1_d3d9_config {
bool windowed;
};
void gfx_insert_hooks(HMODULE target);
bool gfx_get_windowed(void); bool gfx_get_windowed(void);
void gfx_set_windowed(void); void gfx_set_windowed(void);
void gfx_d3d9_calc_win_size_with_framed(
HWND hwnd, DWORD x, DWORD y, DWORD width, DWORD height, LPWINDOWPOS wp);
void gfx_insert_hooks(HMODULE target);
HRESULT gfx_d3d9_irp_handler(struct hook_d3d9_irp *irp);
#endif #endif
+1 -91
View File
@@ -11,8 +11,6 @@
#include "util/log.h" #include "util/log.h"
#include "util/str.h" #include "util/str.h"
static LONG(STDCALL *real_ChangeDisplaySettingsExA)(
char *dev_name, DEVMODE *dev_mode, HWND hwnd, DWORD flags, void *param);
static LRESULT(STDCALL *real_SendMessageW)( static LRESULT(STDCALL *real_SendMessageW)(
HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
static HWND(STDCALL *real_CreateWindowExW)( static HWND(STDCALL *real_CreateWindowExW)(
@@ -28,13 +26,7 @@ static HWND(STDCALL *real_CreateWindowExW)(
HMENU hMenu, HMENU hMenu,
HINSTANCE hInstance, HINSTANCE hInstance,
LPVOID lpParam); LPVOID lpParam);
static LONG(STDCALL *real_SetWindowLongW)(
HWND hWnd, int nIndex, LONG dwNewLong);
static BOOL(STDCALL *real_SetWindowPos)(
HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags);
static LONG STDCALL my_ChangeDisplaySettingsExA(
char *dev_name, DEVMODE *dev_mode, HWND hwnd, DWORD flags, void *param);
static SHORT STDCALL my_GetKeyState(int vk); static SHORT STDCALL my_GetKeyState(int vk);
static LRESULT STDCALL static LRESULT STDCALL
my_SendMessageW(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); my_SendMessageW(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
@@ -64,16 +56,8 @@ static HWND STDCALL my_CreateWindowExW(
HMENU hMenu, HMENU hMenu,
HINSTANCE hInstance, HINSTANCE hInstance,
LPVOID lpParam); LPVOID lpParam);
static LONG STDCALL my_SetWindowLongW(HWND hWnd, int nIndex, LONG dwNewLong);
static BOOL STDCALL my_SetWindowPos(
HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags);
static const struct hook_symbol misc_user32_syms[] = { static const struct hook_symbol misc_user32_syms[] = {
{
.name = "ChangeDisplaySettingsExA",
.patch = my_ChangeDisplaySettingsExA,
.link = (void **) &real_ChangeDisplaySettingsExA,
},
{ {
.name = "SendMessageW", .name = "SendMessageW",
.patch = my_SendMessageW, .patch = my_SendMessageW,
@@ -92,82 +76,8 @@ static const struct hook_symbol misc_user32_syms[] = {
.patch = my_CreateWindowExW, .patch = my_CreateWindowExW,
.link = (void **) &real_CreateWindowExW, .link = (void **) &real_CreateWindowExW,
}, },
{
.name = "SetWindowLongW",
.patch = my_SetWindowLongW,
.link = (void **) &real_SetWindowLongW,
},
{
.name = "SetWindowPos",
.patch = my_SetWindowPos,
.link = (void **) &real_SetWindowPos,
},
}; };
static LONG STDCALL my_SetWindowLongW(HWND hWnd, int nIndex, LONG dwNewLong)
{
if (nIndex == GWL_STYLE)
dwNewLong |= WS_OVERLAPPEDWINDOW;
return real_SetWindowLongW(hWnd, nIndex, dwNewLong);
}
static BOOL STDCALL my_SetWindowPos(
HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags)
{
return true;
}
static LONG STDCALL my_ChangeDisplaySettingsExA(
char *dev_name, DEVMODE *dev_mode, HWND hwnd, DWORD flags, void *param)
{
if (gfx_get_windowed()) {
return DISP_CHANGE_SUCCESSFUL;
} else {
return real_ChangeDisplaySettingsExA(
dev_name, dev_mode, hwnd, flags, param);
}
}
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;
}
static HWND STDCALL my_CreateWindowExW( static HWND STDCALL my_CreateWindowExW(
DWORD dwExStyle, DWORD dwExStyle,
LPCWSTR lpClassName, LPCWSTR lpClassName,
@@ -215,7 +125,7 @@ static HWND STDCALL my_CreateWindowExW(
slightly bigger than the rendering resolution (window caption and slightly bigger than the rendering resolution (window caption and
stuff is included in the window size) */ stuff is included in the window size) */
WINDOWPOS wp; WINDOWPOS wp;
calc_win_size_with_framed(hwnd, X, Y, nWidth, nHeight, &wp); gfx_d3d9_calc_win_size_with_framed(hwnd, X, Y, nWidth, nHeight, &wp);
SetWindowPos(hwnd, 0, wp.x, wp.y, wp.cx, wp.cy, 0); SetWindowPos(hwnd, 0, wp.x, wp.y, wp.cx, wp.cy, 0);
X = wp.x; X = wp.x;
Y = wp.y; Y = wp.y;
-1
View File
@@ -23,6 +23,5 @@ src_ddrhook1 := \
config-eamuse.c \ config-eamuse.c \
config-gfx.c \ config-gfx.c \
config-security.c \ config-security.c \
d3d9.c \
master.c \ master.c \
filesystem.c \ filesystem.c \
+10 -10
View File
@@ -6,10 +6,10 @@
#include "util/log.h" #include "util/log.h"
#define DDRHOOK1_CONFIG_DDRHOOK1_USE_COM4_EMU_KEY "ddrhookx.use_com4_emu" #define DDRHOOK1_CONFIG_DDRHOOK1_USE_COM4_EMU_KEY "ddrhook1.use_com4_emu"
#define DDRHOOK1_CONFIG_DDRHOOK1_STANDARD_DEF_KEY "ddrhookx.standard_def" #define DDRHOOK1_CONFIG_DDRHOOK1_STANDARD_DEF_KEY "ddrhook1.standard_def"
#define DDRHOOK1_CONFIG_DDRHOOK1_USE_15KHZ_KEY "ddrhookx.use_15khz" #define DDRHOOK1_CONFIG_DDRHOOK1_USE_15KHZ_KEY "ddrhook1.use_15khz"
#define DDRHOOK1_CONFIG_DDRHOOK1_USBMEM_PATH "ddrhookx.usbmem_path" #define DDRHOOK1_CONFIG_DDRHOOK1_USBMEM_PATH "ddrhook1.usbmem_path"
#define DDRHOOK1_CONFIG_DDRHOOK1_DEFAULT_USE_COM4_EMU_VALUE true #define DDRHOOK1_CONFIG_DDRHOOK1_DEFAULT_USE_COM4_EMU_VALUE true
#define DDRHOOK1_CONFIG_DDRHOOK1_DEFAULT_STANDARD_DEF_VALUE false #define DDRHOOK1_CONFIG_DDRHOOK1_DEFAULT_STANDARD_DEF_VALUE false
@@ -41,12 +41,12 @@ void ddrhook1_config_ddrhook1_init(struct cconfig *config)
} }
void ddrhook1_config_ddrhook1_get( void ddrhook1_config_ddrhook1_get(
struct ddrhook1_config_ddrhookx *config_ddrhookx, struct cconfig *config) struct ddrhook1_config_ddrhook1 *config_ddrhook1, struct cconfig *config)
{ {
if (!cconfig_util_get_bool( if (!cconfig_util_get_bool(
config, config,
DDRHOOK1_CONFIG_DDRHOOK1_USE_COM4_EMU_KEY, DDRHOOK1_CONFIG_DDRHOOK1_USE_COM4_EMU_KEY,
&config_ddrhookx->use_com4_emu, &config_ddrhook1->use_com4_emu,
DDRHOOK1_CONFIG_DDRHOOK1_DEFAULT_USE_COM4_EMU_VALUE)) { DDRHOOK1_CONFIG_DDRHOOK1_DEFAULT_USE_COM4_EMU_VALUE)) {
log_warning( log_warning(
"Invalid value for key '%s' specified, fallback " "Invalid value for key '%s' specified, fallback "
@@ -57,7 +57,7 @@ void ddrhook1_config_ddrhook1_get(
if (!cconfig_util_get_bool( if (!cconfig_util_get_bool(
config, config,
DDRHOOK1_CONFIG_DDRHOOK1_STANDARD_DEF_KEY, DDRHOOK1_CONFIG_DDRHOOK1_STANDARD_DEF_KEY,
&config_ddrhookx->standard_def, &config_ddrhook1->standard_def,
DDRHOOK1_CONFIG_DDRHOOK1_DEFAULT_STANDARD_DEF_VALUE)) { DDRHOOK1_CONFIG_DDRHOOK1_DEFAULT_STANDARD_DEF_VALUE)) {
log_warning( log_warning(
"Invalid value for key '%s' specified, fallback " "Invalid value for key '%s' specified, fallback "
@@ -68,7 +68,7 @@ void ddrhook1_config_ddrhook1_get(
if (!cconfig_util_get_bool( if (!cconfig_util_get_bool(
config, config,
DDRHOOK1_CONFIG_DDRHOOK1_USE_15KHZ_KEY, DDRHOOK1_CONFIG_DDRHOOK1_USE_15KHZ_KEY,
&config_ddrhookx->standard_def, &config_ddrhook1->use_15khz,
DDRHOOK1_CONFIG_DDRHOOK1_DEFAULT_USE_15KHZ_VALUE)) { DDRHOOK1_CONFIG_DDRHOOK1_DEFAULT_USE_15KHZ_VALUE)) {
log_warning( log_warning(
"Invalid value for key '%s' specified, fallback " "Invalid value for key '%s' specified, fallback "
@@ -79,8 +79,8 @@ void ddrhook1_config_ddrhook1_get(
if (!cconfig_util_get_str( if (!cconfig_util_get_str(
config, config,
DDRHOOK1_CONFIG_DDRHOOK1_USBMEM_PATH, DDRHOOK1_CONFIG_DDRHOOK1_USBMEM_PATH,
config_ddrhookx->usbmem_path, config_ddrhook1->usbmem_path,
sizeof(config_ddrhookx->usbmem_path) - 1, sizeof(config_ddrhook1->usbmem_path) - 1,
DDRHOOK1_CONFIG_DDRHOOK1_DEFAULT_USBMEM_PATH)) { DDRHOOK1_CONFIG_DDRHOOK1_DEFAULT_USBMEM_PATH)) {
log_warning( log_warning(
"Invalid value for key '%s' specified, fallback " "Invalid value for key '%s' specified, fallback "
+3 -3
View File
@@ -8,7 +8,7 @@
/** /**
* Struct holding configuration values for game-specific items. * Struct holding configuration values for game-specific items.
*/ */
struct ddrhook1_config_ddrhookx { struct ddrhook1_config_ddrhook1 {
bool use_com4_emu; bool use_com4_emu;
bool standard_def; bool standard_def;
bool use_15khz; bool use_15khz;
@@ -25,11 +25,11 @@ void ddrhook1_config_ddrhook1_init(struct cconfig *config);
* Read the module specific config struct values from the provided cconfig * Read the module specific config struct values from the provided cconfig
* struct. * struct.
* *
* @param config_ddrhookx Target module specific struct to read configuration * @param config_ddrhook1 Target module specific struct to read configuration
* values to. * values to.
* @param config cconfig struct holding the intermediate data to read from. * @param config cconfig struct holding the intermediate data to read from.
*/ */
void ddrhook1_config_ddrhook1_get( void ddrhook1_config_ddrhook1_get(
struct ddrhook1_config_ddrhookx *config_ddrhookx, struct cconfig *config); struct ddrhook1_config_ddrhook1 *config_ddrhook1, struct cconfig *config);
#endif #endif
-281
View File
@@ -1,281 +0,0 @@
// TODO: Fix gray arrows on NVIDIA cards (also applies to X3)
#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 "ddrhook1/d3d9.h"
#include "util/defs.h"
#include "util/log.h"
#include "util/str.h"
#include "util/time.h"
static LONG(STDCALL *real_ChangeDisplaySettingsExA)(
char *dev_name, DEVMODE *dev_mode, HWND hwnd, DWORD flags, void *param);
static LONG(STDCALL *real_SetWindowLongW)(
HWND hWnd, int nIndex, LONG dwNewLong);
static BOOL(STDCALL *real_SetWindowPos)(
HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags);
static LONG STDCALL my_ChangeDisplaySettingsExA(
char *dev_name, DEVMODE *dev_mode, HWND hwnd, DWORD flags, void *param);
static LONG STDCALL my_SetWindowLongW(HWND hWnd, int nIndex, LONG dwNewLong);
static BOOL STDCALL my_SetWindowPos(
HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags);
static struct ddrhook1_d3d9_config ddrhook1_d3d9_config;
static const struct hook_symbol misc_user32_syms[] = {
{
.name = "ChangeDisplaySettingsExA",
.patch = my_ChangeDisplaySettingsExA,
.link = (void **) &real_ChangeDisplaySettingsExA,
},
{
.name = "SetWindowLongW",
.patch = my_SetWindowLongW,
.link = (void **) &real_SetWindowLongW,
},
{
.name = "SetWindowPos",
.patch = my_SetWindowPos,
.link = (void **) &real_SetWindowPos,
},
};
/* ------------------------------------------------------------------------- */
static void ddrhook1_d3d9_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;
}
/* ------------------------------------------------------------------------- */
static LONG STDCALL my_SetWindowLongW(HWND hWnd, int nIndex, LONG dwNewLong)
{
if (ddrhook1_d3d9_config.windowed && nIndex == GWL_STYLE) {
dwNewLong |= WS_OVERLAPPEDWINDOW;
}
return real_SetWindowLongW(hWnd, nIndex, dwNewLong);
}
static BOOL STDCALL my_SetWindowPos(
HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags)
{
if (ddrhook1_d3d9_config.windowed) {
WINDOWPOS wp;
ddrhook1_d3d9_calc_win_size_with_framed(hWnd, X, Y, cx, cy, &wp);
return real_SetWindowPos(
hWnd, hWndInsertAfter, wp.x, wp.y, wp.cx, wp.cy, uFlags);
}
return real_SetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags);
}
static LONG STDCALL my_ChangeDisplaySettingsExA(
char *dev_name, DEVMODE *dev_mode, HWND hwnd, DWORD flags, void *param)
{
if (ddrhook1_d3d9_config.windowed) {
return DISP_CHANGE_SUCCESSFUL;
}
return real_ChangeDisplaySettingsExA(
dev_name, dev_mode, hwnd, flags, param);
}
/* ------------------------------------------------------------------------- */
static void
ddrhook1_d3d9_log_config(const struct ddrhook1_d3d9_config *config)
{
log_misc(
"ddrhook1_d3d9_config\n"
"windowed: %d\n",
config->windowed);
}
void ddrhook1_d3d9_init_config(struct ddrhook1_d3d9_config *config)
{
config->windowed = false;
}
void ddrhook1_d3d9_hook_init()
{
ddrhook1_d3d9_init_config(&ddrhook1_d3d9_config);
hook_table_apply(
NULL, "user32.dll", misc_user32_syms, lengthof(misc_user32_syms));
log_info("Initialized d3d9 hooks");
}
/* ------------------------------------------------------------------------- */
void ddrhook1_d3d9_configure(
const struct ddrhook1_d3d9_config *config)
{
log_assert(config);
ddrhook1_d3d9_log_config(config);
memcpy(
&ddrhook1_d3d9_config,
config,
sizeof(struct ddrhook1_d3d9_config));
}
static void ddrhook1_d3d9_patch_window(struct hook_d3d9_irp *irp)
{
log_assert(irp);
log_assert(irp->op == HOOK_D3D9_IRP_OP_CREATE_WINDOW_EX);
if (ddrhook1_d3d9_config.windowed) {
/* use a different style */
irp->args.create_window_ex.style |= WS_OVERLAPPEDWINDOW;
/* also show mouse cursor */
ShowCursor(TRUE);
}
}
static void
ddrhook1_d3d9_fix_window_size_and_pos(struct hook_d3d9_irp *irp)
{
log_assert(irp);
log_assert(irp->op == HOOK_D3D9_IRP_OP_CREATE_WINDOW_EX);
if (ddrhook1_d3d9_config.windowed) {
/* 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) */
WINDOWPOS wp;
ddrhook1_d3d9_calc_win_size_with_framed(
irp->args.create_window_ex.result,
irp->args.create_window_ex.x,
irp->args.create_window_ex.y,
irp->args.create_window_ex.width,
irp->args.create_window_ex.height,
&wp);
SetWindowPos(
irp->args.create_window_ex.result, 0, wp.x, wp.y, wp.cx, wp.cy, 0);
irp->args.create_window_ex.x = wp.x;
irp->args.create_window_ex.y = wp.y;
irp->args.create_window_ex.width = wp.cx;
irp->args.create_window_ex.height = wp.cy;
}
}
static void ddrhook1_d3d9_create_device_apply_window_mode(
struct hook_d3d9_irp *irp)
{
log_assert(irp);
log_assert(irp->op == HOOK_D3D9_IRP_OP_CTX_CREATE_DEVICE);
D3DPRESENT_PARAMETERS *pp = irp->args.ctx_create_device.pp;
if (ddrhook1_d3d9_config.windowed) {
pp->Windowed = TRUE;
pp->FullScreen_RefreshRateInHz = 0;
}
}
static void ddrhook1_d3d9_reset_apply_window_mode(
struct hook_d3d9_irp *irp)
{
log_assert(irp);
log_assert(irp->op == HOOK_D3D9_IRP_OP_DEV_RESET);
D3DPRESENT_PARAMETERS *pp = irp->args.dev_reset.pp;
if (ddrhook1_d3d9_config.windowed) {
pp->Windowed = TRUE;
pp->FullScreen_RefreshRateInHz = 0;
}
}
HRESULT
ddrhook1_d3d9_irp_handler(struct hook_d3d9_irp *irp)
{
HRESULT hr;
log_assert(irp);
switch (irp->op) {
case HOOK_D3D9_IRP_OP_CREATE_WINDOW_EX:
ddrhook1_d3d9_patch_window(irp);
hr = hook_d3d9_irp_invoke_next(irp);
if (hr == S_OK) {
ddrhook1_d3d9_fix_window_size_and_pos(irp);
}
return hr;
case HOOK_D3D9_IRP_OP_CTX_CREATE_DEVICE:
ddrhook1_d3d9_create_device_apply_window_mode(irp);
hr = hook_d3d9_irp_invoke_next(irp);
return hr;
case HOOK_D3D9_IRP_OP_DEV_RESET:
ddrhook1_d3d9_reset_apply_window_mode(irp);
hr = hook_d3d9_irp_invoke_next(irp);
return hr;
default:
return hook_d3d9_irp_invoke_next(irp);
}
log_fatal("Illegal state");
}
-18
View File
@@ -1,18 +0,0 @@
#ifndef DDRHOOK1_D3D9_H
#define DDRHOOK1_D3D9_H
#include <stdbool.h>
#include <stdint.h>
#include "hook/d3d9.h"
struct ddrhook1_d3d9_config {
bool windowed;
};
void ddrhook1_d3d9_hook_init();
void ddrhook1_d3d9_configure(
const struct ddrhook1_d3d9_config *config);
HRESULT ddrhook1_d3d9_irp_handler(struct hook_d3d9_irp *irp);
#endif
+20 -28
View File
@@ -18,10 +18,11 @@
#include "ddrhook1/config-eamuse.h" #include "ddrhook1/config-eamuse.h"
#include "ddrhook1/config-gfx.h" #include "ddrhook1/config-gfx.h"
#include "ddrhook1/config-security.h" #include "ddrhook1/config-security.h"
#include "ddrhook1/d3d9.h"
#include "ddrhook1/filesystem.h" #include "ddrhook1/filesystem.h"
#include "ddrhook1/master.h" #include "ddrhook1/master.h"
#include "ddrhook-util/gfx.h"
#include "hook/iohook.h" #include "hook/iohook.h"
#include "hook/process.h" #include "hook/process.h"
@@ -40,10 +41,10 @@
#include "util/thread.h" #include "util/thread.h"
#define DDRHOOK1_INFO_HEADER \ #define DDRHOOK1_INFO_HEADER \
"ddrhookx for DDR X" \ "ddrhook1 for DDR X" \
", build " __DATE__ " " __TIME__ ", gitrev " STRINGIFY(GITREV) ", build " __DATE__ " " __TIME__ ", gitrev " STRINGIFY(GITREV)
#define DDRHOOK1_CMD_USAGE \ #define DDRHOOK1_CMD_USAGE \
"Usage: inject.exe ddrhookx.dll <ddr.exe> [options...]" "Usage: inject.exe ddrhook1.dll <ddr.exe> [options...]"
bool standard_def; bool standard_def;
bool _15khz; bool _15khz;
@@ -52,29 +53,17 @@ static DWORD STDCALL my_main();
static DWORD(STDCALL *real_main)(); static DWORD(STDCALL *real_main)();
static const hook_d3d9_irp_handler_t ddrhook1_d3d9_handlers[] = { static const hook_d3d9_irp_handler_t ddrhook1_d3d9_handlers[] = {
ddrhook1_d3d9_irp_handler, gfx_d3d9_irp_handler,
}; };
static bool ddrhook1_init_check = false; static bool ddrhook1_init_check = false;
static void ddrhook1_setup_d3d9_hooks(
const struct ddrhook1_config_gfx *config_gfx)
{
struct ddrhook1_d3d9_config d3d9_config;
d3d9_config.windowed = config_gfx->windowed;
ddrhook1_d3d9_configure(&d3d9_config);
hook_d3d9_init(ddrhook1_d3d9_handlers, lengthof(ddrhook1_d3d9_handlers));
}
static DWORD STDCALL my_main() static DWORD STDCALL my_main()
{ {
bool ok; bool ok;
struct cconfig *config; struct cconfig *config;
struct ddrhook1_config_ddrhookx config_ddrhookx; struct ddrhook1_config_ddrhook1 config_ddrhook1;
struct ddrhook1_config_eamuse config_eamuse; struct ddrhook1_config_eamuse config_eamuse;
struct ddrhook1_config_gfx config_gfx; struct ddrhook1_config_gfx config_gfx;
struct ddrhook1_config_security config_security; struct ddrhook1_config_security config_security;
@@ -82,7 +71,7 @@ static DWORD STDCALL my_main()
if (ddrhook1_init_check) if (ddrhook1_init_check)
goto skip; goto skip;
log_info("--- Begin ddrhookx GetModuleFileNameA ---"); log_info("--- Begin ddrhook1 main ---");
ddrhook1_init_check = true; ddrhook1_init_check = true;
@@ -101,17 +90,18 @@ static DWORD STDCALL my_main()
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
ddrhook1_config_ddrhook1_get(&config_ddrhookx, config); ddrhook1_config_ddrhook1_get(&config_ddrhook1, config);
ddrhook1_config_eamuse_get(&config_eamuse, config); ddrhook1_config_eamuse_get(&config_eamuse, config);
ddrhook1_config_gfx_get(&config_gfx, config); ddrhook1_config_gfx_get(&config_gfx, config);
ddrhook1_config_security_get(&config_security, config); ddrhook1_config_security_get(&config_security, config);
cconfig_finit(config); cconfig_finit(config);
standard_def = config_ddrhookx.standard_def; standard_def = config_ddrhook1.standard_def;
_15khz = config_ddrhook1.use_15khz;
log_info(DDRHOOK1_INFO_HEADER); log_info(DDRHOOK1_INFO_HEADER);
log_info("Initializing ddrhookx..."); log_info("Initializing ddrhook1...");
ddrhook1_avs_boot_init(); ddrhook1_avs_boot_init();
ddrhook1_avs_boot_set_eamuse_addr(&config_eamuse.server); ddrhook1_avs_boot_set_eamuse_addr(&config_eamuse.server);
@@ -121,12 +111,14 @@ static DWORD STDCALL my_main()
iohook_push_handler(spike_dispatch_irp); iohook_push_handler(spike_dispatch_irp);
iohook_push_handler(usbmem_dispatch_irp); iohook_push_handler(usbmem_dispatch_irp);
if (config_ddrhookx.use_com4_emu) { if (config_ddrhook1.use_com4_emu) {
/* See ddrhook2/p3io.c for details. */ /* See ddrhook-util/p3io.c for details. */
iohook_push_handler(com4_dispatch_irp); iohook_push_handler(com4_dispatch_irp);
} }
ddrhook1_setup_d3d9_hooks(&config_gfx); if (config_gfx.windowed) {
gfx_set_windowed();
}
rs232_hook_init(); rs232_hook_init();
@@ -137,7 +129,7 @@ static DWORD STDCALL my_main()
&security_rp_sign_key_black_ddrx, &security_rp_sign_key_black_ddrx,
&security_rp_sign_key_white_eamuse); &security_rp_sign_key_white_eamuse);
extio_init(); extio_init();
usbmem_init(config_ddrhookx.usbmem_path); usbmem_init(config_ddrhook1.usbmem_path);
spike_init(); spike_init();
com4_init(); com4_init();
@@ -150,7 +142,7 @@ static DWORD STDCALL my_main()
return false; return false;
} }
if (config_ddrhookx.use_com4_emu) { if (config_ddrhook1.use_com4_emu) {
log_info("Initializing card reader backend"); log_info("Initializing card reader backend");
eam_io_set_loggers( eam_io_set_loggers(
@@ -164,7 +156,7 @@ static DWORD STDCALL my_main()
} }
} }
log_info("--- End ddrhookx GetModuleFileNameA ---"); log_info("--- End ddrhook1 main ---");
skip: skip:
return real_main(); return real_main();
@@ -180,7 +172,7 @@ BOOL WINAPI DllMain(HMODULE self, DWORD reason, void *ctx)
ddrhook1_master_insert_hooks(NULL); ddrhook1_master_insert_hooks(NULL);
ddrhook1_filesystem_hook_init(); ddrhook1_filesystem_hook_init();
ddrhook1_d3d9_hook_init(); hook_d3d9_init(ddrhook1_d3d9_handlers, lengthof(ddrhook1_d3d9_handlers));
} }
return TRUE; return TRUE;
+6
View File
@@ -33,6 +33,10 @@ static bool my_dll_entry_main(void);
bool standard_def; bool standard_def;
bool _15khz; bool _15khz;
static const hook_d3d9_irp_handler_t ddrhook2_d3d9_handlers[] = {
gfx_d3d9_irp_handler,
};
static bool my_dll_entry_init(char *sidcode, struct property_node *param) static bool my_dll_entry_init(char *sidcode, struct property_node *param)
{ {
int argc; int argc;
@@ -93,6 +97,8 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
iohook_push_handler(com4_dispatch_irp); iohook_push_handler(com4_dispatch_irp);
} }
hook_d3d9_init(ddrhook2_d3d9_handlers, lengthof(ddrhook2_d3d9_handlers));
rs232_hook_init(); rs232_hook_init();
ddrhook2_master_insert_hooks(NULL); ddrhook2_master_insert_hooks(NULL);