1
0
mirror of https://github.com/djhackersdev/bemanitools.git synced 2024-11-28 00:10:51 +01:00

iidxhook: Fix diagonal tearing on textures on iidx18 and 19

Affects all games based on version 18 and 19 which includes
the chinese versions

This code is based on the toastertools implementation.
Credits to the original authors.
This commit is contained in:
2d9f8a0741a7573b189035dcb819847ecb5d981d 2022-06-13 05:11:49 +09:00 committed by icex2
parent 8081793a5f
commit 4bd0ee5ef6
16 changed files with 342 additions and 0 deletions

View File

@ -40,6 +40,9 @@ gfx.forced_refresh_rate=-1
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1
# Fix diagonal tearing with video cards other than Radeon X1300 and HD3450
gfx.diagonal_tearing_fix=false
# Disable ezusb IO emulation and enable usage of real ezusb1/2 IO hardware
io.disable_io_emu=false

View File

@ -37,6 +37,9 @@ gfx.forced_refresh_rate=-1
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1
# Fix diagonal tearing with video cards other than Radeon X1300 and HD3450
gfx.diagonal_tearing_fix=false
# Disable card reader emulation and enable usage of real card reader hardware on COM1 (for games supporting slotted/wavepass readers)
io.disable_card_reader_emu=false

View File

@ -34,6 +34,9 @@ gfx.forced_refresh_rate=-1
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1
# Fix diagonal tearing with video cards other than Radeon X1300 and HD3450
gfx.diagonal_tearing_fix=false
# Disable card reader emulation and enable usage of real card reader hardware on COM1 (for games supporting slotted/wavepass readers)
io.disable_card_reader_emu=false

View File

@ -37,6 +37,9 @@ gfx.forced_refresh_rate=-1
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1
# Fix diagonal tearing with video cards other than Radeon X1300 and HD3450
gfx.diagonal_tearing_fix=false
# Disable ezusb IO emulation and enable usage of real ezusb1/2 IO hardware
io.disable_io_emu=false

View File

@ -75,6 +75,12 @@ static HRESULT(STDCALL *real_Reset)(
IDirect3DDevice9 *self,
D3DPRESENT_PARAMETERS *pp);
static HRESULT (STDCALL *real_SetViewport)(
IDirect3DDevice9 *self, const D3DVIEWPORT9 *pViewport);
static HRESULT (STDCALL *real_SetVertexShader)(
IDirect3DDevice9 *self, IDirect3DVertexShader9 *pShader);
/* ------------------------------------------------------------------------------------------------------------------
*/
@ -144,6 +150,12 @@ static HRESULT STDCALL my_Reset(
IDirect3DDevice9 *self,
D3DPRESENT_PARAMETERS *pp);
static HRESULT STDCALL my_SetViewport(
IDirect3DDevice9 *self, const D3DVIEWPORT9 *pViewport);
static HRESULT STDCALL my_SetVertexShader(
IDirect3DDevice9 *self, IDirect3DVertexShader9 *pShader);
/* ------------------------------------------------------------------------------------------------------------------
*/
@ -205,6 +217,12 @@ hook_d3d9_irp_handler_real_dev_draw_primitive_up(struct hook_d3d9_irp *irp);
static HRESULT
hook_d3d9_irp_handler_real_dev_reset(struct hook_d3d9_irp *irp);
static HRESULT
hook_d3d9_irp_handler_real_dev_set_viewport(struct hook_d3d9_irp *irp);
static HRESULT
hook_d3d9_irp_handler_real_dev_set_vertex_shader(struct hook_d3d9_irp *irp);
/* ------------------------------------------------------------------------------------------------------------------
*/
@ -231,6 +249,10 @@ static const hook_d3d9_irp_handler_t hook_d3d9_irp_real_handlers[] = {
hook_d3d9_irp_handler_real_dev_draw_primitive_up,
[HOOK_D3D9_IRP_OP_DEV_RESET] =
hook_d3d9_irp_handler_real_dev_reset,
[HOOK_D3D9_IRP_OP_DEV_SET_VIEWPORT] =
hook_d3d9_irp_handler_real_dev_set_viewport,
[HOOK_D3D9_IRP_OP_DEV_SET_VERTEX_SHADER] =
hook_d3d9_irp_handler_real_dev_set_vertex_shader,
};
static const hook_d3d9_irp_handler_t *hook_d3d9_handlers;
@ -501,6 +523,40 @@ static HRESULT STDCALL my_DrawPrimitiveUP(
return hr;
}
static HRESULT STDCALL my_SetViewport(
IDirect3DDevice9 *self, const D3DVIEWPORT9 *pViewport)
{
struct hook_d3d9_irp irp;
HRESULT hr;
memset(&irp, 0, sizeof(irp));
irp.op = HOOK_D3D9_IRP_OP_DEV_SET_VIEWPORT;
irp.args.dev_set_viewport.self = self;
irp.args.dev_set_viewport.pViewport = pViewport;
hr = hook_d3d9_irp_invoke_next(&irp);
return hr;
}
static HRESULT STDCALL my_SetVertexShader(
IDirect3DDevice9 *self, IDirect3DVertexShader9 *pShader)
{
struct hook_d3d9_irp irp;
HRESULT hr;
memset(&irp, 0, sizeof(irp));
irp.op = HOOK_D3D9_IRP_OP_DEV_SET_VERTEX_SHADER;
irp.args.dev_set_vertex_shader.self = self;
irp.args.dev_set_vertex_shader.pShader = pShader;
hr = hook_d3d9_irp_invoke_next(&irp);
return hr;
}
static HRESULT STDCALL my_Reset(
IDirect3DDevice9 *self,
D3DPRESENT_PARAMETERS *pp)
@ -691,6 +747,12 @@ hook_d3d9_irp_handler_real_dev_create_device(struct hook_d3d9_irp *irp)
real_Reset = api_vtbl->Reset;
api_vtbl->Reset = my_Reset;
real_SetViewport = api_vtbl->SetViewport;
api_vtbl->SetViewport = my_SetViewport;
real_SetVertexShader = api_vtbl->SetVertexShader;
api_vtbl->SetVertexShader = my_SetVertexShader;
*irp->args.ctx_create_device.pdev = (IDirect3DDevice9 *) api_proxy;
return hr;
@ -775,6 +837,26 @@ hook_d3d9_irp_handler_real_dev_reset(struct hook_d3d9_irp *irp)
irp->args.dev_reset.pp);
}
static HRESULT
hook_d3d9_irp_handler_real_dev_set_viewport(struct hook_d3d9_irp *irp)
{
log_assert(irp);
return real_SetViewport(
irp->args.dev_set_viewport.self,
irp->args.dev_set_viewport.pViewport);
}
static HRESULT
hook_d3d9_irp_handler_real_dev_set_vertex_shader(struct hook_d3d9_irp *irp)
{
log_assert(irp);
return real_SetVertexShader(
irp->args.dev_set_vertex_shader.self,
irp->args.dev_set_vertex_shader.pShader);
}
/* ------------------------------------------------------------------------------------------------------------------
*/

View File

@ -34,6 +34,8 @@ enum hook_d3d9_irp_op {
HOOK_D3D9_IRP_OP_DEV_SET_RENDER_STATE = 10,
HOOK_D3D9_IRP_OP_DEV_DRAW_PRIMITIVE_UP = 11,
HOOK_D3D9_IRP_OP_DEV_RESET = 12,
HOOK_D3D9_IRP_OP_DEV_SET_VIEWPORT = 13,
HOOK_D3D9_IRP_OP_DEV_SET_VERTEX_SHADER = 14,
};
/**
@ -170,6 +172,22 @@ struct hook_d3d9_irp {
IDirect3DDevice9 *self;
D3DPRESENT_PARAMETERS *pp;
} dev_reset;
/**
* Params of IDIrect3DDevice9_SetViewport
*/
struct {
IDirect3DDevice9 *self;
const D3DVIEWPORT9 *pViewport;
} dev_set_viewport;
/**
* Params of IDIrect3DDevice9_SetVertexShader
*/
struct {
IDirect3DDevice9 *self;
IDirect3DVertexShader9 *pShader;
} dev_set_vertex_shader;
} args;
size_t next_handler;

View File

@ -22,6 +22,7 @@
"gfx.scale_back_buffer_filter"
#define IIDXHOOK_CONFIG_GFX_FORCED_REFRESHRATE_KEY "gfx.forced_refresh_rate"
#define IIDXHOOK_CONFIG_GFX_DEVICE_ADAPTER_KEY "gfx.device_adapter"
#define IIDXHOOK_CONFIG_GFX_DIAGONAL_TEARING_FIX_KEY "gfx.diagonal_tearing_fix"
#define IIDXHOOK_CONFIG_GFX_DEFAULT_BGVIDEO_UV_FIX_VALUE false
#define IIDXHOOK_CONFIG_GFX_DEFAULT_FRAMED_VALUE false
@ -36,6 +37,7 @@
#define IIDXHOOK_CONFIG_GFX_DEFAULT_SCALE_BACK_BUFFER_FILTER_VALUE "none"
#define IIDXHOOK_CONFIG_GFX_DEFAULT_FORCED_RR_VALUE -1
#define IIDXHOOK_CONFIG_GFX_DEFAULT_DEVICE_ADAPTER_VALUE -1
#define IIDXHOOK_CONFIG_GFX_DEFAULT_DIAGONAL_TEARING_FIX_VALUE false
void iidxhook_config_gfx_init(struct cconfig *config)
{
@ -159,6 +161,13 @@ void iidxhook_config_gfx_init(struct cconfig *config)
IIDXHOOK_CONFIG_GFX_DEFAULT_DEVICE_ADAPTER_VALUE,
"D3D9 device adapter (monitor), -1 to use default, "
"0, 1, 2 etc. to use specified adapter");
cconfig_util_set_bool(
config,
IIDXHOOK_CONFIG_GFX_DIAGONAL_TEARING_FIX_KEY,
IIDXHOOK_CONFIG_GFX_DEFAULT_DIAGONAL_TEARING_FIX_VALUE,
"Fix diagonal tearing with video cards "
"other than Radeon X1300 and HD3450");
}
void iidxhook_config_gfx_get(
@ -367,4 +376,16 @@ void iidxhook_config_gfx_get(
IIDXHOOK_CONFIG_GFX_DEVICE_ADAPTER_KEY,
IIDXHOOK_CONFIG_GFX_DEFAULT_DEVICE_ADAPTER_VALUE);
}
if (!cconfig_util_get_bool(
config,
IIDXHOOK_CONFIG_GFX_DIAGONAL_TEARING_FIX_KEY,
&config_gfx->diagonal_tearing_fix,
IIDXHOOK_CONFIG_GFX_DEFAULT_DIAGONAL_TEARING_FIX_VALUE)) {
log_warning(
"Invalid value for key '%s' specified, fallback "
"to default '%d'",
IIDXHOOK_CONFIG_GFX_DIAGONAL_TEARING_FIX_KEY,
IIDXHOOK_CONFIG_GFX_DEFAULT_DIAGONAL_TEARING_FIX_VALUE);
}
}

View File

@ -21,6 +21,7 @@ struct iidxhook_config_gfx {
enum iidxhook_util_d3d9_back_buffer_scale_filter scale_back_buffer_filter;
int32_t forced_refresh_rate;
int32_t device_adapter;
bool diagonal_tearing_fix;
};
void iidxhook_config_gfx_init(struct cconfig *config);

View File

@ -13,6 +13,7 @@
#include "hook/table.h"
#include "iidxhook-util/d3d9.h"
#include "iidxhook-util/vertex-shader.h"
#include "util/defs.h"
#include "util/log.h"
@ -64,6 +65,8 @@ static struct {
D3DTEXTUREFILTERTYPE filter;
} iidxhook_util_d3d9_back_buffer_scaling;
static IDirect3DVertexShader9* vertex_shader;
/* ------------------------------------------------------------------------------------------------------------------
*/
@ -901,6 +904,45 @@ iidxhook_util_d3d9_scale_render_target_to_back_buffer(struct hook_d3d9_irp *irp)
}
}
static void
iidxhook_util_d3d9_iidx18_and_19_fix_diagonal_tearing(struct hook_d3d9_irp *irp)
{
HRESULT hr;
log_assert(irp);
log_assert(irp->op == HOOK_D3D9_IRP_OP_DEV_SET_VIEWPORT || irp->op == HOOK_D3D9_IRP_OP_DEV_SET_VERTEX_SHADER);
if (!iidxhook_util_d3d9_config.iidx18_and_19_diagonal_tearing_fix)
{
return;
}
if (irp->op == HOOK_D3D9_IRP_OP_DEV_SET_VIEWPORT)
{
const D3DVIEWPORT9 *pViewport = irp->args.dev_set_viewport.pViewport;
const float fix_offset[2] = {-1.0F / (float)pViewport->Width, -1.0F / (float)pViewport->Height};
hr = IDirect3DDevice9_SetVertexShaderConstantF(irp->args.dev_set_viewport.self, 63, fix_offset, lengthof(fix_offset));
if (hr != S_OK) {
log_warning("SetVertexShaderConstantF failed: %lX", hr);
}
}
if (irp->op == HOOK_D3D9_IRP_OP_DEV_SET_VERTEX_SHADER)
{
if (!vertex_shader) {
hr = IDirect3DDevice9_CreateVertexShader(irp->args.dev_set_vertex_shader.self, (const DWORD*) g_vs11_vs_main, &vertex_shader);
if (hr != S_OK) {
log_fatal("CreateVertexShader failed: %lX", hr);
}
}
if (irp->args.dev_set_vertex_shader.pShader != NULL) {
irp->args.dev_set_vertex_shader.pShader = vertex_shader;
}
}
}
/* ------------------------------------------------------------------------------------------------------------------
*/
@ -921,6 +963,7 @@ iidxhook_util_d3d9_log_config(const struct iidxhook_util_d3d9_config *config)
"iidx12_fix_song_select_bg: %d\n"
"iidx13_fix_song_select_bg: %d\n"
"iidx14_to_19_nvidia_fix: %d\n"
"iidx18_and_19_diagonal_tearing_fix: %d\n"
"scale_back_buffer_width: %d\n"
"scale_back_buffer_height: %d\n"
"scale_back_buffer_filter: %d\n"
@ -938,6 +981,7 @@ iidxhook_util_d3d9_log_config(const struct iidxhook_util_d3d9_config *config)
config->iidx12_fix_song_select_bg,
config->iidx13_fix_song_select_bg,
config->iidx14_to_19_nvidia_fix,
config->iidx18_and_19_diagonal_tearing_fix,
config->scale_back_buffer_width,
config->scale_back_buffer_height,
config->scale_back_buffer_filter,
@ -1002,6 +1046,7 @@ void iidxhook_util_d3d9_init_config(struct iidxhook_util_d3d9_config *config)
config->iidx12_fix_song_select_bg = false;
config->iidx13_fix_song_select_bg = false;
config->iidx14_to_19_nvidia_fix = false;
config->iidx18_and_19_diagonal_tearing_fix = false;
config->scale_back_buffer_width = 0;
config->scale_back_buffer_height = 0;
config->scale_back_buffer_filter =
@ -1112,6 +1157,12 @@ iidxhook_util_d3d9_irp_handler(struct hook_d3d9_irp *irp)
return hook_d3d9_irp_invoke_next(irp);
case HOOK_D3D9_IRP_OP_DEV_SET_VIEWPORT:
case HOOK_D3D9_IRP_OP_DEV_SET_VERTEX_SHADER:
iidxhook_util_d3d9_iidx18_and_19_fix_diagonal_tearing(irp);
return hook_d3d9_irp_invoke_next(irp);
default:
return hook_d3d9_irp_invoke_next(irp);
}

View File

@ -131,6 +131,11 @@ struct iidxhook_util_d3d9_config {
*/
bool iidx14_to_19_nvidia_fix;
/**
* Fix diagonal tearing with video cards other than Radeon X1300 and HD3450
*/
bool iidx18_and_19_diagonal_tearing_fix;
/**
* Scale the back buffer after a frame got rendered. This allows you to
* up-/downscale the final frame to display arbitrary resolutions, e.g.

View File

@ -0,0 +1,107 @@
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 10.1
//
// Parameters:
//
// float4 ColorMultiply;
// float2 FixOffset;
// float4x4 WorldViewProjection;
//
//
// Registers:
//
// Name Reg Size
// ------------------- ----- ----
// WorldViewProjection c0 4
// ColorMultiply c4 1
// FixOffset c63 1
//
vs_1_1
dcl_position v0
dcl_color v1
dcl_texcoord v2
dp4 oPos.z, v0, c2
mul oD0, v1, c4
dp4 r0.x, v0, c0
dp4 r0.y, v0, c1
dp4 r0.z, v0, c3
mad oPos.xy, c63, r0.z, r0
mov oPos.w, r0.z
mov oT0.xy, v2
// approximately 8 instruction slots used
#endif
const BYTE g_vs11_vs_main[] =
{
1, 1, 254, 255, 254, 255,
59, 0, 67, 84, 65, 66,
28, 0, 0, 0, 191, 0,
0, 0, 1, 1, 254, 255,
3, 0, 0, 0, 28, 0,
0, 0, 0, 1, 0, 0,
184, 0, 0, 0, 88, 0,
0, 0, 2, 0, 4, 0,
1, 0, 18, 0, 104, 0,
0, 0, 0, 0, 0, 0,
120, 0, 0, 0, 2, 0,
63, 0, 1, 0, 254, 0,
132, 0, 0, 0, 0, 0,
0, 0, 148, 0, 0, 0,
2, 0, 0, 0, 4, 0,
2, 0, 168, 0, 0, 0,
0, 0, 0, 0, 67, 111,
108, 111, 114, 77, 117, 108,
116, 105, 112, 108, 121, 0,
171, 171, 1, 0, 3, 0,
1, 0, 4, 0, 1, 0,
0, 0, 0, 0, 0, 0,
70, 105, 120, 79, 102, 102,
115, 101, 116, 0, 171, 171,
1, 0, 3, 0, 1, 0,
2, 0, 1, 0, 0, 0,
0, 0, 0, 0, 87, 111,
114, 108, 100, 86, 105, 101,
119, 80, 114, 111, 106, 101,
99, 116, 105, 111, 110, 0,
3, 0, 3, 0, 4, 0,
4, 0, 1, 0, 0, 0,
0, 0, 0, 0, 118, 115,
95, 49, 95, 49, 0, 77,
105, 99, 114, 111, 115, 111,
102, 116, 32, 40, 82, 41,
32, 72, 76, 83, 76, 32,
83, 104, 97, 100, 101, 114,
32, 67, 111, 109, 112, 105,
108, 101, 114, 32, 49, 48,
46, 49, 0, 171, 31, 0,
0, 0, 0, 0, 0, 128,
0, 0, 15, 144, 31, 0,
0, 0, 10, 0, 0, 128,
1, 0, 15, 144, 31, 0,
0, 0, 5, 0, 0, 128,
2, 0, 15, 144, 9, 0,
0, 0, 0, 0, 4, 192,
0, 0, 228, 144, 2, 0,
228, 160, 5, 0, 0, 0,
0, 0, 15, 208, 1, 0,
228, 144, 4, 0, 228, 160,
9, 0, 0, 0, 0, 0,
1, 128, 0, 0, 228, 144,
0, 0, 228, 160, 9, 0,
0, 0, 0, 0, 2, 128,
0, 0, 228, 144, 1, 0,
228, 160, 9, 0, 0, 0,
0, 0, 4, 128, 0, 0,
228, 144, 3, 0, 228, 160,
4, 0, 0, 0, 0, 0,
3, 192, 63, 0, 228, 160,
0, 0, 170, 128, 0, 0,
228, 128, 1, 0, 0, 0,
0, 0, 8, 192, 0, 0,
170, 128, 1, 0, 0, 0,
0, 0, 3, 224, 2, 0,
228, 144, 255, 255, 0, 0
};

View File

@ -0,0 +1,40 @@
/*
* original shader
* vs.1.1 //Shader version 1.1
* dcl_position v0;
* dcl_color v1;
* dcl_texcoord0 v2;
* m4x4 oPos, v0, c0
* mul oD0, v1, c4
* mov oT0.xy, v2
*
* build command
* fxc.exe /Vi vertex-shader.hlsl /Fh vertex-shader.h /T vs_1_1 /E vs_main
*/
float4x4 WorldViewProjection : register(c0);
float4 ColorMultiply : register(c4);
float2 FixOffset : register(c63);
struct VS {
float4 Position : POSITION; // dcl_position v0;
float4 Color : COLOR; // dcl_color v1;
float2 TexCoord : TEXCOORD0; // dcl_texcoord0 v2;
};
VS vs_main(VS input)
{
VS output;
output.Position = mul(input.Position, WorldViewProjection); // m4x4 oPos, v0, c0
output.Color.x = mul(input.Color.x, ColorMultiply.x); // mul oD0, v1, c4
output.Color.y = mul(input.Color.y, ColorMultiply.y);
output.Color.z = mul(input.Color.z, ColorMultiply.z);
output.Color.w = mul(input.Color.w, ColorMultiply.w);
output.TexCoord = input.TexCoord; // mov oT0.xy, v2
// fix diagonal tearing
output.Position.xy += FixOffset.xy * output.Position.w;
return output;
}

View File

@ -79,8 +79,10 @@ iidxhook4_cn_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
d3d9_config.scale_back_buffer_filter = config_gfx->scale_back_buffer_filter;
d3d9_config.forced_refresh_rate = config_gfx->forced_refresh_rate;
d3d9_config.device_adapter = config_gfx->device_adapter;
d3d9_config.iidx18_and_19_diagonal_tearing_fix = config_gfx->diagonal_tearing_fix;
/* Required for GOLD (and newer?) to not crash with NVIDIA cards */
d3d9_config.iidx14_to_19_nvidia_fix = true;
d3d9_config.iidx18_and_19_diagonal_tearing_fix = config_gfx->diagonal_tearing_fix;
if (config_gfx->monitor_check == 0) {
log_info("Auto monitor check enabled");

View File

@ -72,6 +72,7 @@ iidxhook4_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
d3d9_config.device_adapter = config_gfx->device_adapter;
/* Required for GOLD (and newer?) to not crash with NVIDIA cards */
d3d9_config.iidx14_to_19_nvidia_fix = true;
d3d9_config.iidx18_and_19_diagonal_tearing_fix = config_gfx->diagonal_tearing_fix;
if (config_gfx->monitor_check == 0) {
log_info("Auto monitor check enabled");

View File

@ -81,6 +81,7 @@ iidxhook5_cn_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
d3d9_config.device_adapter = config_gfx->device_adapter;
/* Required for GOLD (and newer?) to not crash with NVIDIA cards */
d3d9_config.iidx14_to_19_nvidia_fix = true;
d3d9_config.iidx18_and_19_diagonal_tearing_fix = config_gfx->diagonal_tearing_fix;
iidxhook_util_d3d9_configure(&d3d9_config);

View File

@ -71,6 +71,7 @@ iidxhook5_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
d3d9_config.device_adapter = config_gfx->device_adapter;
/* Required for GOLD (and newer?) to not crash with NVIDIA cards */
d3d9_config.iidx14_to_19_nvidia_fix = true;
d3d9_config.iidx18_and_19_diagonal_tearing_fix = config_gfx->diagonal_tearing_fix;
iidxhook_util_d3d9_configure(&d3d9_config);