302 lines
9.5 KiB
C
302 lines
9.5 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <GL/gl.h>
|
|
#include <neofx/math.h>
|
|
#include <zoom/types.h>
|
|
#include <zoom/texture.h>
|
|
#include <zoom/level.h>
|
|
|
|
|
|
extern GLuint sphere;
|
|
extern GLuint meditex_blue;
|
|
extern float objrot;
|
|
extern LIGHT light;
|
|
|
|
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;
|
|
}
|
|
|
|
void DrawRoom(LEVEL *level, int nr) {
|
|
int i;
|
|
int r, g;
|
|
GLfloat std_emission[] = {0.0, 0.0, 0.0, 1.0};
|
|
GLfloat medipak100_emission[] = {1.0, 0.0, 0.0, 1.0};
|
|
ROOM room = level->rooms[nr];
|
|
WALL t1, t2;
|
|
VERTEX p1, p2;
|
|
VECTOR v1, v2, n, v;
|
|
float s, t, d;
|
|
MATRIX transform;
|
|
|
|
for(i = 0; i < room.nWalls; i++)
|
|
RenderWall(room.walls[i], level->textures);
|
|
|
|
for(i = 0; i < room.nThings; i++) {
|
|
if(!room.things[i].visible) continue;
|
|
switch(room.things[i].type) {
|
|
case THING_MEDIPAK100:
|
|
glPushMatrix();
|
|
//glBindTexture(GL_TEXTURE_2D, meditex_blue);
|
|
glMaterialfv(GL_FRONT, GL_EMISSION, medipak100_emission);
|
|
glTranslatef(room.things[i].pos.x, room.things[i].pos.y, room.things[i].pos.z);
|
|
glRotatef(objrot*10, 0.0, 1.0, 0.0);
|
|
glScalef(0.3, 0.3, 0.3);
|
|
glCallList(sphere);
|
|
glMaterialfv(GL_FRONT, GL_EMISSION, std_emission);
|
|
glPopMatrix();
|
|
}
|
|
}
|
|
|
|
for(i = 0; i < room.nGates; i++) {
|
|
if(room.gateinfo[i].state == STATE_CLOSED) {
|
|
//glBindTexture(GL_TEXTURE_2D, level->textures[room.gates[i].walls[0].texture]);
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
|
|
glNormal3fv((GLfloat*)&room.gates[i].walls[0].normal);
|
|
glTexCoord2fv((GLfloat*)&room.gates[i].walls[0].texcoords[0]);
|
|
glVertex3fv((GLfloat*)&room.gates[i].walls[0].vertices[0]);
|
|
glTexCoord2fv((GLfloat*)&room.gates[i].walls[0].texcoords[1]);
|
|
glVertex3fv((GLfloat*)&room.gates[i].walls[0].vertices[1]);
|
|
glTexCoord2fv((GLfloat*)&room.gates[i].walls[0].texcoords[2]);
|
|
glVertex3fv((GLfloat*)&room.gates[i].walls[0].vertices[2]);
|
|
|
|
glEnd();
|
|
|
|
//glBindTexture(GL_TEXTURE_2D, level->textures[room.gates[i].walls[0].texture]);
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
|
|
glNormal3fv((GLfloat*)&room.gates[i].walls[1].normal);
|
|
glTexCoord2fv((GLfloat*)&room.gates[i].walls[1].texcoords[0]);
|
|
glVertex3fv((GLfloat*)&room.gates[i].walls[1].vertices[0]);
|
|
glTexCoord2fv((GLfloat*)&room.gates[i].walls[1].texcoords[1]);
|
|
glVertex3fv((GLfloat*)&room.gates[i].walls[1].vertices[1]);
|
|
glTexCoord2fv((GLfloat*)&room.gates[i].walls[1].texcoords[2]);
|
|
glVertex3fv((GLfloat*)&room.gates[i].walls[1].vertices[2]);
|
|
|
|
glEnd();
|
|
}
|
|
else if(room.gateinfo[i].state == STATE_OPENING) {
|
|
t1 = room.gates[i].walls[0];
|
|
t2 = room.gates[i].walls[1];
|
|
|
|
t1.vertices[2] = VectorAdd(VectorMul(t1.vertices[2], room.gateinfo[i].timer/1000.0),
|
|
VectorMul(t1.vertices[1], 1 - (room.gateinfo[i].timer/1000.0)));
|
|
t2.vertices[1] = t1.vertices[2];
|
|
t2.vertices[2] = VectorAdd(VectorMul(t2.vertices[2], room.gateinfo[i].timer/1000.0),
|
|
VectorMul(t2.vertices[0], 1 - (room.gateinfo[i].timer/1000.0)));
|
|
|
|
|
|
t1.texcoords[0].s = t1.texcoords[0].s * room.gateinfo[i].timer/1000.0
|
|
+ t2.texcoords[2].s * (1 - room.gateinfo[i].timer/1000.0);
|
|
t1.texcoords[0].t = t1.texcoords[0].t * room.gateinfo[i].timer/1000.0
|
|
+ t2.texcoords[2].t * (1 - room.gateinfo[i].timer/1000.0);
|
|
t1.texcoords[1].s = t1.texcoords[1].s * room.gateinfo[i].timer/1000.0
|
|
+ t1.texcoords[2].s * (1 - room.gateinfo[i].timer/1000.0);
|
|
t1.texcoords[1].t = t1.texcoords[1].t * room.gateinfo[i].timer/1000.0
|
|
+ t1.texcoords[2].t * (1 - room.gateinfo[i].timer/1000.0);
|
|
t2.texcoords[0] = t1.texcoords[0];
|
|
|
|
//glBindTexture(GL_TEXTURE_2D, level->textures[t1.texture]);
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
|
|
glNormal3fv((GLfloat*)&t1.normal);
|
|
glTexCoord2fv((GLfloat*)&t1.texcoords[0]);
|
|
glVertex3fv((GLfloat*)&t1.vertices[0]);
|
|
glTexCoord2fv((GLfloat*)&t1.texcoords[1]);
|
|
glVertex3fv((GLfloat*)&t1.vertices[1]);
|
|
glTexCoord2fv((GLfloat*)&t1.texcoords[2]);
|
|
glVertex3fv((GLfloat*)&t1.vertices[2]);
|
|
|
|
glEnd();
|
|
|
|
//glBindTexture(GL_TEXTURE_2D, level->textures[t2.texture]);
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
|
|
glNormal3fv((GLfloat*)&t2.normal);
|
|
glTexCoord2fv((GLfloat*)&t2.texcoords[0]);
|
|
glVertex3fv((GLfloat*)&t2.vertices[0]);
|
|
glTexCoord2fv((GLfloat*)&t2.texcoords[1]);
|
|
glVertex3fv((GLfloat*)&t2.vertices[1]);
|
|
glTexCoord2fv((GLfloat*)&t2.texcoords[2]);
|
|
glVertex3fv((GLfloat*)&t2.vertices[2]);
|
|
|
|
glEnd();
|
|
|
|
r = room.gates[i].room;
|
|
g = room.gates[i].gate;
|
|
|
|
t1 = room.gates[i].walls[0];
|
|
t2 = room.gates[i].walls[1];
|
|
p1 = room.gates[i].point;
|
|
v1 = t1.normal;
|
|
|
|
t1 = level->rooms[r].gates[g].walls[0];
|
|
t2 = level->rooms[r].gates[g].walls[1];
|
|
p2 = level->rooms[r].gates[g].point;
|
|
v2 = VectorNeg(t1.normal);
|
|
|
|
glPushMatrix();
|
|
transform = VectorMatrix(p1, v1, p2, v2);
|
|
glMultMatrixf(transform.f);
|
|
DrawRoom(level, r);
|
|
glPopMatrix();
|
|
}
|
|
else if(room.gateinfo[i].state == STATE_CLOSING) {
|
|
t1 = room.gates[i].walls[0];
|
|
t2 = room.gates[i].walls[1];
|
|
|
|
t1.vertices[2] = VectorAdd(VectorMul(t1.vertices[2], 1 - (room.gateinfo[i].timer/1000.0)),
|
|
VectorMul(t1.vertices[1], room.gateinfo[i].timer/1000.0));
|
|
t2.vertices[1] = t1.vertices[2];
|
|
t2.vertices[2] = VectorAdd(VectorMul(t2.vertices[2], 1 - (room.gateinfo[i].timer/1000.0)),
|
|
VectorMul(t2.vertices[0], room.gateinfo[i].timer/1000.0));
|
|
|
|
|
|
t1.texcoords[0].s = t1.texcoords[0].s * (1 - room.gateinfo[i].timer/1000.0)
|
|
+ t2.texcoords[2].s * room.gateinfo[i].timer/1000.0;
|
|
t1.texcoords[0].t = t1.texcoords[0].t * (1 - room.gateinfo[i].timer/1000.0)
|
|
+ t2.texcoords[2].t * room.gateinfo[i].timer/1000.0;
|
|
t1.texcoords[1].s = t1.texcoords[1].s * (1 - room.gateinfo[i].timer/1000.0)
|
|
+ t1.texcoords[2].s * room.gateinfo[i].timer/1000.0;
|
|
t1.texcoords[1].t = t1.texcoords[1].t * (1 - room.gateinfo[i].timer/1000.0)
|
|
+ t1.texcoords[2].t * room.gateinfo[i].timer/1000.0;
|
|
t2.texcoords[0] = t1.texcoords[0];
|
|
|
|
//glBindTexture(GL_TEXTURE_2D, level->textures[t1.texture]);
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
|
|
glNormal3fv((GLfloat*)&t1.normal);
|
|
glTexCoord2fv((GLfloat*)&t1.texcoords[0]);
|
|
glVertex3fv((GLfloat*)&t1.vertices[0]);
|
|
glTexCoord2fv((GLfloat*)&t1.texcoords[1]);
|
|
glVertex3fv((GLfloat*)&t1.vertices[1]);
|
|
glTexCoord2fv((GLfloat*)&t1.texcoords[2]);
|
|
glVertex3fv((GLfloat*)&t1.vertices[2]);
|
|
|
|
glEnd();
|
|
|
|
//glBindTexture(GL_TEXTURE_2D, level->textures[t2.texture]);
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
|
|
glNormal3fv((GLfloat*)&t2.normal);
|
|
glTexCoord2fv((GLfloat*)&t2.texcoords[0]);
|
|
glVertex3fv((GLfloat*)&t2.vertices[0]);
|
|
glTexCoord2fv((GLfloat*)&t2.texcoords[1]);
|
|
glVertex3fv((GLfloat*)&t2.vertices[1]);
|
|
glTexCoord2fv((GLfloat*)&t2.texcoords[2]);
|
|
glVertex3fv((GLfloat*)&t2.vertices[2]);
|
|
|
|
glEnd();
|
|
|
|
r = room.gates[i].room;
|
|
g = room.gates[i].gate;
|
|
|
|
t1 = room.gates[i].walls[0];
|
|
t2 = room.gates[i].walls[1];
|
|
p1 = room.gates[i].point;
|
|
v1 = t1.normal;
|
|
|
|
t1 = level->rooms[r].gates[g].walls[0];
|
|
t2 = level->rooms[r].gates[g].walls[1];
|
|
p2 = level->rooms[r].gates[g].point;
|
|
v2 = VectorNeg(t1.normal);
|
|
|
|
glPushMatrix();
|
|
transform = VectorMatrix(p1, v1, p2, v2);
|
|
glMultMatrixf(transform.f);
|
|
DrawRoom(level, r);
|
|
glPopMatrix();
|
|
}
|
|
else {
|
|
r = room.gates[i].room;
|
|
g = room.gates[i].gate;
|
|
|
|
t1 = room.gates[i].walls[0];
|
|
t2 = room.gates[i].walls[1];
|
|
p1 = room.gates[i].point;
|
|
v1 = t1.normal;
|
|
|
|
t1 = level->rooms[r].gates[g].walls[0];
|
|
t2 = level->rooms[r].gates[g].walls[1];
|
|
p2 = level->rooms[r].gates[g].point;
|
|
v2 = VectorNeg(t1.normal);
|
|
|
|
glPushMatrix();
|
|
transform = VectorMatrix(p1, v1, p2, v2);
|
|
glMultMatrixf(transform.f);
|
|
DrawRoom(level, r);
|
|
glPopMatrix();
|
|
}
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|