#include #include #include #include #include #include #include extern GLuint sphere; extern GLuint meditex_blue; extern float objrot; 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].nObjects = roomheader.nObjects; level->rooms[i].objects = malloc(roomheader.nObjects * sizeof(OBJECT)); fread(level->rooms[i].objects, sizeof(OBJECT), roomheader.nObjects, 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 room) { 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}; WALL t1, t2; VERTEX p1, p2; VECTOR v1, v2; MATRIX transform; for(i = 0; i < level->rooms[room].nWalls; i++) { glBindTexture(GL_TEXTURE_2D, level->textures[level->rooms[room].walls[i].texture]); glBegin(GL_TRIANGLES); glNormal3fv((GLfloat*)&level->rooms[room].walls[i].normal); glTexCoord2fv((GLfloat*)&level->rooms[room].walls[i].texcoords[0]); glVertex3fv((GLfloat*)&level->rooms[room].walls[i].vertices[0]); glTexCoord2fv((GLfloat*)&level->rooms[room].walls[i].texcoords[1]); glVertex3fv((GLfloat*)&level->rooms[room].walls[i].vertices[1]); glTexCoord2fv((GLfloat*)&level->rooms[room].walls[i].texcoords[2]); glVertex3fv((GLfloat*)&level->rooms[room].walls[i].vertices[2]); glEnd(); } for(i = 0; i < level->rooms[room].nObjects; i++) { if(!level->rooms[room].objects[i].visible) continue; switch(level->rooms[room].objects[i].type) { case OBJECT_MEDIPAK100: glPushMatrix(); glBindTexture(GL_TEXTURE_2D, meditex_blue); glMaterialfv(GL_FRONT, GL_EMISSION, medipak100_emission); glTranslatef(level->rooms[room].objects[i].pos.x, level->rooms[room].objects[i].pos.y, level->rooms[room].objects[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 < level->rooms[room].nGates; i++) { if(level->rooms[room].gateinfo[i].state == STATE_CLOSED) { glBindTexture(GL_TEXTURE_2D, level->textures[level->rooms[room].gates[i].walls[0].texture]); glBegin(GL_TRIANGLES); glNormal3fv((GLfloat*)&level->rooms[room].gates[i].walls[0].normal); glTexCoord2fv((GLfloat*)&level->rooms[room].gates[i].walls[0].texcoords[0]); glVertex3fv((GLfloat*)&level->rooms[room].gates[i].walls[0].vertices[0]); glTexCoord2fv((GLfloat*)&level->rooms[room].gates[i].walls[0].texcoords[1]); glVertex3fv((GLfloat*)&level->rooms[room].gates[i].walls[0].vertices[1]); glTexCoord2fv((GLfloat*)&level->rooms[room].gates[i].walls[0].texcoords[2]); glVertex3fv((GLfloat*)&level->rooms[room].gates[i].walls[0].vertices[2]); glEnd(); glBindTexture(GL_TEXTURE_2D, level->textures[level->rooms[room].gates[i].walls[0].texture]); glBegin(GL_TRIANGLES); glNormal3fv((GLfloat*)&level->rooms[room].gates[i].walls[1].normal); glTexCoord2fv((GLfloat*)&level->rooms[room].gates[i].walls[1].texcoords[0]); glVertex3fv((GLfloat*)&level->rooms[room].gates[i].walls[1].vertices[0]); glTexCoord2fv((GLfloat*)&level->rooms[room].gates[i].walls[1].texcoords[1]); glVertex3fv((GLfloat*)&level->rooms[room].gates[i].walls[1].vertices[1]); glTexCoord2fv((GLfloat*)&level->rooms[room].gates[i].walls[1].texcoords[2]); glVertex3fv((GLfloat*)&level->rooms[room].gates[i].walls[1].vertices[2]); glEnd(); } else if(level->rooms[room].gateinfo[i].state == STATE_OPENING) { t1 = level->rooms[room].gates[i].walls[0]; t2 = level->rooms[room].gates[i].walls[1]; t1.vertices[2] = VectorAdd(VectorMul(t1.vertices[2], level->rooms[room].gateinfo[i].timer/1000.0), VectorMul(t1.vertices[1], 1 - (level->rooms[room].gateinfo[i].timer/1000.0))); t2.vertices[1] = t1.vertices[2]; t2.vertices[2] = VectorAdd(VectorMul(t2.vertices[2], level->rooms[room].gateinfo[i].timer/1000.0), VectorMul(t2.vertices[0], 1 - (level->rooms[room].gateinfo[i].timer/1000.0))); t1.texcoords[0].s = t1.texcoords[0].s * level->rooms[room].gateinfo[i].timer/1000.0 + t2.texcoords[2].s * (1 - level->rooms[room].gateinfo[i].timer/1000.0); t1.texcoords[0].t = t1.texcoords[0].t * level->rooms[room].gateinfo[i].timer/1000.0 + t2.texcoords[2].t * (1 - level->rooms[room].gateinfo[i].timer/1000.0); t1.texcoords[1].s = t1.texcoords[1].s * level->rooms[room].gateinfo[i].timer/1000.0 + t1.texcoords[2].s * (1 - level->rooms[room].gateinfo[i].timer/1000.0); t1.texcoords[1].t = t1.texcoords[1].t * level->rooms[room].gateinfo[i].timer/1000.0 + t1.texcoords[2].t * (1 - level->rooms[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 = level->rooms[room].gates[i].room; g = level->rooms[room].gates[i].gate; t1 = level->rooms[room].gates[i].walls[0]; t2 = level->rooms[room].gates[i].walls[1]; p1 = level->rooms[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(level->rooms[room].gateinfo[i].state == STATE_CLOSING) { t1 = level->rooms[room].gates[i].walls[0]; t2 = level->rooms[room].gates[i].walls[1]; t1.vertices[2] = VectorAdd(VectorMul(t1.vertices[2], 1 - (level->rooms[room].gateinfo[i].timer/1000.0)), VectorMul(t1.vertices[1], level->rooms[room].gateinfo[i].timer/1000.0)); t2.vertices[1] = t1.vertices[2]; t2.vertices[2] = VectorAdd(VectorMul(t2.vertices[2], 1 - (level->rooms[room].gateinfo[i].timer/1000.0)), VectorMul(t2.vertices[0], level->rooms[room].gateinfo[i].timer/1000.0)); t1.texcoords[0].s = t1.texcoords[0].s * (1 - level->rooms[room].gateinfo[i].timer/1000.0) + t2.texcoords[2].s * level->rooms[room].gateinfo[i].timer/1000.0; t1.texcoords[0].t = t1.texcoords[0].t * (1 - level->rooms[room].gateinfo[i].timer/1000.0) + t2.texcoords[2].t * level->rooms[room].gateinfo[i].timer/1000.0; t1.texcoords[1].s = t1.texcoords[1].s * (1 - level->rooms[room].gateinfo[i].timer/1000.0) + t1.texcoords[2].s * level->rooms[room].gateinfo[i].timer/1000.0; t1.texcoords[1].t = t1.texcoords[1].t * (1 - level->rooms[room].gateinfo[i].timer/1000.0) + t1.texcoords[2].t * level->rooms[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 = level->rooms[room].gates[i].room; g = level->rooms[room].gates[i].gate; t1 = level->rooms[room].gates[i].walls[0]; t2 = level->rooms[room].gates[i].walls[1]; p1 = level->rooms[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 = level->rooms[room].gates[i].room; g = level->rooms[room].gates[i].gate; t1 = level->rooms[room].gates[i].walls[0]; t2 = level->rooms[room].gates[i].walls[1]; p1 = level->rooms[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].nObjects) free(level->rooms[i].objects); if(level->rooms[i].nGates) free(level->rooms[i].gates); } free(level->rooms); } }