From 5e1af6f479588212a2e9d1407f80586659f5a9d4 Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Tue, 22 May 2007 10:31:51 +0000 Subject: Add load/save interface support for Elvira 2 and Waxworks. svn-id: r26909 --- engines/agos/agos.cpp | 1 + engines/agos/agos.h | 21 ++- engines/agos/event.cpp | 2 +- engines/agos/saveload.cpp | 409 +++++++++++++++++++++++++++++++-------------- engines/agos/script_e1.cpp | 12 +- engines/agos/script_e2.cpp | 14 +- engines/agos/script_ww.cpp | 2 +- engines/agos/window.cpp | 4 +- 8 files changed, 316 insertions(+), 149 deletions(-) (limited to 'engines/agos') diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp index b77d1d0b01..1906f49183 100644 --- a/engines/agos/agos.cpp +++ b/engines/agos/agos.cpp @@ -471,6 +471,7 @@ AGOSEngine::AGOSEngine(OSystem *syst) _saveLoadSlot = 0; memset(_saveLoadName, 0, sizeof(_saveLoadName)); + _saveGameNameLen = 0; _saveLoadRowCurPos = 0; _numSaveGameRows = 0; _saveDialogFlag = false; diff --git a/engines/agos/agos.h b/engines/agos/agos.h index 0560afbb3b..db0b2865e9 100644 --- a/engines/agos/agos.h +++ b/engines/agos/agos.h @@ -456,7 +456,7 @@ protected: int16 *_variableArrayPtr; WindowBlock *_dummyWindow; - WindowBlock *_windowArray[8]; + WindowBlock *_windowArray[80]; byte _fcsData1[8]; bool _fcsData2[8]; @@ -523,8 +523,9 @@ protected: Debugger *_debugger; - int _saveLoadRowCurPos; - int _numSaveGameRows; + uint _saveGameNameLen; + uint _saveLoadRowCurPos; + uint _numSaveGameRows; bool _saveDialogFlag; bool _saveOrLoad; bool _saveLoadEdit; @@ -1192,15 +1193,14 @@ protected: void vcStopAnimation(uint file, uint sprite); - void userGame(bool load); void disableFileBoxes(); - int userGameGetKey(bool *b, char *buf); + virtual void listSaveGames(char *dst); + virtual void userGame(bool load); + virtual int userGameGetKey(bool *b, char *buf, uint maxChar); void userGameBackSpace(WindowBlock *window, int x, byte b = 0); - void listSaveGames(char *buf); void fileError(WindowBlock *window, bool save_error); int countSaveGames(); - int displaySaveGameList(int curpos, bool load, char *dst); char *genSaveName(int slot); }; @@ -1264,6 +1264,8 @@ public: void oe1_bitSet(); void oe1_bitTest(); void oe1_zoneDisk(); + void oe1_saveUserGame(); + void oe1_loadUserGame(); void oe1_printStats(); void oe1_stopTune(); void oe1_printPlayerDamage(); @@ -1296,7 +1298,6 @@ public: void oe2_moveDirn(); void oe2_doClass(); void oe2_pObj(); - void oe2_loadGame(); void oe2_drawItem(); void oe2_doTable(); void oe2_pauseGame(); @@ -1461,6 +1462,10 @@ protected: virtual void addArrows(WindowBlock *window); virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr); + + virtual void listSaveGames(char *dst); + virtual void userGame(bool load); + virtual int userGameGetKey(bool *b, char *buf, uint maxChar); }; class AGOSEngine_Simon2 : public AGOSEngine_Simon1 { diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp index 0385741187..542cbc5266 100644 --- a/engines/agos/event.cpp +++ b/engines/agos/event.cpp @@ -365,7 +365,7 @@ void AGOSEngine::delay(uint amount) { if (_saveLoadSlot == 0) _saveLoadSlot = 10; - sprintf(_saveLoadName, "Quicksave %d", _saveLoadSlot); + sprintf(_saveLoadName, "Quick %d", _saveLoadSlot); _saveLoadType = (event.kbd.flags == Common::KBD_ALT) ? 1 : 2; // We should only allow a load or save when it was possible in original diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp index fca7fe2c01..9d8737f23e 100644 --- a/engines/agos/saveload.cpp +++ b/engines/agos/saveload.cpp @@ -54,59 +54,6 @@ int AGOSEngine::countSaveGames() { return i; } -int AGOSEngine::displaySaveGameList(int curpos, bool load, char *dst) { - int slot, last_slot; - Common::InSaveFile *in; - - showMessageFormat("\xC"); - - memset(dst, 0, 108); - - slot = curpos; - - while (curpos + 6 > slot) { - if (!(in = _saveFileMan->openForLoading(genSaveName(slot)))) - break; - - in->read(dst, 18); - delete in; - - last_slot = slot; - if (slot < 10) { - showMessageFormat(" "); - } else if (_language == Common::HB_ISR) { - last_slot = (slot % 10) * 10; - last_slot += slot / 10; - } - - if (_language == Common::HB_ISR && !(slot % 10)) - showMessageFormat("0"); - showMessageFormat("%d", last_slot); - showMessageFormat(".%s\n", dst); - dst += 18; - slot++; - } - // while_break - if (!load) { - if (curpos + 6 == slot) - slot++; - else { - if (slot < 10) - showMessageFormat(" "); - showMessageFormat("%d.\n", slot); - } - } else { - if (curpos + 6 == slot) { - if ((in = _saveFileMan->openForLoading(genSaveName(slot)))) { - slot++; - delete in; - } - } - } - - return slot - curpos; -} - char *AGOSEngine::genSaveName(int slot) { static char buf[15]; @@ -197,15 +144,243 @@ void AGOSEngine::quickLoadOrSave() { _saveLoadType = 0; } -void AGOSEngine::listSaveGames(char *buf) { - int i; +void AGOSEngine::listSaveGames(char *dst) { + Common::InSaveFile *in; + uint y, slot; + + const uint8 num = (getGameType() == GType_WW) ? 3 : 4; disableFileBoxes(); - i = displaySaveGameList(_saveLoadRowCurPos, _saveOrLoad, buf); + WindowBlock *window = _windowArray[num]; + window->textRow = 0; + window->textColumn = 0; + window->textColumnOffset = 4; + + windowPutChar(window, 12); + + memset(dst, 0, 200); + + slot = _saveLoadRowCurPos; + for (y = 0; y < 8; y++) { + window->textColumn = 0; + window->textColumnOffset = 4; + window->textLength = 0; + if (in = _saveFileMan->openForLoading(genSaveName(slot++))) { + in->read(dst, 8); + delete in; + + const char *name = dst; + for (; *name; name++) + windowPutChar(window, *name); + + enableBox(200 + y * 3 + 0); + } + dst+= 8; + + window->textColumn = 7; + window->textColumnOffset = 4; + window->textLength = 0; + if (in = _saveFileMan->openForLoading(genSaveName(slot++))) { + in->read(dst, 8); + delete in; + + const char *name = dst; + for (; *name; name++) + windowPutChar(window, *name); + + enableBox(200 + y * 3 + 1); + } + dst+= 8; + + window->textColumn = 15; + window->textColumnOffset = 4; + window->textLength = 0; + if (in = _saveFileMan->openForLoading(genSaveName(slot++))) { + in->read(dst, 8); + delete in; + + const char *name = dst; + for (; *name; name++) + windowPutChar(window, *name); + + enableBox(200 + y * 3 + 2); + } + dst+= 8; + + windowPutChar(window, 13); + } + + window->textRow = 9; + window->textColumn = 0; + window->textColumnOffset = 4; + window->textLength = 0; +} + +void AGOSEngine::userGame(bool load) { + time_t saveTime; + int i, numSaveGames; + WindowBlock *window; + char *name; + bool b; + char buf[200]; + + _saveOrLoad = load; + + saveTime = time(NULL); + + haltAnimation(); + + numSaveGames = countSaveGames(); + _numSaveGameRows = numSaveGames; + _saveLoadRowCurPos = 1; + _saveLoadEdit = false; + + const uint8 num = (getGameType() == GType_WW) ? 3 : 4; + + listSaveGames(buf); + + name = buf + 192; + _saveGameNameLen = 0; + + if (!load) { + for (;;) { + window = _windowArray[num]; + windowPutChar(window, 127); + + _saveLoadEdit = true; + + i = userGameGetKey(&b, buf, 128); + if (b) { + if (i <= 223) { + // TODO; Run the overwrite check script in Waxworks + if (!saveGame(_saveLoadRowCurPos + i, buf + i * 8)) + fileError(_windowArray[num], true); + } + + goto get_out; + } + + userGameBackSpace(_windowArray[num], 8); + if (i == 10 || i == 13) + break; + if (i == 8) { + // do_backspace + if (_saveGameNameLen) { + _saveGameNameLen--; + name[_saveGameNameLen] = 0; + userGameBackSpace(_windowArray[num], 8); + } + } else if (i >= 32 && _saveGameNameLen != 8) { + name[_saveGameNameLen++] = i; + windowPutChar(_windowArray[num], i); + } + } + + if (!saveGame(numSaveGames, buf + 192)) + fileError(_windowArray[num], true); + } else { + i = userGameGetKey(&b, buf, 128); + if (i != 225) { + if (!loadGame(genSaveName(_saveLoadRowCurPos + i))) + fileError(_windowArray[num], false); + } + } + +get_out:; + disableFileBoxes(); + + _gameStoppedClock = time(NULL) - saveTime + _gameStoppedClock; + + restartAnimation(); +} + +int AGOSEngine::userGameGetKey(bool *b, char *buf, uint maxChar) { + HitArea *ha; + *b = true; + + _keyPressed = 0; + + for (;;) { + _lastHitArea = NULL; + _lastHitArea3 = NULL; + + do { + if (_saveLoadEdit && _keyPressed && _keyPressed < maxChar) { + *b = false; + return _keyPressed; + } + delay(10); + } while (_lastHitArea3 == 0); + + ha = _lastHitArea; + if (ha == NULL || ha->id < 200) { + } else if (ha->id == 225) { + return ha->id; + } else if (ha->id == 224) { + _saveGameNameLen = 0; + _saveLoadRowCurPos += 24; + if (_saveLoadRowCurPos >= _numSaveGameRows) + _saveLoadRowCurPos = 1; + + listSaveGames(buf); + } else if (ha->id < 224) { + return ha->id - 200; + } + } +} + +void AGOSEngine_Simon1::listSaveGames(char *dst) { + Common::InSaveFile *in; + uint i, slot, lastSlot; + + disableFileBoxes(); + + showMessageFormat("\xC"); + + memset(dst, 0, 108); + + slot = _saveLoadRowCurPos; + while (_saveLoadRowCurPos + 6 > slot) { + if (!(in = _saveFileMan->openForLoading(genSaveName(slot)))) + break; + + in->read(dst, 8); + delete in; + + lastSlot = slot; + if (slot < 10) { + showMessageFormat(" "); + } + + if (_language == Common::HB_ISR && !(slot % 10)) + showMessageFormat("0"); + showMessageFormat("%d", lastSlot); + showMessageFormat(".%s\n", dst); + dst += 18; + slot++; + } + + if (!_saveOrLoad) { + if (_saveLoadRowCurPos + 6 == slot) + slot++; + else { + if (slot < 10) + showMessageFormat(" "); + showMessageFormat("%d.\n", slot); + } + } else { + if (_saveLoadRowCurPos + 6 == slot) { + if ((in = _saveFileMan->openForLoading(genSaveName(slot)))) { + slot++; + delete in; + } + } + } _saveDialogFlag = true; + i = slot - _saveLoadRowCurPos; if (i != 7) { i++; if (!_saveOrLoad) @@ -221,7 +396,6 @@ void AGOSEngine::listSaveGames(char *buf) { } while (--i); } - const byte hebrewKeyTable[96] = { 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 90, 45, 85, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 83, 83, 90, 61, 85, 63, 35, 89, 80, 65, 66, 87, @@ -231,10 +405,9 @@ const byte hebrewKeyTable[96] = { 123, 124, 125, 126, 127, }; -void AGOSEngine::userGame(bool load) { - time_t save_time; - int number_of_savegames; - int i, name_len, result; +void AGOSEngine_Simon1::userGame(bool load) { + time_t saveTime; + int i, numSaveGames, result; WindowBlock *window; char *name; bool b; @@ -243,27 +416,25 @@ void AGOSEngine::userGame(bool load) { _saveOrLoad = load; - save_time = time(NULL); + saveTime = time(NULL); - number_of_savegames = countSaveGames(); + numSaveGames = countSaveGames(); if (!load) - number_of_savegames++; - number_of_savegames -= 6; - if (number_of_savegames < 0) - number_of_savegames = 0; - number_of_savegames++; - _numSaveGameRows = number_of_savegames; + numSaveGames++; + numSaveGames -= 6; + if (numSaveGames < 0) + numSaveGames = 0; + numSaveGames++; + _numSaveGameRows = numSaveGames; _saveLoadRowCurPos = 1; if (!load) - _saveLoadRowCurPos = number_of_savegames; + _saveLoadRowCurPos = numSaveGames; _saveLoadEdit = false; restart:; - do { - i = userGameGetKey(&b, buf); - } while (!b); + i = userGameGetKey(&b, buf, maxChar); if (i == 205) goto get_out; @@ -283,22 +454,21 @@ restart:; if (_language == Common::HB_ISR) { window->textColumn = 3; window->textColumnOffset = 6; - window->textLength = 3; } else { window->textColumn = 2; window->textColumnOffset = 2; - window->textLength = 3; } + window->textLength = 3; name = buf + i * 18; // now process entire savegame name to get correct x offset for cursor - name_len = 0; - while (name[name_len]) { + _saveGameNameLen = 0; + while (name[_saveGameNameLen]) { if (_language == Common::HB_ISR) { byte width = 6; - if (name[name_len] >= 64 && name[name_len] < 91) - width = _hebrewCharWidths [name[name_len] - 64]; + if (name[_saveGameNameLen] >= 64 && name[_saveGameNameLen] < 91) + width = _hebrewCharWidths [name[_saveGameNameLen] - 64]; window->textLength++; window->textColumnOffset -= width; if (window->textColumnOffset < width) { @@ -308,43 +478,37 @@ restart:; } else { window->textLength++; window->textColumnOffset += 6; - if (name[name_len] == 'i' || name[name_len] == 'l') + if (name[_saveGameNameLen] == 'i' || name[_saveGameNameLen] == 'l') window->textColumnOffset -= 2; if (window->textColumnOffset >= 8) { window->textColumnOffset -= 8; window->textColumn++; } } - name_len++; + _saveGameNameLen++; } - // while_1_end - // do_3_start for (;;) { - windowPutChar(window, 0x7f); + windowPutChar(window, 127); _saveLoadEdit = true; - // do_2 - do { - i = userGameGetKey(&b, buf); - - if (b) { - if (i == 205) - goto get_out; - enableBox(208 + result); - if (_saveLoadEdit) { - userGameBackSpace(_windowArray[5], 8); - } - goto if_1; - } + i = userGameGetKey(&b, buf, maxChar); - // is_not_b - if (!_saveLoadEdit) { - enableBox(208 + result); - goto restart; + if (b) { + if (i == 205) + goto get_out; + enableBox(208 + result); + if (_saveLoadEdit) { + userGameBackSpace(_windowArray[5], 8); } - } while (i >= maxChar || i == 0); + goto if_1; + } + + if (!_saveLoadEdit) { + enableBox(208 + result); + goto restart; + } if (_language == Common::HB_ISR) { if (i >= 128) @@ -353,36 +517,33 @@ restart:; i = hebrewKeyTable[i - 32]; } - // after_do_2 userGameBackSpace(_windowArray[5], 8); if (i == 10 || i == 13) break; if (i == 8) { // do_backspace - if (name_len != 0) { - int x; - byte m; + if (_saveGameNameLen) { + byte m, x; - name_len--; - m = name[name_len]; + _saveGameNameLen--; + m = name[_saveGameNameLen]; if (_language == Common::HB_ISR) x = 8; else - x = (name[name_len] == 'i' || name[name_len] == 'l') ? 1 : 8; + x = (name[_saveGameNameLen] == 'i' || name[_saveGameNameLen] == 'l') ? 1 : 8; - name[name_len] = 0; + name[_saveGameNameLen] = 0; userGameBackSpace(_windowArray[5], x, m); } - } else if (i >= 32 && name_len != 17) { - name[name_len++] = i; + } else if (i >= 32 && _saveGameNameLen != 17) { + name[_saveGameNameLen++] = i; windowPutChar(_windowArray[5], i); } } - // do_save if (!saveGame(_saveLoadRowCurPos + result, buf + result * 18)) fileError(_windowArray[5], true); } else { @@ -393,15 +554,10 @@ restart:; get_out:; disableFileBoxes(); - _gameStoppedClock = time(NULL) - save_time + _gameStoppedClock; - - i = _timer4; - do { - delay(10); - } while (i == _timer4); + _gameStoppedClock = time(NULL) - saveTime + _gameStoppedClock; } -int AGOSEngine::userGameGetKey(bool *b, char *buf) { +int AGOSEngine_Simon1::userGameGetKey(bool *b, char *buf, uint maxChar) { HitArea *ha; *b = true; @@ -416,7 +572,7 @@ int AGOSEngine::userGameGetKey(bool *b, char *buf) { _lastHitArea3 = NULL; do { - if (_saveLoadEdit && _keyPressed != 0) { + if (_saveLoadEdit && _keyPressed && _keyPressed < maxChar) { *b = false; return _keyPressed; } @@ -453,8 +609,15 @@ int AGOSEngine::userGameGetKey(bool *b, char *buf) { } void AGOSEngine::disableFileBoxes() { - for (int i = 208; i != 214; i++) - disableBox(i); + int i; + + if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { + for (i = 208; i != 214; i++) + disableBox(i); + } else { + for (i = 200; i != 224; i++) + disableBox(i); + } } void AGOSEngine::userGameBackSpace(WindowBlock *window, int x, byte b) { diff --git a/engines/agos/script_e1.cpp b/engines/agos/script_e1.cpp index 684518abcf..105f4ba16b 100644 --- a/engines/agos/script_e1.cpp +++ b/engines/agos/script_e1.cpp @@ -368,8 +368,8 @@ void AGOSEngine_Elvira1::setupOpcodes() { OPCODE(o_setAdjNoun), OPCODE(oe1_zoneDisk), /* 268 */ - OPCODE(o_saveUserGame), - OPCODE(o_loadUserGame), + OPCODE(oe1_saveUserGame), + OPCODE(oe1_loadUserGame), OPCODE(oe1_printStats), OPCODE(oe1_stopTune), /* 272 */ @@ -865,6 +865,14 @@ void AGOSEngine_Elvira1::oe1_zoneDisk() { getVarOrWord(); } +void AGOSEngine_Elvira1::oe1_saveUserGame() { + // TODO +} + +void AGOSEngine_Elvira1::oe1_loadUserGame() { + // TODO +} + void AGOSEngine_Elvira1::oe1_printStats() { // 270: print stats WindowBlock *window = _dummyWindow; diff --git a/engines/agos/script_e2.cpp b/engines/agos/script_e2.cpp index d64caef752..bb492a30b9 100644 --- a/engines/agos/script_e2.cpp +++ b/engines/agos/script_e2.cpp @@ -143,7 +143,7 @@ void AGOSEngine_Elvira2::setupOpcodes() { OPCODE(o_comment), /* 88 */ OPCODE(o_invalid), - OPCODE(oe2_loadGame), + OPCODE(oe1_loadGame), OPCODE(o_getParent), OPCODE(o_getNext), /* 92 */ @@ -313,18 +313,6 @@ void AGOSEngine_Elvira2::oe2_pObj() { showMessageFormat("%s\n", (const char *)getStringPtrByID(subObject->objectFlagValue[0])); // Difference } -void AGOSEngine_Elvira2::oe2_loadGame() { - // 89: load game - uint16 stringId = getNextStringID(); - debug(0, "oe2_loadGame: stub (%s)", (const char *)getStringPtrByID(stringId)); - - if (!scumm_stricmp(getFileName(GAME_RESTFILE), (const char *)getStringPtrByID(stringId))) { - loadGame(getFileName(GAME_RESTFILE), true); - } else { - loadGame((const char *)getStringPtrByID(stringId)); - } -} - void AGOSEngine_Elvira2::oe2_drawItem() { // 113: draw item Item *i = getNextItemPtr(); diff --git a/engines/agos/script_ww.cpp b/engines/agos/script_ww.cpp index bd825934c6..5edcf1621d 100644 --- a/engines/agos/script_ww.cpp +++ b/engines/agos/script_ww.cpp @@ -145,7 +145,7 @@ void AGOSEngine_Waxworks::setupOpcodes() { OPCODE(o_comment), /* 88 */ OPCODE(o_invalid), - OPCODE(oe2_loadGame), + OPCODE(oe1_loadGame), OPCODE(o_getParent), OPCODE(o_getNext), /* 92 */ diff --git a/engines/agos/window.cpp b/engines/agos/window.cpp index df60f34107..80f4d588ef 100644 --- a/engines/agos/window.cpp +++ b/engines/agos/window.cpp @@ -172,8 +172,10 @@ void AGOSEngine::restoreWindow(WindowBlock *window) { } restoreBlock(window->y + window->height * 8, (window->x + window->width) * 8, window->y, window->x * 8); - } else { + } else if (getGameType() == GType_SIMON1) { restoreBlock(window->y + window->height * 8 + ((window == _windowArray[2]) ? 1 : 0), (window->x + window->width) * 8, window->y, window->x * 8); + } else { + restoreBlock(window->y + window->height * 8, (window->x + window->width) * 8, window->y, window->x * 8); } _lockWord &= ~0x8000; -- cgit v1.2.3