libzoom: XML level loader implemented.
zoom: Converted old test level to XML.
This commit is contained in:
parent
4069752dbc
commit
a5aa4b54e2
6 changed files with 389 additions and 151 deletions
8
init.c
8
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);
|
||||
}
|
||||
|
|
370
level.c
370
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);
|
||||
}
|
||||
}
|
||||
|
|
98
player.c
98
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;
|
||||
|
|
10
render.c
10
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]);
|
||||
|
|
53
zoom/level.h
53
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 *);
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ typedef struct WALL {
|
|||
VECTOR normal;
|
||||
};
|
||||
};
|
||||
VECTOR normals[3];
|
||||
int texture;
|
||||
TEXCOORDS texcoords[3];
|
||||
} WALL;
|
||||
|
|
Reference in a new issue