diff options
-rw-r--r-- | level.c | 291 | ||||
-rw-r--r-- | player.c | 18 | ||||
-rw-r--r-- | zoom/level.h | 27 | ||||
-rw-r--r-- | zoom/types.h | 11 |
4 files changed, 211 insertions, 136 deletions
@@ -23,19 +23,130 @@ static int SortTextures(const void *t1, const void *t2) { return strcmp(((TEXTURE*)t1)->name, ((TEXTURE*)t2)->name); } +static int SortRooms(const void *r1, const void *r2) { + return strcmp(((ROOM*)r1)->id, ((ROOM*)r2)->id); +} + + +static void LoadTriangles(xmlNodePtr node, LEVEL *level, WALL* walls, int nWalls) { + int i = 0, j; + xmlNodePtr node2; + xmlChar *data; + TEXTURE tex, *texp; + VECTOR v; + + + for(; node = node->next; node != NULL) { + if(node->type != XML_ELEMENT_NODE || xmlStrcmp(node->name, "triangle")) continue; + + walls[i].visible = 1; + data = xmlGetProp(node, "visible"); + if(data) { + if(!xmlStrcmp(data, "false")) walls[i].visible = 0; + xmlFree(data); + } + + data = xmlGetProp(node, "texture"); + if(data) { + tex.name = data; + texp = bsearch(&tex, level->textures, level->nTextures, sizeof(TEXTURE), SortTextures); + + if(texp) walls[i].texture = texp->id; + + xmlFree(data); + } + + j = -1; + for(node2 = node->children; node2 = node2->next; node2 != NULL) { + if(node2->type != XML_ELEMENT_NODE) continue; + + if(!xmlStrcmp(node2->name, "vertex")) { + if(++j > 2) break; + + data = xmlGetProp(node2, "x"); + if(data) { + walls[i].vertices[j].x = atof(data); + xmlFree(data); + } + + data = xmlGetProp(node2, "y"); + if(data) { + walls[i].vertices[j].y = atof(data); + xmlFree(data); + } + + data = xmlGetProp(node2, "z"); + if(data) { + walls[i].vertices[j].z = atof(data); + xmlFree(data); + } + } + else if(!xmlStrcmp(node2->name, "normal")) { + if(j < 0) continue; + + data = xmlGetProp(node2, "x"); + if(data) { + walls[i].normals[j].x = atof(data); + xmlFree(data); + } + + data = xmlGetProp(node2, "y"); + if(data) { + walls[i].normals[j].y = atof(data); + xmlFree(data); + } + + data = xmlGetProp(node2, "z"); + if(data) { + walls[i].normals[j].z = atof(data); + xmlFree(data); + } + } + else if(!xmlStrcmp(node2->name, "texcoords")) { + if(j < 0) continue; + + data = xmlGetProp(node2, "s"); + if(data) { + walls[i].texcoords[j].s = atof(data); + xmlFree(data); + } + + data = xmlGetProp(node2, "t"); + if(data) { + walls[i].texcoords[j].t = atof(data); + xmlFree(data); + } + } + } + + v = VectorCross( + VectorSub(walls[i].vertices[1], walls[i].vertices[0]), + VectorSub(walls[i].vertices[2], walls[i].vertices[0]) + ); + if(VectorLengthSq(v) > 0.0) { + walls[i].normal = VectorNormalize(v); + + for(j = 0; j < 3; j++) { + if(VectorLengthSq(walls[i].normals[j]) == 0.0) + walls[i].normals[j] = walls[i].normal; + } + } + + i++; + } +} + LEVEL *LoadLevel(char *filename) { LEVEL *level; xmlDocPtr doc; xmlDtdPtr dtd; xmlValidCtxtPtr validCtxt; - xmlNodePtr root, node, node2, node3, rooms = NULL; + xmlNodePtr root, node, node2, node3, rooms = NULL, gates = NULL; xmlChar *data; char *name; - int i, j, k; - VECTOR v; - TEXTURE tex; - TEXTURE *texp; + int i, j; + ROOM room, *roomp; name = malloc(strlen(filename)+8); @@ -81,7 +192,9 @@ LEVEL *LoadLevel(char *filename) { if(!root || xmlStrcmp(root->name, "level")) { xmlFreeDoc(doc); xmlCleanupParser(); - return NULL; + return NULL;puts("Loaded."); + + } level = calloc(1, sizeof(LEVEL)); @@ -133,6 +246,15 @@ LEVEL *LoadLevel(char *filename) { if(node2->type == XML_ELEMENT_NODE && !xmlStrcmp(node2->name, "room")) level->nRooms++; } } + else if(!xmlStrcmp(node->name, "gates")) { + if(gates != NULL) continue; + + gates = node; + + for(node2 = node->children; node2 = node2->next; node2 != NULL) { + if(node2->type == XML_ELEMENT_NODE && !xmlStrcmp(node2->name, "gate")) level->nGates++; + } + } else if(!xmlStrcmp(node->name, "textures")) { if(level->textures != NULL) continue; @@ -173,120 +295,60 @@ LEVEL *LoadLevel(char *filename) { for(node = rooms->children; node = node->next; node != NULL) { if(node->type != XML_ELEMENT_NODE || xmlStrcmp(node->name, "room")) continue; + data = xmlGetProp(node, "id"); + if(data) { + level->rooms[i].id = strdup(data); + + xmlFree(data); + } + for(node2 = node->children; node2 = node2->next; node2 != NULL) { if(node2->type == XML_ELEMENT_NODE && !xmlStrcmp(node2->name, "triangle")) level->rooms[i].nWalls++; } level->rooms[i].walls = calloc(level->rooms[i].nWalls, sizeof(WALL)); - j = 0; - for(node2 = node->children; node2 = node2->next; node2 != NULL) { - if(node2->type != XML_ELEMENT_NODE || xmlStrcmp(node2->name, "triangle")) continue; - - data = xmlGetProp(node2, "type"); - if(data) { - if(!xmlStrcmp(data, "wall")) level->rooms[i].walls[j].type = TRIANGLE_WALL; - else if(!xmlStrcmp(data, "floor")) level->rooms[i].walls[j].type = TRIANGLE_FLOOR; - else level->rooms[i].walls[j].type = TRIANGLE_UNKNOWN; - xmlFree(data); - } - - level->rooms[i].walls[j].visible = 1; - data = xmlGetProp(node2, "visible"); - if(data) { - if(!xmlStrcmp(data, "false")) level->rooms[i].walls[j].visible = 0; - xmlFree(data); - } + LoadTriangles(node->children, level, level->rooms[i].walls, level->rooms[i].nWalls); + + i++; + } + + qsort(level->rooms, level->nRooms, sizeof(ROOM), SortRooms); + + level->gates = calloc(level->nGates, sizeof(GATE)); + + i = 0; + for(node = gates->children; node = node->next; node != NULL) { + if(node->type != XML_ELEMENT_NODE || xmlStrcmp(node->name, "gate")) continue; + + data = xmlGetProp(node2, "room1"); + if(data) { + room.id = data; + roomp = bsearch(&room, level->rooms, level->nRooms, sizeof(ROOM), SortRooms); - data = xmlGetProp(node2, "texture"); - if(data) { - tex.name = data; - texp = bsearch(&tex, level->textures, level->nTextures, sizeof(TEXTURE), SortTextures); - - if(texp) level->rooms[i].walls[j].texture = texp->id; - - xmlFree(data); - } + if(roomp) level->gates[i].room1 = roomp; - k = -1; - for(node3 = node2->children; node3 = node3->next; node3 != NULL) { - if(node3->type != XML_ELEMENT_NODE) continue; - - if(!xmlStrcmp(node3->name, "vertex")) { - if(++k > 2) break; - - data = xmlGetProp(node3, "x"); - if(data) { - level->rooms[i].walls[j].vertices[k].x = atof(data); - xmlFree(data); - } - - data = xmlGetProp(node3, "y"); - if(data) { - level->rooms[i].walls[j].vertices[k].y = atof(data); - xmlFree(data); - } - - data = xmlGetProp(node3, "z"); - if(data) { - level->rooms[i].walls[j].vertices[k].z = atof(data); - xmlFree(data); - } - } - else if(!xmlStrcmp(node3->name, "normal")) { - if(k < 0) continue; - - data = xmlGetProp(node3, "x"); - if(data) { - level->rooms[i].walls[j].normals[k].x = atof(data); - xmlFree(data); - } - - data = xmlGetProp(node3, "y"); - if(data) { - level->rooms[i].walls[j].normals[k].y = atof(data); - xmlFree(data); - } - - data = xmlGetProp(node3, "z"); - if(data) { - level->rooms[i].walls[j].normals[k].z = atof(data); - xmlFree(data); - } - } - else if(!xmlStrcmp(node3->name, "texcoords")) { - if(k < 0) continue; - - data = xmlGetProp(node3, "s"); - if(data) { - level->rooms[i].walls[j].texcoords[k].s = atof(data); - xmlFree(data); - } - - data = xmlGetProp(node3, "t"); - if(data) { - level->rooms[i].walls[j].texcoords[k].t = atof(data); - xmlFree(data); - } - } - } + xmlFree(data); + } + + data = xmlGetProp(node2, "room2"); + if(data) { + room.id = data; + roomp = bsearch(&room, level->rooms, level->nRooms, sizeof(ROOM), SortRooms); - v = VectorCross( - VectorSub(level->rooms[i].walls[j].vertices[1], level->rooms[i].walls[j].vertices[0]), - VectorSub(level->rooms[i].walls[j].vertices[2], level->rooms[i].walls[j].vertices[0]) - ); - if(VectorLengthSq(v) > 0.0) { - level->rooms[i].walls[j].normal = VectorNormalize(v); - - for(k = 0; k < 3; k++) { - if(VectorLengthSq(level->rooms[i].walls[j].normals[k]) == 0.0) - level->rooms[i].walls[j].normals[k] = level->rooms[i].walls[j].normal; - } - } + if(roomp) level->gates[i].room2 = roomp; - j++; + xmlFree(data); + } + + for(node2 = node->children; node2 = node2->next; node2 != NULL) { + if(node2->type == XML_ELEMENT_NODE && !xmlStrcmp(node2->name, "triangle")) level->gates[i].nWalls++; } + level->gates[i].walls = calloc(level->gates[i].nWalls, sizeof(WALL)); + + LoadTriangles(node->children, level, level->gates[i].walls, level->gates[i].nWalls); + i++; } @@ -573,15 +635,24 @@ void FreeLevel(LEVEL *level) { if(level->nRooms) { for(i = 0; i < level->nRooms; i++) { if(level->rooms[i].nWalls) free(level->rooms[i].walls); - if(level->rooms[i].nThings) free(level->rooms[i].things); + /*if(level->rooms[i].nThings) free(level->rooms[i].things); if(level->rooms[i].nGates) { free(level->rooms[i].gates); free(level->rooms[i].gateinfo); - } + }*/ + + free(level->rooms[i].id); } free(level->rooms); } + if(level->nGates) { + for(i = 0; i < level->nGates; i++) { + if(level->gates[i].nWalls) free(level->gates[i].walls); + } + free(level->gates); + } + if(level->nTextures) { for(i = 0; i < level->nTextures; i++) free(level->textures[i].name); @@ -114,7 +114,7 @@ void DoInput(int delta) { move.x = -c; move.z = -s; } - if(input & INPUT_OPEN) { + /*if(input & INPUT_OPEN) { for(i = 0; i < level->rooms[room].nGates; i++) { if(level->rooms[room].gateinfo[i].state != STATE_CLOSED) continue; if(CollisionSphereTriangle(player.pos, 1.0, level->rooms[room].gates[i].walls[0].triangle) || @@ -123,7 +123,7 @@ void DoInput(int delta) { level->rooms[room].gateinfo[i].timer = 1000; } } - } + }*/ } pos = VectorAdd(player.pos, VectorMul(move, delta/150.0)); @@ -162,21 +162,21 @@ void DoInput(int delta) { }*/ falling = 1; for(i = 0; i < level->rooms[room].nWalls; i++) { - if(level->rooms[room].walls[i].type == TRIANGLE_WALL && + if(/*level->rooms[room].walls[i].type == TRIANGLE_WALL &&*/ CollisionMovingSphereTriangle(VectorSub(pos, VectorMul(move, delta/150.0)), 0.3, move, delta/150.0, level->rooms[room].walls[i].triangle)) { pos = player.pos; - if(player.room != room) { + /*if(player.room != room) { level->rooms[room].gateinfo[g].state = STATE_CLOSED; g = level->rooms[room].gates[g].gate; room = player.room; level->rooms[room].gateinfo[g].state = STATE_OPENED; - } + }*/ s = player.rotysin; c = player.rotycos; falling = 0; break; } - else if(level->rooms[room].walls[i].type == TRIANGLE_FLOOR) { + //else if(level->rooms[room].walls[i].type == TRIANGLE_FLOOR) { pos.y -= 1.81; if(CollisionPointTriangle(pos, level->rooms[room].walls[i].triangle)) { falling = 0; @@ -184,14 +184,14 @@ void DoInput(int delta) { if(wasfalling && CollisionRayTriangle(pos, v, level->rooms[room].walls[i].triangle, &f)) pos.y -= f - 1.8; } else pos.y += 1.81; - } + //} } player.pos = pos; player.room = room; player.rotysin = s; player.rotycos = c; - for(i = 0; i < level->rooms[player.room].nThings; i++) { + /*for(i = 0; i < level->rooms[player.room].nThings; i++) { pos = VectorSub(level->rooms[player.room].things[i].pos, player.pos); pos.y += 0.9; switch(level->rooms[player.room].things[i].type) { @@ -214,7 +214,7 @@ void DoInput(int delta) { else level->rooms[player.room].gateinfo[i].state = STATE_CLOSED; } else level->rooms[player.room].gateinfo[i].timer -= delta; - } + }*/ static int lightpos = 0; diff --git a/zoom/level.h b/zoom/level.h index 49de407..a389f71 100644 --- a/zoom/level.h +++ b/zoom/level.h @@ -5,21 +5,32 @@ #include <zoom/types.h>
#include <zoom/render.h>
-typedef struct _GATEINFO {
+/*typedef struct _GATEINFO {
unsigned short state;
unsigned short timer;
-} GATEINFO;
+} GATEINFO;*/
typedef struct _ROOM {
+ char *id;
int nWalls;
- int nThings;
- int nGates;
+ //int nThings;
+ //int nGates;
WALL *walls;
- THING *things;
- GATE *gates;
- GATEINFO *gateinfo;
+ //THING *things;
+ //GATE *gates;
+ //GATEINFO *gateinfo;
} ROOM;
+typedef struct _GATE {
+ //unsigned char type;
+ //unsigned char open;
+ int nWalls;
+ WALL *walls;
+ //VERTEX point;
+ ROOM *room1, *room2;
+ int gate;
+} GATE;
+
typedef struct _LEVELINFO {
char *name;
char *desc;
@@ -35,6 +46,8 @@ typedef struct _LEVEL { LEVELINFO *info;
int nRooms;
ROOM *rooms;
+ int nGates;
+ GATE *gates;
int nTextures;
TEXTURE *textures;
} LEVEL;
diff --git a/zoom/types.h b/zoom/types.h index 4c86190..3feb5a3 100644 --- a/zoom/types.h +++ b/zoom/types.h @@ -23,7 +23,7 @@ #pragma pack(push, 2)
typedef struct WALL {
- unsigned char type;
+ //unsigned char type;
unsigned char visible;
union {
TRIANGLE triangle;
@@ -42,15 +42,6 @@ typedef struct _THING { unsigned char visible;
VERTEX pos;
} THING;
-
-typedef struct _GATE {
- unsigned char type;
- unsigned char open;
- WALL walls[2];
- VERTEX point;
- int room;
- int gate;
-} GATE;
#pragma pack(pop)
#endif
|