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