AGI: Implement messageBox() as inner loop

Also remove _game.keypress, _game.msgBoxTicks
This commit is contained in:
Martin Kiewitz 2016-02-03 01:32:57 +01:00
parent 9fecbe58a1
commit 8271058a45
7 changed files with 60 additions and 45 deletions

View File

@ -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();

View File

@ -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();

View File

@ -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

View File

@ -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;
}

View File

@ -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();

View File

@ -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);
windowTimer = windowTimer * 10; // 1 = 0.5 seconds
_messageBoxCancelled = false;
_vm->inGameTimerResetPassedCycles();
_vm->cycleInnerLoopActive(CYCLE_INNERLOOP_MESSAGEBOX);
do {
if (_vm->getFlag(VM_FLAG_RESTORE_JUST_RAN))
break;
_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;

View File

@ -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();