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 */ 22 23 #ifndef GNAP_GNAP_H 24 #define GNAP_GNAP_H 25 26 #include "common/array.h" 27 #include "common/events.h" 28 #include "common/file.h" 29 #include "common/memstream.h" 30 #include "common/random.h" 31 #include "common/savefile.h" 32 #include "common/serializer.h" 33 #include "common/str.h" 34 #include "common/substream.h" 35 #include "common/system.h" 36 #include "engines/engine.h" 37 #include "graphics/pixelformat.h" 38 #include "graphics/fontman.h" 39 #include "graphics/font.h" 40 #include "graphics/fonts/ttf.h" 41 42 #include "gnap/debugger.h" 43 #include "gnap/resource.h" 44 #include "gnap/scenes/scenecore.h" 45 #include "gnap/character.h" 46 #include "gnap/music.h" 47 48 struct ADGameDescription; 49 50 namespace Common { 51 class PEResources; 52 } 53 54 namespace Gnap { 55 56 class DatManager; 57 class SequenceResource; 58 class SpriteResource; 59 class GameSys; 60 class SoundMan; 61 class MusicPlayer; 62 63 #define GNAP_SAVEGAME_VERSION 2 64 65 struct MouseButtonState { 66 bool _left; 67 bool _right; MouseButtonStateMouseButtonState68 MouseButtonState() : _left(false), _right(false) { 69 } 70 }; 71 72 struct Hotspot { 73 Common::Rect _rect; 74 uint16 _flags; 75 isPointInsideHotspot76 bool isPointInside(Common::Point pos) const { 77 return _rect.contains(pos); 78 } 79 isFlagHotspot80 bool isFlag(uint16 flag) const { 81 return (_flags & flag) != 0; 82 } 83 clearRectHotspot84 void clearRect() { 85 _rect = Common::Rect(0, 0, 0, 0); 86 } 87 }; 88 89 const int kMaxTimers = 10; 90 91 enum GnapDebugChannels { 92 kDebugBasic = 1 << 0, 93 kDebugMusic = 1 << 1 94 }; 95 96 enum { 97 SF_NONE = 0x0000, 98 SF_LOOK_CURSOR = 0x0001, 99 SF_GRAB_CURSOR = 0x0002, 100 SF_TALK_CURSOR = 0x0004, 101 SF_PLAT_CURSOR = 0x0008, 102 SF_DISABLED = 0x0010, 103 SF_WALKABLE = 0x0020, 104 SF_EXIT_L_CURSOR = 0x0040, 105 SF_EXIT_R_CURSOR = 0x0080, 106 SF_EXIT_U_CURSOR = 0x0100, 107 SF_EXIT_D_CURSOR = 0x0200, 108 SF_EXIT_NW_CURSOR = 0x0400, 109 SF_EXIT_NE_CURSOR = 0x0800, 110 SF_EXIT_SW_CURSOR = 0x1000, 111 SF_EXIT_SE_CURSOR = 0x2000 112 }; 113 114 enum { 115 LOOK_CURSOR = 0, 116 GRAB_CURSOR = 1, 117 TALK_CURSOR = 2, 118 PLAT_CURSOR = 3, 119 NOLOOK_CURSOR = 4, 120 NOGRAB_CURSOR = 5, 121 NOTALK_CURSOR = 6, 122 NOPLAT_CURSOR = 7, 123 EXIT_L_CURSOR = 8, 124 EXIT_R_CURSOR = 9, 125 EXIT_U_CURSOR = 10, 126 EXIT_D_CURSOR = 11, 127 EXIT_NE_CURSOR = 12, 128 EXIT_NW_CURSOR = 13, 129 EXIT_SE_CURSOR = 14, 130 EXIT_SW_CURSOR = 15, 131 WAIT_CURSOR = 16 132 }; 133 134 enum { 135 kGSPullOutDevice = 0, 136 kGSPullOutDeviceNonWorking = 1, 137 kGSIdle = 2, 138 kGSBrainPulsating = 3, 139 kGSImpossible = 4, 140 kGSScratchingHead = 5, 141 kGSDeflect = 6, 142 kGSUseDevice = 7, 143 kGSMoan1 = 8, 144 kGSMoan2 = 9 145 }; 146 147 enum { 148 kItemMagazine = 0, 149 kItemMud = 1, 150 kItemGrass = 2, 151 kItemDisguise = 3, 152 kItemNeedle = 4, 153 kItemTwig = 5, 154 kItemGas = 6, 155 kItemKeys = 7, 156 kItemDice = 8, 157 kItemTongs = 9, 158 kItemQuarter = 10, 159 kItemQuarterWithHole = 11, 160 kItemDiceQuarterHole = 12, 161 kItemWrench = 13, 162 kItemCowboyHat = 14, 163 kItemGroceryStoreHat = 15, 164 kItemBanana = 16, 165 kItemTickets = 17, 166 kItemPicture = 18, 167 kItemEmptyBucket = 19, 168 kItemBucketWithBeer = 20, 169 kItemBucketWithPill = 21, 170 kItemPill = 22, 171 kItemHorn = 23, 172 kItemJoint = 24, 173 kItemChickenBucket = 25, 174 kItemGum = 26, 175 kItemSpring = 27, 176 kItemLightbulb = 28, 177 kItemCereals = 29 178 }; 179 180 enum { 181 kGFPlatypus = 0, 182 kGFMudTaken = 1, 183 kGFNeedleTaken = 2, 184 kGFTwigTaken = 3, 185 kGFUnk04 = 4, 186 kGFKeysTaken = 5, 187 kGFGrassTaken = 6, 188 kGFBarnPadlockOpen = 7, 189 kGFTruckFilledWithGas = 8, 190 kGFTruckKeysUsed = 9, 191 kGFPlatypusDisguised = 10, 192 kGFSceneFlag1 = 11, 193 kGFGnapControlsToyUFO = 12, 194 kGFUnk13 = 13, // Tongue Fight Won? 195 kGFUnk14 = 14, 196 kGFSpringTaken = 15, 197 kGFUnk16 = 16, 198 kGFJointTaken = 17, 199 kGFUnk18 = 18, 200 kGFGroceryStoreHatTaken = 19, 201 kGFPictureTaken = 20, 202 kGFUnk21 = 21, 203 kGFUnk22 = 22, 204 kGFUnk23 = 23, 205 kGFUnk24 = 24, 206 kGFUnk25 = 25, 207 kGFPlatypusTalkingToAssistant = 26, 208 kGFUnk27 = 27, 209 kGFUnk28 = 28, 210 kGFGasTaken = 29, 211 kGFUnk30 = 30, 212 kGFUnk31 = 31 213 }; 214 215 struct GnapSavegameHeader { 216 uint8 _version; 217 Common::String _saveName; 218 Graphics::Surface *_thumbnail; 219 int _year, _month, _day; 220 int _hour, _minute; 221 }; 222 223 class GnapEngine : public Engine { 224 protected: 225 Common::Error run() override; 226 bool hasFeature(EngineFeature f) const override; 227 public: 228 GnapEngine(OSystem *syst, const ADGameDescription *gd); 229 ~GnapEngine() override; 230 private: 231 const ADGameDescription *_gameDescription; 232 Graphics::PixelFormat _pixelFormat; 233 int _loadGameSlot; 234 235 public: 236 Common::RandomSource *_random; 237 Common::PEResources *_exe; 238 239 DatManager *_dat; 240 SpriteCache *_spriteCache; 241 SoundCache *_soundCache; 242 SequenceCache *_sequenceCache; 243 GameSys *_gameSys; 244 SoundMan *_soundMan; 245 Debugger *_debugger; 246 Scene *_scene; 247 PlayerGnap *_gnap; 248 PlayerPlat *_plat; 249 MusicPlayer *_music; 250 Graphics::Font *_font; 251 252 Common::MemoryWriteStreamDynamic *_tempThumbnail; 253 254 int _lastUpdateClock; 255 bool _gameDone; 256 257 bool _keyPressState[512]; 258 bool _keyDownState[512]; 259 260 bool _isPaused; 261 Graphics::Surface *_pauseSprite; 262 int _timers[kMaxTimers], _savedTimers[kMaxTimers]; 263 264 MouseButtonState _mouseButtonState; 265 MouseButtonState _mouseClickState; 266 267 bool _sceneSavegameLoaded, _wasSavegameLoaded; 268 269 Graphics::Surface *_backgroundSurface; 270 int _prevSceneNum, _currentSceneNum, _newSceneNum; 271 bool _sceneDone, _sceneWaiting; 272 273 uint32 _inventory, _gameFlags; 274 275 Hotspot _hotspots[20]; 276 Common::Point _hotspotsWalkPos[20]; 277 int _hotspotsCount; 278 int _sceneClickedHotspot; 279 280 bool _isWaiting; 281 bool _isLeavingScene; 282 283 bool _isStockDatLoaded; 284 285 int _newCursorValue, _cursorValue; 286 287 int _verbCursor, _cursorIndex; 288 Common::Point _mousePos; 289 int _leftClickMouseX, _leftClickMouseY; 290 291 Graphics::Surface *_grabCursorSprite; 292 int _currGrabCursorX, _currGrabCursorY; 293 int _grabCursorSpriteIndex, _newGrabCursorSpriteIndex; 294 295 Graphics::Surface *_fullScreenSprite; 296 int _fullScreenSpriteId; 297 298 int _deviceX1, _deviceY1; 299 300 int _soundTimerIndexA; 301 int _soundTimerIndexB; 302 int _soundTimerIndexC; 303 int _idleTimerIndex; 304 305 void updateEvents(); 306 void gameUpdateTick(); 307 void saveTimers(); 308 void restoreTimers(); 309 310 void pauseGame(); 311 void resumeGame(); 312 void updatePause(); 313 314 int getRandom(int max); 315 316 int readSavegameDescription(int savegameNum, Common::String &description); 317 int loadSavegame(int savegameNum); 318 Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override; 319 Common::Error loadGameState(int slot) override; 320 void synchronize(Common::Serializer &s); 321 void writeSavegameHeader(Common::OutSaveFile *out, GnapSavegameHeader &header); 322 WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, GnapSavegameHeader &header, bool skipThumbnail = true); 323 324 void delayTicks(int val, int idx, bool updateCursor); 325 void delayTicksA(int val, int idx); 326 void delayTicksCursor(int val); 327 328 void setHotspot(int index, int16 x1, int16 y1, int16 x2, int16 y2, uint16 flags = SF_NONE, 329 int16 walkX = -1, int16 walkY = -1); 330 int getHotspotIndexAtPos(Common::Point pos); 331 void updateCursorByHotspot(); 332 int getClickedHotspotId(); 333 334 int getInventoryItemSpriteNum(int index); 335 336 void updateMouseCursor(); 337 void setVerbCursor(int verbCursor); 338 void setCursor(int cursorIndex); 339 void showCursor(); 340 void hideCursor(); 341 342 void setGrabCursorSprite(int index); 343 void createGrabCursorSprite(int spriteId); 344 void freeGrabCursorSprite(); 345 void updateGrabCursorSprite(int x, int y); 346 347 void invClear(); 348 void invAdd(int itemId); 349 void invRemove(int itemId); 350 bool invHas(int itemId); 351 352 void clearFlags(); 353 void setFlag(int num); 354 void clearFlag(int num); 355 bool isFlag(int num); 356 357 Graphics::Surface *addFullScreenSprite(int resourceId, int id); 358 void removeFullScreenSprite(); 359 void showFullScreenSprite(int resourceId); 360 361 void queueInsertDeviceIcon(); 362 void insertDeviceIconActive(); 363 void removeDeviceIconActive(); 364 void setDeviceHotspot(int hotspotIndex, int x1, int y1, int x2, int y2); 365 366 int getSequenceTotalDuration(int resourceId); 367 368 bool isSoundPlaying(int resourceId); 369 void playSound(int resourceId, bool looping); 370 void stopSound(int resourceId); 371 void setSoundVolume(int resourceId, int volume); 372 373 void updateTimers(); 374 375 void initGameFlags(int num); 376 void loadStockDat(); 377 378 void mainLoop(); 379 void initScene(); 380 void endSceneInit(); 381 void afterScene(); 382 383 int initSceneLogic(); 384 void runSceneLogic(); 385 386 void checkGameKeys(); 387 388 void startSoundTimerA(int timerIndex); 389 int playSoundA(); 390 void startSoundTimerB(int timerIndex); 391 int playSoundB(); 392 void startSoundTimerC(int timerIndex); 393 int playSoundC(); 394 void startIdleTimer(int timerIndex); 395 void updateIdleTimer(); 396 397 void screenEffect(int dir, byte r, byte g, byte b); 398 399 bool isKeyStatus1(int key); 400 bool isKeyStatus2(int key); 401 void clearKeyStatus1(int key); 402 void clearAllKeyStatus1(); 403 404 void deleteSurface(Graphics::Surface **surface); 405 406 // Menu 407 int _menuStatus; 408 int _menuSpritesIndex; 409 bool _menuDone; 410 Graphics::Surface *_menuBackgroundSurface; 411 Graphics::Surface *_menuQuitQuerySprite; 412 Graphics::Surface *_largeSprite; 413 Graphics::Surface *_menuSaveLoadSprite; 414 Graphics::Surface *_menuSprite2; 415 Graphics::Surface *_menuSprite1; 416 char _savegameFilenames[7][30]; 417 Graphics::Surface *_savegameSprites[7]; 418 Graphics::Surface *_spriteHandle; 419 Graphics::Surface *_cursorSprite; 420 int _menuInventoryIndices[30]; 421 Graphics::Surface *_menuInventorySprites[30]; 422 int _savegameIndex; 423 void createMenuSprite(); 424 void freeMenuSprite(); 425 void initMenuHotspots1(); 426 void initMenuHotspots2(); 427 void initMenuQuitQueryHotspots(); 428 void initSaveLoadHotspots(); 429 void drawInventoryFrames(); 430 void insertInventorySprites(); 431 void removeInventorySprites(); 432 void runMenu(); 433 void updateMenuStatusInventory(); 434 void updateMenuStatusMainMenu(); 435 void updateMenuStatusSaveGame(); 436 void updateMenuStatusLoadGame(); 437 void updateMenuStatusQueryQuit(); 438 439 // Grid common 440 int _gridMinX, _gridMinY; 441 int _gridMaxX, _gridMaxY; 442 bool isPointBlocked(int gridX, int gridY); 443 bool isPointBlocked(Common::Point gridPos); 444 void initSceneGrid(int gridMinX, int gridMinY, int gridMaxX, int gridMaxY); 445 bool testWalk(int animationIndex, int someStatus, int gridX1, int gridY1, int gridX2, int gridY2); 446 447 // Gnap 448 void doCallback(int callback); 449 450 // Scenes 451 int _toyUfoNextSequenceId, _toyUfoSequenceId; 452 int _toyUfoId; 453 int _toyUfoActionStatus; 454 int _toyUfoX; 455 int _toyUfoY; 456 457 void initGlobalSceneVars(); 458 void playSequences(int fullScreenSpriteId, int sequenceId1, int sequenceId2, int sequenceId3); 459 460 // Shared by scenes 17 & 18 461 int _s18GarbageCanPos; 462 463 // Scene 4x 464 void toyUfoSetStatus(int flagNum); 465 int toyUfoGetSequenceId(); 466 bool toyUfoCheckTimer(); 467 void toyUfoFlyTo(int destX, int destY, int minX, int maxX, int minY, int maxY, int animationIndex); 468 469 void playMidi(const char *name); 470 void stopMidi(); 471 }; 472 473 } // End of namespace Gnap 474 475 #endif // GNAP_GNAP_H 476