Initial commit
This commit is contained in:
371
engines/sci/graphics/screen_item32.h
Normal file
371
engines/sci/graphics/screen_item32.h
Normal file
@@ -0,0 +1,371 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#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 // SCI_GRAPHICS_SCREEN_ITEM32_H
|
||||
Reference in New Issue
Block a user