From 8271058a4598e25096fe305f2c0beb7d2613e178 Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Wed, 3 Feb 2016 01:32:57 +0100 Subject: AGI: Implement messageBox() as inner loop Also remove _game.keypress, _game.msgBoxTicks --- engines/agi/agi.h | 8 +++---- engines/agi/cycle.cpp | 13 ++++++----- engines/agi/global.cpp | 8 ++++++- engines/agi/keyboard.cpp | 9 -------- engines/agi/saveload.cpp | 3 --- engines/agi/text.cpp | 59 ++++++++++++++++++++++++++++++------------------ engines/agi/text.h | 5 ++++ 7 files changed, 60 insertions(+), 45 deletions(-) (limited to 'engines') diff --git a/engines/agi/agi.h b/engines/agi/agi.h index df40344177..4b98a70ec7 100644 --- a/engines/agi/agi.h +++ b/engines/agi/agi.h @@ -389,7 +389,8 @@ enum CycleInnerLoopType { CYCLE_INNERLOOP_INVENTORY = 2, CYCLE_INNERLOOP_MENU_VIA_KEYBOARD = 3, CYCLE_INNERLOOP_MENU_VIA_MOUSE = 4, - CYCLE_INNERLOOP_SYSTEMUI_SELECTSAVEDGAMESLOT = 5 + CYCLE_INNERLOOP_SYSTEMUI_SELECTSAVEDGAMESLOT = 5, + CYCLE_INNERLOOP_MESSAGEBOX = 6 }; enum State { @@ -426,8 +427,6 @@ struct AgiGame { // internal variables int16 horizon; /**< horizon y coordinate */ - int keypress; - bool cycleInnerLoopActive; int16 cycleInnerLoopType; @@ -443,7 +442,6 @@ struct AgiGame { int gameFlags; /**< agi options flags */ // windows - uint32 msgBoxTicks; /**< timed message box tick counter */ AgiBlock block; // graphics & text @@ -945,9 +943,11 @@ public: void redrawScreen(); void inGameTimerReset(uint32 newPlayTime = 0); + void inGameTimerResetPassedCycles(); void inGameTimerPause(); void inGameTimerResume(); uint32 inGameTimerGet(); + uint32 inGameTimerGetPassedCycles(); void inGameTimerUpdate(); diff --git a/engines/agi/cycle.cpp b/engines/agi/cycle.cpp index c9f109b8b3..29c97babbc 100644 --- a/engines/agi/cycle.cpp +++ b/engines/agi/cycle.cpp @@ -237,8 +237,6 @@ int AgiEngine::mainCycle(bool onlyCheckForEvents) { } else { // inner loop active // call specific workers - _game.keypress = 0; - switch (_game.cycleInnerLoopType) { case CYCLE_INNERLOOP_GETSTRING: // loop called from TextMgr::stringEdit() case CYCLE_INNERLOOP_GETNUMBER: @@ -269,6 +267,12 @@ int AgiEngine::mainCycle(bool onlyCheckForEvents) { } break; + case CYCLE_INNERLOOP_MESSAGEBOX: + if (key) { + _text->messageBox_CharPress(key); + } + break; + default: break; } @@ -278,9 +282,6 @@ int AgiEngine::mainCycle(bool onlyCheckForEvents) { if (_menu->delayedExecuteActive()) { _menu->execute(); } - - if (_game.msgBoxTicks > 0) - _game.msgBoxTicks--; } _gfx->updateScreen(); @@ -347,7 +348,7 @@ int AgiEngine::playGame() { inGameTimerUpdate(); if (_passedPlayTimeCycles >= getVar(VM_VAR_TIME_DELAY)) { - _passedPlayTimeCycles = 0; + inGameTimerResetPassedCycles(); interpretCycle(); diff --git a/engines/agi/global.cpp b/engines/agi/global.cpp index b9fcc34ad0..0f10976988 100644 --- a/engines/agi/global.cpp +++ b/engines/agi/global.cpp @@ -137,10 +137,13 @@ void AgiEngine::setVolumeViaSystemSetting() { // In-Game timer, used for timer VM Variables void AgiEngine::inGameTimerReset(uint32 newPlayTime) { - _passedPlayTimeCycles = 0; _lastUsedPlayTimeInCycles = newPlayTime / 50; _lastUsedPlayTimeInSeconds = newPlayTime / 1000; setTotalPlayTime(newPlayTime); + inGameTimerResetPassedCycles(); +} +void AgiEngine::inGameTimerResetPassedCycles() { + _passedPlayTimeCycles = 0; } void AgiEngine::inGameTimerPause() { pauseEngine(true); @@ -151,6 +154,9 @@ void AgiEngine::inGameTimerResume() { uint32 AgiEngine::inGameTimerGet() { return getTotalPlayTime(); } +uint32 AgiEngine::inGameTimerGetPassedCycles() { + return _passedPlayTimeCycles; +} // This is called, when one of the timer variables is read // We calculate the latest variables, according to current official playtime diff --git a/engines/agi/keyboard.cpp b/engines/agi/keyboard.cpp index a22f733cdf..dd850d92f8 100644 --- a/engines/agi/keyboard.cpp +++ b/engines/agi/keyboard.cpp @@ -549,11 +549,6 @@ int AgiEngine::waitKey() { g_system->updateScreen(); } - - // Have to clear it as original did not set this variable, and we do it in doPollKeyboard() - // Fixes bug #2823759 - _game.keypress = 0; - return key; } @@ -570,10 +565,6 @@ int AgiEngine::waitAnyKey() { break; g_system->updateScreen(); } - - // Have to clear it as original did not set this variable, and we do it in doPollKeyboard() - _game.keypress = 0; - return key; } diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp index e04b042bd1..b39f1c7320 100644 --- a/engines/agi/saveload.cpp +++ b/engines/agi/saveload.cpp @@ -465,8 +465,6 @@ int AgiEngine::loadGame(const Common::String &fileName, bool checkId) { // These are never saved _text->promptReset(); - _game.keypress = 0; - in->readSint16BE(); // was _game.inputMode, not needed anymore _game.curLogicNr = in->readSint16BE(); @@ -495,7 +493,6 @@ int AgiEngine::loadGame(const Common::String &fileName, bool checkId) { _text->closeWindow(); - _game.msgBoxTicks = 0; _game.block.active = false; _game.gfxMode = in->readSint16BE(); diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp index cb172ea718..45c5fb05c4 100644 --- a/engines/agi/text.cpp +++ b/engines/agi/text.cpp @@ -71,6 +71,8 @@ TextMgr::TextMgr(AgiEngine *vm, Words *words, GfxMgr *gfx) { _inputString[0] = 0; configureScreen(2); + + _messageBoxCancelled = false; } TextMgr::~TextMgr() { @@ -348,40 +350,53 @@ bool TextMgr::messageBox(const char *textPtr) { _vm->_noSaveLoadAllowed = true; _vm->nonBlockingText_Forget(); - if (_vm->getVar(VM_VAR_WINDOW_RESET) == 0) { - int userKey; - userKey = _vm->waitKey(); - closeWindow(); - - _vm->_noSaveLoadAllowed = false; - if (userKey == AGI_KEY_ENTER) - return true; - return false; - } - // timed window - debugC(3, kDebugLevelText, "f15==0, v21==%d => timed", _vm->getVar(VM_VAR_WINDOW_RESET)); - _vm->_game.msgBoxTicks = _vm->getVar(VM_VAR_WINDOW_RESET) * 10; + uint32 windowTimer = _vm->getVar(VM_VAR_WINDOW_RESET); + debugC(3, kDebugLevelText, "blocking window v21=%d", windowTimer); - do { - if (_vm->getFlag(VM_FLAG_RESTORE_JUST_RAN)) - break; + windowTimer = windowTimer * 10; // 1 = 0.5 seconds + _messageBoxCancelled = false; + _vm->inGameTimerResetPassedCycles(); + _vm->cycleInnerLoopActive(CYCLE_INNERLOOP_MESSAGEBOX); + do { _vm->mainCycle(); - if (_vm->_game.keypress == AGI_KEY_ENTER) { - debugC(4, kDebugLevelText, "KEY_ENTER"); - _vm->setVar(VM_VAR_WINDOW_RESET, 0); - _vm->_game.keypress = 0; - break; + _vm->inGameTimerUpdate(); + + if (windowTimer > 0) { + if (_vm->inGameTimerGetPassedCycles() >= windowTimer) { + // Timer reached, close automatically + _vm->cycleInnerLoopInactive(); + } } - } while (_vm->_game.msgBoxTicks > 0 && !(_vm->shouldQuit() || _vm->_restartGame)); + } while (_vm->cycleInnerLoopIsActive() && !(_vm->shouldQuit() || _vm->_restartGame)); + + _vm->inGameTimerResetPassedCycles(); _vm->setVar(VM_VAR_WINDOW_RESET, 0); + closeWindow(); _vm->_noSaveLoadAllowed = false; + + if (_messageBoxCancelled) + return false; return true; } +void TextMgr::messageBox_CharPress(uint16 newKey) { + switch (newKey) { + case AGI_KEY_ENTER: + _vm->cycleInnerLoopInactive(); // exit messagebox-loop + break; + case AGI_KEY_ESCAPE: + _messageBoxCancelled = true; + _vm->cycleInnerLoopInactive(); // exit messagebox-loop + break; + default: + break; + } +} + void TextMgr::drawMessageBox(const char *textPtr, int16 wantedHeight, int16 wantedWidth, bool wantedForced) { int16 maxWidth = wantedWidth; int16 startingRow = 0; diff --git a/engines/agi/text.h b/engines/agi/text.h index 97f18e7873..1de82e56fa 100644 --- a/engines/agi/text.h +++ b/engines/agi/text.h @@ -130,7 +130,12 @@ public: void printAt(int16 textNr, int16 textPos_Row, int16 textPos_Column, int16 text_Width); void print(int16 textNr); + bool messageBox(const char *textPtr); + void messageBox_CharPress(uint16 newKey); + + bool _messageBoxCancelled; + void drawMessageBox(const char *textPtr, int16 wantedHeight = 0, int16 wantedWidth = 0, bool wantedForced = false); void closeWindow(); -- cgit v1.2.3