From 220c30a788af679f0893360968c18f85025fa9c4 Mon Sep 17 00:00:00 2001 From: Martin Janiczek Date: Tue, 18 Oct 2022 15:44:03 +0200 Subject: [PATCH] Implement LoadGameHook (LoopFlag) --- CMakeLists.txt | 2 ++ src/automap.cc | 5 +++++ src/character_editor.cc | 14 +++++++++++- src/combat.cc | 21 +++++++++++++++--- src/game.cc | 5 +++++ src/game_dialog.cc | 9 ++++++++ src/input.cc | 22 +++++++++++-------- src/inventory.cc | 24 +++++++++++++++++++++ src/loadsave.cc | 33 ++++++++++++++++++++++++++-- src/loop.cc | 45 ++++++++++++++++++++++++++++++++++++++ src/loop.h | 48 +++++++++++++++++++++++++++++++++++++++++ src/main.cc | 24 ++++++++++++++++++++- src/main.h | 7 ++++++ src/options.cc | 23 ++++++++++++++------ src/pipboy.cc | 5 +++++ src/scripts.cc | 3 +++ src/skilldex.cc | 14 +++++++++++- src/window_manager.cc | 2 +- src/worldmap.cc | 5 +++++ 19 files changed, 286 insertions(+), 25 deletions(-) create mode 100644 src/loop.cc create mode 100644 src/loop.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3db0b41..05cbed9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,6 +144,8 @@ target_sources(${EXECUTABLE_NAME} PUBLIC "src/lips.h" "src/loadsave.cc" "src/loadsave.h" + "src/loop.cc" + "src/loop.h" "src/main.cc" "src/main.h" "src/map_defs.h" diff --git a/src/automap.cc b/src/automap.cc index 5d5e44c..c195816 100644 --- a/src/automap.cc +++ b/src/automap.cc @@ -18,6 +18,7 @@ #include "input.h" #include "item.h" #include "kb.h" +#include "loop.h" #include "map.h" #include "memory.h" #include "object.h" @@ -395,6 +396,8 @@ void automapShow(bool isInGame, bool isUsingScanner) bool isoWasEnabled = isoDisable(); gameMouseSetCursor(MOUSE_CURSOR_ARROW); + loopSetFlag(LoopFlag::AUTOMAP); + bool done = false; while (!done) { sharedFpsLimiter.mark(); @@ -488,6 +491,8 @@ void automapShow(bool isInGame, bool isUsingScanner) isoEnable(); } + loopClearFlag(LoopFlag::AUTOMAP); + windowDestroy(window); fontSetCurrent(oldFont); } diff --git a/src/character_editor.cc b/src/character_editor.cc index eaac82f..4666e2e 100644 --- a/src/character_editor.cc +++ b/src/character_editor.cc @@ -25,6 +25,7 @@ #include "interface.h" #include "item.h" #include "kb.h" +#include "loop.h" #include "map.h" #include "memory.h" #include "message.h" @@ -787,8 +788,19 @@ struct CustomKarmaFolderDescription { static std::vector gCustomKarmaFolderDescriptions; static std::vector gCustomTownReputationEntries; +int characterEditorShowInner(bool isCreationMode); + +// Wrapper for editor_design_, setting LoopFlag::CHARSCREEN +// (see sfall: CharacterHook) +int characterEditorShow(bool isCreationMode) { + loopSetFlag(LoopFlag::CHARSCREEN); + int result = characterEditorShowInner(isCreationMode); + loopClearFlag(LoopFlag::CHARSCREEN); + return result; +} + // 0x431DF8 -int characterEditorShow(bool isCreationMode) +int characterEditorShowInner(bool isCreationMode) { char* messageListItemText; char line1[128]; diff --git a/src/combat.cc b/src/combat.cc index 071ac85..4a9599e 100644 --- a/src/combat.cc +++ b/src/combat.cc @@ -23,6 +23,7 @@ #include "item.h" #include "kb.h" #include "loadsave.h" +#include "loop.h" #include "map.h" #include "memory.h" #include "message.h" @@ -102,7 +103,8 @@ static int _compare_faster(const void* a1, const void* a2); static void _combat_sequence_init(Object* a1, Object* a2); static void _combat_sequence(); static void combatAttemptEnd(); -static int _combat_input(); +static int combatInput(); +static int combatInputInner(); static void _combat_set_move_all(); static int _combat_turn(Object* a1, bool a2); static bool _combat_should_end(); @@ -3125,8 +3127,17 @@ void _combat_turn_run() } } +// Wrapper for combatInput, setting LoopFlag::COMBAT_PLAYER_TURN +// (see sfall: PlayerCombatHook) +static int combatInput() { + loopSetFlag(LoopFlag::COMBAT_PLAYER_TURN); + int result = combatInputInner(); + loopClearFlag(LoopFlag::COMBAT_PLAYER_TURN); + return result; +} + // 0x4227F4 -static int _combat_input() +static int combatInputInner() { while ((gCombatState & COMBAT_STATE_0x02) != 0) { sharedFpsLimiter.mark(); @@ -3271,7 +3282,7 @@ static int _combat_turn(Object* a1, bool a2) _combat_outline_on(); } - if (_combat_input() == -1) { + if (combatInput() == -1) { gameUiDisable(1); gameMouseSetCursor(MOUSE_CURSOR_WAIT_WATCH); a1->data.critter.combat.damageLastTurn = 0; @@ -3366,6 +3377,8 @@ static bool _combat_should_end() // 0x422D2C void _combat(STRUCT_664980* attack) { + loopSetFlag(LoopFlag::COMBAT); + if (attack == NULL || (attack->attacker == NULL || attack->attacker->elevation == gElevation) || (attack->defender == NULL || attack->defender->elevation == gElevation)) { @@ -3449,6 +3462,8 @@ void _combat(STRUCT_664980* attack) _game_user_wants_to_quit = 0; } } + + loopClearFlag(LoopFlag::COMBAT); } // 0x422EC4 diff --git a/src/game.cc b/src/game.cc index 5ea3043..b78ac44 100644 --- a/src/game.cc +++ b/src/game.cc @@ -39,6 +39,8 @@ #include "item.h" #include "kb.h" #include "loadsave.h" +#include "loop.h" +#include "main.h" #include "map.h" #include "memory.h" #include "mouse.h" @@ -352,6 +354,7 @@ int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int a4 // 0x442B84 void gameReset() { + mainSetIsGameLoaded(false); tileDisable(); paletteReset(); randomReset(); @@ -819,7 +822,9 @@ int gameHandleKey(int eventCode, bool isInCombatMode) break; case KEY_F1: soundPlayFile("ib1p1xx1"); + loopSetFlag(LoopFlag::HELP); showHelp(); + loopClearFlag(LoopFlag::HELP); break; case KEY_F2: gameSoundSetMasterVolume(gameSoundGetMasterVolume() - 2047); diff --git a/src/game_dialog.cc b/src/game_dialog.cc index b14066f..cf0ded1 100644 --- a/src/game_dialog.cc +++ b/src/game_dialog.cc @@ -24,6 +24,7 @@ #include "item.h" #include "kb.h" #include "lips.h" +#include "loop.h" #include "memory.h" #include "mouse.h" #include "object.h" @@ -920,6 +921,8 @@ int _gdialogInitFromScript(int headFid, int reaction) backgroundSoundDelete(); } + loopSetFlag(LoopFlag::DIALOG); + _gdDialogWentOff = true; return 0; @@ -947,6 +950,8 @@ int _gdialogExitFromScript() _tile_scroll_to(gGameDialogOldCenterTile, 2); } + loopClearFlag(LoopFlag::DIALOG); + _gdDestroyHeadWindow(); // CE: Fix Barter button. @@ -1437,6 +1442,8 @@ int gameDialogShowReview() return -1; } + loopSetFlag(LoopFlag::DIALOG_REVIEW); + // probably current top line or something like this, which is used to scroll int v1 = 0; gameDialogReviewWindowUpdate(win, v1); @@ -1474,6 +1481,8 @@ int gameDialogShowReview() sharedFpsLimiter.throttle(); } + loopClearFlag(LoopFlag::DIALOG_REVIEW); + if (gameDialogReviewWindowFree(&win) == -1) { return -1; } diff --git a/src/input.cc b/src/input.cc index 4c97edc..1bda5c7 100644 --- a/src/input.cc +++ b/src/input.cc @@ -8,6 +8,8 @@ #include "dinput.h" #include "draw.h" #include "kb.h" +#include "loop.h" +#include "main.h" #include "memory.h" #include "mouse.h" #include "sfall_config.h" @@ -634,7 +636,7 @@ unsigned int getTicks() return SDL_GetTicks(); } -// Inspired by sfall SpeedPatch.cpp. +// sfall SpeedPatch.cpp // Returns the potentially sped up (multiplied) tick count. unsigned int getMultipliedTicks() { @@ -651,10 +653,15 @@ unsigned int getMultipliedTicks() gLastTickCount = newTickCount; // Multiply the tick count difference by the multiplier - /* TODO janiczek: Original condition was: - if (IsGameLoaded() && enabled && (!(mode = GetLoopFlags()) || mode == LoopFlag::COMBAT || mode == (LoopFlag::COMBAT | LoopFlag::PCOMBAT) || (mode & LoopFlag::WORLDMAP)) && !slideShow) - */ - if (gSpeedPatchEnabled) { + if (mainIsGameLoaded() + && gSpeedPatchEnabled + && !mainIsInEndgameSlideshow() + && (loopIsInWorldMap() + || loopIsInCombatEnemyTurn() + || loopIsInCombatWaitingForPlayerAction() + || loopIsOutsideCombatWaitingForPlayerAction() + ) + ) { elapsed *= gSpeedMulti; elapsed += gTickCountFraction; gTickCountFraction = modff(gTickCountFraction, &gTickCountFraction); @@ -706,10 +713,7 @@ void inputBlockForTocks(unsigned int ms) // 0x4C93E0 unsigned int getTicksSince(unsigned int start) { - // TODO janiczek: this one was supposed to be patched, but the game seems to work better without that. - // We can retry after implementing the big condition, it will likely fix - // all the issues, eg. with inventory animation spinning too fast etc. - unsigned int end = getTicks(); + unsigned int end = getMultipliedTicks(); // NOTE: Uninline. return getTicksBetween(end, start); diff --git a/src/inventory.cc b/src/inventory.cc index e2f4d9e..0c481ce 100644 --- a/src/inventory.cc +++ b/src/inventory.cc @@ -27,6 +27,7 @@ #include "item.h" #include "kb.h" #include "light.h" +#include "loop.h" #include "map.h" #include "message.h" #include "mouse.h" @@ -585,6 +586,9 @@ void inventoryOpen() reg_anim_clear(_inven_dude); inventoryRenderSummary(); _display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_NORMAL); + + loopSetFlag(LoopFlag::INVENTORY); + inventorySetCursor(INVENTORY_WINDOW_CURSOR_HAND); for (;;) { @@ -706,6 +710,8 @@ void inventoryOpen() } } + loopClearFlag(LoopFlag::INVENTORY); + _exit_inventory(isoWasEnabled); // NOTE: Uninline. @@ -2624,6 +2630,9 @@ void inventoryOpenUseItemOn(Object* a1) bool isoWasEnabled = _setup_inventory(INVENTORY_WINDOW_TYPE_USE_ITEM_ON); _display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_USE_ITEM_ON); + + loopSetFlag(LoopFlag::USE_INTERFACE); + inventorySetCursor(INVENTORY_WINDOW_CURSOR_HAND); for (;;) { sharedFpsLimiter.mark(); @@ -2743,6 +2752,8 @@ void inventoryOpenUseItemOn(Object* a1) sharedFpsLimiter.throttle(); } + loopClearFlag(LoopFlag::USE_INTERFACE); + _exit_inventory(isoWasEnabled); // NOTE: Uninline. @@ -4218,6 +4229,9 @@ int inventoryOpenLooting(Object* a1, Object* a2) _display_target_inventory(_target_stack_offset[_target_curr_stack], -1, _target_pud, INVENTORY_WINDOW_TYPE_LOOT); _display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_LOOT); _display_body(a2->fid, INVENTORY_WINDOW_TYPE_LOOT); + + loopSetFlag(LoopFlag::LOOT_INTERFACE); + inventorySetCursor(INVENTORY_WINDOW_CURSOR_HAND); bool isCaughtStealing = false; @@ -4466,6 +4480,8 @@ int inventoryOpenLooting(Object* a1, Object* a2) } } + loopClearFlag(LoopFlag::LOOT_INTERFACE); + _exit_inventory(isoWasEnabled); // NOTE: Uninline. @@ -5024,6 +5040,8 @@ void inventoryOpenTrade(int win, Object* a2, Object* a3, Object* a4, int a5) return; } + loopSetFlag(LoopFlag::BARTER); + Object* armor = critterGetArmor(a2); if (armor != NULL) { itemRemove(a2, armor, 1); @@ -5338,6 +5356,8 @@ void inventoryOpenTrade(int win, Object* a2, Object* a3, Object* a4, int a5) itemAdd(a2, item1, 1); } + loopClearFlag(LoopFlag::BARTER); + _exit_inventory(isoWasEnabled); // NOTE: Uninline. @@ -5725,6 +5745,8 @@ static int inventoryQuantitySelect(int inventoryWindowType, Object* item, int ma // 0x476AB8 static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item) { + loopSetFlag(LoopFlag::COUNTER_WINDOW); + const int oldFont = fontGetCurrent(); fontSetCurrent(103); @@ -5945,6 +5967,8 @@ static int inventoryQuantityWindowFree(int inventoryWindowType) _moveFrmImages[index].unlock(); } + loopClearFlag(LoopFlag::COUNTER_WINDOW); + windowDestroy(_mt_wid); return 0; diff --git a/src/loadsave.cc b/src/loadsave.cc index 2efb329..8d92899 100644 --- a/src/loadsave.cc +++ b/src/loadsave.cc @@ -30,6 +30,8 @@ #include "interface.h" #include "item.h" #include "kb.h" +#include "loop.h" +#include "main.h" #include "map.h" #include "memory.h" #include "message.h" @@ -149,6 +151,8 @@ static int _QuickSnapShot(); static int lsgWindowInit(int windowType); static int lsgWindowFree(int windowType); static int lsgPerformSaveGame(); +int lsgSaveGameInner(int mode); +static int lsgLoadGameInner(int slot); static int lsgLoadGameInSlot(int slot); static int lsgSaveHeaderInSlot(int slot); static int lsgLoadHeaderInSlot(int slot); @@ -326,6 +330,7 @@ static int gLoadSaveWindowOldFont; static FrmImage _loadsaveFrmImages[LOAD_SAVE_FRM_COUNT]; + // 0x47B7E4 void _InitLoadSave() { @@ -346,9 +351,19 @@ void _ResetLoadSave() _MapDirErase(PROTO_DIR_NAME "\\" ITEMS_DIR_NAME "\\", PROTO_FILE_EXT); } +// Wrapper for SaveGame, setting LoopFlag::SAVEGAME +// (see sfall: SaveGame_hook) +int lsgSaveGame(int mode) +{ + loopSetFlag(LoopFlag::SAVEGAME); + int result = lsgSaveGameInner(mode); + loopClearFlag(LoopFlag::SAVEGAME); + return result; +} + // SaveGame // 0x47B88C -int lsgSaveGame(int mode) +int lsgSaveGameInner(int mode) { MessageListItem messageListItem; @@ -850,9 +865,23 @@ static int _QuickSnapShot() return 1; } +// Wrapper for LoadGame, setting the main::isGameLoaded flag if successful +// (see sfall: LoadGame_hook and LoadGame_After) +int lsgLoadGame(int mode) { + loopSetFlag(LoopFlag::LOADGAME); + int result = lsgLoadGameInner(mode); + loopClearFlag(LoopFlag::LOADGAME); + + if (result == 1) { + mainSetIsGameLoaded(true); + } + + return result; +} + // LoadGame // 0x47C640 -int lsgLoadGame(int mode) +int lsgLoadGameInner(int mode) { MessageListItem messageListItem; diff --git a/src/loop.cc b/src/loop.cc new file mode 100644 index 0000000..3b60e09 --- /dev/null +++ b/src/loop.cc @@ -0,0 +1,45 @@ +#include "loop.h" + +namespace fallout { + +static uint32_t loopFlags = 0; + +// low-level API + +uint32_t loopCurrentFlags() { + return loopFlags; +} + +bool loopGetFlag(LoopFlag flag) { + return loopFlags & flag; +} + +void loopSetFlag(LoopFlag flag) { + loopFlags |= flag; +} + +void loopClearFlag(LoopFlag flag) { + loopFlags &= ~flag; +} + +// high-level helpers + +bool loopIsInWorldMap() { + return loopFlags & LoopFlag::WORLDMAP; +} + +bool loopIsInCombatEnemyTurn() { + return loopFlags == LoopFlag::COMBAT; +} + +// with no menus open +bool loopIsInCombatWaitingForPlayerAction() { + return loopFlags == (LoopFlag::COMBAT | LoopFlag::COMBAT_PLAYER_TURN); +} + +// with no menus open +bool loopIsOutsideCombatWaitingForPlayerAction() { + return !loopFlags; +} + +} // namespace fallout diff --git a/src/loop.h b/src/loop.h new file mode 100644 index 0000000..bd67df0 --- /dev/null +++ b/src/loop.h @@ -0,0 +1,48 @@ +#ifndef FALLOUT_LOOP_H_ +#define FALLOUT_LOOP_H_ + +#include + +namespace fallout { + +enum LoopFlag : unsigned long { + WORLDMAP = 1 << 0, // 0x1 +// RESERVED = 1 << 1, // 0x2 (unused) + DIALOG = 1 << 2, // 0x4 + ESCMENU = 1 << 3, // 0x8 + SAVEGAME = 1 << 4, // 0x10 + LOADGAME = 1 << 5, // 0x20 + COMBAT = 1 << 6, // 0x40 + OPTIONS = 1 << 7, // 0x80 + HELP = 1 << 8, // 0x100 + CHARSCREEN = 1 << 9, // 0x200 + PIPBOY = 1 << 10, // 0x400 + COMBAT_PLAYER_TURN = 1 << 11, // 0x800 + INVENTORY = 1 << 12, // 0x1000 + AUTOMAP = 1 << 13, // 0x2000 + SKILLDEX = 1 << 14, // 0x4000 + USE_INTERFACE = 1 << 15, // 0x8000 + LOOT_INTERFACE = 1 << 16, // 0x10000 + BARTER = 1 << 17, // 0x20000 +// HERO_WINDOW = 1 << 18, // 0x40000 Hero Appearance mod + DIALOG_REVIEW = 1 << 19, // 0x80000 + COUNTER_WINDOW = 1 << 20, // 0x100000 Counter window for moving multiple items or setting a timer + +// SPECIAL = 1UL << 31 // 0x80000000 Additional special flag for all modes +}; + +// low-level API +uint32_t loopCurrentFlags(); +bool loopGetFlag(LoopFlag flag); +void loopSetFlag(LoopFlag flag); +void loopClearFlag(LoopFlag flag); + +// high-level predicates +bool loopIsInWorldMap(); +bool loopIsInCombatEnemyTurn(); +bool loopIsInCombatWaitingForPlayerAction(); // with no menus open +bool loopIsOutsideCombatWaitingForPlayerAction(); // with no menus open + +} // namespace fallout + +#endif /* FALLOUT_LOOP_H_ */ diff --git a/src/main.cc b/src/main.cc index 027006e..84e996a 100644 --- a/src/main.cc +++ b/src/main.cc @@ -172,6 +172,9 @@ static FrmImage _mainMenuBackgroundFrmImage; static FrmImage _mainMenuButtonNormalFrmImage; static FrmImage _mainMenuButtonPressedFrmImage; +static bool gIsGameLoaded = false; +static bool gIsInEndgameSlideshow = false; + // 0x48099C int falloutMain(int argc, char** argv) { @@ -228,6 +231,8 @@ int falloutMain(int argc, char** argv) _main_load_new(mapNameCopy); free(mapNameCopy); + gIsGameLoaded = true; + mainLoop(); paletteFadeTo(gPaletteWhite); @@ -1021,7 +1026,7 @@ static int mainMenuWindowHandleEvents() mouseShowCursor(); } - unsigned int tick = getTicks(); + unsigned int tick = getMultipliedTicks(); int rc = -1; while (rc == -1) { @@ -1109,4 +1114,21 @@ static void main_menu_play_sound(const char* fileName) soundPlayFile(fileName); } +// True if game was started, false when on the main menu +bool mainIsGameLoaded() { + return gIsGameLoaded; +} + +void mainSetIsGameLoaded(bool isGameLoaded) { + gIsGameLoaded = isGameLoaded; +} + +bool mainIsInEndgameSlideshow() { + return gIsInEndgameSlideshow; +} + +void mainSetIsInEndgameSlideshow(bool isInEndgameSlideshow) { + gIsInEndgameSlideshow = isInEndgameSlideshow; +} + } // namespace fallout diff --git a/src/main.h b/src/main.h index bd63c8e..c113c20 100644 --- a/src/main.h +++ b/src/main.h @@ -5,6 +5,13 @@ namespace fallout { int falloutMain(int argc, char** argv); +// True if game was started, false when on the main menu +bool mainIsGameLoaded(); +void mainSetIsGameLoaded(bool isGameLoaded); + +bool mainIsInEndgameSlideshow(); +void mainSetIsInEndgameSlideshow(bool isInEndgameSlideshow); + } // namespace fallout #endif /* MAIN_H */ diff --git a/src/options.cc b/src/options.cc index 9cb1142..462dbd6 100644 --- a/src/options.cc +++ b/src/options.cc @@ -21,6 +21,7 @@ #include "input.h" #include "kb.h" #include "loadsave.h" +#include "loop.h" #include "memory.h" #include "message.h" #include "mouse.h" @@ -455,14 +456,26 @@ int gPreferencesCombatLooks1; static FrmImage _optionsFrmImages[OPTIONS_WINDOW_FRM_COUNT]; static FrmImage _preferencesFrmImages[PREFERENCES_WINDOW_FRM_COUNT]; +int showOptionsWithInitialKeyCodeInner(int initialKeyCode); + +// _do_options // 0x48FC48 int showOptions() { return showOptionsWithInitialKeyCode(-1); } +// Wrapper for do_optionsFunc_, setting LoopFlag::ESCMENU +// (see sfall: EscMenuHook) +int showOptionsWithInitialKeyCode(int initialKeyCode) { + loopSetFlag(LoopFlag::ESCMENU); + int result = showOptionsWithInitialKeyCodeInner(initialKeyCode); + loopClearFlag(LoopFlag::ESCMENU); + return result; +} + // 0x48FC50 -int showOptionsWithInitialKeyCode(int initialKeyCode) +int showOptionsWithInitialKeyCodeInner(int initialKeyCode) { if (optionsWindowInit() == -1) { debugPrint("\nOPTION MENU: Error loading option dialog data!\n"); @@ -527,7 +540,9 @@ int showOptionsWithInitialKeyCode(int initialKeyCode) } if (showPreferences) { + loopSetFlag(LoopFlag::OPTIONS); _do_prefscreen(); + loopClearFlag(LoopFlag::OPTIONS); } else { switch (keyCode) { case KEY_F12: @@ -2063,10 +2078,4 @@ static void _DoThing(int eventCode) _changed = true; } -// 0x48FC48 -int _do_options() -{ - return showOptionsWithInitialKeyCode(-1); -} - } // namespace fallout diff --git a/src/pipboy.cc b/src/pipboy.cc index b553fdc..df08a31 100644 --- a/src/pipboy.cc +++ b/src/pipboy.cc @@ -22,6 +22,7 @@ #include "input.h" #include "interface.h" #include "kb.h" +#include "loop.h" #include "map.h" #include "memory.h" #include "message.h" @@ -541,6 +542,8 @@ static int pipboyWindowInit(int intent) return -1; } + loopSetFlag(LoopFlag::PIPBOY); + int pipboyWindowX = (screenGetWidth() - PIPBOY_WINDOW_WIDTH) / 2; int pipboyWindowY = (screenGetHeight() - PIPBOY_WINDOW_HEIGHT) / 2; gPipboyWindow = windowCreate(pipboyWindowX, pipboyWindowY, PIPBOY_WINDOW_WIDTH, PIPBOY_WINDOW_HEIGHT, _colorTable[0], WINDOW_FLAG_0x10); @@ -706,6 +709,8 @@ static void pipboyWindowFree() scriptsExecMapUpdateProc(); + loopClearFlag(LoopFlag::PIPBOY); + windowDestroy(gPipboyWindow); messageListFree(&gPipboyMessageList); diff --git a/src/scripts.cc b/src/scripts.cc index d5bf37c..55d6a8e 100644 --- a/src/scripts.cc +++ b/src/scripts.cc @@ -21,6 +21,7 @@ #include "game_mouse.h" #include "game_movie.h" #include "input.h" +#include "main.h" #include "memory.h" #include "message.h" #include "object.h" @@ -1006,7 +1007,9 @@ int scriptsHandleRequests() if ((gScriptsRequests & SCRIPT_REQUEST_ENDGAME) != 0) { gScriptsRequests &= ~SCRIPT_REQUEST_ENDGAME; + mainSetIsInEndgameSlideshow(true); endgamePlaySlideshow(); + mainSetIsInEndgameSlideshow(false); endgamePlayMovie(); } diff --git a/src/skilldex.cc b/src/skilldex.cc index feb32be..160b024 100644 --- a/src/skilldex.cc +++ b/src/skilldex.cc @@ -15,6 +15,7 @@ #include "input.h" #include "interface.h" #include "kb.h" +#include "loop.h" #include "map.h" #include "memory.h" #include "message.h" @@ -105,9 +106,20 @@ static int gSkilldexWindowOldFont; static FrmImage _skilldexFrmImages[SKILLDEX_FRM_COUNT]; +static int skilldexOpenInner(); + +// Wrapper for skilldex_select, setting LoopFlag::SKILLDEX +// (see sfall: SkilldexHook) +int skilldexOpen() { + loopSetFlag(LoopFlag::SKILLDEX); + int rc = skilldexOpenInner(); + loopClearFlag(LoopFlag::SKILLDEX); + return rc; +} + // skilldex_select // 0x4ABFD0 -int skilldexOpen() +int skilldexOpenInner() { if (skilldexWindowInit() == -1) { debugPrint("\n ** Error loading skilldex dialog data! **\n"); diff --git a/src/window_manager.cc b/src/window_manager.cc index 6e13b3e..867c87d 100644 --- a/src/window_manager.cc +++ b/src/window_manager.cc @@ -413,7 +413,7 @@ int windowCreate(int x, int y, int width, int height, int a4, int flags) return index; } -// win_remove +// win_remove, win_delete // 0x4D6468 void windowDestroy(int win) { diff --git a/src/worldmap.cc b/src/worldmap.cc index 481ca00..5da9d9f 100644 --- a/src/worldmap.cc +++ b/src/worldmap.cc @@ -27,6 +27,7 @@ #include "interface.h" #include "item.h" #include "kb.h" +#include "loop.h" #include "memory.h" #include "mouse.h" #include "object.h" @@ -2941,6 +2942,8 @@ static int wmWorldMapFunc(int a1) return -1; } + loopSetFlag(LoopFlag::WORLDMAP); + wmMatchWorldPosToArea(wmGenData.worldPosX, wmGenData.worldPosY, &(wmGenData.currentAreaId)); unsigned int v24 = 0; @@ -4695,6 +4698,8 @@ static int wmInterfaceExit() int i; TileInfo* tile; + loopClearFlag(LoopFlag::WORLDMAP); + tickersRemove(wmMouseBkProc); _backgroundFrmImage.unlock();