diff options
author | Gregory Montoir | 2007-10-29 23:35:50 +0000 |
---|---|---|
committer | Gregory Montoir | 2007-10-29 23:35:50 +0000 |
commit | 6c6e8657b68ebc075871031ee8c662f349c4ab77 (patch) | |
tree | 1e2c691ffe1d142a3e781670ac63a981ebf70114 /engines/igor/menu.cpp | |
parent | caa451f5d2b471fc207739815638056f86fc8dce (diff) | |
download | scummvm-rg350-6c6e8657b68ebc075871031ee8c662f349c4ab77.tar.gz scummvm-rg350-6c6e8657b68ebc075871031ee8c662f349c4ab77.tar.bz2 scummvm-rg350-6c6e8657b68ebc075871031ee8c662f349c4ab77.zip |
added 'igor' engine for the game 'Igor: Objective Uikokahonia'
svn-id: r29318
Diffstat (limited to 'engines/igor/menu.cpp')
-rw-r--r-- | engines/igor/menu.cpp | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/engines/igor/menu.cpp b/engines/igor/menu.cpp new file mode 100644 index 0000000000..abe38d35ea --- /dev/null +++ b/engines/igor/menu.cpp @@ -0,0 +1,346 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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/events.h" +#include "common/system.h" + +#include "igor/igor.h" + +namespace Igor { + +static const struct { + int y; + int h; +} buttonsBarCoords[] = { + { 3, 1 }, + { 1, 1 }, + { 2, 2 }, + { 4, 1 }, + { 5, 10 }, + { 6, 1 }, + { 2, 2 }, + { 7, 1 }, + { 8, 93 }, + { 9, 1 }, + { 2, 2 }, + { 3, 1 } +}; + +static void drawButtonsBar(uint8 *dst, const uint8 *src) { + int y0 = 15; + for (int i = 1; i <= 11; ++i) { + int y2 = y0 + buttonsBarCoords[i].h - 1; + if (y0 > y2) { + continue; + } + for (int y1 = y0; y1 <= y2; ++y1) { + memcpy(dst + (y1 - 15) * 320 + 43, src + (buttonsBarCoords[i].y - 1) * 234, 234); + ++y0; + } + } +} + +static void redrawButton(uint8 *dst, int button, bool highlight) { + const int colorDiff = highlight ? 4 : -4; + for (int y = 0; y <= 11; ++y) { + uint8 *p = dst + (y + 3) * 320 + button * 46 + 43 + 3; + for (int x = 0; x <= 43; ++x) { + p[x] += colorDiff; + } + } +} + +enum { + kPageSave = 0, + kPageLoad, + kPageQuit, + kPageCtrl, + kPagePlay +}; + +struct Page { + const char *captions[2]; + int xPos[2]; + void (IgorEngine::*paintProc)(); + bool (IgorEngine::*handleKeyDownProc)(int key); +}; + +static const Page pages[] = { + { + { "SAVE", "Choose a position to SAVE to" }, + { 53, 75 }, + &IgorEngine::handleOptionsMenu_paintSave, + &IgorEngine::handleOptionsMenu_handleKeyDownSave + }, + { + { "LOAD", "Choose a game to load" }, + { 98, 93 }, + &IgorEngine::handleOptionsMenu_paintLoad, + &IgorEngine::handleOptionsMenu_handleKeyDownLoad + }, + { + { "QUIT", "QUIT" }, + { 146, 146 }, + &IgorEngine::handleOptionsMenu_paintQuit, + &IgorEngine::handleOptionsMenu_handleKeyDownQuit + }, + { + { "CTRL", "Game CONTROLS" }, + { 190, 112 }, + &IgorEngine::handleOptionsMenu_paintCtrl, + &IgorEngine::handleOptionsMenu_handleKeyDownCtrl + }, + { + { "PLAY", 0 }, + { 237, 0 }, + 0, + 0 + } +}; + +void IgorEngine::handleOptionsMenu_paintSave() { + drawString(_screenTextLayer, "Not available in shareware version", 60, 70 - 16, 0xF6, -1, 0); +} + +bool IgorEngine::handleOptionsMenu_handleKeyDownSave(int key) { + return true; +} + +void IgorEngine::handleOptionsMenu_paintLoad() { + drawString(_screenTextLayer, "Not available in shareware version", 60, 70 - 16, 0xF6, -1, 0); +} + +bool IgorEngine::handleOptionsMenu_handleKeyDownLoad(int key) { + return true; +} + +void IgorEngine::handleOptionsMenu_paintQuit() { + drawString(_screenTextLayer, "Are you sure?", 120, 64 - 15, 0xF6, -1, 0); + drawString(_screenTextLayer, "(Y/N)", 143, 76 - 15, 0xF6, -1, 0); +} + +bool IgorEngine::handleOptionsMenu_handleKeyDownQuit(int key) { + if (key == Common::KEYCODE_y) { + _currentPart = 255; // display the shareware screens + } + return true; +} + +static void redrawRect(uint8 *dst, int num, bool border) { + const int x = 43 + 6; + const int y = 22 * num; + for (int i = 0; i < 21; ++i) { + memset(dst + (y + i) * 320 + x, 0xF8, 222); + } + if (border) { + memset(dst + y * 320 + x, 0xF7, 222); + memset(dst + (y + 20) * 320 + x, 0xF9, 222); + for (int i = 1; i < 20; ++i) { + dst[(y + i) * 320 + x ] = 0xF7; + dst[(y + i) * 320 + x + 221] = 0xF9; + } + } +} + +void IgorEngine::handleOptionsMenu_paintCtrl() { + static const char *textsStrTable1[] = { + "Sound effects OFF", + "Sound effects ON", + "Sound effects UNAVAILABLE" + }; + static int textsPosTable1[] = { 106, 110, 77 }; + int i = _gameState.configSoundEnabled; + redrawRect(_screenTextLayer, 1, false); + drawString(_screenTextLayer, textsStrTable1[i], textsPosTable1[i], 41 - 15, 0xF7, -1, 0); + + redrawRect(_screenTextLayer, 2, false); + drawString(_screenTextLayer, "Only TEXT AVAILABLE", 93, 63 - 15, 0xF7, -1, 0); + + static const char *textsStrTable2[] = { + "Music OFF", + "Music ON", + "Music UNAVAILABLE" + }; + static int textsPosTable2[] = { 129, 133, 100 }; + i = 1; + redrawRect(_screenTextLayer, 3, false); + drawString(_screenTextLayer, textsStrTable2[i], textsPosTable2[i], 85 - 15, 0xF7, -1, 0); + + static const char *textsStrTable3[] = { + "Text speed VERY SLOW", + "Text speed SLOW", + "Text speed NORMAL", + "Text speed FAST", + "Text speed VERY FAST" + }; + static int textsPosTable3[] = { 93, 110, 102, 111, 94 }; + i = _gameState.talkSpeed - 1; + redrawRect(_screenTextLayer, 4, true); + drawString(_screenTextLayer, textsStrTable3[i], textsPosTable3[i], 107 - 15, 0xF6, -1, 0); +} + +bool IgorEngine::handleOptionsMenu_handleKeyDownCtrl(int key) { + switch (key) { + case Common::KEYCODE_ESCAPE: + return true; + case Common::KEYCODE_RETURN: + if (_gameState.talkSpeed == 5) { + _gameState.talkSpeed = 1; + } else { + ++_gameState.talkSpeed; + } + handleOptionsMenu_paintCtrl(); + break; + } + return false; +} + +void IgorEngine::handleOptionsMenu() { + hideCursor(); + memcpy(_paletteBuffer, _currentPalette, 768); + memset(_screenVGA + 144 * 320, 0, 11 * 320); + _system->copyRectToScreen(_screenVGA, 320, 0, 0, 320, 200); + for (int m = 3; m < 22; m += 3) { + for (int i = 1 * 3; i <= 245 * 3; ++i) { + if (_paletteBuffer[i] >= m) { + _currentPalette[i] = MAX<int>(_paletteBuffer[i] - m, _currentPalette[i] - 3); + } + } + setPaletteRange(1, 245); + _system->updateScreen(); + _system->delayMillis(1000 / 60); + } + setPaletteColor(255, 35, 35, 23); + + memcpy(_screenTextLayer, _screenVGA + 4800, 36800); + + uint8 *optionsMenu = loadData(IMG_OptionsMenu); + for (int i = 0; i < 36800; ++i) { + if (optionsMenu[i]) { + _screenTextLayer[i] = optionsMenu[i]; + } + } + free(optionsMenu); + uint8 *optionsButton = loadData(IMG_OptionsButton); + drawButtonsBar(_screenTextLayer, optionsButton); + free(optionsButton); + + const int yPosCaption = 18 - 15; + for (int i = 0; i < 5; ++i) { + drawString(_screenTextLayer, pages[i].captions[0], pages[i].xPos[0], yPosCaption, 0xF6, -1, 0); + } + redrawButton(_screenTextLayer, 0, true); + + uint8 buttonsBarBackup[320 * 12]; + int currentPage = 0; + bool menuLoop = true; + bool focusOnPage = false; + while (menuLoop && _currentPart != 255) { + int previousPage = currentPage; + Common::Event ev; + while (_eventMan->pollEvent(ev)) { + switch (ev.type) { + case Common::EVENT_QUIT: + _currentPart = 255; + _eventQuitGame = true; + break; + case Common::EVENT_KEYDOWN: + if (focusOnPage) { + if ((this->*pages[currentPage].handleKeyDownProc)(ev.kbd.keycode)) { + memcpy(_screenTextLayer + 3 * 320, buttonsBarBackup, 320 * 12); + for (int y = 22; y <= 110; ++y) { + memset(_screenTextLayer + y * 320 + 43 + 4, 0xF8, 226); + } + focusOnPage = false; + } + } else { + switch (ev.kbd.keycode) { + case Common::KEYCODE_ESCAPE: + menuLoop = false; + break; + case Common::KEYCODE_RETURN: + if (currentPage == kPagePlay) { + menuLoop = false; + } else { + memcpy(buttonsBarBackup, _screenTextLayer + 3 * 320, 320 * 12); + for (int y = 0; y <= 11; ++y) { + memset(_screenTextLayer + (y + 3) * 320 + 44, 0xF8, 232); + } + drawString(_screenTextLayer, pages[currentPage].captions[1], pages[currentPage].xPos[1], yPosCaption, 0xFB, -1, 0); + (this->*pages[currentPage].paintProc)(); + focusOnPage = true; + } + break; + case Common::KEYCODE_LEFT: + --currentPage; + if (currentPage < 0) { + currentPage = 0; + } + break; + case Common::KEYCODE_RIGHT: + ++currentPage; + if (currentPage > 4) { + currentPage = 4; + } + break; + default: + break; + } + } + break; + default: + break; + } + } + if (previousPage != currentPage) { + redrawButton(_screenTextLayer, previousPage, false); + redrawButton(_screenTextLayer, currentPage, true); + } + _system->delayMillis(10); + _system->copyRectToScreen(_screenTextLayer, 320, 0, 15, 320, 115); + _system->updateScreen(); + } + + for (int m = 21; m >= 3; m -= 3) { + for (int i = 1 * 3; i <= 245 * 3; ++i) { + if (_paletteBuffer[i] >= m) { + _currentPalette[i] = MIN<int>(_paletteBuffer[i], _currentPalette[i] + 3); + } + } + setPaletteRange(1, 245); + _system->updateScreen(); + _system->delayMillis(1000 / 60); + } +} + +void IgorEngine::handlePause() { + drawActionSentence("GAME PAUSED", 0xFB); + do { + waitForTimer(); + } while (!_inputVars[kInputPause]); + memset(_inputVars, 0, sizeof(_inputVars)); +} + +} // namespace Igor |