ScummVM API documentation
pelrock.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 PELROCK_H
23 #define PELROCK_H
24 
25 #include "common/random.h"
26 #include "common/serializer.h"
27 
28 #include "graphics/managed_surface.h"
29 
30 #include "pelrock/detection.h"
31 #include "pelrock/types.h"
32 
33 namespace Graphics {
34 class Screen;
35 }
36 
37 namespace Pelrock {
38 
39 struct PelrockGameDescription;
40 
41 class ChronoManager;
42 class DialogManager;
43 class DoubleSmallFont;
44 class GraphicsManager;
45 class LargeFont;
46 class MenuManager;
47 class PelrockEventManager;
48 class RoomManager;
49 class ResourceManager;
50 class SmallFont;
51 class SoundManager;
52 class VideoManager;
53 
54 
55 class PelrockEngine : public Engine {
56 private:
57  const ADGameDescription *_gameDescription;
58  Common::RandomSource _randomSource;
59  VideoManager *_videoManager = nullptr;
60  SoundManager *_sound = nullptr;
61  MenuManager *_menu = nullptr;
62 
63  void init();
64  void loadInventoryArrows();
65  void loadAnims();
66 
67  /*
68  Walking alforithm
69  */
70  void walkTo(int x, int y);
71  void walkAndAction(HotSpot *hotspot, VerbIcon action);
72  AlfredDirection calculateAlfredsDirection(HotSpot *hotspot);
73 
74  Common::Array<VerbIcon> availableActions(HotSpot *hotspot);
75  VerbIcon isActionUnder(int x, int y);
76  bool isAlfredUnder(int x, int y);
77  int isHotspotUnder(int x, int y);
78  Exit *isExitUnder(int x, int y);
79  bool isSpriteUnder(Sprite *sprite, int x, int y);
80 
81  void showActionBalloon(int posx, int posy, int curFrame);
82 
83  int getScrollPositionForItem(int item);
84 
85  void checkMouse();
86  void updateAnimations();
87  void renderOverlay(int overlayMode);
88 
89  void doAction(VerbIcon action, HotSpot *hotspot);
90  void talkTo(HotSpot *hotspot);
91  void lookAt(HotSpot *hotspot);
92 
93  void chooseAlfredStateAndDraw();
94  void exitTriggers(Pelrock::Exit *exit);
95  void drawIdleFrame();
96  void drawAlfred(byte *buf);
97  void drawNextFrame(Sprite *animSet);
98  void animateTalkingNPC(Sprite *animSet);
99  void pickupIconFlash();
100 
101  void playSoundIfNeeded();
102 
103  void showInventoryOverlay();
104 
105  void checkMouseOverInventoryOverlay(int x);
106  int checkMouseClickInventoryOverlay(int x);
107 
108  void gameLoop();
109  void firstScene();
110  void computerLoop();
111  void extraScreenLoop();
112  void walkLoop(int16 x, int16 y, AlfredDirection direction);
113 
114  void checkMouseHover();
115  void checkMouseClick(int x, int y);
116  void checkLongMouseClick(int x, int y);
117 
118  // walking
119  int _currentStep = 0;
120  PathContext _currentContext = {nullptr, nullptr, 0, 0, 0};
121 
122  ActionPopupState _actionPopupState;
123  InventoryOverlayState _inventoryOverlayState;
124 
125 
126  HotSpot *_currentHotspot = nullptr;
127  int _newItem = -1;
128 
129  Common::Point _curWalkTarget;
130  QueuedAction _queuedAction = {NO_ACTION, -1, false, false};
131 
132  bool shouldPlayIntro = false;
133  bool gameInitialized = false;
134  bool screenReady = false;
135 
136  Common::String _hoveredMapLocation = "";
137  byte *_alfredSprite = nullptr;
138 
139  int _numPressedX = 0;
140 
141  bool _mouseDisabled = false;
142 
143  // Original timing: counter-based render-skip to replicate process_game_state(N) slowdown.
144  // _renderSkipAmount = N means skip N ticks, then render 1 → (1+N) ticks per render.
145  int _renderSkipAmount = 0;
146  int _renderSkipCounter = 0;
147 
148  int _fightFrameCounter = 0;
149  int _fightSorcererSpriteIdx = -1;
150  bool _fightSorcererAppeared = false;
151  bool _fightSpellCast = false;
152  int _fightSpellFrameCounter = 0;
153  bool _fightInBlockingAnim = false;
154  bool _disableAmbientSounds = false;
155  bool _isDogPeeing = false;
156  bool _disableAction = false;
157  bool _roomChangedDuringAnimation = false;
158 
159 protected:
160  // Engine APIs
161  Common::Error run() override;
162 
163 public:
164  GraphicsManager *_graphics = nullptr;
165  Graphics::Screen *_screen = nullptr;
166  ResourceManager *_res = nullptr;
167  RoomManager *_room = nullptr;
168  ChronoManager *_chrono = nullptr;
169  PelrockEventManager *_events = nullptr;
170  DialogManager *_dialog = nullptr;
171  AlfredState _alfredState;
172  ShakeEffectState _shakeEffectState;
173  byte _npcTalkSpeedByte = 0;
174  Graphics::ManagedSurface _compositeBuffer; // Working composition buffer
175  Graphics::ManagedSurface _currentBackground; // Clean background - NEVER modified
176  Graphics::ManagedSurface _bgScreen;
177  Graphics::Surface _saveThumbnail;
178 
179  GameStateData *_state = new GameStateData();
180  bool _autoSaveAllowed = true;
181  SmallFont *_smallFont = nullptr;
182  LargeFont *_largeFont = nullptr;
183  DoubleSmallFont *_doubleSmallFont = nullptr;
184 
185 public:
186  PelrockEngine(OSystem *syst, const ADGameDescription *gameDesc);
187  ~PelrockEngine() override;
188 
189  uint32 getFeatures() const;
190 
194  Common::String getGameId() const;
195 
199  uint32 getRandomNumber(uint maxNum) {
200  return _randomSource.getRandomNumber(maxNum);
201  }
202 
207  bool isAlternateTiming() const;
208 
209  bool isScreenSaverDisabled() const;
210 
211  bool hasFeature(EngineFeature f) const override {
212  return (f == kSupportsLoadingDuringRuntime) ||
213  (f == kSupportsSavingDuringRuntime) ||
214  (f == kSupportsReturnToLauncher);
215  };
216 
217  bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override {
218  return true;
219  }
220  bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override {
221  return true;
222  }
223 
224  bool canSaveAutosaveCurrently() override {
225  return _autoSaveAllowed;
226  }
227 
232  Common::Error syncGame(Common::Serializer &s);
233 
234  void loadGame(SaveGameData &saveGame);
235 
236  SaveGameData *createSaveGameData() const;
237 
238  Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override {
239  Common::Serializer s(nullptr, stream);
240  return syncGame(s);
241  }
243  Common::Serializer s(stream, nullptr);
244  return syncGame(s);
245  }
246 
247  void setScreen(int s);
248  void setScreenAndPrepare(int s, AlfredDirection dir);
249  void loadExtraScreenAndPresent(int screenIndex);
250  void waitForSpecialAnimation();
251  bool renderScene(int overlayMode = OVERLAY_NONE);
252  void mouseHoverForMap();
253  void frameTriggers();
254  void maybeHaveDogPee();
255  void maybePlayPostIntro();
256  void maybeShakeEffect();
257  void resetPasserByAnim(int startX, int startY, Sprite *sprite);
258  void handleFightRoomFrame();
259  void paintDebugLayer();
260 
261  void maybeUpdatePasserByAnim(uint32 frameCount);
262  void changeCursor(Cursor cursor);
263 
264  void travelToEgypt();
265 
266  bool shouldSkipFrame();
267 
268  // Actions
269  void doExtraActions(int roomNumber);
270  void pyramidCollapse();
271  void endingScene();
272  void credits();
273  void initGodsSequences(int roomNumber);
274  void addInventoryItem(int item);
275  void buyFromStore(HotSpot *hotspot, int stickerId);
276  void performActionTrigger(uint16 actionTrigger);
277  void dialogActionTrigger(uint16 actionTrigger, byte room, byte rootIndex);
278 
279  void turnLightsOff();
280 
281  void givenItems();
282  void advanceQuotesConversation(byte rootIndex, byte room);
283  void toJail();
284 
285  void executeAction(VerbIcon action, HotSpot *hotspot);
286  void openRoomDrawer(HotSpot *hotspot);
287  void closeRoomDrawer(HotSpot *hotspot);
288  void openClosedDrawer(HotSpot *hotspot);
289  void openRoomDoor(HotSpot *hotspot);
290  void closeRoomDoor(HotSpot *hotspot);
291  void pickUpAndDisable(HotSpot *hotspot);
292  void grabKetchup(HotSpot *hotspot);
293  void grabMustard(HotSpot *hotspot);
294  void grabSpicey(HotSpot *hotspot);
295  void openKitchenDoor(HotSpot *hotspot);
296  void closeKitchenDoor(HotSpot *HotSpot);
297  void openKitchenDrawer(HotSpot *hotspot);
298  void openKitchenDoorFromInside(HotSpot *hotspot);
299  void useSpicySauceWithBurger(int inventoryObject, HotSpot *hotspot);
300  void openShopDoor(HotSpot *hotspot);
301  void closeShopDoor(HotSpot *hotspot);
302  void openLamppost(HotSpot *hotspot);
303  void openDoor(HotSpot *hotspot, int doorIndex, int sticker, bool masculine, bool stayClosed);
304  void closeDoor(HotSpot *hotspot, int doorIndex, int sticker, bool masculine, bool stayOpen);
305  void pickUpPhoto(HotSpot *hotspot);
306  void pickYellowBook(HotSpot *hotspot);
307  void pickUpBrick(HotSpot *hotspot);
308  void openIceCreamShopDoor(HotSpot *hotspot);
309  void pickupGarbageCan(HotSpot *hotspot);
310  void noOpAction(HotSpot *hotspot);
311  void noOpItem(int item, HotSpot *hotspot);
312  void useOnAlfred(int inventoryObject);
313  void sayRandomIncorrectResponse();
314  void chooseCorrectDoor();
315  void useCardWithATM(int inventoryObject, HotSpot *hotspot);
316  void useBrickWithWindow(int inventoryObject, HotSpot *hotspot);
317  void moveCable(HotSpot *hotspot);
318  void useBrickWithShopWindow(int inventoryObject, HotSpot *hotspot);
319  void pickGuitar(HotSpot *hotspot);
320  void pickFish(HotSpot *hotspot);
321  void pickTeddyBear(HotSpot *hotspot);
322  void pickDiscs(HotSpot *hotspot);
323  void pickMonkeyBrain(HotSpot *hotspot);
324  void pickBooks(HotSpot *hotspot);
325  void pickPalette(HotSpot *hotspot);
326  void pickCandy(HotSpot *hotspot);
327  void pickConch(HotSpot *hotspot);
328  void pickHat(HotSpot *hotspot);
329  void pickCord(HotSpot *hotspot);
330  void pickAmulet(HotSpot *hotspot);
331  void openPlug(HotSpot *hotspot);
332  void useCordWithPlug(int inventoryObject, HotSpot *hotspot);
333  void pickCables(HotSpot *hotspot);
334  void showIdToGuard(int inventoryObject, HotSpot *hotspot);
335  void unlockMuseum();
336  void giveMoneyToGuard(int inventoryObject, HotSpot *hotspot);
337  void openMuseumDoor(HotSpot *hotspot);
338  void closeMuseumDoor(HotSpot *hotspot);
339  void pickupFruit(HotSpot *hotspot);
340  void useAmuletWithStatue(int inventoryObject, HotSpot *hotspot);
341  void useSecretCodeWithStatue(int inventoryObject, HotSpot *hotspot);
342  void pickUpLetter(HotSpot *hotspot);
343  void openLibraryOutdoorsDoor(HotSpot *hotspot);
344  void closeLibraryOutdoorsDoor(HotSpot *hotspot);
345  void openLibraryIndoorsDoor(HotSpot *hotspot);
346  void closeLibraryIndoorsDoor(HotSpot *hotspot);
347  void pickBooksFromShelf1(HotSpot *hotspot);
348  void pickBooksFromShelf2(HotSpot *hotspot);
349  void pickBooksFromShelf3(HotSpot *hotspot);
350  void giveSecretCodeToLibrarian(int inventoryObject, HotSpot *hotspot);
351  void useBrickWithLibrarian(int inventoryObject, HotSpot *hotspot);
352  void openNewspaperDoor(HotSpot *hotspot);
353  void closeNewspaperDoor(HotSpot *hotspot);
354  void openNewspaperBossDor(HotSpot *hotspot);
355  void closeNewspaperBossDoor(HotSpot *hotspot);
356  void openTravelAgencyDoor(HotSpot *hotspot);
357  void closeTravelAgencyDoor(HotSpot *hotspot);
358  void usePumpkinWithRiver(int inventoryObject, HotSpot *hotspot);
359  void playAlfredSpecialAnim(int anim, bool reverse = false);
360  void waitForSoundEnd(int channel = 0);
361  void pickupSunflower(HotSpot *hotspot);
362  void checkIngredients();
363  void pickUpBook(int i);
364  void pickUpChainsaw(HotSpot *hotspot);
365  void pickUpSpellbook(HotSpot *hotspot);
366  void pickUpBoot(HotSpot *hotspot);
367  void pickupCondoms(HotSpot *hotspot);
368  void openEgyptMuseumDoor(HotSpot *hotspot);
369  void closeEgyptMuseumDoor(HotSpot *hotspot);
370  void pushSymbol1(HotSpot *hotspot);
371  void pushSymbol2(HotSpot *hotspot);
372  void pushSymbol3(HotSpot *hotspot);
373  void pushSymbol4(HotSpot *hotspot);
374  void pickUpHairStrand(HotSpot *hotspot);
375  void openJailFloorTile(HotSpot *hotspot);
376  void openTunnelDrawer(HotSpot *hotspot);
377  void useKeyWithPortrait(int inventoryObject, HotSpot *hotspot);
378  void openSafe(HotSpot *hotspot);
379  void openTunnelDoor(HotSpot *hotspot);
380  void closeTunnelDoor(HotSpot *hotspot);
381  void useDollWithBed(int inventoryObject, HotSpot *hotspot);
382  void giveMagazineToGuard(int inventoryObject, HotSpot *hotspot);
383  void giveWaterToGuard(int inventoryObject, HotSpot *hotspot);
384  void guardMovement();
385  void pickUpStone(HotSpot *hotspot);
386  void playSpecialAnim(uint32 offset, bool compressed, int x, int y, int width, int height, int numFrames);
387  void giveStoneToSlaves(int inventoryObject, HotSpot *hotspot);
388  void swimmingPoolCutscene(HotSpot *hotspot);
389  void pickUpStones(HotSpot *hotspot);
390  void pickUpMud(HotSpot *hotspot);
391  void openPyramidDoor(HotSpot *hotspot);
392  void usePumpkinWithPond(int inventoryObject, HotSpot *hotspot);
393  void useWaterOnFakeStone(int inventoryObject, HotSpot *hotspot);
394  void useWigWithPot(int inventoryObject, HotSpot *hotspot);
395  void magicFormula(int inventoryObject, HotSpot *hotspot);
396  void smokeAnimation(int spriteIndex, bool hide = true);
397  // void endgameTransportAnimation();
398  void openArchitectDoor(HotSpot *hotspot);
399  void closeArchitectDoor(HotSpot *hotspot);
400  void pickupPyramidMap(HotSpot *hotspot);
401  void openArchitectDoorFromInside(HotSpot *hotspot);
402  void closeArchitectDoorFromInside(HotSpot *hotspot);
403  void checkAllSymbols();
404  void openMcDoor(HotSpot *hotspot);
405  void closeMcDoor(HotSpot *hotspot);
406  void pickupBush(HotSpot *hotspot);
407  void teleportToPrincess();
408 
409  void animateStatuePaletteFade(bool reverse = false);
410  void pickUpMatches(HotSpot *hotspot);
411  void antiPiracyEffect();
412  void checkObjectsForPart2();
413  void waitForActionEnd();
414 };
415 
416 extern PelrockEngine *g_engine;
417 #define SHOULD_QUIT ::Pelrock::g_engine->shouldQuit()
418 
419 } // End of namespace Pelrock
420 
421 #endif // PELROCK_H
Definition: managed_surface.h:51
Definition: str.h:59
Definition: surface.h:67
EngineFeature
Definition: engine.h:282
bool canSaveAutosaveCurrently() override
Definition: pelrock.h:224
bool canSaveGameStateCurrently(Common::U32String *msg=nullptr) override
Definition: pelrock.h:220
Definition: stream.h:77
Definition: error.h:81
Definition: types.h:740
Definition: array.h:52
Definition: advancedDetector.h:164
Definition: types.h:160
Definition: events.h:28
Definition: random.h:44
Definition: actions.h:26
Definition: types.h:588
uint getRandomNumber(uint max)
Definition: atari-screen.h:58
Definition: stream.h:745
uint32 getRandomNumber(uint maxNum)
Definition: pelrock.h:199
Definition: screen.h:47
Definition: types.h:308
Engine * g_engine
Common::Error loadGameStream(Common::SeekableReadStream *stream) override
Definition: pelrock.h:242
Definition: serializer.h:80
Definition: small_font.h:30
Definition: types.h:233
Definition: video.h:73
Definition: graphics.h:32
Definition: types.h:207
Definition: ustr.h:57
Definition: atari-cursor.h:35
Definition: pelrock.h:55
Definition: formatinfo.h:28
Definition: rect.h:144
Definition: resources.h:30
Definition: types.h:182
bool hasFeature(EngineFeature f) const override
Definition: pelrock.h:211
Definition: dialog.h:76
Definition: room.h:36
Definition: sound.h:55
Definition: chrono.h:29
Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave=false) override
Definition: pelrock.h:238
Definition: graphics.h:38
Definition: menu.h:93
Definition: types.h:289
Definition: types.h:169
Definition: types.h:276
Definition: system.h:166
Definition: engine.h:149
bool canLoadGameStateCurrently(Common::U32String *msg=nullptr) override
Definition: pelrock.h:217
Definition: types.h:374
Definition: small_font_double.h:31
Definition: large_font.h:27