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