Logo Search packages:      
Sourcecode: scummvm version File versions  Download package

menu.cpp

/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-0-11-1/engines/igor/menu.cpp $
 * $Id: menu.cpp 30944 2008-02-23 22:50:18Z sev $
 *
 */

#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 = kInvalidPart;
      }
      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 && !_eventQuitGame && _currentPart != kInvalidPart) {
            int previousPage = currentPage;
            Common::Event ev;
            while (_eventMan->pollEvent(ev)) {
                  switch (ev.type) {
                  case Common::EVENT_QUIT:
                        _currentPart = kInvalidPart;
                        _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);
      }
      showCursor();
}

void IgorEngine::handlePause() {
      drawActionSentence(getString(STR_GamePaused), 0xFB);
      do {
            waitForTimer();
      } while (!_inputVars[kInputPause]);
      memset(_inputVars, 0, sizeof(_inputVars));
}

} // namespace Igor

Generated by  Doxygen 1.6.0   Back to index