2021-09-05 17:14:13 +00:00
|
|
|
/* 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.
|
|
|
|
*
|
2021-12-26 17:47:58 +00:00
|
|
|
* 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.
|
2021-09-05 17:14:13 +00:00
|
|
|
*
|
|
|
|
* 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
|
2021-12-26 17:47:58 +00:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2021-09-05 17:14:13 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2021-08-30 19:08:22 +00:00
|
|
|
#include "common/events.h"
|
|
|
|
|
|
|
|
#include "hypno/grammar.h"
|
|
|
|
#include "hypno/hypno.h"
|
|
|
|
|
|
|
|
namespace Hypno {
|
|
|
|
|
2022-01-26 17:52:04 +00:00
|
|
|
// Actions
|
2021-08-30 19:08:22 +00:00
|
|
|
|
2022-04-15 21:07:04 +00:00
|
|
|
void HypnoEngine::runMenu(Hotspots *hs, bool only_menu) {
|
2022-01-17 10:34:03 +00:00
|
|
|
Hotspot *h = hs->begin();
|
|
|
|
assert(h->type == MakeMenu);
|
2022-05-06 18:49:19 +00:00
|
|
|
|
2022-01-17 10:34:03 +00:00
|
|
|
debugC(1, kHypnoDebugScene, "hotspot actions size: %d", h->actions.size());
|
2022-04-15 21:07:04 +00:00
|
|
|
for (Actions::const_iterator itt = h->actions.begin(); !only_menu && itt != h->actions.end(); ++itt) {
|
2021-08-30 19:08:22 +00:00
|
|
|
Action *action = *itt;
|
2021-10-24 19:11:32 +00:00
|
|
|
switch (action->type) {
|
2022-01-26 17:52:04 +00:00
|
|
|
case QuitAction:
|
|
|
|
runQuit((Quit *)action);
|
2021-10-24 19:11:32 +00:00
|
|
|
break;
|
2022-01-26 17:52:04 +00:00
|
|
|
case TimerAction:
|
|
|
|
runTimer((Timer *)action);
|
2022-01-07 18:28:04 +00:00
|
|
|
break;
|
2022-01-26 17:52:04 +00:00
|
|
|
case BackgroundAction:
|
|
|
|
runBackground((Background *)action);
|
2021-10-24 19:11:32 +00:00
|
|
|
break;
|
2022-01-26 17:52:04 +00:00
|
|
|
case OverlayAction:
|
|
|
|
runOverlay((Overlay *)action);
|
2021-10-24 19:11:32 +00:00
|
|
|
break;
|
2022-01-26 17:52:04 +00:00
|
|
|
case AmbientAction:
|
|
|
|
runAmbient((Ambient *)action);
|
2021-10-24 19:11:32 +00:00
|
|
|
break;
|
2022-01-26 17:52:04 +00:00
|
|
|
case IntroAction:
|
|
|
|
runIntro((Intro *)action);
|
2022-01-15 19:25:35 +00:00
|
|
|
break;
|
2022-01-26 17:52:04 +00:00
|
|
|
case PaletteAction:
|
|
|
|
runPalette((Palette *)action);
|
2022-01-08 18:07:49 +00:00
|
|
|
break;
|
2021-10-24 19:11:32 +00:00
|
|
|
|
2022-01-26 17:52:04 +00:00
|
|
|
default:
|
2021-10-24 19:11:32 +00:00
|
|
|
break;
|
|
|
|
}
|
2021-08-30 19:08:22 +00:00
|
|
|
|
2022-01-26 17:52:04 +00:00
|
|
|
// else if (typeid(*action) == typeid(Mice))
|
2021-08-30 19:08:22 +00:00
|
|
|
// runMice(h, (Mice*) action);
|
|
|
|
}
|
|
|
|
|
2022-01-22 08:58:17 +00:00
|
|
|
drawBackToMenu(h);
|
2021-08-30 19:08:22 +00:00
|
|
|
}
|
|
|
|
|
2022-01-22 08:58:17 +00:00
|
|
|
void HypnoEngine::drawBackToMenu(Hotspot *h) {}
|
|
|
|
|
2022-01-26 17:52:04 +00:00
|
|
|
void HypnoEngine::runBackground(Background *a) {
|
2021-11-05 23:04:35 +00:00
|
|
|
if (a->condition.size() > 0) {
|
|
|
|
bool condition = _sceneState[a->condition];
|
|
|
|
|
2022-01-26 17:52:04 +00:00
|
|
|
if (a->flag1 == "/NSTATE" || a->flag2 == "/NSTATE")
|
2021-11-05 23:04:35 +00:00
|
|
|
condition = !condition;
|
|
|
|
|
|
|
|
if (!condition)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-09-17 07:05:04 +00:00
|
|
|
loadImage(a->path, a->origin.x, a->origin.y, false);
|
2021-08-30 19:08:22 +00:00
|
|
|
}
|
|
|
|
|
2022-01-07 18:28:04 +00:00
|
|
|
void HypnoEngine::runTimer(Timer *a) {
|
|
|
|
if (_timerStarted)
|
|
|
|
return; // Do not start another timer
|
|
|
|
|
2022-01-26 17:52:04 +00:00
|
|
|
uint32 delay = a->delay / 1000;
|
2022-06-18 08:00:03 +00:00
|
|
|
if (a->flag == "vus0")
|
|
|
|
_keepTimerDuringScenes = true;
|
2022-01-07 18:28:04 +00:00
|
|
|
debugC(1, kHypnoDebugScene, "Starting timer with %d secons", delay);
|
|
|
|
|
|
|
|
if (delay == 0 || !startCountdown(delay))
|
|
|
|
error("Failed to start countdown");
|
|
|
|
}
|
|
|
|
|
2021-08-30 19:08:22 +00:00
|
|
|
void HypnoEngine::runOverlay(Overlay *a) {
|
2021-09-17 07:05:04 +00:00
|
|
|
loadImage(a->path, a->origin.x, a->origin.y, false);
|
2021-08-30 19:08:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void HypnoEngine::runMice(Mice *a) {
|
|
|
|
changeCursor(a->path, a->index);
|
|
|
|
}
|
|
|
|
|
2022-05-07 14:58:53 +00:00
|
|
|
void HypnoEngine::runSwapPointer(SwapPointer *a) {
|
|
|
|
_defaultCursorIdx = a->index;
|
|
|
|
defaultCursor();
|
|
|
|
}
|
|
|
|
|
2022-01-08 18:07:49 +00:00
|
|
|
void HypnoEngine::runPalette(Palette *a) {
|
2022-01-10 19:22:07 +00:00
|
|
|
loadPalette(a->path);
|
2022-01-08 18:07:49 +00:00
|
|
|
}
|
|
|
|
|
2021-11-06 19:07:26 +00:00
|
|
|
void HypnoEngine::runEscape() {
|
2021-08-30 19:08:22 +00:00
|
|
|
_nextHotsToRemove = stack.back();
|
2021-11-06 19:07:26 +00:00
|
|
|
_nextSequentialVideoToPlay = _escapeSequentialVideoToPlay;
|
|
|
|
_escapeSequentialVideoToPlay.clear();
|
2021-08-30 19:08:22 +00:00
|
|
|
}
|
|
|
|
|
2022-01-15 19:25:35 +00:00
|
|
|
void HypnoEngine::runIntro(Intro *a) {
|
|
|
|
// Should not repeat the same
|
|
|
|
if (_intros.contains(a->path))
|
|
|
|
return;
|
|
|
|
|
|
|
|
_intros[a->path] = true;
|
|
|
|
MVideo v(a->path, Common::Point(0, 0), false, true, false);
|
2022-08-11 06:52:08 +00:00
|
|
|
disableCursor();
|
2022-01-15 19:25:35 +00:00
|
|
|
runIntro(v);
|
2022-08-11 06:52:08 +00:00
|
|
|
defaultCursor();
|
2022-01-15 19:25:35 +00:00
|
|
|
}
|
|
|
|
|
2021-08-30 19:08:22 +00:00
|
|
|
void HypnoEngine::runCutscene(Cutscene *a) {
|
|
|
|
stopSound();
|
2021-11-15 18:37:36 +00:00
|
|
|
defaultCursor();
|
2021-09-17 07:05:04 +00:00
|
|
|
_music.clear();
|
2022-08-11 06:52:08 +00:00
|
|
|
MVideo v(a->path, Common::Point(0, 0), false, true, false);
|
|
|
|
disableCursor();
|
|
|
|
runIntro(v);
|
|
|
|
defaultCursor();
|
|
|
|
runMenu(stack.back());
|
|
|
|
drawScreen();
|
2021-08-30 19:08:22 +00:00
|
|
|
}
|
|
|
|
|
2021-11-05 23:04:35 +00:00
|
|
|
bool HypnoEngine::runGlobal(Global *a) {
|
2022-01-02 10:08:39 +00:00
|
|
|
debugC(1, kHypnoDebugScene, "Runing global with command '%s' and variable '%s'", a->command.c_str(), a->variable.c_str());
|
2021-08-30 19:08:22 +00:00
|
|
|
if (a->command == "TURNON")
|
|
|
|
_sceneState[a->variable] = 1;
|
|
|
|
else if (a->command == "TURNOFF")
|
|
|
|
_sceneState[a->variable] = 0;
|
2021-10-06 15:45:40 +00:00
|
|
|
else if (a->command == "TOGGLE")
|
|
|
|
_sceneState[a->variable] = !_sceneState[a->variable];
|
2021-11-13 08:53:58 +00:00
|
|
|
else if (a->command == "CHECK") {
|
|
|
|
if (!_sceneState[a->variable]) // Clear any video to play
|
|
|
|
_nextSequentialVideoToPlay.clear();
|
2021-11-05 23:04:35 +00:00
|
|
|
return _sceneState[a->variable];
|
2021-11-13 08:53:58 +00:00
|
|
|
} else if (a->command == "NCHECK") {
|
|
|
|
if (_sceneState[a->variable]) // Clear any video to play
|
|
|
|
_nextSequentialVideoToPlay.clear();
|
2021-11-05 23:04:35 +00:00
|
|
|
return !_sceneState[a->variable];
|
2022-01-02 10:08:39 +00:00
|
|
|
} else if (a->command == "CLEAR") {
|
|
|
|
resetSceneState();
|
|
|
|
return true;
|
2021-11-13 08:53:58 +00:00
|
|
|
} else
|
2021-08-30 19:08:22 +00:00
|
|
|
error("Invalid command %s", a->command.c_str());
|
2021-11-05 23:04:35 +00:00
|
|
|
return true;
|
2021-08-30 19:08:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void HypnoEngine::runPlay(Play *a) {
|
|
|
|
if (a->condition.size() > 0 && !_sceneState[a->condition])
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (a->flag == "/BITMAP")
|
2021-09-17 07:05:04 +00:00
|
|
|
loadImage(a->path, a->origin.x, a->origin.y, false);
|
2021-08-30 19:08:22 +00:00
|
|
|
else {
|
|
|
|
_nextSequentialVideoToPlay.push_back(MVideo(a->path, a->origin, false, false, false));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-30 21:49:26 +00:00
|
|
|
void HypnoEngine::runSound(Sound *a) {
|
|
|
|
playSound(a->path, 1);
|
|
|
|
}
|
|
|
|
|
2021-08-30 19:08:22 +00:00
|
|
|
void HypnoEngine::runAmbient(Ambient *a) {
|
2021-10-31 10:47:48 +00:00
|
|
|
if (a->flag == "/BITMAP") {
|
2022-01-10 19:22:07 +00:00
|
|
|
Graphics::Surface *frame = decodeFrame(a->path, a->frameNumber);
|
2021-10-31 10:47:48 +00:00
|
|
|
Graphics::Surface *sframe;
|
|
|
|
if (a->fullscreen)
|
|
|
|
sframe = frame->scale(_screenW, _screenH);
|
|
|
|
else
|
|
|
|
sframe = frame;
|
|
|
|
drawImage(*sframe, a->origin.x, a->origin.y, true);
|
2022-01-26 17:52:04 +00:00
|
|
|
if (a->fullscreen) {
|
2022-01-19 08:23:33 +00:00
|
|
|
frame->free();
|
|
|
|
delete frame;
|
|
|
|
}
|
|
|
|
sframe->free();
|
|
|
|
delete sframe;
|
2021-10-31 10:47:48 +00:00
|
|
|
} else {
|
2022-01-15 19:25:35 +00:00
|
|
|
bool loop = a->flag == "/LOOP";
|
|
|
|
if (loop) { // Avoid re-adding the same looping video
|
|
|
|
if (_intros.contains(a->path))
|
|
|
|
return;
|
|
|
|
_intros[a->path] = true;
|
|
|
|
}
|
|
|
|
_nextSequentialVideoToPlay.push_back(MVideo(a->path, a->origin, false, a->fullscreen, loop));
|
2021-08-30 19:08:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void HypnoEngine::runWalN(WalN *a) {
|
|
|
|
if (a->condition.size() > 0 && !_sceneState[a->condition])
|
|
|
|
return;
|
2021-11-06 19:07:26 +00:00
|
|
|
|
|
|
|
if (a->wn == "WAL0")
|
2021-08-30 19:08:22 +00:00
|
|
|
_nextSequentialVideoToPlay.push_back(MVideo(a->path, a->origin, false, false, false));
|
2021-11-06 19:07:26 +00:00
|
|
|
else if (a->wn == "WAL1")
|
|
|
|
_escapeSequentialVideoToPlay.push_back(MVideo(a->path, a->origin, false, false, false));
|
|
|
|
else
|
|
|
|
error("Invalid WALN command: %s", a->wn.c_str());
|
2021-08-30 19:08:22 +00:00
|
|
|
}
|
|
|
|
|
2022-01-03 19:46:20 +00:00
|
|
|
void HypnoEngine::runSave(Save *a) {
|
2022-01-17 18:21:34 +00:00
|
|
|
// TODO: enable this when saving in the main menu is available
|
2022-01-26 17:52:04 +00:00
|
|
|
// saveGameDialog();
|
2022-01-03 19:46:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void HypnoEngine::runLoad(Load *a) {
|
|
|
|
loadGameDialog();
|
|
|
|
}
|
|
|
|
|
2022-01-06 19:04:52 +00:00
|
|
|
void HypnoEngine::runLoadCheckpoint(LoadCheckpoint *a) {
|
|
|
|
if (_checkpoint.empty())
|
|
|
|
error("Invalid checkpoint!");
|
2022-03-13 10:00:16 +00:00
|
|
|
loadGame(_checkpoint, _score, _sceneState["GS_PUZZLELEVEL"], _sceneState["GS_COMBATLEVEL"]);
|
2022-01-06 19:04:52 +00:00
|
|
|
}
|
|
|
|
|
2021-08-30 19:08:22 +00:00
|
|
|
void HypnoEngine::runQuit(Quit *a) {
|
|
|
|
quitGame();
|
|
|
|
}
|
|
|
|
|
|
|
|
void HypnoEngine::runChangeLevel(ChangeLevel *a) {
|
2022-01-26 17:52:04 +00:00
|
|
|
debugC(1, kHypnoDebugScene, "Next level is '%s'", a->level.c_str());
|
2021-08-30 19:08:22 +00:00
|
|
|
_nextLevel = a->level;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HypnoEngine::runTalk(Talk *a) {
|
2022-04-15 10:07:07 +00:00
|
|
|
// Recreate the items to allow modifications
|
|
|
|
Talk *n = new Talk(a);
|
|
|
|
_conversation.push_back(n);
|
2021-08-30 19:08:22 +00:00
|
|
|
_refreshConversation = true;
|
|
|
|
}
|
|
|
|
|
2021-09-08 20:49:56 +00:00
|
|
|
} // End of namespace Hypno
|