From 4ed512855ed412666320f43c0540bd91c4b2d1f2 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Sun, 12 Sep 2021 14:41:08 +0800 Subject: [PATCH] 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. --- artifacts/ddraw.ini | 4 +- artifacts/scripting/headers/sfall.h | 2 + sfall/Graphics.cpp | 118 +++++++--------------------- sfall/Graphics.h | 70 +++++++++++++++++ sfall/MiscPatches.cpp | 71 +++++++---------- sfall/SpeedPatch.cpp | 16 ++-- 6 files changed, 142 insertions(+), 139 deletions(-) diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index be08010d..7ad2c8b0 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -46,8 +46,8 @@ GraphicsWidth=0 GraphicsHeight=0 ;Window position data. Do not modify -;Set to 0 to reset if the window position is incorrect -WindowData=0 +;Set to -1 or 0 to reset if the window position is incorrect +WindowData=-1 ;Uncomment the option to use a hardware shader (requires DX9 graphics mode) ;The shader file .fx must be placed in \\shaders\ and must contain one technique with one or more passes diff --git a/artifacts/scripting/headers/sfall.h b/artifacts/scripting/headers/sfall.h index ef3074f1..53f4e06f 100644 --- a/artifacts/scripting/headers/sfall.h +++ b/artifacts/scripting/headers/sfall.h @@ -310,6 +310,7 @@ #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_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 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) @@ -354,6 +355,7 @@ #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_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 spatial_radius(obj) sfall_func1("spatial_radius", obj) #define string_compare(str1, str2) sfall_func2("string_compare", str1, str2) diff --git a/sfall/Graphics.cpp b/sfall/Graphics.cpp index c929712c..f9e51a36 100644 --- a/sfall/Graphics.cpp +++ b/sfall/Graphics.cpp @@ -30,76 +30,6 @@ typedef HRESULT (__stdcall *DDrawCreateProc)(void*, IDirectDraw**, void*); //typedef IDirect3D9* (__stdcall *D3DCreateProc)(UINT version); -static const char* gpuEffectA8 = - "texture image;" - "texture palette;" - "texture head;" - "sampler s0 = sampler_state { texture=; };" - "sampler s1 = sampler_state { texture=; minFilter=none; magFilter=none; addressU=clamp; addressV=clamp; };" - "sampler s2 = sampler_state { texture=; 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=; };" - "sampler s1 = sampler_state { texture=; minFilter=none; magFilter=none; addressU=clamp; addressV=clamp; };" - "sampler s2 = sampler_state { texture=; 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 static DWORD ResWidth; @@ -127,9 +57,10 @@ static struct PALCOLOR { union { DWORD xRGB; struct { - BYTE B; - BYTE G; BYTE R; + BYTE G; + BYTE B; + BYTE x; }; }; } palette[256]; @@ -143,8 +74,8 @@ static DWORD gHeight; static long moveWindowKey[2]; static bool windowInit = false; -static DWORD windowLeft = 0; -static DWORD windowTop = 0; +static long windowLeft = 0; +static long windowTop = 0; static HWND window; static DWORD windowStyle = WS_CAPTION | WS_BORDER | WS_MINIMIZEBOX; @@ -364,6 +295,14 @@ static void WindowInit() { 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) { ZeroMemory(&ddm, sizeof(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 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) { SetGPUPalette(); } else { // X8B8G8R8 format for (size_t i = b; i < b + c; i++) { // swap color B <> R - BYTE clr = palette[i].B; - palette[i].B = palette[i].R; - palette[i].R = clr; + BYTE clrB = palette[i].R; + palette[i].R = palette[i].B; + palette[i].B = clrB; } primaryDDSurface->SetPalette(0); // update texture 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); r.right -= r.left; r.bottom -= r.top; - if (!SetWindowPos(a, HWND_NOTOPMOST, windowLeft, windowTop, r.right, r.bottom, SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_SHOWWINDOW)) { - windowLeft = windowTop = 0; // fail to set position - } + SetWindowPos(a, HWND_NOTOPMOST, windowLeft, windowTop, r.right, r.bottom, SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_SHOWWINDOW); } dlogr(" Done", DL_MAIN); @@ -1225,10 +1162,10 @@ HRESULT __stdcall FakeDirectDrawCreate2(void*, IDirectDraw** b, void*) { gWidth = dispMode.Width; gHeight = dispMode.Height; } else { - gWidth = GetConfigInt("Graphics", "GraphicsWidth", 0); + gWidth = GetConfigInt("Graphics", "GraphicsWidth", 0); gHeight = GetConfigInt("Graphics", "GraphicsHeight", 0); if (!gWidth || !gHeight) { - gWidth = ResWidth; + gWidth = ResWidth; gHeight = ResHeight; } } @@ -1260,12 +1197,12 @@ HRESULT __stdcall FakeDirectDrawCreate2(void*, IDirectDraw** b, void*) { } else { moveWindowKey[0] &= 0xFF; } - windowData = GetConfigInt("Graphics", "WindowData", 0); + windowData = GetConfigInt("Graphics", "WindowData", -1); if (windowData > 0) { windowLeft = windowData >> 16; windowTop = windowData & 0xFFFF; - } else { - windowData = 0; + } else if (windowData == -1) { + CenterWindow(); } } @@ -1469,8 +1406,13 @@ void Graphics_Init() { SafeWrite8(0x50FB6B, '2'); // Set call DirectDrawCreate2 HookCall(0x44260C, game_init_hook); - // Patch HRP to show the mouse cursor over the window title - if (GraphicsMode == 5 && hrpVersionValid) SafeWrite8(HRPAddress(0x10027142), CODETYPE_JumpShort); + if (hrpVersionValid) { + // 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); dlogr(" Done", DL_INIT); diff --git a/sfall/Graphics.h b/sfall/Graphics.h index b47d073e..00a7dfb5 100644 --- a/sfall/Graphics.h +++ b/sfall/Graphics.h @@ -103,3 +103,73 @@ __forceinline void UpdateDDSurface(BYTE* surface, int width, int height, int wid primaryDDSurface->Unlock(desc.lpSurface); } } + +static const char* gpuEffectA8 = + "texture image;" + "texture palette;" + "texture head;" + "sampler s0 = sampler_state { texture=; };" + "sampler s1 = sampler_state { texture=; minFilter=none; magFilter=none; addressU=clamp; addressV=clamp; };" + "sampler s2 = sampler_state { texture=; 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=; };" + "sampler s1 = sampler_state { texture=; minFilter=none; magFilter=none; addressU=clamp; addressV=clamp; };" + "sampler s2 = sampler_state { texture=; 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(); }" + "}"; diff --git a/sfall/MiscPatches.cpp b/sfall/MiscPatches.cpp index b135c341..ab0584f1 100644 --- a/sfall/MiscPatches.cpp +++ b/sfall/MiscPatches.cpp @@ -725,58 +725,47 @@ static void __declspec(naked) main_death_scene_hook() { } } -static void __declspec(naked) SplitPrintMessage() { - __asm { - push esi; - push ecx; - test eax, eax; // Is there a string? - jz end; // No - mov esi, eax; - xor ecx, ecx; -loopString: - cmp byte ptr [esi], 0; // End of string? - je printLine; // Yes - cmp byte ptr [esi], 0x5C; // Possible a newline character '\'? - jne nextChar; // No - cmp byte ptr [esi + 1], 0x6E; // Exactly the newline character 'n'? - jne nextChar; // No - inc ecx; - mov byte ptr [esi], 0; // set null terminator -printLine: - call edi; - test ecx, ecx; - 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 __stdcall SplitPrintMessage(char* message, void* printFunc) { + char* text = message; + while (*text) { + if (text[0] == '\\' && text[1] == 'n') { + *text = 0; // set null terminator + + __asm mov eax, message; + __asm call printFunc; + + *text = '\\'; + text += 2; // position after the 'n' character + message = text; + } else { + text++; + } + } + // print the last line or all the text if there is no line break + if (message != text) { + __asm mov eax, message; + __asm call printFunc; } } static void __declspec(naked) sf_display_print_alt() { __asm { - push edi; - mov edi, display_print_; - call SplitPrintMessage; // eax - message - pop edi; + push ecx; + push display_print_; + push eax; // message + call SplitPrintMessage; + pop ecx; retn; } } static void __declspec(naked) sf_inven_display_msg() { __asm { - push edi; - mov edi, inven_display_msg_; - call SplitPrintMessage; // eax - message - pop edi; + push ecx; + push inven_display_msg_; + push eax; // message + call SplitPrintMessage; + pop ecx; retn; } } diff --git a/sfall/SpeedPatch.cpp b/sfall/SpeedPatch.cpp index 152c7f0f..6c5d25a6 100644 --- a/sfall/SpeedPatch.cpp +++ b/sfall/SpeedPatch.cpp @@ -62,16 +62,16 @@ static bool enabled = true; static bool toggled = false; static bool slideShow = false; -static double multi; +static float multi; static DWORD sfallTickCount = 0; static DWORD lastTickCount; -static double tickCountFraction = 0.0; +static float tickCountFraction = 0.0f; static __int64 startTime; static struct SpeedCfg { int key; - double multiplier; + float multiplier; } *speed = nullptr; static int modKey[2]; @@ -122,7 +122,7 @@ static DWORD __stdcall FakeGetTickCount() { return sfallTickCount; } - double elapsed = (double)(newTickCount - lastTickCount); + float elapsed = static_cast(newTickCount - lastTickCount); lastTickCount = newTickCount; // Multiply the tick count difference by the multiplier @@ -132,13 +132,13 @@ static DWORD __stdcall FakeGetTickCount() { { elapsed *= multi; elapsed += tickCountFraction; - tickCountFraction = modf(elapsed, &elapsed); + tickCountFraction = std::modf(elapsed, &elapsed); if (defaultDelay) SetKeyboardDelay(); } else { SetKeyboardDefaultDelay(); } - sfallTickCount += (DWORD)elapsed; + sfallTickCount += static_cast(elapsed); return sfallTickCount; } @@ -181,7 +181,7 @@ void TimerInit() { _itoa(i, buf, 10); spKey[8] = spMulti[10] = buf[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; } - multi = (double)init / 100.0; + multi = init / 100.0f; toggleKey = GetConfigInt("Input", "SpeedToggleKey", 0); getTickCountOffs = (DWORD)&FakeGetTickCount;