Files
2010-11-11 20:44:02 +02:00

317 lines
7.9 KiB
C++

/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* 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.
*/
#include "game.h"
#include "mod_player.h"
#include "resource.h"
#include "systemstub.h"
#include "video.h"
#include "menu.h"
Menu::Menu(ModPlayer *ply, Resource *res, SystemStub *stub, Video *vid)
: _ply(ply), _res(res), _stub(stub), _vid(vid) {
}
void Menu::drawString(const char *str, int16 y, int16 x, uint8 color) {
debug(DBG_MENU, "Menu::drawString()");
uint8 v1b = _vid->_charFrontColor;
uint8 v2b = _vid->_charTransparentColor;
uint8 v3b = _vid->_charShadowColor;
switch (color) {
case 0:
_vid->_charFrontColor = _charVar1;
_vid->_charTransparentColor = _charVar2;
_vid->_charShadowColor = _charVar2;
break;
case 1:
_vid->_charFrontColor = _charVar2;
_vid->_charTransparentColor = _charVar1;
_vid->_charShadowColor = _charVar1;
break;
case 2:
_vid->_charFrontColor = _charVar3;
_vid->_charTransparentColor = 0xFF;
_vid->_charShadowColor = _charVar1;
break;
case 3:
_vid->_charFrontColor = _charVar4;
_vid->_charTransparentColor = 0xFF;
_vid->_charShadowColor = _charVar1;
break;
case 4:
_vid->_charFrontColor = _charVar2;
_vid->_charTransparentColor = 0xFF;
_vid->_charShadowColor = _charVar1;
break;
case 5:
_vid->_charFrontColor = _charVar2;
_vid->_charTransparentColor = 0xFF;
_vid->_charShadowColor = _charVar5;
break;
}
drawString2(str, y, x);
_vid->_charFrontColor = v1b;
_vid->_charTransparentColor = v2b;
_vid->_charShadowColor = v3b;
}
void Menu::drawString2(const char *str, int16 y, int16 x) {
debug(DBG_MENU, "Menu::drawString2()");
int len = 0;
while (*str) {
_vid->drawChar((uint8)*str, y, x + len);
++str;
++len;
}
_vid->markBlockAsDirty(x * 8, y * 8, len * 8, 8);
}
void Menu::loadPicture(const char *prefix) {
debug(DBG_MENU, "Menu::loadPicture('%s')", prefix);
_res->load_MAP_menu(prefix, _res->_memBuf);
for (int i = 0; i < 4; ++i) {
for (int y = 0; y < 224; ++y) {
for (int x = 0; x < 64; ++x) {
_vid->_frontLayer[i + x * 4 + 256 * y] = _res->_memBuf[0x3800 * i + x + 64 * y];
}
}
}
_res->load_PAL_menu(prefix, _res->_memBuf);
_stub->setPalette(_res->_memBuf, 256);
}
void Menu::handleInfoScreen() {
debug(DBG_MENU, "Menu::handleInfoScreen()");
_vid->fadeOut();
switch (_res->_ver) {
case VER_FR:
loadPicture("instru_f");
break;
case VER_EN:
case VER_DE:
case VER_SP:
loadPicture("instru_e");
break;
}
_vid->fullRefresh();
_vid->updateScreen();
do {
_stub->sleep(EVENTS_DELAY);
_stub->processEvents();
if (_stub->_pi.enter) {
_stub->_pi.enter = false;
break;
}
} while (!_stub->_pi.quit);
}
void Menu::handleSkillScreen(uint8 &new_skill) {
debug(DBG_MENU, "Menu::handleSkillScreen()");
static const uint8 option_colors[3][3] = { { 2, 3, 3 }, { 3, 2, 3}, { 3, 3, 2 } };
_vid->fadeOut();
loadPicture("menu3");
_vid->fullRefresh();
drawString(_res->getMenuString(LocaleData::LI_12_SKILL_LEVEL), 12, 4, 3);
int skill_level = new_skill;
do {
drawString(_res->getMenuString(LocaleData::LI_13_EASY), 15, 14, option_colors[skill_level][0]);
drawString(_res->getMenuString(LocaleData::LI_14_NORMAL), 17, 14, option_colors[skill_level][1]);
drawString(_res->getMenuString(LocaleData::LI_15_EXPERT), 19, 14, option_colors[skill_level][2]);
_vid->updateScreen();
_stub->sleep(EVENTS_DELAY);
_stub->processEvents();
if (_stub->_pi.dirMask & PlayerInput::DIR_UP) {
_stub->_pi.dirMask &= ~PlayerInput::DIR_UP;
if (skill_level != 0) {
--skill_level;
} else {
skill_level = 2;
}
}
if (_stub->_pi.dirMask & PlayerInput::DIR_DOWN) {
_stub->_pi.dirMask &= ~PlayerInput::DIR_DOWN;
if (skill_level != 2) {
++skill_level;
} else {
skill_level = 0;
}
}
if (_stub->_pi.enter) {
_stub->_pi.enter = false;
new_skill = skill_level;
return;
}
} while (!_stub->_pi.quit);
new_skill = 1;
}
bool Menu::handlePasswordScreen(uint8 &new_skill, uint8 &new_level) {
debug(DBG_MENU, "Menu::handlePasswordScreen()");
_vid->fadeOut();
_vid->_charShadowColor = _charVar1;
_vid->_charTransparentColor = 0xFF;
_vid->_charFrontColor = _charVar4;
_vid->fullRefresh();
char password[7];
int len = 0;
do {
loadPicture("menu2");
drawString2(_res->getMenuString(LocaleData::LI_16_ENTER_PASSWORD1), 15, 3);
drawString2(_res->getMenuString(LocaleData::LI_17_ENTER_PASSWORD2), 17, 3);
for (int i = 0; i < len; ++i) {
_vid->drawChar((uint8)password[i], 21, i + 15);
}
_vid->drawChar(0x20, 21, len + 15);
_vid->markBlockAsDirty(15 * 8, 21 * 8, (len + 1) * 8, 8);
_vid->updateScreen();
_stub->sleep(EVENTS_DELAY);
_stub->processEvents();
char c = _stub->_pi.lastChar;
if (c != 0) {
_stub->_pi.lastChar = 0;
if (len < 6) {
if (c >= 'a' && c <= 'z') {
c &= ~0x20;
}
if ((c >= 'A' && c <= 'Z') || (c == 0x20)) {
password[len] = c;
++len;
}
}
}
if (_stub->_pi.backspace) {
_stub->_pi.backspace = false;
if (len > 0) {
--len;
}
}
if (_stub->_pi.enter) {
_stub->_pi.enter = false;
password[len] = '\0';
for (int level = 0; level < 8; ++level) {
for (int skill = 0; skill < 3; ++skill) {
if (strcmp(_passwords[level][skill], password) == 0) {
new_level = level;
new_skill = skill;
return true;
}
}
}
return false;
}
} while (!_stub->_pi.quit);
return false;
}
bool Menu::handleTitleScreen(uint8 &new_skill, uint8 &new_level) {
debug(DBG_MENU, "Menu::handleTitleScreen()");
bool quit_loop = false;
int menu_entry = 0;
bool reinit_screen = true;
bool continue_game = true;
_charVar1 = 0;
_charVar2 = 0;
_charVar3 = 0;
_charVar4 = 0;
_charVar5 = 0;
_ply->play(1);
while (!quit_loop) {
if (reinit_screen) {
_vid->fadeOut();
loadPicture("menu1");
_vid->fullRefresh();
_charVar3 = 1;
_charVar4 = 2;
menu_entry = 0;
reinit_screen = false;
}
int selected_menu_entry = -1;
for (int i = 0; i < 5; ++i) {
int color = (i == menu_entry) ? 2 : 3;
drawString(_res->getMenuString(LocaleData::LI_07_START + i), 16 + i * 2, 20, color);
}
_vid->updateScreen();
_stub->sleep(EVENTS_DELAY);
_stub->processEvents();
if (_stub->_pi.dirMask & PlayerInput::DIR_UP) {
_stub->_pi.dirMask &= ~PlayerInput::DIR_UP;
if (menu_entry != 0) {
--menu_entry;
} else {
menu_entry = 4;
}
}
if (_stub->_pi.dirMask & PlayerInput::DIR_DOWN) {
_stub->_pi.dirMask &= ~PlayerInput::DIR_DOWN;
if (menu_entry != 4) {
++menu_entry;
} else {
menu_entry = 0;
}
}
if (_stub->_pi.enter) {
_stub->_pi.enter = false;
selected_menu_entry = menu_entry;
}
if (selected_menu_entry != -1) {
switch (selected_menu_entry) {
case MENU_OPTION_ITEM_START:
new_level = 0;
quit_loop = true;
break;
case MENU_OPTION_ITEM_SKILL:
handleSkillScreen(new_skill);
reinit_screen = true;
break;
case MENU_OPTION_ITEM_PASSWORD:
if (handlePasswordScreen(new_skill, new_level)) {
quit_loop = true;
} else {
reinit_screen = true;
}
break;
case MENU_OPTION_ITEM_INFO:
handleInfoScreen();
reinit_screen = true;
break;
case MENU_OPTION_ITEM_QUIT:
continue_game = false;
quit_loop = true;
break;
}
}
if (_stub->_pi.quit) {
continue_game = false;
quit_loop = true;
break;
}
}
_ply->stop();
return continue_game;
}