aboutsummaryrefslogtreecommitdiff
path: root/engines/lure
diff options
context:
space:
mode:
authorPaul Gilbert2006-04-11 10:43:53 +0000
committerPaul Gilbert2006-04-11 10:43:53 +0000
commitf6b2cf2c6dcc37c54913ad2209545002727ee6fd (patch)
treeb9a44cad20be0fe7e5d558fbda3ee2b2a71d1be9 /engines/lure
parent70654bc2a97e063169b4b603861093ba6593ff34 (diff)
downloadscummvm-rg350-f6b2cf2c6dcc37c54913ad2209545002727ee6fd.tar.gz
scummvm-rg350-f6b2cf2c6dcc37c54913ad2209545002727ee6fd.tar.bz2
scummvm-rg350-f6b2cf2c6dcc37c54913ad2209545002727ee6fd.zip
Updated resource structures to add support for hotspot y corrections, proximity data, room walkable areas, and the room exit coordinate list
svn-id: r21779
Diffstat (limited to 'engines/lure')
-rw-r--r--engines/lure/res_struct.cpp178
-rw-r--r--engines/lure/res_struct.h114
2 files changed, 277 insertions, 15 deletions
diff --git a/engines/lure/res_struct.cpp b/engines/lure/res_struct.cpp
index 587e25919f..75cb27f9c5 100644
--- a/engines/lure/res_struct.cpp
+++ b/engines/lure/res_struct.cpp
@@ -35,12 +35,14 @@ const char *actionList[] = {NULL, "Get", NULL, "Push", "Pull", "Operate", "Open"
// Room data holding class
-RoomData::RoomData(RoomResource *rec) {
+RoomData::RoomData(RoomResource *rec, MemoryBlock *pathData) {
roomNumber = READ_LE_UINT16(&rec->roomNumber);
descId = READ_LE_UINT16(&rec->descId);
sequenceOffset = READ_LE_UINT16(&rec->sequenceOffset);
numLayers = READ_LE_UINT16(&rec->numLayers);
+ paths.load(pathData->data() + (roomNumber - 1) * ROOM_PATHS_SIZE);
+
for (int ctr = 0; ctr < 4; ++ctr)
layers[ctr] = READ_LE_UINT16(&rec->layers[ctr]);
@@ -92,31 +94,143 @@ RoomExitData::RoomExitData(RoomExitResource *rec) {
}
bool RoomExitData::insideRect(int16 xp, int16 yp) {
- return ((xp >= xs) && (xp <= xe) && (yp >= ys) && (yp <= ye));
+ return ((xp >= xs) && (xp < xe) && (yp >= ys) && (yp < ye));
}
RoomExitData *RoomExitList::checkExits(int16 xp, int16 yp) {
iterator i;
for (i = begin(); i != end(); i++) {
RoomExitData *rec = *i;
- if (rec->insideRect(xp, yp)) return rec;
+ if (rec->insideRect(xp, yp)) {
+ return rec;
+ }
}
return NULL;
}
+// Room paths
+
+bool RoomPathsData::isOccupied(int x, int y) {
+ if ((x < 0) || (y < 0) || (x >= ROOM_PATHS_WIDTH) || (y >= ROOM_PATHS_HEIGHT))
+ // Off screen, so flag as not occupied
+ return false;
+ return (_data[y * 5 + (x >> 3)] & (0x80 >> (x % 8))) != 0;
+}
+
+void RoomPathsData::setOccupied(int x, int y, int width) {
+ if ((x < 0) || (y < 0) || (x >= ROOM_PATHS_WIDTH) || (x >= ROOM_PATHS_HEIGHT))
+ return;
+
+ byte *p = &_data[y * 5 + (x % 8)];
+ byte bitMask = 0x80 >> (x % 8);
+
+ for (int bitCtr = 0; bitCtr < width; ++bitCtr) {
+ *p |= bitMask;
+ bitMask >>= 1;
+ if (bitMask == 0) {
+ ++p;
+ bitMask = 0x80;
+ }
+ }
+}
+
+void RoomPathsData::clearOccupied(int x, int y, int width) {
+ if ((x < 0) || (y < 0) || (x >= ROOM_PATHS_WIDTH) || (x >= ROOM_PATHS_HEIGHT))
+ return;
+
+ byte *p = &_data[y * 5 + (x % 8)];
+ byte bitMask = 0x80 >> (x % 8);
+
+ for (int bitCtr = 0; bitCtr < width; ++bitCtr) {
+ *p &= !bitMask;
+ bitMask >>= 1;
+ if (bitMask == 0) {
+ ++p;
+ bitMask = 0x80;
+ }
+ }
+}
+
+// decompresses the bit-packed data for which parts of a room are occupied
+// into a byte array. It also adds a column and row of padding around the
+// edges of the screen, and extends occupied areas to adjust for the width
+// of the chracter
+
+void RoomPathsData::decompress(RoomPathsDecompressedData &dataOut, int characterWidth) {
+ byte *pIn = &_data[ROOM_PATHS_SIZE - 1];
+ uint16 *pOut = &dataOut[DECODED_PATHS_WIDTH * DECODED_PATHS_HEIGHT - 1];
+ byte v;
+ int paddingCtr;
+ int charWidth = (characterWidth - 1) >> 3;
+ int charCtr = 0;
+ bool charState = false;
+
+ // Handle padding for last row, including left/right edge padding, as
+ // well as the right column of the second row
+ for (paddingCtr = 0; paddingCtr < (DECODED_PATHS_WIDTH + 1); ++paddingCtr)
+ *pOut-- = 0;
+
+ for (int y = 0; y < ROOM_PATHS_HEIGHT; ++y) {
+ for (int x = 0; x < (ROOM_PATHS_WIDTH / 8); ++x) {
+ // Get next byte, which containing bits for 8 blocks
+ v = *pIn--;
+
+ for (int bitCtr = 0; bitCtr < 8; ++bitCtr) {
+ bool isSet = (v & 1) != 0;
+ v >>= 1;
+
+ if (charState) {
+ // Handling occupied characters adjusted for character width
+ if (isSet)
+ // Reset character counter
+ charCtr = charWidth;
+
+ *pOut-- = 0xffff;
+ charState = (--charCtr != 0);
+
+ } else {
+ // Normal decompression
+ if (!isSet) {
+ // Flag block is available for walking on
+ *pOut-- = 0;
+ } else {
+ // Flag block is occupied
+ *pOut-- = 0xffff;
+
+ // Handling for adjusting for character widths
+ charCtr = charWidth - 1;
+ charState = charCtr >= 0;
+ }
+ }
+ }
+ }
+
+ // Store 2 words to allow off-screen row-start/prior row end
+ *pOut-- = 0;
+ *pOut-- = 0;
+ charState = false;
+ }
+
+ // Handle padding for final top row - no need for end column, as end of prior
+ // row provided padding for it
+ for (paddingCtr = 0; paddingCtr < (ROOM_PATHS_WIDTH + 1); ++paddingCtr)
+ *pOut-- = 0;
+}
+
// Room exit joins class
RoomExitJoinData::RoomExitJoinData(RoomExitJoinResource *rec) {
hotspot1Id = READ_LE_UINT16(&rec->hotspot1Id);
h1CurrentFrame = rec->h1CurrentFrame;
h1DestFrame = rec->h1DestFrame;
- h1Unknown = READ_LE_UINT16(&rec->h1Unknown);
+ h1OpenSound = rec->h1OpenSound;
+ h1CloseSound = rec->h1CloseSound;
hotspot2Id = READ_LE_UINT16(&rec->hotspot2Id);
h2CurrentFrame = rec->h2CurrentFrame;
h2DestFrame = rec->h2DestFrame;
- h2Unknown = READ_LE_UINT16(&rec->h2Unknown);
+ h2OpenSound = rec->h2OpenSound;
+ h2CloseSound = rec->h2CloseSound;
blocked = rec->blocked;
- unknown = rec->unknown;
}
// Hotspot action record
@@ -159,6 +273,7 @@ HotspotData::HotspotData(HotspotResource *rec) {
height = READ_LE_UINT16(&rec->height);
widthCopy = READ_LE_UINT16(&rec->widthCopy);
heightCopy = READ_LE_UINT16(&rec->heightCopy);
+ yCorrection = READ_LE_UINT16(&rec->yCorrection);
talkX = rec->talkX;
talkY = rec->talkY;
colourOffset = READ_LE_UINT16(&rec->colourOffset);
@@ -309,6 +424,34 @@ TalkEntryData *TalkData::getResponse(int index) {
return *i;
}
+// The following class handles a set of coordinates a character should walk to
+// if they're to exit a room to a designated secondary room
+
+RoomExitCoordinates::RoomExitCoordinates(RoomExitCoordinateEntryResource *rec) {
+ int ctr;
+ for (ctr = 0; ctr < ROOM_EXIT_COORDINATES_NUM_ENTRIES; ++ctr) {
+ _entries[ctr].x = FROM_LE_16(rec->entries[ctr].x);
+ _entries[ctr].y = FROM_LE_16(rec->entries[ctr].y);
+ uint16 v = FROM_LE_16(rec->entries[ctr].roomNumber);
+ _entries[ctr].roomNumber = v & 0xfff;
+ _entries[ctr].unknown = v >> 12;
+ }
+
+ for (ctr = 0; ctr < ROOM_EXIT_COORDINATES_NUM_ROOMS; ++ctr)
+ _roomIndex[ctr] = rec->roomIndex[ctr];
+}
+
+RoomExitCoordinates &RoomExitCoordinatesList::getEntry(uint16 roomNumber) {
+ RoomExitCoordinatesList::iterator i = begin();
+ while (--roomNumber > 0)
+ ++i;
+ return **i;
+}
+
+RoomExitCoordinateData &RoomExitCoordinates::getData(uint16 destRoomNumber) {
+ return _entries[_roomIndex[destRoomNumber - 1]];
+}
+
// The following classes hold any sequence offsets that are being delayed
SequenceDelayData::SequenceDelayData(uint16 delay, uint16 seqOffset) {
@@ -338,11 +481,32 @@ void SequenceDelayList::tick() {
}
}
+// The following class holds the proximity data for hotspots that is used
+// to determine whether a character needs to walk to a hotspot or not
+
+HotspotProximityData::HotspotProximityData(HotspotProximityResource *rec) {
+ hotspotId = FROM_LE_16(rec->hotspotId);
+ x = FROM_LE_16(rec->x);
+ y = FROM_LE_16(rec->y);
+}
+
+HotspotProximityData *HotspotProximityList::getHotspot(uint16 hotspotId) {
+ iterator i;
+ for (i = begin(); i != end(); ++i) {
+ HotspotProximityData *rec = *i;
+ if (rec->hotspotId == hotspotId) return rec;
+ }
+
+ return NULL;
+}
+
// Field list and miscellaneous variables
ValueTableData::ValueTableData() {
_numGroats = 0;
-
+ _playerNewPos.roomNumber = 0;
+ _playerNewPos.position.x = 0;
+ _playerNewPos.position.y = 0;
for (uint16 index = 0; index < NUM_VALUE_FIELDS; ++index)
_fieldList[index] = 0;
}
diff --git a/engines/lure/res_struct.h b/engines/lure/res_struct.h
index 86f2a0b779..d8334c8c1f 100644
--- a/engines/lure/res_struct.h
+++ b/engines/lure/res_struct.h
@@ -28,6 +28,8 @@
namespace Lure {
+using namespace Common;
+
extern const char *actionList[];
/*-------------------------------------------------------------------------*/
@@ -70,6 +72,7 @@ struct HotspotResource {
uint16 height;
uint16 widthCopy;
uint16 heightCopy;
+ uint16 yCorrection;
int8 talkX;
int8 talkY;
uint16 colourOffset;
@@ -136,13 +139,14 @@ struct RoomExitJoinResource {
uint16 hotspot1Id;
byte h1CurrentFrame;
byte h1DestFrame;
- uint16 h1Unknown;
+ uint8 h1OpenSound;
+ uint8 h1CloseSound;
uint16 hotspot2Id;
byte h2CurrentFrame;
byte h2DestFrame;
- uint16 h2Unknown;
+ uint8 h2OpenSound;
+ uint8 h2CloseSound;
byte blocked;
- uint32 unknown;
} GCC_PACK;
struct HotspotActionResource {
@@ -173,6 +177,26 @@ struct TalkResponseResource {
uint16 sequenceId3;
} GCC_PACK;
+struct HotspotProximityResource {
+ uint16 hotspotId;
+ uint16 x;
+ uint16 y;
+} GCC_PACK;
+
+struct RoomExitCoordinateResource {
+ int16 x;
+ int16 y;
+ uint16 roomNumber;
+} GCC_PACK;
+
+#define ROOM_EXIT_COORDINATES_NUM_ENTRIES 6
+#define ROOM_EXIT_COORDINATES_NUM_ROOMS 52
+
+struct RoomExitCoordinateEntryResource {
+ RoomExitCoordinateResource entries[ROOM_EXIT_COORDINATES_NUM_ENTRIES];
+ uint8 roomIndex[ROOM_EXIT_COORDINATES_NUM_ROOMS];
+} GCC_PACK;
+
#if !defined(__GNUC__)
#pragma END_PACK_STRUCTS
#endif
@@ -247,11 +271,35 @@ public:
RoomExitData *checkExits(int16 xp, int16 yp);
};
+#define ROOM_PATHS_WIDTH 40
+#define ROOM_PATHS_HEIGHT 24
+#define ROOM_PATHS_SIZE (ROOM_PATHS_WIDTH / 8 * ROOM_PATHS_HEIGHT)
+#define DECODED_PATHS_WIDTH 42
+#define DECODED_PATHS_HEIGHT 26
+
+typedef uint16 RoomPathsDecompressedData[DECODED_PATHS_WIDTH * DECODED_PATHS_HEIGHT];
+
+class RoomPathsData {
+private:
+ byte _data[ROOM_PATHS_HEIGHT * ROOM_PATHS_WIDTH];
+public:
+ RoomPathsData() {};
+ RoomPathsData(byte *srcData) { load(srcData); }
+
+ void load(byte *srcData) {
+ memcpy(_data, srcData, ROOM_PATHS_SIZE);
+ }
+ bool isOccupied(int x, int y);
+ void setOccupied(int x, int y, int width);
+ void clearOccupied(int x, int y, int width);
+ void decompress(RoomPathsDecompressedData &dataOut, int characterWidth);
+};
+
#define MAX_NUM_LAYERS 4
class RoomData {
public:
- RoomData(RoomResource *rec);
+ RoomData(RoomResource *rec, MemoryBlock *pathData);
uint16 roomNumber;
uint16 descId;
@@ -262,6 +310,7 @@ public:
int16 clippingXEnd;
RoomExitHotspotList exitHotspots;
RoomExitList exits;
+ RoomPathsData paths;
};
typedef ManagedList<RoomData *> RoomDataList;
@@ -273,11 +322,13 @@ public:
uint16 hotspot1Id;
byte h1CurrentFrame;
byte h1DestFrame;
- uint16 h1Unknown;
+ uint8 h1OpenSound;
+ uint8 h1CloseSound;
uint16 hotspot2Id;
byte h2CurrentFrame;
byte h2DestFrame;
- uint16 h2Unknown;
+ uint8 h2OpenSound;
+ uint8 h2CloseSound;
byte blocked;
uint32 unknown;
};
@@ -326,6 +377,7 @@ public:
uint16 height;
uint16 widthCopy;
uint16 heightCopy;
+ uint16 yCorrection;
int8 talkX;
int8 talkY;
uint16 colourOffset;
@@ -333,6 +385,9 @@ public:
uint16 sequenceOffset;
uint16 tickProcOffset;
uint16 tickTimeout;
+
+ void enable() { flags |= 0x80; }
+ void disable() { flags &= 0x7F; }
};
typedef ManagedList<HotspotData *> HotspotDataList;
@@ -407,7 +462,7 @@ public:
typedef ManagedList<TalkEntryData *> TalkEntryList;
-struct TalkData {
+class TalkData {
public:
TalkData(uint16 id);
~TalkData();
@@ -421,6 +476,27 @@ public:
typedef ManagedList<TalkData *> TalkDataList;
+struct RoomExitCoordinateData {
+ int16 x;
+ int16 y;
+ uint16 roomNumber;
+ byte unknown;
+};
+
+class RoomExitCoordinates {
+private:
+ RoomExitCoordinateData _entries[ROOM_EXIT_COORDINATES_NUM_ENTRIES];
+ uint8 _roomIndex[ROOM_EXIT_COORDINATES_NUM_ROOMS];
+public:
+ RoomExitCoordinates(RoomExitCoordinateEntryResource *rec);
+ RoomExitCoordinateData &getData(uint16 destRoomNumber);
+};
+
+class RoomExitCoordinatesList: public ManagedList<RoomExitCoordinates *> {
+public:
+ RoomExitCoordinates &getEntry(uint16 roomNumber);
+};
+
// The following classes hold any sequence offsets that are being delayed
class SequenceDelayData {
@@ -438,10 +514,29 @@ public:
void tick();
};
+class HotspotProximityData {
+public:
+ HotspotProximityData(HotspotProximityResource *rec);
+
+ uint16 hotspotId;
+ uint16 x;
+ uint16 y;
+};
+
+class HotspotProximityList: public ManagedList<HotspotProximityData *> {
+public:
+ HotspotProximityData *getHotspot(uint16 hotspotId);
+};
+
+struct PlayerNewPosition {
+ Point position;
+ uint16 roomNumber;
+};
+
// The following class holds the field list used by the script engine as
// well as miscellaneous fields used by the game.
-#define NUM_VALUE_FIELDS 85
+#define NUM_VALUE_FIELDS 90
enum FieldName {
ROOM_NUMBER = 0,
@@ -463,6 +558,8 @@ enum FieldName {
class ValueTableData {
private:
uint16 _numGroats;
+ PlayerNewPosition _playerNewPos;
+
uint16 _fieldList[NUM_VALUE_FIELDS];
bool isKnownField(uint16 fieldIndex);
public:
@@ -473,6 +570,7 @@ public:
void setField(uint16 fieldIndex, uint16 value);
void setField(FieldName fieldName, uint16 value);
uint16 &numGroats() { return _numGroats; }
+ PlayerNewPosition &playerNewPos() { return _playerNewPos; }
};
} // End of namespace Lure