libzoom: Added gates to level loader;

zoom: Added gate to level; some Makefile.am changes
This commit is contained in:
neoraider 2007-06-12 17:19:01 +00:00
parent a4339f0570
commit f5c8fc72ca
4 changed files with 213 additions and 138 deletions

285
level.c
View file

@ -23,19 +23,130 @@ static int SortTextures(const void *t1, const void *t2) {
return strcmp(((TEXTURE*)t1)->name, ((TEXTURE*)t2)->name); 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 *LoadLevel(char *filename) {
LEVEL *level; LEVEL *level;
xmlDocPtr doc; xmlDocPtr doc;
xmlDtdPtr dtd; xmlDtdPtr dtd;
xmlValidCtxtPtr validCtxt; xmlValidCtxtPtr validCtxt;
xmlNodePtr root, node, node2, node3, rooms = NULL; xmlNodePtr root, node, node2, node3, rooms = NULL, gates = NULL;
xmlChar *data; xmlChar *data;
char *name; char *name;
int i, j, k; int i, j;
VECTOR v; ROOM room, *roomp;
TEXTURE tex;
TEXTURE *texp;
name = malloc(strlen(filename)+8); name = malloc(strlen(filename)+8);
@ -81,7 +192,9 @@ LEVEL *LoadLevel(char *filename) {
if(!root || xmlStrcmp(root->name, "level")) { if(!root || xmlStrcmp(root->name, "level")) {
xmlFreeDoc(doc); xmlFreeDoc(doc);
xmlCleanupParser(); xmlCleanupParser();
return NULL; return NULL;puts("Loaded.");
} }
level = calloc(1, sizeof(LEVEL)); 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++; 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")) { else if(!xmlStrcmp(node->name, "textures")) {
if(level->textures != NULL) continue; if(level->textures != NULL) continue;
@ -173,120 +295,60 @@ LEVEL *LoadLevel(char *filename) {
for(node = rooms->children; node = node->next; node != NULL) { for(node = rooms->children; node = node->next; node != NULL) {
if(node->type != XML_ELEMENT_NODE || xmlStrcmp(node->name, "room")) continue; 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) { for(node2 = node->children; node2 = node2->next; node2 != NULL) {
if(node2->type == XML_ELEMENT_NODE && !xmlStrcmp(node2->name, "triangle")) level->rooms[i].nWalls++; 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)); level->rooms[i].walls = calloc(level->rooms[i].nWalls, sizeof(WALL));
j = 0; LoadTriangles(node->children, level, level->rooms[i].walls, level->rooms[i].nWalls);
for(node2 = node->children; node2 = node2->next; node2 != NULL) {
if(node2->type != XML_ELEMENT_NODE || xmlStrcmp(node2->name, "triangle")) continue;
data = xmlGetProp(node2, "type"); i++;
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; qsort(level->rooms, level->nRooms, sizeof(ROOM), SortRooms);
data = xmlGetProp(node2, "visible");
if(data) {
if(!xmlStrcmp(data, "false")) level->rooms[i].walls[j].visible = 0;
xmlFree(data);
}
data = xmlGetProp(node2, "texture"); level->gates = calloc(level->nGates, sizeof(GATE));
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; i = 0;
for(node = gates->children; node = node->next; node != NULL) {
if(node->type != XML_ELEMENT_NODE || xmlStrcmp(node->name, "gate")) continue;
xmlFree(data); data = xmlGetProp(node2, "room1");
} if(data) {
room.id = data;
roomp = bsearch(&room, level->rooms, level->nRooms, sizeof(ROOM), SortRooms);
k = -1; if(roomp) level->gates[i].room1 = roomp;
for(node3 = node2->children; node3 = node3->next; node3 != NULL) {
if(node3->type != XML_ELEMENT_NODE) continue;
if(!xmlStrcmp(node3->name, "vertex")) { xmlFree(data);
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);
}
}
}
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;
}
}
j++;
} }
data = xmlGetProp(node2, "room2");
if(data) {
room.id = data;
roomp = bsearch(&room, level->rooms, level->nRooms, sizeof(ROOM), SortRooms);
if(roomp) level->gates[i].room2 = roomp;
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++; i++;
} }
@ -573,15 +635,24 @@ void FreeLevel(LEVEL *level) {
if(level->nRooms) { if(level->nRooms) {
for(i = 0; i < level->nRooms; i++) { for(i = 0; i < level->nRooms; i++) {
if(level->rooms[i].nWalls) free(level->rooms[i].walls); 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) { if(level->rooms[i].nGates) {
free(level->rooms[i].gates); free(level->rooms[i].gates);
free(level->rooms[i].gateinfo); free(level->rooms[i].gateinfo);
} }*/
free(level->rooms[i].id);
} }
free(level->rooms); 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) { if(level->nTextures) {
for(i = 0; i < level->nTextures; i++) for(i = 0; i < level->nTextures; i++)
free(level->textures[i].name); free(level->textures[i].name);

View file

@ -114,7 +114,7 @@ void DoInput(int delta) {
move.x = -c; move.x = -c;
move.z = -s; move.z = -s;
} }
if(input & INPUT_OPEN) { /*if(input & INPUT_OPEN) {
for(i = 0; i < level->rooms[room].nGates; i++) { for(i = 0; i < level->rooms[room].nGates; i++) {
if(level->rooms[room].gateinfo[i].state != STATE_CLOSED) continue; if(level->rooms[room].gateinfo[i].state != STATE_CLOSED) continue;
if(CollisionSphereTriangle(player.pos, 1.0, level->rooms[room].gates[i].walls[0].triangle) || 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; level->rooms[room].gateinfo[i].timer = 1000;
} }
} }
} }*/
} }
pos = VectorAdd(player.pos, VectorMul(move, delta/150.0)); pos = VectorAdd(player.pos, VectorMul(move, delta/150.0));
@ -162,21 +162,21 @@ void DoInput(int delta) {
}*/ }*/
falling = 1; falling = 1;
for(i = 0; i < level->rooms[room].nWalls; i++) { 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)) { CollisionMovingSphereTriangle(VectorSub(pos, VectorMul(move, delta/150.0)), 0.3, move, delta/150.0, level->rooms[room].walls[i].triangle)) {
pos = player.pos; pos = player.pos;
if(player.room != room) { /*if(player.room != room) {
level->rooms[room].gateinfo[g].state = STATE_CLOSED; level->rooms[room].gateinfo[g].state = STATE_CLOSED;
g = level->rooms[room].gates[g].gate; g = level->rooms[room].gates[g].gate;
room = player.room; room = player.room;
level->rooms[room].gateinfo[g].state = STATE_OPENED; level->rooms[room].gateinfo[g].state = STATE_OPENED;
} }*/
s = player.rotysin; s = player.rotysin;
c = player.rotycos; c = player.rotycos;
falling = 0; falling = 0;
break; 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; pos.y -= 1.81;
if(CollisionPointTriangle(pos, level->rooms[room].walls[i].triangle)) { if(CollisionPointTriangle(pos, level->rooms[room].walls[i].triangle)) {
falling = 0; 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; if(wasfalling && CollisionRayTriangle(pos, v, level->rooms[room].walls[i].triangle, &f)) pos.y -= f - 1.8;
} }
else pos.y += 1.81; else pos.y += 1.81;
} //}
} }
player.pos = pos; player.pos = pos;
player.room = room; player.room = room;
player.rotysin = s; player.rotysin = s;
player.rotycos = c; 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 = VectorSub(level->rooms[player.room].things[i].pos, player.pos);
pos.y += 0.9; pos.y += 0.9;
switch(level->rooms[player.room].things[i].type) { 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].state = STATE_CLOSED;
} }
else level->rooms[player.room].gateinfo[i].timer -= delta; else level->rooms[player.room].gateinfo[i].timer -= delta;
} }*/
static int lightpos = 0; static int lightpos = 0;

View file

@ -5,21 +5,32 @@
#include <zoom/types.h> #include <zoom/types.h>
#include <zoom/render.h> #include <zoom/render.h>
typedef struct _GATEINFO { /*typedef struct _GATEINFO {
unsigned short state; unsigned short state;
unsigned short timer; unsigned short timer;
} GATEINFO; } GATEINFO;*/
typedef struct _ROOM { typedef struct _ROOM {
char *id;
int nWalls; int nWalls;
int nThings; //int nThings;
int nGates; //int nGates;
WALL *walls; WALL *walls;
THING *things; //THING *things;
GATE *gates; //GATE *gates;
GATEINFO *gateinfo; //GATEINFO *gateinfo;
} ROOM; } 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 { typedef struct _LEVELINFO {
char *name; char *name;
char *desc; char *desc;
@ -35,6 +46,8 @@ typedef struct _LEVEL {
LEVELINFO *info; LEVELINFO *info;
int nRooms; int nRooms;
ROOM *rooms; ROOM *rooms;
int nGates;
GATE *gates;
int nTextures; int nTextures;
TEXTURE *textures; TEXTURE *textures;
} LEVEL; } LEVEL;

View file

@ -23,7 +23,7 @@
#pragma pack(push, 2) #pragma pack(push, 2)
typedef struct WALL { typedef struct WALL {
unsigned char type; //unsigned char type;
unsigned char visible; unsigned char visible;
union { union {
TRIANGLE triangle; TRIANGLE triangle;
@ -42,15 +42,6 @@ typedef struct _THING {
unsigned char visible; unsigned char visible;
VERTEX pos; VERTEX pos;
} THING; } THING;
typedef struct _GATE {
unsigned char type;
unsigned char open;
WALL walls[2];
VERTEX point;
int room;
int gate;
} GATE;
#pragma pack(pop) #pragma pack(pop)
#endif #endif