/* 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 3 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, see . * */ #include "common/bitarray.h" #include "gui/message.h" #include "common/events.h" #include "common/config-manager.h" #include "common/savefile.h" #include "hypno/hypno.h" #include "backends/keymapper/keymapper.h" namespace Hypno { void WetEngine::endCredits(Code *code) { showCredits(); _nextLevel = ""; } void WetEngine::runCode(Code *code) { changeScreenMode("320x200"); if (code->name == "") runMainMenu(code); else if (code->name == "") runLevelMenu(code); else if (code->name == "") runCheckLives(code); else if (code->name == "") endCredits(code); else error("invalid hardcoded level: %s", code->name.c_str()); } void WetEngine::runCheckLives(Code *code) { if (_lives < 0) { _nextLevel = ""; _score = 0; _lives = 2; restoreScoreMilestones(_score); saveProfile(_name, _lastLevel); } else _nextLevel = _checkpoint; } void WetEngine::runLevelMenu(Code *code) { if (_lastLevel == 0) { _nextLevel = Common::String::format("c%d", _ids[0]); return; } Common::Event event; byte *palette; Graphics::Surface *menu = decodeFrame("c_misc/menus.smk", 20, &palette); loadPalette(palette, 0, 256); free(palette); byte black[3] = {0x00, 0x00, 0x00}; // Always red? byte lime[3] = {0x00, 0xFF, 0x00}; // Always red? byte green[3] = {0x2C, 0x82, 0x28}; // Always red? int maxLevel = 20; int currentLevel = 0; for (int i = 0; i < maxLevel; i++) if (i <= _lastLevel) loadPalette((byte *) &green, 192+i, 1); else loadPalette((byte *) &black, 192+i, 1); loadPalette((byte *) &lime, 192+currentLevel, 1); drawImage(*menu, 0, 0, false); bool cont = true; // TODO: Should this be played as music instead? playSound("sound/bub01.raw", 0, 22050); Common::Keymapper *keymapper = g_system->getEventManager()->getKeymapper(); keymapper->getKeymap("game-shortcuts")->setEnabled(false); keymapper->getKeymap("menu")->setEnabled(true); while (!shouldQuit() && cont) { while (g_system->getEventManager()->pollEvent(event)) { // Events switch (event.type) { case Common::EVENT_QUIT: case Common::EVENT_RETURN_TO_LAUNCHER: break; case Common::EVENT_CUSTOM_ENGINE_ACTION_START: if (event.customType == kActionDown && currentLevel < _lastLevel) { playSound("sound/m_hilite.raw", 1, 11025); currentLevel++; } else if (event.customType == kActionUp && currentLevel > 0) { playSound("sound/m_hilite.raw", 1, 11025); currentLevel--; } else if (event.customType == kActionSelect ) { playSound("sound/m_choice.raw", 1, 11025); _nextLevel = Common::String::format("c%d", _ids[currentLevel]); cont = false; } else if (event.customType == kActionPause) { openMainMenuDialog(); } for (int i = 0; i < maxLevel; i++) if (i <= _lastLevel) loadPalette((byte *) &green, 192+i, 1); else loadPalette((byte *) &black, 192+i, 1); loadPalette((byte *) &lime, 192+currentLevel, 1); drawImage(*menu, 0, 0, false); break; default: break; } } drawScreen(); g_system->delayMillis(10); } keymapper->getKeymap("menu")->setEnabled(false); keymapper->getKeymap("game-shortcuts")->setEnabled(true); menu->free(); delete menu; } void WetEngine::runMainMenu(Code *code) { Common::Event event; uint32 c = 252; // green byte *palette; Graphics::Surface *menu = decodeFrame("c_misc/menus.smk", 16, &palette); Graphics::Surface *overlay = decodeFrame("c_misc/menus.smk", 18, nullptr); loadPalette(palette, 0, 256); free(palette); Common::Rect subName(21, 10, 169, 24); drawImage(*menu, 0, 0, false); Graphics::Surface surName = overlay->getSubArea(subName); drawImage(surName, subName.left, subName.top, true); drawString("scifi08.fgx", _enterNameString, 48, 50, 100, c); _name.clear(); Common::Keymapper *keymapper = g_system->getEventManager()->getKeymapper(); keymapper->getKeymap("game-shortcuts")->setEnabled(false); keymapper->getKeymap("pause")->setEnabled(false); keymapper->getKeymap("direction")->setEnabled(false); g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true); bool cont = true; while (!shouldQuit() && cont) { while (g_system->getEventManager()->pollEvent(event)) { // Events switch (event.type) { case Common::EVENT_QUIT: case Common::EVENT_RETURN_TO_LAUNCHER: break; case Common::EVENT_KEYDOWN: if (event.kbd.keycode == Common::KEYCODE_BACKSPACE) _name.deleteLastChar(); else if (event.kbd.keycode == Common::KEYCODE_RETURN && !_name.empty()) { cont = false; } else if (Common::isAlpha(event.kbd.keycode)) { playSound("sound/m_choice.raw", 1); _name = _name + char(event.kbd.keycode - 32); } if (event.kbd.keycode == Common::KEYCODE_ESCAPE) { openMainMenuDialog(); } drawImage(*menu, 0, 0, false); drawImage(surName, subName.left, subName.top, true); drawString("scifi08.fgx", _enterNameString, 48, 50, 100, c); drawString("scifi08.fgx", _name, 140, 50, 170, c); break; default: break; } } drawScreen(); g_system->delayMillis(10); } if (_name == "COOLCOLE" || _unlockAllLevels) { _lastLevel = 19; playSound("sound/extra.raw", 1); } else _lastLevel = 0; if (_name == "ELRAPIDO") { _infiniteAmmoCheat = true; playSound("sound/extra.raw", 1); } if (_name == "SAVANNAH") { _infiniteHealthCheat = true; playSound("sound/extra.raw", 1); } if ((_name == "FRASCAS" && _language == Common::ES_ESP) || \ (_name == "RITCHY" && _language == Common::FR_FRA)) { _infiniteAmmoCheat = true; _infiniteHealthCheat = true; _lastLevel = 19; playSound("sound/extra.raw", 1); } _name.toLowercase(); bool found = loadProfile(_name); g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false); keymapper->getKeymap("game-shortcuts")->setEnabled(true); keymapper->getKeymap("pause")->setEnabled(true); keymapper->getKeymap("direction")->setEnabled(true); if (found || _name.empty()) { menu->free(); delete menu; overlay->free(); delete overlay; return; } saveProfile(_name, _ids[_lastLevel]); _name.toUppercase(); // We do this in order to show it again Common::Rect subDifficulty(20, 104, 233, 119); Graphics::Surface surDifficulty = overlay->getSubArea(subDifficulty); drawImage(*menu, 0, 0, false); drawImage(surDifficulty, subDifficulty.left, subDifficulty.top, true); Common::Rect subWet(129, 149, 195, 159); Graphics::Surface surWet = overlay->getSubArea(subWet); drawImage(surWet, subWet.left, subWet.top, true); playSound("sound/no_rapid.raw", 1, 11025); Common::Rect subDamp(52, 149, 115, 159); Graphics::Surface surDamp = overlay->getSubArea(subDamp); Common::Rect subSoaked(202, 149, 272, 159); Graphics::Surface surSoaked = overlay->getSubArea(subSoaked); Common::Array difficulties; difficulties.push_back("0"); difficulties.push_back("1"); difficulties.push_back("2"); uint32 idx = 1; drawString("scifi08.fgx", _enterNameString, 48, 50, 100, c); drawString("scifi08.fgx", _name, 140, 50, 170, c); cont = true; keymapper->getKeymap("game-shortcuts")->setEnabled(false); keymapper->getKeymap("pause")->setEnabled(false); keymapper->getKeymap("menu")->setEnabled(true); while (!shouldQuit() && cont) { while (g_system->getEventManager()->pollEvent(event)) { // Events switch (event.type) { case Common::EVENT_QUIT: case Common::EVENT_RETURN_TO_LAUNCHER: break; case Common::EVENT_LBUTTONDOWN: case Common::EVENT_CUSTOM_ENGINE_ACTION_START: if (!g_system->hasFeature(OSystem::kFeatureTouchscreen)) event.mouse = Common::Point(0, 0); if (idx == 1 && (subDamp.contains(event.mouse) || subSoaked.contains(event.mouse))) { if (subDamp.contains(event.mouse)) { playSound("sound/no_rapid.raw", 1, 11025); idx--; } else if (subSoaked.contains(event.mouse)) { playSound("sound/no_rapid.raw", 1, 11025); idx++; } } else if (idx == 1 && subWet.contains(event.mouse)) { // Nothing } else if ((subWet.contains(event.mouse) || subDamp.contains(event.mouse) || event.customType == kActionLeft) && idx > 0) { playSound("sound/no_rapid.raw", 1, 11025); idx--; } else if ((subWet.contains(event.mouse) || subSoaked.contains(event.mouse) || event.customType == kActionRight) && idx < 2) { playSound("sound/no_rapid.raw", 1, 11025); idx++; } else if (event.customType == kActionSelect) cont = false; drawImage(*menu, 0, 0, false); drawImage(surDifficulty, subDifficulty.left, subDifficulty.top, true); if (difficulties[idx] == "0") drawImage(surDamp, subDamp.left, subDamp.top, true); else if (difficulties[idx] == "1") drawImage(surWet, subWet.left, subWet.top, true); else if (difficulties[idx] == "2") drawImage(surSoaked, subSoaked.left, subSoaked.top, true); else error("Invalid difficulty: %s", difficulties[idx].c_str()); drawString("scifi08.fgx", _enterNameString, 48, 50, 100, c); drawString("scifi08.fgx", _name, 140, 50, 170, c); break; default: break; } } drawScreen(); g_system->delayMillis(10); } keymapper->getKeymap("menu")->setEnabled(false); keymapper->getKeymap("game-shortcuts")->setEnabled(true); keymapper->getKeymap("pause")->setEnabled(true); _name.toLowercase(); // make sure it is lowercase when we finish _difficulty = difficulties[idx]; _nextLevel = code->levelIfWin; menu->free(); delete menu; overlay->free(); delete overlay; } void WetEngine::showDemoScore() { Common::String fmessage = "You finished this demo level with an accuracy of %d%% and a score of %d points"; Common::String message = Common::String::format(fmessage.c_str(), accuracyRatio(), _score); GUI::MessageDialog dialog(message); dialog.runModal(); } Common::String WetEngine::getLocalizedString(const Common::String &name) { if (name == "name") { switch (_language) { case Common::FR_FRA: return "NOM :"; case Common::ES_ESP: return "NOMBRE :"; case Common::KO_KOR: return "\xb7\xa1\x9f\x71\xb7\xb3\x9d\x62:"; default: return "ENTER NAME :"; } } else if (name == "health") { switch (_language) { case Common::FR_FRA: return "ENERGIE"; case Common::ES_ESP: return "ENERGIA"; case Common::KO_KOR: return "\xb5\x41\x90\xe1\xbb\xa1"; // 체력 (health) default: return "ENERGY"; } } else if (name == "objectives") { switch (_language) { case Common::FR_FRA: return "OBJ."; case Common::ES_ESP: return "O. M."; case Common::KO_KOR: return "\xa1\xa2\xce\x61"; // 목표 (objective) default: return "M. O."; } } else if (name == "score") { switch (_language) { case Common::ES_ESP: return "PUNTOS"; case Common::KO_KOR: return "\xb8\xf1\xae\x81"; // 점수 (score) default: return "SCORE"; } } else if (name == "target") { switch (_language) { case Common::FR_FRA: return "VERROUILLAGE"; case Common::ES_ESP: return "BLANCO FIJADO"; case Common::KO_KOR: return "\xa1\xa2\xce\x61\x20\xbb\xe1\xaf\x81"; // 목표물포착 (target acquired) default: return "TARGET ACQUIRED"; } } else if (name == "direction") { switch (_language) { case Common::FR_FRA: return "DIRECTION ?"; case Common::ES_ESP: return "ELIGE DIRECCION"; case Common::KO_KOR: return "\xa4\x77\xd0\xb7\xac\xe5\x00\x00\xc8\x82"; // 전향선택 (choose direction) default: return "CHOOSE DIRECTION"; } } else error("Invalid string name to localize: %s", name.c_str()); } } // End of namespace Hypno