/* 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 . * */ #ifndef HYPNO_GRAMMAR_H #define HYPNO_GRAMMAR_H #include "common/array.h" #include "common/hash-ptr.h" #include "common/hash-str.h" #include "common/list.h" #include "common/queue.h" #include "common/rect.h" #include "common/str.h" #include "video/smk_decoder.h" namespace Hypno { typedef Common::String Filename; typedef Common::List Filenames; class HypnoSmackerDecoder : public Video::SmackerDecoder { public: bool loadStream(Common::SeekableReadStream *stream) override; protected: uint32 getSignatureVersion(uint32 signature) const override; }; class MVideo { public: MVideo(Filename, Common::Point, bool, bool, bool); Filename path; Common::Point position; bool scaled; bool transparent; bool loop; HypnoSmackerDecoder *decoder; }; typedef Common::Array Videos; enum HotspotType { MakeMenu, MakeHotspot }; enum ActionType { MiceAction, TimerAction, PaletteAction, BackgroundAction, HighlightAction, OverlayAction, EscapeAction, SaveAction, LoadAction, LoadCheckpointAction, QuitAction, CutsceneAction, PlayAction, IntroAction, AmbientAction, WalNAction, GlobalAction, TalkAction, SwapPointerAction, SoundAction, ChangeLevelAction }; class Action { public: virtual ~Action() {} // needed to make Action polymorphic ActionType type; }; typedef Common::Array Actions; class Hotspot; typedef Common::Array Hotspots; typedef Common::Array HotspotsStack; typedef Common::Array Frames; class Hotspot { public: Hotspot(HotspotType type_, Common::Rect rect_ = Common::Rect(0, 0, 0, 0)) { type = type_; rect = rect_; smenu = nullptr; } HotspotType type; Common::String flags[3]; Common::Rect rect; Common::String setting; Filename background; Frames backgroundFrames; Actions actions; Hotspots *smenu; }; class Mice : public Action { public: Mice(Filename path_, uint32 index_) { type = MiceAction; path = path_; index = index_; } Filename path; uint32 index; }; class SwapPointer : public Action { public: SwapPointer(uint32 index_) { type = SwapPointerAction; index = index_; } uint32 index; }; class Timer : public Action { public: Timer(uint32 delay_, Common::String flag_) { type = TimerAction; delay = delay_; flag = flag_; } uint32 delay; Common::String flag; }; class Palette : public Action { public: Palette(Filename path_) { type = PaletteAction; path = path_; } 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_) { type = BackgroundAction; path = path_; origin = origin_; condition = condition_; flag1 = flag1_; flag2 = flag2_; } Filename path; Common::Point origin; Common::String condition; Common::String flag1; Common::String flag2; }; class Overlay : public Action { public: Overlay(Filename path_, Common::Point origin_, Common::String flag_) { type = OverlayAction; path = path_; origin = origin_; flag = flag_; } Filename path; Common::Point origin; Common::String flag; }; class Escape : public Action { public: Escape() { type = EscapeAction; } }; class Save : public Action { public: Save() { type = SaveAction; } }; class Load : public Action { public: Load() { type = LoadAction; } }; class LoadCheckpoint : public Action { public: LoadCheckpoint() { type = LoadCheckpointAction; } }; class Quit : public Action { public: Quit() { type = QuitAction; } }; class Cutscene : public Action { public: Cutscene(Filename path_) { type = CutsceneAction; path = path_; } Filename path; }; class Sound : public Action { public: Sound(Filename path_) { type = SoundAction; path = path_; } Filename path; }; class Intro : public Action { public: Intro(Filename path_) { type = IntroAction; path = path_; } Filename path; }; class Play : public Action { public: Play(Filename path_, Common::Point origin_, Common::String condition_, Common::String flag_) { type = PlayAction; path = path_; origin = origin_; condition = condition_; flag = flag_; } Filename path; Common::Point origin; Common::String condition; Common::String flag; }; class Ambient : public Action { public: Ambient(Filename path_, Common::Point origin_, Common::String flag_) { type = AmbientAction; path = path_; origin = origin_; flag = flag_; fullscreen = false; frameNumber = 0; } Filename path; Common::Point origin; Common::String flag; uint32 frameNumber; bool fullscreen; }; class WalN : public Action { public: WalN(Common::String wn_, Filename path_, Common::Point origin_, Common::String condition_, Common::String flag_) { wn = wn_; type = WalNAction; path = path_; origin = origin_; condition = condition_; flag = flag_; } Common::String wn; Filename path; Common::Point origin; Common::String condition; Common::String flag; }; class Global : public Action { public: Global(Common::String variable_, Common::String command_) { type = GlobalAction; variable = variable_; command = command_; } Common::String variable; Common::String command; }; class TalkCommand { public: Common::String command; Common::String variable; Filename path; uint32 num; Common::Point position; }; typedef Common::Array TalkCommands; class Talk : public Action { public: Talk() { type = TalkAction; boxPos = Common::Point(0, 0); escape = false; active = true; } Talk(Talk *t) { *this = *t; } TalkCommands commands; bool active; bool escape; Common::Point introPos; Filename intro; Common::Point boxPos; Filename background; Common::Point backgroundPos; Common::Rect rect; Filename second; Common::Point secondPos; }; class ChangeLevel : public Action { public: ChangeLevel(Filename level_) { type = ChangeLevelAction; level = level_; } Filename level; }; enum LevelType { TransitionLevel, SceneLevel, ArcadeLevel, CodeLevel }; class Level { public: Level() { type = CodeLevel; musicRate = 22050; playMusicDuringIntro = false; musicStereo = false; } virtual ~Level() {} // needed to make Level polymorphic LevelType type; Filenames intros; Filename prefix; Filename levelIfWin; Filename levelIfLose; bool playMusicDuringIntro; Filename music; uint32 musicRate; bool musicStereo; }; class Scene : public Level { public: Scene() { type = SceneLevel; resolution = "640x480"; } Common::String resolution; Hotspots hots; }; class FrameInfo { public: FrameInfo(uint32 start_, uint32 length_) { start = start_; length = length_; } uint32 lastFrame() { return start + length; } uint32 start; uint32 length; }; enum ScriptMode { Interactive = 1, NonInteractive, }; class ScriptInfo { public: ScriptInfo(uint32 time_, uint32 mode_, uint32 actor_, uint32 cursor_) { time = time_; mode = ScriptMode(mode_); actor = actor_; cursor = cursor_; } uint32 time; ScriptMode mode; uint32 actor; uint32 cursor; }; typedef Common::List Script; class Shoot { public: Shoot() { destroyed = false; video = nullptr; timesToShoot = 1; pointsToShoot = 0; attackWeight = 0; paletteOffset = 0; paletteSize = 0; missedAnimation = 0; objKillsCount = 0; objMissesCount = 0; animation = "NONE"; explosionAnimation = ""; startFrame = 0; lastFrame = 1024; interactionFrame = 0; noEnemySound = false; enemySoundRate = 22050; isAnimal = false; nonHostile = false; playInteractionAudio = false; animalSound = ""; jumpToTimeAfterKilled = 0; warningVideoIdx = 0; waitForClickAfterInteraction = 0; direction = 0; } Common::String name; Filename animation; Filename startSound; Common::Point position; Common::Point deathPosition; uint32 timesToShoot; uint32 pointsToShoot; uint32 attackWeight; // Objectives uint32 objKillsCount; uint32 objMissesCount; // Palette uint32 paletteOffset; uint32 paletteSize; // Missed animation uint32 missedAnimation; // Sounds Filename enemySound; uint32 enemySoundRate; Filename deathSound; Filename hitSound; Filename animalSound; MVideo *video; Common::List attackFrames; Common::Array bodyFrames; Common::Array explosionFrames; uint32 startFrame; uint32 lastFrame; uint32 interactionFrame; Filename explosionAnimation; Filename additionalVideo; bool playInteractionAudio; bool destroyed; bool noEnemySound; // Soldier Boyz specific bool nonHostile; bool isAnimal; Common::String checkIfDestroyed; int jumpToTimeAfterKilled; char direction; uint32 waitForClickAfterInteraction; uint32 warningVideoIdx; }; typedef Common::Array Shoots; class ShootInfo { public: Common::String name; uint32 timestamp; }; typedef Common::List ShootSequence; class SegmentShoots { public: SegmentShoots() { segmentRepetition = 0; } ShootSequence shootSequence; uint32 segmentRepetition; }; typedef Common::Array SegmentShootsSequence; typedef Common::Array Sounds; enum SegmentType { Straight, Select3, TurnLeft3, Straight3, TurnRight3, Select2, TurnLeft2, TurnRight2, }; class Segment { public: Segment(byte type_, uint32 start_, uint32 size_) { type = type_; start = start_; size = size_; end = false; } byte type; uint32 start; uint32 size; bool end; }; typedef Common::Array Segments; class ArcadeTransition { public: ArcadeTransition(Filename video_, Filename palette_, Filename sound_, uint32 soundRate_, uint32 time_) { video = video_; palette = palette_; sound = sound_; soundRate = soundRate_; soundStereo = false; loseLevel = false; winLevel = false; selection = false; jumpToTime = 0; time = time_; } Filename video; Filename palette; Filename sound; uint32 soundRate; bool soundStereo; bool loseLevel; bool winLevel; bool selection; uint32 jumpToTime; uint32 time; }; typedef Common::List ArcadeTransitions; class ArcadeShooting : public Level { public: ArcadeShooting() { type = ArcadeLevel; health = 100; id = 0; objKillsRequired[0] = 0; objKillsRequired[1] = 0; objMissesAllowed[0] = 0; objMissesAllowed[1] = 0; mouseBox = Common::Rect(0, 0, 320, 200); frameDelay = 0; targetSoundRate = 0; // TODO: unused shootSoundRate = 0; enemySoundRate = 0; hitSoundRate = 0; additionalSoundRate = 0; noAmmoSoundRate = 0; } void clear() { nextLevelVideo.clear(); postStatsVideo.clear(); backgroundVideo.clear(); transitions.clear(); maskVideo.clear(); player.clear(); shoots.clear(); intros.clear(); defeatNoEnergyFirstVideo.clear(); defeatMissBossVideo.clear(); defeatNoEnergySecondVideo.clear(); missBoss1Video.clear(); missBoss2Video.clear(); hitBoss1Video.clear(); hitBoss2Video.clear(); beforeVideo.clear(); briefingVideo.clear(); additionalVideo.clear(); additionalSound.clear(); noAmmoSound.clear(); segments.clear(); script.clear(); objKillsRequired[0] = 0; objKillsRequired[1] = 0; objMissesAllowed[0] = 0; objMissesAllowed[1] = 0; mouseBox = Common::Rect(0, 0, 320, 200); anchor = Common::Point(0, 0); targetSoundRate = 0; shootSoundRate = 0; enemySoundRate = 0; hitSoundRate = 0; noAmmoSoundRate = 0; } uint32 id; uint32 frameDelay; Common::String mode; Common::Rect mouseBox; Common::Point anchor; ArcadeTransitions transitions; Segments segments; // Objectives uint32 objKillsRequired [2]; uint32 objMissesAllowed [2]; // Script Script script; // Videos Filename nextLevelVideo; Filename postStatsVideo; Filename defeatNoEnergyFirstVideo; Filename defeatNoEnergySecondVideo; Filename defeatMissBossVideo; Filename hitBoss1Video; Filename missBoss1Video; Filename hitBoss2Video; Filename missBoss2Video; Filename beforeVideo; Filename additionalVideo; Filename briefingVideo; Filename backgroundVideo; Filename backgroundPalette; Filename maskVideo; Filename player; int health; Shoots shoots; SegmentShootsSequence shootSequence; // Sounds Filename targetSound; uint32 targetSoundRate; Filename shootSound; uint32 shootSoundRate; Filename enemySound; uint32 enemySoundRate; Filename hitSound; uint32 hitSoundRate; Filename additionalSound; uint32 additionalSoundRate; Filename noAmmoSound; uint32 noAmmoSoundRate; }; class Transition : public Level { public: Transition(Common::String level) { type = TransitionLevel; nextLevel = level; levelEasy = ""; levelHard = ""; frameNumber = 0; frameImage = ""; } Transition(Common::String easy, Common::String hard) { type = TransitionLevel; levelEasy = easy; levelHard = hard; frameNumber = 0; frameImage = ""; } Common::String nextLevel; Common::String levelEasy; Common::String levelHard; Filename frameImage; uint32 frameNumber; }; class Code : public Level { public: Code(Common::String name_) { type = CodeLevel; name = name_; } Common::String name; }; typedef Common::HashMap Levels; extern Hotspots *g_parsedHots; extern ArcadeShooting *g_parsedArc; class ArcadeStats { public: ArcadeStats() { livesUsed = 0; shootsFired = 0; enemyHits = 0; enemyTargets = 0; targetsDestroyed = 0; targetsMissed = 0; friendliesEncountered = 0; infoReceived = 0; } uint32 livesUsed; uint32 shootsFired; uint32 enemyHits; uint32 enemyTargets; uint32 targetsDestroyed; uint32 targetsMissed; uint32 friendliesEncountered; uint32 infoReceived; }; } // End of namespace Hypno #endif