/* ScummVM - Scumm Interpreter
* Copyright (C) 2003-2006 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#ifndef QUEENSTRUCTS_H
#define QUEENSTRUCTS_H
#include "queen/defs.h"
#include "common/endian.h"
namespace Queen {
struct Box {
int16 x1, y1, x2, y2;
Box()
: x1(0), y1(0), x2(0), y2(0) {
}
Box(int16 xx1, int16 yy1, int16 xx2, int16 yy2)
: x1(xx1), y1(yy1), x2(xx2), y2(yy2) {
}
void readFromBE(byte *&ptr) {
x1 = (int16)READ_BE_UINT16(ptr); ptr += 2;
y1 = (int16)READ_BE_UINT16(ptr); ptr += 2;
x2 = (int16)READ_BE_UINT16(ptr); ptr += 2;
y2 = (int16)READ_BE_UINT16(ptr); ptr += 2;
}
void writeToBE(byte *&ptr) {
WRITE_BE_UINT16(ptr, x1); ptr += 2;
WRITE_BE_UINT16(ptr, y1); ptr += 2;
WRITE_BE_UINT16(ptr, x2); ptr += 2;
WRITE_BE_UINT16(ptr, y2); ptr += 2;
}
int16 xDiff() const {
return x2 - x1;
}
int16 yDiff() const {
return y2 - y1;
}
bool intersects(int16 x, int16 y, uint16 w, uint16 h) const {
return (x + w > x1) && (y + h > y1) && (x <= x2) && (y <= y2);
}
bool contains(int16 x, int16 y) const {
return (x >= x1) && (x <= x2) && (y >= y1) && (y <= y2);
}
bool operator==(const Box &b) const {
return (x1 == b.x1) && (x2 == b.x2) && (y1 == b.y1) && (y2 == b.y2);
}
};
struct Area {
//! bitmask of connected areas
int16 mapNeighbours;
//! coordinates defining area limits
Box box;
//! scaling factors for bobs actors
uint16 bottomScaleFactor, topScaleFactor;
//! entry in ObjectData, object lying in this area
uint16 object;
void readFromBE(byte *&ptr) {
mapNeighbours = (int16)READ_BE_UINT16(ptr); ptr += 2;
box.readFromBE(ptr);
bottomScaleFactor = READ_BE_UINT16(ptr); ptr += 2;
topScaleFactor = READ_BE_UINT16(ptr); ptr += 2;
object = READ_BE_UINT16(ptr); ptr += 2;
}
void writeToBE(byte *&ptr) {
WRITE_BE_UINT16(ptr, mapNeighbours); ptr += 2;
box.writeToBE(ptr);
WRITE_BE_UINT16(ptr, bottomScaleFactor); ptr += 2;
WRITE_BE_UINT16(ptr, topScaleFactor); ptr += 2;
WRITE_BE_UINT16(ptr, object); ptr += 2;
}
uint16 calcScale(int16 y) const {
uint16 dy = box.yDiff();
int16 ds = scaleDiff();
uint16 scale = 0;
if (dy) // Prevent division-by-zero
scale = ((((y - box.y1) * 100) / dy) * ds) / 100 + bottomScaleFactor;
if (scale == 0)
scale = 100;
return scale;
}
int16 scaleDiff() const {
return (int16)(topScaleFactor - bottomScaleFactor);
}
};
struct WalkOffData {
//! entry in ObjectData
int16 entryObj;
//! coordinates to reach
uint16 x, y;
void readFromBE(byte *&ptr) {
entryObj = (int16)READ_BE_UINT16(ptr); ptr += 2;
x = READ_BE_UINT16(ptr); ptr += 2;
y = READ_BE_UINT16(ptr); ptr += 2;
}
void writeToBE(byte *&ptr) {
WRITE_BE_UINT16(ptr, entryObj); ptr += 2;
WRITE_BE_UINT16(ptr, x); ptr += 2;
WRITE_BE_UINT16(ptr, y); ptr += 2;
}
};
struct GraphicData {
//! coordinates of object
uint16 x, y;
//! bank bobframes
/*!
lastFrame == 0 |
non-animated bob (one frame) |
lastFrame < 0 |
rebound animation |
firstFrame < 0 |
BobSlot::animString (animation is described by a string) |
firstFrame > 0 |
BobSlot::animNormal (animation is a sequence of frames) |
*/
int16 firstFrame, lastFrame;
//! moving speed of object
uint16 speed;
void readFromBE(byte *&ptr) {
x = READ_BE_UINT16(ptr); ptr += 2;
y = READ_BE_UINT16(ptr); ptr += 2;
firstFrame = (int16)READ_BE_UINT16(ptr); ptr += 2;
lastFrame = (int16)READ_BE_UINT16(ptr); ptr += 2;
speed = READ_BE_UINT16(ptr); ptr += 2;
}
};
struct ObjectData {
//! entry in OBJECT_NAME (<0: object is hidden, 0: object has been deleted)
int16 name;
//! coordinates of object
uint16 x, y;
//! entry in OBJECT_DESCR
uint16 description;
//! associated object
int16 entryObj;
//! room in which this object is available
uint16 room;
//! state of the object (grab direction, on/off, default command...)
uint16 state;
//! entry in GraphicData
/*!
value |
description |
]-4000..-10] |
graphic image turned off |
-4 |
person object (right facing) |
-3 |
person object (left facing) |
-2 |
animated bob (off) |
-1 |
static bob (off) |
0 |
object deleted |
]0..5000] |
static or animated bob (on) |
]5000.. [ |
'paste down' bob |
*/
int16 image;
void readFromBE(byte *&ptr) {
name = (int16)READ_BE_UINT16(ptr); ptr += 2;
x = READ_BE_UINT16(ptr); ptr += 2;
y = READ_BE_UINT16(ptr); ptr += 2;
description = READ_BE_UINT16(ptr); ptr += 2;
entryObj = (int16)READ_BE_UINT16(ptr); ptr += 2;
room = READ_BE_UINT16(ptr); ptr += 2;
state = READ_BE_UINT16(ptr); ptr += 2;
image = (int16)READ_BE_UINT16(ptr); ptr += 2;
}
void writeToBE(byte *&ptr) {
WRITE_BE_UINT16(ptr, name); ptr += 2;
WRITE_BE_UINT16(ptr, x); ptr += 2;
WRITE_BE_UINT16(ptr, y); ptr += 2;
WRITE_BE_UINT16(ptr, description); ptr += 2;
WRITE_BE_UINT16(ptr, entryObj); ptr += 2;
WRITE_BE_UINT16(ptr, room); ptr += 2;
WRITE_BE_UINT16(ptr, state); ptr += 2;
WRITE_BE_UINT16(ptr, image); ptr += 2;
}
};
struct ObjectDescription {
//! entry in ObjectData or ItemData
uint16 object;
//! type of the description
/*!
refer to select.c l.75-101
value |
description |
0 |
random but starts at first description |
1 |
random |
2 |
sequential with loop |
3 |
sequential and set description to last |
*/
uint16 type;
//! last entry possible in OBJECT_DESCR for this object
uint16 lastDescription;
//! last description number used (in order to avoid re-using it)
uint16 lastSeenNumber;
void readFromBE(byte *&ptr) {
object = READ_BE_UINT16(ptr); ptr += 2;
type = READ_BE_UINT16(ptr); ptr += 2;
lastDescription = READ_BE_UINT16(ptr); ptr += 2;
lastSeenNumber = READ_BE_UINT16(ptr); ptr += 2;
}
void writeToBE(byte *&ptr) {
WRITE_BE_UINT16(ptr, object); ptr += 2;
WRITE_BE_UINT16(ptr, type); ptr += 2;
WRITE_BE_UINT16(ptr, lastDescription); ptr += 2;
WRITE_BE_UINT16(ptr, lastSeenNumber); ptr += 2;
}
};
struct ItemData {
//! entry in OBJECT_NAME
int16 name;
//! entry in OBJECT_DESCR
uint16 description;
//! state of the object
uint16 state;
//! bank bobframe
uint16 frame;
//! entry in OBJECT_DESCR (>0 if available)
int16 sfxDescription;
void readFromBE(byte *&ptr) {
name = (int16)READ_BE_UINT16(ptr); ptr += 2;
description = READ_BE_UINT16(ptr); ptr += 2;
state = READ_BE_UINT16(ptr); ptr += 2;
frame = READ_BE_UINT16(ptr); ptr += 2;
sfxDescription = (int16)READ_BE_UINT16(ptr); ptr += 2;
}
void writeToBE(byte *&ptr) {
WRITE_BE_UINT16(ptr, name); ptr += 2;
WRITE_BE_UINT16(ptr, description); ptr += 2;
WRITE_BE_UINT16(ptr, state); ptr += 2;
WRITE_BE_UINT16(ptr, frame); ptr += 2;
WRITE_BE_UINT16(ptr, sfxDescription); ptr += 2;
}
};
struct ActorData {
//! room in which the actor is
int16 room;
//! bob number associated to this actor
int16 bobNum;
//! entry in ACTOR_NAME
uint16 name;
//! gamestate entry/value, actor is valid if GAMESTATE[slot] == value
int16 gsSlot, gsValue;
//! spoken text color
uint16 color;
//! bank bobframe for standing position of the actor
uint16 bobFrameStanding;
//! initial coordinates in the room
uint16 x, y;
//! entry in ACTOR_ANIM
uint16 anim;
//! bank to use to load the actor file
uint16 bankNum;
//! entry in ACTOR_FILE
uint16 file;
void readFromBE(byte *&ptr) {
room = (int16)READ_BE_UINT16(ptr); ptr += 2;
bobNum = (int16)READ_BE_UINT16(ptr); ptr += 2;
name = READ_BE_UINT16(ptr); ptr += 2;
gsSlot = (int16)READ_BE_UINT16(ptr); ptr += 2;
gsValue = (int16)READ_BE_UINT16(ptr); ptr += 2;
color = READ_BE_UINT16(ptr); ptr += 2;
bobFrameStanding = READ_BE_UINT16(ptr); ptr += 2;
x = READ_BE_UINT16(ptr); ptr += 2;
y = READ_BE_UINT16(ptr); ptr += 2;
anim = READ_BE_UINT16(ptr); ptr += 2;
bankNum = READ_BE_UINT16(ptr); ptr += 2;
file = READ_BE_UINT16(ptr); ptr += 2;
// Fix the actor data (see queen.c - l.1518-1519). When there is no
// valid actor file, we must load the data from the objects room bank.
// This bank has number 15 (not 10 as in the data files).
if (file == 0) {
bankNum = 15;
}
}
};
struct CmdListData {
//! action to perform
Verb verb;
//! first object used in the action
int16 nounObj1;
//! second object used in the action
int16 nounObj2;
//! song to play (>0: playbefore, <0: playafter)
int16 song;
//! if set, P2_SET_AREAS must be called (using CmdArea)
bool setAreas;
//! if set, P3_SET_OBJECTS must be called (using CmdObject)
bool setObjects;
//! if set, P4_SET_ITEMS must be called (using CmdInventory)
bool setItems;
//! if set, P1_SET_CONDITIONS must be called (using CmdGameState)
bool setConditions;
//! graphic image order
int16 imageOrder;
//! special section to execute (refer to execute.c l.423-451)
int16 specialSection;
void readFromBE(byte *&ptr) {
verb = (Verb)READ_BE_UINT16(ptr); ptr += 2;
nounObj1 = (int16)READ_BE_UINT16(ptr); ptr += 2;
nounObj2 = (int16)READ_BE_UINT16(ptr); ptr += 2;
song = (int16)READ_BE_UINT16(ptr); ptr += 2;
setAreas = READ_BE_UINT16(ptr) != 0; ptr += 2;
setObjects = READ_BE_UINT16(ptr) != 0; ptr += 2;
setItems = READ_BE_UINT16(ptr) != 0; ptr += 2;
setConditions = READ_BE_UINT16(ptr) != 0; ptr += 2;
imageOrder = (int16)READ_BE_UINT16(ptr); ptr += 2;
specialSection = (int16)READ_BE_UINT16(ptr); ptr += 2;
}
bool match(const Verb& v, int16 obj1, int16 obj2) const {
return verb == v && nounObj1 == obj1 && nounObj2 == obj2;
}
};
struct CmdArea {
//! CmdListData number
int16 id;
//! area to turn off/on (<0: off, >0: on)
int16 area;
//! room in which the area must be changed
uint16 room;
void readFromBE(byte *&ptr) {
id = (int16)READ_BE_UINT16(ptr); ptr += 2;
area = (int16)READ_BE_UINT16(ptr); ptr += 2;
room = READ_BE_UINT16(ptr); ptr += 2;
}
};
struct CmdObject {
//! CmdListData number
int16 id;
//! >0: show, <0: hide
int16 dstObj;
//! >0: copy from srcObj, 0: nothing, -1: delete dstObj
int16 srcObj;
void readFromBE(byte *&ptr) {
id = (int16)READ_BE_UINT16(ptr); ptr += 2;
dstObj = (int16)READ_BE_UINT16(ptr); ptr += 2;
srcObj = (int16)READ_BE_UINT16(ptr); ptr += 2;
}
};
struct CmdInventory {
//! CmdListData number
int16 id;
//! <0: delete, >0: add
int16 dstItem;
//! >0: valid
int16 srcItem;
void readFromBE(byte *&ptr) {
id = (int16)READ_BE_UINT16(ptr); ptr += 2;
dstItem = (int16)READ_BE_UINT16(ptr); ptr += 2;
srcItem = (int16)READ_BE_UINT16(ptr); ptr += 2;
}
};
struct CmdGameState {
//! CmdListData number
int16 id;
int16 gameStateSlot;
int16 gameStateValue;
uint16 speakValue;
void readFromBE(byte *&ptr) {
id = (int16)READ_BE_UINT16(ptr); ptr += 2;
gameStateSlot = (int16)READ_BE_UINT16(ptr); ptr += 2;
gameStateValue = (int16)READ_BE_UINT16(ptr); ptr += 2;
speakValue = READ_BE_UINT16(ptr); ptr += 2;
}
};
struct FurnitureData {
//! room in which the furniture are
int16 room;
//! furniture object number
/*!
range |
type |
]0..5000] |
static or animated |
]5000..[ |
paste down |
*/
int16 objNum;
void readFromBE(byte *&ptr) {
room = (int16)READ_BE_UINT16(ptr); ptr += 2;
objNum = (int16)READ_BE_UINT16(ptr); ptr += 2;
}
};
struct GraphicAnim {
int16 keyFrame;
int16 frame;
uint16 speed;
void readFromBE(byte *&ptr) {
keyFrame = (int16)READ_BE_UINT16(ptr); ptr += 2;
frame = (int16)READ_BE_UINT16(ptr); ptr += 2;
speed = READ_BE_UINT16(ptr); ptr += 2;
}
};
struct AnimFrame {
uint16 frame;
uint16 speed;
};
struct Person {
//! actor settings to use
const ActorData *actor;
//! actor name
const char *name;
//! animation string
const char *anim;
//! current frame
uint16 bobFrame;
};
struct TalkSelected {
bool hasTalkedTo;
int16 values[4];
void readFromBE(byte *&ptr) {
hasTalkedTo = READ_BE_UINT16(ptr) != 0; ptr += 2;
for (int i = 0; i < 4; i++) {
values[i] = (int16)READ_BE_UINT16(ptr); ptr += 2;
}
}
void writeToBE(byte *&ptr) {
WRITE_BE_UINT16(ptr, (uint16)hasTalkedTo); ptr += 2;
for (int i = 0; i < 4; i++) {
WRITE_BE_UINT16(ptr, values[i]); ptr += 2;
}
}
};
struct BobFrame {
uint16 width, height;
uint16 xhotspot, yhotspot;
uint8 *data;
};
} // End of namespace Queen
#endif