Added a fix to display the color index 255 of the palette correctly

* in DX9 mode when using the hi-res patch

Some minor code corrections.
This commit is contained in:
NovaRain
2021-09-12 14:41:08 +08:00
parent 95a03d7429
commit 4ed512855e
6 changed files with 142 additions and 139 deletions
+2 -2
View File
@@ -46,8 +46,8 @@ GraphicsWidth=0
GraphicsHeight=0 GraphicsHeight=0
;Window position data. Do not modify ;Window position data. Do not modify
;Set to 0 to reset if the window position is incorrect ;Set to -1 or 0 to reset if the window position is incorrect
WindowData=0 WindowData=-1
;Uncomment the option to use a hardware shader (requires DX9 graphics mode) ;Uncomment the option to use a hardware shader (requires DX9 graphics mode)
;The shader file <name>.fx must be placed in <GameRoot>\<master_patches>\shaders\ and must contain one technique with one or more passes ;The shader file <name>.fx must be placed in <GameRoot>\<master_patches>\shaders\ and must contain one technique with one or more passes
+2
View File
@@ -310,6 +310,7 @@
#define get_npc_stat_min(stat) sfall_func2("get_stat_min", stat, 1) #define get_npc_stat_min(stat) sfall_func2("get_stat_min", stat, 1)
#define get_sfall_arg_at(argNum) sfall_func1("get_sfall_arg_at", argNum) #define get_sfall_arg_at(argNum) sfall_func1("get_sfall_arg_at", argNum)
#define get_text_width(text) sfall_func1("get_text_width", text) #define get_text_width(text) sfall_func1("get_text_width", text)
#define hide_win sfall_func0("hide_window")
#define hide_window(winName) sfall_func1("hide_window", winName) #define hide_window(winName) sfall_func1("hide_window", winName)
#define interface_art_draw(winID, artFile, x, y) sfall_func4("interface_art_draw", winID, artFile, x, y) #define interface_art_draw(winID, artFile, x, y) sfall_func4("interface_art_draw", winID, artFile, x, y)
#define interface_art_draw_frame(winID, artID, x, y, frame) sfall_func5("interface_art_draw", winID, artID, x, y, frame) #define interface_art_draw_frame(winID, artID, x, y, frame) sfall_func5("interface_art_draw", winID, artID, x, y, frame)
@@ -354,6 +355,7 @@
#define set_unique_id(obj) sfall_func1("set_unique_id", obj) #define set_unique_id(obj) sfall_func1("set_unique_id", obj)
#define set_unjam_locks_time(time) sfall_func1("set_unjam_locks_time", time) #define set_unjam_locks_time(time) sfall_func1("set_unjam_locks_time", time)
#define set_window_flag(winID, flag, value) sfall_func3("set_window_flag", winID, flag, value) #define set_window_flag(winID, flag, value) sfall_func3("set_window_flag", winID, flag, value)
#define show_win sfall_func0("show_window")
#define show_window(winName) sfall_func1("show_window", winName) #define show_window(winName) sfall_func1("show_window", winName)
#define spatial_radius(obj) sfall_func1("spatial_radius", obj) #define spatial_radius(obj) sfall_func1("spatial_radius", obj)
#define string_compare(str1, str2) sfall_func2("string_compare", str1, str2) #define string_compare(str1, str2) sfall_func2("string_compare", str1, str2)
+30 -88
View File
@@ -30,76 +30,6 @@
typedef HRESULT (__stdcall *DDrawCreateProc)(void*, IDirectDraw**, void*); typedef HRESULT (__stdcall *DDrawCreateProc)(void*, IDirectDraw**, void*);
//typedef IDirect3D9* (__stdcall *D3DCreateProc)(UINT version); //typedef IDirect3D9* (__stdcall *D3DCreateProc)(UINT version);
static const char* gpuEffectA8 =
"texture image;"
"texture palette;"
"texture head;"
"sampler s0 = sampler_state { texture=<image>; };"
"sampler s1 = sampler_state { texture=<palette>; minFilter=none; magFilter=none; addressU=clamp; addressV=clamp; };"
"sampler s2 = sampler_state { texture=<head>; minFilter=linear; magFilter=linear; addressU=clamp; addressV=clamp; };"
"float2 size;"
"float2 corner;"
// shader for displaying head textures
"float4 P1( in float2 Tex : TEXCOORD0 ) : COLOR0 {"
"float backdrop = tex2D(s0, Tex).a;"
"float3 result;"
"if (abs(backdrop - 1.0) < 0.001) {" // (48.0 / 255.0) // 48 - key index color
"result = tex2D(s2, saturate((Tex - corner) / size));"
"} else {"
"result = tex1D(s1, backdrop).bgr;" // get color in palette and swap R <> B
"}"
"return float4(result, 1);"
"}"
"technique T1"
"{"
"pass p1 { PixelShader = compile ps_2_0 P1(); }"
"}"
// main shader
"float4 P0( in float2 Tex : TEXCOORD0 ) : COLOR0 {"
"float3 result = tex1D(s1, tex2D(s0, Tex).a);" // get color in palette
"return float4(result.bgr, 1);" // swap R <> B
"}"
"technique T0"
"{"
"pass p0 { PixelShader = compile ps_2_0 P0(); }"
"}";
static const char* gpuEffectL8 =
"texture image;"
"texture palette;"
"texture head;"
"sampler s0 = sampler_state { texture=<image>; };"
"sampler s1 = sampler_state { texture=<palette>; minFilter=none; magFilter=none; addressU=clamp; addressV=clamp; };"
"sampler s2 = sampler_state { texture=<head>; minFilter=linear; magFilter=linear; addressU=clamp; addressV=clamp; };"
"float2 size;"
"float2 corner;"
// shader for displaying head textures
"float4 P1( in float2 Tex : TEXCOORD0 ) : COLOR0 {"
"float backdrop = tex2D(s0, Tex).r;"
"float3 result;"
"if (abs(backdrop - 1.0) < 0.001) {"
"result = tex2D(s2, saturate((Tex - corner) / size));"
"} else {"
"result = tex1D(s1, backdrop).bgr;"
"}"
"return float4(result, 1);"
"}"
"technique T1"
"{"
"pass p1 { PixelShader = compile ps_2_0 P1(); }"
"}"
// main shader
"float4 P0( in float2 Tex : TEXCOORD0 ) : COLOR0 {"
"float3 result = tex1D(s1, tex2D(s0, Tex).r);"
"return float4(result.bgr, 1);"
"}"
"technique T0"
"{"
"pass p0 { PixelShader = compile ps_2_0 P0(); }"
"}";
IDirectDrawSurface* primaryDDSurface = nullptr; // aka _GNW95_DDPrimarySurface IDirectDrawSurface* primaryDDSurface = nullptr; // aka _GNW95_DDPrimarySurface
static DWORD ResWidth; static DWORD ResWidth;
@@ -127,9 +57,10 @@ static struct PALCOLOR {
union { union {
DWORD xRGB; DWORD xRGB;
struct { struct {
BYTE B;
BYTE G;
BYTE R; BYTE R;
BYTE G;
BYTE B;
BYTE x;
}; };
}; };
} palette[256]; } palette[256];
@@ -143,8 +74,8 @@ static DWORD gHeight;
static long moveWindowKey[2]; static long moveWindowKey[2];
static bool windowInit = false; static bool windowInit = false;
static DWORD windowLeft = 0; static long windowLeft = 0;
static DWORD windowTop = 0; static long windowTop = 0;
static HWND window; static HWND window;
static DWORD windowStyle = WS_CAPTION | WS_BORDER | WS_MINIMIZEBOX; static DWORD windowStyle = WS_CAPTION | WS_BORDER | WS_MINIMIZEBOX;
@@ -364,6 +295,14 @@ static void WindowInit() {
LoadGlobalShader(); LoadGlobalShader();
} }
static void CenterWindow() {
RECT desktop;
GetWindowRect(GetDesktopWindow(), &desktop);
windowLeft = (desktop.right / 2) - (gWidth / 2);
windowTop = (desktop.bottom / 2) - (gHeight / 2);
}
static void GetDisplayMode(D3DDISPLAYMODE &ddm) { static void GetDisplayMode(D3DDISPLAYMODE &ddm) {
ZeroMemory(&ddm, sizeof(ddm)); ZeroMemory(&ddm, sizeof(ddm));
d3d9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &ddm); d3d9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &ddm);
@@ -1058,16 +997,16 @@ public:
HRESULT __stdcall SetEntries(DWORD a, DWORD b, DWORD c, LPPALETTEENTRY destPal) { // used to set palette for splash screen, fades, subtitles HRESULT __stdcall SetEntries(DWORD a, DWORD b, DWORD c, LPPALETTEENTRY destPal) { // used to set palette for splash screen, fades, subtitles
if (!windowInit || c == 0 || b + c > 256) return DDERR_INVALIDPARAMS; if (!windowInit || c == 0 || b + c > 256) return DDERR_INVALIDPARAMS;
__movsd((DWORD*)&palette[b], (DWORD*)destPal, c); __movsd((DWORD*)&palette[b], (DWORD*)destPal, c); // copy DWORDs
if (GPUBlt) { if (GPUBlt) {
SetGPUPalette(); SetGPUPalette();
} else { } else {
// X8B8G8R8 format // X8B8G8R8 format
for (size_t i = b; i < b + c; i++) { // swap color B <> R for (size_t i = b; i < b + c; i++) { // swap color B <> R
BYTE clr = palette[i].B; BYTE clrB = palette[i].R;
palette[i].B = palette[i].R; palette[i].R = palette[i].B;
palette[i].R = clr; palette[i].B = clrB;
} }
primaryDDSurface->SetPalette(0); // update texture primaryDDSurface->SetPalette(0); // update texture
if (FakeDirectDrawSurface::IsPlayMovie) return DD_OK; // prevents flickering at the beginning of playback (w/o HRP & GPUBlt=2) if (FakeDirectDrawSurface::IsPlayMovie) return DD_OK; // prevents flickering at the beginning of playback (w/o HRP & GPUBlt=2)
@@ -1176,9 +1115,7 @@ public:
AdjustWindowRect(&r, windowStyle, false); AdjustWindowRect(&r, windowStyle, false);
r.right -= r.left; r.right -= r.left;
r.bottom -= r.top; r.bottom -= r.top;
if (!SetWindowPos(a, HWND_NOTOPMOST, windowLeft, windowTop, r.right, r.bottom, SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_SHOWWINDOW)) { SetWindowPos(a, HWND_NOTOPMOST, windowLeft, windowTop, r.right, r.bottom, SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_SHOWWINDOW);
windowLeft = windowTop = 0; // fail to set position
}
} }
dlogr(" Done", DL_MAIN); dlogr(" Done", DL_MAIN);
@@ -1225,10 +1162,10 @@ HRESULT __stdcall FakeDirectDrawCreate2(void*, IDirectDraw** b, void*) {
gWidth = dispMode.Width; gWidth = dispMode.Width;
gHeight = dispMode.Height; gHeight = dispMode.Height;
} else { } else {
gWidth = GetConfigInt("Graphics", "GraphicsWidth", 0); gWidth = GetConfigInt("Graphics", "GraphicsWidth", 0);
gHeight = GetConfigInt("Graphics", "GraphicsHeight", 0); gHeight = GetConfigInt("Graphics", "GraphicsHeight", 0);
if (!gWidth || !gHeight) { if (!gWidth || !gHeight) {
gWidth = ResWidth; gWidth = ResWidth;
gHeight = ResHeight; gHeight = ResHeight;
} }
} }
@@ -1260,12 +1197,12 @@ HRESULT __stdcall FakeDirectDrawCreate2(void*, IDirectDraw** b, void*) {
} else { } else {
moveWindowKey[0] &= 0xFF; moveWindowKey[0] &= 0xFF;
} }
windowData = GetConfigInt("Graphics", "WindowData", 0); windowData = GetConfigInt("Graphics", "WindowData", -1);
if (windowData > 0) { if (windowData > 0) {
windowLeft = windowData >> 16; windowLeft = windowData >> 16;
windowTop = windowData & 0xFFFF; windowTop = windowData & 0xFFFF;
} else { } else if (windowData == -1) {
windowData = 0; CenterWindow();
} }
} }
@@ -1469,8 +1406,13 @@ void Graphics_Init() {
SafeWrite8(0x50FB6B, '2'); // Set call DirectDrawCreate2 SafeWrite8(0x50FB6B, '2'); // Set call DirectDrawCreate2
HookCall(0x44260C, game_init_hook); HookCall(0x44260C, game_init_hook);
// Patch HRP to show the mouse cursor over the window title if (hrpVersionValid) {
if (GraphicsMode == 5 && hrpVersionValid) SafeWrite8(HRPAddress(0x10027142), CODETYPE_JumpShort); // Patch HRP to show the mouse cursor over the window title
if (GraphicsMode == 5) SafeWrite8(HRPAddress(0x10027142), CODETYPE_JumpShort);
// Patch HRP to fix the issue of displaying a palette color with index 255 for images (splash screens, ending slides)
SafeWrite8(HRPAddress(0x1000F8C7), CODETYPE_JumpShort);
}
textureFilter = GetConfigInt("Graphics", "TextureFilter", 1); textureFilter = GetConfigInt("Graphics", "TextureFilter", 1);
dlogr(" Done", DL_INIT); dlogr(" Done", DL_INIT);
+70
View File
@@ -103,3 +103,73 @@ __forceinline void UpdateDDSurface(BYTE* surface, int width, int height, int wid
primaryDDSurface->Unlock(desc.lpSurface); primaryDDSurface->Unlock(desc.lpSurface);
} }
} }
static const char* gpuEffectA8 =
"texture image;"
"texture palette;"
"texture head;"
"sampler s0 = sampler_state { texture=<image>; };"
"sampler s1 = sampler_state { texture=<palette>; minFilter=none; magFilter=none; addressU=clamp; addressV=clamp; };"
"sampler s2 = sampler_state { texture=<head>; minFilter=linear; magFilter=linear; addressU=clamp; addressV=clamp; };"
"float2 size;"
"float2 corner;"
// shader for displaying head textures
"float4 P1( in float2 Tex : TEXCOORD0 ) : COLOR0 {"
"float backdrop = tex2D(s0, Tex).a;"
"float3 result;"
"if (abs(backdrop - 1.0) < 0.001) {" // (48.0 / 255.0) // 48 - key index color
"result = tex2D(s2, saturate((Tex - corner) / size));"
"} else {"
"result = tex1D(s1, backdrop).bgr;" // get color in palette and swap R <> B
"}"
"return float4(result, 1);"
"}"
"technique T1"
"{"
"pass p1 { PixelShader = compile ps_2_0 P1(); }"
"}"
// main shader
"float4 P0( in float2 Tex : TEXCOORD0 ) : COLOR0 {"
"float3 result = tex1D(s1, tex2D(s0, Tex).a);" // get color in palette
"return float4(result.bgr, 1);" // swap R <> B
"}"
"technique T0"
"{"
"pass p0 { PixelShader = compile ps_2_0 P0(); }"
"}";
static const char* gpuEffectL8 =
"texture image;"
"texture palette;"
"texture head;"
"sampler s0 = sampler_state { texture=<image>; };"
"sampler s1 = sampler_state { texture=<palette>; minFilter=none; magFilter=none; addressU=clamp; addressV=clamp; };"
"sampler s2 = sampler_state { texture=<head>; minFilter=linear; magFilter=linear; addressU=clamp; addressV=clamp; };"
"float2 size;"
"float2 corner;"
// shader for displaying head textures
"float4 P1( in float2 Tex : TEXCOORD0 ) : COLOR0 {"
"float backdrop = tex2D(s0, Tex).r;"
"float3 result;"
"if (abs(backdrop - 1.0) < 0.001) {"
"result = tex2D(s2, saturate((Tex - corner) / size));"
"} else {"
"result = tex1D(s1, backdrop).bgr;"
"}"
"return float4(result, 1);"
"}"
"technique T1"
"{"
"pass p1 { PixelShader = compile ps_2_0 P1(); }"
"}"
// main shader
"float4 P0( in float2 Tex : TEXCOORD0 ) : COLOR0 {"
"float3 result = tex1D(s1, tex2D(s0, Tex).r);"
"return float4(result.bgr, 1);"
"}"
"technique T0"
"{"
"pass p0 { PixelShader = compile ps_2_0 P0(); }"
"}";
+30 -41
View File
@@ -725,58 +725,47 @@ static void __declspec(naked) main_death_scene_hook() {
} }
} }
static void __declspec(naked) SplitPrintMessage() { static void __stdcall SplitPrintMessage(char* message, void* printFunc) {
__asm { char* text = message;
push esi; while (*text) {
push ecx; if (text[0] == '\\' && text[1] == 'n') {
test eax, eax; // Is there a string? *text = 0; // set null terminator
jz end; // No
mov esi, eax; __asm mov eax, message;
xor ecx, ecx; __asm call printFunc;
loopString:
cmp byte ptr [esi], 0; // End of string? *text = '\\';
je printLine; // Yes text += 2; // position after the 'n' character
cmp byte ptr [esi], 0x5C; // Possible a newline character '\'? message = text;
jne nextChar; // No } else {
cmp byte ptr [esi + 1], 0x6E; // Exactly the newline character 'n'? text++;
jne nextChar; // No }
inc ecx; }
mov byte ptr [esi], 0; // set null terminator // print the last line or all the text if there is no line break
printLine: if (message != text) {
call edi; __asm mov eax, message;
test ecx, ecx; __asm call printFunc;
jz end;
dec ecx;
mov byte ptr [esi], 0x5C;
inc esi;
mov eax, esi;
inc eax;
nextChar:
inc esi;
jmp loopString;
end:
pop ecx;
pop esi;
retn;
} }
} }
static void __declspec(naked) sf_display_print_alt() { static void __declspec(naked) sf_display_print_alt() {
__asm { __asm {
push edi; push ecx;
mov edi, display_print_; push display_print_;
call SplitPrintMessage; // eax - message push eax; // message
pop edi; call SplitPrintMessage;
pop ecx;
retn; retn;
} }
} }
static void __declspec(naked) sf_inven_display_msg() { static void __declspec(naked) sf_inven_display_msg() {
__asm { __asm {
push edi; push ecx;
mov edi, inven_display_msg_; push inven_display_msg_;
call SplitPrintMessage; // eax - message push eax; // message
pop edi; call SplitPrintMessage;
pop ecx;
retn; retn;
} }
} }
+8 -8
View File
@@ -62,16 +62,16 @@ static bool enabled = true;
static bool toggled = false; static bool toggled = false;
static bool slideShow = false; static bool slideShow = false;
static double multi; static float multi;
static DWORD sfallTickCount = 0; static DWORD sfallTickCount = 0;
static DWORD lastTickCount; static DWORD lastTickCount;
static double tickCountFraction = 0.0; static float tickCountFraction = 0.0f;
static __int64 startTime; static __int64 startTime;
static struct SpeedCfg { static struct SpeedCfg {
int key; int key;
double multiplier; float multiplier;
} *speed = nullptr; } *speed = nullptr;
static int modKey[2]; static int modKey[2];
@@ -122,7 +122,7 @@ static DWORD __stdcall FakeGetTickCount() {
return sfallTickCount; return sfallTickCount;
} }
double elapsed = (double)(newTickCount - lastTickCount); float elapsed = static_cast<float>(newTickCount - lastTickCount);
lastTickCount = newTickCount; lastTickCount = newTickCount;
// Multiply the tick count difference by the multiplier // Multiply the tick count difference by the multiplier
@@ -132,13 +132,13 @@ static DWORD __stdcall FakeGetTickCount() {
{ {
elapsed *= multi; elapsed *= multi;
elapsed += tickCountFraction; elapsed += tickCountFraction;
tickCountFraction = modf(elapsed, &elapsed); tickCountFraction = std::modf(elapsed, &elapsed);
if (defaultDelay) SetKeyboardDelay(); if (defaultDelay) SetKeyboardDelay();
} else { } else {
SetKeyboardDefaultDelay(); SetKeyboardDefaultDelay();
} }
sfallTickCount += (DWORD)elapsed; sfallTickCount += static_cast<DWORD>(elapsed);
return sfallTickCount; return sfallTickCount;
} }
@@ -181,7 +181,7 @@ void TimerInit() {
_itoa(i, buf, 10); _itoa(i, buf, 10);
spKey[8] = spMulti[10] = buf[0]; spKey[8] = spMulti[10] = buf[0];
speed[i].key = GetConfigInt("Input", spKey, 0); speed[i].key = GetConfigInt("Input", spKey, 0);
speed[i].multiplier = GetConfigInt("Speed", spMulti, 0) / 100.0; speed[i].multiplier = GetConfigInt("Speed", spMulti, 0) / 100.0f;
} }
} }
@@ -210,7 +210,7 @@ void SpeedPatch_Init() {
modKey[1] = 0; modKey[1] = 0;
} }
multi = (double)init / 100.0; multi = init / 100.0f;
toggleKey = GetConfigInt("Input", "SpeedToggleKey", 0); toggleKey = GetConfigInt("Input", "SpeedToggleKey", 0);
getTickCountOffs = (DWORD)&FakeGetTickCount; getTickCountOffs = (DWORD)&FakeGetTickCount;