mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-02 16:31:01 +00:00
SCUMM: HE: Relabel Polygon functions
This commit is contained in:
parent
4bcfff35bd
commit
483ac31ced
@ -28,7 +28,7 @@
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
void Wiz::polygonClear() {
|
||||
void Wiz::deleteLocalPolygons() {
|
||||
for (int i = 0; i < ARRAYSIZE(_polygons); i++) {
|
||||
if (_polygons[i].flag == 1)
|
||||
_polygons[i].reset();
|
||||
@ -56,11 +56,11 @@ void Wiz::polygonLoad(const uint8 *polData) {
|
||||
vert4y = READ_LE_UINT32(polData + 36);
|
||||
|
||||
polData += 40;
|
||||
polygonStore(id, flag, vert1x, vert1y, vert2x, vert2y, vert3x, vert3y, vert4x, vert4y);
|
||||
set4Polygon(id, flag, vert1x, vert1y, vert2x, vert2y, vert3x, vert3y, vert4x, vert4y);
|
||||
}
|
||||
}
|
||||
|
||||
void Wiz::polygonStore(int id, bool localFlag, int vert1x, int vert1y, int vert2x, int vert2y, int vert3x, int vert3y, int vert4x, int vert4y) {
|
||||
void Wiz::set4Polygon(int id, bool localFlag, int vert1x, int vert1y, int vert2x, int vert2y, int vert3x, int vert3y, int vert4x, int vert4y) {
|
||||
for (int i = 0; i < ARRAYSIZE(_polygons); ++i) {
|
||||
if (_polygons[i].id == 0) {
|
||||
_polygons[i].points[0].x = vert1x;
|
||||
@ -83,7 +83,7 @@ void Wiz::polygonStore(int id, bool localFlag, int vert1x, int vert1y, int vert2
|
||||
}
|
||||
}
|
||||
|
||||
error("Wiz::polygonStore: out of polygon slot, max = %d", ARRAYSIZE(_polygons));
|
||||
error("Wiz::set4Polygon: out of polygon slot, max = %d", ARRAYSIZE(_polygons));
|
||||
}
|
||||
|
||||
void Wiz::polyRotatePoints(Common::Point *pts, int num, int angle) {
|
||||
@ -99,42 +99,6 @@ void Wiz::polyRotatePoints(Common::Point *pts, int num, int angle) {
|
||||
}
|
||||
}
|
||||
|
||||
void Wiz::polygonTransform(int resNum, int state, int po_x, int po_y, int angle, int scale, Common::Point *pts) {
|
||||
int32 w, h;
|
||||
|
||||
getWizImageDim(resNum, state, w, h);
|
||||
|
||||
// set the transformation origin to the center of the image
|
||||
if (_vm->_game.heversion >= 99) {
|
||||
pts[0].x = pts[3].x = -(w / 2);
|
||||
pts[1].x = pts[2].x = w / 2 - 1;
|
||||
pts[0].y = pts[1].y = -(h / 2);
|
||||
pts[2].y = pts[3].y = h / 2 - 1;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
// scale
|
||||
if (scale != 0 && scale != 256) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
pts[i].x = pts[i].x * scale / 256;
|
||||
pts[i].y = pts[i].y * scale / 256;
|
||||
}
|
||||
}
|
||||
|
||||
// rotate
|
||||
if (angle != 0)
|
||||
polyRotatePoints(pts, 4, angle);
|
||||
|
||||
// translate
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
pts[i].x += po_x;
|
||||
pts[i].y += po_y;
|
||||
}
|
||||
}
|
||||
|
||||
void Wiz::polyMovePolygonPoints(Common::Point *listOfPoints, int numverts, int deltaX, int deltaY) {
|
||||
for (int i = 0; i < numverts; i++) {
|
||||
listOfPoints->x += deltaX;
|
||||
@ -187,28 +151,51 @@ void Wiz::polyBuildBoundingRect(Common::Point *points, int numVerts, Common::Rec
|
||||
}
|
||||
}
|
||||
|
||||
void Wiz::polygonErase(int fromId, int toId) {
|
||||
void Wiz::deletePolygon(int fromId, int toId) {
|
||||
for (int i = 0; i < ARRAYSIZE(_polygons); i++) {
|
||||
if (_polygons[i].id >= fromId && _polygons[i].id <= toId)
|
||||
_polygons[i].reset();
|
||||
}
|
||||
}
|
||||
|
||||
int Wiz::polygonTestForObjectHit(int id, int x, int y) {
|
||||
int Wiz::findPolygon(int x, int y) {
|
||||
Common::Point checkPoint((int16)x, (int16)y);
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(_polygons); i++) {
|
||||
if ((id == 0 || _polygons[i].id == id) && _polygons[i].boundingRect.contains(x, y)) {
|
||||
if (isPointInRect(&_polygons[i].boundingRect, &checkPoint)) {
|
||||
if (polyIsPointInsidePoly(_polygons[i], x, y)) {
|
||||
return _polygons[i].id;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Wiz::testForObjectPolygon(int object, int x, int y) {
|
||||
Common::Point checkPoint((int16)x, (int16)y);
|
||||
|
||||
if (object == 0)
|
||||
return 0;
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(_polygons); i++) {
|
||||
if (_polygons[i].id == object) {
|
||||
if (isPointInRect(&_polygons[i].boundingRect, &checkPoint)) {
|
||||
if (polyIsPointInsidePoly(_polygons[i], x, y)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Wiz::polygonDefined(int id) {
|
||||
bool Wiz::doesObjectHavePolygon(int object) {
|
||||
if (object == 0)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(_polygons); i++)
|
||||
if (_polygons[i].id == id)
|
||||
if (_polygons[i].id == object)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -418,13 +418,13 @@ void ScummEngine_v71he::o71_polygonOps() {
|
||||
vert1x = pop();
|
||||
flag = (subOp == ScummEngine_v100he::SO_SET_POLYGON_LOCAL || subOp == SO_SET_POLYGON_LOCAL);
|
||||
id = pop();
|
||||
_wiz->polygonStore(id, flag, vert1x, vert1y, vert2x, vert2y, vert3x, vert3y, vert4x, vert4y);
|
||||
_wiz->set4Polygon(id, flag, vert1x, vert1y, vert2x, vert2y, vert3x, vert3y, vert4x, vert4y);
|
||||
break;
|
||||
case ScummEngine_v100he::SO_DELETE_POLYGON: // HE 100
|
||||
case SO_DELETE_POLYGON:
|
||||
toId = pop();
|
||||
fromId = pop();
|
||||
_wiz->polygonErase(fromId, toId);
|
||||
_wiz->deletePolygon(fromId, toId);
|
||||
break;
|
||||
default:
|
||||
error("o71_polygonOps: default case %d", subOp);
|
||||
@ -434,7 +434,7 @@ void ScummEngine_v71he::o71_polygonOps() {
|
||||
void ScummEngine_v71he::o71_polygonHit() {
|
||||
int y = pop();
|
||||
int x = pop();
|
||||
push(_wiz->polygonTestForObjectHit(0, x, y));
|
||||
push(_wiz->findPolygon(x, y));
|
||||
}
|
||||
|
||||
} // End of namespace Scumm
|
||||
|
@ -417,8 +417,8 @@ int ScummEngine_v72he::findObject(int x, int y, int num, int *args) {
|
||||
continue;
|
||||
|
||||
// Check polygon bounds
|
||||
if (_wiz->polygonDefined(_objs[i].obj_nr)) {
|
||||
if (_wiz->polygonTestForObjectHit(_objs[i].obj_nr, x, y))
|
||||
if (_wiz->doesObjectHavePolygon(_objs[i].obj_nr)) {
|
||||
if (_wiz->testForObjectPolygon(_objs[i].obj_nr, x, y))
|
||||
result = _objs[i].obj_nr;
|
||||
else if (VAR_POLYGONS_ONLY != 0xFF && VAR(VAR_POLYGONS_ONLY))
|
||||
continue;
|
||||
|
@ -1206,7 +1206,7 @@ void ScummEngine_v90he::o90_setSpriteGroupInfo() {
|
||||
_sprite->setGroupMembersShadow(_curSpriteGroupId, value1);
|
||||
break;
|
||||
default:
|
||||
error("o90_setSpriteGroupInfo subOp 0: Unknown case %d", subOp);
|
||||
error("o90_setSpriteGroupInfo checkType 0: Unknown case %d", subOp);
|
||||
}
|
||||
break;
|
||||
case SO_PROPERTY: // 42
|
||||
@ -1229,7 +1229,7 @@ void ScummEngine_v90he::o90_setSpriteGroupInfo() {
|
||||
_sprite->setGroupYDiv(_curSpriteGroupId, value1);
|
||||
break;
|
||||
default:
|
||||
error("o90_setSpriteGroupInfo subOp 5: Unknown case %d", subOp);
|
||||
error("o90_setSpriteGroupInfo checkType 5: Unknown case %d", subOp);
|
||||
}
|
||||
break;
|
||||
case SO_PRIORITY: // 43
|
||||
@ -1536,7 +1536,7 @@ void ScummEngine_v90he::o90_getVideoData() {
|
||||
push(_moviePlay->getImageNum());
|
||||
break;
|
||||
case SO_NEW_GENERAL_PROPERTY: // 139
|
||||
debug(0, "o90_getVideoData: subOp 107 stub (%d, %d)", pop(), pop());
|
||||
debug(0, "o90_getVideoData: checkType 107 stub (%d, %d)", pop(), pop());
|
||||
push(0);
|
||||
break;
|
||||
default:
|
||||
@ -1637,71 +1637,72 @@ void ScummEngine_v90he::o90_findAllObjectsWithClassOf() {
|
||||
}
|
||||
|
||||
void ScummEngine_v90he::o90_getPolygonOverlap() {
|
||||
int args1[32];
|
||||
int args2[32];
|
||||
int lastList[32];
|
||||
int firstList[32];
|
||||
|
||||
int n1 = getStackList(args1, ARRAYSIZE(args1));
|
||||
int n2 = getStackList(args2, ARRAYSIZE(args2));
|
||||
int lastCount = getStackList(lastList, ARRAYSIZE(lastList));
|
||||
int firstCount = getStackList(firstList, ARRAYSIZE(firstList));
|
||||
|
||||
int subOp = pop();
|
||||
int checkType = pop();
|
||||
|
||||
switch (subOp) {
|
||||
switch (checkType) {
|
||||
case OVERLAP_POINT_TO_RECT: // 1
|
||||
{
|
||||
Common::Rect r(args1[0], args1[1], args1[2] + 1, args1[3] + 1);
|
||||
Common::Point p(args2[0], args2[1]);
|
||||
push(r.contains(p) ? 1 : 0);
|
||||
Common::Rect r(lastList[0], lastList[1], lastList[2], lastList[3]);
|
||||
Common::Point p(firstList[0], firstList[1]);
|
||||
|
||||
push(_wiz->isPointInRect(&r, &p) ? 1 : 0);
|
||||
}
|
||||
break;
|
||||
case OVERLAP_POINT_TO_CIRCLE: // 2
|
||||
{
|
||||
int dx = args2[0] - args1[0];
|
||||
int dy = args2[1] - args1[1];
|
||||
int dx = firstList[0] - lastList[0];
|
||||
int dy = firstList[1] - lastList[1];
|
||||
int dist = dx * dx + dy * dy;
|
||||
if (dist >= 2) {
|
||||
dist = (int)sqrt((double)(dist + 1));
|
||||
}
|
||||
if (_game.heversion >= 98) {
|
||||
push((dist <= args1[2]) ? 1 : 0);
|
||||
push((dist <= lastList[2]) ? 1 : 0);
|
||||
} else {
|
||||
push((dist > args1[2]) ? 1 : 0);
|
||||
push((dist > lastList[2]) ? 1 : 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OVERLAP_RECT_TO_RECT: // 3
|
||||
{
|
||||
Common::Rect r1(args1[0], args1[1], args1[2] + 1, args1[3] + 1);
|
||||
Common::Rect r2(args2[0], args2[1], args2[2] + 1, args2[3] + 1);
|
||||
Common::Rect r1(lastList[0], lastList[1], lastList[2] + 1, lastList[3] + 1);
|
||||
Common::Rect r2(firstList[0], firstList[1], firstList[2] + 1, firstList[3] + 1);
|
||||
push(r2.intersects(r1) ? 1 : 0);
|
||||
}
|
||||
break;
|
||||
case OVERLAP_CIRCLE_TO_CIRCLE: // 4
|
||||
{
|
||||
int dx = args2[0] - args1[0];
|
||||
int dy = args2[1] - args1[1];
|
||||
int dx = firstList[0] - lastList[0];
|
||||
int dy = firstList[1] - lastList[1];
|
||||
int dist = dx * dx + dy * dy;
|
||||
if (dist >= 2) {
|
||||
dist = (int)sqrt((double)(dist + 1));
|
||||
}
|
||||
push((dist < args1[2] && dist < args2[2]) ? 1 : 0);
|
||||
push((dist < lastList[2] && dist < firstList[2]) ? 1 : 0);
|
||||
}
|
||||
break;
|
||||
case OVERLAP_POINT_N_SIDED_POLYGON: // 5
|
||||
{
|
||||
assert((n1 & 1) == 0);
|
||||
n1 /= 2;
|
||||
if (n1 == 0) {
|
||||
assert((lastCount & 1) == 0);
|
||||
lastCount /= 2;
|
||||
if (lastCount == 0) {
|
||||
push(0);
|
||||
} else {
|
||||
WizPolygon wp;
|
||||
wp.reset();
|
||||
wp.numPoints = n1;
|
||||
assert(n1 < ARRAYSIZE(wp.points));
|
||||
for (int i = 0; i < n1; ++i) {
|
||||
wp.points[i].x = args1[i * 2 + 0];
|
||||
wp.points[i].y = args1[i * 2 + 1];
|
||||
wp.numPoints = lastCount;
|
||||
assert(lastCount < ARRAYSIZE(wp.points));
|
||||
for (int i = 0; i < lastCount; ++i) {
|
||||
wp.points[i].x = lastList[i * 2 + 0];
|
||||
wp.points[i].y = lastList[i * 2 + 1];
|
||||
}
|
||||
push(_wiz->polyIsPointInsidePoly(wp, args2[0], args2[1]) ? 1 : 0);
|
||||
push(_wiz->polyIsPointInsidePoly(wp, firstList[0], firstList[1]) ? 1 : 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1709,24 +1710,24 @@ void ScummEngine_v90he::o90_getPolygonOverlap() {
|
||||
case OVERLAP_SPRITE_TO_SPRITE: // 6
|
||||
{
|
||||
Common::Rect r1, r2;
|
||||
_sprite->getSpriteLogicalRect(args2[0], false, r2);
|
||||
_sprite->getSpriteLogicalRect(args1[0], false, r1);
|
||||
_sprite->getSpriteLogicalRect(firstList[0], false, r2);
|
||||
_sprite->getSpriteLogicalRect(lastList[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];
|
||||
if (firstCount == 3) {
|
||||
r2.left += firstList[1];
|
||||
r2.right += firstList[1];
|
||||
r2.top += firstList[2];
|
||||
r2.bottom += firstList[2];
|
||||
}
|
||||
if (n1 == 3) {
|
||||
r1.left += args1[1];
|
||||
r1.right += args1[1];
|
||||
r1.top += args1[2];
|
||||
r1.bottom += args1[2];
|
||||
if (lastCount == 3) {
|
||||
r1.left += lastList[1];
|
||||
r1.right += lastList[1];
|
||||
r1.top += lastList[2];
|
||||
r1.bottom += lastList[2];
|
||||
}
|
||||
push(r2.intersects(r1) ? 1 : 0);
|
||||
}
|
||||
@ -1734,18 +1735,18 @@ void ScummEngine_v90he::o90_getPolygonOverlap() {
|
||||
case OVERLAP_SPRITE_TO_RECT: // 7
|
||||
{
|
||||
Common::Rect r2;
|
||||
_sprite->getSpriteLogicalRect(args2[0], false, r2);
|
||||
Common::Rect r1(args1[0], args1[1], args1[2] + 1, args1[3] + 1);
|
||||
_sprite->getSpriteLogicalRect(firstList[0], false, r2);
|
||||
Common::Rect r1(lastList[0], lastList[1], lastList[2] + 1, lastList[3] + 1);
|
||||
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];
|
||||
if (firstCount == 3) {
|
||||
r2.left += firstList[1];
|
||||
r2.right += firstList[1];
|
||||
r2.top += firstList[2];
|
||||
r2.bottom += firstList[2];
|
||||
}
|
||||
push(r2.intersects(r1) ? 1 : 0);
|
||||
}
|
||||
@ -1755,24 +1756,24 @@ void ScummEngine_v90he::o90_getPolygonOverlap() {
|
||||
// TODO: Draw sprites to buffer and compare.
|
||||
{
|
||||
Common::Rect r1, r2;
|
||||
_sprite->getSpriteLogicalRect(args2[0], true, r2);
|
||||
_sprite->getSpriteLogicalRect(args1[0], true, r1);
|
||||
_sprite->getSpriteLogicalRect(firstList[0], true, r2);
|
||||
_sprite->getSpriteLogicalRect(lastList[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];
|
||||
if (firstCount == 3) {
|
||||
r2.left += firstList[1];
|
||||
r2.right += firstList[1];
|
||||
r2.top += firstList[2];
|
||||
r2.bottom += firstList[2];
|
||||
}
|
||||
if (n1 == 3) {
|
||||
r1.left += args1[1];
|
||||
r1.right += args1[1];
|
||||
r1.top += args1[2];
|
||||
r1.bottom += args1[2];
|
||||
if (lastCount == 3) {
|
||||
r1.left += lastList[1];
|
||||
r1.right += lastList[1];
|
||||
r1.top += lastList[2];
|
||||
r1.bottom += lastList[2];
|
||||
}
|
||||
push(r2.intersects(r1) ? 1 : 0);
|
||||
}
|
||||
@ -1780,24 +1781,24 @@ void ScummEngine_v90he::o90_getPolygonOverlap() {
|
||||
case OVERLAP_DRAW_POS_SPRITE_TO_RECT: // 9
|
||||
{
|
||||
Common::Rect r2;
|
||||
_sprite->getSpriteLogicalRect(args2[0], true, r2);
|
||||
Common::Rect r1(args1[0], args1[1], args1[2] + 1, args1[3] + 1);
|
||||
_sprite->getSpriteLogicalRect(firstList[0], true, r2);
|
||||
Common::Rect r1(lastList[0], lastList[1], lastList[2] + 1, lastList[3] + 1);
|
||||
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];
|
||||
if (firstCount == 3) {
|
||||
r2.left += firstList[1];
|
||||
r2.right += firstList[1];
|
||||
r2.top += firstList[2];
|
||||
r2.bottom += firstList[2];
|
||||
}
|
||||
push(r2.intersects(r1) ? 1 : 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error("o90_getPolygonOverlap: default case %d", subOp);
|
||||
error("o90_getPolygonOverlap: default case %d", checkType);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -520,16 +520,16 @@ public:
|
||||
bool _uses16BitColor = false;
|
||||
int _lWizActiveShadow = 0;
|
||||
|
||||
void polygonClear();
|
||||
void deleteLocalPolygons();
|
||||
void polygonLoad(const uint8 *polData);
|
||||
void polygonStore(int id, bool flag, int vert1x, int vert1y, int vert2x, int vert2y, int vert3x, int vert3y, int vert4x, int vert4y);
|
||||
void set4Polygon(int id, bool flag, int vert1x, int vert1y, int vert2x, int vert2y, int vert3x, int vert3y, int vert4x, int vert4y);
|
||||
void polyBuildBoundingRect(Common::Point *vert, int numVerts, Common::Rect & bound);
|
||||
void polygonErase(int fromId, int toId);
|
||||
int polygonTestForObjectHit(int id, int x, int y);
|
||||
bool polygonDefined(int id);
|
||||
void deletePolygon(int fromId, int toId);
|
||||
int testForObjectPolygon(int id, int x, int y);
|
||||
int findPolygon(int x, int y);
|
||||
bool doesObjectHavePolygon(int id);
|
||||
bool polyIsPointInsidePoly(const WizPolygon &pol, int x, int y);
|
||||
void polyRotatePoints(Common::Point *pts, int num, int alpha);
|
||||
void polygonTransform(int resNum, int state, int po_x, int po_y, int angle, int zoom, Common::Point *vert);
|
||||
void polyMovePolygonPoints(Common::Point *listOfPoints, int numverts, int deltaX, int deltaY);
|
||||
bool polyIsRectangle(const Common::Point *points, int numverts);
|
||||
|
||||
|
@ -569,7 +569,7 @@ int ScummEngine::findObject(int x, int y) {
|
||||
if (b == 0) {
|
||||
#ifdef ENABLE_HE
|
||||
if (_game.heversion >= 71) {
|
||||
if (((ScummEngine_v71he *)this)->_wiz->polygonTestForObjectHit(_objs[i].obj_nr, x, y))
|
||||
if (((ScummEngine_v71he *)this)->_wiz->testForObjectPolygon(_objs[i].obj_nr, x, y))
|
||||
return _objs[i].obj_nr;
|
||||
}
|
||||
#endif
|
||||
@ -1213,7 +1213,7 @@ void ScummEngine_v6::clearDrawQueues() {
|
||||
void ScummEngine_v71he::clearDrawQueues() {
|
||||
ScummEngine_v6::clearDrawQueues();
|
||||
|
||||
_wiz->polygonClear();
|
||||
_wiz->deleteLocalPolygons();
|
||||
}
|
||||
|
||||
void ScummEngine_v80he::clearDrawQueues() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user