mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-22 12:05:11 +00:00
WIP: uncapped framerate 5
This commit is contained in:
parent
0eece3001f
commit
6e47f226c9
4 changed files with 149 additions and 62 deletions
|
@ -155,6 +155,11 @@ Vtx* gBackgroundSkyboxVerts[3][3] = { 0 };
|
|||
Mtx* gBackgroundSkyboxMtx = NULL;
|
||||
struct GraphNodeRoot* sBackgroundNodeRoot = NULL;
|
||||
|
||||
#define MAX_SHADOW_NODES 128
|
||||
struct ShadowInterp sShadowInterp[MAX_SHADOW_NODES] = { 0 };
|
||||
struct ShadowInterp* gShadowInterpCurrent = NULL;
|
||||
static u8 sShadowInterpCount = 0;
|
||||
|
||||
struct {
|
||||
Gfx *pos;
|
||||
void *mtx;
|
||||
|
@ -189,6 +194,8 @@ void patch_mtx_before(void) {
|
|||
sBackgroundNode = NULL;
|
||||
gBackgroundSkyboxGfx = NULL;
|
||||
}
|
||||
|
||||
sShadowInterpCount = 0;
|
||||
}
|
||||
|
||||
void patch_mtx_interpolated(f32 delta) {
|
||||
|
@ -232,6 +239,20 @@ void patch_mtx_interpolated(f32 delta) {
|
|||
gCurGraphNodeRoot = rootCopy;
|
||||
}
|
||||
|
||||
struct GraphNodeObject* savedObj = gCurGraphNodeObject;
|
||||
for (s32 i = 0; i < sShadowInterpCount; i++) {
|
||||
struct ShadowInterp* interp = &sShadowInterp[i];
|
||||
gShadowInterpCurrent = interp;
|
||||
Vec3f posInterp;
|
||||
delta_interpolate_vec3f(posInterp, interp->shadowPosPrev, interp->shadowPos, delta);
|
||||
if (i == 0) {
|
||||
printf("XXX: %f <--> %f == %f\n", interp->shadowPosPrev[1], interp->shadowPos[1], posInterp[1]);
|
||||
}
|
||||
gCurGraphNodeObject = interp->obj;
|
||||
create_shadow_below_xyz(posInterp[0], posInterp[1], posInterp[2], interp->shadowScale, interp->node->shadowSolidity, interp->node->shadowType);
|
||||
}
|
||||
gCurGraphNodeObject = savedObj;
|
||||
|
||||
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);
|
||||
|
@ -241,6 +262,7 @@ void patch_mtx_interpolated(f32 delta) {
|
|||
gSPDisplayList(pos++, gMtxTbl[i].displayList);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -949,16 +971,30 @@ static void geo_process_shadow(struct GraphNodeShadow *node) {
|
|||
gCurGraphNodeObject->prevShadowPosTimestamp = gGlobalTimer;
|
||||
}
|
||||
|
||||
if (sShadowInterpCount < MAX_SHADOW_NODES) {
|
||||
struct ShadowInterp* interp = &sShadowInterp[sShadowInterpCount++];
|
||||
gShadowInterpCurrent = interp;
|
||||
interp->gfx = NULL;
|
||||
interp->node = node;
|
||||
interp->shadowScale = shadowScale;
|
||||
interp->obj = gCurGraphNodeObject;
|
||||
vec3f_copy(interp->shadowPos, shadowPos);
|
||||
vec3f_copy(interp->shadowPosPrev, shadowPosPrev);
|
||||
} else {
|
||||
gShadowInterpCurrent = NULL;
|
||||
}
|
||||
|
||||
Gfx *shadowListPrev = create_shadow_below_xyz(shadowPosPrev[0], shadowPosPrev[1],
|
||||
shadowPosPrev[2], shadowScale,
|
||||
node->shadowSolidity, node->shadowType);
|
||||
|
||||
Gfx *shadowList = create_shadow_below_xyz(shadowPos[0], shadowPos[1], shadowPos[2], shadowScale,
|
||||
node->shadowSolidity, node->shadowType);
|
||||
if (shadowListPrev != NULL && shadowList != NULL) {
|
||||
if (gShadowInterpCurrent != NULL) {
|
||||
gShadowInterpCurrent->gfx = shadowListPrev;
|
||||
}
|
||||
|
||||
if (shadowListPrev != NULL) {
|
||||
mtxf_translate(mtxf, shadowPos);
|
||||
mtxf_mul(gMatStack[gMatStackIndex + 1], mtxf, *gCurGraphNodeCamera->matrixPtr);
|
||||
|
||||
mtxf_translate(mtxf, shadowPosPrev);
|
||||
mtxf_mul(gMatStackPrev[gMatStackIndex + 1], mtxf, *gCurGraphNodeCamera->matrixPtrPrev);
|
||||
|
||||
|
@ -966,13 +1002,13 @@ static void geo_process_shadow(struct GraphNodeShadow *node) {
|
|||
if (!increment_mat_stack()) { return; }
|
||||
|
||||
if (gShadowAboveWaterOrLava == TRUE) {
|
||||
geo_append_display_list2((void *) VIRTUAL_TO_PHYSICAL(shadowList),
|
||||
geo_append_display_list2((void *) VIRTUAL_TO_PHYSICAL(shadowListPrev),
|
||||
(void *) VIRTUAL_TO_PHYSICAL(shadowListPrev), 4);
|
||||
} else if (gMarioOnIceOrCarpet == TRUE) {
|
||||
geo_append_display_list2((void *) VIRTUAL_TO_PHYSICAL(shadowList),
|
||||
geo_append_display_list2((void *) VIRTUAL_TO_PHYSICAL(shadowListPrev),
|
||||
(void *) VIRTUAL_TO_PHYSICAL(shadowListPrev), 5);
|
||||
} else {
|
||||
geo_append_display_list2((void *) VIRTUAL_TO_PHYSICAL(shadowList),
|
||||
geo_append_display_list2((void *) VIRTUAL_TO_PHYSICAL(shadowListPrev),
|
||||
(void *) VIRTUAL_TO_PHYSICAL(shadowListPrev), 6);
|
||||
}
|
||||
gMatStackIndex--;
|
||||
|
|
|
@ -33,4 +33,15 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor);
|
|||
void interpolate_vectors(Vec3f res, Vec3f a, Vec3f b);
|
||||
void interpolate_vectors_s16(Vec3s res, Vec3s a, Vec3s b);
|
||||
|
||||
struct ShadowInterp {
|
||||
Gfx* gfx;
|
||||
Vec3f shadowPos;
|
||||
Vec3f shadowPosPrev;
|
||||
Vtx *verts;
|
||||
Gfx *displayList;
|
||||
struct GraphNodeShadow *node;
|
||||
f32 shadowScale;
|
||||
struct GraphNodeObject *obj;
|
||||
};
|
||||
|
||||
#endif // RENDERING_GRAPH_NODE_H
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
// Avoid Z-fighting
|
||||
#define find_floor_height_and_data 0.4 + find_floor_height_and_data
|
||||
|
||||
extern u8 gRenderingInterpolated;
|
||||
extern struct ShadowInterp* gShadowInterpCurrent;
|
||||
|
||||
/**
|
||||
* @file shadow.c
|
||||
* This file implements a self-contained subsystem used to draw shadows.
|
||||
|
@ -114,6 +117,39 @@ s8 gMarioOnIceOrCarpet;
|
|||
s8 sMarioOnFlyingCarpet;
|
||||
s16 sSurfaceTypeBelowShadow;
|
||||
|
||||
static Vtx* shadow_get_or_alloc_verts(u8 vertCount) {
|
||||
if (gRenderingInterpolated) {
|
||||
if (gShadowInterpCurrent == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return gShadowInterpCurrent->verts;
|
||||
} else {
|
||||
Vtx* verts = alloc_display_list(vertCount * sizeof(Vtx));
|
||||
if (gShadowInterpCurrent) {
|
||||
gShadowInterpCurrent->verts = verts;
|
||||
}
|
||||
return verts;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Gfx* shadow_get_or_alloc_display_list(u8 dlCount) {
|
||||
if (gRenderingInterpolated) {
|
||||
if (gShadowInterpCurrent == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return gShadowInterpCurrent->displayList;
|
||||
} else {
|
||||
Gfx *displayList = alloc_display_list(dlCount * sizeof(Gfx));
|
||||
if (gShadowInterpCurrent) {
|
||||
gShadowInterpCurrent->displayList = displayList;
|
||||
}
|
||||
return displayList;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Let (oldZ, oldX) be the relative coordinates of a point on a rectangle,
|
||||
* assumed to be centered at the origin on the standard SM64 X-Z plane. This
|
||||
|
@ -622,8 +658,8 @@ Gfx *create_shadow_player(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, u8 soli
|
|||
return NULL;
|
||||
}
|
||||
|
||||
verts = alloc_display_list(9 * sizeof(Vtx));
|
||||
displayList = alloc_display_list(5 * sizeof(Gfx));
|
||||
verts = shadow_get_or_alloc_verts(9);
|
||||
displayList = shadow_get_or_alloc_display_list(5);
|
||||
if (verts == NULL || displayList == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -650,8 +686,8 @@ Gfx *create_shadow_circle_9_verts(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
verts = alloc_display_list(9 * sizeof(Vtx));
|
||||
displayList = alloc_display_list(5 * sizeof(Gfx));
|
||||
verts = shadow_get_or_alloc_verts(9);
|
||||
displayList = shadow_get_or_alloc_display_list(5);
|
||||
|
||||
if (verts == NULL || displayList == NULL) {
|
||||
return 0;
|
||||
|
@ -676,8 +712,8 @@ Gfx *create_shadow_circle_4_verts(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
verts = alloc_display_list(4 * sizeof(Vtx));
|
||||
displayList = alloc_display_list(5 * sizeof(Gfx));
|
||||
verts = shadow_get_or_alloc_verts(4);
|
||||
displayList = shadow_get_or_alloc_display_list(5);
|
||||
|
||||
if (verts == NULL || displayList == NULL) {
|
||||
return 0;
|
||||
|
@ -709,8 +745,8 @@ Gfx *create_shadow_circle_assuming_flat_ground(f32 xPos, f32 yPos, f32 zPos, s16
|
|||
distBelowFloor = floorHeight - yPos;
|
||||
}
|
||||
|
||||
verts = alloc_display_list(4 * sizeof(Vtx));
|
||||
displayList = alloc_display_list(5 * sizeof(Gfx));
|
||||
verts = shadow_get_or_alloc_verts(4);
|
||||
displayList = shadow_get_or_alloc_display_list(5);
|
||||
|
||||
if (verts == NULL || displayList == NULL) {
|
||||
return 0;
|
||||
|
@ -738,8 +774,8 @@ Gfx *create_shadow_spike_ext(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, u8 s
|
|||
return NULL;
|
||||
}
|
||||
|
||||
verts = alloc_display_list(4 * sizeof(Vtx));
|
||||
displayList = alloc_display_list(5 * sizeof(Gfx));
|
||||
verts = shadow_get_or_alloc_verts(4);
|
||||
displayList = shadow_get_or_alloc_display_list(5);
|
||||
|
||||
if (verts == NULL || displayList == NULL) {
|
||||
return 0;
|
||||
|
@ -757,8 +793,9 @@ Gfx *create_shadow_spike_ext(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, u8 s
|
|||
* underneath the shadow is totally flat.
|
||||
*/
|
||||
Gfx *create_shadow_rectangle(f32 halfWidth, f32 halfLength, f32 relY, u8 solidity) {
|
||||
Vtx *verts = alloc_display_list(4 * sizeof(Vtx));
|
||||
Gfx *displayList = alloc_display_list(5 * sizeof(Gfx));
|
||||
Vtx *verts = shadow_get_or_alloc_verts(4);
|
||||
Gfx *displayList = shadow_get_or_alloc_display_list(5);
|
||||
|
||||
f32 frontLeftX, frontLeftZ, frontRightX, frontRightZ, backLeftX, backLeftZ, backRightX, backRightZ;
|
||||
|
||||
if (verts == NULL || displayList == NULL) {
|
||||
|
|
|
@ -45,10 +45,10 @@
|
|||
* first, in a display list with the Z buffer disabled
|
||||
*/
|
||||
struct Skybox {
|
||||
/// The camera's yaw, from 0 to 65536, which maps to 0 to 360 degrees
|
||||
u16 yaw;
|
||||
/// The camera's pitch, which is bounded by +-16384, which maps to -90 to 90 degrees
|
||||
s16 pitch;
|
||||
/// The camera's yaw, from 0 to (M_PI*2), which maps to 0 to 360 degrees
|
||||
f32 yaw;
|
||||
/// The camera's pitch, which is bounded by +-(M_PI/2), which maps to -90 to 90 degrees
|
||||
f32 pitch;
|
||||
/// The skybox's X position in world space
|
||||
f32 scaledX;
|
||||
/// The skybox's Y position in world space
|
||||
|
@ -138,11 +138,11 @@ u8 sSkyboxColors[][3] = {
|
|||
* (how far is the camera rotated from 0, scaled 0 to 1) *
|
||||
* (the screen width)
|
||||
*/
|
||||
s32 calculate_skybox_scaled_x(s8 player, f32 fov) {
|
||||
f32 calculate_skybox_scaled_x(s8 player, f32 fov) {
|
||||
f32 yaw = sSkyBoxInfo[player].yaw;
|
||||
|
||||
//! double literals are used instead of floats
|
||||
f32 scaledX = SCREEN_WIDTH * 360.0 * yaw / (fov * 65536.0);
|
||||
f32 scaledX = SCREEN_WIDTH * 180.0 * yaw / (fov * M_PI);
|
||||
|
||||
if (scaledX > SKYBOX_WIDTH) {
|
||||
scaledX -= (s32) scaledX / SKYBOX_WIDTH * SKYBOX_WIDTH;
|
||||
|
@ -156,9 +156,9 @@ s32 calculate_skybox_scaled_x(s8 player, f32 fov) {
|
|||
* fov may have been used in an earlier version, but the developers changed the function to always use
|
||||
* 90 degrees.
|
||||
*/
|
||||
s32 calculate_skybox_scaled_y(s8 player, UNUSED f32 fov) {
|
||||
f32 calculate_skybox_scaled_y(s8 player, UNUSED f32 fov) {
|
||||
// Convert pitch to degrees. Pitch is bounded between -90 (looking down) and 90 (looking up).
|
||||
f32 pitchInDegrees = (f32) sSkyBoxInfo[player].pitch * 360.0 / 65535.0;
|
||||
f32 pitchInDegrees = sSkyBoxInfo[player].pitch * 180.0 / M_PI;
|
||||
|
||||
// Scale by 360 / fov
|
||||
f32 degreesToScale = 360.0f * pitchInDegrees / 90.0;
|
||||
|
@ -193,7 +193,7 @@ 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, s32 row, s32 col, s8 player) {
|
||||
Vtx *make_skybox_rect(s32 tileIndex, s8 colorIndex, s32 row, s32 col) {
|
||||
extern Vtx* gBackgroundSkyboxVerts[3][3];
|
||||
|
||||
Vtx *verts;
|
||||
|
@ -242,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, row, col, player);
|
||||
Vtx *vertices = make_skybox_rect(tileIndex, colorIndex, row, col);
|
||||
|
||||
gLoadBlockTexture((*dlist)++, 32, 32, G_IM_FMT_RGBA, texture);
|
||||
gSPVertex((*dlist)++, VIRTUAL_TO_PHYSICAL(vertices), 4, 0);
|
||||
|
@ -342,8 +342,11 @@ Gfx *create_skybox_facing_camera(s8 player, s8 background, f32 fov,
|
|||
//! fov is always set to 90.0f. If this line is removed, then the game crashes because fov is 0 on
|
||||
//! the first frame, which causes a floating point divide by 0
|
||||
fov = 90.0f;
|
||||
sSkyBoxInfo[player].yaw = atan2s(cameraFaceZ, cameraFaceX);
|
||||
sSkyBoxInfo[player].pitch = atan2s(sqrtf(cameraFaceX * cameraFaceX + cameraFaceZ * cameraFaceZ), cameraFaceY);
|
||||
|
||||
sSkyBoxInfo[player].yaw = (M_PI / 2.0) - atan2(cameraFaceZ, cameraFaceX);
|
||||
if (sSkyBoxInfo[player].yaw < 0) { sSkyBoxInfo[player].yaw += M_PI * 2.0; }
|
||||
sSkyBoxInfo[player].pitch = (M_PI / 2.0) - atan2(sqrtf(cameraFaceX * cameraFaceX + cameraFaceZ * cameraFaceZ), cameraFaceY);
|
||||
|
||||
sSkyBoxInfo[player].scaledX = calculate_skybox_scaled_x(player, fov);
|
||||
sSkyBoxInfo[player].scaledY = calculate_skybox_scaled_y(player, fov);
|
||||
sSkyBoxInfo[player].upperLeftTile = get_top_left_tile_idx(player);
|
||||
|
|
Loading…
Reference in a new issue