From 6a16c8bbb5c8ef97833dd1d8490a02aa9d57bb26 Mon Sep 17 00:00:00 2001 From: neuromancer Date: Sun, 22 May 2022 18:41:11 +0200 Subject: [PATCH] HYPNO: added basic implementation for selection in specific scenes in boyz --- engines/hypno/actions.cpp | 3 - engines/hypno/boyz/boyz.cpp | 49 ++++++++++++++++- engines/hypno/boyz/scene.cpp | 103 +++++++++++++++++++++++++++++++++++ engines/hypno/grammar.h | 14 ++++- engines/hypno/hypno.h | 13 +++-- engines/hypno/module.mk | 3 +- 6 files changed, 175 insertions(+), 10 deletions(-) create mode 100644 engines/hypno/boyz/scene.cpp diff --git a/engines/hypno/actions.cpp b/engines/hypno/actions.cpp index 6764e636c45..58f527c9ccd 100644 --- a/engines/hypno/actions.cpp +++ b/engines/hypno/actions.cpp @@ -31,9 +31,6 @@ namespace Hypno { void HypnoEngine::runMenu(Hotspots *hs, bool only_menu) { Hotspot *h = hs->begin(); assert(h->type == MakeMenu); - if (!h->background.empty()) { - loadImage(h->background, 0, 0, false, true); - } debugC(1, kHypnoDebugScene, "hotspot actions size: %d", h->actions.size()); for (Actions::const_iterator itt = h->actions.begin(); !only_menu && itt != h->actions.end(); ++itt) { diff --git a/engines/hypno/boyz/boyz.cpp b/engines/hypno/boyz/boyz.cpp index 799d2c78168..bc81bc2ff6d 100644 --- a/engines/hypno/boyz/boyz.cpp +++ b/engines/hypno/boyz/boyz.cpp @@ -157,11 +157,58 @@ void BoyzEngine::loadAssets() { loadArcadeLevel("c58.mi_", "c59.mi_", "", ""); loadArcadeLevel("c59.mi_", "", "", ""); + Global *gl; + ChangeLevel *cl; + Cutscene *cs; + Highlight *hl; + loadSceneLevel(selectBoyz, "", "", ""); Scene *sc = (Scene *) _levels[""]; sc->resolution = "320x200"; - ChangeLevel *cl = new ChangeLevel("c19.mi_"); + hl = new Highlight("GS_SWITCH1"); + sc->hots[1].actions.push_back(hl); + gl = new Global("GS_SWITCH1", "TURNON"); + sc->hots[1].actions.push_back(gl); + cs = new Cutscene("intro/c0i01s.smk"); + sc->hots[1].actions.push_back(cs); + + hl = new Highlight("GS_SWITCH2"); + sc->hots[2].actions.push_back(hl); + gl = new Global("GS_SWITCH2", "TURNON"); + sc->hots[2].actions.push_back(gl); + cs = new Cutscene("intro/c0i02s.smk"); + sc->hots[2].actions.push_back(cs); + + hl = new Highlight("GS_SWITCH3"); + sc->hots[3].actions.push_back(hl); + gl = new Global("GS_SWITCH3", "TURNON"); + sc->hots[3].actions.push_back(gl); + cs = new Cutscene("intro/c0i03s.smk"); + sc->hots[3].actions.push_back(cs); + + hl = new Highlight("GS_SWITCH4"); + sc->hots[4].actions.push_back(hl); + gl = new Global("GS_SWITCH4", "TURNON"); + sc->hots[4].actions.push_back(gl); + cs = new Cutscene("intro/c0i04s.smk"); + sc->hots[4].actions.push_back(cs); + + hl = new Highlight("GS_SWITCH5"); + sc->hots[5].actions.push_back(hl); + gl = new Global("GS_SWITCH5", "TURNON"); + sc->hots[5].actions.push_back(gl); + cs = new Cutscene("intro/c0i05s.smk"); + sc->hots[5].actions.push_back(cs); + + hl = new Highlight("GS_SWITCH6"); + sc->hots[6].actions.push_back(hl); + gl = new Global("GS_SWITCH6", "TURNON"); + sc->hots[6].actions.push_back(gl); + cs = new Cutscene("intro/c0i06s.smk"); + sc->hots[6].actions.push_back(cs); + + cl = new ChangeLevel("c19.mi_"); sc->hots[7].actions.push_back(cl); loadSceneLevel(selectC3, "", "", ""); diff --git a/engines/hypno/boyz/scene.cpp b/engines/hypno/boyz/scene.cpp new file mode 100644 index 00000000000..2e7b3b06393 --- /dev/null +++ b/engines/hypno/boyz/scene.cpp @@ -0,0 +1,103 @@ +/* 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/events.h" + +#include "hypno/hypno.h" + +namespace Hypno { + +void BoyzEngine::runMenu(Hotspots *hs, bool only_menu) { + Hotspot *h = hs->begin(); + assert(h->type == MakeMenu); + if (!h->background.empty()) { + loadImage(h->background, 0, 0, false, true, 1); + if (h->backgroundFrames.empty()) { + h->backgroundFrames = decodeFrames(h->background); + } + } + renderHighlights(hs); +} + +void BoyzEngine::renderHighlights(Hotspots *hs) { + Hotspot *menu = hs->begin(); + if (menu->type != MakeMenu || menu->background.empty()) + return; + + for (Hotspots::const_iterator it = hs->begin(); it != hs->end(); ++it) { + if (it->type == MakeMenu) + continue; + + Highlight *hl; + for (Actions::const_iterator itt = it->actions.begin(); itt != it->actions.end(); ++itt) { + Action *action = *itt; + switch (action->type) { + case HighlightAction: + hl = (Highlight *)action; + if (_sceneState[hl->condition]) { + Graphics::Surface sub = menu->backgroundFrames[0]->getSubArea(it->rect); + drawImage(sub, it->rect.left, it->rect.top, false); + } + break; + + default: + break; + } + } + } +} + +bool BoyzEngine::hoverHotspot(Common::Point mousePos) { + if (_rnd->getRandomBit()) + return false; // Dirty trick to avoid updating the screen too often + Hotspots *hots = stack.back(); + Hotspot selected(MakeHotspot); + bool found = false; + int rs = 100000000; + for (Hotspots::const_iterator it = hots->begin(); it != hots->end(); ++it) { + const Hotspot h = *it; + if (h.type != MakeHotspot) + continue; + + int cs = h.rect.width() * h.rect.height(); + if (h.rect.contains(mousePos)) { + if (cs < rs) { + selected = h; + found = true; + rs = cs; + } + } + } + if (found) { + Hotspot *menu = hots->begin(); + if (menu->type == MakeMenu && !menu->background.empty()) { // Hihghlight + Graphics::Surface sub = menu->backgroundFrames[2]->getSubArea(selected.rect); + drawImage(*menu->backgroundFrames[1], 0, 0, false); + drawImage(sub, selected.rect.left, selected.rect.top, false); + renderHighlights(hots); + drawScreen(); + } + return true; + } + return false; +} + +} // End of namespace Hypno \ No newline at end of file diff --git a/engines/hypno/grammar.h b/engines/hypno/grammar.h index d73e146f11b..eb380f62394 100644 --- a/engines/hypno/grammar.h +++ b/engines/hypno/grammar.h @@ -65,6 +65,7 @@ enum ActionType { TimerAction, PaletteAction, BackgroundAction, + HighlightAction, OverlayAction, EscapeAction, SaveAction, @@ -94,6 +95,7 @@ class Hotspot; typedef Common::Array Hotspots; typedef Common::Array HotspotsStack; +typedef Common::Array Frames; class Hotspot { public: @@ -106,7 +108,8 @@ public: Common::String flags[3]; Common::Rect rect; Common::String setting; - Common::String background; + Filename background; + Frames backgroundFrames; Actions actions; Hotspots *smenu; }; @@ -149,6 +152,15 @@ public: Filename path; }; +class Highlight : public Action { +public: + Highlight(Common::String condition_) { + type = HighlightAction; + condition = condition_; + } + Common::String condition; +}; + class Background : public Action { public: Background(Filename path_, Common::Point origin_, Common::String condition_, Common::String flag1_, Common::String flag2_) { diff --git a/engines/hypno/hypno.h b/engines/hypno/hypno.h index 3093139829b..bfddc3cf2db 100644 --- a/engines/hypno/hypno.h +++ b/engines/hypno/hypno.h @@ -57,8 +57,6 @@ enum { kHypnoDebugScene = 1 << 3 }; -typedef Common::Array Frames; - // Player positions enum PlayerPosition { @@ -141,7 +139,7 @@ public: // User input void clickedHotspot(Common::Point); - bool hoverHotspot(Common::Point); + virtual bool hoverHotspot(Common::Point); // Cursors bool cursorPauseMovie(Common::Point); @@ -178,7 +176,7 @@ public: void changeCursor(const Graphics::Surface &entry, byte *palette, bool centerCursor = false); // Actions - void runMenu(Hotspots *hs, bool only_menu = false); + virtual void runMenu(Hotspots *hs, bool only_menu = false); void runBackground(Background *a); void runOverlay(Overlay *a); void runMice(Mice *a); @@ -545,6 +543,11 @@ public: Common::String findNextLevel(const Common::String &level) override; Common::String findNextLevel(const Transition *trans) override; + // Scenes + void runMenu(Hotspots *hs, bool only_menu = false) override; + bool hoverHotspot(Common::Point) override; + + // Arcade void runBeforeArcade(ArcadeShooting *arc) override; void runAfterArcade(ArcadeShooting *arc) override; void pressedKey(const int keycode) override; @@ -575,6 +578,8 @@ public: void saveProfile(const Common::String &name, int levelId); private: + void renderHighlights(Hotspots *hs); + void runMainMenu(Code *code); void runRetryMenu(Code *code); void runDifficultyMenu(Code *code); diff --git a/engines/hypno/module.mk b/engines/hypno/module.mk index 898a0c859fd..c6f7b9eccea 100644 --- a/engines/hypno/module.mk +++ b/engines/hypno/module.mk @@ -4,8 +4,9 @@ MODULE_OBJS := \ actions.o \ arcade.o \ boyz/arcade.o \ - boyz/hard.o \ boyz/boyz.o \ + boyz/hard.o \ + boyz/scene.o \ cursors.o \ grammar_mis.o \ grammar_arc.o \