diff options
author | Gregory Montoir | 2006-11-10 20:48:52 +0000 |
---|---|---|
committer | Gregory Montoir | 2006-11-10 20:48:52 +0000 |
commit | 4e8d042e5cbe6a01cf0f32c692d99e0644559c1a (patch) | |
tree | c5b2613ef705629f897869da31268fe20cc686f1 | |
parent | 195a46477f1f74caed31519d3c0a723b390c1e32 (diff) | |
download | scummvm-rg350-4e8d042e5cbe6a01cf0f32c692d99e0644559c1a.tar.gz scummvm-rg350-4e8d042e5cbe6a01cf0f32c692d99e0644559c1a.tar.bz2 scummvm-rg350-4e8d042e5cbe6a01cf0f32c692d99e0644559c1a.zip |
new menu code
workaround a possible scripting bug in introduction screen
svn-id: r24668
-rw-r--r-- | engines/touche/opcodes.cpp | 14 | ||||
-rw-r--r-- | engines/touche/resource.cpp | 6 | ||||
-rw-r--r-- | engines/touche/saveload.cpp | 13 | ||||
-rw-r--r-- | engines/touche/staticres.cpp | 12 | ||||
-rw-r--r-- | engines/touche/touche.cpp | 27 | ||||
-rw-r--r-- | engines/touche/touche.h | 42 | ||||
-rw-r--r-- | engines/touche/ui.cpp | 702 |
7 files changed, 404 insertions, 412 deletions
diff --git a/engines/touche/opcodes.cpp b/engines/touche/opcodes.cpp index e1492e4e08..1a287330d6 100644 --- a/engines/touche/opcodes.cpp +++ b/engines/touche/opcodes.cpp @@ -465,6 +465,20 @@ void ToucheEngine::op_initKeyCharTalk() { void ToucheEngine::op_loadRoom() { debugC(9, kDebugOpcodes, "ToucheEngine::op_loadRoom()"); int16 num = _script.readNextWord(); + if (_currentEpisodeNum == 27 && num == 34 && _currentRoomNum != 58) { + // + // Workaround to what appears to be a scripting bug. The script + // 27 triggers a palette fading just after loading the room 34. + // Set flag 115, so that only *one* palette refresh occurs. + // + // [0086] (13) ST[0] = 1 + // [0089] (1E) FLAGS[606] = ST[0] + // [008C] (34) LOAD_ROOM(34) + // [xxxx] ... + // [00B4] (84) START_PALETTE_FADE_IN(20) + // + _flagsTable[115] = 1; + } res_loadRoom(num); } diff --git a/engines/touche/resource.cpp b/engines/touche/resource.cpp index 51018b9b11..d0607acfb3 100644 --- a/engines/touche/resource.cpp +++ b/engines/touche/resource.cpp @@ -98,12 +98,12 @@ void ToucheEngine::res_allocateTables() { error("Unable to allocate memory for backdrop buffer"); } - _menuKitData = (uint8 *)malloc(5040); + _menuKitData = (uint8 *)malloc(42 * 120); if (!_menuKitData) { error("Unable to allocate memory for menu kit data"); } - _convKitData = (uint8 *)malloc(12160); + _convKitData = (uint8 *)malloc(152 * 80); if (!_convKitData) { error("Unable to allocate memory for conv kit data"); } @@ -450,7 +450,7 @@ void ToucheEngine::res_loadSprite(int num, int index) { spr->size = size; spr->ptr = (uint8 *)realloc(spr->ptr, size); if (!spr->ptr) { - error("Unable to reallocate memory for sprite %d", index); + error("Unable to reallocate memory for sprite %d", num); } } for (int i = 0; i < _currentImageHeight; ++i) { diff --git a/engines/touche/saveload.cpp b/engines/touche/saveload.cpp index 4e9e6844c3..1c13bcfe36 100644 --- a/engines/touche/saveload.cpp +++ b/engines/touche/saveload.cpp @@ -267,13 +267,12 @@ void ToucheEngine::loadGameStateData(Common::ReadStream *stream) { clearAreaTable(); _flagsTable[115] = 0; clearRoomArea(); - int16 room_offs_x, room_offs_y; _currentEpisodeNum = stream->readUint16LE(); _newMusicNum = stream->readUint16LE(); _currentRoomNum = stream->readUint16LE(); res_loadRoom(_currentRoomNum); - room_offs_x = stream->readUint16LE(); - room_offs_y = stream->readUint16LE(); + int16 roomOffsX = stream->readUint16LE(); + int16 roomOffsY = stream->readUint16LE(); _disabledInputCounter = stream->readUint16LE(); res_loadProgram(_currentEpisodeNum); setupEpisode(-1); @@ -322,9 +321,9 @@ void ToucheEngine::loadGameStateData(Common::ReadStream *stream) { } _talkListEnd = stream->readUint16LE(); _talkListCurrent = stream->readUint16LE(); - _flagsTable[614] = room_offs_x; - _flagsTable[615] = room_offs_y; - for (uint i = 0; i < 6; ++i) { + _flagsTable[614] = roomOffsX; + _flagsTable[615] = roomOffsY; + for (uint i = 0; i < NUM_SEQUENCES; ++i) { if (_sequenceEntryTable[i].seqNum != -1) { res_loadSequence(_sequenceEntryTable[i].seqNum, i); } @@ -377,7 +376,7 @@ bool ToucheEngine::loadGameState(int num) { if (f) { uint16 version = f->readUint16LE(); if (version < kCurrentGameStateVersion) { - warning("Unsupported gamestate version %d\n", version); + warning("Unsupported gamestate version %d (index %d)", version, num); } else { f->skip(2 + kGameStateDescriptionLen); loadGameStateData(f); diff --git a/engines/touche/staticres.cpp b/engines/touche/staticres.cpp index aaf2763f2f..bd0a246a4d 100644 --- a/engines/touche/staticres.cpp +++ b/engines/touche/staticres.cpp @@ -49,18 +49,6 @@ const uint8 ToucheEngine::_directionsTable[NUM_DIRECTIONS] = { 0x7F, 0x7F, 0x7F, 0x7F, 0x00, 0x00, 0x00 }; -char ToucheEngine::_saveLoadDescriptionsTable[10][33] = { - "[Empty.1.......................]", - "[Empty.2.......................]", - "[Empty.3.......................]", - "[Empty.4.......................]", - "[Empty.5.......................]", - "[Empty.6.......................]", - "[Empty.7.......................]", - "[Empty.8.......................]", - "[Empty.9.......................]" -}; - const uint16 Graphics::_fontOffs[] = { 0x0000, 0x0007, 0x0024, 0x0043, 0x0072, 0x00AD, 0x00E0, 0x0113, 0x0124, 0x0141, 0x015E, 0x0191, 0x01C4, 0x01E3, 0x01F8, 0x0215, 0x0232, 0x0269, 0x0286, 0x02BD, diff --git a/engines/touche/touche.cpp b/engines/touche/touche.cpp index 75497e1755..317f447e0f 100644 --- a/engines/touche/touche.cpp +++ b/engines/touche/touche.cpp @@ -65,7 +65,6 @@ ToucheEngine::ToucheEngine(OSystem *system, Common::Language language) memset(_paletteBuffer, 0, sizeof(_paletteBuffer)); setupOpcodes(); - setupUIRect(); Common::addSpecialDebugLevel(kDebugEngine, "Engine", "Engine debug level"); Common::addSpecialDebugLevel(kDebugGraphics, "Graphics", "Graphics debug level"); @@ -237,11 +236,11 @@ void ToucheEngine::processEvents() { _flagsTable[600] = event.kbd.keycode; if (event.kbd.keycode == 27) { // ESC if (_displayQuitDialog) { - _flagsTable[611] = ui_displayQuitDialog(); + _flagsTable[611] = displayQuitDialog(); } } else if (event.kbd.keycode == 286) { // F5 if (_flagsTable[618] == 0 && !_hideInventoryTexts) { - ui_handleOptions(0); + handleOptions(0); } } else if (event.kbd.keycode == 290) { // F9 _fastWalkMode = true; @@ -261,7 +260,7 @@ void ToucheEngine::processEvents() { if (_talkTextMode == kTalkModeCount) { _talkTextMode = 0; } - ui_displayTextMode(-(92 + _talkTextMode)); + displayTextMode(-(92 + _talkTextMode)); } else if (event.kbd.ascii == ' ') { updateKeyCharTalk(2); } @@ -1366,8 +1365,8 @@ void ToucheEngine::setCursor(int num) { _system->showMouse(true); } -void ToucheEngine::updateCursor(int num) { - debugC(9, kDebugEngine, "ToucheEngine::updateCursor(%d)", num); +void ToucheEngine::setDefaultCursor(int num) { + debugC(9, kDebugEngine, "ToucheEngine::setDefaultCursor(%d)", num); if (_currentCursorObject != 0) { if (_currentCursorObject != 1) { addItemToInventory(num, _currentCursorObject); @@ -1390,13 +1389,13 @@ void ToucheEngine::handleLeftMouseButtonClickOnInventory() { } if (item != 0 && _currentCursorObject != 0) { if (restartKeyCharScriptOnAction(-53, item | 0x1000, 0)) { - updateCursor(_objectDescriptionNum); + setDefaultCursor(_objectDescriptionNum); drawInventory(_objectDescriptionNum, 1); } } else { _inventoryVar1[area - 6 + *_inventoryVar2] = 0; if (_currentCursorObject != 0) { - updateCursor(_objectDescriptionNum); + setDefaultCursor(_objectDescriptionNum); } if (item != 0) { setCursor(item); @@ -1410,7 +1409,7 @@ void ToucheEngine::handleLeftMouseButtonClickOnInventory() { case kInventoryCharacter: _keyCharsTable[_currentKeyCharNum].money += _currentAmountOfMoney; _currentAmountOfMoney = 0; - ui_handleOptions(0); + handleOptions(0); break; case kInventoryMoneyDisplay: setKeyCharMoney(); @@ -1434,7 +1433,7 @@ void ToucheEngine::handleLeftMouseButtonClickOnInventory() { break; case kInventoryMoney: if (_currentAmountOfMoney != 0) { - updateCursor(_objectDescriptionNum); + setDefaultCursor(_objectDescriptionNum); int money = _currentAmountOfMoney; _currentAmountOfMoney = 0; drawAmountOfMoneyInInventory(); @@ -1597,7 +1596,7 @@ void ToucheEngine::handleMouseClickOnRoom(int flag) { if (_inp_leftMouseButtonPressed) { _inp_leftMouseButtonPressed = false; if (_currentCursorObject != 0) { - updateCursor(_currentKeyCharNum); + setDefaultCursor(_currentKeyCharNum); } else { drawInventory(_currentKeyCharNum, 0); if (restartKeyCharScriptOnAction(-49, _programHitBoxTable[i].item, 0) == 0) { @@ -1784,7 +1783,7 @@ int ToucheEngine::handleActionMenuUnderCursor(const int16 *actions, int offs, in addToDirtyRect(_cursorObjectRect); Graphics::fillRect(_offscreenBuffer, 640, cursorPosX + 14, cursorPosY + 24, cursorW - 28, cursorH - 40, 0xF8); - ui_drawActionsPanel(cursorPosX, cursorPosY, cursorW, cursorH); + drawActionsPanel(cursorPosX, cursorPosY, cursorW, cursorH); const char *strData = getString(str); drawGameString(16, 0xF8FF, offs + strW / 2, cursorPosY + 4, strData); @@ -2436,7 +2435,7 @@ void ToucheEngine::drawCharacterConversation() { return; } } - ui_drawConversationPanel(); + drawConversationPanel(); for (int i = 0; i < 4; ++i) { drawString(_offscreenBuffer, 640, 16, 214, 42, 328 + i * 16, _conversationChoicesTable[_drawCharacterConversionRepeatCounter + i].msg); } @@ -2451,7 +2450,7 @@ void ToucheEngine::drawConversationString(int num, uint16 color) { } void ToucheEngine::clearConversationArea() { - ui_drawConversationPanel(); + drawConversationPanel(); updateScreenArea(_offscreenBuffer, 640, 0, 320, 0, 320, 640, 80); _conversationAreaCleared = true; } diff --git a/engines/touche/touche.h b/engines/touche/touche.h index a77489fe8f..3c1b3a6603 100644 --- a/engines/touche/touche.h +++ b/engines/touche/touche.h @@ -329,7 +329,6 @@ public: NUM_ANIMATION_ENTRIES = 4, NUM_INVENTORY_ITEMS = 100, NUM_DIRTY_RECTS = 50, - NUM_GAMESTATE_FILES = 100, NUM_DIRECTIONS = 135 }; @@ -389,7 +388,7 @@ protected: void lockUnlockHitBox(int num, int lock); void drawHitBoxes(); void setCursor(int num); - void updateCursor(int num); + void setDefaultCursor(int num); void handleLeftMouseButtonClickOnInventory(); void handleRightMouseButtonClickOnInventory(); void handleMouseInput(int flag); @@ -584,27 +583,17 @@ protected: void res_loadSpeechSegment(int num); void res_stopSpeech(); - bool ui_processEvents(); - void ui_drawButtonBorders(const Common::Rect *r, int count); - void ui_drawMusicVolumeBar(); - void ui_drawTalkMode(); - void ui_drawAllBorders(); - void ui_drawSaveGamesList(int page); - void ui_drawSaveLoadMenu(int page, SaveLoadMode mode); - int ui_getButtonPressed(const Common::Rect *r, int count) const; - void ui_drawButtonText(const int16 *texts, const Common::Rect *r, int count, bool centerTexts); - void ui_drawArrow(int x, int y, int dx, uint8 color); - void ui_drawOptionsMenu(); - void ui_drawCurrentGameStateDescription(); - int ui_handleSaveLoad(SaveLoadMode mode); - void ui_handleOptions(int forceDisplay); - void ui_drawActionsPanel(int dstX, int dstY, int deltaX, int deltaY); - void ui_drawConversationPanelBorder(int dstY, int srcX, int srcY); - void ui_drawConversationPanel(); - void ui_printStatusString(const char *str); - void ui_clearStatusString(); - int ui_displayQuitDialog(); - void ui_displayTextMode(int str); + void drawButton(void *button); + void redrawMenu(void *menu); + void handleMenuAction(void *menu, int actionId); + void handleOptions(int forceDisplay); + void drawActionsPanel(int dstX, int dstY, int deltaX, int deltaY); + void drawConversationPanelBorder(int dstY, int srcX, int srcY); + void drawConversationPanel(); + void printStatusString(const char *str); + void clearStatusString(); + int displayQuitDialog(); + void displayTextMode(int str); MidiPlayer *_midiPlayer; @@ -621,9 +610,6 @@ protected: bool _displayQuitDialog; int _saveLoadCurrentPage; int _saveLoadCurrentSlot; - bool _saveLoadMarks[NUM_GAMESTATE_FILES]; - char _saveLoadCurrentDescription[33]; - int _saveLoadCurrentDescriptionLen; int _defaultSoundPriority; int _newMusicNum; @@ -751,9 +737,6 @@ protected: static SpriteData _spritesTable[NUM_SPRITES]; static const uint8 _directionsTable[NUM_DIRECTIONS]; - static char _saveLoadDescriptionsTable[10][33]; - - void setupUIRect(); }; /* @@ -766,6 +749,7 @@ protected: 266 : keychar direction override 267 : don't decode picture/sprite images (in load_image_helper) 268 : don't decode picture/sprite images + 269 : disable room background animations 270 : play random sound 290 : process random palette 295 : game cycle counter (incremented) diff --git a/engines/touche/ui.cpp b/engines/touche/ui.cpp index 1732acd24e..9e0e093dc4 100644 --- a/engines/touche/ui.cpp +++ b/engines/touche/ui.cpp @@ -30,386 +30,394 @@ namespace Touche { -static const Common::Rect *buttonsRectTable1; -static const Common::Rect *buttonsRectTable2; - -void ToucheEngine::setupUIRect() { - static const Common::Rect inButtonsRectTable1[15] = { - Common::Rect(108, 120, 444, 135), - Common::Rect(108, 136, 444, 151), - Common::Rect(108, 152, 444, 167), - Common::Rect(108, 168, 444, 183), - Common::Rect(108, 184, 444, 199), - Common::Rect(108, 200, 444, 215), - Common::Rect(108, 216, 444, 231), - Common::Rect(108, 232, 444, 247), - Common::Rect(108, 248, 444, 263), - Common::Rect(108, 264, 444, 279), - Common::Rect(452, 120, 546, 144), - Common::Rect(452, 152, 546, 176), - Common::Rect(452, 216, 546, 240), - Common::Rect(452, 248, 546, 272), - Common::Rect(452, 184, 546, 208) - }; - - static const Common::Rect inButtonsRectTable2[10] = { - Common::Rect(396, 130, 420, 154), - Common::Rect(396, 160, 420, 184), - Common::Rect(396, 190, 420, 214), - Common::Rect(126, 130, 380, 154), - Common::Rect(126, 160, 380, 184), - Common::Rect(126, 190, 380, 214), - Common::Rect(126, 250, 150, 274), - Common::Rect(396, 250, 420, 274), - Common::Rect(154, 256, 392, 268), - Common::Rect(126, 222, 420, 242) - }; - - buttonsRectTable1 = inButtonsRectTable1; - buttonsRectTable2 = inButtonsRectTable2; -} - -static int16 settingsMenuTextsTable[] = { 0, 0, 0, -92, -93, -94, -87, -88, 0, -91 }; - -static const int16 optionsMenuTextsTable[] = { -52, -53, -54, -55, -90 }; - -static const int16 loadMenuTextsTable[] = { 2000, -56, -52, 2001, 0 }; - -static const int16 saveMenuTextsTable[] = { 2000, -56, -53, 2001, 0 }; - -bool ToucheEngine::ui_processEvents() { - bool quit = false; - OSystem::Event event; - while (_system->pollEvent(event)) { - switch (event.type) { - case OSystem::EVENT_QUIT: - quit = true; - break; - case OSystem::EVENT_KEYDOWN: - if (_saveLoadCurrentDescriptionLen != -1) { - if (event.kbd.keycode == 8) { - if (_saveLoadCurrentDescriptionLen > 0) { - --_saveLoadCurrentDescriptionLen; - _saveLoadCurrentDescription[_saveLoadCurrentDescriptionLen] = 0; - } - } else if (isprint((char)event.kbd.ascii)) { - if (_saveLoadCurrentDescriptionLen < 32) { - _saveLoadCurrentDescription[_saveLoadCurrentDescriptionLen] = (char)event.kbd.ascii; - ++_saveLoadCurrentDescriptionLen; - _saveLoadCurrentDescription[_saveLoadCurrentDescriptionLen] = 0; - } - } - } - break; - case OSystem::EVENT_MOUSEMOVE: - _inp_mousePos.x = event.mouse.x; - _inp_mousePos.y = event.mouse.y; - break; - case OSystem::EVENT_LBUTTONDOWN: - _inp_mousePos.x = event.mouse.x; - _inp_mousePos.y = event.mouse.y; - _inp_leftMouseButtonPressed = true; - break; - case OSystem::EVENT_LBUTTONUP: - _inp_mousePos.x = event.mouse.x; - _inp_mousePos.y = event.mouse.y; - break; - default: - break; +enum ActionId { + kActionNone, + + // settings menu + kActionLoadMenu, + kActionSaveMenu, + kActionRestartGame, + kActionPlayGame, + kActionQuitGame, + kActionTextOnly, + kActionVoiceOnly, + kActionTextAndVoice, + kActionLowerVolume, + kActionUpperVolume, + + // saveLoad menu + kActionGameState1, + kActionGameState2, + kActionGameState3, + kActionGameState4, + kActionGameState5, + kActionGameState6, + kActionGameState7, + kActionGameState8, + kActionGameState9, + kActionGameState10, + kActionScrollUpSaves, + kActionScrollDownSaves, + kActionPerformSaveLoad, + kActionCancelSaveLoad +}; + +enum MenuMode { + kMenuSettingsMode = 0, + kMenuLoadStateMode, + kMenuSaveStateMode +}; + +enum ButtonFlags { + kButtonBorder = 1 << 0, + kButtonText = 1 << 1, + kButtonArrow = 1 << 2 +}; + +struct Button { + int x, y; + int w, h; + ActionId action; + int data; + uint8 flags; +}; + +struct MenuData { + MenuMode mode; + Button *buttonsTable; + uint buttonsCount; + bool quit; + bool saveLoadMarks[100]; + char saveLoadDescriptionsTable[100][33]; + + void removeLastCharFromDescription(int slot) { + char *description = saveLoadDescriptionsTable[slot]; + int descriptionLen = strlen(description); + if (descriptionLen > 0) { + --descriptionLen; + description[descriptionLen] = 0; } } - _system->updateScreen(); - _system->delayMillis(50); - return quit; -} -void ToucheEngine::ui_drawButtonBorders(const Common::Rect *r, int count) { - while (count--) { - Graphics::drawRect(_offscreenBuffer, 640, r->left, r->top, r->width(), r->height(), 0xF7, 0xF9); - ++r; + void addCharToDescription(int slot, char chr) { + char *description = saveLoadDescriptionsTable[slot]; + int descriptionLen = strlen(description); + if (descriptionLen < 32 && isprint(chr)) { + description[descriptionLen] = chr; + description[descriptionLen + 1] = 0; + } } -} -void ToucheEngine::ui_drawMusicVolumeBar() { - int volume = _midiPlayer->getVolume() * 232 / 255; - if (volume != 0) { - Graphics::fillRect(_offscreenBuffer, 640, 157, 259, volume, 6, 0xF0); + const Button *findButtonUnderCursor(int cursorX, int cursorY) const { + for (uint i = 0; i < buttonsCount; ++i) { + const Button *button = &buttonsTable[i]; + if (cursorX >= button->x && cursorX < button->x + button->w && + cursorY >= button->y && cursorY < button->y + button->h) { + return button; + } + } + return 0; } - if (volume <= 232) { - Graphics::fillRect(_offscreenBuffer, 640, 157 + volume, 259, 232 - volume, 6, 0xD2); +}; + +static void drawArrow(uint8 *dst, int dstPitch, int x, int y, int delta, uint8 color) { + static const int8 arrowCoordsTable[7][4] = { + { 5, 0, 9, 0 }, + { 5, 0, 5, 4 }, + { -5, 4, 5, 4 }, + { -5, 0, -5, 4 }, + { -9, 0, -5, 0 }, + { -9, 0, 0, -9 }, + { 0, -9, 9, 0 } + }; + for (uint i = 0; i < 7; ++i) { + const int x1 = x + arrowCoordsTable[i][0]; + const int y1 = y + arrowCoordsTable[i][1] * delta; + const int x2 = x + arrowCoordsTable[i][2]; + const int y2 = y + arrowCoordsTable[i][3] * delta; + Graphics::drawLine(dst, dstPitch, x1, y1, x2, y2, color); } } -void ToucheEngine::ui_drawTalkMode() { - settingsMenuTextsTable[0] = 0; - settingsMenuTextsTable[1] = 0; - settingsMenuTextsTable[2] = 0; - settingsMenuTextsTable[_talkTextMode] = -86; -} - -void ToucheEngine::ui_drawAllBorders() { - Graphics::fillRect(_offscreenBuffer, 640, 90, 102, 460, 196, 248); - Graphics::drawRect(_offscreenBuffer, 640, 90, 102, 460, 196, 0xF7, 0xF9); - Graphics::drawRect(_offscreenBuffer, 640, 106, 118, 340, 164, 0xF9, 0xF7); - ui_drawButtonBorders(&buttonsRectTable1[10], 5); -} - -void ToucheEngine::ui_drawSaveGamesList(int page) { - ui_drawAllBorders(); - for (int i = 0; i < 10; ++i) { - const Common::Rect *r = &buttonsRectTable1[i]; - uint8 color = (_saveLoadCurrentSlot == i) ? 0xCB : 0xD9; - char num[10]; - sprintf(num, "%d.", page + i); - Graphics::drawString16(_offscreenBuffer, 640, color, r->left, r->top, num); - Graphics::drawString16(_offscreenBuffer, 640, color, r->left + 30, r->top, _saveLoadDescriptionsTable[i]); +void ToucheEngine::drawButton(void *button) { + Button *b = (Button *)button; + if (b->flags & kButtonBorder) { + Graphics::drawRect(_offscreenBuffer, 640, b->x, b->y, b->w, b->h, 0xF7, 0xF9); } -} - -void ToucheEngine::ui_drawCurrentGameStateDescription() { - const Common::Rect *r = &buttonsRectTable1[_saveLoadCurrentSlot % 10]; - Graphics::fillRect(_offscreenBuffer, 640, r->left, r->top, r->width(), r->height(), 0xF8); - - int y = r->top; - int x = r->left; - char num[10]; - sprintf(num, "%d.", _saveLoadCurrentSlot); - Graphics::drawString16(_offscreenBuffer, 640, 0xCB, x, y, num); - x += 30; - Graphics::drawString16(_offscreenBuffer, 640, 0xCB, x, y, _saveLoadCurrentDescription); - x += Graphics::getStringWidth16(_saveLoadCurrentDescription); - Graphics::drawString16(_offscreenBuffer, 640, 0xCB, x, y, "_"); - - updateScreenArea(_offscreenBuffer, 640, r->left, r->top, r->left, r->top, r->width(), r->height()); -} - -void ToucheEngine::ui_drawSaveLoadMenu(int page, SaveLoadMode mode) { - for (int i = 0; i < 10; ++i) { - _saveLoadDescriptionsTable[i][0] = 0; - const int gameState = page + i; - if (_saveLoadMarks[gameState]) { - readGameStateDescription(gameState, _saveLoadDescriptionsTable[i], 32); + if (b->flags & kButtonText) { + if (b->data != 0) { + const char *str = getString(b->data); + const int w = getStringWidth(16, b->data); + const int h = 16; + const int x = b->x + (b->w - w) / 2; + const int y = b->y + (b->h - h) / 2; + Graphics::drawString16(_offscreenBuffer, 640, 0xFF, x, y, str); } } - ui_drawSaveGamesList(page); - switch (mode) { - case kLoadGameState: - ui_drawButtonText(loadMenuTextsTable, &buttonsRectTable1[10], 5, true); - break; - case kSaveGameState: - ui_drawButtonText(saveMenuTextsTable, &buttonsRectTable1[10], 5, true); - break; + if (b->flags & kButtonArrow) { + int dx = 0; + int dy = 0; + switch (b->data) { + case 2000: // up arrow + dx = 1; + dy = 2; + break; + case 2001: // down arrow + dx = -1; + dy = -2; + break; + } + const int x = b->x + b->w / 2; + const int y = b->y + b->h / 2; + drawArrow(_offscreenBuffer, 640, x, y + dy + 1, dx, 0xD2); + drawArrow(_offscreenBuffer, 640, x, y + dy, dx, 0xFF); } - updateScreenArea(_offscreenBuffer, 640, 90, 102, 90, 102, 460, 196); } -int ToucheEngine::ui_getButtonPressed(const Common::Rect *r, int count) const { - for (int i = 0; i < count; ++i) { - if (r[i].contains(_inp_mousePos)) { - return i; - } +static void drawVolumeSlideBar(uint8 *dst, int dstPitch, int volume) { + const int w = volume * 232 / 255; + if (w > 0) { + Graphics::fillRect(dst, dstPitch, 157, 259, w, 6, 0xF0); + } + if (w < 232) { + Graphics::fillRect(dst, dstPitch, 157 + w, 259, 232 - w, 6, 0xD2); } - return -1; } -void ToucheEngine::ui_drawButtonText(const int16 *texts, const Common::Rect *r, int count, bool centerTexts) { - for (int i = 0; i < count; ++i, ++texts, ++r) { - int x, y; - if (*texts < 2000) { - const char *str = getString(*texts); - x = r->left; - y = r->top; - if (centerTexts) { - const int w = getStringWidth(16, *texts); - x += (r->width() - w) / 2; - y += (r->height() - 16) / 2; - } - Graphics::drawString16(_offscreenBuffer, 640, 0xFF, x, y, str); - } else { - x = r->left + r->width() / 2; - y = r->top + r->height() / 2; - int dx, dy; - switch (*texts) { - case 2000: // up arrow - dx = 1; - dy = 2; - break; - case 2001: // down arrow - dx = -1; - dy = -2; - break; - } - ui_drawArrow(x, y + dy + 1, dx, 0xD2); - ui_drawArrow(x, y + dy, dx, 0xFF); +static void drawSaveGameStateDescriptions(uint8 *dst, int dstPitch, MenuData *menuData, int currentPage, int currentSlot) { + for (int i = 0, slot = currentPage * 10; i < 10; ++i, ++slot) { + const Button *b = &menuData->buttonsTable[i]; + const uint8 color = (slot == currentSlot) ? 0xCB : 0xD9; + char buf[64]; + sprintf(buf, "%d.", slot); + Graphics::drawString16(dst, dstPitch, color, b->x, b->y, buf); + strcpy(buf, menuData->saveLoadDescriptionsTable[slot]); + if (slot == currentSlot && menuData->mode == kMenuSaveStateMode) { + strcat(buf, "_"); } + Graphics::drawString16(dst, dstPitch, color, b->x + 30, b->y, buf); } } -void ToucheEngine::ui_drawArrow(int x, int y, int dx, uint8 color) { - static const int16 arrowCoordsTable[] = { - 5, 0, 9, 0, - 5, 0, 5, 4, - -5, 4, 5, 4, - -5, 0, -5, 4, - -9, 0, -5, 0, - -9, 0, 0, -9, - 0, -9, 9, 0 +static void setupMenu(MenuMode mode, MenuData *menuData) { + static Button settingsButtonsTable[] = { + { 452, 120, 94, 24, kActionLoadMenu, -52, kButtonBorder | kButtonText }, + { 452, 152, 94, 24, kActionSaveMenu, -53, kButtonBorder | kButtonText }, + { 452, 184, 94, 24, kActionRestartGame, -90, kButtonBorder | kButtonText }, + { 452, 216, 94, 24, kActionPlayGame, -54, kButtonBorder | kButtonText }, + { 452, 248, 94, 24, kActionQuitGame, -55, kButtonBorder | kButtonText }, + { 396, 130, 24, 24, kActionTextOnly, 0, kButtonBorder | kButtonText }, + { 396, 160, 24, 24, kActionVoiceOnly, 0, kButtonBorder | kButtonText }, + { 396, 190, 24, 24, kActionTextAndVoice, 0, kButtonBorder | kButtonText }, + { 126, 130, 254, 24, kActionNone, -92, kButtonBorder | kButtonText }, + { 126, 160, 254, 24, kActionNone, -93, kButtonBorder | kButtonText }, + { 126, 190, 254, 24, kActionNone, -94, kButtonBorder | kButtonText }, + { 126, 222, 294, 20, kActionNone, -91, kButtonBorder | kButtonText }, + { 126, 250, 24, 24, kActionLowerVolume, -87, kButtonBorder | kButtonText }, + { 396, 250, 24, 24, kActionUpperVolume, -88, kButtonBorder | kButtonText }, + { 154, 256, 238, 12, kActionNone, 0, kButtonBorder } + }; + static Button saveLoadButtonsTable[] = { + { 108, 120, 336, 15, kActionGameState1, 0, 0 }, + { 108, 136, 336, 15, kActionGameState2, 0, 0 }, + { 108, 152, 336, 15, kActionGameState3, 0, 0 }, + { 108, 168, 336, 15, kActionGameState4, 0, 0 }, + { 108, 184, 336, 15, kActionGameState5, 0, 0 }, + { 108, 200, 336, 15, kActionGameState6, 0, 0 }, + { 108, 216, 336, 15, kActionGameState7, 0, 0 }, + { 108, 232, 336, 15, kActionGameState8, 0, 0 }, + { 108, 248, 336, 15, kActionGameState9, 0, 0 }, + { 108, 264, 336, 15, kActionGameState10, 0, 0 }, + { 452, 120, 94, 24, kActionScrollUpSaves, 2000, kButtonBorder | kButtonArrow }, + { 452, 152, 94, 24, kActionCancelSaveLoad, -56, kButtonBorder | kButtonText }, + { 452, 216, 94, 24, kActionPerformSaveLoad, 0, kButtonBorder | kButtonText }, + { 452, 248, 94, 24, kActionScrollDownSaves, 2001, kButtonBorder | kButtonArrow } }; - for (uint i = 0; i < ARRAYSIZE(arrowCoordsTable) / 4; ++i) { - const int x1 = x + arrowCoordsTable[i * 4 + 0]; - const int y1 = y + arrowCoordsTable[i * 4 + 1] * dx; - const int x2 = x + arrowCoordsTable[i * 4 + 2]; - const int y2 = y + arrowCoordsTable[i * 4 + 3] * dx; - Graphics::drawLine(_offscreenBuffer, 640, x1, y1, x2, y2, color); + + switch (mode) { + case kMenuSettingsMode: + menuData->buttonsTable = settingsButtonsTable; + menuData->buttonsCount = ARRAYSIZE(settingsButtonsTable); + break; + case kMenuLoadStateMode: + saveLoadButtonsTable[12].data = -52; + menuData->buttonsTable = saveLoadButtonsTable; + menuData->buttonsCount = ARRAYSIZE(saveLoadButtonsTable); + break; + case kMenuSaveStateMode: + saveLoadButtonsTable[12].data = -53; + menuData->buttonsTable = saveLoadButtonsTable; + menuData->buttonsCount = ARRAYSIZE(saveLoadButtonsTable); + break; } } -void ToucheEngine::ui_drawOptionsMenu() { - ui_drawTalkMode(); - ui_drawAllBorders(); - ui_drawButtonText(optionsMenuTextsTable, &buttonsRectTable1[10], 5, true); - ui_drawButtonBorders(buttonsRectTable2, 10); - ui_drawButtonText(settingsMenuTextsTable, buttonsRectTable2, 10, true); - ui_drawMusicVolumeBar(); - updateScreenArea(_offscreenBuffer, 640, 90, 102, 90, 102, 460, 196); +void ToucheEngine::redrawMenu(void *menu) { + MenuData *menuData = (MenuData *)menu; + Graphics::fillRect(_offscreenBuffer, 640, 90, 102, 460, 196, 0xF8); + Graphics::drawRect(_offscreenBuffer, 640, 90, 102, 460, 196, 0xF7, 0xF9); + Graphics::drawRect(_offscreenBuffer, 640, 106, 118, 340, 164, 0xF9, 0xF7); + switch (menuData->mode) { + case kMenuSettingsMode: + drawVolumeSlideBar(_offscreenBuffer, 640, _midiPlayer->getVolume()); + menuData->buttonsTable[5].data = 0; + menuData->buttonsTable[6].data = 0; + menuData->buttonsTable[7].data = 0; + menuData->buttonsTable[5 + _talkTextMode].data = -86; + break; + case kMenuLoadStateMode: + case kMenuSaveStateMode: + drawSaveGameStateDescriptions(_offscreenBuffer, 640, menuData, _saveLoadCurrentPage, _saveLoadCurrentSlot); + break; + } + for (uint i = 0; i < menuData->buttonsCount; ++i) { + drawButton(&menuData->buttonsTable[i]); + } } -int ToucheEngine::ui_handleSaveLoad(SaveLoadMode mode) { - char gameStateFileName[16]; - generateGameStateFileName(999, gameStateFileName, 15, true); - _saveFileMan->listSavefiles(gameStateFileName, _saveLoadMarks, NUM_GAMESTATE_FILES); - int ret = 0; - bool quitMenu = false; - while (!quitMenu) { - _saveLoadCurrentDescription[0] = 0; - _saveLoadCurrentDescriptionLen = 0; - ui_drawSaveLoadMenu(_saveLoadCurrentPage, mode); - int descriptionLen = 0; - int button = -1; - while (button == -1 && !quitMenu) { - button = ui_getButtonPressed(buttonsRectTable1, 15); - if (!_inp_leftMouseButtonPressed) { - button = -1; - } - if (mode == kSaveGameState) { - if (_saveLoadCurrentDescriptionLen != descriptionLen) { - descriptionLen = _saveLoadCurrentDescriptionLen; - ui_drawCurrentGameStateDescription(); - strcpy(_saveLoadDescriptionsTable[_saveLoadCurrentSlot % 10], _saveLoadCurrentDescription); - } - } - quitMenu = ui_processEvents(); +void ToucheEngine::handleMenuAction(void *menu, int actionId) { + MenuData *menuData = (MenuData *)menu; + switch (actionId) { + case kActionLoadMenu: + menuData->mode = kMenuLoadStateMode; + break; + case kActionSaveMenu: + menuData->mode = kMenuSaveStateMode; + break; + case kActionRestartGame: + restart(); + menuData->quit = true; + break; + case kActionPlayGame: + menuData->quit = true; + break; + case kActionQuitGame: + _flagsTable[611] = 1; + menuData->quit = true; + break; + case kActionTextOnly: + _talkTextMode = kTalkModeTextOnly; + break; + case kActionVoiceOnly: + _talkTextMode = kTalkModeVoiceOnly; + break; + case kActionTextAndVoice: + _talkTextMode = kTalkModeVoiceAndText; + break; + case kActionLowerVolume: + _midiPlayer->adjustVolume(-16); + break; + case kActionUpperVolume: + _midiPlayer->adjustVolume(+16); + break; + case kActionScrollUpSaves: + --_saveLoadCurrentPage; + if (_saveLoadCurrentPage < 0) { + _saveLoadCurrentPage = 9; + } + _saveLoadCurrentSlot = _saveLoadCurrentPage * 10 + (_saveLoadCurrentSlot % 10); + break; + case kActionScrollDownSaves: + ++_saveLoadCurrentPage; + if (_saveLoadCurrentPage > 9) { + _saveLoadCurrentPage = 0; } - _inp_leftMouseButtonPressed = false; - switch (button) { - case 10: - _saveLoadCurrentPage -= 10; - if (_saveLoadCurrentPage < 0) { - _saveLoadCurrentPage = 90; + _saveLoadCurrentSlot = _saveLoadCurrentPage * 10 + (_saveLoadCurrentSlot % 10); + break; + case kActionPerformSaveLoad: + if (menuData->mode == kMenuLoadStateMode) { + if (loadGameState(_saveLoadCurrentSlot)) { + menuData->quit = true; } - break; - case 11: - quitMenu = true; - ret = 0; - break; - case 12: - quitMenu = true; - ret = 1; - if (mode == kSaveGameState) { - if (saveGameState(_saveLoadCurrentSlot, _saveLoadDescriptionsTable[_saveLoadCurrentSlot % 10])) { - ret = 2; + } else if (menuData->mode == kMenuSaveStateMode) { + const char *description = menuData->saveLoadDescriptionsTable[_saveLoadCurrentSlot]; + if (strlen(description) > 0) { + if (saveGameState(_saveLoadCurrentSlot, description)) { + menuData->quit = true; } - } else { - if (loadGameState(_saveLoadCurrentSlot)) { - ret = 2; - } - } - break; - case 13: - _saveLoadCurrentPage += 10; - if (_saveLoadCurrentPage > 90) { - _saveLoadCurrentPage = 0; } - break; - default: - if (button >= 0 && button <= 9) { - _saveLoadCurrentSlot = _saveLoadCurrentPage + button; - } - break; } + break; + case kActionCancelSaveLoad: + menuData->mode = kMenuSettingsMode; + break; + default: + if (actionId >= kActionGameState1 && actionId <= kActionGameState10) { + _saveLoadCurrentSlot = _saveLoadCurrentPage * 10 + (actionId - kActionGameState1); + } + break; } - return ret; } -void ToucheEngine::ui_handleOptions(int forceDisplay) { +void ToucheEngine::handleOptions(int forceDisplay) { if (_disabledInputCounter == 0 || forceDisplay != 0) { - _saveLoadCurrentDescriptionLen = -1; - updateCursor(_currentKeyCharNum); - int16 mode = _flagsTable[618]; - _flagsTable[618] = 0; - updateEntireScreen(); - bool quitMenu = false; - while (!quitMenu) { - ui_drawOptionsMenu(); - int button = -1; - while (button == -1 && !quitMenu) { - if (_inp_leftMouseButtonPressed) { - button = ui_getButtonPressed(buttonsRectTable1, 15); - if (button < 10) { - button = ui_getButtonPressed(buttonsRectTable2, 10) + 20; + setDefaultCursor(_currentKeyCharNum); + MenuData menuData; + memset(&menuData, 0, sizeof(MenuData)); + menuData.quit = false; + menuData.mode = kMenuSettingsMode; + int curMode = -1; + while (!menuData.quit) { + if (menuData.mode != curMode) { + setupMenu(menuData.mode, &menuData); + curMode = menuData.mode; + if (menuData.mode == kMenuLoadStateMode || menuData.mode == kMenuSaveStateMode) { + char gameStateFileName[16]; + generateGameStateFileName(999, gameStateFileName, 15, true); + _saveFileMan->listSavefiles(gameStateFileName, menuData.saveLoadMarks, 100); + for (int i = 0; i < 100; ++i) { + menuData.saveLoadDescriptionsTable[i][0] = 0; + if (menuData.saveLoadMarks[i]) { + readGameStateDescription(i, menuData.saveLoadDescriptionsTable[i], 32); + } } } - quitMenu = ui_processEvents(); } - _inp_leftMouseButtonPressed = false; - switch (button) { - case 10: - if (ui_handleSaveLoad(kLoadGameState) == 2) { - quitMenu = true; - } - break; - case 11: - if (ui_handleSaveLoad(kSaveGameState) == 2) { - quitMenu = true; + redrawMenu(&menuData); + OSystem::Event event; + while (_system->pollEvent(event)) { + const Button *button = 0; + switch (event.type) { + case OSystem::EVENT_QUIT: + menuData.quit = true; + break; + case OSystem::EVENT_LBUTTONDOWN: + button = menuData.findButtonUnderCursor(event.mouse.x, event.mouse.y); + if (button) { + handleMenuAction(&menuData, button->action); + } + break; + case OSystem::EVENT_KEYDOWN: + if (menuData.mode == kMenuSaveStateMode) { + if (event.kbd.keycode == 8) { + menuData.removeLastCharFromDescription(_saveLoadCurrentSlot); + } else { + menuData.addCharToDescription(_saveLoadCurrentSlot, (char)event.kbd.ascii); + } + } + break; + case OSystem::EVENT_WHEELUP: + handleMenuAction(&menuData, kActionScrollUpSaves); + break; + case OSystem::EVENT_WHEELDOWN: + handleMenuAction(&menuData, kActionScrollDownSaves); + break; + default: + break; } - break; - case 12: - quitMenu = true; - break; - case 13: - quitMenu = true; - _flagsTable[611] = 1; - break; - case 14: - restart(); - quitMenu = true; - break; - case 20: - _talkTextMode = kTalkModeTextOnly; - break; - case 21: - _talkTextMode = kTalkModeVoiceOnly; - break; - case 22: - _talkTextMode = kTalkModeVoiceAndText; - break; - case 26: - _midiPlayer->adjustVolume(-16); - break; - case 27: - _midiPlayer->adjustVolume(+16); - break; } + updateScreenArea(_offscreenBuffer, 640, 90, 102, 90, 102, 460, 196); + _system->updateScreen(); + _system->delayMillis(50); } _fullRedrawCounter = 2; - _flagsTable[618] = mode; if (_flagsTable[611] != 0) { - _flagsTable[611] = ui_displayQuitDialog(); + _flagsTable[611] = displayQuitDialog(); } } } -void ToucheEngine::ui_drawActionsPanel(int dstX, int dstY, int deltaX, int deltaY) { +void ToucheEngine::drawActionsPanel(int dstX, int dstY, int deltaX, int deltaY) { Graphics::copyRect(_offscreenBuffer, 640, dstX, dstY, _menuKitData, 42, 0, 0, 14, 24, @@ -458,7 +466,7 @@ void ToucheEngine::ui_drawActionsPanel(int dstX, int dstY, int deltaX, int delta } } -void ToucheEngine::ui_drawConversationPanelBorder(int dstY, int srcX, int srcY) { +void ToucheEngine::drawConversationPanelBorder(int dstY, int srcX, int srcY) { int dstX = 24; int w = 48; for (int i = 0; i < 13; ++i) { @@ -470,7 +478,7 @@ void ToucheEngine::ui_drawConversationPanelBorder(int dstY, int srcX, int srcY) } } -void ToucheEngine::ui_drawConversationPanel() { +void ToucheEngine::drawConversationPanel() { Graphics::copyRect(_offscreenBuffer, 640, 0, 320, _convKitData, 152, 0, 0, 72, 80); int dstX = 54; int dstY = 326; @@ -486,38 +494,38 @@ void ToucheEngine::ui_drawConversationPanel() { Graphics::copyRect(_offscreenBuffer, 640, dstX, 320, _convKitData, 152, 120, 0, 7, 80); dstX -= 3; if (_drawCharacterConversionRepeatCounter != 0) { - ui_drawConversationPanelBorder(320, 72, 0); + drawConversationPanelBorder(320, 72, 0); Graphics::copyRect(_offscreenBuffer, 640, 0, 320, _convKitData, 152, 128, 0, 24, 21); Graphics::copyRect(_offscreenBuffer, 640, dstX, 320, _convKitData, 152, 128, 34, 10, 10); } else { - ui_drawConversationPanelBorder(320, 24, 0); + drawConversationPanelBorder(320, 24, 0); } if (_conversationChoicesTable[_drawCharacterConversionRepeatCounter + 4].msg != 0) { - ui_drawConversationPanelBorder(394, 72, 74); + drawConversationPanelBorder(394, 72, 74); Graphics::copyRect(_offscreenBuffer, 640, 0, 379, _convKitData, 152, 128, 59, 24, 21); Graphics::copyRect(_offscreenBuffer, 640, dstX, 394, _convKitData, 152, 128, 46, 10, 6); } else { - ui_drawConversationPanelBorder(394, 24, 74); + drawConversationPanelBorder(394, 24, 74); } } -void ToucheEngine::ui_printStatusString(const char *str) { +void ToucheEngine::printStatusString(const char *str) { Graphics::fillRect(_offscreenBuffer, 640, 0, 0, 640, 16, 0xD7); Graphics::drawRect(_offscreenBuffer, 640, 0, 0, 640, 16, 0xD6, 0xD8); Graphics::drawString16(_offscreenBuffer, 640, 0xFF, 0, 0, str); updateScreenArea(_offscreenBuffer, 640, 0, 0, 0, 0, 640, 16); } -void ToucheEngine::ui_clearStatusString() { +void ToucheEngine::clearStatusString() { Graphics::copyRect(_offscreenBuffer, 640, 0, 0, _backdropBuffer, _currentBitmapWidth, _flagsTable[614], _flagsTable[615], 640, 16); updateScreenArea(_offscreenBuffer, 640, 0, 0, 0, 0, 640, 16); } -int ToucheEngine::ui_displayQuitDialog() { - debug(kDebugUserIntf, "ui_displayQuitDialog()"); - ui_printStatusString(getString(-85)); +int ToucheEngine::displayQuitDialog() { + debug(kDebugUserIntf, "ToucheEngine::displayQuitDialog()"); + printStatusString(getString(-85)); int ret = 0; bool quitLoop = false; while (!quitLoop) { @@ -549,15 +557,15 @@ int ToucheEngine::ui_displayQuitDialog() { } _system->delayMillis(50); } - ui_clearStatusString(); + clearStatusString(); return ret; } -void ToucheEngine::ui_displayTextMode(int str) { - debug(kDebugUserIntf, "ui_displayTextMode(%d)", str); - ui_printStatusString(getString(str)); +void ToucheEngine::displayTextMode(int str) { + debug(kDebugUserIntf, "ToucheEngine::displayTextMode(%d)", str); + printStatusString(getString(str)); _system->delayMillis(1000); - ui_clearStatusString(); + clearStatusString(); } } // namespace Touche |