From a56162c949ae0053acb16ff3f21adabd3068d016 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Tue, 14 May 2024 21:33:11 +0800 Subject: [PATCH] Backported the options for internal debug window --- artifacts/ddraw.ini | 13 +++- sfall/FalloutEngine/FunctionOffsets_def.h | 1 + sfall/FalloutEngine/Functions_def.h | 2 + sfall/Modules/DebugEditor.cpp | 73 +++++++++++++++++++++++ 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index e4237a0c..a98a3b46 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -109,7 +109,7 @@ FadeMultiplier=100 ;Set to 2 to skip correcting the position of entrance markers on town maps ;You can use resized FRMs in 700x682 for town maps in the expanded world map interface ;Requires the hi-res patch and a new WORLDMAP.frm file in art\intrface\ (included in sfall.dat) -;The resolution of the hi-res patch must be set to at least 890x720 +;The screen resolution must be set to at least 890x720 ExpandWorldMap=0 ;Set to 1 to draw a dotted line while traveling on the world map (similar to Fallout 1) @@ -706,7 +706,7 @@ NumbersInDialogue=0 ;Set to 1 to use Fallout's normal text font instead of DOS-like font on the world map WorldMapFontPatch=0 -;Set to 1 to use Fallout's normal text font for death screen subtitles +;Set to 1 to use Fallout's normal text font instead of DOS-like font for death screen subtitles ;Requires changing the color of subtitles in death.pal palette to white color (index 220) to display the text correctly DeathScreenFontPatch=0 @@ -872,6 +872,15 @@ SkipCompatModeCheck=0 ;------- DebugMode=0 +;Changes the font used for debug output in the internal debug window (DebugMode 1 or 3) +;Set to 1 to use Fallout's normal text font instead of DOS-like font +DebugWindowFont=0 + +;Changes the width of the internal debug window (valid range: 300..1920; default is 300) +DebugWindowWidth=300 +;Changes the height of the internal debug window (valid range: 192..1080; default is 192) +DebugWindowHeight=192 + ;Set to 1 to hide error messages in debug output when a null value is passed to the function as an object HideObjIsNullMsg=0 diff --git a/sfall/FalloutEngine/FunctionOffsets_def.h b/sfall/FalloutEngine/FunctionOffsets_def.h index 21946abb..7faa00c1 100644 --- a/sfall/FalloutEngine/FunctionOffsets_def.h +++ b/sfall/FalloutEngine/FunctionOffsets_def.h @@ -728,6 +728,7 @@ FUNC(talk_to_critter_reacts_, 0x447CA0) FUNC(talk_to_translucent_trans_buf_to_buf_, 0x44AC68) FUNC(text_curr_, 0x4D58D4) FUNC(text_font_, 0x4D58DC) +FUNC(text_font_exists_, 0x4D595C) FUNC(text_object_create_, 0x4B036C) FUNC(tile_coord_, 0x4B1674) // eax - tilenum, edx (int*) - x, ebx (int*) - y FUNC(tile_dir_, 0x4B1ABC) diff --git a/sfall/FalloutEngine/Functions_def.h b/sfall/FalloutEngine/Functions_def.h index d01f5984..ec2fbb22 100644 --- a/sfall/FalloutEngine/Functions_def.h +++ b/sfall/FalloutEngine/Functions_def.h @@ -229,7 +229,9 @@ WRAP_WATCOM_FUNC1(void, stat_recalc_derived, fo::GameObject*, critter) WRAP_WATCOM_FUNC3(long, stat_set_bonus, fo::GameObject*, critter, long, statID, long, amount) WRAP_WATCOM_FUNC2(long, stat_level, fo::GameObject*, critter, long, statId) WRAP_WATCOM_FUNC1(void, stat_pc_add_experience, long, amount) // Adds experience points to PC +WRAP_WATCOM_FUNC0(long, text_curr) WRAP_WATCOM_FUNC1(long, text_font, long, fontNum) +WRAP_WATCOM_FUNC2(long, text_font_exists, long, fontNum, DWORD*, fontPtr) WRAP_WATCOM_FUNC2(long, tile_dist, long, scrTile, long, dstTile) WRAP_WATCOM_FUNC2(long, tile_dir, long, scrTile, long, dstTile) WRAP_WATCOM_FUNC2(long, tile_idistance, long, sourceTile, long, targetTile) diff --git a/sfall/Modules/DebugEditor.cpp b/sfall/Modules/DebugEditor.cpp index 93ab09f8..656fec73 100644 --- a/sfall/Modules/DebugEditor.cpp +++ b/sfall/Modules/DebugEditor.cpp @@ -22,6 +22,7 @@ #include "..\ConsoleWindow.h" #include "..\FalloutEngine\Fallout2.h" #include "..\InputFuncs.h" +#include "..\Utils.h" //#include "Graphics.h" #include "LoadGameHook.h" #include "ScriptExtender.h" @@ -434,6 +435,42 @@ static void __declspec(naked) op_debug_msg_hack() { } } +static long debugWndFontOld; +static long debugWndFont = 0; +// Before something is printed in the window: remembers current font, replace it with debugWndFont. +static void __declspec(naked) win_debug_text_height_hook() { + __asm { + call fo::funcoffs::text_curr_; + mov debugWndFontOld, eax; + mov eax, debugWndFont; + call fo::funcoffs::text_font_; + call dword ptr ds:[FO_VAR_text_height]; + retn; + } +} + +// After something is printed in the window: restores current font. +static void __declspec(naked) win_debug_win_draw_hook() { + __asm { + push eax; // winID + mov eax, debugWndFontOld; + call fo::funcoffs::text_font_; + pop eax; + jmp fo::funcoffs::win_draw_; + } +} + +static long debugWndWidth; +static void __declspec(naked) win_debug_pitch_calc_hack() { + static const DWORD win_debug_pitch_calc_hack_back = 0x4DC542; + __asm { + mov eax, debugWndWidth; + imul esi; + mov ebp, eax; + jmp win_debug_pitch_calc_hack_back; + } +} + // Shifts the string one character to the right and inserts a newline control character at the beginning static void MoveDebugString(char* messageAddr) { int i = 0; @@ -471,6 +508,42 @@ static void DebugModePatch() { SafeWrite8(0x4C6EF2, CodeType::JumpShort); SafeWrite16(0x4C7033, 0x9090); MakeCall(0x4DC319, win_debug_hook, 2); + MakeCall(0x4DC32C, win_debug_text_height_hook, 1); + HookCall(0x4DC649, win_debug_win_draw_hook); + + if (IniReader::GetIntDefaultConfig("Debugging", "DebugWindowFont", 0)) { + debugWndFont = 101; + } + + const int defaultWidth = 300; + long wdWidth = clamp(IniReader::GetIntDefaultConfig("Debugging", "DebugWindowWidth", defaultWidth), defaultWidth, 1920); + if (wdWidth != defaultWidth) { + const DWORD dbgWinWidthAddr[] = { + 0x4DC357, 0x4DC3AB, 0x4DC408, 0x4DC476, 0x4DC49C, 0x4DC5A0, 0x4DC5AB + }; + SafeWriteBatch(wdWidth, dbgWinWidthAddr); // width/pitch, was 300 + const DWORD titleFillWidthAddr[] = {0x4DC38A, 0x4DC4FE}; + SafeWriteBatch(wdWidth - 16, titleFillWidthAddr); // header BG fill width, was 284 + const DWORD innerFillWidthAddr[] = {0x4DC420, 0x4DC5B1, 0x4DC5C1}; + SafeWriteBatch(wdWidth - 18, innerFillWidthAddr); // Inner box fill width, was 282 + const DWORD outerFillWidthAddr[] = {0x4DC40D, 0x4DC471, 0x4DC562}; + SafeWriteBatch(wdWidth - 9, outerFillWidthAddr); // Outer box fill width, was 291 + SafeWrite32(0x4DC5A5, wdWidth * 26 + 9); // text shift buffer offset, was 7809 + + debugWndWidth = wdWidth; + MakeJump(0x4DC52E, win_debug_pitch_calc_hack); + } + + const int defaultHeight = 192; + long wdHeight = clamp(IniReader::GetIntDefaultConfig("Debugging", "DebugWindowHeight", defaultHeight), defaultHeight, 1080); + if (wdHeight != defaultHeight) { + SafeWrite32(0x4DC348, wdHeight); // Wnd height, was 192 + SafeWrite32(0x4DC42A, wdHeight - 57); // inner box fill height, was 135 + SafeWrite32(0x4DC461, wdHeight - 47); // Inner box height, was 145 + SafeWrite32(0x4DC4C0, wdHeight - 8); // Close button Y, was 184 + SafeWrite32(0x4DC582, wdHeight - 32); // Text loop max Y, was 160 + SafeWrite32(0x4DC528, wdHeight - 58); // Text shift height, was 134 + } } } else { SafeWrite32(0x4C6D9C, (DWORD)debugGnw);