ASYLUM: Cleanup polygon class

This commit is contained in:
Julien Templier 2011-07-15 13:56:46 -04:00 committed by Eugene Sandulenko
parent def09b8c20
commit 5b3efe8192
No known key found for this signature in database
GPG key ID: 014D387312D34F08
6 changed files with 71 additions and 99 deletions

View file

@ -117,13 +117,13 @@ void Puzzle::exitPuzzle() {
// Hit test functions // Hit test functions
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
bool Puzzle::hitTest(const Common::Point *polygonPoint, Common::Point point, uint32 index) { bool Puzzle::hitTest(const Common::Point *polygonPoint, Common::Point point, uint32 index) {
PolyDefinitions polygon(polygonPoint[index], polygonPoint[index + 1], polygonPoint[index + 2], polygonPoint[index + 3]); Polygon polygon(polygonPoint[index], polygonPoint[index + 1], polygonPoint[index + 2], polygonPoint[index + 3]);
return polygon.contains(point); return polygon.contains(point);
} }
bool Puzzle::hitTest(const Common::Point *polygonPoint, Common::Point point) { bool Puzzle::hitTest(const Common::Point *polygonPoint, Common::Point point) {
PolyDefinitions polygon(polygonPoint[0], polygonPoint[1], polygonPoint[2], polygonPoint[3]); Polygon polygon(polygonPoint[0], polygonPoint[1], polygonPoint[2], polygonPoint[3]);
return polygon.contains(point); return polygon.contains(point);
} }

View file

@ -816,10 +816,10 @@ void Actor::faceTarget(uint32 target, DirectionFrom from) {
return; return;
} }
PolyDefinitions *polygon = &getScene()->polygons()->entries[getWorld()->actions[actionIndex]->polygonIndex]; Polygon polygon = getScene()->polygons()->get(getWorld()->actions[actionIndex]->polygonIndex);
point.x = polygon->boundingRect.left + (polygon->boundingRect.right - polygon->boundingRect.left) / 2; point.x = polygon.boundingRect.left + (polygon.boundingRect.right - polygon.boundingRect.left) / 2;
point.y = polygon->boundingRect.top + (polygon->boundingRect.bottom - polygon->boundingRect.top) / 2; point.y = polygon.boundingRect.top + (polygon.boundingRect.bottom - polygon.boundingRect.top) / 2;
} }
break; break;
@ -1177,15 +1177,15 @@ void Actor::process_401830(int32 field980, int32 actionAreaId, int32 field978, i
field_984 = field984; field_984 = field984;
field_988 = field988; field_988 = field988;
} else { } else {
PolyDefinitions *polygon = &getScene()->polygons()->entries[_actionIdx1]; Polygon polygon = getScene()->polygons()->get(_actionIdx1);
field_984 = polygon->points[0].x; field_984 = polygon.points[0].x;
field_988 = polygon->points[0].y; field_988 = polygon.points[0].y;
// Iterate through points // Iterate through points
if (polygon->count() > 1) { if (polygon.count() > 1) {
for (uint i = 1; i < polygon->count() - 1; i++) { for (uint i = 1; i < polygon.count() - 1; i++) {
Common::Point point = polygon->points[i]; Common::Point point = polygon.points[i];
switch (field978) { switch (field978) {
default: default:
@ -1867,15 +1867,15 @@ void Actor::updateStatusEnabled() {
if (areaIndex != -1) { if (areaIndex != -1) {
ActionArea *area = getWorld()->actions[areaIndex]; ActionArea *area = getWorld()->actions[areaIndex];
PolyDefinitions *poly = &getScene()->polygons()->entries[area->polygonIndex]; Polygon poly = getScene()->polygons()->get(area->polygonIndex);
Common::Point pt(poly->boundingRect.left + rnd(poly->boundingRect.width()), Common::Point pt(poly.boundingRect.left + rnd(poly.boundingRect.width()),
poly->boundingRect.top + rnd(poly->boundingRect.height())); poly.boundingRect.top + rnd(poly.boundingRect.height()));
if (!getSharedData()->actorUpdateEnabledCheck) { if (!getSharedData()->actorUpdateEnabledCheck) {
if (!isInActionArea(pt, area)) { if (!isInActionArea(pt, area)) {
Common::Point *polyPoint = &poly->points[rnd(poly->count())]; Common::Point polyPoint = poly.points[rnd(poly.count())];
processStatus(polyPoint->x, polyPoint->y, false); processStatus(polyPoint.x, polyPoint.y, false);
} else { } else {
processStatus(pt.x, pt.y, false); processStatus(pt.x, pt.y, false);
} }
@ -2699,7 +2699,7 @@ bool Actor::isInActionArea(const Common::Point &pt, ActionArea *area) {
if (found) if (found)
return false; return false;
PolyDefinitions poly = getScene()->polygons()->entries[area->polygonIndex]; Polygon poly = getScene()->polygons()->get(area->polygonIndex);
if (!poly.contains(pt)) if (!poly.contains(pt))
return false; return false;

View file

@ -24,15 +24,10 @@
namespace Asylum { namespace Asylum {
Polygons::Polygons(Common::SeekableReadStream *stream) : size(0), numEntries(0) { //////////////////////////////////////////////////////////////////////////
load(stream); // Contains
} //////////////////////////////////////////////////////////////////////////
bool Polygon::contains(const Common::Point &point) {
Polygons::~Polygons() {
entries.clear();
}
bool PolyDefinitions::contains(int16 x, int16 y) {
// Copied from backends/vkeybd/polygon.cpp // Copied from backends/vkeybd/polygon.cpp
bool yflag0; bool yflag0;
bool yflag1; bool yflag1;
@ -41,11 +36,11 @@ bool PolyDefinitions::contains(int16 x, int16 y) {
Common::Point *vtx0 = &points[count() - 1]; Common::Point *vtx0 = &points[count() - 1];
Common::Point *vtx1 = &points[0]; Common::Point *vtx1 = &points[0];
yflag0 = (vtx0->y >= y); yflag0 = (vtx0->y >= point.y);
for (uint32 pt = 0; pt < count(); pt++, vtx1++) { for (uint32 pt = 0; pt < count(); pt++, vtx1++) {
yflag1 = (vtx1->y >= y); yflag1 = (vtx1->y >= point.y);
if (yflag0 != yflag1) { if (yflag0 != yflag1) {
if (((vtx1->y - y) * (vtx0->x - vtx1->x) >= (vtx1->x - x) * (vtx0->y - vtx1->y)) == yflag1) { if (((vtx1->y - point.y) * (vtx0->x - vtx1->x) >= (vtx1->x - point.x) * (vtx0->y - vtx1->y)) == yflag1) {
inside_flag = !inside_flag; inside_flag = !inside_flag;
} }
} }
@ -56,12 +51,30 @@ bool PolyDefinitions::contains(int16 x, int16 y) {
return inside_flag; return inside_flag;
} }
void Polygons::load(Common::SeekableReadStream *stream) { //////////////////////////////////////////////////////////////////////////
size = stream->readSint32LE(); // Polygons
numEntries = stream->readSint32LE(); //////////////////////////////////////////////////////////////////////////
Polygons::Polygons(Common::SeekableReadStream *stream) : _size(0), _numEntries(0) {
load(stream);
}
for (int32 g = 0; g < numEntries; g++) { Polygons::~Polygons() {
PolyDefinitions poly; _entries.clear();
}
Polygon Polygons::get(uint32 index) {
if (index >= _entries.size())
error("[Polygons::getEntry] Invalid polygon index (was: %d, max: %d)", index, _entries.size() - 1);
return _entries[index];
}
void Polygons::load(Common::SeekableReadStream *stream) {
_size = stream->readSint32LE();
_numEntries = stream->readSint32LE();
for (int32 g = 0; g < _numEntries; g++) {
Polygon poly;
uint32 numPoints = stream->readUint32LE(); uint32 numPoints = stream->readUint32LE();
@ -80,32 +93,8 @@ void Polygons::load(Common::SeekableReadStream *stream) {
poly.boundingRect.right = (int16)(stream->readSint32LE() & 0xFFFF); poly.boundingRect.right = (int16)(stream->readSint32LE() & 0xFFFF);
poly.boundingRect.bottom = (int16)(stream->readSint32LE() & 0xFFFF); poly.boundingRect.bottom = (int16)(stream->readSint32LE() & 0xFFFF);
entries.push_back(poly); _entries.push_back(poly);
} }
} }
//////////////////////////////////////////////////////////////////////////
// Contains
//////////////////////////////////////////////////////////////////////////
bool Polygons::contains(Common::Point *points, uint32 count, Common::Point point, Common::Rect *boundingRect) {
error("[Polygons::contains] Not implemented!");
}
bool Polygons::contains(int32 x1, int32 y1, int32 x2, int32 y2, int32 x3, int32 y3, int32 x4, int32 y4) {
return (compareDistance(x1, y1, x2, y2, x3, y3) * compareDistance(x1, y1, x2, y2, x4, y4)) <= 0
&& (compareDistance(x3, y3, x4, y4, x1, y1) * compareDistance(x3, y3, x4, y4, x2, y2) <= 0);
}
int32 Polygons::compareDistance(int32 x1, int32 y1, int32 x2, int32 y2, int32 x3, int32 y3) {
uint32 d1 = (y3 - y1) * (x2 - x1);
uint32 d2 = (x3 - x1) * (y2 - y1);
return (d1 <= d2) ? -1 : 1;
}
bool Polygons::containsRect(Common::Point *points, uint32 count, Common::Point point, Common::Rect *boundingRect) {
error("[Polygons::containsHelper] Not implemented!");
}
} // end of namespace Asylum } // end of namespace Asylum

View file

@ -31,55 +31,38 @@
namespace Asylum { namespace Asylum {
typedef struct PolyDefinitions { class Polygon {
public:
Common::Array<Common::Point> points; Common::Array<Common::Point> points;
Common::Rect boundingRect; Common::Rect boundingRect;
PolyDefinitions() {}; Polygon() {};
PolyDefinitions(Common::Point point1, Common::Point point2, Common::Point point3, Common::Point point4) { Polygon(Common::Point point1, Common::Point point2, Common::Point point3, Common::Point point4) {
points.push_back(point1); points.push_back(point1);
points.push_back(point2); points.push_back(point2);
points.push_back(point3); points.push_back(point3);
points.push_back(point4); points.push_back(point4);
} }
/** bool contains(const Common::Point &point);
* Check if the x/y coordinates exist within uint32 count() { return points.size(); }
* the current polygon definition };
*
* (was pointInPoly())
*/
bool contains(int16 x, int16 y);
bool contains(Common::Point point) {
return contains(point.x, point.y);
}
uint32 count() {
return points.size();
}
} PolyDefinitions;
class Polygons { class Polygons {
public: public:
Polygons(Common::SeekableReadStream *stream); Polygons(Common::SeekableReadStream *stream);
virtual ~Polygons(); virtual ~Polygons();
int32 size; Polygon get(uint32 index);
int32 numEntries; // TODO remove and use entries.size() uint32 size() { return _entries.size(); }
Common::Array<PolyDefinitions> entries;
static bool contains(Common::Point *points, uint32 count, Common::Point point, Common::Rect *boundingRect);
static bool contains(int32 x1, int32 y1, int32 x2, int32 y2, int32 x3, int32 y3, int32 x4, int32 y4);
private: private:
int32 _size;
int32 _numEntries;
Common::Array<Polygon> _entries;
void load(Common::SeekableReadStream *stream); void load(Common::SeekableReadStream *stream);
static int32 compareDistance(int32 x1, int32 y1, int32 x2, int32 y2, int32 x3, int32 y3);
static bool containsRect(Common::Point *points, uint32 count, Common::Point point, Common::Rect *boundingRect);
}; // end of class Polygons }; // end of class Polygons
} // end of namespace Asylum } // end of namespace Asylum

View file

@ -2158,7 +2158,7 @@ int32 Scene::findActionArea(ActionAreaType type, const Common::Point pt) {
} }
} }
if (!found && _polygons->entries[area->polygonIndex].contains(pt)) if (!found && _polygons->get(area->polygonIndex).contains(pt))
return i; return i;
} }
break; break;
@ -2189,7 +2189,7 @@ int32 Scene::findActionArea(ActionAreaType type, const Common::Point pt) {
} }
} }
if (!found && _polygons->entries[area->polygonIndex].contains(pt)) if (!found && _polygons->get(area->polygonIndex).contains(pt))
return i; return i;
} }
break; break;
@ -2482,8 +2482,8 @@ void Scene::processUpdateList() {
if (object->flags & kObjectFlag2) { if (object->flags & kObjectFlag2) {
isMasked = !pointIntersectsRect(sum, *object->getRect()); isMasked = !pointIntersectsRect(sum, *object->getRect());
} else if (object->flags & kObjectFlag40) { } else if (object->flags & kObjectFlag40) {
PolyDefinitions *poly = &_polygons->entries[object->getPolygonIndex()]; Polygon poly = _polygons->get(object->getPolygonIndex());
isMasked = poly->contains(sum); isMasked = poly.contains(sum);
} }
// Adjust object flags // Adjust object flags
@ -2650,7 +2650,7 @@ void Scene::debugScreenScrolling() {
} }
// WALK REGION DEBUG // WALK REGION DEBUG
void Scene::debugShowWalkRegion(PolyDefinitions *poly) { void Scene::debugShowWalkRegion(Polygon *poly) {
Graphics::Surface surface; Graphics::Surface surface;
surface.create(poly->boundingRect.right - poly->boundingRect.left + 1, surface.create(poly->boundingRect.right - poly->boundingRect.left + 1,
poly->boundingRect.bottom - poly->boundingRect.top + 1, poly->boundingRect.bottom - poly->boundingRect.top + 1,
@ -2675,9 +2675,9 @@ void Scene::debugShowPolygons() {
if (!_polygons) if (!_polygons)
error("[Scene::debugShowPolygons] Polygons not initialized properly!"); error("[Scene::debugShowPolygons] Polygons not initialized properly!");
for (int32 p = 0; p < _polygons->numEntries; p++) { for (uint32 p = 0; p < _polygons->size(); p++) {
Graphics::Surface surface; Graphics::Surface surface;
PolyDefinitions poly = _polygons->entries[p]; Polygon poly = _polygons->get(p);
surface.create(poly.boundingRect.right - poly.boundingRect.left + 1, surface.create(poly.boundingRect.right - poly.boundingRect.left + 1,
poly.boundingRect.bottom - poly.boundingRect.top + 1, poly.boundingRect.bottom - poly.boundingRect.top + 1,
Graphics::PixelFormat::createFormatCLUT8()); Graphics::PixelFormat::createFormatCLUT8());

View file

@ -42,6 +42,7 @@ class Puzzle;
class Cursor; class Cursor;
class GraphicResource; class GraphicResource;
class Polygons; class Polygons;
class Polygon;
class ResourcePack; class ResourcePack;
class SceneTitle; class SceneTitle;
class Screen; class Screen;
@ -56,7 +57,6 @@ struct ActionArea;
struct AmbientSoundItem; struct AmbientSoundItem;
struct GraphicFrame; struct GraphicFrame;
struct ObjectItem; struct ObjectItem;
struct PolyDefinitions;
enum HitType { enum HitType {
kHitNone = -1, kHitNone = -1,
@ -467,7 +467,7 @@ private:
void debugShowPolygons(); void debugShowPolygons();
void debugShowSceneRects(); void debugShowSceneRects();
void debugScreenScrolling(); void debugScreenScrolling();
void debugShowWalkRegion(PolyDefinitions *poly); void debugShowWalkRegion(Polygon *poly);
friend class SceneTitle; friend class SceneTitle;
}; };