aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjohndoe1232015-12-10 22:16:25 +0100
committerEugene Sandulenko2018-07-20 06:43:33 +0000
commit869d342e9f110374683002d405803d01d365119b (patch)
tree5aaa3f091594dd1a46d43628011b8e3e9d1dd625
parent27a5e93268310062767c52e6fd1effa2e39920e4 (diff)
downloadscummvm-rg350-869d342e9f110374683002d405803d01d365119b.tar.gz
scummvm-rg350-869d342e9f110374683002d405803d01d365119b.tar.bz2
scummvm-rg350-869d342e9f110374683002d405803d01d365119b.zip
ILLUSIONS: BBDOU: Implement getOverlappedObjectAccurate and related functions
-rw-r--r--engines/illusions/actor.cpp41
-rw-r--r--engines/illusions/actor.h2
-rw-r--r--engines/illusions/bbdou/bbdou_specialcode.cpp10
-rw-r--r--engines/illusions/screen.cpp56
-rw-r--r--engines/illusions/screen.h3
5 files changed, 106 insertions, 6 deletions
diff --git a/engines/illusions/actor.cpp b/engines/illusions/actor.cpp
index 33610ca6af..a273b52373 100644
--- a/engines/illusions/actor.cpp
+++ b/engines/illusions/actor.cpp
@@ -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) {
diff --git a/engines/illusions/actor.h b/engines/illusions/actor.h
index add7519156..d82ca02228 100644
--- a/engines/illusions/actor.h
+++ b/engines/illusions/actor.h
@@ -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);
diff --git a/engines/illusions/bbdou/bbdou_specialcode.cpp b/engines/illusions/bbdou/bbdou_specialcode.cpp
index 9278a41813..497bc561b0 100644
--- a/engines/illusions/bbdou/bbdou_specialcode.cpp
+++ b/engines/illusions/bbdou/bbdou_specialcode.cpp
@@ -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) {
diff --git a/engines/illusions/screen.cpp b/engines/illusions/screen.cpp
index a4a3d27430..52627c84ce 100644
--- a/engines/illusions/screen.cpp
+++ b/engines/illusions/screen.cpp
@@ -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;
diff --git a/engines/illusions/screen.h b/engines/illusions/screen.h
index 6c3e83b8ee..e22e9b16dc 100644
--- a/engines/illusions/screen.h
+++ b/engines/illusions/screen.h
@@ -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);
};