2015-03-19 23:31:28 -04:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
*
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
* file distributed with this source distribution.
|
|
|
|
*
|
|
|
|
* 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.
|
2015-05-09 18:04:13 +02:00
|
|
|
*
|
2015-03-19 23:31:28 -04:00
|
|
|
* 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.
|
2015-05-09 18:04:13 +02:00
|
|
|
*
|
2015-03-19 23:31:28 -04:00
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SHERLOCK_OBJECTS_H
|
|
|
|
#define SHERLOCK_OBJECTS_H
|
|
|
|
|
|
|
|
#include "common/scummsys.h"
|
|
|
|
#include "common/rect.h"
|
|
|
|
#include "common/str-array.h"
|
|
|
|
#include "common/str.h"
|
|
|
|
#include "sherlock/resources.h"
|
|
|
|
|
|
|
|
namespace Sherlock {
|
|
|
|
|
|
|
|
class SherlockEngine;
|
|
|
|
|
|
|
|
enum ObjectAllow {
|
2015-04-11 23:42:11 -05:00
|
|
|
ALLOW_MOVE = 1, ALLOW_OPEN = 2, ALLOW_CLOSE = 4
|
2015-03-19 23:31:28 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
enum SpriteType {
|
|
|
|
INVALID = 0,
|
|
|
|
CHARACTER = 1,
|
|
|
|
CURSOR = 2,
|
|
|
|
STATIC_BG_SHAPE = 3, // Background shape that doesn't animate
|
|
|
|
ACTIVE_BG_SHAPE = 4, // Background shape that animates
|
|
|
|
REMOVE = 5, // Object should be removed next frame
|
|
|
|
NO_SHAPE = 6, // Background object with no shape
|
|
|
|
HIDDEN = 7, // Hidden backgruond object
|
|
|
|
HIDE_SHAPE = 8 // Object needs to be hidden
|
|
|
|
};
|
|
|
|
|
2015-03-20 19:44:32 -04:00
|
|
|
enum AType {
|
|
|
|
OBJECT = 0,
|
|
|
|
PERSON = 1,
|
|
|
|
SOLID = 2,
|
|
|
|
TALK = 3, // Standard talk zone
|
|
|
|
FLAG_SET = 4,
|
|
|
|
DELTA = 5,
|
|
|
|
WALK_AROUND = 6,
|
|
|
|
TALK_EVERY = 7, // Talk zone that turns on every room visit
|
|
|
|
TALK_MOVE = 8, // Talk zone that only activates when Holmes moves
|
|
|
|
PAL_CHANGE = 9, // Changes the palette down so that it gets darker
|
|
|
|
PAL_CHANGE2 = 10, // Same as PAL_CHANGE, except that it goes up
|
|
|
|
SCRIPT_ZONE = 11, // If this is clicked in, it is activated
|
|
|
|
BLANK_ZONE = 12, // This masks out other objects when entered
|
|
|
|
NOWALK_ZONE = 13 // Player cannot walk here
|
|
|
|
};
|
|
|
|
|
2015-03-21 13:01:45 -04:00
|
|
|
// Different levels for sprites to be at
|
|
|
|
enum {
|
|
|
|
BEHIND = 0, NORMAL_BEHIND = 1, NORMAL_FORWARD = 2, FORWARD = 3
|
|
|
|
};
|
|
|
|
|
2015-03-19 23:31:28 -04:00
|
|
|
#define MAX_HOLMES_SEQUENCE 16
|
|
|
|
#define MAX_FRAME 30
|
|
|
|
|
2015-03-20 19:44:32 -04:00
|
|
|
// code put into sequences to defines 1-10 type seqs
|
2015-05-07 19:33:44 +02:00
|
|
|
#define SEQ_TO_CODE 67
|
2015-03-20 19:44:32 -04:00
|
|
|
#define FLIP_CODE (64 + 128)
|
|
|
|
#define SOUND_CODE (34 + 128)
|
|
|
|
|
2015-04-28 21:35:20 -10:00
|
|
|
class Point32 {
|
|
|
|
public:
|
|
|
|
int x;
|
|
|
|
int y;
|
|
|
|
|
|
|
|
Point32() : x(0), y(0) {}
|
|
|
|
Point32(int x1, int y1) : x(x1), y(y1) {}
|
|
|
|
Point32(const Common::Point &pt) : x(pt.x), y(pt.y) {}
|
|
|
|
|
|
|
|
bool operator==(const Point32 &p) const { return x == p.x && y == p.y; }
|
|
|
|
bool operator!=(const Point32 &p) const { return x != p.x || y != p.y; }
|
|
|
|
Point32 operator+(const Point32 &delta) const { return Point32(x + delta.x, y + delta.y); }
|
|
|
|
Point32 operator-(const Point32 &delta) const { return Point32(x - delta.x, y - delta.y); }
|
|
|
|
operator Common::Point() { return Common::Point(x, y); }
|
|
|
|
|
|
|
|
void operator+=(const Point32 &delta) { x += delta.x; y += delta.y; }
|
|
|
|
void operator-=(const Point32 &delta) { x -= delta.x; y -= delta.y; }
|
|
|
|
};
|
|
|
|
|
2015-03-21 11:24:35 -04:00
|
|
|
class Sprite {
|
|
|
|
private:
|
|
|
|
static SherlockEngine *_vm;
|
|
|
|
public:
|
2015-05-18 23:44:59 -04:00
|
|
|
Common::String _name;
|
|
|
|
Common::String _description;
|
2015-03-19 23:31:28 -04:00
|
|
|
Common::StringArray _examine; // Examine in-depth description
|
|
|
|
Common::String _pickUp; // Message for if you can't pick up object
|
|
|
|
|
|
|
|
const uint8 (*_sequences)[MAX_HOLMES_SEQUENCE][MAX_FRAME]; // Holds animation sequences
|
|
|
|
ImageFile *_images; // Sprite images
|
|
|
|
ImageFrame *_imageFrame; // Pointer to shape in the images
|
|
|
|
int _walkCount; // Character walk counter
|
|
|
|
int _allow; // Allowed menu commands - ObjectAllow
|
|
|
|
int _frameNumber; // Frame number in rame sequence to draw
|
|
|
|
int _sequenceNumber; // Sequence being used
|
2015-04-28 21:35:20 -10:00
|
|
|
Point32 _position; // Current position
|
|
|
|
Point32 _delta; // Momvement delta
|
2015-03-19 23:31:28 -04:00
|
|
|
Common::Point _oldPosition; // Old position
|
|
|
|
Common::Point _oldSize; // Image's old size
|
|
|
|
Common::Point _goto; // Walk destination
|
|
|
|
SpriteType _type; // Type of object
|
|
|
|
Common::Point _noShapeSize; // Size of a NO_SHAPE
|
|
|
|
int _status; // Status: open/closed, moved/not moved
|
|
|
|
int8 _misc; // Miscellaneous use
|
|
|
|
int _numFrames; // How many frames the object has
|
2015-03-21 11:24:35 -04:00
|
|
|
public:
|
2015-03-19 23:31:28 -04:00
|
|
|
Sprite() { clear(); }
|
2015-03-21 11:24:35 -04:00
|
|
|
static void setVm(SherlockEngine *vm) { _vm = vm; }
|
|
|
|
|
2015-05-19 07:37:55 -04:00
|
|
|
/**
|
|
|
|
* Reset the data for the sprite
|
|
|
|
*/
|
2015-03-19 23:31:28 -04:00
|
|
|
void clear();
|
2015-03-20 22:01:52 -04:00
|
|
|
|
2015-05-19 07:37:55 -04:00
|
|
|
/**
|
|
|
|
* Updates the image frame poiner for the sprite
|
|
|
|
*/
|
2015-03-20 22:01:52 -04:00
|
|
|
void setImageFrame();
|
2015-03-21 09:20:39 -04:00
|
|
|
|
2015-05-19 07:37:55 -04:00
|
|
|
/**
|
|
|
|
* This adjusts the sprites position, as well as it's animation sequence:
|
|
|
|
*/
|
2015-03-21 11:24:35 -04:00
|
|
|
void adjustSprite();
|
2015-03-21 20:25:15 -04:00
|
|
|
|
2015-05-19 07:37:55 -04:00
|
|
|
/**
|
|
|
|
* Checks the sprite's position to see if it's collided with any special objects
|
|
|
|
*/
|
2015-03-21 20:25:15 -04:00
|
|
|
void checkSprite();
|
2015-03-22 18:24:13 -04:00
|
|
|
|
2015-05-19 07:37:55 -04:00
|
|
|
/**
|
|
|
|
* Return frame width
|
|
|
|
*/
|
2015-03-22 18:24:13 -04:00
|
|
|
int frameWidth() const { return _imageFrame ? _imageFrame->_frame.w : 0; }
|
2015-05-19 07:37:55 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return frame height
|
|
|
|
*/
|
2015-03-22 18:24:13 -04:00
|
|
|
int frameHeight() const { return _imageFrame ? _imageFrame->_frame.h : 0; }
|
2015-03-19 23:31:28 -04:00
|
|
|
};
|
|
|
|
|
2015-04-11 23:42:11 -05:00
|
|
|
enum { REVERSE_DIRECTION = 0x80 };
|
2015-05-18 19:15:17 -04:00
|
|
|
#define NAMES_COUNT 4
|
2015-04-11 23:42:11 -05:00
|
|
|
|
2015-03-19 23:31:28 -04:00
|
|
|
struct ActionType {
|
2015-04-26 03:45:28 -05:00
|
|
|
int _cAnimNum;
|
2015-05-09 10:01:36 -04:00
|
|
|
int _cAnimSpeed;
|
2015-05-18 19:15:17 -04:00
|
|
|
Common::String _names[NAMES_COUNT];
|
2015-03-19 23:31:28 -04:00
|
|
|
|
2015-05-19 07:37:55 -04:00
|
|
|
/**
|
|
|
|
* Load the data for the action
|
|
|
|
*/
|
2015-05-12 19:55:53 -04:00
|
|
|
void load(Common::SeekableReadStream &s);
|
2015-03-19 23:31:28 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
struct UseType {
|
|
|
|
int _cAnimNum;
|
2015-05-09 10:01:36 -04:00
|
|
|
int _cAnimSpeed;
|
2015-05-18 19:15:17 -04:00
|
|
|
Common::String _names[NAMES_COUNT];
|
2015-03-19 23:31:28 -04:00
|
|
|
int _useFlag; // Which flag USE will set (if any)
|
|
|
|
Common::String _target;
|
2015-05-12 22:02:59 -04:00
|
|
|
Common::String _verb;
|
2015-03-19 23:31:28 -04:00
|
|
|
|
2015-05-01 14:54:28 -10:00
|
|
|
UseType();
|
2015-05-19 07:37:55 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Load the data for the UseType
|
|
|
|
*/
|
2015-05-12 22:02:59 -04:00
|
|
|
void load(Common::SeekableReadStream &s, bool isRoseTattoo);
|
2015-03-19 23:31:28 -04:00
|
|
|
};
|
|
|
|
|
2015-05-19 08:13:46 -04:00
|
|
|
enum { OBJ_BEHIND = 1, OBJ_FLIPPED = 2, OBJ_FORWARD = 4, TURNON_OBJ = 0x20, TURNOFF_OBJ = 0x40 };
|
2015-05-18 19:15:17 -04:00
|
|
|
#define USE_COUNT 4
|
|
|
|
|
2015-03-21 18:18:12 -04:00
|
|
|
class Object {
|
|
|
|
private:
|
|
|
|
static SherlockEngine *_vm;
|
|
|
|
|
2015-05-19 07:37:55 -04:00
|
|
|
/**
|
|
|
|
* This will check to see if the object has reached the end of a sequence.
|
|
|
|
* If it has, it switch to whichever next sequence should be started.
|
|
|
|
* @returns true if the end of a sequence was reached
|
|
|
|
*/
|
2015-03-22 00:52:02 -04:00
|
|
|
bool checkEndOfSequence();
|
2015-03-21 18:18:12 -04:00
|
|
|
|
2015-05-19 07:37:55 -04:00
|
|
|
/**
|
|
|
|
* Scans through the sequences array and finds the designated sequence.
|
|
|
|
* It then sets the frame number of the start of that sequence
|
|
|
|
*/
|
2015-03-21 18:18:12 -04:00
|
|
|
void setObjSequence(int seq, bool wait);
|
|
|
|
public:
|
|
|
|
static bool _countCAnimFrames;
|
|
|
|
|
|
|
|
static void setVm(SherlockEngine *vm);
|
|
|
|
public:
|
2015-03-19 23:31:28 -04:00
|
|
|
Common::String _name; // Name
|
2015-03-26 21:40:24 -04:00
|
|
|
Common::String _description; // Description lines
|
2015-03-20 07:54:39 -04:00
|
|
|
Common::String _examine; // Examine in-depth description
|
|
|
|
int _sequenceOffset;
|
|
|
|
uint8 *_sequences; // Holds animation sequences
|
2015-03-19 23:31:28 -04:00
|
|
|
ImageFile *_images; // Sprite images
|
|
|
|
ImageFrame *_imageFrame; // Pointer to shape in the images
|
|
|
|
int _walkCount; // Character walk counter
|
|
|
|
int _allow; // Allowed menu commands - ObjectAllow
|
|
|
|
int _frameNumber; // Frame number in rame sequence to draw
|
|
|
|
int _sequenceNumber; // Sequence being used
|
|
|
|
SpriteType _type; // Object type
|
|
|
|
Common::Point _position; // Current position
|
2015-03-21 18:18:12 -04:00
|
|
|
Common::Point _delta; // Momvement amount
|
2015-03-19 23:31:28 -04:00
|
|
|
Common::Point _oldPosition; // Old position
|
|
|
|
Common::Point _oldSize; // Image's old size
|
|
|
|
Common::Point _goto; // Walk destination
|
|
|
|
|
|
|
|
int _pickup;
|
|
|
|
int _defaultCommand; // Default right-click command
|
|
|
|
int _lookFlag; // Which flag LOOK will set (if any)
|
|
|
|
int _requiredFlag; // Object will be hidden if not set
|
|
|
|
Common::Point _noShapeSize; // Size of a NO_SHAPE
|
|
|
|
int _status; // Status (open/closed, moved/not)
|
|
|
|
int8 _misc; // Misc field -- use varies with type
|
|
|
|
int _maxFrames; // Number of frames
|
|
|
|
int _flags; // Tells if object can be walked behind
|
2015-03-20 19:44:32 -04:00
|
|
|
AType _aType; // Tells if this is an object, person, talk, etc.
|
2015-03-19 23:31:28 -04:00
|
|
|
int _lookFrames; // How many frames to play of the look anim before pausing
|
2015-03-20 07:54:39 -04:00
|
|
|
int _seqCounter; // How many times this sequence has been executed
|
2015-03-19 23:31:28 -04:00
|
|
|
Common::Point _lookPosition; // Where to walk when examining object
|
|
|
|
int _lookFacing; // Direction to face when examining object
|
|
|
|
int _lookcAnim;
|
|
|
|
int _seqStack; // Allows gosubs to return to calling frame
|
|
|
|
int _seqTo; // Allows 1-5, 8-3 type sequences encoded in 2 bytes
|
2015-03-20 07:54:39 -04:00
|
|
|
uint _descOffset; // Tells where description starts in DescText
|
2015-03-22 00:52:02 -04:00
|
|
|
int _seqCounter2; // Counter of calling frame sequence
|
2015-05-07 19:33:44 +02:00
|
|
|
uint _seqSize; // Tells where description starts
|
2015-05-12 22:02:59 -04:00
|
|
|
UseType _use[6]; // Serrated Scalpel uses 4, Rose Tattoo 6
|
|
|
|
|
|
|
|
// Serrated Scalpel fields
|
|
|
|
int _pickupFlag; // Which flag PICKUP will set (if any)
|
|
|
|
ActionType _aOpen; // Holds data for moving object
|
|
|
|
ActionType _aClose;
|
2015-03-19 23:31:28 -04:00
|
|
|
ActionType _aMove;
|
2015-05-12 22:02:59 -04:00
|
|
|
|
|
|
|
// Rose Tattoo fields
|
|
|
|
int _quickDraw;
|
|
|
|
int _scaleVal;
|
|
|
|
int _requiredFlag1;
|
|
|
|
int _gotoSeq;
|
|
|
|
int _talkSeq;
|
|
|
|
int _restoreSlot;
|
2015-03-19 23:31:28 -04:00
|
|
|
|
2015-04-11 23:42:11 -05:00
|
|
|
Object();
|
|
|
|
|
2015-05-19 07:37:55 -04:00
|
|
|
/**
|
|
|
|
* Load the data for the object
|
|
|
|
*/
|
2015-05-12 22:02:59 -04:00
|
|
|
void load(Common::SeekableReadStream &s, bool isRoseTattoo);
|
2015-03-20 19:44:32 -04:00
|
|
|
|
2015-05-19 07:37:55 -04:00
|
|
|
/**
|
|
|
|
* Toggle the type of an object between hidden and active
|
|
|
|
*/
|
2015-03-20 19:44:32 -04:00
|
|
|
void toggleHidden();
|
2015-03-21 18:18:12 -04:00
|
|
|
|
2015-05-19 07:37:55 -04:00
|
|
|
/**
|
|
|
|
* Check the state of the object
|
|
|
|
*/
|
2015-04-25 05:52:04 -05:00
|
|
|
void checkObject();
|
2015-03-21 18:18:12 -04:00
|
|
|
|
2015-05-19 07:37:55 -04:00
|
|
|
/**
|
|
|
|
* Checks for codes
|
|
|
|
* @param name The name to check for codes
|
|
|
|
* @param messages Provides a lookup list of messages that can be printed
|
|
|
|
* @returns 0 if no codes are found, 1 if codes were found
|
|
|
|
*/
|
2015-04-11 23:42:11 -05:00
|
|
|
int checkNameForCodes(const Common::String &name, const char *const messages[]);
|
2015-03-21 20:25:15 -04:00
|
|
|
|
2015-05-19 07:37:55 -04:00
|
|
|
/**
|
|
|
|
* Handle setting any flags associated with the object
|
|
|
|
*/
|
2015-03-21 20:25:15 -04:00
|
|
|
void setFlagsAndToggles();
|
2015-03-22 00:52:02 -04:00
|
|
|
|
2015-05-19 07:37:55 -04:00
|
|
|
/**
|
|
|
|
* Adjusts the sprite's position and animation sequence, advancing by 1 frame.
|
|
|
|
* If the end of the sequence is reached, the appropriate action is taken.
|
|
|
|
*/
|
2015-03-22 00:52:02 -04:00
|
|
|
void adjustObject();
|
2015-03-22 15:44:11 -04:00
|
|
|
|
2015-05-19 07:37:55 -04:00
|
|
|
/**
|
|
|
|
* Handles trying to pick up an object. If allowed, plays an y necessary animation for picking
|
|
|
|
* up the item, and then adds it to the player's inventory
|
|
|
|
*/
|
2015-04-12 11:06:25 -05:00
|
|
|
int pickUpObject(const char *const messages[]);
|
|
|
|
|
2015-05-19 07:37:55 -04:00
|
|
|
/**
|
|
|
|
* Return the frame width
|
|
|
|
*/
|
2015-03-22 15:44:11 -04:00
|
|
|
int frameWidth() const { return _imageFrame ? _imageFrame->_frame.w : 0; }
|
2015-05-19 07:37:55 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the frame height
|
|
|
|
*/
|
2015-03-22 15:44:11 -04:00
|
|
|
int frameHeight() const { return _imageFrame ? _imageFrame->_frame.h : 0; }
|
2015-05-19 07:37:55 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the current bounds for the sprite
|
|
|
|
*/
|
2015-03-23 20:34:34 -04:00
|
|
|
const Common::Rect getNewBounds() const;
|
2015-05-19 07:37:55 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the bounds for a sprite without a shape
|
|
|
|
*/
|
2015-03-23 20:34:34 -04:00
|
|
|
const Common::Rect getNoShapeBounds() const;
|
2015-05-19 07:37:55 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the old bounsd for the sprite from the previous frame
|
|
|
|
*/
|
2015-03-23 20:34:34 -04:00
|
|
|
const Common::Rect getOldBounds() const;
|
2015-03-19 23:31:28 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
struct CAnim {
|
|
|
|
Common::String _name; // Name
|
|
|
|
Common::Point _position; // Position
|
|
|
|
int _size; // Size of uncompressed animation
|
|
|
|
int _flags; // Tells if can be walked behind
|
|
|
|
Common::Point _goto; // coords holmes should walk to before starting canim
|
2015-03-21 18:18:12 -04:00
|
|
|
int _gotoDir;
|
2015-03-19 23:31:28 -04:00
|
|
|
Common::Point _teleportPos; // Location Holmes shoul teleport to after
|
2015-03-21 18:18:12 -04:00
|
|
|
int _teleportDir; // playing canim
|
2015-03-20 07:54:39 -04:00
|
|
|
|
2015-05-16 22:48:24 -04:00
|
|
|
// Scalpel specific
|
|
|
|
byte _sequences[MAX_FRAME]; // Animation sequences
|
|
|
|
SpriteType _type;
|
|
|
|
|
|
|
|
// Rose Tattoo specific
|
|
|
|
int _scaleVal; // How much the canim is scaled
|
|
|
|
|
2015-05-19 07:37:55 -04:00
|
|
|
/**
|
|
|
|
* Load the data for the animation
|
|
|
|
*/
|
2015-05-16 22:48:24 -04:00
|
|
|
void load(Common::SeekableReadStream &s, bool isRoseTattoo);
|
2015-03-19 23:31:28 -04:00
|
|
|
};
|
|
|
|
|
2015-03-22 09:51:37 -04:00
|
|
|
struct SceneImage {
|
2015-03-20 07:54:39 -04:00
|
|
|
ImageFile *_images; // Object images
|
|
|
|
int _maxFrames; // How many frames in object
|
|
|
|
int _filesize; // File size
|
|
|
|
|
2015-03-22 09:51:37 -04:00
|
|
|
SceneImage();
|
2015-03-20 07:54:39 -04:00
|
|
|
} ;
|
|
|
|
|
2015-03-19 23:31:28 -04:00
|
|
|
} // End of namespace Sherlock
|
|
|
|
|
|
|
|
#endif
|