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 original Tony Tough source code 25 * 26 * Copyright (c) 1997-2003 Nayma Software 27 */ 28 29 #ifndef TONY_LOC_H 30 #define TONY_LOC_H 31 32 #include "common/scummsys.h" 33 #include "common/system.h" 34 #include "common/file.h" 35 #include "tony/sound.h" 36 #include "tony/utils.h" 37 38 namespace Tony { 39 40 /****************************************************************************\ 41 * Various defines 42 \****************************************************************************/ 43 44 /** 45 * Valid color modes 46 */ 47 typedef enum { 48 CM_256, 49 CM_65K 50 } RMColorMode; 51 52 /****************************************************************************\ 53 * Class declarations 54 \****************************************************************************/ 55 56 /** 57 * Generic palette 58 */ 59 class RMPalette { 60 public: 61 byte _data[1024]; 62 63 public: 64 void readFromStream(Common::ReadStream &ds); 65 }; 66 67 /** 68 * Sound effect of an object 69 */ 70 class RMSfx { 71 public: 72 Common::String _name; 73 FPSfx *_fx; 74 bool _bPlayingLoop; 75 76 public: 77 RMSfx(); 78 virtual ~RMSfx(); 79 80 void play(bool bLoop = false); 81 void setVolume(int vol); 82 void pause(bool bPause); 83 void stop(); 84 85 void readFromStream(Common::ReadStream &ds, bool bLOX = false); 86 }; 87 88 /** 89 * Object pattern 90 */ 91 class RMPattern { 92 public: 93 // Type of slot 94 enum RMSlotType { 95 DUMMY1 = 0, 96 DUMMY2, 97 SPRITE, 98 SOUND, 99 COMMAND, 100 SPECIAL 101 }; 102 103 // Class slot 104 class RMSlot { 105 private: 106 RMPoint _pos; // Child co-ordinates 107 108 public: 109 RMSlotType _type; 110 int _data; 111 byte _flag; 112 113 public: pos()114 RMPoint pos() { 115 return _pos; 116 } 117 118 void readFromStream(Common::ReadStream &ds, bool bLOX = false); 119 }; 120 121 public: 122 Common::String _name; 123 124 private: 125 int _speed; 126 RMPoint _pos; // Parent coordinates 127 RMPoint _curPos; // Parent + child coordinates 128 int _bLoop; 129 int _nSlots; 130 int _nCurSlot; 131 int _nCurSprite; 132 133 RMSlot *_slots; 134 135 uint32 _nStartTime; 136 137 public: 138 RMPattern(); 139 virtual ~RMPattern(); 140 141 // A warning that the pattern now and the current 142 int init(RMSfx *sfx, bool bPlayP0 = false, byte *bFlag = NULL); 143 144 // Update the pattern, checking to see if it's time to change slot and executing 145 // any associated commands 146 int update(uint32 hEndPattern, byte &bFlag, RMSfx *sfx); 147 148 // Stop a sound effect 149 void stopSfx(RMSfx *sfx); 150 151 // Reads the position of the pattern 152 RMPoint pos(); 153 154 void readFromStream(Common::ReadStream &ds, bool bLOX); 155 156 private: 157 void updateCoord(); 158 }; 159 160 /** 161 * Sprite (frame) animation of an item 162 */ 163 class RMSprite : public RMGfxTask { 164 public: 165 Common::String _name; 166 RMRect _rcBox; 167 168 protected: 169 RMGfxSourceBuffer *_buf; 170 171 public: 172 RMSprite(); 173 virtual ~RMSprite(); 174 175 void init(RMGfxSourceBuffer *buf); 176 virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim); 177 void setPalette(byte *lpBuf); 178 void getSizeFromStream(Common::SeekableReadStream &ds, int *dimx, int *dimy); 179 void LOXGetSizeFromStream(Common::SeekableReadStream &ds, int *dimx, int *dimy); 180 181 void readFromStream(Common::SeekableReadStream &ds, bool bLOX = false); 182 }; 183 184 /** 185 * Data on an item 186 */ 187 class RMItem : public RMGfxTask { 188 public: 189 Common::String _name; 190 191 protected: 192 int _z; 193 RMPoint _pos; // Coordinate ancestor 194 RMColorMode _cm; 195 RMPoint _curScroll; 196 197 byte _FX; 198 byte _FXparm; 199 200 virtual int getCurPattern(); 201 202 private: 203 int _nCurPattern; 204 int _mpalCode; 205 RMPoint _hot; 206 RMRect _rcBox; 207 int _nSprites, _nSfx, _nPatterns; 208 byte _bPal; 209 RMPalette _pal; 210 211 RMSprite *_sprites; 212 RMSfx *_sfx; 213 RMPattern *_patterns; 214 215 byte _bCurFlag; 216 int _nCurSprite; 217 bool _bIsActive; 218 uint32 _hEndPattern; 219 bool _bInitCurPattern; 220 221 public: 222 RMPoint calculatePos(); 223 224 public: 225 RMItem(); 226 virtual ~RMItem(); 227 228 // Process to make the object move on any animations. 229 // Returns TRUE if it should be redrawn on the next frame 230 bool doFrame(RMGfxTargetBuffer *bigBuf, bool bAddToList = true); 231 232 // Sets the current scrolling position 233 void setScrollPosition(const RMPoint &scroll); 234 235 // Overloading of check whether to remove from active list 236 virtual void removeThis(CORO_PARAM, bool &result); 237 238 // Overloaded Draw 239 virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim); 240 241 // Overloaded priority: it's based on Z ordering 242 virtual int priority(); 243 244 // Pattern number 245 int numPattern(); 246 247 // Set anew animation pattern, changing abruptly from the current 248 virtual void setPattern(int nPattern, bool bPlayP0 = false); 249 250 // Set a new status 251 void setStatus(int nStatus); 252 253 bool isIn(const RMPoint &pt, int *size = NULL); 254 RMPoint getHotspot(); 255 bool getName(Common::String &name); 256 int mpalCode(); 257 258 // Unload 259 void unload(); 260 261 // Wait for the end of the current pattern 262 void waitForEndPattern(CORO_PARAM, uint32 hCustomSkip = CORO_INVALID_PID_VALUE); 263 264 // Sets a new hotspot fro the object 265 void changeHotspot(const RMPoint &pt); 266 267 void setInitCurPattern(bool status); 268 269 void playSfx(int nSfx); 270 271 void readFromStream(Common::SeekableReadStream &ds, bool bLOX = false); 272 273 void pauseSound(bool bPause); 274 275 protected: 276 // Create a primitive that has as it's task this item 277 virtual RMGfxPrimitive *newItemPrimitive(); 278 279 // Allocate memory for the sprites 280 virtual RMGfxSourceBuffer *newItemSpriteBuffer(int dimx, int dimy, bool bPreRLE); 281 }; 282 283 #define MAXBOXES 50 // Maximum number of allowed boxes 284 #define MAXHOTSPOT 20 // Maximum nimber of allowed hotspots 285 286 class RMBox { 287 public: 288 struct Hotspot { 289 int _hotx, _hoty; // Hotspot coordinates 290 int _destination; // Hotspot destination 291 }; 292 293 public: 294 int _left, _top, _right, _bottom; // Vertici bounding boxes 295 int _adj[MAXBOXES]; // List of adjacent bounding boxes 296 int _numHotspot; // Hotspot number 297 uint8 _destZ; // Z value for the bounding box 298 Hotspot _hotspot[MAXHOTSPOT]; // List of hotspots 299 300 bool _bActive; 301 bool _bReversed; 302 303 void readFromStream(Common::ReadStream &ds); 304 }; 305 306 class RMBoxLoc { 307 public: 308 int _numbBox; 309 RMBox *_boxes; 310 311 void readFromStream(Common::ReadStream &ds); 312 313 public: 314 RMBoxLoc(); 315 virtual ~RMBoxLoc(); 316 317 void recalcAllAdj(); 318 }; 319 320 #define GAME_BOXES_SIZE 200 321 322 class RMGameBoxes { 323 protected: 324 RMBoxLoc *_allBoxes[GAME_BOXES_SIZE]; 325 int _nLocBoxes; 326 327 public: 328 RMGameBoxes(); 329 ~RMGameBoxes(); 330 331 void init(); 332 void close(); 333 334 // Get binding boxes for a given location 335 RMBoxLoc *getBoxes(int nLoc); 336 int getLocBoxesCount() const; 337 338 // Return the box which contains a given point 339 int whichBox(int nLoc, const RMPoint &pt); 340 341 // Check whether a point is inside a given box 342 bool isInBox(int nLoc, int nBox, const RMPoint &pt); 343 344 // Change the status of a box 345 void changeBoxStatus(int nLoc, int nBox, int status); 346 347 // Save state handling 348 int getSaveStateSize(); 349 void saveState(byte *buf); 350 void loadState(byte *buf); 351 }; 352 353 class RMCharacter : protected RMItem { 354 public: 355 enum Patterns { 356 PAT_STANDUP = 1, 357 PAT_STANDDOWN, 358 PAT_STANDLEFT, 359 PAT_STANDRIGHT, 360 PAT_WALKUP, 361 PAT_WALKDOWN, 362 PAT_WALKLEFT, 363 PAT_WALKRIGHT 364 }; 365 366 private: 367 enum CharacterStatus { 368 STAND, 369 WALK 370 }; 371 372 signed short _walkCount; 373 int _dx, _dy, _olddx, _olddy; 374 float _fx, _fy, _slope; 375 RMPoint _lineStart, _lineEnd, _pathEnd; 376 signed char _walkSpeed, _walkStatus; 377 char _minPath; 378 short _nextBox; 379 short _path[MAXBOXES]; 380 short _pathLength, _pathCount; 381 int _curBox; 382 383 CharacterStatus _status; 384 int _curSpeed; 385 bool _bEndOfPath; 386 uint32 _hEndOfPath; 387 OSystem::MutexRef _csMove; 388 int _curLocation; 389 bool _bRemoveFromOT; 390 bool _bMovingWithoutMinpath; 391 RMGameBoxes *_theBoxes; 392 393 RMPoint _fixedScroll; 394 395 private: 396 int inWhichBox(const RMPoint &pt); 397 398 bool findPath(short source, short destination); 399 RMPoint searching(char UP, char DOWN, char RIGHT, char LEFT, RMPoint point); 400 RMPoint nearestPoint(const RMPoint &punto); 401 402 void goTo(CORO_PARAM, RMPoint destcoord, bool bReversed = false); 403 short scanLine(const RMPoint &point); 404 RMPoint invScanLine(const RMPoint &point); 405 RMPoint nearestHotSpot(int sourcebox, int destbox); 406 407 void newBoxEntered(int nBox); 408 409 protected: 410 bool _bMoving; 411 bool _bDrawNow; 412 bool _bNeedToStop; 413 414 public: 415 RMCharacter(); 416 virtual ~RMCharacter(); 417 418 void linkToBoxes(RMGameBoxes *theBoxes); 419 420 virtual void removeThis(CORO_PARAM, bool &result); 421 422 // Update the position of a character 423 void doFrame(CORO_PARAM, RMGfxTargetBuffer *bigBuf, int loc); 424 425 // Overloaded draw 426 virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim); 427 428 // TRUE if you just stopped 429 bool endOfPath(); 430 431 // Change the pattern of a character to STOP 432 virtual void stop(CORO_PARAM); 433 434 // Check if the character is moving 435 bool isMoving(); 436 437 // Move the character to a certain position 438 void move(CORO_PARAM, RMPoint pt, bool *result = NULL); 439 440 // Place the character in a certain position WITHOUT moving 441 void setPosition(const RMPoint &pt, int newloc = -1); 442 443 // Wait for the end of movement 444 void waitForEndMovement(CORO_PARAM); 445 446 void setFixedScroll(const RMPoint &fix); 447 void setSpeed(int speed); 448 }; 449 450 class RMWipe : public RMGfxTask { 451 private: 452 bool _bFading; 453 bool _bEndFade; 454 bool _bUnregister; 455 uint32 _hUnregistered; 456 int _nFadeStep; 457 uint32 _hEndOfFade; 458 bool _bMustRegister; 459 460 RMItem _wip0r; 461 462 public: 463 RMWipe(); 464 virtual ~RMWipe(); 465 466 void doFrame(RMGfxTargetBuffer &bigBuf); 467 virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim); 468 469 void initFade(int type); 470 void closeFade(); 471 void waitForFadeEnd(CORO_PARAM); 472 473 virtual void unregister(); 474 virtual void removeThis(CORO_PARAM, bool &result); 475 virtual int priority(); 476 }; 477 478 /** 479 * Location 480 */ 481 class RMLocation : public RMGfxTaskSetPrior { 482 public: 483 Common::String _name; // Name 484 485 private: 486 RMColorMode _cmode; // Color mode 487 RMGfxSourceBuffer *_buf; // Location picture 488 489 int _nItems; // Number of objects 490 RMItem *_items; // Objects 491 492 RMPoint _curScroll; // Current scroll position 493 RMPoint _fixedScroll; 494 495 RMPoint _prevScroll; // Previous scroll position 496 RMPoint _prevFixedScroll; 497 498 public: 499 // @@@@@@@@@@@@@@@@@@@@@@@ 500 501 RMPoint TEMPTonyStart; 502 RMPoint TEMPGetTonyStart(); 503 504 int TEMPNumLoc; 505 int TEMPGetNumLoc(); 506 507 public: 508 RMLocation(); 509 virtual ~RMLocation(); 510 511 // Load variations 512 bool load(Common::SeekableReadStream &ds); 513 bool loadLOX(Common::SeekableReadStream &ds); 514 515 // Unload 516 void unload(); 517 518 // Overloaded draw 519 virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim); 520 521 // Prepare a frame by drawing the location and all it's items 522 void doFrame(RMGfxTargetBuffer *bigBuf); 523 524 // Return the item at a given point 525 RMItem *whichItemIsIn(const RMPoint &pt); 526 527 // Return the item based on it's MPAL code 528 RMItem *getItemFromCode(uint32 dwCode); 529 530 // Set the current scroll position 531 void setScrollPosition(const RMPoint &scroll); 532 533 // Sets an additinal offset for scrolling 534 void setFixedScroll(const RMPoint &scroll); 535 536 // Update the scrolling coordinates to display the specified point 537 void updateScrolling(const RMPoint &ptShowThis); 538 539 // Read the current scroll position 540 RMPoint scrollPosition(); 541 542 // Pause sound 543 void pauseSound(bool bPause); 544 }; 545 546 /** 547 * MPAL message, composed of more ASCIIZ 548 */ 549 class RMMessage { 550 private: 551 char *_lpMessage; 552 char *_lpPeriods[256]; 553 int _nPeriods; 554 555 private: 556 void parseMessage(); 557 558 public: 559 RMMessage(); 560 RMMessage(uint32 dwId); 561 virtual ~RMMessage(); 562 563 void load(uint32 dwId); 564 bool isValid(); 565 int numPeriods(); 566 char *period(int num); 567 char *operator[](int num); 568 }; 569 570 } // End of namespace Tony 571 572 #endif /* TONY_H */ 573