ScummVM API documentation
phoenixvr.h
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 modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (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, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef PHOENIXVR_H
23 #define PHOENIXVR_H
24 
25 #include "audio/mixer.h"
26 #include "common/error.h"
27 #include "common/fs.h"
28 #include "common/hash-str.h"
29 #include "common/keyboard.h"
30 #include "common/ptr.h"
31 #include "common/random.h"
32 #include "common/scummsys.h"
33 #include "common/serializer.h"
34 #include "common/system.h"
35 #include "common/util.h"
36 #include "engines/engine.h"
37 #include "engines/savestate.h"
38 #include "graphics/framelimiter.h"
39 #include "graphics/screen.h"
40 #include "video/video_decoder.h"
41 
42 #include "phoenixvr/angle.h"
43 #include "phoenixvr/detection.h"
44 #include "phoenixvr/region_set.h"
45 #include "phoenixvr/script.h"
46 #include "phoenixvr/variables.h"
47 #include "phoenixvr/vr.h"
48 
49 namespace Common {
50 struct Event;
51 }
52 
53 namespace Graphics {
54 class Font;
55 }
56 
57 namespace Video {
58 class Subtitles;
59 }
60 
61 namespace PhoenixVR {
62 
63 class ARN;
64 struct PhoenixVRGameDescription;
65 struct GameState;
66 
67 enum struct RolloverType : uint8 {
68  Default,
69  Malette,
70  Secretaire
71 };
72 
73 class PhoenixVREngine : public Engine {
74  friend class ARN;
75 
76 private:
77  static constexpr uint kFPSLimit = 60;
78  static constexpr float kMaxTick = 4.0f / kFPSLimit;
79 
80  Graphics::FrameLimiter _frameLimiter;
81  Graphics::Screen *_screen = nullptr;
82  Common::Point _screenCenter;
83  const ADGameDescription *_gameDescription;
84  Common::RandomSource _randomSource;
85  Graphics::PixelFormat _pixelFormat;
86  Graphics::PixelFormat _rgb565;
87  Graphics::ManagedSurface _thumbnail;
89 
90  // Engine APIs
91  Common::Error run() override;
92 
93 public:
94  PhoenixVREngine(OSystem *syst, const ADGameDescription *gameDesc);
95  ~PhoenixVREngine() override;
96 
97  uint32 getFeatures() const;
98 
99  int version() const;
100 
101  bool gameIdMatches(const char *gameId) const;
102 
106  uint32 getRandomNumber(uint maxNum) {
107  return _randomSource.getRandomNumber(maxNum);
108  }
109 
110  bool hasFeature(EngineFeature f) const override {
111  return (f == kSupportsLoadingDuringRuntime) ||
112  (f == kSupportsSavingDuringRuntime) ||
113  (f == kSupportsSubtitleOptions) ||
114  (f == kSupportsReturnToLauncher);
115  };
116 
117  // disable autosave
118  int getAutosaveSlot() const override { return -1; }
119 
120  bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override {
121  return true;
122  }
123  bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override {
124  return false;
125  }
126 
127  void syncSoundSettings() override;
128 
129  // Script API
130  void setNextScript(const Common::String &path);
131  bool goToWarp(const Common::String &warp, bool savePrev = false);
132  void goToLevel(const Common::String &name);
133  void returnToWarp();
134  void loadCursor(int idx, const Common::String &path, int offsetX, int offsetY);
135  void setCursorDefault(int idx, const Common::String &path);
136  void setCursorDefault(int idx, int cursorIdx);
137  void setCursor(const Common::String &path, const Common::String &warp, int idx);
138  void hideCursor(const Common::String &warp, int idx);
139 
140  void playSound(const Common::String &sound, Audio::Mixer::SoundType type, uint8 volume, int loops, bool spatial = false, float angle = 0);
141  void playRandomSound(const Common::String &sound, Audio::Mixer::SoundType type, uint8 volume, int probability, int loops);
142  void stopSound(const Common::String &sound);
143  void stopAllSounds();
144  void playMovie(const Common::String &movie);
145 
146  void declareVariable(const Common::String &name);
147  bool hasVariable(const Common::String &name) const;
148  void setVariable(const Common::String &name, int value);
149  int getVariable(const Common::String &name) const;
150 
151  void executeTest(int idx);
152  void scheduleTest(int idx);
153  void end();
154  void wait(float seconds);
155  void until(const Common::String &var, int value);
156 
157  const Region *getRegion(int idx) const;
158 
159  void resetLockKey();
160  void lockKey(int idx, const Common::String &warp);
161  void startTimer(float seconds, bool showTimer);
162  void startTimer(float seconds, bool showTimer, const Common::String &warp);
163  void pauseTimer(bool pause, bool deactivate);
164  void killTimer();
165  void playAnimation(const Common::String &name, const Common::String &var, int varValue, float speed);
166  void stopAnimation(const Common::String &name);
167  void setZoom(float fov) {
168  _fov = fov;
169  }
170  void interpolateAngle(float x, float y, float speed, float zoom);
171  void fade(int start, int stop, int speed);
172  void transFade(int speed);
173 
174  void setXMax(float max) {
175  _angleY.setRange(-max, max);
176  }
177  void limitView(float min, float max) {
178  _angleY.setRange(kPi2 - max, kPi2 - min);
179  }
180 
181  // this is set to large values and effectively useless
182  void setYMax(float min, float max) {
183  _angleX.setRange(min, max);
184  }
185 
186  void resetYMax() {
187  _angleX.resetRange();
188  }
189 
190  void setAngle(float x, float y) {
191  _angleX.set(y);
192  _angleY.set(kPi2 - x);
193  }
194 
195  void setNord(float a) {
196  _angleX.add(a);
197  }
198 
199  bool testSaveSlot(int idx) const;
200  Common::Error loadGameStream(Common::SeekableReadStream *stream) override;
201  Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override;
202  void drawSlot(int idx, int face, int x, int y);
203  void drawSaveCard(int idx);
204  void loadSaveCardSprite(int idx, const Common::String &name);
205  void captureContext();
206 
207  void setContextLabel(const Common::String &contextLabel) {
208  _contextLabel = contextLabel;
209  }
210  bool enterScript();
211  bool isLoading() const { return !_loadedState.empty(); }
212 
213  bool wasRestarted() const { return _restarted; }
214  bool wasLoaded() const { return _loaded; }
215  uint currentLevel() const;
216 
217  void saveVariables();
218  void loadVariables();
219 
220  void rollover(int textId, RolloverType type);
221  void clearText();
222  void showWaves();
223  void restart();
224  bool setNextLevel();
225 
226  void setGlobalVolume(int vol);
227  void setGlobalPan(int pan);
228  void drawArchiveImage(const Common::String &image, int x, int y);
229  void drawArchiveText(int textId, const Common::Rect &dstRect, int size, bool bold, uint16 color);
230  void clearArchiveText(const Common::Rect &dstRect);
231  void showImageOverlay(const Common::String &image, int x, int y);
232  void stopImageOverlay();
233  void updateStage();
234  void startCible(const Common::String &name, int periodSeconds, const Common::Array<int> &bounds);
235  void stopCible();
236  void testCible(const Common::String &insideVar, const Common::String &outsideVar);
237 
238  int retrieveState(int index) const;
239  void storeState(int index, int value);
240 
241  void spriteLoad(const Common::String &name, const Common::String &path);
242  void spriteScreen(int index, const Common::String &name, int x, int y);
243  void setLens(int index, const Common::String &name, float size);
244  void resetLensflare();
245  void setLensflare(float x, float y);
246  void startLight(const Common::String &path);
247  void stopLight();
248 
249 private:
250  struct ArchiveImage {
251  Common::String image;
252  Common::Point pos;
253  };
254 
255  struct TextState {
256  TextState() : textId(-1), size(0), bold(false), color(0) {}
257  TextState(int textId_, const Common::Rect &rect_, int size_, bool bold_, uint16 color_) : textId(textId_), rect(rect_), size(size_), bold(bold_), color(color_) {}
258 
259  int textId;
260  Common::Rect rect;
261  int size;
262  bool bold;
263  uint16 color;
264  };
265 
266  struct Level {
267  Common::String path;
268  Common::String name;
269  };
270 
271  struct CachedCursor {
273  Common::Point offset;
274  };
275 
276  static Common::String removeDrive(const Common::String &path);
277  Common::SeekableReadStream *open(const Common::String &name, Common::String *origName = nullptr);
278  Common::SeekableReadStream *tryOpen(const Common::Path &name, Common::String *origName);
279 
280  Graphics::ManagedSurface *loadSurface(const Common::String &path);
281  CachedCursor *loadCursor(const Common::String &path, int offsetX = -1, int offsetY = -1);
282  PointF currentVRPos() const {
283  return RectF::transform(_angleX.angle(), _angleY.angle(), _fov);
284  }
285  void tick(float dt);
286  void tickTimer(float dt);
287  void loadNextScript();
288  const Graphics::Surface *findArchiveImage(const Common::String &image) const;
289  void renderVR(float dt);
290  void renderArchiveImages();
291  void renderArchiveTexts();
292  void paintText(const TextState &textState);
293  void renderImageOverlay();
294  void renderTimer();
295  void renderFade(int color);
296  void renderSprites();
297  void renderLensflare();
298  void renderLightEffect();
299  void resetState();
300  const Graphics::Font *getFont(int size, bool bold) const;
301  Common::Path getSubtitlePath(const Common::String &path) const;
302  Common::SharedPtr<Video::Subtitles> loadSubtitles(const Common::String &path) const;
303  void setupSubtitles(Video::Subtitles &subtitles) const;
304  void drawAudioSubtitles();
305 
306  void processGenericEvents(const Common::Event &event);
307  void pauseEngineIntern(bool pause) override;
308  Common::String getLevelLabel(const Common::String &script) const;
309  Common::String getLevelScript(const Level &level) const;
310  void saveThumbnail();
311 
312 private:
313  bool _hasFocus = true;
314  Common::Point _mousePos, _mouseRel;
315  Common::String _nextScript;
316  Common::Path _currentScriptPath;
317  int _warpIdx = -1;
318  int _vrWarpIdx = -1; // temporary v2 hack
319  Script::ConstWarpPtr _warp;
320  int _nextWarp = -1;
321  int _prevWarp = -1;
322  Common::List<int> _prevWarpHistory; // V2 stack of warps
323  int _hoverIndex = -1;
324  int _messengerInventoryHover = -1;
325  int _nextTest = -1;
326 
327  struct KeyCodeHash : public Common::UnaryFunction<Common::KeyCode, uint> {
328  uint operator()(Common::KeyCode val) const { return static_cast<uint>(val); }
329  };
330 
332 
333  Variables _variables;
334  Common::Array<int> _state;
335 
336  struct Sound {
337  Audio::SoundHandle handle;
338  bool spatial;
339  float angle;
340  uint8 volume;
341  int loops;
343  };
345 
346  struct RandomSound {
347  Common::String sound;
349  int volume;
350  int probability;
351  int loops;
352  };
353  Common::Array<RandomSound> _randomSounds;
354 
356 
358 
359  struct PreloadedCursor {
360  Common::String path;
361  };
362  Common::Array<PreloadedCursor> _loadedCursors;
363 
366  struct Sprite {
367  Common::String name;
368  int x = 0;
369  int y = 0;
370  };
371  Common::Array<Sprite> _sprites;
372  struct Lens {
373  Common::String name;
374  float scale = 0.0f;
375  };
376  Common::Array<Lens> _lenses;
377  bool _lensflareActive = false;
378  float _lensflareX = 0.0f;
379  float _lensflareY = 0.0f;
380  Common::Array<uint32> _lightEffect;
381 
382  struct WarpCursorState {
383  Common::String name;
384  bool hidden = false;
385  };
387  Common::String _defaultCursor[2];
388  Common::String _currentMusic;
389  int _currentMusicVolume = 0;
390  int _globalPan = 128;
391 
392  VR _vr;
393  float _fov;
394  AngleX _angleX;
395  AngleY _angleY;
396  Audio::Mixer *_mixer;
397  bool _showRegions = false;
398 
399  static constexpr byte kPaused = 2;
400  static constexpr byte kActive = 4;
401  byte _timerFlags = 0;
402  bool _showTimer = false;
403  float _timer = 0, _initialTimer = 0;
404  Common::String _timerWarp;
405 
406  Common::String _contextScript;
407  Common::String _contextLabel;
408  Common::Array<byte> _capturedState;
409  Common::Array<byte> _loadedState;
410 
412 
413  static const int kFontSizeCount = 6;
414  Common::ScopedPtr<Graphics::Font> _regularFonts[kFontSizeCount];
415  Common::ScopedPtr<Graphics::Font> _boldFonts[kFontSizeCount];
416 
417  TextState _rolloverText;
419  Common::Point _imageOverlayPos;
420  Common::Array<ArchiveImage> _archiveImages;
421  Common::Array<TextState> _archiveTexts;
422  bool _cibleActive = false;
423  uint32 _cibleStartMillis = 0;
424  int _ciblePeriodSeconds = 0;
425  Common::Array<int> _cibleBounds;
426 
427  Common::Array<Level> _levels;
428  uint _nextLevel = 0;
429 
430  bool _restarted = false;
431  bool _loaded = false;
432 
433  Video::VideoDecoder *_currentDecoder = nullptr;
434 };
435 
436 extern PhoenixVREngine *g_engine;
437 #define SHOULD_QUIT ::PhoenixVR::g_engine->shouldQuit()
438 
439 } // End of namespace PhoenixVR
440 
441 #endif // PHOENIXVR_H
Definition: managed_surface.h:51
bool hasFeature(EngineFeature f) const override
Definition: phoenixvr.h:110
Definition: framelimiter.h:40
Definition: str.h:59
Definition: font.h:83
Definition: surface.h:67
bool saveThumbnail(Common::WriteStream &out)
Definition: arn.h:32
EngineFeature
Definition: engine.h:282
Definition: stream.h:77
Definition: error.h:81
bool canLoadGameStateCurrently(Common::U32String *msg=nullptr) override
Definition: phoenixvr.h:120
bool canSaveGameStateCurrently(Common::U32String *msg=nullptr) override
Definition: phoenixvr.h:123
Definition: pixelformat.h:138
Definition: advancedDetector.h:164
Definition: random.h:44
Definition: angle.h:114
Definition: phoenixvr.h:73
Definition: rect.h:536
Definition: path.h:52
uint getRandomNumber(uint max)
Definition: stream.h:745
Definition: screen.h:47
Engine * g_engine
Definition: ptr.h:572
Definition: region_set.h:34
Definition: subtitles.h:78
Definition: mixer.h:49
SoundType
Definition: mixer.h:73
Definition: mixer.h:70
Definition: angle.h:110
uint32 getRandomNumber(uint maxNum)
Definition: phoenixvr.h:106
Definition: angle.h:33
Definition: ustr.h:57
Definition: video_decoder.h:53
Definition: events.h:218
Definition: algorithm.h:29
Definition: formatinfo.h:28
Definition: rect.h:144
Definition: vr.h:37
int getAutosaveSlot() const override
Definition: phoenixvr.h:118
Definition: variables.h:31
Definition: system.h:166
Definition: animation.h:37
Definition: engine.h:149
Definition: hash-str.h:49
Definition: hash-str.h:45
Definition: func.h:43