summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorneoraider <devnull@localhost>2007-05-14 19:38:01 +0200
committerneoraider <devnull@localhost>2007-05-14 19:38:01 +0200
commita5aa4b54e23d0793793384a6794cc543ea48ad34 (patch)
tree480f4686b8879347119803ac0973266216a5e6bc
parent4069752dbc64302b2fb64703644622cb2ec09eef (diff)
downloadlibzoom-a5aa4b54e23d0793793384a6794cc543ea48ad34.tar
libzoom-a5aa4b54e23d0793793384a6794cc543ea48ad34.zip
libzoom: XML level loader implemented.
zoom: Converted old test level to XML.
-rw-r--r--init.c8
-rw-r--r--level.c370
-rw-r--r--player.c98
-rw-r--r--render.c10
-rw-r--r--zoom/level.h53
-rw-r--r--zoom/types.h1
6 files changed, 389 insertions, 151 deletions
diff --git a/init.c b/init.c
index 2df1763..d5407cd 100644
--- a/init.c
+++ b/init.c
@@ -6,7 +6,7 @@
#include <zoom/level.h>
#include <zoom/light.h>
-LEVEL level;
+LEVEL *level;
GLuint sphere;
GLuint meditex_blue;
GLuint lightmap;
@@ -57,8 +57,8 @@ int InitGame() {
gluQuadricDrawStyle(quadric, GLU_FILL);
gluQuadricTexture(quadric, GL_TRUE);
- LoadLevel("level2.lvl", &level);
-
+ level = LoadLevel("level.lvl");
+
sphere = glGenLists(1);
glNewList(sphere, GL_COMPILE);
glRotatef(90, 1.0, 0.0, 0.0);
@@ -71,6 +71,6 @@ int InitGame() {
}
void UninitGame() {
- FreeLevel(&level);
+ FreeLevel(level);
free(texlist);
}
diff --git a/level.c b/level.c
index e7b8343..0d22f64 100644
--- a/level.c
+++ b/level.c
@@ -7,6 +7,9 @@
#include <zoom/texture.h>
#include <zoom/level.h>
#include <zoom/light.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/valid.h>
extern GLuint sphere;
@@ -15,66 +18,281 @@ extern float objrot;
extern LIGHT *lights;
extern int nLights;
-int LoadLevel(char *filename, LEVEL *level) {
- FILE *file;
- LEVELHEADER levelheader;
- ROOMHEADER roomheader;
- int i, j;
- unsigned char c;
- unsigned char buffer[260];
-
- strcpy(buffer, "levels/");
- strcat(buffer, filename);
- file = fopen(buffer, "rb");
- if(!file) return 0;
-
- fread(&levelheader, sizeof(LEVELHEADER), 1, file);
- if(levelheader.l != 'L' || levelheader.f != 'F') {
- fclose(file);
- return 0;
- }
-
- level->nRooms = levelheader.nRooms;
- level->rooms = malloc(levelheader.nRooms * sizeof(ROOM));
-
- for(i = 0; i < levelheader.nRooms; i++) {
- fread(&roomheader, sizeof(ROOMHEADER), 1, file);
-
- level->rooms[i].nWalls = roomheader.nWalls;
- level->rooms[i].walls = malloc(roomheader.nWalls * sizeof(WALL));
- fread(level->rooms[i].walls, sizeof(WALL), roomheader.nWalls, file);
-
- level->rooms[i].nThings = roomheader.nThings;
- level->rooms[i].things = malloc(roomheader.nThings * sizeof(THING));
- fread(level->rooms[i].things, sizeof(THING), roomheader.nThings, file);
-
- level->rooms[i].nGates = roomheader.nGates;
- level->rooms[i].gates = malloc(roomheader.nGates * sizeof(GATE));
- fread(level->rooms[i].gates, sizeof(GATE), roomheader.nGates, file);
-
- level->rooms[i].gateinfo = malloc(roomheader.nGates * sizeof(GATEINFO));
- for(j = 0; j < level->rooms[i].nGates; j++) level->rooms[i].gateinfo[j].state = STATE_CLOSED;
- }
-
- level->nTextures = levelheader.nTextures;
- level->textures = malloc(levelheader.nTextures * sizeof(GLuint));
-
- for(i = 0; i < levelheader.nTextures; i++) {
- fread(&c, 1, 1, file);
- fread(buffer, c, 1, file);
- buffer[c] = 0;
- level->textures[i] = LoadTexture(buffer);
- }
-
- fclose(file);
- return 1;
+
+static int SortTextures(const void *t1, const void *t2) {
+ return strcmp(((TEXTURE*)t1)->name, ((TEXTURE*)t2)->name);
+}
+
+
+LEVEL *LoadLevel(char *filename) {
+ LEVEL *level;
+ xmlDocPtr doc;
+ xmlDtdPtr dtd;
+ xmlValidCtxtPtr validCtxt;
+ xmlNodePtr root, node, node2, node3, rooms = NULL;
+ xmlChar *data;
+ char *name;
+ int i, j, k;
+ VECTOR v;
+ TEXTURE tex;
+ TEXTURE *texp;
+
+
+ name = malloc(strlen(filename)+8);
+ strcpy(name, "levels/");
+ strcat(name, filename);
+
+ doc = xmlParseFile(name);
+
+ free(name);
+
+ if(!doc)
+ return NULL;
+
+ dtd = xmlParseDTD("-//libzoom//DTD level 0.1//EN", "levels/level.dtd");
+
+ if(!dtd) {
+ xmlFreeDoc(doc);
+ xmlCleanupParser();
+ return NULL;
+ }
+
+ validCtxt = xmlNewValidCtxt();
+
+ if(!validCtxt) {
+ xmlFreeDtd(dtd);
+ xmlFreeDoc(doc);
+ xmlCleanupParser();
+ return NULL;
+ }
+
+ if(!xmlValidateDtd(validCtxt, doc, dtd)) {
+ xmlFreeValidCtxt(validCtxt);
+ xmlFreeDtd(dtd);
+ xmlFreeDoc(doc);
+ xmlCleanupParser();
+ return NULL;
+ }
+
+ xmlFreeValidCtxt(validCtxt);
+ xmlFreeDtd(dtd);
+
+ root = xmlDocGetRootElement(doc);
+ if(!root || xmlStrcmp(root->name, "level")) {
+ xmlFreeDoc(doc);
+ xmlCleanupParser();
+ return NULL;
+ }
+
+ level = calloc(1, sizeof(LEVEL));
+
+ for(node = root->children; node = node->next; node != NULL) {
+ if(node->type != XML_ELEMENT_NODE) continue;
+
+ if(!xmlStrcmp(node->name, "info")) {
+ level->info = calloc(1, sizeof(LEVELINFO));
+
+ for(node2 = node->children; node2 = node2->next; node2 != NULL) {
+ if(node2->type != XML_ELEMENT_NODE) continue;
+
+ if(!xmlStrcmp(node2->name, "name")) {
+ if(level->info->name != NULL) continue;
+
+ data = xmlNodeGetContent(node2);
+ level->info->name = strdup(data);
+ xmlFree(data);
+ }
+ else if(!xmlStrcmp(node2->name, "desc")) {
+ if(level->info->desc != NULL) continue;
+
+ data = xmlNodeGetContent(node2);
+ level->info->desc = strdup(data);
+ xmlFree(data);
+ }
+ else if(!xmlStrcmp(node2->name, "start")) {
+ data = xmlGetProp(node2, "x");
+ if(data) level->info->start.x = atof(data);
+ xmlFree(data);
+
+ data = xmlGetProp(node2, "y");
+ if(data) level->info->start.y = atof(data);
+ xmlFree(data);
+
+ data = xmlGetProp(node2, "z");
+ if(data) level->info->start.z = atof(data);
+ xmlFree(data);
+ }
+ }
+ }
+ else if(!xmlStrcmp(node->name, "rooms")) {
+ if(rooms != NULL) continue;
+
+ rooms = node;
+
+ for(node2 = node->children; node2 = node2->next; node2 != NULL) {
+ if(node2->type == XML_ELEMENT_NODE && !xmlStrcmp(node2->name, "room")) level->nRooms++;
+ }
+ }
+ else if(!xmlStrcmp(node->name, "textures")) {
+ if(level->textures != NULL) continue;
+
+ for(node2 = node->children; node2 = node2->next; node2 != NULL) {
+ if(node2->type == XML_ELEMENT_NODE && !xmlStrcmp(node2->name, "texture")) level->nTextures++;
+ }
+
+ level->textures = calloc(level->nTextures, sizeof(TEXTURE));
+
+ i = 0;
+ for(node2 = node->children; node2 = node2->next; node2 != NULL) {
+ if(node2->type != XML_ELEMENT_NODE || xmlStrcmp(node2->name, "texture")) continue;
+
+ data = xmlGetProp(node2, "name");
+ if(data) {
+ level->textures[i].id = LoadTexture(data);
+
+ xmlFree(data);
+ }
+
+ data = xmlGetProp(node2, "id");
+ if(data) {
+ level->textures[i].name = strdup(data);
+
+ xmlFree(data);
+ }
+
+ i++;
+ }
+
+ qsort(level->textures, level->nTextures, sizeof(TEXTURE), SortTextures);
+ }
+ }
+
+ level->rooms = calloc(level->nRooms, sizeof(ROOM));
+
+ i = 0;
+ for(node = rooms->children; node = node->next; node != NULL) {
+ if(node->type != XML_ELEMENT_NODE || xmlStrcmp(node->name, "room")) continue;
+
+ 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);
+ }
+
+ 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);
+ }
+
+ 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);
+ }
+ }
+ }
+ 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)) level->rooms[i].walls[j].normal = VectorNormalize(v);
+
+ j++;
+ }
+
+ i++;
+ }
+
+ xmlFreeDoc(doc);
+ xmlCleanupParser();
+
+ return level;
}
POLYGON_LIST *DrawRoom(LEVEL *level, int nr) {
ROOM room = level->rooms[nr];
POLYGON_LIST *p;
int i;
-
+
p = malloc(sizeof(POLYGON_LIST)+sizeof(POLYGON)*room.nWalls);
p->nPolygons = room.nWalls;
@@ -84,8 +302,11 @@ POLYGON_LIST *DrawRoom(LEVEL *level, int nr) {
p->polygons[i].vertices[2] = room.walls[i].vertices[2];
p->polygons[i].normal = room.walls[i].normal;
+ p->polygons[i].normals[0] = room.walls[i].normals[0];
+ p->polygons[i].normals[1] = room.walls[i].normals[1];
+ p->polygons[i].normals[2] = room.walls[i].normals[2];
- p->polygons[i].texture = level->textures[room.walls[i].texture];
+ p->polygons[i].texture = room.walls[i].texture;
p->polygons[i].texcoords[0] = room.walls[i].texcoords[0];
p->polygons[i].texcoords[1] = room.walls[i].texcoords[1];
@@ -334,15 +555,32 @@ POLYGON_LIST *DrawRoom(LEVEL *level, int nr) {
void FreeLevel(LEVEL *level) {
int i;
- 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].nGates) {
- free(level->rooms[i].gates);
- free(level->rooms[i].gateinfo);
- }
- }
- free(level->rooms);
- }
+ if(level) {
+ if(level->info) {
+ free(level->info->name);
+ free(level->info->desc);
+ free(level->info);
+ }
+
+ 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].nGates) {
+ free(level->rooms[i].gates);
+ free(level->rooms[i].gateinfo);
+ }
+ }
+ free(level->rooms);
+ }
+
+ if(level->nTextures) {
+ for(i = 0; i < level->nTextures; i++)
+ free(level->textures[i].name);
+
+ free(level->textures);
+ }
+
+ free(level);
+ }
}
diff --git a/player.c b/player.c
index 2715d92..77c0704 100644
--- a/player.c
+++ b/player.c
@@ -20,7 +20,7 @@ float rotxspeed = 0, rotyspeed = 0;
float objrot = 0;
-extern LEVEL level;
+extern LEVEL *level;
extern int nLights;
extern LIGHT *lights;
@@ -77,7 +77,7 @@ void DoInput(int delta) {
s = player.rotysin;
c = player.rotycos;
- if(!falling) {
+ if(!falling) {
if((input & INPUT_UP) && !(input & INPUT_DOWN)) {
if((input & INPUT_RIGHT) && !(input & INPUT_LEFT)) {
move.x = (s+c)*M_SQRT1_2;
@@ -115,12 +115,12 @@ void DoInput(int delta) {
move.z = -s;
}
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) ||
- CollisionSphereTriangle(player.pos, 1.0, level.rooms[room].gates[i].walls[1].triangle)) {
- level.rooms[room].gateinfo[i].state = STATE_OPENING;
- level.rooms[room].gateinfo[i].timer = 1000;
+ 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) ||
+ CollisionSphereTriangle(player.pos, 1.0, level->rooms[room].gates[i].walls[1].triangle)) {
+ level->rooms[room].gateinfo[i].state = STATE_OPENING;
+ level->rooms[room].gateinfo[i].timer = 1000;
}
}
}
@@ -130,21 +130,21 @@ void DoInput(int delta) {
if(falling) pos.y -= delta/100.0;
- for(i = 0; i < level.rooms[room].nGates; i++) {
- if(CollisionSphereTriangle(pos, 0.3, level.rooms[room].gates[i].walls[0].triangle) ||
- CollisionSphereTriangle(pos, 0.3, level.rooms[room].gates[i].walls[1].triangle)) {
- if(level.rooms[room].gateinfo[i].state == STATE_OPENED) {
- if(CollisionPointTriangle(pos, level.rooms[room].gates[i].walls[0].triangle) ||
- CollisionPointTriangle(pos, level.rooms[room].gates[i].walls[1].triangle)) {
- p1 = level.rooms[room].gates[i].point;
- v1 = level.rooms[room].gates[i].walls[0].normal;
- level.rooms[room].gateinfo[i].state = STATE_CLOSED;
- g = level.rooms[room].gates[i].gate;
- room = level.rooms[room].gates[i].room;
- p2 = level.rooms[room].gates[g].point;
- v2 = VectorNeg(level.rooms[room].gates[g].walls[0].normal);
- level.rooms[room].gateinfo[g].state = STATE_OPENED;
- level.rooms[room].gateinfo[g].timer = 5000;
+ /*for(i = 0; i < level->rooms[room].nGates; i++) {
+ if(CollisionSphereTriangle(pos, 0.3, level->rooms[room].gates[i].walls[0].triangle) ||
+ CollisionSphereTriangle(pos, 0.3, level->rooms[room].gates[i].walls[1].triangle)) {
+ if(level->rooms[room].gateinfo[i].state == STATE_OPENED) {
+ if(CollisionPointTriangle(pos, level->rooms[room].gates[i].walls[0].triangle) ||
+ CollisionPointTriangle(pos, level->rooms[room].gates[i].walls[1].triangle)) {
+ p1 = level->rooms[room].gates[i].point;
+ v1 = level->rooms[room].gates[i].walls[0].normal;
+ level->rooms[room].gateinfo[i].state = STATE_CLOSED;
+ g = level->rooms[room].gates[i].gate;
+ room = level->rooms[room].gates[i].room;
+ p2 = level->rooms[room].gates[g].point;
+ v2 = VectorNeg(level->rooms[room].gates[g].walls[0].normal);
+ level->rooms[room].gateinfo[g].state = STATE_OPENED;
+ level->rooms[room].gateinfo[g].timer = 5000;
transform = VectorMatrix(p2, v2, p1, v1);
pos = VectorMatrixMul(pos, transform);
v1.x = p1.x + c;
@@ -155,33 +155,33 @@ void DoInput(int delta) {
move = VectorSub(VectorMatrixMul(VectorAdd(move, p1), transform), p2);
break;
}
- level.rooms[room].gateinfo[i].timer = 5000;
+ level->rooms[room].gateinfo[i].timer = 5000;
}
else pos = player.pos;
}
- }
+ }*/
falling = 1;
- for(i = 0; i < level.rooms[room].nWalls; i++) {
- 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)) {
+ for(i = 0; i < level->rooms[room].nWalls; i++) {
+ 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) {
- level.rooms[room].gateinfo[g].state = STATE_CLOSED;
- g = level.rooms[room].gates[g].gate;
+ 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;
+ 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)) {
+ if(CollisionPointTriangle(pos, level->rooms[room].walls[i].triangle)) {
falling = 0;
pos.y += 1.81;
- 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;
}
@@ -191,29 +191,29 @@ void DoInput(int delta) {
player.rotysin = s;
player.rotycos = c;
- for(i = 0; i < level.rooms[player.room].nThings; i++) {
- pos = VectorSub(level.rooms[player.room].things[i].pos, player.pos);
+ 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) {
+ switch(level->rooms[player.room].things[i].type) {
case THING_MEDIPAK100:
- if((pos.x*pos.x + (pos.y*pos.y)/3 + pos.z*pos.z) < 0.36) level.rooms[player.room].things[i].visible = 0;
+ if((pos.x*pos.x + (pos.y*pos.y)/3 + pos.z*pos.z) < 0.36) level->rooms[player.room].things[i].visible = 0;
}
}
- for(i = 0; i < level.rooms[player.room].nGates; i++) {
- if(level.rooms[player.room].gateinfo[i].state == STATE_CLOSED) continue;
- if((level.rooms[player.room].gateinfo[i].timer - delta) < 0) {
- if(level.rooms[player.room].gateinfo[i].state == STATE_OPENING) {
- level.rooms[player.room].gateinfo[i].state = STATE_OPENED;
- level.rooms[player.room].gateinfo[i].timer = 5000;
+ for(i = 0; i < level->rooms[player.room].nGates; i++) {
+ if(level->rooms[player.room].gateinfo[i].state == STATE_CLOSED) continue;
+ if((level->rooms[player.room].gateinfo[i].timer - delta) < 0) {
+ if(level->rooms[player.room].gateinfo[i].state == STATE_OPENING) {
+ level->rooms[player.room].gateinfo[i].state = STATE_OPENED;
+ level->rooms[player.room].gateinfo[i].timer = 5000;
}
- else if(level.rooms[player.room].gateinfo[i].state == STATE_OPENED) {
- level.rooms[player.room].gateinfo[i].state = STATE_CLOSING;
- level.rooms[player.room].gateinfo[i].timer = 1000;
+ else if(level->rooms[player.room].gateinfo[i].state == STATE_OPENED) {
+ level->rooms[player.room].gateinfo[i].state = STATE_CLOSING;
+ level->rooms[player.room].gateinfo[i].timer = 1000;
}
- 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;
diff --git a/render.c b/render.c
index 7500281..ba57e2a 100644
--- a/render.c
+++ b/render.c
@@ -10,7 +10,7 @@
extern PLAYER player;
-extern LEVEL level;
+extern LEVEL *level;
extern GLuint sphere;
extern int nLights;
extern LIGHT *lights;
@@ -47,7 +47,7 @@ void Render() {
glTranslatef(-player.pos.x, -player.pos.y, -player.pos.z);
- room = DrawRoom(&level, player.room);
+ room = DrawRoom(level, player.room);
qsort(room->polygons, room->nPolygons, sizeof(POLYGON), SortByTex);
glDepthMask(GL_TRUE);
@@ -118,14 +118,14 @@ void Render() {
c = VectorMul(lights[i].diffuse, 1.0/(d*d));
glColor3fv((GLfloat*)&c);
- p = VectorAdd(lights[i].pos, VectorMul(room->polygons[j].normal, d));
-
v1 = VectorNormalize(VectorSub(room->polygons[j].vertices[0], room->polygons[j].vertices[1]));
- v2 = VectorCross(v1, room->polygons[j].normal);
for(k = 0; k < 3; k++) {
+ p = VectorAdd(lights[i].pos, VectorMul(room->polygons[j].normals[k], d));
v = VectorSub(room->polygons[j].vertices[k], p);
+ v2 = VectorCross(v1, room->polygons[j].normals[k]);
+
glMultiTexCoord2f(0, VectorDot(v, v1)*0.04 / d + 0.5, VectorDot(v, v2)*0.04 / d + 0.5);
glMultiTexCoord2fv(1, (GLfloat*)&room->polygons[j].texcoords[k]);
glVertex3fv((GLfloat*)&room->polygons[j].vertices[k]);
diff --git a/zoom/level.h b/zoom/level.h
index c93fd3b..49de407 100644
--- a/zoom/level.h
+++ b/zoom/level.h
@@ -5,45 +5,44 @@
#include <zoom/types.h>
#include <zoom/render.h>
-#pragma pack(push, 2)
-typedef struct _LEVELHEADER {
- char l, f;
- int nRooms;
- int nTextures;
-} LEVELHEADER;
-
-typedef struct _ROOMHEADER {
- int nWalls;
- int nThings;
- int nGates;
-} ROOMHEADER;
-
typedef struct _GATEINFO {
unsigned short state;
unsigned short timer;
} GATEINFO;
typedef struct _ROOM {
- int nWalls;
- int nThings;
- int nGates;
- WALL *walls;
- THING *things;
- GATE *gates;
- GATEINFO *gateinfo;
+ int nWalls;
+ int nThings;
+ int nGates;
+ WALL *walls;
+ THING *things;
+ GATE *gates;
+ GATEINFO *gateinfo;
} ROOM;
+typedef struct _LEVELINFO {
+ char *name;
+ char *desc;
+ VERTEX start;
+} LEVELINFO;
+
+typedef struct _TEXTURE {
+ char *name;
+ GLuint id;
+} TEXTURE;
+
typedef struct _LEVEL {
- int nRooms;
- ROOM *rooms;
- int nTextures;
- GLuint *textures;
+ LEVELINFO *info;
+ int nRooms;
+ ROOM *rooms;
+ int nTextures;
+ TEXTURE *textures;
} LEVEL;
-#pragma pack(pop)
typedef struct _POLYGON {
+ VECTOR normal;
VERTEX vertices[3];
- VECTOR normal;
+ VECTOR normals[3];
GLuint texture;
TEXCOORDS texcoords[3];
@@ -56,7 +55,7 @@ typedef struct _POLYGON_LIST {
} POLYGON_LIST;
-int LoadLevel(char *, LEVEL *);
+LEVEL *LoadLevel(char *);
POLYGON_LIST *DrawRoom(LEVEL *, int);
void FreeLevel(LEVEL *);
diff --git a/zoom/types.h b/zoom/types.h
index 0a60876..4c86190 100644
--- a/zoom/types.h
+++ b/zoom/types.h
@@ -32,6 +32,7 @@ typedef struct WALL {
VECTOR normal;
};
};
+ VECTOR normals[3];
int texture;
TEXCOORDS texcoords[3];
} WALL;