#include "common.h" #include "world.h" #include "display.h" #include static CVECTOR colors[] = { { 255, 0, 0 }, { 0, 255, 0 }, { 0, 0, 255 }, { 255, 255, 0 }, { 255, 0, 255 }, { 0, 255, 255 }, { 128, 255, 0 }, { 255, 128, 0 }, { 128, 0, 255 }, { 255, 0, 128 }, { 0, 128, 255 }, { 0, 255, 128 }, }; static const int numColors = sizeof(colors) / sizeof(CVECTOR); void world_load(const u_long *data, world_t *world) { const char *bytes = (const char*)data; world->header = (ps1bsp_header_t*)bytes; bytes += sizeof(ps1bsp_header_t); world->vertices = (ps1bsp_vertex_t*)bytes; bytes += sizeof(ps1bsp_vertex_t) * world->header->numVertices; world->triangles = (ps1bsp_triangle_t*)bytes; bytes += sizeof(ps1bsp_triangle_t) * world->header->numTriangles; world->faces = (ps1bsp_face_t*)bytes; bytes += sizeof(ps1bsp_face_t) * world->header->numFaces; } void world_draw(const world_t *world) { int p; // The world doesn't move, so we just set the camera view-projection matrix gte_SetRotMatrix(&vp_matrix); gte_SetTransMatrix(&vp_matrix); for (int faceIdx = 0; faceIdx < world->header->numFaces; ++faceIdx) { const ps1bsp_face_t *face = &world->faces[faceIdx]; const CVECTOR *col = &colors[faceIdx % numColors]; for (int triangleIdx = 0; triangleIdx < face->numTriangles; ++triangleIdx) { const ps1bsp_triangle_t *tri = &world->triangles[face->firstTriangleId + triangleIdx]; // Naively draw the triangle with GTE, nothing special or optimized about this SVECTOR *v0 = (SVECTOR*)&world->vertices[tri->vertex0]; SVECTOR *v1 = (SVECTOR*)&world->vertices[tri->vertex1]; SVECTOR *v2 = (SVECTOR*)&world->vertices[tri->vertex2]; gte_ldv3(v0, v1, v2); gte_rtpt(); // Rotation, translation, perspective projection // Normal clipping for backface culling gte_nclip(); gte_stopz(&p); if (p < 0) continue; // Average Z for depth sorting and culling gte_avsz3(); gte_stotz(&p); unsigned short depth = p >> 2; if (depth <= 0 || depth >= OTLEN) continue; // Draw a flat-shaded untextured colored triangle POLY_F3 *poly = (POLY_F3*)display_allocPrim(sizeof(POLY_F3)); if (poly == NULL) break; setPolyF3(poly); gte_stsxy3_f3(poly); poly->r0 = col->r; poly->g0 = col->g; poly->b0 = col->b; addPrim(curOT + depth, poly); } } }