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 /* 24 * This code is based on Labyrinth of Time code with assistance of 25 * 26 * Copyright (c) 1993 Terra Nova Development 27 * Copyright (c) 2004 The Wyrmkeep Entertainment Co. 28 * 29 */ 30 31 #ifndef LAB_LAB_H 32 #define LAB_LAB_H 33 34 #include "common/system.h" 35 #include "common/random.h" 36 #include "common/rect.h" 37 #include "common/savefile.h" 38 #include "engines/engine.h" 39 #include "engines/savestate.h" 40 41 #include "lab/console.h" 42 #include "lab/image.h" 43 #include "lab/labsets.h" 44 #include "lab/detection.h" 45 46 struct ADGameDescription; 47 48 namespace Lab { 49 50 struct MapData; 51 struct Action; 52 struct CloseData; 53 struct Button; 54 struct IntuiMessage; 55 struct InventoryData; 56 struct RoomData; 57 struct Rule; 58 struct TextFont; 59 struct ViewData; 60 61 class Anim; 62 class DisplayMan; 63 class EventManager; 64 class Interface; 65 class Image; 66 class Music; 67 class Resource; 68 class SpecialLocks; 69 class Utils; 70 71 struct SaveGameHeader { 72 byte _version; 73 SaveStateDescriptor _descr; 74 uint16 _roomNumber; 75 uint16 _direction; 76 }; 77 78 typedef Common::List<Button *> ButtonList; 79 80 struct CrumbData { 81 uint16 _crumbRoomNum; 82 uint16 _crumbDirection; 83 }; 84 85 #define MAX_CRUMBS 128 86 87 typedef Common::List<Rule> RuleList; 88 typedef Common::List<Action> ActionList; 89 typedef Common::List<CloseData> CloseDataList; 90 typedef Common::List<ViewData> ViewDataList; 91 92 enum Direction { 93 kDirectionNorth, 94 kDirectionSouth, 95 kDirectionEast, 96 kDirectionWest 97 }; 98 99 enum MainButton { 100 kButtonNone = -1, 101 kButtonPickup, 102 kButtonUse, 103 kButtonOpen, 104 kButtonClose, 105 kButtonLook, 106 kButtonInventory, 107 kButtonLeft, 108 kButtonForward, 109 kButtonRight, 110 kButtonMap 111 }; 112 113 enum MessageClass { 114 kMessageLeftClick, 115 kMessageRightClick, 116 kMessageButtonUp, 117 kMessageRawKey 118 }; 119 120 class LabEngine : public Engine { 121 friend class Console; 122 123 private: 124 bool _isCrumbWaiting; 125 bool _lastTooLong; 126 bool _lastPage; 127 bool _mainDisplay; 128 bool _noUpdateDiff; 129 bool _quitLab; 130 131 byte *_blankJournal; 132 133 int _lastWaitTOFTicks; 134 135 uint16 _direction; 136 uint16 _highPalette[20]; 137 uint16 _journalPage; 138 uint16 _maxRooms; 139 uint16 _monitorPage; 140 uint16 _monitorButtonHeight; 141 142 uint32 _extraGameFeatures; 143 144 Common::String _journalText; 145 Common::String _journalTextTitle; 146 Common::String _nextFileName; 147 Common::String _newFileName; 148 Common::String _monitorTextFilename; 149 150 const CloseData *_closeDataPtr; 151 ButtonList _journalButtonList; 152 ButtonList _mapButtonList; 153 Image *_imgMap, *_imgRoom, *_imgUpArrowRoom, *_imgDownArrowRoom, *_imgBridge; 154 Image *_imgHRoom, *_imgVRoom, *_imgMaze, *_imgHugeMaze, *_imgPath; 155 Image *_imgMapX[4]; 156 InventoryData *_inventory; 157 MapData *_maps; 158 Image *_monitorButton; 159 Image *_journalBackImage; 160 TextFont *_journalFont; 161 bool _introPlaying; 162 163 public: 164 bool _alternate; 165 bool _droppingCrumbs; 166 bool _followingCrumbs; 167 bool _followCrumbsFast; 168 bool _isCrumbTurning; 169 bool _isHiRes; 170 171 int _roomNum; 172 173 uint16 _highestCondition; 174 uint16 _manyRooms; 175 uint16 _numCrumbs; 176 uint16 _numInv; 177 178 uint32 _crumbTimestamp; 179 180 Common::String _curFileName; 181 182 Anim *_anim; 183 CrumbData _breadCrumbs[MAX_CRUMBS]; 184 DisplayMan *_graphics; 185 EventManager *_event; 186 Interface *_interface; 187 ButtonList _invButtonList; 188 ButtonList _moveButtonList; 189 Image *_invImages[10]; 190 Image *_moveImages[20]; 191 LargeSet *_conditions, *_roomsFound; 192 Music *_music; 193 Resource *_resource; 194 RoomData *_rooms; 195 TextFont *_msgFont; 196 SpecialLocks *_specialLocks; 197 Utils *_utils; 198 199 public: 200 LabEngine(OSystem *syst, const ADGameDescription *gameDesc); 201 ~LabEngine() override; 202 203 Common::Error run() override; 204 void go(); 205 206 const ADGameDescription *_gameDescription; 207 Common::Platform getPlatform() const; 208 uint32 getFeatures() const; 209 210 bool hasFeature(EngineFeature f) const override; 211 212 void changeVolume(int delta); getDirection()213 uint16 getDirection() { return _direction; } 214 215 /** 216 * Returns the current picture name. 217 */ 218 Common::String getPictName(bool useClose); 219 uint16 getQuarters(); 220 void setQuarters(uint16 quarters); 221 void updateEvents(); 222 void waitTOF(); 223 224 Common::Error loadGameState(int slot) override; 225 Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override; 226 bool canLoadGameStateCurrently() override; 227 bool canSaveGameStateCurrently() override; 228 isMainDisplay()229 bool isMainDisplay() const { return _mainDisplay; } 230 231 private: 232 /** 233 * Checks whether all the conditions in a condition list are met. 234 */ 235 bool checkConditions(const Common::Array<int16> &cond); 236 237 /** 238 * Decrements the current inventory number. 239 */ 240 void decIncInv(uint16 *CurInv, bool dec); 241 242 /** 243 * Processes the action list. 244 */ 245 void doActions(const ActionList &actionList); 246 247 /** 248 * Goes through the rules if an action is taken. 249 */ 250 bool doActionRule(Common::Point pos, int16 action, int16 roomNum); 251 252 /** 253 * Does the work for doActionRule. 254 */ 255 bool doActionRuleSub(int16 action, int16 roomNum, const CloseData *closePtr, bool allowDefaults); 256 257 /** 258 * Handles monitor closeups 259 */ 260 void handleMonitorCloseup(); 261 262 /** 263 * Goes through the rules if the user tries to go forward. 264 */ 265 bool doGoForward(); 266 267 /** 268 * Does the journal processing. 269 */ 270 void doJournal(); 271 272 /** 273 * Goes through the rules if the user tries to go to the main view 274 */ 275 bool doMainView(); 276 277 /** 278 * Does the map processing. 279 */ 280 void doMap(); 281 282 /** 283 * Does what's necessary for the monitor. 284 */ 285 void doMonitor(const Common::String background, const Common::String textfile, bool isinteractive, Common::Rect textRect); 286 287 /** 288 * Does the things to properly set up the detective notes. 289 */ 290 void doNotes(); 291 292 /** 293 * Does the work for doActionRule. 294 */ 295 bool doOperateRuleSub(int16 itemNum, int16 roomNum, const CloseData *closePtr, bool allowDefaults); 296 297 /** 298 * Goes through the rules if the user tries to operate an item on an object. 299 */ 300 bool doOperateRule(Common::Point pos, int16 ItemNum); 301 302 /** 303 * Goes through the rules if the user tries to turn. 304 */ 305 bool doTurn(uint16 from, uint16 to); 306 307 /** 308 * If the user hits the "Use" button; things that can get used on themselves. 309 */ 310 bool doUse(uint16 curInv); 311 312 /** 313 * Does the things to properly set up the old west newspaper. Assumes that 314 * OpenHiRes already called. 315 */ 316 void doWestPaper(); 317 318 /** 319 * Draws the current direction to the screen. 320 */ 321 void drawDirection(const CloseData *closePtr); 322 323 /** 324 * Draws the journal from page x. 325 */ 326 void drawJournal(uint16 wipenum, bool needFade); 327 328 /** 329 * Draws the text to the back journal screen to the appropriate Page number 330 */ 331 void drawJournalText(); 332 333 /** 334 * Draws the map 335 */ 336 void drawMap(uint16 curRoom, uint16 curMsg, uint16 floorNum, bool fadeIn); 337 338 /** 339 * Draws the text for the monitor. 340 */ 341 void drawMonText(const char *text, TextFont *monitorFont, Common::Rect textRect, bool isinteractive); 342 343 /** 344 * Draws a room map. 345 */ 346 void drawRoomMap(uint16 curRoom, bool drawMarkFl); 347 348 /** 349 * Draws the message for the room. 350 */ 351 void drawRoomMessage(uint16 curInv, const CloseData *closePtr); 352 void drawStaticMessage(byte index); 353 354 /** 355 * Eats all the available messages. 356 */ 357 void eatMessages(); 358 359 /** 360 * Goes through the list of closeups to find a match. 361 * @note Known bug here. If there are two objects that have closeups, and 362 * some of the closeups have the same hit boxes, then this returns the first 363 * occurrence of the object with the same hit box. 364 */ 365 const CloseData *findClosePtrMatch(const CloseData *closePtr, const CloseDataList &list); 366 367 /** 368 * Checks if a floor has been visited. 369 */ 370 bool floorVisited(uint16 floorNum); 371 372 /** 373 * New code to allow quick(er) return navigation in game. 374 */ 375 MainButton followCrumbs(); 376 void freeMapData(); 377 void freeScreens(); 378 bool processEvent(MessageClass tmpClass, uint16 code, uint16 qualifier, Common::Point tmpPos, 379 uint16 &curInv, IntuiMessage *curMsg, bool &forceDraw, uint16 buttonId, uint16 &actionMode); 380 381 /** 382 * Gets the current inventory name. 383 */ 384 Common::String getInvName(uint16 curInv); 385 386 /** 387 * Returns the floor to show when the down arrow is pressed 388 * @note The original did not show all the visited floors, but we do 389 */ 390 uint16 getLowerFloor(uint16 floorNum); 391 392 /** 393 * Gets an object, if any, from the user's click on the screen. 394 */ 395 const CloseData *getObject(Common::Point pos, const CloseData *closePtr); 396 397 /** 398 * Returns the floor to show when the up arrow is pressed 399 * @note The original did not show all the visited floors, but we do 400 */ 401 uint16 getUpperFloor(uint16 floorNum); 402 403 /** 404 * Gets the current ViewDataPointer. 405 */ 406 ViewData *getViewData(uint16 roomNum, uint16 direction); 407 408 /** 409 * Turns the interface off. 410 */ 411 void interfaceOff(); 412 413 /** 414 * Turns the interface on. 415 */ 416 void interfaceOn(); 417 418 /** 419 * Loads in the data for the journal. 420 */ 421 void loadJournalData(); 422 423 /** 424 * Loads in the map data. 425 */ 426 void loadMapData(); 427 428 /** 429 * The main game loop. 430 */ 431 void mainGameLoop(); 432 void showLab2Teaser(); 433 434 /** 435 * Permanently flips the imagery of a button. 436 */ 437 void perFlipButton(uint16 buttonId); 438 439 /** 440 * process a arrow button movement. 441 */ 442 uint16 processArrow(uint16 curDirection, uint16 arrow); 443 444 /** 445 * Processes user input. 446 */ 447 void processJournal(); 448 449 /** 450 * Processes the map. 451 */ 452 void processMap(uint16 curRoom); 453 454 /** 455 * Processes user input. 456 */ 457 void processMonitor(const Common::String &ntext, TextFont *monitorFont, bool isInteractive, Common::Rect textRect); 458 459 /** 460 * Figures out what a room's coordinates should be. 461 */ 462 Common::Rect roomCoords(uint16 curRoom); 463 bool saveRestoreGame(); 464 465 /** 466 * Sets the current close up data. 467 */ 468 void setCurrentClose(Common::Point pos, const CloseData **closePtrList, bool useAbsoluteCoords, bool next=false); 469 470 /** 471 * Takes the currently selected item. 472 */ 473 bool takeItem(Common::Point pos); 474 475 /** 476 * Does the turn page wipe. 477 */ 478 void turnPage(bool fromLeft); 479 bool processKey(IntuiMessage *curMsg, uint32 msgClass, uint16 &qualifier, Common::Point &curPos, uint16 &curInv, bool &forceDraw, uint16 code); 480 void processMainButton(uint16 &curInv, uint16 &lastInv, uint16 &oldDirection, bool &forceDraw, uint16 buttonId, uint16 &actionMode); 481 void processAltButton(uint16 &curInv, uint16 &lastInv, uint16 buttonId, uint16 &actionMode); 482 void performAction(uint16 actionMode, Common::Point curPos, uint16 &curInv); 483 484 /** 485 * Writes the game out to disk. 486 */ 487 bool saveGame(int slot, const Common::String desc); 488 489 /** 490 * Reads the game from disk. 491 */ 492 bool loadGame(int slot); 493 void writeSaveGameHeader(Common::OutSaveFile *out, const Common::String &saveName); 494 495 void handleTrialWarning(); 496 }; 497 498 WARN_UNUSED_RESULT bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header, bool skipThumbnail = true); 499 500 } // End of namespace Lab 501 502 #endif // LAB_LAB_H 503