mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
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:
+2
-2
@@ -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 <name>.fx must be placed in <GameRoot>\<master_patches>\shaders\ and must contain one technique with one or more passes
|
||||
|
||||
@@ -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)
|
||||
|
||||
+30
-88
@@ -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=<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
|
||||
|
||||
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);
|
||||
|
||||
@@ -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=<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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<float>(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<DWORD>(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;
|
||||
|
||||
Reference in New Issue
Block a user