diff options
-rw-r--r-- | scumm/intern.h | 1 | ||||
-rw-r--r-- | scumm/script_v90he.cpp | 74 | ||||
-rw-r--r-- | scumm/sprite_he.cpp | 74 |
3 files changed, 143 insertions, 6 deletions
diff --git a/scumm/intern.h b/scumm/intern.h index b8ebadc038..fcdd1741f5 100644 --- a/scumm/intern.h +++ b/scumm/intern.h @@ -910,6 +910,7 @@ protected: void copyHEPalette(int dstPalSlot, int srcPalSlot); void copyHEPaletteColor(int palSlot, uint8 dstColor, uint8 srcColor); + void getSpriteBounds(int spriteId, bool checkGroup, Common::Rect &bound); int findSpriteWithClassOf(int x, int y, int spriteGroupId, int d, int num, int *args); int spriteInfoGet_classFlags(int spriteId, int num, int *args); int spriteInfoGet_flagDoubleBuffered(int spriteId); diff --git a/scumm/script_v90he.cpp b/scumm/script_v90he.cpp index 9ac08c16dc..a3533fb20b 100644 --- a/scumm/script_v90he.cpp +++ b/scumm/script_v90he.cpp @@ -1729,7 +1729,7 @@ void ScummEngine_v90he::o90_getPolygonOverlap() { int args2[32]; int n1 = getStackList(args1, ARRAYSIZE(args1)); - getStackList(args2, ARRAYSIZE(args2)); + int n2 = getStackList(args2, ARRAYSIZE(args2)); int subOp = pop(); @@ -1791,9 +1791,81 @@ void ScummEngine_v90he::o90_getPolygonOverlap() { break; // HE 98+ case 6: + { + Common::Rect r1, r2; + getSpriteBounds(args2[0], false, r2); + getSpriteBounds(args1[0], false, r1); + if (r2.isValidRect() == false) { + push(0); + break; + } + + if (n2 == 3) { + r2.left += args2[1]; + r2.right += args2[1]; + r2.top += args2[2]; + r2.bottom += args2[2]; + } + push(r2.intersects(r1) ? 1 : 0); + } + break; case 7: + { + Common::Rect r2; + getSpriteBounds(args2[0], false, r2); + Common::Rect r1(args1[0], args1[1], args1[2], args1[3]); + if (r2.isValidRect() == false) { + push(0); + break; + } + + if (n2 == 3) { + r2.left += args2[1]; + r2.right += args2[1]; + r2.top += args2[2]; + r2.bottom += args2[2]; + } + push(r2.intersects(r1) ? 1 : 0); + } + break; case 8: + { + Common::Rect r1, r2; + getSpriteBounds(args2[0], true, r2); + getSpriteBounds(args1[0], true, r1); + if (r2.isValidRect() == false) { + push(0); + break; + } + + if (n2 == 3) { + r2.left += args2[1]; + r2.right += args2[1]; + r2.top += args2[2]; + r2.bottom += args2[2]; + } + push(r2.intersects(r1) ? 1 : 0); + } + break; case 9: + { + Common::Rect r2; + getSpriteBounds(args2[0], true, r2); + Common::Rect r1(args1[0], args1[1], args1[2], args1[3]); + if (r2.isValidRect() == false) { + push(0); + break; + } + + if (n2 == 3) { + r2.left += args2[1]; + r2.right += args2[1]; + r2.top += args2[2]; + r2.bottom += args2[2]; + } + push(r2.intersects(r1) ? 1 : 0); + } + break; case 10: push(0); break; diff --git a/scumm/sprite_he.cpp b/scumm/sprite_he.cpp index 60e8e33f2c..4e006186b7 100644 --- a/scumm/sprite_he.cpp +++ b/scumm/sprite_he.cpp @@ -35,6 +35,70 @@ void ScummEngine_v90he::allocateArrays() { spritesAllocTables(_numSprites, MAX(64, _numSprites / 4), 64); } +void ScummEngine_v90he::getSpriteBounds(int spriteId, bool checkGroup, Common::Rect &bound) { + checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d"); + int16 spr_wiz_x, spr_wiz_y; + int rot_angle, zoom, x1, y1; + int32 w, h; + + SpriteInfo *spi = &_spriteTable[spriteId]; + + loadImgSpot(spi->res_id, spi->res_state, spr_wiz_x, spr_wiz_y); + if (checkGroup && spi->group_num) { + SpriteGroup *spg = &_spriteGroups[spi->group_num]; + + if (spg->scaling) { + x1 = spi->tx * spg->scale_x - spr_wiz_x + spg->tx; + y1 = spi->ty * spg->scale_y - spr_wiz_y + spg->ty; + } else { + x1 = spi->tx - spr_wiz_x + spg->tx; + y1 = spi->ty - spr_wiz_y + spg->ty; + } + } else { + x1 = spi->tx - spr_wiz_x; + y1 = spi->ty - spr_wiz_y; + } + + if (spi->res_id) { + rot_angle = spi->rot_angle; + zoom = spi->zoom; + getWizImageDim(spi->res_id, spi->res_state, w, h); + if (!(spi->flags & (kSFZoomed | kSFRotated))) { + bound.left = x1; + bound.top = y1; + bound.right = x1 + w; + bound.bottom = y1 + h; + } else { + Common::Point pts[4]; + + pts[1].x = pts[2].x = w / 2 - 1; + pts[0].x = pts[0].y = pts[1].y = pts[3].x = -w / 2; + pts[2].y = pts[3].y = h / 2 - 1; + + if ((spi->flags & kSFZoomed) && zoom) { + for (int j = 0; j < 4; ++j) { + pts[j].x = pts[j].x * zoom / 256; + pts[j].y = pts[j].y * zoom / 256; + } + } + if ((spi->flags & kSFRotated) && rot_angle) + _wiz.polygonRotatePoints(pts, 4, rot_angle); + + for (int j = 0; j < 4; ++j) { + pts[j].x += x1; + pts[j].y += y1; + } + + _wiz.polygonCalcBoundBox(pts, 4, bound); + } + } else { + bound.left = 1234; + bound.top = 1234; + bound.right = -1234; + bound.bottom = -1234; + } +} + // // spriteInfoGet functions // @@ -1193,7 +1257,7 @@ void ScummEngine_v90he::spritesProcessWiz(bool arg) { rot_angle = spi->rot_angle; zoom = spi->zoom; getWizImageDim(res_id, res_state, w, h); - if (!(spi->flags & kSFZoomed) && !(spi->flags & kSFRotated)) { + if (!(spi->flags & (kSFZoomed | kSFRotated))) { bboxPtr->left = wiz.img.x1; bboxPtr->top = wiz.img.y1; bboxPtr->right = wiz.img.x1 + w; @@ -1205,13 +1269,13 @@ void ScummEngine_v90he::spritesProcessWiz(bool arg) { pts[0].x = pts[0].y = pts[1].y = pts[3].x = -w / 2; pts[2].y = pts[3].y = h / 2 - 1; - if (spi->flags & kSFZoomed && zoom) { + if ((spi->flags & kSFZoomed) && zoom) { for (int j = 0; j < 4; ++j) { - pts[j].x = pts[i].x * zoom / 256; - pts[j].y = pts[i].y * zoom / 256; + pts[j].x = pts[j].x * zoom / 256; + pts[j].y = pts[j].y * zoom / 256; } } - if (spi->flags & kSFRotated && rot_angle) + if ((spi->flags & kSFRotated) && rot_angle) _wiz.polygonRotatePoints(pts, 4, rot_angle); for (int j = 0; j < 4; ++j) { |