aboutsummaryrefslogtreecommitdiff
path: root/engines/igor/menu.cpp
diff options
context:
space:
mode:
authorGregory Montoir2007-10-29 23:35:50 +0000
committerGregory Montoir2007-10-29 23:35:50 +0000
commit6c6e8657b68ebc075871031ee8c662f349c4ab77 (patch)
tree1e2c691ffe1d142a3e781670ac63a981ebf70114 /engines/igor/menu.cpp
parentcaa451f5d2b471fc207739815638056f86fc8dce (diff)
downloadscummvm-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.cpp346
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