summaryrefslogtreecommitdiffstats
path: root/edit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'edit.cpp')
-rw-r--r--edit.cpp170
1 files changed, 170 insertions, 0 deletions
diff --git a/edit.cpp b/edit.cpp
new file mode 100644
index 0000000..c54f308
--- /dev/null
+++ b/edit.cpp
@@ -0,0 +1,170 @@
+#include "edit.h"
+#include "level.h"
+#include "geometry.h"
+#include <stdlib.h>
+
+
+static int editMode = EDIT_MODE_VIEW;
+
+static ROOM *activeRoom = NULL;
+static ROOM *hoveredRoom = NULL;
+
+static VERTEX hoveredVertex;
+static int hasHoveredVertex = 0;
+
+int getEditMode() {
+ return editMode;
+}
+
+ROOM *getActiveRoom() {
+ return activeRoom;
+}
+
+void setActiveRoom(ROOM *room) {
+ activeRoom = room;
+
+ if(room == NULL) {
+ editMode = EDIT_MODE_VIEW;
+ }
+ else if(editMode == EDIT_MODE_VIEW) {
+ editMode = EDIT_MODE_SELECTED;
+ }
+}
+
+VERTEX *getHoveredVertex() {
+ if(hasHoveredVertex) return &hoveredVertex;
+ else return NULL;
+}
+
+void setHoveredVertex(VERTEX *v) {
+ int i;
+ LEVEL *l;
+
+ if(v) {
+ hasHoveredVertex = 1;
+ hoveredVertex = *v;
+
+ l = getLevel();
+ hoveredRoom = NULL;
+
+ for(i = 0; i < l->nRooms; i++) {
+ if(vertexInPolygon(v, &l->rooms[i].polygon)) {
+ hoveredRoom = &l->rooms[i];
+ break;
+ }
+ }
+ }
+ else {
+ hasHoveredVertex = 0;
+ hoveredRoom = NULL;
+ }
+}
+
+void startAddMode() {
+ activeRoom = (ROOM*)calloc(1, sizeof(ROOM));
+ activeRoom->polygon.nVertices = 0;
+ activeRoom->polygon.vertices = NULL;
+ activeRoom->name = (char*)calloc(1, sizeof(unsigned char));
+
+ editMode = EDIT_MODE_ADD;
+}
+
+void endAddMode() {
+ editMode = activeRoom ? EDIT_MODE_SELECTED : EDIT_MODE_VIEW;
+}
+
+ROOM *getHoveredRoom() {
+ return hoveredRoom;
+}
+
+static int isLineOk(LINE *l) {
+ LEVEL *lvl = getLevel();
+ LINE l2;
+ int i;
+
+
+ if(activeRoom) {
+ for(i = 0; i+2 < activeRoom->polygon.nVertices; i++) {
+ l2.v1 = activeRoom->polygon.vertices[i];
+ l2.v2 = activeRoom->polygon.vertices[i+1];
+
+ if(lineIntersection(l, &l2, NULL) == INTERSECTION_SEGMENT_SEGMENT) return 0;
+ }
+
+ if(activeRoom->polygon.nVertices > 1) {
+ l2.v1 = activeRoom->polygon.vertices[activeRoom->polygon.nVertices-2];
+ l2.v2 = activeRoom->polygon.vertices[activeRoom->polygon.nVertices-1];
+ if(vertexOnLine(&l->v2, &l2)) return 0;
+ }
+ }
+
+ for(i = 0; i < lvl->nRooms; i++) {
+ if(linePolygonIntersection(l, &lvl->rooms[i].polygon))
+ return 0;
+ }
+
+ return 1;
+}
+
+int isVertexOk(VERTEX *v) {
+ LEVEL *lvl = getLevel();
+ LINE l;
+ int i;
+
+ for(i = 0; i < lvl->nRooms; i++) {
+ if(vertexInPolygon(v, &lvl->rooms[i].polygon)) return 0;
+ }
+
+ if(!(getActiveRoom() && getActiveRoom()->polygon.nVertices))
+ return 1;
+
+ l.v1 = getActiveRoom()->polygon.vertices[getActiveRoom()->polygon.nVertices-1];
+ l.v2 = *v;
+
+ return isLineOk(&l);
+}
+
+
+
+int isPolygonOk(POLYGON *polygon) {
+ LEVEL *lvl = getLevel();
+ LINE l, l2;
+ int i, j;
+
+ if(!polygon->nVertices) return 0;
+
+ for(i = 0; i < lvl->nRooms; i++) {
+ if(!lvl->rooms[i].polygon.nVertices) continue;
+
+ if(vertexInPolygon(&polygon->vertices[0], &lvl->rooms[i].polygon))
+ return 0;
+
+ if(vertexInPolygon(&lvl->rooms[i].polygon.vertices[0], polygon))
+ return 0;
+ }
+
+ if(polygon->nVertices == 1)
+ return 1;
+
+ for(i = 0; i < polygon->nVertices; i++) {
+ l.v1 = polygon->vertices[i];
+ l.v2 = polygon->vertices[(i+1)%polygon->nVertices];
+
+ for(j = 0; j < lvl->nRooms; j++) {
+ if(linePolygonIntersection(&l, &lvl->rooms[j].polygon))
+ return 0;
+ }
+
+ for(j = i+2; j < polygon->nVertices; j++) {
+ if(i == 0 && j == polygon->nVertices-1) continue;
+
+ l2.v1 = polygon->vertices[j];
+ l2.v2 = polygon->vertices[(j+1)%polygon->nVertices];
+
+ if(lineIntersection(&l, &l2, NULL) == INTERSECTION_SEGMENT_SEGMENT)
+ return 0;
+ }
+ }
+
+ return 1;
+}