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 "common/winexe.h" 37 #include "common/winexe_pe.h" 38 #include "engines/engine.h" 39 #include "graphics/pixelformat.h" 40 #include "graphics/wincursor.h" 41 #include "graphics/fontman.h" 42 #include "graphics/font.h" 43 #include "graphics/fonts/ttf.h" 44 45 #include "gnap/debugger.h" 46 #include "gnap/resource.h" 47 #include "gnap/scenes/scenecore.h" 48 #include "gnap/character.h" 49 #include "gnap/music.h" 50 51 struct ADGameDescription; 52 53 namespace Gnap { 54 55 class DatManager; 56 class SequenceResource; 57 class SpriteResource; 58 class GameSys; 59 class SoundMan; 60 class MusicPlayer; 61 62 #define GNAP_SAVEGAME_VERSION 2 63 64 struct MouseButtonState { 65 bool _left; 66 bool _right; MouseButtonStateMouseButtonState67 MouseButtonState() : _left(false), _right(false) { 68 } 69 }; 70 71 struct Hotspot { 72 Common::Rect _rect; 73 uint16 _flags; 74 isPointInsideHotspot75 bool isPointInside(Common::Point pos) const { 76 return _rect.contains(pos); 77 } 78 isFlagHotspot79 bool isFlag(uint16 flag) const { 80 return (_flags & flag) != 0; 81 } 82 clearRectHotspot83 void clearRect() { 84 _rect = Common::Rect(0, 0, 0, 0); 85 } 86 }; 87 88 const int kMaxTimers = 10; 89 90 enum GnapDebugChannels { 91 kDebugBasic = 1 << 0, 92 kDebugMusic = 1 << 1 93 }; 94 95 enum { 96 SF_NONE = 0x0000, 97 SF_LOOK_CURSOR = 0x0001, 98 SF_GRAB_CURSOR = 0x0002, 99 SF_TALK_CURSOR = 0x0004, 100 SF_PLAT_CURSOR = 0x0008, 101 SF_DISABLED = 0x0010, 102 SF_WALKABLE = 0x0020, 103 SF_EXIT_L_CURSOR = 0x0040, 104 SF_EXIT_R_CURSOR = 0x0080, 105 SF_EXIT_U_CURSOR = 0x0100, 106 SF_EXIT_D_CURSOR = 0x0200, 107 SF_EXIT_NW_CURSOR = 0x0400, 108 SF_EXIT_NE_CURSOR = 0x0800, 109 SF_EXIT_SW_CURSOR = 0x1000, 110 SF_EXIT_SE_CURSOR = 0x2000 111 }; 112 113 enum { 114 LOOK_CURSOR = 0, 115 GRAB_CURSOR = 1, 116 TALK_CURSOR = 2, 117 PLAT_CURSOR = 3, 118 NOLOOK_CURSOR = 4, 119 NOGRAB_CURSOR = 5, 120 NOTALK_CURSOR = 6, 121 NOPLAT_CURSOR = 7, 122 EXIT_L_CURSOR = 8, 123 EXIT_R_CURSOR = 9, 124 EXIT_U_CURSOR = 10, 125 EXIT_D_CURSOR = 11, 126 EXIT_NE_CURSOR = 12, 127 EXIT_NW_CURSOR = 13, 128 EXIT_SE_CURSOR = 14, 129 EXIT_SW_CURSOR = 15, 130 WAIT_CURSOR = 16 131 }; 132 133 enum { 134 kGSPullOutDevice = 0, 135 kGSPullOutDeviceNonWorking = 1, 136 kGSIdle = 2, 137 kGSBrainPulsating = 3, 138 kGSImpossible = 4, 139 kGSScratchingHead = 5, 140 kGSDeflect = 6, 141 kGSUseDevice = 7, 142 kGSMoan1 = 8, 143 kGSMoan2 = 9 144 }; 145 146 enum { 147 kItemMagazine = 0, 148 kItemMud = 1, 149 kItemGrass = 2, 150 kItemDisguise = 3, 151 kItemNeedle = 4, 152 kItemTwig = 5, 153 kItemGas = 6, 154 kItemKeys = 7, 155 kItemDice = 8, 156 kItemTongs = 9, 157 kItemQuarter = 10, 158 kItemQuarterWithHole = 11, 159 kItemDiceQuarterHole = 12, 160 kItemWrench = 13, 161 kItemCowboyHat = 14, 162 kItemGroceryStoreHat = 15, 163 kItemBanana = 16, 164 kItemTickets = 17, 165 kItemPicture = 18, 166 kItemEmptyBucket = 19, 167 kItemBucketWithBeer = 20, 168 kItemBucketWithPill = 21, 169 kItemPill = 22, 170 kItemHorn = 23, 171 kItemJoint = 24, 172 kItemChickenBucket = 25, 173 kItemGum = 26, 174 kItemSpring = 27, 175 kItemLightbulb = 28, 176 kItemCereals = 29 177 }; 178 179 enum { 180 kGFPlatypus = 0, 181 kGFMudTaken = 1, 182 kGFNeedleTaken = 2, 183 kGFTwigTaken = 3, 184 kGFUnk04 = 4, 185 kGFKeysTaken = 5, 186 kGFGrassTaken = 6, 187 kGFBarnPadlockOpen = 7, 188 kGFTruckFilledWithGas = 8, 189 kGFTruckKeysUsed = 9, 190 kGFPlatypusDisguised = 10, 191 kGFSceneFlag1 = 11, 192 kGFGnapControlsToyUFO = 12, 193 kGFUnk13 = 13, // Tongue Fight Won? 194 kGFUnk14 = 14, 195 kGFSpringTaken = 15, 196 kGFUnk16 = 16, 197 kGFJointTaken = 17, 198 kGFUnk18 = 18, 199 kGFGroceryStoreHatTaken = 19, 200 kGFPictureTaken = 20, 201 kGFUnk21 = 21, 202 kGFUnk22 = 22, 203 kGFUnk23 = 23, 204 kGFUnk24 = 24, 205 kGFUnk25 = 25, 206 kGFPlatypusTalkingToAssistant = 26, 207 kGFUnk27 = 27, 208 kGFUnk28 = 28, 209 kGFGasTaken = 29, 210 kGFUnk30 = 30, 211 kGFUnk31 = 31 212 }; 213 214 struct GnapSavegameHeader { 215 uint8 _version; 216 Common::String _saveName; 217 Graphics::Surface *_thumbnail; 218 int _year, _month, _day; 219 int _hour, _minute; 220 }; 221 222 class GnapEngine : public Engine { 223 protected: 224 Common::Error run(); 225 virtual bool hasFeature(EngineFeature f) const; 226 public: 227 GnapEngine(OSystem *syst, const ADGameDescription *gd); 228 ~GnapEngine(); 229 private: 230 const ADGameDescription *_gameDescription; 231 Graphics::PixelFormat _pixelFormat; 232 int _loadGameSlot; 233 234 public: 235 Common::RandomSource *_random; 236 Common::PEResources *_exe; 237 238 DatManager *_dat; 239 SpriteCache *_spriteCache; 240 SoundCache *_soundCache; 241 SequenceCache *_sequenceCache; 242 GameSys *_gameSys; 243 SoundMan *_soundMan; 244 Debugger *_debugger; 245 Scene *_scene; 246 PlayerGnap *_gnap; 247 PlayerPlat *_plat; 248 MusicPlayer *_music; 249 Graphics::Font *_font; 250 251 Common::MemoryWriteStreamDynamic *_tempThumbnail; 252 253 int _lastUpdateClock; 254 bool _gameDone; 255 256 bool _keyPressState[512]; 257 bool _keyDownState[512]; 258 259 bool _isPaused; 260 Graphics::Surface *_pauseSprite; 261 int _timers[kMaxTimers], _savedTimers[kMaxTimers]; 262 263 MouseButtonState _mouseButtonState; 264 MouseButtonState _mouseClickState; 265 266 bool _sceneSavegameLoaded, _wasSavegameLoaded; 267 268 Graphics::Surface *_backgroundSurface; 269 int _prevSceneNum, _currentSceneNum, _newSceneNum; 270 bool _sceneDone, _sceneWaiting; 271 272 uint32 _inventory, _gameFlags; 273 274 Hotspot _hotspots[20]; 275 Common::Point _hotspotsWalkPos[20]; 276 int _hotspotsCount; 277 int _sceneClickedHotspot; 278 279 bool _isWaiting; 280 bool _isLeavingScene; 281 282 bool _isStockDatLoaded; 283 284 int _newCursorValue, _cursorValue; 285 286 int _verbCursor, _cursorIndex; 287 Common::Point _mousePos; 288 int _leftClickMouseX, _leftClickMouseY; 289 290 Graphics::Surface *_grabCursorSprite; 291 int _currGrabCursorX, _currGrabCursorY; 292 int _grabCursorSpriteIndex, _newGrabCursorSpriteIndex; 293 294 Graphics::Surface *_fullScreenSprite; 295 int _fullScreenSpriteId; 296 297 int _deviceX1, _deviceY1; 298 299 int _soundTimerIndexA; 300 int _soundTimerIndexB; 301 int _soundTimerIndexC; 302 int _idleTimerIndex; 303 304 void updateEvents(); 305 void gameUpdateTick(); 306 void saveTimers(); 307 void restoreTimers(); 308 309 void pauseGame(); 310 void resumeGame(); 311 void updatePause(); 312 313 int getRandom(int max); 314 315 int readSavegameDescription(int savegameNum, Common::String &description); 316 int loadSavegame(int savegameNum); 317 Common::Error saveGameState(int slot, const Common::String &desc); 318 Common::Error loadGameState(int slot); 319 Common::String generateSaveName(int slot); 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