From 3a7ea8d4b38ce5ad4ccea620c0c3106083ab156f Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Wed, 18 Jan 2023 11:30:32 +0100 Subject: [PATCH] Debugging work: - Load map data using a macro, so I can easily change the implementation for all data chunks. - Implemented a visdata function that loads all 1's, so that every leaf will be drawn. - Point-to-plane distance now uses copies of input vectors. May or may not be faster. - Fixed fps counter rounding and disabled vsync so we can see the true framerate --- display.c | 2 +- main.c | 18 +++++++++--------- qmath.h | 9 +++++---- world.c | 54 +++++++++++++++++++++++++++++------------------------- 4 files changed, 44 insertions(+), 39 deletions(-) diff --git a/display.c b/display.c index 667ee74..7253dc0 100644 --- a/display.c +++ b/display.c @@ -178,7 +178,7 @@ void display_finish() // Wait for vertical sync to cap the logic to 60fps (or 50 in PAL mode) // and prevent screen tearing - VSync(0); + //VSync(0); // Switch pages PutDispEnv(&disp[db]); diff --git a/main.c b/main.c index efa91eb..22f0eb4 100644 --- a/main.c +++ b/main.c @@ -25,13 +25,13 @@ world_t world; // Init function void init(void) { - input_init(); // Works - display_init(); // Works - time_init(); // Works + input_init(); + display_init(); + time_init(); //asset_loadTexture(tim_e1m1, NULL); - world_load(bsp_test, &world); // Works + world_load(bsp_test, &world); } // Main function, program entrypoint @@ -43,20 +43,20 @@ int main(int argc, const char *argv[]) // Main loop while(1) { - input_process(); // Works + input_process(); - display_start(); // Works + display_start(); - FntPrint(-1, "Time: %d, ticks: %d, delta time: %d, fps: %d\n", (time_getRealTime() * 1000) >> 12, time_getFrameNumber(), time_getDeltaTime(), time_getFrameRate() >> 8); + FntPrint(-1, "Time: %d, frame: %d, delta time: %3d, fps: %d\n", (time_getRealTime() * 1000) >> 12, time_getFrameNumber(), time_getDeltaTime(), (time_getFrameRate() + 128) >> 8); FntPrint(-1, "Camera pos: (%d, %d, %d) rot: (%d, %d, %d) leaf: %d\n", cam_pos.vx, cam_pos.vy, cam_pos.vz, cam_rot.vx, cam_rot.vy, cam_rot.vz, cam_leaf); // Draw stuff - world_draw(&world); // Doesn't work >:( + world_draw(&world); FntPrint(-1, "Polycount: %d\n", polyCount); FntFlush(-1); - display_finish(); // Works + display_finish(); time_tick(); } diff --git a/qmath.h b/qmath.h index d004af8..24176f5 100644 --- a/qmath.h +++ b/qmath.h @@ -8,11 +8,12 @@ INLINE short m_dot12(const SVECTOR *a, const SVECTOR *b) return ((a->vx * b->vx) >> 12) + ((a->vy * b->vy) >> 12) + ((a->vz * b->vz) >> 12); } -INLINE short m_pointPlaneDist2(const VECTOR *point2, const SVECTOR *normal12, short dist2) +// TODO: worth a benchmark: is it faster to copy these vectors and use them from the stack, or to do six pointer dereferences? +INLINE short m_pointPlaneDist2(const VECTOR point2, const SVECTOR normal12, short dist2) { - int x = ((int)point2->vx * normal12->vx) >> 12; - int y = ((int)point2->vy * normal12->vy) >> 12; - int z = ((int)point2->vz * normal12->vz) >> 12; + int x = ((int)point2.vx * normal12.vx) >> 12; + int y = ((int)point2.vy * normal12.vy) >> 12; + int z = ((int)point2.vz * normal12.vz) >> 12; return (short)(x + y + z - dist2); } diff --git a/world.c b/world.c index 79d214e..06ef638 100644 --- a/world.c +++ b/world.c @@ -22,35 +22,24 @@ static CVECTOR colors[] = }; static const int numColors = sizeof(colors) / sizeof(CVECTOR); +#define LOAD_CHUNK(type, dst, num, src, entry) \ + dst = (type*)((src) + (entry).offset); \ + num = (entry).size / sizeof(type); + void world_load(const u_long *data, world_t *world) { const char *bytes = (const char*)data; ps1bsp_header_t* header = (ps1bsp_header_t*)bytes; - world->vertices = (ps1bsp_vertex_t*)(bytes + header->vertices.offset); - world->numVertices = header->vertices.size / sizeof(ps1bsp_vertex_t); - - world->faces = (ps1bsp_face_t*)(bytes + header->faces.offset); - world->numFaces = header->faces.size / sizeof(ps1bsp_face_t); - - 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); - - world->visData = (u_char*)(bytes + header->visData.offset); - world->numVisData = header->visData.size / sizeof(u_char); + LOAD_CHUNK(ps1bsp_vertex_t, world->vertices, world->numVertices, bytes, header->vertices); + LOAD_CHUNK(ps1bsp_face_t, world->faces, world->numFaces, bytes, header->faces); + LOAD_CHUNK(ps1bsp_facevertex_t, world->faceVertices, world->numFaceVertices, bytes, header->faceVertices); + LOAD_CHUNK(ps1bsp_plane_t, world->planes, world->numPlanes, bytes, header->planes); + LOAD_CHUNK(ps1bsp_node_t, world->nodes, world->numNodes, bytes, header->nodes); + LOAD_CHUNK(ps1bsp_leaf_t, world->leaves, world->numLeaves, bytes, header->leaves); + LOAD_CHUNK(u_short, world->leafFaces, world->numLeafFaces, bytes, header->leafFaces); + LOAD_CHUNK(u_char, world->visData, world->numVisData, bytes, header->visData); } static INLINE void drawface_triangle_fan(const ps1bsp_face_t *face, SVECTOR *vecs) @@ -292,7 +281,7 @@ static void world_drawnode(const world_t *world, short nodeIdx, u_char *pvs, u_c // } const ps1bsp_plane_t *plane = &world->planes[node->planeId]; - short dist = m_pointPlaneDist2(&cam_pos, &plane->normal, plane->dist); + short dist = m_pointPlaneDist2(cam_pos, plane->normal, plane->dist); // Draw child nodes in front-to-back order; adding faces to the OT will reverse the drawing order if (dist > 0) @@ -339,6 +328,20 @@ static u_char *world_loadVisData(const world_t *world, u_short leafIdx, u_char * return head; } +static u_char *world_noVisData(const world_t *world, u_char **scratchptr) +{ + u_char *head = *scratchptr; + u_char *tail = head; + + for (int l = 1; l < world->numLeaves; l += 8) + { + *tail++ = 0xFF; + } + + *scratchptr = tail; + return head; +} + static u_short world_leafAtPoint(const world_t *world, const VECTOR *point) { short nodeIdx = 0; @@ -348,7 +351,7 @@ static u_short world_leafAtPoint(const world_t *world, const VECTOR *point) const ps1bsp_plane_t *plane = &world->planes[node->planeId]; // TODO: can be optimized for axis-aligned planes, no need for a dot product there - short dist = m_pointPlaneDist2(point, &plane->normal, plane->dist); + short dist = m_pointPlaneDist2(*point, plane->normal, plane->dist); nodeIdx = dist > 0 ? node->front : node->back; // TODO: this can be done branchless with (dist < 0)^1 } @@ -368,6 +371,7 @@ void world_draw(const world_t *world) u_char *scratchptr = scratchpad_root; u_char *pvs = world_loadVisData(world, cam_leaf, &scratchptr); + //u_char *pvs = world_noVisData(world, &scratchptr); world_drawnode(world, 0, pvs, scratchptr); }