diff options
author | yinsimei | 2017-05-26 05:24:38 +0200 |
---|---|---|
committer | Eugene Sandulenko | 2017-07-13 18:27:45 +0200 |
commit | 219044abf9841461043d6e2acf0d5a48a7c7648b (patch) | |
tree | e9d16f9de2317e3596da5a71447e0c823ba3861d /engines/sludge/floor.cpp | |
parent | 94439e2ce311734bfe7bb5700a6584b7550ea8f9 (diff) | |
download | scummvm-rg350-219044abf9841461043d6e2acf0d5a48a7c7648b.tar.gz scummvm-rg350-219044abf9841461043d6e2acf0d5a48a7c7648b.tar.bz2 scummvm-rg350-219044abf9841461043d6e2acf0d5a48a7c7648b.zip |
SLUDGE: Add sludge files and make it compile
Diffstat (limited to 'engines/sludge/floor.cpp')
-rw-r--r-- | engines/sludge/floor.cpp | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/engines/sludge/floor.cpp b/engines/sludge/floor.cpp new file mode 100644 index 0000000000..826632a76a --- /dev/null +++ b/engines/sludge/floor.cpp @@ -0,0 +1,290 @@ +/* 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. + * + */ +#include "allfiles.h" +#include "newfatal.h" +#include "fileset.h" +#include "moreio.h" +#include "floor.h" +#include "line.h" + +flor *currentFloor = NULL; + +bool pointInFloorPolygon(floorPolygon &floorPoly, int x, int y) { + int i = 0, j, c = 0; + float xp_i, yp_i; + float xp_j, yp_j; + + for (j = floorPoly.numVertices - 1; i < floorPoly.numVertices; + j = i ++) { + + xp_i = currentFloor -> vertex[floorPoly.vertexID[i]].x; + yp_i = currentFloor -> vertex[floorPoly.vertexID[i]].y; + xp_j = currentFloor -> vertex[floorPoly.vertexID[j]].x; + yp_j = currentFloor -> vertex[floorPoly.vertexID[j]].y; + + if ((((yp_i <= y) && (y < yp_j)) || + ((yp_j <= y) && (y < yp_i))) && + (x < (xp_j - xp_i) * (y - yp_i) / (yp_j - yp_i) + xp_i)) { + + c = !c; + } + } + return c; +} + +bool getMatchingCorners(floorPolygon &a, floorPolygon &b, int &cornerA, int &cornerB) { + int sharedVertices = 0; + int i, j; + + for (i = 0; i < a.numVertices; i ++) { + for (j = 0; j < b.numVertices; j ++) { + if (a.vertexID[i] == b.vertexID[j]) { + if (sharedVertices ++) { + cornerB = a.vertexID[i]; + return true; + } else { + cornerA = a.vertexID[i]; + } + } + } + } + + return false; +} + +bool polysShareSide(floorPolygon &a, floorPolygon &b) { + int sharedVertices = 0; + int i, j; + + for (i = 0; i < a.numVertices; i ++) { + for (j = 0; j < b.numVertices; j ++) { + if (a.vertexID[i] == b.vertexID[j]) { + if (sharedVertices ++) return true; + } + } + } + + return false; +} + +void noFloor() { + currentFloor -> numPolygons = 0; + currentFloor -> polygon = NULL; + currentFloor -> vertex = NULL; + currentFloor -> matrix = NULL; +} + +bool initFloor() { + currentFloor = new flor; + if (! checkNew(currentFloor)) return false; + noFloor(); + return true; +} + +void killFloor() { + for (int i = 0; i < currentFloor -> numPolygons; i ++) { + delete currentFloor -> polygon[i].vertexID; + delete currentFloor -> matrix[i]; + } + delete currentFloor -> polygon; + currentFloor -> polygon = NULL; + delete currentFloor -> vertex; + currentFloor -> vertex = NULL; + delete currentFloor -> matrix; + currentFloor -> matrix = NULL; +} + +void setFloorNull() { + killFloor(); + noFloor(); +} + +bool setFloor(int fileNum) { + + int i, j; + + killFloor(); + + setResourceForFatal(fileNum); +#if ALLOW_FILE + if (! openFileFromNum(fileNum)) return false; + + // Find out how many polygons there are and reserve memory + + currentFloor -> originalNum = fileNum; + currentFloor -> numPolygons = fgetc(bigDataFile); + currentFloor -> polygon = new floorPolygon[currentFloor -> numPolygons]; + if (! checkNew(currentFloor -> polygon)) return false; + + // Read in each polygon + + for (i = 0; i < currentFloor -> numPolygons; i ++) { + + // Find out how many vertex IDs there are and reserve memory + + currentFloor -> polygon[i].numVertices = fgetc(bigDataFile); + currentFloor -> polygon[i].vertexID = new int[currentFloor -> polygon[i].numVertices]; + if (! checkNew(currentFloor -> polygon[i].vertexID)) return false; + + // Read in each vertex ID + + for (j = 0; j < currentFloor -> polygon[i].numVertices; j ++) { + currentFloor -> polygon[i].vertexID[j] = get2bytes(bigDataFile); + } + } + + // Find out how many vertices there are and reserve memory + + i = get2bytes(bigDataFile); + currentFloor -> vertex = new POINT[i]; + if (! checkNew(currentFloor -> vertex)) return false; + + for (j = 0; j < i; j ++) { + + currentFloor -> vertex[j].x = get2bytes(bigDataFile); + currentFloor -> vertex[j].y = get2bytes(bigDataFile); + } + + finishAccess(); +#endif + // Now build the movement martix + + currentFloor -> matrix = new int *[currentFloor -> numPolygons]; + int * * distanceMatrix = new int *[currentFloor -> numPolygons]; + + if (! checkNew(currentFloor -> matrix)) return false; + + for (i = 0; i < currentFloor -> numPolygons; i ++) { + currentFloor -> matrix[i] = new int [currentFloor -> numPolygons]; + distanceMatrix [i] = new int [currentFloor -> numPolygons]; + if (! checkNew(currentFloor -> matrix[i])) return false; + for (j = 0; j < currentFloor -> numPolygons; j ++) { + currentFloor -> matrix[i][j] = -1; + distanceMatrix [i][j] = 10000; + } + } + + for (i = 0; i < currentFloor -> numPolygons; i ++) { + for (j = 0; j < currentFloor -> numPolygons; j ++) { + if (i != j) { + if (polysShareSide(currentFloor -> polygon[i], currentFloor -> polygon[j])) { + currentFloor -> matrix[i][j] = j; + distanceMatrix [i][j] = 1; + } + } else { + currentFloor -> matrix[i][j] = -2; + distanceMatrix [i][j] = 0; + } + } + } + + bool madeChange; + int lookForDistance = 0; + + do { + lookForDistance ++; +// debugMatrix (); + madeChange = false; + for (i = 0; i < currentFloor -> numPolygons; i ++) { + for (j = 0; j < currentFloor -> numPolygons; j ++) { + if (currentFloor -> matrix[i][j] == -1) { + + // OK, so we don't know how to get from i to j... + for (int d = 0; d < currentFloor -> numPolygons; d ++) { + if (d != i && d != j) { + if (currentFloor -> matrix[i][d] == d && + currentFloor -> matrix[d][j] >= 0 && + distanceMatrix [d][j] <= lookForDistance) { + + currentFloor -> matrix[i][j] = d; + distanceMatrix [i][j] = lookForDistance + 1; + madeChange = true; + } + } + } + } + } + } + } while (madeChange); + + for (i = 0; i < currentFloor -> numPolygons; i ++) { + delete distanceMatrix [i]; + } + + delete distanceMatrix; + distanceMatrix = NULL; + + setResourceForFatal(-1); + + return true; +} + +void drawFloor() { + int i, j, nV; + for (i = 0; i < currentFloor -> numPolygons; i ++) { +// drawLine (i, 0, i + 5, 100); + nV = currentFloor -> polygon[i].numVertices; + if (nV > 1) { + for (j = 1; j < nV; j ++) { + drawLine(currentFloor -> vertex[currentFloor -> polygon[i].vertexID[j - 1]].x, + currentFloor -> vertex[currentFloor -> polygon[i].vertexID[j - 1]].y, + currentFloor -> vertex[currentFloor -> polygon[i].vertexID[j]].x, + currentFloor -> vertex[currentFloor -> polygon[i].vertexID[j]].y); + } + drawLine(currentFloor -> vertex[currentFloor -> polygon[i].vertexID[0]].x, + currentFloor -> vertex[currentFloor -> polygon[i].vertexID[0]].y, + currentFloor -> vertex[currentFloor -> polygon[i].vertexID[nV - 1]].x, + currentFloor -> vertex[currentFloor -> polygon[i].vertexID[nV - 1]].y); + } + } +} + +int inFloor(int x, int y) { + int i, r = -1; + + for (i = 0; i < currentFloor -> numPolygons; i ++) + if (pointInFloorPolygon(currentFloor -> polygon[i], x, y)) + r = i; + + return r; +} + +bool closestPointOnLine(int &closestX, int &closestY, int x1, int y1, int x2, int y2, int xP, int yP) { + int xDiff = x2 - x1; + int yDiff = y2 - y1; + + double m = xDiff * (xP - x1) + yDiff * (yP - y1); + m /= (xDiff * xDiff) + (yDiff * yDiff); + + if (m < 0) { + closestX = x1; + closestY = y1; + } else if (m > 1) { + closestX = x2; + closestY = y2; + } else { + closestX = x1 + m * xDiff; + closestY = y1 + m * yDiff; + return true; + } + return false; +} |