WIP: uncapped framerate 4

This commit is contained in:
MysterD 2022-04-27 18:41:05 -07:00
parent 02ab54b3ad
commit 0eece3001f
4 changed files with 105 additions and 42 deletions

View File

@ -445,10 +445,10 @@ void append_bubble_vertex_buffer(Gfx *gfx, s32 index, Vec3s vertex1, Vec3s verte
for (i = 0; i < 15; i += 3) { for (i = 0; i < 15; i += 3) {
vertBuf[i] = template[0]; vertBuf[i] = template[0];
s32 xPos; s32 xPos;
s32 yPos; s32 yPos;
s32 zPos; s32 zPos;
s32 particleIndex = (index + i / 3); s32 particleIndex = (index + i / 3);
struct EnvFxParticle* particle = (gEnvFxBuffer + particleIndex); struct EnvFxParticle* particle = (gEnvFxBuffer + particleIndex);

View File

@ -149,6 +149,12 @@ static Gfx* sViewportClipPos = NULL;
static Vp sViewportPrev = { 0 }; static Vp sViewportPrev = { 0 };
static Vp sViewportInterp = { 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 { struct {
Gfx *pos; Gfx *pos;
void *mtx; void *mtx;
@ -161,7 +167,31 @@ s32 gMtxTblSize;
struct Object* gCurGraphNodeProcessingObject = NULL; struct Object* gCurGraphNodeProcessingObject = NULL;
struct MarioState* gCurGraphNodeMarioState = 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) { if (sPerspectiveNode != NULL) {
u16 perspNorm; u16 perspNorm;
f32 fovInterpolated = delta_interpolate_f32(sPerspectiveNode->prevFov, sPerspectiveNode->fov, delta); f32 fovInterpolated = delta_interpolate_f32(sPerspectiveNode->prevFov, sPerspectiveNode->fov, delta);
@ -182,6 +212,26 @@ void mtx_patch_interpolated(f32 delta) {
gDisplayListHead = saved; 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++) { for (s32 i = 0; i < gMtxTblSize; i++) {
Gfx *pos = gMtxTbl[i].pos; Gfx *pos = gMtxTbl[i].pos;
delta_interpolate_mtx(&gMtxTbl[i].interp, (Mtx*) gMtxTbl[i].mtxPrev, (Mtx*) gMtxTbl[i].mtx, delta); 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. * 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) { static void geo_process_background(struct GraphNodeBackground *node) {
Gfx *list = NULL; Gfx *list = NULL;
Gfx *listPrev = NULL;
if (node->fnNode.func != NULL) { if (node->fnNode.func != NULL) {
Vec3f posCopy; Vec3f posCopy;
Vec3f focusCopy; Vec3f focusCopy;
list = node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node,
(struct AllocOnlyPool *) gMatStack[gMatStackIndex]);
vec3f_copy(posCopy, gLakituState.pos); vec3f_copy(posCopy, gLakituState.pos);
vec3f_copy(focusCopy, gLakituState.focus); vec3f_copy(focusCopy, gLakituState.focus);
if (gGlobalTimer == node->prevCameraTimestamp + 1 && /*if (gGlobalTimer == node->prevCameraTimestamp + 1 &&
gGlobalTimer != gLakituState.skipCameraInterpolationTimestamp) { gGlobalTimer != gLakituState.skipCameraInterpolationTimestamp) {*/
vec3f_copy(gLakituState.pos, node->prevCameraPos); vec3f_copy(gLakituState.pos, node->prevCameraPos);
vec3f_copy(gLakituState.focus, node->prevCameraFocus); vec3f_copy(gLakituState.focus, node->prevCameraFocus);
} sBackgroundNode = node;
listPrev = node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, NULL); sBackgroundNodeRoot = gCurGraphNodeRoot;
//}
list = node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, NULL);
vec3f_copy(gLakituState.pos, posCopy); vec3f_copy(gLakituState.pos, posCopy);
vec3f_copy(gLakituState.focus, focusCopy); vec3f_copy(gLakituState.focus, focusCopy);
vec3f_copy(node->prevCameraPos, gLakituState.pos);
vec3f_copy(node->prevCameraFocus, gLakituState.focus);
node->prevCameraTimestamp = gGlobalTimer;
} }
if (list != NULL) { 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) { } else if (gCurGraphNodeMasterList != NULL) {
#ifndef F3DEX_GBI_2E #ifndef F3DEX_GBI_2E
Gfx *gfxStart = alloc_display_list(sizeof(Gfx) * 7); Gfx *gfxStart = alloc_display_list(sizeof(Gfx) * 7);

View File

@ -62,6 +62,8 @@ struct Skybox sSkyBoxInfo[2];
typedef const Texture *const SkyboxTexture[80]; typedef const Texture *const SkyboxTexture[80];
extern u8 gRenderingInterpolated;
extern SkyboxTexture bbh_skybox_ptrlist; extern SkyboxTexture bbh_skybox_ptrlist;
extern SkyboxTexture bidw_skybox_ptrlist; extern SkyboxTexture bidw_skybox_ptrlist;
extern SkyboxTexture bitfs_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 * 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. * SKYBOX_TILE_WIDTH to get a point in world space.
*/ */
Vtx *make_skybox_rect(s32 tileIndex, s8 colorIndex) { Vtx *make_skybox_rect(s32 tileIndex, s8 colorIndex, s32 row, s32 col, s8 player) {
Vtx *verts = alloc_display_list(4 * sizeof(*verts)); extern Vtx* gBackgroundSkyboxVerts[3][3];
s16 x = tileIndex % SKYBOX_COLS * SKYBOX_TILE_WIDTH;
s16 y = SKYBOX_HEIGHT - tileIndex / SKYBOX_COLS * SKYBOX_TILE_HEIGHT; 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) { if (verts != NULL) {
make_vertex(verts, 0, x, y, -1, 0, 0, sSkyboxColors[colorIndex][0], sSkyboxColors[colorIndex][1], 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]; 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); gLoadBlockTexture((*dlist)++, 32, 32, G_IM_FMT_RGBA, texture);
gSPVertex((*dlist)++, VIRTUAL_TO_PHYSICAL(vertices), 4, 0); 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 right = sSkyBoxInfo[player].scaledX + SCREEN_WIDTH;
f32 bottom = sSkyBoxInfo[player].scaledY - SCREEN_HEIGHT; f32 bottom = sSkyBoxInfo[player].scaledY - SCREEN_HEIGHT;
f32 top = sSkyBoxInfo[player].scaledY; 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 half_width = (4.0f / 3.0f) / GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_WIDTH / 2;
f32 center = (sSkyBoxInfo[player].scaledX + 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. * Creates the skybox's display list, then draws the 3x3 grid of tiles.
*/ */
Gfx *init_skybox_display_list(s8 player, s8 background, s8 colorIndex) { 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 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; Gfx *dlist = skybox;
if (skybox == NULL) { if (skybox == NULL) {

View File

@ -64,7 +64,9 @@ s8 gShowDebugText;
s32 gRumblePakPfs; s32 gRumblePakPfs;
u32 gNumVblanks = 0; u32 gNumVblanks = 0;
u8 gRenderingInterpolated = 0;
f32 gRenderingDelta = 0; f32 gRenderingDelta = 0;
f32 gGameSpeed = 1.0f; // DO NOT COMMIT f32 gGameSpeed = 1.0f; // DO NOT COMMIT
static struct AudioAPI *audio_api; static struct AudioAPI *audio_api;
@ -99,7 +101,7 @@ void send_display_list(struct SPTask *spTask) {
#endif #endif
static void patch_interpolations_before(void) { 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_screen_transition_before(void);
extern void patch_title_screen_before(void); extern void patch_title_screen_before(void);
extern void patch_dialog_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_paintings_before(void);
extern void patch_bubble_particles_before(void); extern void patch_bubble_particles_before(void);
extern void patch_snow_particles_before(void); extern void patch_snow_particles_before(void);
mtx_patch_before(); patch_mtx_before();
patch_screen_transition_before(); patch_screen_transition_before();
patch_title_screen_before(); patch_title_screen_before();
patch_dialog_before(); patch_dialog_before();
@ -118,7 +120,7 @@ static void patch_interpolations_before(void) {
} }
static inline void patch_interpolations(f32 delta) { 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_screen_transition_interpolated(f32 delta);
extern void patch_title_screen_interpolated(f32 delta); extern void patch_title_screen_interpolated(f32 delta);
extern void patch_dialog_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_bubble_particles_interpolated(f32 delta);
extern void patch_snow_particles_interpolated(f32 delta); extern void patch_snow_particles_interpolated(f32 delta);
extern void djui_render_patch(void); extern void djui_render_patch(void);
mtx_patch_interpolated(delta); patch_mtx_interpolated(delta);
patch_screen_transition_interpolated(delta); patch_screen_transition_interpolated(delta);
patch_title_screen_interpolated(delta); patch_title_screen_interpolated(delta);
patch_dialog_interpolated(delta); patch_dialog_interpolated(delta);
@ -143,6 +145,8 @@ void produce_uncapped_frames(void) {
static const f64 sFrameTime = (1.0 / ((double)FRAMERATE)); static const f64 sFrameTime = (1.0 / ((double)FRAMERATE));
static f64 sFrameTargetTime = 0; static f64 sFrameTargetTime = 0;
gRenderingInterpolated = true;
f64 startTime = clock_elapsed_f64(); f64 startTime = clock_elapsed_f64();
f64 curTime = startTime; f64 curTime = startTime;
u64 frames = 0; u64 frames = 0;
@ -156,6 +160,8 @@ void produce_uncapped_frames(void) {
frames++; frames++;
} }
gRenderingInterpolated = false;
printf(">> frames %llu | %f\n", frames, gGameSpeed); printf(">> frames %llu | %f\n", frames, gGameSpeed);
fflush(stdout); fflush(stdout);