1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  * Copyright 2020 Google
22  *
23  */
24 #ifndef HADESCH_HADESCH_H
25 #define HADESCH_HADESCH_H
26 
27 #include "common/random.h"
28 #include "common/stream.h"
29 #include "common/savefile.h"
30 #include "common/list.h"
31 
32 #include "engines/engine.h"
33 #include "engines/savestate.h"
34 
35 #include "gui/debugger.h"
36 #include "graphics/cursor.h"
37 #include "hadesch/pod_file.h"
38 #include "hadesch/video.h"
39 #include "hadesch/enums.h"
40 #include "hadesch/event.h"
41 #include "hadesch/herobelt.h"
42 #include "hadesch/persistent.h"
43 #include "common/translation.h"
44 
45 struct ADGameDescription;
46 
47 namespace Common {
48 class SeekableReadStream;
49 class PEResources;
50 }
51 
52 namespace Graphics {
53 struct WinCursorGroup;
54 class MacCursor;
55 }
56 
57 namespace Hadesch {
58 
59 class VideoRoom;
60 
61 class Handler {
62 public:
63 	virtual void handleClick(const Common::String &name) = 0;
handleAbsoluteClick(Common::Point pnt)64 	virtual void handleAbsoluteClick(Common::Point pnt) {}
handleClickWithItem(const Common::String & name,InventoryItem item)65 	virtual bool handleClickWithItem(const Common::String &name, InventoryItem item) {
66 		return false;
67 	}
68 	virtual void handleEvent(int eventId) = 0;
handleMouseOver(const Common::String & name)69 	virtual void handleMouseOver(const Common::String &name) {}
handleMouseOut(const Common::String & name)70 	virtual void handleMouseOut(const Common::String &name) {}
frameCallback()71 	virtual void frameCallback() {}
handleKeypress(uint32 ucode)72 	virtual void handleKeypress(uint32 ucode) {}
73 	virtual void prepareRoom() = 0;
handleCheat(const Common::String & cheat)74 	virtual bool handleCheat(const Common::String &cheat) {
75 		return false;
76 	}
handleUnclick(const Common::String & name,Common::Point pnt)77 	virtual void handleUnclick(const Common::String &name, Common::Point pnt) {}
~Handler()78 	virtual ~Handler() {}
79 };
80 
81 Common::SharedPtr<Hadesch::Handler> makeOlympusHandler();
82 Common::SharedPtr<Hadesch::Handler> makeWallOfFameHandler();
83 Common::SharedPtr<Hadesch::Handler> makeArgoHandler();
84 Common::SharedPtr<Hadesch::Handler> makeCreteHandler();
85 Common::SharedPtr<Hadesch::Handler> makeMinosHandler();
86 Common::SharedPtr<Hadesch::Handler> makeDaedalusHandler();
87 Common::SharedPtr<Hadesch::Handler> makeSeriphosHandler();
88 Common::SharedPtr<Hadesch::Handler> makeMedIsleHandler();
89 Common::SharedPtr<Hadesch::Handler> makeTroyHandler();
90 Common::SharedPtr<Hadesch::Handler> makeMinotaurHandler();
91 Common::SharedPtr<Hadesch::Handler> makeQuizHandler();
92 Common::SharedPtr<Hadesch::Handler> makeCatacombsHandler();
93 Common::SharedPtr<Hadesch::Handler> makePriamHandler();
94 Common::SharedPtr<Hadesch::Handler> makeAthenaHandler();
95 Common::SharedPtr<Hadesch::Handler> makeVolcanoHandler();
96 Common::SharedPtr<Hadesch::Handler> makeRiverStyxHandler();
97 Common::SharedPtr<Hadesch::Handler> makeHadesThroneHandler();
98 Common::SharedPtr<Hadesch::Handler> makeCreditsHandler(bool inOptions);
99 Common::SharedPtr<Hadesch::Handler> makeIntroHandler();
100 Common::SharedPtr<Hadesch::Handler> makeFerryHandler();
101 Common::SharedPtr<Hadesch::Handler> makeOptionsHandler();
102 Common::SharedPtr<Hadesch::Handler> makeMonsterHandler();
103 Common::SharedPtr<Hadesch::Handler> makeMedusaHandler();
104 Common::SharedPtr<Hadesch::Handler> makeTrojanHandler();
105 
106 class HadeschEngine : public Engine, Common::NonCopyable {
107 public:
108 	HadeschEngine(OSystem *syst, const ADGameDescription *desc);
109 	~HadeschEngine() override;
110 
111 	Common::Error run() override;
112 
113 	bool hasFeature(EngineFeature f) const override;
114 
canLoadGameStateCurrently()115 	bool canLoadGameStateCurrently() override { return true; }
canSaveGameStateCurrently()116 	bool canSaveGameStateCurrently() override { return _persistent._currentRoomId != 0; }
117 	Common::Error loadGameStream(Common::SeekableReadStream *stream) override;
118 	Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override;
119 
120 	Common::SeekableReadStream *openFile(const Common::String &name, bool addCurrentPath);
121 
122 	Common::RandomSource &getRnd();
123 
124 	const Common::String &getCDScenesPath() const;
125 
126 	Common::SharedPtr<VideoRoom> getVideoRoom();
127 
moveToRoom(RoomId id)128 	void moveToRoom(RoomId id) {
129 		_nextRoom.push_back(id);
130 		_heroBelt->clearHold();
131 	}
132 
133 	void handleEvent(EventHandlerWrapper event);
getCurrentTime()134 	int32 getCurrentTime() {
135 		return _currentTime;
136 	}
137 	Common::Point getMousePos();
138 
139 	void addTimer(EventHandlerWrapper event, int period, int repeat = 1);
140 	void addSkippableTimer(EventHandlerWrapper event, int period, int repeat = 1);
141 	void cancelTimer(int eventId);
142 
getWdPodFile()143 	Common::SharedPtr<PodFile> getWdPodFile() {
144 		return _wdPodFile;
145 	}
146 
getPreviousRoomId()147 	RoomId getPreviousRoomId() const {
148 		return _persistent._previousRoomId;
149 	}
150 
isRoomVisited(RoomId id)151 	bool isRoomVisited(RoomId id) const {
152 		return _persistent._roomVisited[id];
153 	}
154 
getPersistent()155 	Persistent *getPersistent() {
156 		return &_persistent;
157 	}
158 
159 	Common::SharedPtr<Handler> getCurrentHandler();
160 
getHeroBelt()161 	Common::SharedPtr<HeroBelt> getHeroBelt() {
162 		return _heroBelt;
163 	}
164 
165 	int firstAvailableSlot();
166 
167 	void newGame();
168 	void enterOptions();
169 	void resetOptionsRoom();
170 	void exitOptions();
171 	void enterOptionsCredits();
172 	void quit();
173 	bool hasAnySaves();
174 
175 	Common::Array<HadeschSaveDescriptor> getHadeschSavesList();
176 	void deleteSave(int slot);
177 	int genSubtitleID();
178 	uint32 getSubtitleDelayPerChar() const;
179 	void wrapSubtitles(const Common::U32String &str, Common::Array<Common::U32String> &lines);
180 	Common::U32String translate(const Common::String &str);
181 
182 private:
183 	void addTimer(EventHandlerWrapper event, int32 start_time, int period,
184 		      int repeat, bool skippable);
185 	void moveToRoomReal(RoomId id);
186 	void setVideoRoom(Common::SharedPtr<VideoRoom> scene,
187 			  Common::SharedPtr<Handler> handler,
188 			  RoomId roomId);
189 	Common::ErrorCode loadCursors();
190 	bool handleGenericCheat(const Common::String &cheat);
191 	Common::ErrorCode loadWindowsCursors(Common::PEResources &exe);
192 
193 	struct Timer {
194 		int32 next_time;
195 		int32 period;
196 		int32 period_count;
197 		EventHandlerWrapper event;
198 		bool skippable;
199 	};
200 	const ADGameDescription *_desc;
201 
202 	Common::RandomSource _rnd;
203 
204 	Common::String _cdScenesPath;
205 
206 	Common::SharedPtr<VideoRoom> _sceneVideoRoom;
207 	Common::SharedPtr<Handler> _sceneHandler;
208 	Common::SharedPtr<VideoRoom> _optionsRoom;
209 	Common::SharedPtr<Handler> _optionsHandler;
210 	bool _isInOptions;
211 	uint32 _optionsEnterTime;
212 	uint32 _sceneStartTime;
213 	int32 _currentTime;
214 	Common::Array<Graphics::Cursor *> _cursors;
215 	Common::List<Timer> _sceneTimers;
216 	Common::SharedPtr<PodFile> _wdPodFile;
217 	Common::SharedPtr<HeroBelt> _heroBelt;
218 	Common::String _cheat;
219 	Common::SharedPtr<GfxContext8Bit> _gfxContext;
220 	bool _cheatsEnabled;
221 	Common::Point _mousePos;
222 
223 	Persistent _persistent;
224 	Common::Array<RoomId> _nextRoom;
225 	bool _isRestoring;
226   	bool _isQuitting;
227 	int _subtitleID;
228 	int _subtitleDelayPerChar;
229 
230 #ifdef USE_TRANSLATION
231 	Common::TranslationManager *_transMan;
232 #endif
233 
234 	// For freeing purposes
235 	Common::Array <Graphics::MacCursor *> _macCursors;
236 	Common::Array <Graphics::WinCursorGroup *> _winCursors;
237 };
238 
239 extern HadeschEngine *g_vm;
240 
241 } // End of namespace Hadesch
242 
243 #endif
244