diff options
Diffstat (limited to 'engines/touche/ui.cpp')
-rw-r--r-- | engines/touche/ui.cpp | 557 |
1 files changed, 557 insertions, 0 deletions
diff --git a/engines/touche/ui.cpp b/engines/touche/ui.cpp new file mode 100644 index 0000000000..997420345d --- /dev/null +++ b/engines/touche/ui.cpp @@ -0,0 +1,557 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id: $ + * + */ + +#include "common/stdafx.h" +#include "common/system.h" +#include "common/savefile.h" + +#include "touche/graphics.h" +#include "touche/touche.h" + +namespace Touche { + +static const Common::Rect buttonsRectTable1[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 buttonsRectTable2[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) +}; + +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 saveMenuTextsTable[] = { 2000, -56, -52, 2001, 0 }; + +static const int16 loadMenuTextsTable[] = { 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_mouseButtonClicked = true; + break; + case OSystem::EVENT_LBUTTONUP: + _inp_mousePos.x = event.mouse.x; + _inp_mousePos.y = event.mouse.y; + break; + default: + break; + } + } + _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 ToucheEngine::ui_drawMusicVolumeBar() { + int volume = _snd_midiContext.volume * 232 / 256; + if (volume != 0) { + Graphics::fillRect(_offscreenBuffer, 640, 157, 259, volume, 6, 0xF0); + } + if (volume <= 232) { + Graphics::fillRect(_offscreenBuffer, 640, 157 + volume, 259, 232 - volume, 6, 0xD2); + } +} + +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::ui_drawCurrentGameStateDescription() { + const Common::Rect *r = &buttonsRectTable1[_saveLoadCurrentSlot]; + 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, int saveOrLoad) { + for (int i = 0; i < 10; ++i) { + _saveLoadDescriptionsTable[i][0] = 0; + const int gameState = page + i; + if (_saveLoadMarks[gameState]) { + readGameStateDescription(gameState, _saveLoadDescriptionsTable[i], 32); + } + } + ui_drawSaveGamesList(page); + if (saveOrLoad == 0) { + ui_drawButtonText(loadMenuTextsTable, &buttonsRectTable1[10], 5, true); + } else { + ui_drawButtonText(saveMenuTextsTable, &buttonsRectTable1[10], 5, true); + } + 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; + } + } + 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); + } + } +} + +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 + }; + 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); + } +} + +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); +} + +int ToucheEngine::ui_handleSaveLoad(int saveOrLoad) { + 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, saveOrLoad); + int descriptionLen = 0; + int button = -1; + while (button == -1 && !quitMenu) { + button = ui_getButtonPressed(buttonsRectTable1, 15); + if (!_inp_mouseButtonClicked) { + button = -1; + } + if (saveOrLoad == 0) { + _saveLoadCurrentPage = (_saveLoadCurrentSlot / 10) * 10; + if (_saveLoadCurrentDescriptionLen != descriptionLen) { + descriptionLen = _saveLoadCurrentDescriptionLen; + ui_drawCurrentGameStateDescription(); + strcpy(_saveLoadDescriptionsTable[_saveLoadCurrentSlot % 10], _saveLoadCurrentDescription); + } + } + quitMenu = ui_processEvents(); + } + _inp_mouseButtonClicked = false; + switch (button) { + case 10: + _saveLoadCurrentPage -= 10; + if (_saveLoadCurrentPage < 0) { + _saveLoadCurrentPage = 90; + } + break; + case 11: + quitMenu = true; + ret = 0; + break; + case 12: + quitMenu = true; + ret = 1; + if (saveOrLoad == 0) { + if (saveGameState(_saveLoadCurrentSlot, _saveLoadDescriptionsTable[_saveLoadCurrentSlot % 10])) { + ret = 2; + } + } else { + if (loadGameState(_saveLoadCurrentSlot, _saveLoadDescriptionsTable[_saveLoadCurrentSlot % 10])) { + ret = 2; + } + } + break; + case 13: + _saveLoadCurrentPage += 10; + if (_saveLoadCurrentPage > 90) { + _saveLoadCurrentPage = 0; + } + break; + default: + if (button >= 0 && button <= 9) { + _saveLoadCurrentSlot = _saveLoadCurrentPage + button; + } + break; + } + } + return ret; +} + +void ToucheEngine::ui_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_mouseButtonClicked) { + button = ui_getButtonPressed(buttonsRectTable1, 15); + if (button < 10) { + button = ui_getButtonPressed(buttonsRectTable2, 10) + 20; + } + } + quitMenu = ui_processEvents(); + } + _inp_mouseButtonClicked = false; + switch (button) { + case 10: + if (ui_handleSaveLoad(1) == 2) { + quitMenu = true; + } + break; + case 11: + if (ui_handleSaveLoad(0) == 2) { + quitMenu = true; + } + 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: + if (_snd_midiContext.volume > 0) { + _snd_midiContext.volume -= 16; + } + break; + case 27: + if (_snd_midiContext.volume < 256) { + _snd_midiContext.volume += 16; + } + break; + } + } + _fullRedrawCounter = 2; + _flagsTable[618] = mode; + if (_flagsTable[611] != 0) { + _flagsTable[611] = ui_displayQuitDialog(); + } + _snd_midiContext.currentVolume = _snd_midiContext.volume; + } +} + +void ToucheEngine::ui_drawActionsPanel(int dstX, int dstY, int deltaX, int deltaY) { + Graphics::copyRect(_offscreenBuffer, 640, dstX, dstY, + _menuKitData, 42, 0, 0, + 14, 24, + Graphics::kTransparent); + Graphics::copyRect(_offscreenBuffer, 640, deltaX - 14 + dstX, dstY, + _menuKitData, 42, 0, 40, + 14, 24, + Graphics::kTransparent); + Graphics::copyRect(_offscreenBuffer, 640, dstX, deltaY - 16 + dstY, + _menuKitData, 42, 0, 24, + 14, 16, + Graphics::kTransparent); + Graphics::copyRect(_offscreenBuffer, 640, deltaX - 14 + dstX, deltaY - 16 + dstY, + _menuKitData, 42, 0, 64, + 14, 16, + Graphics::kTransparent); + int x1 = deltaX - 28; + int x2 = dstX + 14; + while (x1 > 0) { + int w = (x1 > 14) ? 14 : x1; + Graphics::copyRect(_offscreenBuffer, 640, x2, dstY, + _menuKitData, 42, 0, 80, + w, 24, + Graphics::kTransparent); + Graphics::copyRect(_offscreenBuffer, 640, x2, deltaY - 16 + dstY, + _menuKitData, 42, 0, 104, + w, 16, + Graphics::kTransparent); + x1 -= 14; + x2 += 14; + } + x1 = deltaY - 40; + x2 = dstY + 24; + while (x1 > 0) { + int w = (x1 > 120) ? 120 : x1; + Graphics::copyRect(_offscreenBuffer, 640, dstX, x2, + _menuKitData, 42, 14, 0, + 14, w, + Graphics::kTransparent); + Graphics::copyRect(_offscreenBuffer, 640, deltaX - 14 + dstX, x2, + _menuKitData, 42, 28, 0, + 14, w, + Graphics::kTransparent); + x1 -= 120; + x2 += 120; + } +} + +void ToucheEngine::ui_drawConversationPanelBorder(int dstY, int srcX, int srcY) { + int dstX = 24; + int w = 48; + for (int i = 0; i < 13; ++i) { + if (i == 12) { + w = 34; + } + Graphics::copyRect(_offscreenBuffer, 640, dstX, dstY, _convKitData, 152, srcX, srcY, w, 6); + dstX += w; + } +} + +void ToucheEngine::ui_drawConversationPanel() { + Graphics::copyRect(_offscreenBuffer, 640, 0, 320, _convKitData, 152, 0, 0, 72, 80); + int dstX = 54; + int dstY = 326; + int w = 96; + for (int i = 0; i < 7; ++i) { + if (i == 5) { + w = 50; + } + Graphics::copyRect(_offscreenBuffer, 640, dstX, dstY, _convKitData, 152, 24, 6, w, 68); + dstX += w; + } + --dstX; + Graphics::copyRect(_offscreenBuffer, 640, dstX, 320, _convKitData, 152, 120, 0, 7, 80); + dstX -= 3; + if (_drawCharacterConversionRepeatCounter != 0) { + ui_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); + } + if (_conversationChoicesTable[_drawCharacterConversionRepeatCounter + 4].msg != 0) { + ui_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); + } +} + +void ToucheEngine::ui_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() { + 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 ret = 0; + bool quitLoop = false; + while (!quitLoop) { + OSystem::Event event; + while (_system->pollEvent(event)) { + switch (event.type) { + case OSystem::EVENT_QUIT: + quitLoop = true; + ret = 1; + break; + case OSystem::EVENT_KEYDOWN: + quitLoop = true; + switch (_language) { + case Common::FR_FRA: + if (event.kbd.ascii == 'o' || event.kbd.ascii == 'O') { + ret = 1; + } + break; + default: + if (event.kbd.ascii == 'y' || event.kbd.ascii == 'Y') { + ret = 1; + } + break; + } + break; + default: + break; + } + } + _system->delayMillis(50); + } + ui_clearStatusString(); + return ret; +} + +void ToucheEngine::ui_displayTextMode(int str) { + debug(kDebugUserIntf, "ui_displayTextMode(%d)", str); + ui_printStatusString(getString(str)); + _system->delayMillis(1000); + ui_clearStatusString(); +} + +} // namespace Touche |