Files
2026-02-02 04:50:13 +01:00

428 lines
12 KiB
C++

/* 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 <http://www.gnu.org/licenses/>.
*
*/
#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 = "<main_menu>";
}
void WetEngine::runCode(Code *code) {
changeScreenMode("320x200");
if (code->name == "<main_menu>")
runMainMenu(code);
else if (code->name == "<level_menu>")
runLevelMenu(code);
else if (code->name == "<check_lives>")
runCheckLives(code);
else if (code->name == "<credits>")
endCredits(code);
else
error("invalid hardcoded level: %s", code->name.c_str());
}
void WetEngine::runCheckLives(Code *code) {
if (_lives < 0) {
_nextLevel = "<game_over>";
_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<Common::String> 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