ILLUSIONS: BBDOU: Implement getOverlappedObjectAccurate and related functions

This commit is contained in:
johndoe123 2015-12-10 22:16:25 +01:00 committed by Eugene Sandulenko
parent 27a5e93268
commit 869d342e9f
5 changed files with 106 additions and 6 deletions

View File

@ -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) {

View File

@ -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);

View File

@ -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) {

View File

@ -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;

View File

@ -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);
};