diff options
Diffstat (limited to 'engines/m4/rails.cpp')
-rw-r--r-- | engines/m4/rails.cpp | 358 |
1 files changed, 0 insertions, 358 deletions
diff --git a/engines/m4/rails.cpp b/engines/m4/rails.cpp deleted file mode 100644 index f51d81c8f4..0000000000 --- a/engines/m4/rails.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - TODO: - - rewrite functions (GetShortestPath etc.) -*/ - -#include "graphics/primitives.h" -#include "common/list.h" -#include "common/rect.h" -#include "common/util.h" - -#include "m4/rails.h" -#include "m4/m4.h" - -namespace M4 { - -#define TOP_EDGE 1 << 0 -#define LEFT_EDGE 1 << 1 -#define BOTTOM_EDGE 1 << 2 -#define RIGHT_EDGE 1 << 3 - - -Rails::Rails() { -} - - -Rails::~Rails() { - clearRails(); -} - - -void Rails::clearRails() { - uint32 i; - Common::List<NoWalkRect *>::iterator j; - RailNode *tempNode; - - for (i = 0; i < _nodes.size(); i++) { - tempNode = _nodes[i]; - _nodes.remove_at(i); - delete tempNode; - } - - _edges.clear(); - - for (j = _noWalkRects.begin(); j != _noWalkRects.end(); ++j) - delete (*j); - _noWalkRects.clear(); -} - -static void checkPoint(int x, int y, int color, void *data) { - IsWalkableData *isWalkableData = (IsWalkableData*)data; - if (!isWalkableData->result) - return; - else { - M4Surface *codes = isWalkableData->codes; - if (x >= 0 && x < codes->width() && y >= 0 && y < codes->height()) { - isWalkableData->result = !((*((uint8*)codes->getBasePtr(x, y))) & 0x10); - } else { - isWalkableData->result = false; - } - } -} - -bool Rails::isLineWalkable(int x0, int y0, int x1, int y1) { - IsWalkableData isWalkableData; - isWalkableData.codes = _walkCodes; - isWalkableData.result = true; - Graphics::drawLine(x0, y0, x1, y1, 0, &checkPoint, &isWalkableData); - return isWalkableData.result; -} - -uint8 Rails::getDepth(const Common::Point &pt) { - // TODO: Check based on sceneResources - const byte *b = _walkCodes->getBasePtr(pt.x, pt.y); - return *b & 0xf; -} - -// helper function -uint8 getEndCode(int32 x, int32 y, Common::Rect rect) { - uint8 endCode = 0; - endCode = (x < rect.left) ? LEFT_EDGE : endCode; - endCode = (x > rect.right) ? RIGHT_EDGE : endCode; - endCode = (y < rect.top) ? endCode | TOP_EDGE : endCode; - endCode = (y > rect.bottom) ? endCode | BOTTOM_EDGE : endCode; - return endCode; -} - -bool Rails::lineCrossesRect(int32 x1, int32 y1, int32 x2, int32 y2, Common::Rect rect) { - int32 mX, mY; - int32 pX1 = x1, pX2 = x2, pY1 = y1, pY2 = y2; - uint8 endCode1, endCode2, midCode; - - if (rect.left > rect.right || rect.top > rect.bottom) - return false; - - // Cohen-Sutherland line clipping algorithm - - endCode1 = getEndCode(pX1, pY1, rect); - endCode2 = getEndCode(pX2, pY2, rect); - - if (!endCode1 || !endCode2) // if both endcodes are zero - return true; // point is inside the rectangle, therefore the line intersects - - while (true) { - if (endCode1 & endCode2) // if both endcodes have a common bitset - return false; // line is completely off one edge - - // calculate midpoint - mX = (pX1 + pX2)>>1; - mY = (pY1 + pY2)>>1; - - // avoid round-off error: make sure that the midpoint isn't the same as one of the - // two endpoints - if (((mX == pX1) && (mY == pY1)) || ((mX == pX2) && (mY == pY2))) - return false; - - midCode = getEndCode(mX, mY, rect); - - if (!midCode) { - return true; - } else if (midCode & endCode1) { - // the midCode and an end point form a line segment completely off one edge, so - // remove that half of the line segment - pX1 = mX; - pY1 = mY; - endCode1 = midCode; - } else { - pX2 = mX; - pY2 = mY; - endCode2 = midCode; - } - } -} - - -bool Rails::linePassesThroughRect(int32 x1, int32 y1, int32 x2, int32 y2) { - if (_noWalkRects.empty()) - return false; - - bool intersected = false; - Common::List<NoWalkRect *>::iterator i; - - for (i = _noWalkRects.begin(); i != _noWalkRects.end(); ++i) { - intersected = lineCrossesRect(x1, y1, x2, y2, Common::Rect((*i)->x1, (*i)->y1, (*i)->x2, (*i)->y2)); - if (intersected) - break; - } - - return intersected; -} - -long SqrtF16(long n) { - uint32 r = 0, s; - uint32 v = (uint32)n; - - for (int i = 15; i >= 0; --i) { - s = r + (1L << i * 2); - r >>= 1; - if (s <= v) { - v -= s; - r |= (1L << i * 2); - } - } - - return (long)r; -} - -void Rails::createEdge(int32 node1, int32 node2) { - uint32 index; - int32 x1, y1, x2, y2; - bool valid; - long deltaX, deltaY, distance; - - if ((node1 < 0) || (node1 >= MAXRAILNODES) || (node2 < 0) || (node2 >= MAXRAILNODES)) - return; - - if (node1 == node2) - return; - - if (node2 < node1) - SWAP(node1, node2); // ensure node1 < node2 - - // Find the table entry i.e. tableWidth * node1 + node2 and then subtract - // n(n+1)/2, since only the upper triangle of the table is stored - index = (MAXRAILNODES-1) * node1 + node2 - 1 - (node1*(node1+1)>>1); - if (index > _edges.size() - 1) - _edges.resize(index + 1); - _edges.insert_at(index, 0); - valid = true; - - if (_nodes.size() <= (uint32)node1 || _nodes.size() <= (uint32)node2) - return; - - x1 = _nodes[node1]->x; - y1 = _nodes[node1]->y; - x2 = _nodes[node2]->x; - y2 = _nodes[node2]->y; - - // Make sure that the algorithm is symmetric - if (x2 < x1) { - SWAP(x1, x2); - SWAP(y1, y2); - } - - valid = isLineWalkable(_nodes[node1]->x, _nodes[node1]->y, - _nodes[node2]->x, _nodes[node2]->y); - debugCN(kDebugCore, "test code says: %d\n", valid); - - // Check if the line passes through a forbidden rectangle - if (valid) { - if (linePassesThroughRect(x1, y1, x2, y2)) { - valid = false; - } - } - - if (valid) { - deltaX = ABS(((long)(x2 - x1)) << 16); - deltaY = ABS(((long)(y2 - y1)) << 16); - if ((deltaX >= 0x800000) || (deltaY >= 0x800000)) { - deltaX >>= 16; - deltaY >>= 16; - distance = (long)(SqrtF16(deltaX * deltaX + deltaY * deltaY) << 16); - } else { - distance = SqrtF16(FixedMul(deltaX, deltaX) + FixedMul(deltaY, deltaY)) << 8; - } - _edges.insert_at(index, distance >> 16); - } - - debugCN(kDebugCore, "node1 = %d, node2 = %d, valid = %d\n", node1, node2, valid); - -} - - -void Rails::restoreNodeEdges(int32 nodeID) { - for (int32 i = 0; i < MAXRAILNODES; i++) { - createEdge(i, nodeID); - } -} - -void Rails::restoreEdgeList() { - int32 j; - for (int32 i = 0; i < MAXRAILNODES; i++) { - for (j = i + 1; j < MAXRAILNODES; j++) { - createEdge(i, j); - } - } -} - -int32 Rails::addRailNode(int32 x, int32 y, bool restoreEdges) { - uint32 i = _nodes.size(); - if (i >= MAXRAILNODES) - return -1; - - RailNode *newNode = new RailNode(); - newNode->nodeID = i; - newNode->x = x; - newNode->y = y; - _nodes.insert_at(i, newNode); - if (restoreEdges) { - for (uint32 j=0; j<_nodes.size(); j++) - createEdge(i, j); - } - return i; -} - -bool Rails::removeRailNode(int32 nodeID, bool restoreEdges) { - if (nodeID < 0 || nodeID >= MAXRAILNODES) - return false; - - if (_nodes.empty() || _edges.empty()) - return false; - - RailNode *tempNode = _nodes[nodeID]; - _nodes.remove_at(nodeID); - delete tempNode; - - if (restoreEdges) { - restoreNodeEdges(nodeID); - } - return true; -} - -int16 Rails::getEdgeLength(int32 node1, int32 node2) { - int32 index; - if (_edges.empty() || node1 == node2) - return 0; - if (node2 < node1) - SWAP(node1, node2); - // Find the table entry i.e. tableWidth * node1 + node2 and then subtract - // n(n+1)/2, since only the upper triangle of the table is stored - index = (MAXRAILNODES-1)*node1 + node2 - 1 - (node1*(node1+1)>>1); - return _edges[index]; -} - -void Rails::disposePath(RailNode *pathStart) { - RailNode *tempNode = pathStart; - while (tempNode) { - pathStart = pathStart->shortPath; - delete tempNode; - tempNode = pathStart; - } -} - -/* -static RailNode* duplicatePath(RailNode *pathStart) { - RailNode *newNode = NULL; - RailNode *firstNode = NULL; - RailNode *prevNode = NULL; - // A valid path is assumed - RailNode *pathNode = pathStart; - - while (pathNode) { - newNode = new RailNode(); - newNode->x = pathNode->x; - newNode->y = pathNode->y; - newNode->shortPath = NULL; - - if (!firstNode) - firstNode = newNode; - else - prevNode->shortPath = newNode; - - prevNode = newNode; - // Get the next node - pathNode = pathNode->shortPath; - } - - return firstNode; -} -*/ - -bool Rails::getShortestPath(int32 origID, int32 destID, RailNode **shortPath) { - // TODO - return true; -} - -} // End of namespace M4 |