mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-22 18:37:01 +00:00
SCI32: Implement engine-accurate screen item list sorting
It seems highly probable that there are later SCI games that use the "hi res" rendering path, so sorting and unsorting of ScreenItemLists needs to be accurate.
This commit is contained in:
parent
a785147d6c
commit
0310b4dc4d
@ -657,23 +657,43 @@ ScreenItem *ScreenItemList::findByObject(const reg_t object) const {
|
||||
return *screenItemIt;
|
||||
}
|
||||
void ScreenItemList::sort() {
|
||||
// TODO: SCI engine used _unsorted as an array of indexes into the
|
||||
// list itself and then performed the same swap operations on the
|
||||
// _unsorted array as the _storage array during sorting, but the
|
||||
// only reason to do this would be if some of the pointers in the
|
||||
// list were replaced so the pointer values themselves couldn’t
|
||||
// simply be recorded and then restored later. It is not yet
|
||||
// verified whether this simplification of the sort/unsort is
|
||||
// safe.
|
||||
for (size_type i = 0; i < size(); ++i) {
|
||||
_unsorted[i] = (*this)[i];
|
||||
if (size() < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
Common::sort(begin(), end(), sortHelper);
|
||||
for (size_type i = 0; i < size(); ++i) {
|
||||
_unsorted[i] = i;
|
||||
}
|
||||
|
||||
for (size_type i = size() - 1; i > 0; --i) {
|
||||
bool swap = false;
|
||||
|
||||
for (size_type j = 0; j < i; ++j) {
|
||||
value_type &a = operator[](j);
|
||||
value_type &b = operator[](j + 1);
|
||||
|
||||
if (a == nullptr || *a > *b) {
|
||||
SWAP(a, b);
|
||||
SWAP(_unsorted[j], _unsorted[j + 1]);
|
||||
swap = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!swap) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void ScreenItemList::unsort() {
|
||||
if (size() < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_type i = 0; i < size(); ++i) {
|
||||
(*this)[i] = _unsorted[i];
|
||||
while (_unsorted[i] != i) {
|
||||
SWAP(operator[](_unsorted[i]), operator[](i));
|
||||
SWAP(_unsorted[_unsorted[i]], _unsorted[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,6 +236,24 @@ public:
|
||||
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) {
|
||||
return _object > other._object;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the dimensions and scaling parameters for
|
||||
* the screen item, using the given plane as the parent
|
||||
@ -279,12 +297,10 @@ public:
|
||||
|
||||
typedef StablePointerArray<ScreenItem, 250> ScreenItemListBase;
|
||||
class ScreenItemList : public ScreenItemListBase {
|
||||
inline static bool sortHelper(const ScreenItem *a, const ScreenItem *b) {
|
||||
return *a < *b;
|
||||
}
|
||||
public:
|
||||
ScreenItem *_unsorted[250];
|
||||
private:
|
||||
size_type _unsorted[250];
|
||||
|
||||
public:
|
||||
ScreenItem *findByObject(const reg_t object) const;
|
||||
void sort();
|
||||
void unsort();
|
||||
|
Loading…
x
Reference in New Issue
Block a user