diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index b143050c..c029eef3 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -390,7 +390,7 @@ AlwaysReloadMsgs=0 PlayIdleAnimOnReload=0 ;Changes the timer (in days) for deleting corpses on a map after you leave (valid range: 0..13) -;The corpses of critters with 'Ages' flag or on maps with 'dead_bodies_age=No' set in maps.txt will not disappear +;The corpses of critters with 'Ages' flag set or on maps with 'dead_bodies_age=No' set in maps.txt will not disappear ;Default is 6. Set to 0 for a 12-hour timer CorpseDeleteTime=6 diff --git a/sfall/DebugEditor.cpp b/sfall/DebugEditor.cpp index bdf487a2..50a7ac43 100644 --- a/sfall/DebugEditor.cpp +++ b/sfall/DebugEditor.cpp @@ -302,8 +302,8 @@ hide: } } -static char* artDbgMsg = "\nERROR: File not found: %s\n"; static void __declspec(naked) art_data_size_hook() { + static char* artDbgMsg = "\nERROR: File not found: %s\n"; __asm { test edi, edi; jz artNotExist; diff --git a/sfall/ExtraSaveSlots.cpp b/sfall/ExtraSaveSlots.cpp index 307a8a5c..8aadd02f 100644 --- a/sfall/ExtraSaveSlots.cpp +++ b/sfall/ExtraSaveSlots.cpp @@ -23,7 +23,6 @@ #include "ExtraSaveSlots.h" -//extern DWORD LSPageOffset = 0; int LSButtDN = 0; @@ -31,7 +30,6 @@ BYTE* SaveLoadSurface = nullptr; static const char* filename = "%s\\savegame\\slotdat.ini"; -//-------------------------------------- void SavePageOffsets() { char SavePath[MAX_PATH], buffer[6]; @@ -43,18 +41,16 @@ void SavePageOffsets() { WritePrivateProfileStringA("POSITION", "PageOffset", buffer, SavePath); } -//------------------------------------------ static void __declspec(naked) save_page_offsets(void) { __asm { // save last slot position values to file - call SavePageOffsets + call SavePageOffsets; // restore original code - mov eax, dword ptr ds:[_lsgwin] - ret + mov eax, dword ptr ds:[_lsgwin]; + retn; } } -//-------------------------------------- void LoadPageOffsets() { char LoadPath[MAX_PATH]; @@ -70,18 +66,16 @@ void LoadPageOffsets() { } } -//------------------------------------------ static void __declspec(naked) load_page_offsets(void) { __asm { // load last slot position values from file - call LoadPageOffsets + call LoadPageOffsets; // restore original code - mov edx, 0x50A480 // ASCII "SAV" - ret + mov edx, 0x50A480; // ASCII "SAV" + retn; } } -//------------------------------------------ static void CreateButtons() { DWORD winRef = *ptr_lsgwin; @@ -100,13 +94,11 @@ static void CreateButtons() { static void __declspec(naked) create_page_buttons(void) { __asm { call CreateButtons; - // restore original code - mov eax, 0x65; - ret; + mov eax, 0x65; // restore original code + retn; } } -//------------------------------------------------------ void SetPageNum() { DWORD winRef = *ptr_lsgwin; // load/save winref if (winRef == 0) { @@ -205,7 +197,6 @@ void SetPageNum() { SaveLoadWin = nullptr; } -//------------------------------------------ static long __fastcall CheckPage(long button) { switch (button) { case 0x14B: // left button @@ -257,11 +248,10 @@ static void __declspec(naked) check_page_buttons(void) { CheckUp: // restore original code cmp eax, 0x148; // up button - ret; + retn; } } -//------------------------------------------ void DrawPageText() { if (*ptr_lsgwin == 0) { return; @@ -334,29 +324,25 @@ void DrawPageText() { SaveLoadWin = nullptr; } -//------------------------------------------ static void __declspec(naked) draw_page_text(void) { __asm { - pushad - call DrawPageText - popad - // restore original code - mov ebp, 0x57 - ret + pushad; + call DrawPageText; + popad; + mov ebp, 0x57; // restore original code + retn; } } -//------------------------------------------ // add page num offset when reading and writing various save data files static void __declspec(naked) AddPageOffset01(void) { __asm { - mov eax, dword ptr ds:[_slot_cursor] // list position 0-9 - add eax, LSPageOffset // add page num offset - ret + mov eax, dword ptr ds:[_slot_cursor]; // list position 0-9 + add eax, LSPageOffset; // add page num offset + retn; } } -//------------------------------------------ // getting info for the 10 currently displayed save slots from save.dats static void __declspec(naked) AddPageOffset02(void) { __asm { @@ -368,20 +354,17 @@ static void __declspec(naked) AddPageOffset02(void) { } } -//------------------------------------------ // printing current 10 slot numbers static void __declspec(naked) AddPageOffset03(void) { __asm { - inc eax - add eax, LSPageOffset // add page num offset - mov bl, byte ptr ss:[esp+0x10] // add 4 bytes - func ret addr - ret + inc eax; + add eax, LSPageOffset; // add page num offset + mov bl, byte ptr ss:[esp + 0x10]; // add 4 bytes - func ret addr + retn; } } -//-------------------------------------------------------------------------- void EnableSuperSaving() { - // save/load button setup func MakeCall(0x47D80D, create_page_buttons); @@ -428,6 +411,7 @@ static void GetSaveFileTime(char* filename, FILETIME* ftSlot) { } static const char* commentFmt = "%02d/%02d/%d - %02d:%02d:%02d"; + static void CreateSaveComment(char* bufstr) { SYSTEMTIME stUTC, stLocal; GetSystemTime(&stUTC); @@ -497,6 +481,31 @@ static void __declspec(naked) SaveGame_hack1() { } } +/////////////////////////////////////////////////////////////////////////////// + +static void __fastcall SetSaveComment(char* comment) { + int i = 0; + const char* mapName = MapGetShortName(*ptr_map_number); + do { + comment[i] = mapName[i]; + } while (++i < 20 && mapName[i]); + comment[i++] = ':'; + comment[i] = '\0'; +} + +static void __declspec(naked) GetComment_hack() { + __asm { + cmp [ecx], 0; + jne notEmpty; + pushadc; + call SetSaveComment; + popadc; +notEmpty: + push 0x47F031; + jmp get_input_str2_; + } +} + void ExtraSaveSlotsInit() { bool extraSaveSlots = (GetConfigInt("Misc", "ExtraSaveSlots", 0) != 0); if (extraSaveSlots) { @@ -524,6 +533,9 @@ void ExtraSaveSlotsInit() { MakeJump(0x47B984, SaveGame_hack0); dlogr(" Done", DL_INIT); } + + // Adds the city name in the description of a save slot + MakeJump(0x47F02C, GetComment_hack); } void ExtraSaveSlotsExit() { diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp index 459a4225..9dbbc05f 100644 --- a/sfall/FalloutEngine.cpp +++ b/sfall/FalloutEngine.cpp @@ -128,6 +128,7 @@ DWORD* ptr_main_death_voiceover_done = reinterpret_cast(_main_death_voi DWORD* ptr_main_window = reinterpret_cast(_main_window); DWORD* ptr_map_elevation = reinterpret_cast(_map_elevation); long** ptr_map_global_vars = reinterpret_cast(_map_global_vars); // array +DWORD* ptr_map_number = reinterpret_cast(_map_number); PathNode** ptr_master_db_handle = reinterpret_cast(_master_db_handle); DWORD* ptr_master_volume = reinterpret_cast(_master_volume); DWORD* ptr_max = reinterpret_cast(_max); @@ -424,6 +425,7 @@ const DWORD gdReviewExit_ = 0x445C18; const DWORD gdReviewInit_ = 0x445938; const DWORD GetSlotList_ = 0x47E5D0; const DWORD get_input_ = 0x4C8B78; +const DWORD get_input_str2_ = 0x47F084; const DWORD get_time_ = 0x4C9370; const DWORD getmsg_ = 0x48504C; // eax - msg file addr, ebx - message ID, edx - int[4] - loads string from MSG file preloaded in memory const DWORD gmouse_3d_get_mode_ = 0x44CB6C; @@ -527,6 +529,7 @@ const DWORD item_w_subtype_ = 0x478280; const DWORD item_w_try_reload_ = 0x478768; const DWORD item_w_unload_ = 0x478F80; const DWORD item_weight_ = 0x477B88; +const DWORD kb_clear_ = 0x4CBDA8; const DWORD light_get_tile_ = 0x47A980; const DWORD ListDPerks_ = 0x43D0BC; const DWORD ListDrvdStats_ = 0x43527C; @@ -548,6 +551,7 @@ const DWORD make_straight_path_ = 0x4163AC; const DWORD make_straight_path_func_ = 0x4163C8; const DWORD map_disable_bk_processes_ = 0x482104; const DWORD map_enable_bk_processes_ = 0x4820C0; +const DWORD map_get_short_name_ = 0x48261C; const DWORD map_load_idx_ = 0x482B34; const DWORD MapDirErase_ = 0x480040; const DWORD mem_free_ = 0x4C5C24; @@ -1489,12 +1493,16 @@ void __fastcall GNWWinRefresh(WINinfo* win, BoundRect* rect, long* buffer) { WRAP_WATCOM_FCALL3(GNW_win_refresh_, win, rect, buffer) } +const char* __stdcall MapGetShortName(long mapID) { + WRAP_WATCOM_CALL1(map_get_short_name_, mapID) +} + void __stdcall MapDirErase(const char* folder, const char* ext) { WRAP_WATCOM_CALL2(MapDirErase_, folder, ext) } -void __stdcall MemFree(void* folder) { - WRAP_WATCOM_CALL1(mem_free_, folder) +void __stdcall MemFree(void* mem) { + WRAP_WATCOM_CALL1(mem_free_, mem) } void __stdcall MouseGetPosition(long* outX, long* outY) { diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h index 61843246..ac678915 100644 --- a/sfall/FalloutEngine.h +++ b/sfall/FalloutEngine.h @@ -423,6 +423,7 @@ extern DWORD* ptr_main_death_voiceover_done; extern DWORD* ptr_main_window; extern DWORD* ptr_map_elevation; extern long** ptr_map_global_vars; // array +extern DWORD* ptr_map_number; extern PathNode** ptr_master_db_handle; extern DWORD* ptr_master_volume; extern DWORD* ptr_max; @@ -703,6 +704,7 @@ extern const DWORD gdReviewExit_; extern const DWORD gdReviewInit_; extern const DWORD GetSlotList_; extern const DWORD get_input_; +extern const DWORD get_input_str2_; extern const DWORD get_time_; extern const DWORD getmsg_; // eax - msg file addr, ebx - message ID, edx - int[4] - loads string from MSG file preloaded in memory extern const DWORD gmouse_3d_get_mode_; @@ -809,6 +811,7 @@ extern const DWORD item_w_subtype_; extern const DWORD item_w_try_reload_; extern const DWORD item_w_unload_; extern const DWORD item_weight_; +extern const DWORD kb_clear_; extern const DWORD light_get_tile_; // aElev, aTilenum extern const DWORD ListDPerks_; extern const DWORD ListDrvdStats_; @@ -833,6 +836,7 @@ extern const DWORD make_straight_path_; extern const DWORD make_straight_path_func_; // (TGameObj *aObj, int aTileFrom, int a3, signed int aTileTo, TGameObj **aObjResult, int a5, int (*a6)(void)) extern const DWORD map_disable_bk_processes_; extern const DWORD map_enable_bk_processes_; +extern const DWORD map_get_short_name_; extern const DWORD map_load_idx_; extern const DWORD MapDirErase_; extern const DWORD mem_free_; @@ -1358,9 +1362,11 @@ FrmFrameData* __fastcall FramePtr(FrmHeaderData* frm, long frame, long direction void __fastcall GNWWinRefresh(WINinfo* win, BoundRect* rect, long* buffer); +const char* __stdcall MapGetShortName(long mapID); + void __stdcall MapDirErase(const char* folder, const char* ext); -void __stdcall MemFree(void* folder); +void __stdcall MemFree(void* mem); void __stdcall MouseGetPosition(long* outX, long* outY); diff --git a/sfall/MiscPatches.cpp b/sfall/MiscPatches.cpp index 6f4743a4..55246b07 100644 --- a/sfall/MiscPatches.cpp +++ b/sfall/MiscPatches.cpp @@ -18,6 +18,7 @@ #include "main.h" #include "FalloutEngine.h" +#include "ScriptExtender.h" #include "MiscPatches.h" @@ -257,6 +258,7 @@ static void __fastcall RemoveAllFloatTextObjects(DWORD tile, DWORD flags) { mov edx, flags; call tile_set_center_; } + displayWinUpdateState = true; } static void __declspec(naked) obj_move_to_tile_hook() { @@ -268,6 +270,14 @@ static void __declspec(naked) obj_move_to_tile_hook() { } } +static void __declspec(naked) map_check_state_hook() { + __asm { + cmp displayWinUpdateState, 0; + je obj_move_to_tile_hook; + jmp tile_set_center_; + } +} + static void AdditionalWeaponAnimsPatch() { if (GetConfigInt("Misc", "AdditionalWeaponAnims", 0)) { dlog("Applying additional weapon animations patch.", DL_INIT); @@ -672,6 +682,7 @@ void MiscPatchesInit() { // and redraw the screen to update black edges of the map (HRP bug) // https://github.com/phobos2077/sfall/issues/282 HookCall(0x48A954, obj_move_to_tile_hook); + HookCall(0x483726, map_check_state_hook); F1EngineBehaviorPatch(); DialogueFix(); diff --git a/sfall/ScriptExtender.cpp b/sfall/ScriptExtender.cpp index 61723486..1b0b410b 100644 --- a/sfall/ScriptExtender.cpp +++ b/sfall/ScriptExtender.cpp @@ -422,7 +422,6 @@ std::tr1::unordered_map selfOverrideMap; typedef std::tr1::unordered_map ExportedVarsMap; static ExportedVarsMap globalExportedVars; -DWORD isGlobalScriptLoading = 0; std::tr1::unordered_map<__int64, int> globalVars; typedef std::tr1::unordered_map<__int64, int>::iterator glob_itr; @@ -431,7 +430,9 @@ typedef std::pair<__int64, int> glob_pair; static void* opcodes[0x300]; DWORD availableGlobalScriptTypes = 0; +DWORD isGlobalScriptLoading = 0; bool isGameLoading; +bool displayWinUpdateState = false; TScript overrideScriptStruct = {0}; @@ -984,13 +985,21 @@ end: } } +/** + Do some cleaning after each combat attack action +*/ +static void __stdcall AfterCombatAttack() { // OnAfterCombatAttack + ResetExplosionSettings(); +} + static void __declspec(naked) MainGameLoopHook() { __asm { - call get_input_; push ecx; + call get_input_; push edx; push eax; call RunGlobalScripts1; + mov displayWinUpdateState, 0; // reset pop eax; pop edx; pop ecx; @@ -1016,7 +1025,7 @@ static void __declspec(naked) AfterCombatAttackHook() { __asm { push ecx; push edx; - call AfterAttackCleanup; + call AfterCombatAttack; pop edx; pop ecx; mov eax, 1; @@ -1416,13 +1425,6 @@ static void ResetStateAfterFrame() { RegAnimCombatCheck(1); } -/** - Do some cleaning after each combat attack action -*/ -void AfterAttackCleanup() { - ResetExplosionSettings(); -} - static void RunGlobalScripts1() { if (idle > -1) Sleep(idle); diff --git a/sfall/ScriptExtender.h b/sfall/ScriptExtender.h index 140c7c59..375b28e2 100644 --- a/sfall/ScriptExtender.h +++ b/sfall/ScriptExtender.h @@ -51,7 +51,6 @@ void LoadGlobalScripts(); void RunGlobalScripts2(); void RunGlobalScripts3(); void __stdcall RunGlobalScriptsAtProc(DWORD procId); -void AfterAttackCleanup(); bool LoadGlobals(HANDLE h); void SaveGlobals(HANDLE h); @@ -95,3 +94,4 @@ void __stdcall RemoveTimerEventScripts(DWORD script); // variables extern DWORD isGlobalScriptLoading; extern DWORD availableGlobalScriptTypes; +extern bool displayWinUpdateState; diff --git a/sfall/ScriptOps/MiscOps.hpp b/sfall/ScriptOps/MiscOps.hpp index c003ec93..5e8f9e8e 100644 --- a/sfall/ScriptOps/MiscOps.hpp +++ b/sfall/ScriptOps/MiscOps.hpp @@ -581,7 +581,7 @@ result: } static DWORD __stdcall GetTickCount2() { - return GetTickCount(); //timeGetTime + return GetTickCount(); } static void __declspec(naked) op_get_uptime() {