|
|
|
@ -1,6 +1,7 @@ |
|
|
|
#include "common.h" |
|
|
|
#include "world.h" |
|
|
|
#include "display.h" |
|
|
|
#include "time.h" |
|
|
|
|
|
|
|
#include <inline_c.h> |
|
|
|
|
|
|
|
@ -35,6 +36,18 @@ void world_load(const u_long *data, world_t *world) |
|
|
|
|
|
|
|
world->faceVertices = (ps1bsp_facevertex_t*)(bytes + header->faceVertices.offset); |
|
|
|
world->numFaceVertices = header->faceVertices.size / sizeof(ps1bsp_facevertex_t); |
|
|
|
|
|
|
|
world->planes = (ps1bsp_plane_t*)(bytes + header->planes.offset); |
|
|
|
world->numPlanes = header->planes.size / sizeof(ps1bsp_plane_t); |
|
|
|
|
|
|
|
world->nodes = (ps1bsp_node_t*)(bytes + header->nodes.offset); |
|
|
|
world->numNodes = header->nodes.size / sizeof(ps1bsp_node_t); |
|
|
|
|
|
|
|
world->leaves = (ps1bsp_leaf_t*)(bytes + header->leaves.offset); |
|
|
|
world->numLeaves = header->leaves.size / sizeof(ps1bsp_leaf_t); |
|
|
|
|
|
|
|
world->leafFaces = (u_short*)(bytes + header->leafFaces.offset); |
|
|
|
world->numLeafFaces = header->leafFaces.size / sizeof(u_short); |
|
|
|
} |
|
|
|
|
|
|
|
static INLINE void drawface_triangle_fan(const ps1bsp_face_t *face, SVECTOR *vecs) |
|
|
|
@ -209,6 +222,27 @@ static INLINE void drawface_quad_strip(const ps1bsp_face_t *face, SVECTOR *vecs) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void world_drawface(const world_t *world, const ps1bsp_face_t *face, char *scratchptr) |
|
|
|
{ |
|
|
|
const CVECTOR *col = &colors[(u_long)face % numColors]; |
|
|
|
|
|
|
|
SVECTOR *vecs = (SVECTOR*)mem_scratch(&scratchptr, sizeof(SVECTOR) * face->numFaceVertices); |
|
|
|
|
|
|
|
// Copy this face's vertices into scratch RAM for fast reuse |
|
|
|
ps1bsp_facevertex_t *faceVertex = &world->faceVertices[face->firstFaceVertex]; |
|
|
|
for (int vertIdx = 0; vertIdx < face->numFaceVertices; ++vertIdx, ++faceVertex) |
|
|
|
{ |
|
|
|
const ps1bsp_vertex_t *vert = &world->vertices[faceVertex->index]; |
|
|
|
vecs[vertIdx] = *((SVECTOR*)vert); |
|
|
|
vecs[vertIdx].pad = vert->baseLight; |
|
|
|
} |
|
|
|
|
|
|
|
if (face->numFaceVertices == 3) |
|
|
|
drawface_triangle_fan(face, vecs); |
|
|
|
else |
|
|
|
drawface_quad_strip(face, vecs); |
|
|
|
} |
|
|
|
|
|
|
|
void world_draw(const world_t *world) |
|
|
|
{ |
|
|
|
int p; |
|
|
|
@ -217,26 +251,22 @@ void world_draw(const world_t *world) |
|
|
|
gte_SetRotMatrix(&vp_matrix); |
|
|
|
gte_SetTransMatrix(&vp_matrix); |
|
|
|
|
|
|
|
for (int faceIdx = 0; faceIdx < world->numFaces; ++faceIdx) |
|
|
|
u_long frameNum = time_getFrameNumber(); |
|
|
|
|
|
|
|
const ps1bsp_leaf_t *leaf = &world->leaves[0]; |
|
|
|
for (u_short leafIdx = 0; leafIdx < world->numLeaves; ++leafIdx, ++leaf) |
|
|
|
{ |
|
|
|
const ps1bsp_face_t *face = &world->faces[faceIdx]; |
|
|
|
const CVECTOR *col = &colors[faceIdx % numColors]; |
|
|
|
u_short *leafFace = &world->leafFaces[leaf->firstLeafFace]; |
|
|
|
for (u_short leafFaceIdx = 0; leafFaceIdx < leaf->numLeafFaces; ++leafFaceIdx, ++leafFace) |
|
|
|
{ |
|
|
|
ps1bsp_face_t *face = &world->faces[*leafFace]; |
|
|
|
|
|
|
|
char *scratch = scratchpad; |
|
|
|
SVECTOR *vecs = (SVECTOR*)mem_scratch(&scratch, sizeof(SVECTOR) * face->numFaceVertices); |
|
|
|
// Check if we've already drawn this face |
|
|
|
if (face->drawFrame == frameNum) |
|
|
|
continue; |
|
|
|
|
|
|
|
// Copy this face's vertices into scratch RAM for fast reuse |
|
|
|
ps1bsp_facevertex_t *faceVertex = &world->faceVertices[face->firstFaceVertex]; |
|
|
|
for (int vertIdx = 0; vertIdx < face->numFaceVertices; ++vertIdx, ++faceVertex) |
|
|
|
{ |
|
|
|
const ps1bsp_vertex_t *vert = &world->vertices[faceVertex->index]; |
|
|
|
vecs[vertIdx] = *((SVECTOR*)vert); |
|
|
|
vecs[vertIdx].pad = vert->baseLight; |
|
|
|
world_drawface(world, face, scratchpad); |
|
|
|
face->drawFrame = frameNum; |
|
|
|
} |
|
|
|
|
|
|
|
if (face->numFaceVertices == 3) |
|
|
|
drawface_triangle_strip(face, vecs); |
|
|
|
else |
|
|
|
drawface_quad_strip(face, vecs); |
|
|
|
} |
|
|
|
} |