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
6
init.c
6
init.c
|
@ -6,7 +6,7 @@
|
||||||
#include <zoom/level.h>
|
#include <zoom/level.h>
|
||||||
#include <zoom/light.h>
|
#include <zoom/light.h>
|
||||||
|
|
||||||
LEVEL level;
|
LEVEL *level;
|
||||||
GLuint sphere;
|
GLuint sphere;
|
||||||
GLuint meditex_blue;
|
GLuint meditex_blue;
|
||||||
GLuint lightmap;
|
GLuint lightmap;
|
||||||
|
@ -57,7 +57,7 @@ int InitGame() {
|
||||||
gluQuadricDrawStyle(quadric, GLU_FILL);
|
gluQuadricDrawStyle(quadric, GLU_FILL);
|
||||||
gluQuadricTexture(quadric, GL_TRUE);
|
gluQuadricTexture(quadric, GL_TRUE);
|
||||||
|
|
||||||
LoadLevel("level2.lvl", &level);
|
level = LoadLevel("level.lvl");
|
||||||
|
|
||||||
sphere = glGenLists(1);
|
sphere = glGenLists(1);
|
||||||
glNewList(sphere, GL_COMPILE);
|
glNewList(sphere, GL_COMPILE);
|
||||||
|
@ -71,6 +71,6 @@ int InitGame() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void UninitGame() {
|
void UninitGame() {
|
||||||
FreeLevel(&level);
|
FreeLevel(level);
|
||||||
free(texlist);
|
free(texlist);
|
||||||
}
|
}
|
||||||
|
|
320
level.c
320
level.c
|
@ -7,6 +7,9 @@
|
||||||
#include <zoom/texture.h>
|
#include <zoom/texture.h>
|
||||||
#include <zoom/level.h>
|
#include <zoom/level.h>
|
||||||
#include <zoom/light.h>
|
#include <zoom/light.h>
|
||||||
|
#include <libxml/parser.h>
|
||||||
|
#include <libxml/tree.h>
|
||||||
|
#include <libxml/valid.h>
|
||||||
|
|
||||||
|
|
||||||
extern GLuint sphere;
|
extern GLuint sphere;
|
||||||
|
@ -15,59 +18,274 @@ extern float objrot;
|
||||||
extern LIGHT *lights;
|
extern LIGHT *lights;
|
||||||
extern int nLights;
|
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/");
|
static int SortTextures(const void *t1, const void *t2) {
|
||||||
strcat(buffer, filename);
|
return strcmp(((TEXTURE*)t1)->name, ((TEXTURE*)t2)->name);
|
||||||
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++) {
|
LEVEL *LoadLevel(char *filename) {
|
||||||
fread(&roomheader, sizeof(ROOMHEADER), 1, file);
|
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;
|
||||||
|
|
||||||
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;
|
name = malloc(strlen(filename)+8);
|
||||||
level->rooms[i].things = malloc(roomheader.nThings * sizeof(THING));
|
strcpy(name, "levels/");
|
||||||
fread(level->rooms[i].things, sizeof(THING), roomheader.nThings, file);
|
strcat(name, filename);
|
||||||
|
|
||||||
level->rooms[i].nGates = roomheader.nGates;
|
doc = xmlParseFile(name);
|
||||||
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));
|
free(name);
|
||||||
for(j = 0; j < level->rooms[i].nGates; j++) level->rooms[i].gateinfo[j].state = STATE_CLOSED;
|
|
||||||
|
if(!doc)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dtd = xmlParseDTD("-//libzoom//DTD level 0.1//EN", "levels/level.dtd");
|
||||||
|
|
||||||
|
if(!dtd) {
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
xmlCleanupParser();
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
level->nTextures = levelheader.nTextures;
|
validCtxt = xmlNewValidCtxt();
|
||||||
level->textures = malloc(levelheader.nTextures * sizeof(GLuint));
|
|
||||||
|
|
||||||
for(i = 0; i < levelheader.nTextures; i++) {
|
if(!validCtxt) {
|
||||||
fread(&c, 1, 1, file);
|
xmlFreeDtd(dtd);
|
||||||
fread(buffer, c, 1, file);
|
xmlFreeDoc(doc);
|
||||||
buffer[c] = 0;
|
xmlCleanupParser();
|
||||||
level->textures[i] = LoadTexture(buffer);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(file);
|
if(!xmlValidateDtd(validCtxt, doc, dtd)) {
|
||||||
return 1;
|
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) {
|
POLYGON_LIST *DrawRoom(LEVEL *level, int nr) {
|
||||||
|
@ -84,8 +302,11 @@ POLYGON_LIST *DrawRoom(LEVEL *level, int nr) {
|
||||||
p->polygons[i].vertices[2] = room.walls[i].vertices[2];
|
p->polygons[i].vertices[2] = room.walls[i].vertices[2];
|
||||||
|
|
||||||
p->polygons[i].normal = room.walls[i].normal;
|
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[0] = room.walls[i].texcoords[0];
|
||||||
p->polygons[i].texcoords[1] = room.walls[i].texcoords[1];
|
p->polygons[i].texcoords[1] = room.walls[i].texcoords[1];
|
||||||
|
@ -334,6 +555,13 @@ POLYGON_LIST *DrawRoom(LEVEL *level, int nr) {
|
||||||
void FreeLevel(LEVEL *level) {
|
void FreeLevel(LEVEL *level) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if(level) {
|
||||||
|
if(level->info) {
|
||||||
|
free(level->info->name);
|
||||||
|
free(level->info->desc);
|
||||||
|
free(level->info);
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
@ -345,4 +573,14 @@ void FreeLevel(LEVEL *level) {
|
||||||
}
|
}
|
||||||
free(level->rooms);
|
free(level->rooms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(level->nTextures) {
|
||||||
|
for(i = 0; i < level->nTextures; i++)
|
||||||
|
free(level->textures[i].name);
|
||||||
|
|
||||||
|
free(level->textures);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(level);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
96
player.c
96
player.c
|
@ -20,7 +20,7 @@ float rotxspeed = 0, rotyspeed = 0;
|
||||||
|
|
||||||
float objrot = 0;
|
float objrot = 0;
|
||||||
|
|
||||||
extern LEVEL level;
|
extern LEVEL *level;
|
||||||
extern int nLights;
|
extern int nLights;
|
||||||
extern LIGHT *lights;
|
extern LIGHT *lights;
|
||||||
|
|
||||||
|
@ -115,12 +115,12 @@ void DoInput(int delta) {
|
||||||
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) ||
|
||||||
CollisionSphereTriangle(player.pos, 1.0, level.rooms[room].gates[i].walls[1].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].state = STATE_OPENING;
|
||||||
level.rooms[room].gateinfo[i].timer = 1000;
|
level->rooms[room].gateinfo[i].timer = 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,21 +130,21 @@ void DoInput(int delta) {
|
||||||
|
|
||||||
if(falling) pos.y -= delta/100.0;
|
if(falling) pos.y -= delta/100.0;
|
||||||
|
|
||||||
for(i = 0; i < level.rooms[room].nGates; i++) {
|
/*for(i = 0; i < level->rooms[room].nGates; i++) {
|
||||||
if(CollisionSphereTriangle(pos, 0.3, level.rooms[room].gates[i].walls[0].triangle) ||
|
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)) {
|
CollisionSphereTriangle(pos, 0.3, level->rooms[room].gates[i].walls[1].triangle)) {
|
||||||
if(level.rooms[room].gateinfo[i].state == STATE_OPENED) {
|
if(level->rooms[room].gateinfo[i].state == STATE_OPENED) {
|
||||||
if(CollisionPointTriangle(pos, level.rooms[room].gates[i].walls[0].triangle) ||
|
if(CollisionPointTriangle(pos, level->rooms[room].gates[i].walls[0].triangle) ||
|
||||||
CollisionPointTriangle(pos, level.rooms[room].gates[i].walls[1].triangle)) {
|
CollisionPointTriangle(pos, level->rooms[room].gates[i].walls[1].triangle)) {
|
||||||
p1 = level.rooms[room].gates[i].point;
|
p1 = level->rooms[room].gates[i].point;
|
||||||
v1 = level.rooms[room].gates[i].walls[0].normal;
|
v1 = level->rooms[room].gates[i].walls[0].normal;
|
||||||
level.rooms[room].gateinfo[i].state = STATE_CLOSED;
|
level->rooms[room].gateinfo[i].state = STATE_CLOSED;
|
||||||
g = level.rooms[room].gates[i].gate;
|
g = level->rooms[room].gates[i].gate;
|
||||||
room = level.rooms[room].gates[i].room;
|
room = level->rooms[room].gates[i].room;
|
||||||
p2 = level.rooms[room].gates[g].point;
|
p2 = level->rooms[room].gates[g].point;
|
||||||
v2 = VectorNeg(level.rooms[room].gates[g].walls[0].normal);
|
v2 = VectorNeg(level->rooms[room].gates[g].walls[0].normal);
|
||||||
level.rooms[room].gateinfo[g].state = STATE_OPENED;
|
level->rooms[room].gateinfo[g].state = STATE_OPENED;
|
||||||
level.rooms[room].gateinfo[g].timer = 5000;
|
level->rooms[room].gateinfo[g].timer = 5000;
|
||||||
transform = VectorMatrix(p2, v2, p1, v1);
|
transform = VectorMatrix(p2, v2, p1, v1);
|
||||||
pos = VectorMatrixMul(pos, transform);
|
pos = VectorMatrixMul(pos, transform);
|
||||||
v1.x = p1.x + c;
|
v1.x = p1.x + c;
|
||||||
|
@ -155,33 +155,33 @@ void DoInput(int delta) {
|
||||||
move = VectorSub(VectorMatrixMul(VectorAdd(move, p1), transform), p2);
|
move = VectorSub(VectorMatrixMul(VectorAdd(move, p1), transform), p2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
level.rooms[room].gateinfo[i].timer = 5000;
|
level->rooms[room].gateinfo[i].timer = 5000;
|
||||||
}
|
}
|
||||||
else pos = player.pos;
|
else pos = player.pos;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
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;
|
||||||
pos.y += 1.81;
|
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;
|
else pos.y += 1.81;
|
||||||
}
|
}
|
||||||
|
@ -191,29 +191,29 @@ void DoInput(int delta) {
|
||||||
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) {
|
||||||
case THING_MEDIPAK100:
|
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++) {
|
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].state == STATE_CLOSED) continue;
|
||||||
if((level.rooms[player.room].gateinfo[i].timer - delta) < 0) {
|
if((level->rooms[player.room].gateinfo[i].timer - delta) < 0) {
|
||||||
if(level.rooms[player.room].gateinfo[i].state == STATE_OPENING) {
|
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].state = STATE_OPENED;
|
||||||
level.rooms[player.room].gateinfo[i].timer = 5000;
|
level->rooms[player.room].gateinfo[i].timer = 5000;
|
||||||
}
|
}
|
||||||
else if(level.rooms[player.room].gateinfo[i].state == STATE_OPENED) {
|
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].state = STATE_CLOSING;
|
||||||
level.rooms[player.room].gateinfo[i].timer = 1000;
|
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;
|
static int lightpos = 0;
|
||||||
|
|
10
render.c
10
render.c
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
|
|
||||||
extern PLAYER player;
|
extern PLAYER player;
|
||||||
extern LEVEL level;
|
extern LEVEL *level;
|
||||||
extern GLuint sphere;
|
extern GLuint sphere;
|
||||||
extern int nLights;
|
extern int nLights;
|
||||||
extern LIGHT *lights;
|
extern LIGHT *lights;
|
||||||
|
@ -47,7 +47,7 @@ void Render() {
|
||||||
|
|
||||||
glTranslatef(-player.pos.x, -player.pos.y, -player.pos.z);
|
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);
|
qsort(room->polygons, room->nPolygons, sizeof(POLYGON), SortByTex);
|
||||||
|
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
|
@ -118,14 +118,14 @@ void Render() {
|
||||||
c = VectorMul(lights[i].diffuse, 1.0/(d*d));
|
c = VectorMul(lights[i].diffuse, 1.0/(d*d));
|
||||||
glColor3fv((GLfloat*)&c);
|
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]));
|
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++) {
|
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);
|
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);
|
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]);
|
glMultiTexCoord2fv(1, (GLfloat*)&room->polygons[j].texcoords[k]);
|
||||||
glVertex3fv((GLfloat*)&room->polygons[j].vertices[k]);
|
glVertex3fv((GLfloat*)&room->polygons[j].vertices[k]);
|
||||||
|
|
33
zoom/level.h
33
zoom/level.h
|
@ -5,19 +5,6 @@
|
||||||
#include <zoom/types.h>
|
#include <zoom/types.h>
|
||||||
#include <zoom/render.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 {
|
typedef struct _GATEINFO {
|
||||||
unsigned short state;
|
unsigned short state;
|
||||||
unsigned short timer;
|
unsigned short timer;
|
||||||
|
@ -33,17 +20,29 @@ typedef struct _ROOM {
|
||||||
GATEINFO *gateinfo;
|
GATEINFO *gateinfo;
|
||||||
} ROOM;
|
} ROOM;
|
||||||
|
|
||||||
|
typedef struct _LEVELINFO {
|
||||||
|
char *name;
|
||||||
|
char *desc;
|
||||||
|
VERTEX start;
|
||||||
|
} LEVELINFO;
|
||||||
|
|
||||||
|
typedef struct _TEXTURE {
|
||||||
|
char *name;
|
||||||
|
GLuint id;
|
||||||
|
} TEXTURE;
|
||||||
|
|
||||||
typedef struct _LEVEL {
|
typedef struct _LEVEL {
|
||||||
|
LEVELINFO *info;
|
||||||
int nRooms;
|
int nRooms;
|
||||||
ROOM *rooms;
|
ROOM *rooms;
|
||||||
int nTextures;
|
int nTextures;
|
||||||
GLuint *textures;
|
TEXTURE *textures;
|
||||||
} LEVEL;
|
} LEVEL;
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
typedef struct _POLYGON {
|
typedef struct _POLYGON {
|
||||||
VERTEX vertices[3];
|
|
||||||
VECTOR normal;
|
VECTOR normal;
|
||||||
|
VERTEX vertices[3];
|
||||||
|
VECTOR normals[3];
|
||||||
|
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
TEXCOORDS texcoords[3];
|
TEXCOORDS texcoords[3];
|
||||||
|
@ -56,7 +55,7 @@ typedef struct _POLYGON_LIST {
|
||||||
} POLYGON_LIST;
|
} POLYGON_LIST;
|
||||||
|
|
||||||
|
|
||||||
int LoadLevel(char *, LEVEL *);
|
LEVEL *LoadLevel(char *);
|
||||||
POLYGON_LIST *DrawRoom(LEVEL *, int);
|
POLYGON_LIST *DrawRoom(LEVEL *, int);
|
||||||
void FreeLevel(LEVEL *);
|
void FreeLevel(LEVEL *);
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ typedef struct WALL {
|
||||||
VECTOR normal;
|
VECTOR normal;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
VECTOR normals[3];
|
||||||
int texture;
|
int texture;
|
||||||
TEXCOORDS texcoords[3];
|
TEXCOORDS texcoords[3];
|
||||||
} WALL;
|
} WALL;
|
||||||
|
|
Reference in a new issue