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
33namespace Graphics {
34class Screen;
35}
36
37namespace Pelrock {
38
39struct PelrockGameDescription;
40
41class ChronoManager;
42class DialogManager;
43class DoubleSmallFont;
44class GraphicsManager;
45class LargeFont;
46class MenuManager;
47class PelrockEventManager;
48class RoomManager;
49class ResourceManager;
50class SmallFont;
51class SoundManager;
52class VideoManager;
53
54
55class PelrockEngine : public Engine {
56private:
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
159protected:
160 // Engine APIs
161 Common::Error run() override;
162
163public:
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
185public:
186 PelrockEngine(OSystem *syst, const ADGameDescription *gameDesc);
187 ~PelrockEngine() override;
188
189 uint32 getFeatures() const;
190
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) ||
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
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
416extern PelrockEngine *g_engine;
417#define SHOULD_QUIT ::Pelrock::g_engine->shouldQuit()
418
419} // End of namespace Pelrock
420
421#endif // PELROCK_H
Definition: array.h:52
Definition: error.h:81
Definition: random.h:44
uint getRandomNumber(uint max)
Definition: stream.h:745
Definition: serializer.h:80
Definition: str.h:59
Definition: ustr.h:57
Definition: stream.h:77
Definition: engine.h:149
EngineFeature
Definition: engine.h:282
@ kSupportsReturnToLauncher
Definition: engine.h:296
@ kSupportsSavingDuringRuntime
Definition: engine.h:314
@ kSupportsLoadingDuringRuntime
Definition: engine.h:305
Definition: managed_surface.h:51
Definition: screen.h:47
Definition: graphics.h:38
Definition: system.h:166
Definition: chrono.h:29
Definition: dialog.h:76
Definition: small_font_double.h:31
Definition: graphics.h:32
Definition: large_font.h:27
Definition: menu.h:93
Definition: pelrock.h:55
bool hasFeature(EngineFeature f) const override
Definition: pelrock.h:211
bool canSaveAutosaveCurrently() override
Definition: pelrock.h:224
bool canSaveGameStateCurrently(Common::U32String *msg=nullptr) override
Definition: pelrock.h:220
Common::String getGameId() const
Common::Error syncGame(Common::Serializer &s)
bool canLoadGameStateCurrently(Common::U32String *msg=nullptr) override
Definition: pelrock.h:217
Common::Error run() override
bool isAlternateTiming() const
uint32 getRandomNumber(uint maxNum)
Definition: pelrock.h:199
Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave=false) override
Definition: pelrock.h:238
Common::Error loadGameStream(Common::SeekableReadStream *stream) override
Definition: pelrock.h:242
Definition: events.h:28
Definition: resources.h:30
Definition: room.h:36
Definition: small_font.h:30
Definition: sound.h:55
Definition: video.h:73
Engine * g_engine
Definition: formatinfo.h:28
Definition: advancedDetector.h:164
Definition: rect.h:144
Definition: atari-cursor.h:35
Definition: surface.h:67
Definition: types.h:160
Definition: types.h:182
Definition: types.h:276
Definition: types.h:588
Definition: types.h:308
Definition: types.h:169
Definition: types.h:233
Definition: types.h:374
Definition: types.h:740
Definition: types.h:207
Definition: types.h:289
Definition: atari-screen.h:58