From 0eece3001f685ff9acc0f21b32de2769243dd4ed Mon Sep 17 00:00:00 2001 From: MysterD Date: Wed, 27 Apr 2022 18:41:05 -0700 Subject: [PATCH] WIP: uncapped framerate 4 --- src/game/envfx_bubbles.c | 2 +- src/game/rendering_graph_node.c | 88 ++++++++++++++++++++++----------- src/game/skybox.c | 43 +++++++++++++--- src/pc/pc_main.c | 14 ++++-- 4 files changed, 105 insertions(+), 42 deletions(-) diff --git a/src/game/envfx_bubbles.c b/src/game/envfx_bubbles.c index e2245b45..0bfd74f7 100644 --- a/src/game/envfx_bubbles.c +++ b/src/game/envfx_bubbles.c @@ -445,10 +445,10 @@ void append_bubble_vertex_buffer(Gfx *gfx, s32 index, Vec3s vertex1, Vec3s verte for (i = 0; i < 15; i += 3) { vertBuf[i] = template[0]; + s32 xPos; s32 yPos; s32 zPos; - s32 particleIndex = (index + i / 3); struct EnvFxParticle* particle = (gEnvFxBuffer + particleIndex); diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index d7438c5a..33e042e6 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -149,6 +149,12 @@ static Gfx* sViewportClipPos = NULL; static Vp sViewportPrev = { 0 }; static Vp sViewportInterp = { 0 }; +static struct GraphNodeBackground* sBackgroundNode; +Gfx* gBackgroundSkyboxGfx = NULL; +Vtx* gBackgroundSkyboxVerts[3][3] = { 0 }; +Mtx* gBackgroundSkyboxMtx = NULL; +struct GraphNodeRoot* sBackgroundNodeRoot = NULL; + struct { Gfx *pos; void *mtx; @@ -161,7 +167,31 @@ s32 gMtxTblSize; struct Object* gCurGraphNodeProcessingObject = NULL; struct MarioState* gCurGraphNodeMarioState = NULL; -void mtx_patch_interpolated(f32 delta) { +void patch_mtx_before(void) { + gMtxTblSize = 0; + + if (sPerspectiveNode != NULL) { + sPerspectiveNode->prevFov = sPerspectiveNode->fov; + sPerspectiveNode = NULL; + } + + if (sViewport != NULL) { + sViewportPrev = *sViewport; + sViewport = NULL; + sViewportPos = NULL; + sViewportClipPos = NULL; + } + + if (sBackgroundNode != NULL) { + vec3f_copy(sBackgroundNode->prevCameraPos, gLakituState.pos); + vec3f_copy(sBackgroundNode->prevCameraFocus, gLakituState.focus); + sBackgroundNode->prevCameraTimestamp = gGlobalTimer; + sBackgroundNode = NULL; + gBackgroundSkyboxGfx = NULL; + } +} + +void patch_mtx_interpolated(f32 delta) { if (sPerspectiveNode != NULL) { u16 perspNorm; f32 fovInterpolated = delta_interpolate_f32(sPerspectiveNode->prevFov, sPerspectiveNode->fov, delta); @@ -182,6 +212,26 @@ void mtx_patch_interpolated(f32 delta) { gDisplayListHead = saved; } + if (sBackgroundNode != NULL) { + Vec3f posCopy; + Vec3f focusCopy; + struct GraphNodeRoot* rootCopy = gCurGraphNodeRoot; + + gCurGraphNodeRoot = sBackgroundNodeRoot; + vec3f_copy(posCopy, gLakituState.pos); + vec3f_copy(focusCopy, gLakituState.focus); + /*if (gGlobalTimer == sBackgroundNode->prevCameraTimestamp + 1 && + gGlobalTimer != gLakituState.skipCameraInterpolationTimestamp) {*/ + delta_interpolate_vec3f(gLakituState.pos, sBackgroundNode->prevCameraPos, posCopy, delta); + delta_interpolate_vec3f(gLakituState.focus, sBackgroundNode->prevCameraFocus, focusCopy, delta); + //} + /*list = */sBackgroundNode->fnNode.func(GEO_CONTEXT_RENDER, &sBackgroundNode->fnNode.node, NULL); + + vec3f_copy(gLakituState.pos, posCopy); + vec3f_copy(gLakituState.focus, focusCopy); + gCurGraphNodeRoot = rootCopy; + } + for (s32 i = 0; i < gMtxTblSize; i++) { Gfx *pos = gMtxTbl[i].pos; delta_interpolate_mtx(&gMtxTbl[i].interp, (Mtx*) gMtxTbl[i].mtxPrev, (Mtx*) gMtxTbl[i].mtx, delta); @@ -193,22 +243,6 @@ void mtx_patch_interpolated(f32 delta) { } } -void mtx_patch_before(void) { - gMtxTblSize = 0; - - if (sPerspectiveNode != NULL) { - sPerspectiveNode->prevFov = sPerspectiveNode->fov; - sPerspectiveNode = NULL; - } - - if (sViewport != NULL) { - sViewportPrev = *sViewport; - sViewport = NULL; - sViewportPos = NULL; - sViewportClipPos = NULL; - } -} - /** * Increments the matrix stack index and sets the matrixs at the new index. */ @@ -661,33 +695,27 @@ static void geo_process_generated_list(struct GraphNodeGenerated *node) { */ static void geo_process_background(struct GraphNodeBackground *node) { Gfx *list = NULL; - Gfx *listPrev = NULL; if (node->fnNode.func != NULL) { Vec3f posCopy; Vec3f focusCopy; - list = node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, - (struct AllocOnlyPool *) gMatStack[gMatStackIndex]); - vec3f_copy(posCopy, gLakituState.pos); vec3f_copy(focusCopy, gLakituState.focus); - if (gGlobalTimer == node->prevCameraTimestamp + 1 && - gGlobalTimer != gLakituState.skipCameraInterpolationTimestamp) { + /*if (gGlobalTimer == node->prevCameraTimestamp + 1 && + gGlobalTimer != gLakituState.skipCameraInterpolationTimestamp) {*/ vec3f_copy(gLakituState.pos, node->prevCameraPos); vec3f_copy(gLakituState.focus, node->prevCameraFocus); - } - listPrev = node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, NULL); + sBackgroundNode = node; + sBackgroundNodeRoot = gCurGraphNodeRoot; + //} + list = node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, NULL); vec3f_copy(gLakituState.pos, posCopy); vec3f_copy(gLakituState.focus, focusCopy); - - vec3f_copy(node->prevCameraPos, gLakituState.pos); - vec3f_copy(node->prevCameraFocus, gLakituState.focus); - node->prevCameraTimestamp = gGlobalTimer; } if (list != NULL) { - geo_append_display_list2((void *) VIRTUAL_TO_PHYSICAL(list), (void *) VIRTUAL_TO_PHYSICAL(listPrev), node->fnNode.node.flags >> 8); + geo_append_display_list2((void *) VIRTUAL_TO_PHYSICAL(list), (void *) VIRTUAL_TO_PHYSICAL(list), node->fnNode.node.flags >> 8); } else if (gCurGraphNodeMasterList != NULL) { #ifndef F3DEX_GBI_2E Gfx *gfxStart = alloc_display_list(sizeof(Gfx) * 7); diff --git a/src/game/skybox.c b/src/game/skybox.c index 750d6f0b..88620750 100644 --- a/src/game/skybox.c +++ b/src/game/skybox.c @@ -62,6 +62,8 @@ struct Skybox sSkyBoxInfo[2]; typedef const Texture *const SkyboxTexture[80]; +extern u8 gRenderingInterpolated; + extern SkyboxTexture bbh_skybox_ptrlist; extern SkyboxTexture bidw_skybox_ptrlist; extern SkyboxTexture bitfs_skybox_ptrlist; @@ -191,10 +193,19 @@ static s32 get_top_left_tile_idx(s8 player) { * into an x and y by modulus and division by SKYBOX_COLS. x and y are then scaled by * SKYBOX_TILE_WIDTH to get a point in world space. */ -Vtx *make_skybox_rect(s32 tileIndex, s8 colorIndex) { - Vtx *verts = alloc_display_list(4 * sizeof(*verts)); - s16 x = tileIndex % SKYBOX_COLS * SKYBOX_TILE_WIDTH; - s16 y = SKYBOX_HEIGHT - tileIndex / SKYBOX_COLS * SKYBOX_TILE_HEIGHT; +Vtx *make_skybox_rect(s32 tileIndex, s8 colorIndex, s32 row, s32 col, s8 player) { + extern Vtx* gBackgroundSkyboxVerts[3][3]; + + Vtx *verts; + if (gRenderingInterpolated) { + verts = gBackgroundSkyboxVerts[row][col]; + } else { + verts = alloc_display_list(4 * sizeof(*verts)); + gBackgroundSkyboxVerts[row][col] = verts; + } + + f32 x = tileIndex % SKYBOX_COLS * SKYBOX_TILE_WIDTH; + f32 y = SKYBOX_HEIGHT - tileIndex / SKYBOX_COLS * SKYBOX_TILE_HEIGHT; if (verts != NULL) { make_vertex(verts, 0, x, y, -1, 0, 0, sSkyboxColors[colorIndex][0], sSkyboxColors[colorIndex][1], @@ -231,7 +242,7 @@ void draw_skybox_tile_grid(Gfx **dlist, s8 background, s8 player, s8 colorIndex) texture = (Texture*)(*(SkyboxTexture *) segmented_to_virtual(sSkyboxTextures[background]))[tileIndex]; } - Vtx *vertices = make_skybox_rect(tileIndex, colorIndex); + Vtx *vertices = make_skybox_rect(tileIndex, colorIndex, row, col, player); gLoadBlockTexture((*dlist)++, 32, 32, G_IM_FMT_RGBA, texture); gSPVertex((*dlist)++, VIRTUAL_TO_PHYSICAL(vertices), 4, 0); @@ -245,7 +256,15 @@ void *create_skybox_ortho_matrix(s8 player) { f32 right = sSkyBoxInfo[player].scaledX + SCREEN_WIDTH; f32 bottom = sSkyBoxInfo[player].scaledY - SCREEN_HEIGHT; f32 top = sSkyBoxInfo[player].scaledY; - Mtx *mtx = alloc_display_list(sizeof(*mtx)); + + extern Mtx* gBackgroundSkyboxMtx; + Mtx *mtx; + if (gRenderingInterpolated) { + mtx = gBackgroundSkyboxMtx; + } else { + mtx = alloc_display_list(sizeof(*mtx)); + gBackgroundSkyboxMtx = mtx; + } f32 half_width = (4.0f / 3.0f) / GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_WIDTH / 2; f32 center = (sSkyBoxInfo[player].scaledX + SCREEN_WIDTH / 2); @@ -267,8 +286,18 @@ void *create_skybox_ortho_matrix(s8 player) { * Creates the skybox's display list, then draws the 3x3 grid of tiles. */ Gfx *init_skybox_display_list(s8 player, s8 background, s8 colorIndex) { + extern Gfx* gBackgroundSkyboxGfx; + s32 dlCommandCount = 5 + (3 * 3) * 7; // 5 for the start and end, plus 9 skybox tiles - void *skybox = alloc_display_list(dlCommandCount * sizeof(Gfx)); + + void *skybox; + if (gRenderingInterpolated) { + skybox = gBackgroundSkyboxGfx; + } else { + skybox = alloc_display_list(dlCommandCount * sizeof(Gfx)); + gBackgroundSkyboxGfx = (Gfx*)skybox; + } + Gfx *dlist = skybox; if (skybox == NULL) { diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index 94e95d7c..bca22f4c 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -64,7 +64,9 @@ s8 gShowDebugText; s32 gRumblePakPfs; u32 gNumVblanks = 0; +u8 gRenderingInterpolated = 0; f32 gRenderingDelta = 0; + f32 gGameSpeed = 1.0f; // DO NOT COMMIT static struct AudioAPI *audio_api; @@ -99,7 +101,7 @@ void send_display_list(struct SPTask *spTask) { #endif static void patch_interpolations_before(void) { - extern void mtx_patch_before(void); + extern void patch_mtx_before(void); extern void patch_screen_transition_before(void); extern void patch_title_screen_before(void); extern void patch_dialog_before(void); @@ -107,7 +109,7 @@ static void patch_interpolations_before(void) { extern void patch_paintings_before(void); extern void patch_bubble_particles_before(void); extern void patch_snow_particles_before(void); - mtx_patch_before(); + patch_mtx_before(); patch_screen_transition_before(); patch_title_screen_before(); patch_dialog_before(); @@ -118,7 +120,7 @@ static void patch_interpolations_before(void) { } static inline void patch_interpolations(f32 delta) { - extern void mtx_patch_interpolated(f32 delta); + extern void patch_mtx_interpolated(f32 delta); extern void patch_screen_transition_interpolated(f32 delta); extern void patch_title_screen_interpolated(f32 delta); extern void patch_dialog_interpolated(f32 delta); @@ -127,7 +129,7 @@ static inline void patch_interpolations(f32 delta) { extern void patch_bubble_particles_interpolated(f32 delta); extern void patch_snow_particles_interpolated(f32 delta); extern void djui_render_patch(void); - mtx_patch_interpolated(delta); + patch_mtx_interpolated(delta); patch_screen_transition_interpolated(delta); patch_title_screen_interpolated(delta); patch_dialog_interpolated(delta); @@ -143,6 +145,8 @@ void produce_uncapped_frames(void) { static const f64 sFrameTime = (1.0 / ((double)FRAMERATE)); static f64 sFrameTargetTime = 0; + gRenderingInterpolated = true; + f64 startTime = clock_elapsed_f64(); f64 curTime = startTime; u64 frames = 0; @@ -156,6 +160,8 @@ void produce_uncapped_frames(void) { frames++; } + gRenderingInterpolated = false; + printf(">> frames %llu | %f\n", frames, gGameSpeed); fflush(stdout);