ScummVM API documentation
tile.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  * Based on the original sources
22  * Faery Tale II -- The Halls of the Dead
23  * (c) 1993-1996 The Wyrmkeep Entertainment Co.
24  */
25 
26 #ifndef SAGA2_TILE_H
27 #define SAGA2_TILE_H
28 
29 #include "common/memstream.h"
30 #include "saga2/fta.h"
31 #include "saga2/tileload.h"
32 #include "saga2/annoy.h"
33 #include "saga2/terrain.h"
34 #include "saga2/property.h"
35 #include "saga2/tcoords.h"
36 
37 namespace Saga2 {
38 
39 /* ===================================================================== *
40  Tile ID's and associated functions
41  * ===================================================================== */
42 
43 class TileBank;
44 typedef TileBank *TileBankPtr; // pointer to tile bank
45 
46 
47 inline TileID makeTileID(int bank, int num) {
48  return (TileID)((bank << 10) | num);
49 }
50 
51 inline void TileID2Bank(TileID t, int16 &bank, int16 &num) {
52  bank = (int16)(t >> 10);
53  num = (int16)(t & 0x3ff);
54 }
55 
56 /* ===================================================================== *
57  Inline functions
58  * ===================================================================== */
59 
60 // Given a U between 0 and 3, and a V between 0 and 3, compute
61 // a terrain mask for the subtile at (U,V)
62 
63 inline int16 calcSubTileMask(int u, int v) {
64  return (int16)(1 << ((u << 2) + v));
65 }
66 
67 /* ===================================================================== *
68  Tile Attributes
69  * ===================================================================== */
70 
71 struct TileAttrs {
72 
73 
74  // Height above base of tile below which terrain has effect
75  uint8 terrainHeight;
76 
77  // Visual information
78  uint8 height; // height of tile bitmap
79 
80  // Terrain information
81 
82  uint16 terrainMask; // 16 terrain selector bits
83  uint8 fgdTerrain,
84  bgdTerrain;
85 
86  // Reserved bytes
87  uint8 reserved0[8]; // auto-terrain data
88 
89  // Masking information
90 
91  uint8 maskRule, // which tile masking rule to use
92  altMask; // for tiles with special masks
93 
94  // Altitude information
95 
96  uint8 cornerHeight[4];
97 
98  // Animation information
99 
100  uint8 cycleRange; // cycle range for tile
101  uint8 tileFlags; // various flags for tile
102 
103  // Reserved bytes
104  uint16 reserved1;
105 
106  int32 testTerrain(int16 mask) {
107  int32 terrain = 0;
108 
109  if (terrainMask & mask) terrain |= (1 << fgdTerrain);
110  if (~terrainMask & mask) terrain |= (1 << bgdTerrain);
111  return terrain;
112  }
113 };
114 
115 enum tile_flags {
116  // This tile has been used in at least one activity group
117  kTileInGroup = (1 << 0),
118 
119  // Indicates that an activity group should be placed in lieu
120  // of the tile.
121  kTileAutoGroup = (1 << 1),
122 
123  // Indicates that the tile is sensitive to being walked on
124  kTileWalkSense = (1 << 2),
125 
126  // Indicates that tile has been recently modified
127  kTileModified = (1 << 3)
128 };
129 
130 /* ===================================================================== *
131  Terrain types
132  * ===================================================================== */
133 
134 enum terrainTypes {
135  kTerrNumNormal = 0,
136  kTerrNumEasy,
137  kTerrNumRough,
138  kTerrNumStone,
139  kTerrNumWood,
140  kTerrNumHedge,
141  kTerrNumTree,
142  kTerrNumWater,
143  kTerrNumFall,
144  kTerrNumRamp,
145  kTerrNumStair,
146  kTerrNumLadder,
147  kTerrNumObject,
148  kTerrNumActive,
149  kTerrNumSlash,
150  kTerrNumBash,
151  kTerrNumIce,
152  kTerrNumCold,
153  kTerrNumHot,
154  kTerrNumFurniture
155 };
156 
157 enum terrainBits {
158  kTerrainNormal = (1 << kTerrNumNormal), // clear terrain
159  kTerrainEasy = (1 << kTerrNumEasy), // easy terrain (path)
160  kTerrainRough = (1 << kTerrNumRough), // rough terrain (shrub)
161  kTerrainStone = (1 << kTerrNumStone), // stone obstacle
162  kTerrainWood = (1 << kTerrNumWood), // wood obstacle
163  kTerrainHedge = (1 << kTerrNumHedge), // penetrable obstacle
164  kTerrainTree = (1 << kTerrNumTree), // tree obstacle
165  kTerrainWater = (1 << kTerrNumWater), // water (depth given by height)
166  kTerrainFall = (1 << kTerrNumFall), // does not support things
167  kTerrainRamp = (1 << kTerrNumRamp), // low friction slope
168  kTerrainStair = (1 << kTerrNumStair), // high friction slope
169  kTerrainLadder = (1 << kTerrNumLadder), // vertical climb
170  kTerrainObject = (1 << kTerrNumObject), // collision with other object
171  kTerrainActive = (1 << kTerrNumActive), // tile is sensitive to walking on
172  kTerrainSlash = (1 << kTerrNumSlash), // Slide Down Slope Left
173  kTerrainBash = (1 << kTerrNumBash), // Slide Down Slope Left
174  kTerrainIce = (1 << kTerrNumIce),
175  kTerrainCold = (1 << kTerrNumCold),
176  kTerrainHot = (1 << kTerrNumHot),
177  kTerrainFurniture = (1 << kTerrNumFurniture)
178 };
179 
180 // A combination mask of all the terrain types which can have
181 // sloped surfaces. (Water is a negative sloped surface)
182 
183 const int kTerrainSurface = kTerrainNormal
184  | kTerrainEasy
185  | kTerrainRough
186  | kTerrainWater
187  | kTerrainRamp
188  | kTerrainCold
189  | kTerrainStair;
190 
191 const int kTerrainSolidSurface
192  = kTerrainNormal
193  | kTerrainEasy
194  | kTerrainRough
195  | kTerrainRamp
196  | kTerrainCold
197  | kTerrainStair;
198 
199 // A combination mask of all terrain types which can have
200 // raised surfaces.
201 
202 const int kTerrainRaised = kTerrainStone
203  | kTerrainWood
204  | kTerrainTree
205  | kTerrainHedge
206  | kTerrainFurniture;
207 
208 const int kTerrainSupportingRaised = kTerrainStone
209  | kTerrainWood
210  | kTerrainFurniture;
211 
212 const int kTerrainImpassable = kTerrainStone
213  | kTerrainWood
214  | kTerrainTree
215  | kTerrainHedge
216  | kTerrainFurniture;
217 
218 const int kTerrainSlow = kTerrainRough
219  | kTerrainWater
220  | kTerrainLadder;
221 
222 const int kTerrainAverage = kTerrainNormal
223  | kTerrainRamp
224  | kTerrainStair;
225 
226 const int kTerrainInsubstantial = kTerrainFall
227  | kTerrainLadder
228  | kTerrainSlash
229  | kTerrainBash;
230 
231 const int kTerrainTransparent = kTerrainSurface
232  | kTerrainInsubstantial;
233 
234 
235 /* ===================================================================== *
236  Describes an individual tile
237  * ===================================================================== */
238 
239 struct TileInfo {
240  uint32 offset; // offset in tile list
241  TileAttrs attrs; // tile attributes
242 
243  int32 combinedTerrainMask() {
244  return (1 << attrs.fgdTerrain) | (1 << attrs.bgdTerrain);
245  }
246 
247  bool hasProperty(const TileProperty &tileProp) {
248  return tileProp.operator()(this);
249  }
250 
251  static TileInfo *tileAddress(TileID id);
252  static TileInfo *tileAddress(TileID id, uint8 **imageData);
253 };
254 
255 /* ===================================================================== *
256  Describes a bank of tiles
257  * ===================================================================== */
258 
259 class TileBank {
260 public:
261  uint32 _numTiles; // number of tiles in list
262  TileInfo *_tileArray; // variable-sized array
263 
264  TileBank() {
265  _numTiles = 0;
266  _tileArray = nullptr;
267  }
268 
270  ~TileBank();
271 
272  TileInfo *tile(uint16 index) {
273  return &_tileArray[index];
274  }
275 };
276 
277 
278 /* ===================================================================== *
279  TileRef: This structure is used whenever a tile is positioned on a
280  map or TAG. It contains the tile, the tile height, and various flags.
281  * ===================================================================== */
282 
283 struct TileRef {
284  TileID tile; // which tile
285  uint8 flags; // tile flags
286  uint8 tileHeight; // height of tile above platform
287 };
288 
289 enum tileRefFlags {
290  kTrTileTAG = (1 << 0), // this tile part of a TAG
291  kTrTileHidden = (1 << 1), // tile hidden when covered
292  kTrTileFlipped = (1 << 2), // draw tile flipped horizontal
293  kTrTileSensitive = (1 << 3) // tile is triggerable (TAG only)
294 };
295 
296 typedef TileRef *TileRefPtr, **TileRefHandle;
297 
298 void drawMainDisplay();
299 
300 /* ===================================================================== *
301  TileCycleData: This structure is used to define continuously cycling
302  tiles such as waves on the ocean or a flickering torch.
303  * ===================================================================== */
304 
306 public:
307  int32 _counter; // cycling counter
308  uint8 _pad; // odd-byte pad
309  uint8 _numStates, // number of animated states
310  _currentState, // current state of animation
311  _cycleSpeed; // speed of cycling (0=none)
312 
313  TileID _cycleList[16]; // array of tiles
314 
315  void load(Common::SeekableReadStream *stream) {
316  _counter = stream->readSint32LE();
317  _pad = stream->readByte();
318  _numStates = stream->readByte();
319  _currentState = stream->readByte();
320  _cycleSpeed = stream->readByte();
321 
322  for (int i = 0; i < 16; ++i)
323  _cycleList[i] = stream->readUint16LE();
324  }
325 };
326 
327 typedef TileCycleData *CyclePtr, // pointer to cycle data
328  **CycleHandle; // handle to cycle data
329 
330 const int kMaxCycleRanges = 128; // 128 should do for now...
331 
332 /* ===================================================================== *
333  ActiveTileItem: This is the base class for all of the behavioral
334  objects which can be placed on a tilemap.
335  * ===================================================================== */
336 
337 enum ActiveItemTypes {
338  kActiveTypeGroup = 0,
339  kActiveTypeInstance
340 };
341 
342 // A pointer to the array of active item state arrays
343 extern byte **stateArray;
344 
345 class ActiveItemList;
346 
347 class ActiveItem;
348 
349 #include "common/pack-start.h"
350 
352  uint32 nextHashDummy; // next item in hash chain
353  uint16 scriptClassID; // associated script object
354  uint16 associationOffset; // offset into association table
355  uint8 numAssociations; // number of associated items
356  uint8 itemType; // item type code.
357 
358  union {
359  struct {
360  uint16 grDataOffset; // offset to group data
361  uint8 numStates, // number of animated states
362  uSize, // dimensions of group
363  vSize,
364  animArea, // uSize * vSize
365  triggerWeight, // sensitivity
366  pad;
367  uint16 reserved0;
368  uint16 reserved1;
369  } group;
370 
371  struct {
372  int16 groupID; // id of defining group
373  int16 u, v, h;
374  uint16 stateIndex; // for state-based anims.
375  uint16 scriptFlags;
376  uint16 targetU, // U-coord of target
377  targetV; // V-coord of target
378  uint8 targetZ, // Z-coord of target
379  worldNum; // Add 0xf000 to get world Object ID
380  } instance;
381  };
382 
383  ActiveItem *aItem; // active item this ActiveItemData is a part of
384 } PACKED_STRUCT;
385 
386 #include "common/pack-end.h"
387 
388 class ActiveItem {
389 public:
390  ActiveItem *_nextHash; // next item in hash chain
391  int _index;
392  ActiveItemList *_parent;
393  ActiveItemData _data;
394 
395  enum {
396  kActiveItemLocked = (1 << 8), // The door is locked
397  kActiveItemOpen = (1 << 9), // The door is open (not used)
398  kActiveItemExclusive = (1 << 10) // Script semaphore
399  };
400 
401  ActiveItem(ActiveItemList *parent, int ind, Common::SeekableReadStream *stream);
402 
403  // Return the map number of this active item
404  int16 getMapNum();
405 
406  // Return the address of an active item, given its ID
407  static ActiveItem *activeItemAddress(ActiveItemID id);
408 
409  // Return this active items ID
410  ActiveItemID thisID();
411 
412  // Return this active items ID
413  ActiveItemID thisID(int16 mapNum);
414 
415  // Return a pointer to this TAI's group
416  ActiveItem *getGroup() {
417  assert(_data.itemType == kActiveTypeInstance);
418  return activeItemAddress(ActiveItemID(getMapNum(), _data.instance.groupID));
419  }
420 
421  enum BuiltInBehaviorType {
422  kBuiltInNone = 0, // TAG handled by SAGA
423  kBuiltInLamp, // TAG has lamp behavior
424  kBuiltInDoor, // TAG has door behavior
425  kBuiltInTransporter // TAG has transporter behavior
426  };
427 
428  // Return the state number of this active item instance
429  uint8 getInstanceState(int16 mapNum) {
430  return stateArray[mapNum][_data.instance.stateIndex];
431  }
432 
433  // Set the state number of this active item instance
434  void setInstanceState(int16 mapNum, uint8 state) {
435  stateArray[mapNum][_data.instance.stateIndex] = state;
436  }
437 
438  uint8 builtInBehavior() {
439  return (uint8)(_data.instance.scriptFlags >> 13);
440  }
441 
442  // Access to the locked bit
443  bool isLocked() {
444  return (bool)(_data.instance.scriptFlags & kActiveItemLocked);
445  }
446  void setLocked(bool val) {
447  if (val)
448  _data.instance.scriptFlags |= kActiveItemLocked;
449  else
450  _data.instance.scriptFlags &= ~kActiveItemLocked;
451  }
452 
453  // Access to the exclusion semaphore
454  bool isExclusive() {
455  return (bool)(_data.instance.scriptFlags & kActiveItemExclusive);
456  }
457  void setExclusive(bool val) {
458  if (val)
459  _data.instance.scriptFlags |= kActiveItemExclusive;
460  else
461  _data.instance.scriptFlags &= ~kActiveItemExclusive;
462  }
463 
464  uint8 lockType() {
465  return (uint8)_data.instance.scriptFlags;
466  }
467 
468  // ActiveItem instance methods
469  bool use(ObjectID enactor);
470  bool trigger(ObjectID enactor, ObjectID objID);
471  bool release(ObjectID enactor, ObjectID objID);
472  bool acceptLockToggle(ObjectID enactor, uint8 keyCode);
473 
474  bool inRange(const TilePoint &loc, int16 range);
475 
476  // ActiveItem group methods
477  bool use(ActiveItem *ins, ObjectID enactor);
478  bool trigger(ActiveItem *ins, ObjectID enactor, ObjectID objID);
479  bool release(ActiveItem *ins, ObjectID enactor, ObjectID objID);
480  bool acceptLockToggle(ActiveItem *ins, ObjectID enactor, uint8 keyCode);
481 
482  bool inRange(ActiveItem *ins, const TilePoint &loc, int16 range) {
483  return loc.u >= ins->_data.instance.u - range
484  && loc.v >= ins->_data.instance.v - range
485  && loc.u < ins->_data.instance.u + _data.group.uSize + range
486  && loc.v < ins->_data.instance.v + _data.group.vSize + range;
487  }
488 
489  ObjectID getInstanceContext();
490  Location getInstanceLocation();
491 
492  static void playTAGNoise(ActiveItem *ai, int16 tagNoiseID);
493 
494 };
495 
496 typedef ActiveItem *ActiveItemPtr,
498 
499 struct WorldMapData;
500 
502 public:
503  int _count;
504  ActiveItem **_items;
505  WorldMapData *_parent;
506 
507  ActiveItemList(WorldMapData *parent, int count, Common::SeekableReadStream *stream);
508  ~ActiveItemList();
509 };
510 
511 #if 0
512 
513 /* ===================================================================== *
514  TileHitZone: This object represents a large region which overlays the
515  tile map without affecting it's appearance. It does not contain any
516  tiles or animation information, it is a behavioral region only.
517  It can be much larger and more complex in shape than an activity group.
518  * ===================================================================== */
519 
520 class TileHitZone : public ActiveItem {
521 public:
522 
523  // REM: Allow discontiguous regions??
524  int16 _numVertices;
525  XArray<Point16> _vertexList;
526 
527  int16 type() {
528  return activeTypeHitZone;
529  }
530 };
531 
532 class ObjectClass : public ActiveItem {
533 public:
534  // A general type of object
535 
536  int16 type() {
537  return activeTypeObjectType;
538  }
539 };
540 
541 class ObjectInstance : public ActiveItem {
542 public:
543  TileGroupID _classID; // ID of object class
544 
545  // An instance of a specific object.
546 
547  uint16 _u, _v, _h; // where the instance lies
548  uint8 _facing; // which direction it's facing
549 
550  int16 type() {
551  return activeTypeObject;
552  }
553 };
554 #endif
555 
556 
557 /* ============================================================================ *
558  TileActivityTask class
559  * ============================================================================ */
560 
561 // This class handles the built-in movement of active terrain items. It
562 // includes things like opening/closing doors, and toggling lamps.
563 //
564 // Since most things in the game aren't moving at a given point, the
565 // variables for simulating motion don't need to always be present.
566 
568  friend class TileActivityTaskList;
569  friend class ActiveItem;
570 
571  uint8 _activityType; // open or close
572  uint8 _targetState;
573  ActiveItem *_tai; // the tile activity instance
574  ThreadID _script; // script to wake up when task done
575 
576  enum activityTypes {
577  kActivityTypeNone, // no activity
578 
579  kActivityTypeOpen, // open door
580  kActivityTypeClose, // close door
581 
582  kActivityTypeScript // scriptable activity
583  };
584 
585  void remove(); // tile activity task is finished.
586 
587 public:
588 
589  // Functions to create a new tile activity task.
590  static void openDoor(ActiveItem &activeInstance);
591  static void closeDoor(ActiveItem &activeInstance);
592  static void doScript(ActiveItem &activeInstance, uint8 finalState, ThreadID id);
593 
594  static void updateActiveItems();
595 
596  static void initTileActivityTasks();
597 
598  static TileActivityTask *find(ActiveItem *tai);
599  static bool setWait(ActiveItem *tai, ThreadID script);
600 };
601 
602 /* ============================================================================ *
603  TileActivityTaskList class
604  * ============================================================================ */
605 
607  friend class TileActivityTask;
608 
609 public:
611 
612  // Constructor -- initial construction
614 
615  // Reconstruct the TileActivityTaskList from an archive buffer
617 
618  void read(Common::InSaveFile *in);
619  void write(Common::MemoryWriteStreamDynamic *out);
620 
621  // Cleanup this list
622  void cleanup();
623 
624  // get new tile activity task
625  TileActivityTask *newTask(ActiveItem *activeInstance);
626 };
627 
628 void moveActiveTerrain(int32 deltaTime);
629 
630 /* ===================================================================== *
631  A structure to record special return values from tileSlopeHeight
632  * ===================================================================== */
633 
635  TileInfo *surfaceTile;
636  ActiveItemPtr surfaceTAG;
637  TileRef surfaceRef;
638  int16 surfaceHeight;
639 };
640 
641 /* ======================================================================= *
642  Platform struct
643  * ======================================================================= */
644 
645 const int kMaxPlatforms = 8;
646 
647 struct Platform {
648  uint16 height, // height above ground
649  highestPixel; // tallest tile upper extent
650  uint16 flags; // platform flags
651  TileRef tiles[kPlatformWidth][kPlatformWidth];
652 
653  void load(Common::SeekableReadStream *stream) {
654  height = stream->readUint16LE();
655  highestPixel = stream->readUint16LE();
656  flags = stream->readUint16LE();
657 
658  for (int j = 0; j < kPlatformWidth; ++j) {
659  for (int i = 0; i < kPlatformWidth; ++i) {
660  tiles[j][i].tile = stream->readUint16LE();
661  tiles[j][i].flags = stream->readByte();
662  tiles[j][i].tileHeight = stream->readByte();
663  }
664  }
665  }
666 
667  TileRef &getTileRef(const TilePoint p) {
668  return tiles[p.u][p.v];
669  }
670 
671  TileRef &getTileRef(int16 u, int16 v) {
672  return tiles[u][v];
673  }
674 
675  // fetch the REAL tile terrain info
676  TileInfo *fetchTile(int16 mapNum,
677  const TilePoint &pt,
678  const TilePoint &origin,
679  int16 &height,
680  int16 &trFlags);
681 
682  // Fetch the tile and the active item it came from...
683  TileInfo *fetchTAGInstance(
684  int16 mapNum,
685  const TilePoint &pt,
686  const TilePoint &origin,
687  StandingTileInfo &sti);
688 
689  // fetch the REAL tile terrain info and image data
690  TileInfo *fetchTile(int16 mapNum,
691  const TilePoint &pt,
692  const TilePoint &origin,
693  uint8 **imageData,
694  int16 &height,
695  int16 &trFlags);
696 
697  // Fetch the tile and image data and the active item it came from...
698  TileInfo *fetchTAGInstance(
699  int16 mapNum,
700  const TilePoint &pt,
701  const TilePoint &origin,
702  uint8 **imageData,
703  StandingTileInfo &sti);
704 
705  uint16 roofRipID() {
706  return (uint16)(flags & 0x0FFF);
707  }
708 };
709 
710 typedef Platform *PlatformPtr,
711  * *PlatformHandle;
712 
713 enum platformFlags {
714  kPlCutaway = (1 << 0), // remove when player underneath
715 
716  // Cutaway directions: When platform is cut away, also cut
717  // away any adjacent platforms in these directions.
718  kPlVisible = (1 << 15), // platform is visible
719  kPlModified = (1 << 14), // platform has been changed
720  kPlCutUPos = (1 << 13),
721  kPlCutUNeg = (1 << 13),
722  kPlCutVPos = (1 << 13),
723  kPlCutVNeg = (1 << 13)
724 };
725 
726 #ifdef OLDPLATFLAAGS
727 enum platformFlags {
728  kPlCutaway = (1 << 0), // remove when player underneath
729 
730  // Cutaway directions: When platform is cut away, also cut
731  // away any adjacent platforms in these directions.
732 
733  kPlCutUPos = (1 << 1),
734  kPlCutUNeg = (1 << 2),
735  kPlCutVPos = (1 << 3),
736  kPlCutVNeg = (1 << 4),
737 
738  kPlVisible = (1 << 5), // platform is visible
739  kPlEnabled = (1 << 6) // enforce platform terrain.
740 };
741 #endif
742 
743 /* ======================================================================= *
744  PlatformCacheEntry struct
745  * ======================================================================= */
746 
748  uint16 platformNum, // original platform num
749  layerNum; // index of this plat in mt.
750  MetaTileID metaID; // pointer to parent metatile
751  Platform pl; // actual platform data
752 
753  enum {
754  kPlatformCacheSize = 256
755  };
756 };
757 
758 /* ======================================================================= *
759  RipTable struct
760  * ======================================================================= */
761 
762 // An object roof ripping "z-buffer" type structure
763 
764 typedef int16 RipTableID;
765 
766 struct RipTable {
767  MetaTileID metaID;
768  uint16 ripID;
769  int16 zTable[kPlatformWidth][kPlatformWidth];
770  int _index;
771 
772  enum {
773  kRipTableSize = 25
774  };
775 
776  // Constructor
777  RipTable() : metaID(NoMetaTile), ripID(0), _index(-1) {
778  for (int i = 0; i < kPlatformWidth; i++)
779  for (int j = 0; j < kPlatformWidth; j++)
780  zTable[i][j] = 0;
781  }
782 
783  // Return a pointer to a rip table, given the rip table's ID
784  static RipTable *ripTableAddress(RipTableID id);
785 
786  // Return the rip table's ID
787  RipTableID thisID();
788 };
789 
790 typedef RipTable *RipTablePtr;
791 typedef RipTableID *RipTableIDPtr,
792  **RipTableIDHandle;
793 
794 typedef uint16 metaTileNoise;
795 
796 /* ======================================================================= *
797  MetaTile struct
798  * ======================================================================= */
799 
800 // A "Metatile" is a larger tile made up of smaller tiles.
801 
802 class MetaTileList;
803 
804 class MetaTile {
805 public:
806  uint16 _highestPixel; // more drawing optimization
807  BankBits _banksNeeded; // which banks are needed
808  uint16 _stack[kMaxPlatforms]; // pointer to platforms
809  uint32 _properties; // more drawing optimization
810  int _index;
811  MetaTileList *_parent;
812 
813  MetaTile(MetaTileList *parent, int ind, Common::SeekableReadStream *stream);
814 
815  // Return a pointer to a meta tile given its ID
816  static MetaTile *metaTileAddress(MetaTileID id);
817 
818  // Return this meta tile's ID
819  MetaTileID thisID(int16 mapNum);
820 
821  // Return a pointer to the specified platform
822  Platform *fetchPlatform(int16 mapNum, int16 index);
823 
824  // Return a pointer to this metatile's current object ripping
825  // table
826  RipTable *ripTable(int16 mapNum);
827 
828  // Return a reference to this meta tile's rip table ID
829  RipTableID &ripTableID(int16 mapNum);
830 
831  metaTileNoise HeavyMetaMusic();
832 
833  bool hasProperty(
834  const MetaTileProperty &metaTileProp,
835  int16 mapNum,
836  const TilePoint &mCoords) {
837  return metaTileProp(this, mapNum, mCoords);
838  }
839 };
840 
841 typedef MetaTile *MetaTilePtr,
842  * *MetaTileHandle;
843 
845 public:
846  int _count;
847  MetaTile **_tiles;
848 
849  MetaTileList(int count, Common::SeekableReadStream *stream);
850  ~MetaTileList();
851 };
852 
853 /* ===================================================================== *
854  MapHeader struct
855  * ===================================================================== */
856 
857 struct MapHeader {
858  int16 size; // size of map
859  int16 edgeType; // edge type of map
860  uint16 *mapData; // start of map array
861 
863  ~MapHeader();
864 };
865 
866 enum mapEdgeTypes {
867  kEdgeTypeBlack = 0,
868  kEdgeTypeFill0,
869  kEdgeTypeFill1,
870  kEdgeTypeRepeat,
871  kEdgeTypeWrap
872 };
873 
874 typedef MapHeader *MapPtr,
875  * *MapHandle;
876 
877 /* ===================================================================== *
878  WorldMapData struct
879  * ===================================================================== */
880 
881 const uint16 kMetaTileVisited = (1 << 15);
882 
883 struct WorldMapData {
884  ObjectID worldID; // The number of this map
885 
886  MapPtr map; // Map data
887  MetaTileList *metaList; // MetaTile list
888  TileRefPtr activeItemData; // ActiveItem tileRefs
889  ActiveItemList *activeItemList; // ActiveItem list
890  uint16 *assocList; // Associations
891  RipTableIDPtr ripTableIDList; // MetaTile object ripping
892 
893  ActiveItem *instHash[513]; // ActiveItem hash table
894 
895  int16 metaCount, // Number of MetaTiles
896  activeCount; // Number of ActiveItems
897  int16 mapSize; // Size of map in meta tiles
898  int32 mapHeight; // Height of map in Y
899 
900 
901  // Lookup metatile on map.
902  MetaTilePtr lookupMeta(TilePoint coords);
903 
904  // Build active item instance hash table
905  void buildInstanceHash();
906 
907  // Return a pointer to an active item instance based upon the
908  // group ID and the MetaTile's coordinates
909  ActiveItem *findHashedInstance(TilePoint &tp, int16 group);
910 };
911 
912 /* ===================================================================== *
913  MetaTileIterator class
914  * ===================================================================== */
915 
917  TilePoint _mCoords;
918  TileRegion _region;
919 
920  int16 _mapNum;
921 
922  bool iterate();
923 
924 public:
925  MetaTileIterator(int16 map, const TileRegion &reg) : _mapNum(map) {
926  _region.min.u = reg.min.u >> kPlatShift;
927  _region.max.u = (reg.max.u + kPlatMask) >> kPlatShift;
928  _region.min.v = reg.min.v >> kPlatShift;
929  _region.max.v = (reg.max.v + kPlatMask) >> kPlatShift;
930  _region.min.z = _region.max.z = 0;
931  }
932 
933  MetaTile *first(TilePoint *loc = NULL);
934  MetaTile *next(TilePoint *loc = NULL);
935 
936  int16 getMapNum() {
937  return _mapNum;
938  }
939 };
940 
941 /* ===================================================================== *
942  TileIterator class
943  * ===================================================================== */
944 
946  MetaTileIterator _metaIter;
947  MetaTile *_mt;
948  int16 _platIndex;
949  Platform *_platform;
950  TilePoint _tCoords,
951  _origin;
952  TileRegion _region,
953  _tCoordsReg;
954 
955  bool iterate();
956 
957 public:
958  TileIterator(int16 mapNum, const TileRegion &reg) :
959  _metaIter(mapNum, reg),
960  _region(reg) {
961  _mt = nullptr;
962  _platIndex = 0;
963  _platform = nullptr;
964  }
965 
966  TileInfo *first(TilePoint *loc, StandingTileInfo *stiResult = NULL);
967  TileInfo *next(TilePoint *loc, StandingTileInfo *stiResult = NULL);
968 };
969 
970 /* ===================================================================== *
971  Exports
972  * ===================================================================== */
973 
974 extern StaticTilePoint viewCenter; // coordinates of view on map
975 
976 // These two variables define which sectors overlap the view rect.
977 
978 extern uint16 rippedRoofID;
979 
980 /* ===================================================================== *
981  Prototypes
982  * ===================================================================== */
983 
984 // Initialize map data
985 void initMaps();
986 
987 // Cleanup map data
988 void cleanupMaps();
989 
990 void setCurrentMap(int mapNum); // set which map is current
991 
992 // Initialize the platform cache
993 void initPlatformCache();
994 
995 // Initialize the tile activity task list
996 void initTileTasks();
997 
998 void saveTileTasks(Common::OutSaveFile *outS);
999 void loadTileTasks(Common::InSaveFile *in, int32 chunkSize);
1000 
1001 // Cleanup the tile activity task list
1002 void cleanupTileTasks();
1003 
1004 TilePoint getClosestPointOnTAI(ActiveItem *TAI, GameObject *obj);
1005 
1006 void initActiveItemStates();
1007 void saveActiveItemStates(Common::OutSaveFile *outS);
1008 void loadActiveItemStates(Common::InSaveFile *in);
1009 void cleanupActiveItemStates();
1010 
1011 void initTileCyclingStates();
1012 void saveTileCyclingStates(Common::OutSaveFile *outS);
1013 void loadTileCyclingStates(Common::InSaveFile *in);
1014 void cleanupTileCyclingStates();
1015 
1016 void initAutoMap();
1017 void saveAutoMap(Common::OutSaveFile *outS);
1018 void loadAutoMap(Common::InSaveFile *in, int32 chunkSize);
1019 inline void cleanupAutoMap() { /* nothing to do */ }
1020 
1021 // Determine if a platform is ripped
1022 inline bool platformRipped(Platform *pl) {
1023  if (rippedRoofID != 0)
1024  return pl->roofRipID() == rippedRoofID;
1025 
1026  return false;
1027 }
1028 
1029 // Compute visible area in U/V coords
1030 TilePoint XYToUV(const Point32 &pt);
1031 void TileToScreenCoords(const TilePoint &tp, Point16 &p);
1032 void TileToScreenCoords(const TilePoint &tp, StaticPoint16 &p);
1033 
1034 // Determine height of point on a tile based on four corner heights
1035 int16 ptHeight(const TilePoint &tp, uint8 *cornerHeight);
1036 
1037 
1038 /* --------------------------------------------------------------------- *
1039  Prototypes for TERRAIN.CPP moved to terrain.h
1040  * --------------------------------------------------------------------- */
1041 
1042 
1043 // Determine which roof is above object
1044 uint16 objRoofID(GameObject *obj);
1045 uint16 objRoofID(GameObject *obj, int16 objMapNum, const TilePoint &objCoords);
1046 
1047 // Determine if roof over an object is ripped
1048 bool objRoofRipped(GameObject *obj);
1049 
1050 // Determine if two objects are both under the same roof
1051 bool underSameRoof(GameObject *obj1, GameObject *obj2);
1052 
1053 // Determine the distance between a point and a line
1054 uint16 lineDist(
1055  const TilePoint &p1,
1056  const TilePoint &p2,
1057  const TilePoint &m);
1058 
1059 /* ============================================================================ *
1060  Misc prototypes
1061  * ============================================================================ */
1062 
1063 // Converts Local XY to UV coordinates
1064 StaticTilePoint pickTilePos(Point32 pos, const TilePoint &protagPos);
1065 StaticTilePoint pickTile(Point32 pos,
1066  const TilePoint &protagPos,
1067  StaticTilePoint *floor = NULL,
1068  ActiveItemPtr *pickTAI = NULL);
1069 
1070 // Function to select a nearby site
1071 TilePoint selectNearbySite(
1072  ObjectID worldID,
1073  const TilePoint &startingCoords,
1074  int32 minDist,
1075  int32 maxDist,
1076  bool offScreenOnly = false); // true if we want it off-screen
1077 
1078 void drawMetaTiles(gPixelMap &drawMap);
1079 
1080 } // end of namespace Saga2
1081 
1082 #endif
Definition: tile.h:259
Definition: tile.h:71
Definition: tile.h:766
Definition: rect.h:184
Definition: tile.h:239
uint16 readUint16LE()
Definition: stream.h:459
Definition: tile.h:388
Definition: objproto.h:105
FORCEINLINE int32 readSint32LE()
Definition: stream.h:555
Definition: savefile.h:54
Definition: tile.h:945
Definition: property.h:284
Definition: actor.h:32
Definition: idtypes.h:124
Definition: gdraw.h:56
In find(In first, In last, const T &v)
Definition: algorithm.h:225
Definition: list.h:44
Definition: memstream.h:194
Definition: tcoords.h:127
Definition: stream.h:745
Definition: tcoords.h:222
Definition: tile.h:916
Definition: tile.h:747
Definition: tcoords.h:48
Definition: tile.h:606
byte readByte()
Definition: stream.h:434
Definition: tile.h:305
Definition: rect.h:42
Definition: tile.h:634
Definition: tile.h:804
Definition: objects.h:118
Definition: tile.h:844
Definition: tile.h:567
Definition: idtypes.h:73
Definition: tileload.h:41
Definition: tile.h:501
Definition: rect.h:33
Definition: tile.h:857
Definition: property.h:45
Definition: tile.h:883
Definition: tile.h:647
Definition: tile.h:351
Definition: tile.h:283