/* ScummVM - Scumm Interpreter
* Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*
*/
#ifndef QUEENSTRUCTS_H
#define QUEENSTRUCTS_H
#include "queen/verb.h"
namespace Queen {
struct Box {
int16 x1, y1, x2, y2;
void readFrom(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;
}
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);
}
};
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 readFrom(byte *&ptr) {
mapNeighbours = (int16)READ_BE_UINT16(ptr); ptr += 2;
box.readFrom(ptr);
bottomScaleFactor = READ_BE_UINT16(ptr); ptr += 2;
topScaleFactor = READ_BE_UINT16(ptr); ptr += 2;
object = READ_BE_UINT16(ptr); ptr += 2;
}
uint16 calcScale(int16 y) const {
uint16 dy = box.y2 - box.y1;
int16 ds = (int16)(topScaleFactor - bottomScaleFactor);
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 readFrom(byte *& ptr) {
entryObj = (int16)READ_BE_UINT16(ptr); ptr += 2;
x = READ_BE_UINT16(ptr); ptr += 2;
y = READ_BE_UINT16(ptr); 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 |
bobAnimString (animation is described by a string) |
firstFrame > 0 |
bobAnimNormal (animation is a sequence of frames) |
*/
int16 firstFrame, lastFrame;
//! moving speed of object
uint16 speed;
void readFrom(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 readFrom(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;
}
};
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 readFrom(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;
}
};
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 readFrom(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;
}
};
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 gameStateSlot, gameStateValue;
//! 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 actorFile;
void readFrom(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;
gameStateSlot = (int16)READ_BE_UINT16(ptr); ptr += 2;
gameStateValue = (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;
actorFile = READ_BE_UINT16(ptr); ptr += 2;
}
};
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
value |
description |
1 |
use journal |
2 |
use dress |
3 |
use normal clothes |
4 |
use underwear |
*/
int16 specialSection;
void readFrom(byte *&ptr) {
verb = Verb((VerbEnum)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
int16 room;
void readFrom(byte *&ptr) {
id = (int16)READ_BE_UINT16(ptr); ptr += 2;
area = (int16)READ_BE_UINT16(ptr); ptr += 2;
room = (int16)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 readFrom(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 readFrom(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 readFrom(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;
//! type of furniture (stored in GAMESTATE)
/*!
value |
description |
]0..5000] |
static or animated |
]5000..[ |
paste down |
*/
int16 gameStateValue;
void readFrom(byte *&ptr) {
room = (int16)READ_BE_UINT16(ptr); ptr += 2;
gameStateValue = (int16)READ_BE_UINT16(ptr); ptr += 2;
}
};
struct GraphicAnim {
int16 keyFrame;
int16 frame;
uint16 speed;
void readFrom(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; // P_ROOM, P_BNUM, P_GAMES, P_VALUE, P_COLOR, P_STAND, P_X, P_Y
//! name of the actor
const char *name; // P_NAMEstr
//! string animation
const char *anim; // P_ANIMstr
uint16 bobFrame; // SFRAME
//! As the bank number may change, we can't re-use actor->bankNum
uint16 bankNum; // P_BANK
};
} // End of namespace Queen
#endif