mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 21:59:17 +00:00
ILLUSIONS: BBDOU: Implement getOverlappedObjectAccurate and related functions
This commit is contained in:
parent
27a5e93268
commit
869d342e9f
@ -945,6 +945,12 @@ void Control::fillActor(byte color) {
|
||||
_actor->_flags |= 0x4000;
|
||||
}
|
||||
|
||||
bool Control::isPixelCollision(Common::Point &pt) {
|
||||
Frame *frame = &(*_actor->_frames)[_actor->_frameIndex - 1];
|
||||
return _vm->_screen->isSpritePixelSolid16(pt, _position, _actor->_position,
|
||||
_actor->_surfInfo, _actor->_scale, frame->_flags, frame->_compressedPixels);
|
||||
}
|
||||
|
||||
void Control::startSequenceActorIntern(uint32 sequenceId, int value, byte *entryTblPtr, uint32 notifyThreadId) {
|
||||
stopActor();
|
||||
|
||||
@ -1311,6 +1317,41 @@ bool Controls::getOverlappedObject(Control *control, Common::Point pt, Control *
|
||||
return foundControl != 0;
|
||||
}
|
||||
|
||||
bool Controls::getOverlappedObjectAccurate(Control *control, Common::Point pt, Control **outOverlappedControl, int minPriority) {
|
||||
Control *foundControl = 0;
|
||||
uint32 foundPriority = 0;
|
||||
uint32 minPriorityExt = _vm->getPriorityFromBase(minPriority);
|
||||
|
||||
for (ItemsIterator it = _controls.begin(); it != _controls.end(); ++it) {
|
||||
Control *testControl = *it;
|
||||
if (testControl != control && testControl->_pauseCtr == 0 &&
|
||||
(testControl->_flags & 1) && !(testControl->_flags & 0x10) &&
|
||||
(!testControl->_actor || (testControl->_actor->_flags & 1))) {
|
||||
Common::Rect collisionRect;
|
||||
testControl->getCollisionRectAccurate(collisionRect);
|
||||
if (!collisionRect.isEmpty() && collisionRect.contains(pt) &&
|
||||
(!testControl->_actor || testControl->isPixelCollision(pt))) {
|
||||
uint32 testPriority = testControl->getOverlapPriority();
|
||||
if ((!foundControl || foundPriority < testPriority) &&
|
||||
testPriority >= minPriorityExt) {
|
||||
foundControl = testControl;
|
||||
foundPriority = testPriority;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (foundControl) {
|
||||
if (foundControl->_actor && foundControl->_actor->_parentObjectId && (foundControl->_actor->_flags & 0x40)) {
|
||||
uint32 parentObjectId = foundControl->getSubActorParent();
|
||||
foundControl = _vm->_dict->getObjectControl(parentObjectId);
|
||||
}
|
||||
*outOverlappedControl = foundControl;
|
||||
}
|
||||
|
||||
return foundControl != 0;
|
||||
}
|
||||
|
||||
bool Controls::getDialogItemAtPos(Control *control, Common::Point pt, Control **outOverlappedControl) {
|
||||
Control *foundControl = 0;
|
||||
for (ItemsIterator it = _controls.begin(); it != _controls.end(); ++it) {
|
||||
|
@ -204,6 +204,7 @@ public:
|
||||
void getActorFrameDimensions(WidthHeight &dimensions);
|
||||
void drawActorRect(const Common::Rect r, byte color);
|
||||
void fillActor(byte color);
|
||||
bool isPixelCollision(Common::Point &pt);
|
||||
public:
|
||||
IllusionsEngine *_vm;
|
||||
uint _flags;
|
||||
@ -245,6 +246,7 @@ public:
|
||||
void pauseControlsBySceneId(uint32 sceneId);
|
||||
void unpauseControlsBySceneId(uint32 sceneId);
|
||||
bool getOverlappedObject(Control *control, Common::Point pt, Control **outOverlappedControl, int minPriority);
|
||||
bool getOverlappedObjectAccurate(Control *control, Common::Point pt, Control **outOverlappedControl, int minPriority);
|
||||
bool getDialogItemAtPos(Control *control, Common::Point pt, Control **outOverlappedControl);
|
||||
bool getOverlappedWalkObject(Control *control, Common::Point pt, Control **outOverlappedControl);
|
||||
void destroyControl(Control *control);
|
||||
|
@ -489,10 +489,10 @@ void BbdouSpecialCode::cursorInteractControlRoutine(Control *cursorControl, uint
|
||||
Control *overlappedControl = 0;
|
||||
|
||||
if (cursorData._flags & 1) {
|
||||
foundOverlapped = 0;
|
||||
foundOverlapped = false;
|
||||
} else if (_vm->getCurrentScene() == 0x1000D) {
|
||||
/* TODO foundOverlapped = artcntrlGetOverlappedObjectAccurate(cursorControl, cursorPos,
|
||||
&overlappedControl, cursorData._item10._field58);*/
|
||||
foundOverlapped = _vm->_controls->getOverlappedObjectAccurate(cursorControl, cursorPos,
|
||||
&overlappedControl, cursorData._item10._field58);
|
||||
} else {
|
||||
foundOverlapped = _vm->_controls->getOverlappedObject(cursorControl, cursorPos,
|
||||
&overlappedControl, cursorData._item10._field58);
|
||||
@ -660,17 +660,15 @@ void BbdouSpecialCode::cursorCrosshairControlRoutine(Control *cursorControl, uin
|
||||
|
||||
}
|
||||
|
||||
Common::Point cursorPos = getBackgroundCursorPos(cursorPos);
|
||||
Common::Point cursorPos = getBackgroundCursorPos(screenCursorPos);
|
||||
bool foundOverlapped = false;
|
||||
Control *overlappedControl = 0;
|
||||
|
||||
if (cursorData._flags & 1)
|
||||
foundOverlapped = false;
|
||||
else {
|
||||
/* TODO Implement getOverlappedObjectAccurate
|
||||
foundOverlapped = _vm->_controls->getOverlappedObjectAccurate(cursorControl, cursorPos,
|
||||
&overlappedControl, cursorData._item10._field58);
|
||||
*/
|
||||
}
|
||||
|
||||
if (foundOverlapped) {
|
||||
|
@ -877,6 +877,62 @@ void Screen::drawSurface21(Common::Rect &dstRect, Graphics::Surface *surface, Co
|
||||
|
||||
}
|
||||
|
||||
bool Screen::isSpritePixelSolid16(Common::Point &testPt, Common::Point &drawPosition, Common::Point &drawOffset,
|
||||
const SurfInfo &surfInfo, int16 scale, uint flags, byte *compressedPixels) {
|
||||
|
||||
int ptX = scale * drawPosition.x / 100 + testPt.x - drawOffset.x;
|
||||
int ptY = scale * drawPosition.y / 100 + testPt.y - drawOffset.y;
|
||||
|
||||
if (flags & 1) {
|
||||
const int scaledWidth = scale * surfInfo._dimensions._width / 100;
|
||||
ptX += 2 * (scaledWidth - scaledWidth / 2 - ptX);
|
||||
}
|
||||
|
||||
if (flags & 2) {
|
||||
const int scaledHeight = scale * surfInfo._dimensions._height / 100;
|
||||
ptY += 2 * (scaledHeight - scaledHeight / 2 - ptY);
|
||||
}
|
||||
|
||||
const int pixelLookX = 100 * ptX / scale;
|
||||
const int pixelLookY = 100 * ptY / scale;
|
||||
const int lookOffset = pixelLookX + surfInfo._dimensions._width * pixelLookY;
|
||||
const int dstSize = surfInfo._dimensions._width * surfInfo._dimensions._height;
|
||||
|
||||
if (pixelLookX < 0 || pixelLookX >= surfInfo._dimensions._width ||
|
||||
pixelLookY < 0 || pixelLookY >= surfInfo._dimensions._height ||
|
||||
lookOffset < 0 || lookOffset >= dstSize)
|
||||
return false;
|
||||
|
||||
byte *src = compressedPixels;
|
||||
int processedSize = 0;
|
||||
|
||||
while (processedSize < dstSize) {
|
||||
int16 op = READ_LE_UINT16(src);
|
||||
src += 2;
|
||||
if (op & 0x8000) {
|
||||
int runCount = (op & 0x7FFF) + 1;
|
||||
uint16 runColor = READ_LE_UINT16(src);
|
||||
src += 2;
|
||||
while (runCount--) {
|
||||
if (processedSize == lookOffset)
|
||||
return runColor != _colorKey1;
|
||||
++processedSize;
|
||||
}
|
||||
} else {
|
||||
int copyCount = op + 1;
|
||||
while (copyCount--) {
|
||||
uint16 color = READ_LE_UINT16(src);
|
||||
src += 2;
|
||||
if (processedSize == lookOffset)
|
||||
return color != _colorKey1;
|
||||
++processedSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16 Screen::convertFontColor(byte color) {
|
||||
if (color) {
|
||||
byte r, g, b;
|
||||
|
@ -181,6 +181,9 @@ public:
|
||||
void drawSurface20(Common::Rect &dstRect, Graphics::Surface *surface, Common::Rect &srcRect, uint16 colorKey);
|
||||
void drawSurface21(Common::Rect &dstRect, Graphics::Surface *surface, Common::Rect &srcRect);
|
||||
|
||||
bool isSpritePixelSolid16(Common::Point &testPt, Common::Point &drawPosition, Common::Point &drawOffset,
|
||||
const SurfInfo &surfInfo, int16 scale, uint flags, byte *compressedPixels);
|
||||
|
||||
uint16 convertFontColor(byte color);
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user