mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-16 06:39:17 +00:00
0ac5d84062
* Rewrap comments to 80 columns * Clarify comments where possible * Use smart pointers where appropriate
372 lines
10 KiB
C++
372 lines
10 KiB
C++
/* 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.
|
|
*
|
|
* 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.
|
|
*
|
|
*/
|
|
|
|
#ifndef SCI_GRAPHICS_SCREEN_ITEM32_H
|
|
#define SCI_GRAPHICS_SCREEN_ITEM32_H
|
|
|
|
#include "common/rect.h"
|
|
#include "sci/graphics/celobj32.h"
|
|
#include "sci/graphics/lists32.h"
|
|
|
|
namespace Sci {
|
|
|
|
enum ScaleSignals32 {
|
|
kScaleSignalNone = 0,
|
|
kScaleSignalManual = 1,
|
|
kScaleSignalVanishingPoint = 2
|
|
};
|
|
|
|
struct ScaleInfo {
|
|
int x, y, max;
|
|
ScaleSignals32 signal;
|
|
ScaleInfo() : x(128), y(128), max(100), signal(kScaleSignalNone) {}
|
|
};
|
|
|
|
class CelObj;
|
|
class Plane;
|
|
class SegManager;
|
|
|
|
#pragma mark -
|
|
#pragma mark ScreenItem
|
|
|
|
/**
|
|
* A ScreenItem is the engine-side representation of a game script View.
|
|
*/
|
|
class ScreenItem {
|
|
private:
|
|
/**
|
|
* A serial used for screen items that are generated inside the graphics
|
|
* engine, rather than the interpreter.
|
|
*/
|
|
static uint16 _nextObjectId;
|
|
|
|
/**
|
|
* A serial used to identify the creation order of screen items, to ensure a
|
|
* stable sort order for screen items with identical priorities and
|
|
* z-indexes.
|
|
*/
|
|
static uint32 _nextCreationId;
|
|
|
|
public:
|
|
/**
|
|
* The parent plane of this screen item.
|
|
*/
|
|
reg_t _plane;
|
|
|
|
/**
|
|
* Scaling data used to calculate the final screen dimensions of the screen
|
|
* item as well as the scaling ratios used when drawing the item to screen.
|
|
*/
|
|
ScaleInfo _scale;
|
|
|
|
private:
|
|
/**
|
|
* The position & dimensions of the screen item in screen coordinates. This
|
|
* rect includes the offset of the parent plane, but is not clipped to the
|
|
* screen, so may include coordinates that are offscreen.
|
|
*/
|
|
Common::Rect _screenItemRect;
|
|
|
|
/**
|
|
* If true, the `_insetRect` rectangle will be used when calculating the
|
|
* dimensions of the screen item instead of the cel's intrinsic width and
|
|
* height.
|
|
*
|
|
* In other words, using an inset rect means that the cel is cropped to the
|
|
* dimensions given in `_insetRect`.
|
|
*/
|
|
bool _useInsetRect;
|
|
|
|
/**
|
|
* The cropping rectangle used when `_useInsetRect` is true.
|
|
*
|
|
* `_insetRect` is also used to describe the fill rectangle of a screen item
|
|
* with a CelObjColor cel.
|
|
*/
|
|
Common::Rect _insetRect;
|
|
|
|
/**
|
|
* The z-index of the screen item in pseudo-3D space. Higher values are
|
|
* drawn on top of lower values.
|
|
*/
|
|
int _z;
|
|
|
|
/**
|
|
* Sets the common properties of a screen item that must be set both during
|
|
* creation and update of a screen item.
|
|
*/
|
|
void setFromObject(SegManager *segMan, const reg_t object, const bool updateCel, const bool updateBitmap);
|
|
|
|
public:
|
|
/**
|
|
* The creation order number, which ensures a stable sort when screen items
|
|
* with identical priorities and z-indexes are added to the screen item
|
|
* list.
|
|
*/
|
|
uint32 _creationId;
|
|
|
|
/**
|
|
* A descriptor for the cel object represented by the screen item.
|
|
*/
|
|
CelInfo32 _celInfo;
|
|
|
|
/**
|
|
* The cel object used to actually render the screen item. This member is
|
|
* populated by calling `getCelObj`.
|
|
*/
|
|
mutable Common::ScopedPtr<CelObj> _celObj;
|
|
|
|
/**
|
|
* If set, the priority for this screen item is fixed in place. Otherwise,
|
|
* the priority of the screen item is calculated from its y-position +
|
|
* z-index.
|
|
*/
|
|
bool _fixedPriority;
|
|
|
|
/**
|
|
* The rendering priority of the screen item, relative only to the other
|
|
* screen items within the same plane. Higher priorities are drawn above
|
|
* lower priorities.
|
|
*/
|
|
int16 _priority;
|
|
|
|
/**
|
|
* The top-left corner of the screen item, in game script coordinates,
|
|
* relative to the parent plane.
|
|
*/
|
|
Common::Point _position;
|
|
|
|
/**
|
|
* The associated View script object that was used to create the ScreenItem,
|
|
* or a numeric value in the case of a ScreenItem that was generated by the
|
|
* kernel.
|
|
*/
|
|
reg_t _object;
|
|
|
|
/**
|
|
* For screen items representing picture resources, the resource ID of the
|
|
* picture.
|
|
*/
|
|
GuiResourceId _pictureId;
|
|
|
|
/**
|
|
* Flags indicating the state of the screen item.
|
|
* - `created` is set when the screen item is first created, either from a
|
|
* VM object or from within the kernel
|
|
* - `updated` is set when `created` is not already set and the screen item
|
|
* is updated from a VM object
|
|
* - `deleted` is set by the parent plane, if the parent plane is a pic type
|
|
* and its picture resource ID has changed
|
|
*/
|
|
int _created, _updated, _deleted;
|
|
|
|
/**
|
|
* For screen items that represent picture cels, this value is set to match
|
|
* the `_mirrorX` property of the parent plane and indicates that the cel
|
|
* should be
|
|
* drawn horizontally mirrored. For final drawing, it is XORed with the
|
|
* `_mirrorX` property of the cel object. The cel object's `_mirrorX`
|
|
* property comes from the resource data.
|
|
*/
|
|
bool _mirrorX;
|
|
|
|
/**
|
|
* The scaling ratios to use when drawing this screen item. These values are
|
|
* calculated according to the scale info whenever the screen item is
|
|
* updated.
|
|
*/
|
|
Ratio _ratioX, _ratioY;
|
|
|
|
/**
|
|
* The top-left corner of the screen item, in screen coordinates.
|
|
*/
|
|
Common::Point _scaledPosition;
|
|
|
|
/**
|
|
* The position & dimensions of the screen item in screen coordinates. This
|
|
* rect includes the offset of the parent plane and is clipped to the
|
|
* screen.
|
|
*/
|
|
Common::Rect _screenRect;
|
|
|
|
/**
|
|
* Whether or not the screen item should be drawn with black lines drawn
|
|
* every second line. This is used when pixel doubling videos to improve
|
|
* apparent sharpness at the cost of your eyesight.
|
|
*/
|
|
bool _drawBlackLines;
|
|
|
|
/**
|
|
* Initialises static Plane members.
|
|
*/
|
|
static void init();
|
|
|
|
ScreenItem(const reg_t screenItem);
|
|
ScreenItem(const reg_t plane, const CelInfo32 &celInfo);
|
|
ScreenItem(const reg_t plane, const CelInfo32 &celInfo, const Common::Rect &rect);
|
|
ScreenItem(const reg_t plane, const CelInfo32 &celInfo, const Common::Point &position, const ScaleInfo &scaleInfo);
|
|
ScreenItem(const ScreenItem &other);
|
|
void operator=(const ScreenItem &);
|
|
|
|
inline bool operator<(const ScreenItem &other) const {
|
|
if (_priority < other._priority) {
|
|
return true;
|
|
}
|
|
|
|
if (_priority == other._priority) {
|
|
if (_position.y + _z < other._position.y + other._z) {
|
|
return true;
|
|
}
|
|
|
|
if (_position.y + _z == other._position.y + other._z) {
|
|
// Synthetic object IDs (numeric IDs) are used for screen items
|
|
// generated by the kernel, like the screen items generated by
|
|
// plane pics. In SSCI, these synthetic IDs started at 20000 so
|
|
// would deterministically always sort higher than any
|
|
// script-generated view in SSCI at the same position and
|
|
// priority.
|
|
if (other._object.isNumber() && !_object.isNumber()) {
|
|
return true;
|
|
}
|
|
|
|
// SSCI's last resort comparison here is to compare the _object
|
|
// IDs, but this is wrong and randomly breaks (at least):
|
|
//
|
|
// (1) the death dialog at the end of Phant1, where the ID of
|
|
// the text is often higher than the ID of the border;
|
|
// (2) text-based buttons and dialogues in Hoyle5, where the ID
|
|
// of the text is often lower than the ID of the
|
|
// button/dialogue background.
|
|
//
|
|
// This occurs because object IDs (in both ScummVM and SSCI) are
|
|
// reused, so objects created later may receive a lower ID,
|
|
// which makes them sort lower when the programmer intended them
|
|
// to sort higher.
|
|
//
|
|
// To fix this problem, we give each ScreenItem a monotonically
|
|
// increasing insertion ID at construction time, and compare
|
|
// these insertion IDs instead. They are more stable and cause
|
|
// objects with identical priority and z-index to be rendered in
|
|
// the order that they were created.
|
|
//
|
|
// This also applies to ScreenItem::hasPriorityAbove.
|
|
return _creationId < other._creationId;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
inline bool operator>(const ScreenItem &other) const {
|
|
if (_priority > other._priority) {
|
|
return true;
|
|
}
|
|
|
|
if (_priority == other._priority) {
|
|
if (_position.y + _z > other._position.y + other._z) {
|
|
return true;
|
|
}
|
|
|
|
if (_position.y + _z == other._position.y + other._z) {
|
|
if (_object.isNumber() && !other._object.isNumber()) {
|
|
return true;
|
|
}
|
|
|
|
// This is different than SSCI; see ScreenItem::operator< for an
|
|
// explanation
|
|
return _creationId > other._creationId;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
inline bool hasPriorityAbove(const ScreenItem &other) const {
|
|
if (_priority > other._priority) {
|
|
return true;
|
|
}
|
|
|
|
if (_priority == other._priority) {
|
|
if (_object.isNumber() && !other._object.isNumber()) {
|
|
return true;
|
|
}
|
|
|
|
// This is different than SSCI; see ScreenItem::operator< for an
|
|
// explanation
|
|
return _creationId > other._creationId;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Calculates the dimensions and scaling parameters for the screen item,
|
|
* using the given plane as the parent plane for screen rect positioning.
|
|
*
|
|
* @note This method was called Update in SSCI.
|
|
*/
|
|
void calcRects(const Plane &plane);
|
|
|
|
/**
|
|
* Retrieves the corresponding cel object for this screen item. If a cel
|
|
* object does not already exist, one will be created and assigned.
|
|
*/
|
|
CelObj &getCelObj() const;
|
|
|
|
void printDebugInfo(Console *con) const;
|
|
|
|
/**
|
|
* Updates the properties of the screen item from a VM object.
|
|
*/
|
|
void update(const reg_t object);
|
|
|
|
/**
|
|
* Updates the properties of the screen item for one not belonging to a VM
|
|
* object. Originally GraphicsMgr::UpdateScreenItem.
|
|
*/
|
|
void update();
|
|
|
|
/**
|
|
* Gets the "now seen" rect for the screen item, which represents the
|
|
* current size and position of the screen item on the screen in script
|
|
* coordinates.
|
|
*/
|
|
Common::Rect getNowSeenRect(const Plane &plane) const;
|
|
};
|
|
|
|
#pragma mark -
|
|
#pragma mark ScreenItemList
|
|
|
|
typedef StablePointerArray<ScreenItem, 250> ScreenItemListBase;
|
|
class ScreenItemList : public ScreenItemListBase {
|
|
private:
|
|
size_type _unsorted[250];
|
|
|
|
public:
|
|
ScreenItem *findByObject(const reg_t object) const;
|
|
void sort();
|
|
void unsort();
|
|
};
|
|
} // End of namespace Sci
|
|
|
|
#endif
|