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
|
@ -38,7 +38,7 @@
|
|||
* - Script node (Cannon overlay)
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define MATRIX_STACK_SIZE 32
|
||||
|
||||
s16 gMatStackIndex;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -250,7 +272,7 @@ static u8 increment_mat_stack() {
|
|||
Mtx *mtx = alloc_display_list(sizeof(*mtx));
|
||||
Mtx *mtxPrev = alloc_display_list(sizeof(*mtxPrev));
|
||||
if (mtx == NULL || mtxPrev == NULL) { return FALSE; }
|
||||
|
||||
|
||||
gMatStackIndex++;
|
||||
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
|
||||
mtxf_to_mtx(mtxPrev, gMatStackPrev[gMatStackIndex]);
|
||||
|
@ -446,10 +468,10 @@ static void geo_process_switch(struct GraphNodeSwitchCase *node) {
|
|||
*/
|
||||
static void geo_process_camera(struct GraphNodeCamera *node) {
|
||||
Mat4 cameraTransform;
|
||||
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return to prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
|
||||
|
||||
Mtx *rollMtx = alloc_display_list(sizeof(*rollMtx));
|
||||
if (rollMtx == NULL) { return; }
|
||||
|
||||
|
@ -477,7 +499,7 @@ static void geo_process_camera(struct GraphNodeCamera *node) {
|
|||
|
||||
// Increment the matrix stack, If we fail to do so. Just return.
|
||||
if (!increment_mat_stack()) { return; }
|
||||
|
||||
|
||||
if (node->fnNode.node.children != 0) {
|
||||
gCurGraphNodeCamera = node;
|
||||
node->matrixPtr = &gMatStack[gMatStackIndex];
|
||||
|
@ -497,7 +519,7 @@ static void geo_process_camera(struct GraphNodeCamera *node) {
|
|||
static void geo_process_translation_rotation(struct GraphNodeTranslationRotation *node) {
|
||||
Mat4 mtxf;
|
||||
Vec3f translation;
|
||||
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return top prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
|
||||
|
@ -505,10 +527,10 @@ static void geo_process_translation_rotation(struct GraphNodeTranslationRotation
|
|||
mtxf_rotate_zxy_and_translate(mtxf, translation, node->rotation);
|
||||
mtxf_mul(gMatStack[gMatStackIndex + 1], mtxf, gMatStack[gMatStackIndex]);
|
||||
mtxf_mul(gMatStackPrev[gMatStackIndex + 1], mtxf, gMatStackPrev[gMatStackIndex]);
|
||||
|
||||
|
||||
// Increment the matrix stack, If we fail to do so. Just return.
|
||||
if (!increment_mat_stack()) { return; }
|
||||
|
||||
|
||||
if (node->displayList != NULL) {
|
||||
geo_append_display_list(node->displayList, node->node.flags >> 8);
|
||||
}
|
||||
|
@ -526,7 +548,7 @@ static void geo_process_translation_rotation(struct GraphNodeTranslationRotation
|
|||
static void geo_process_translation(struct GraphNodeTranslation *node) {
|
||||
Mat4 mtxf;
|
||||
Vec3f translation;
|
||||
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return top prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
|
||||
|
@ -534,10 +556,10 @@ static void geo_process_translation(struct GraphNodeTranslation *node) {
|
|||
mtxf_rotate_zxy_and_translate(mtxf, translation, gVec3sZero);
|
||||
mtxf_mul(gMatStack[gMatStackIndex + 1], mtxf, gMatStack[gMatStackIndex]);
|
||||
mtxf_mul(gMatStackPrev[gMatStackIndex + 1], mtxf, gMatStackPrev[gMatStackIndex]);
|
||||
|
||||
|
||||
// Increment the matrix stack, If we fail to do so. Just return.
|
||||
if (!increment_mat_stack()) { return; }
|
||||
|
||||
|
||||
if (node->displayList != NULL) {
|
||||
geo_append_display_list(node->displayList, node->node.flags >> 8);
|
||||
}
|
||||
|
@ -554,7 +576,7 @@ static void geo_process_translation(struct GraphNodeTranslation *node) {
|
|||
*/
|
||||
static void geo_process_rotation(struct GraphNodeRotation *node) {
|
||||
Mat4 mtxf;
|
||||
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return top prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
|
||||
|
@ -569,10 +591,10 @@ static void geo_process_rotation(struct GraphNodeRotation *node) {
|
|||
mtxf_mul(gMatStackPrev[gMatStackIndex + 1], mtxf, gMatStackPrev[gMatStackIndex]);
|
||||
vec3s_copy(node->prevRotation, node->rotation);
|
||||
node->prevTimestamp = gGlobalTimer;
|
||||
|
||||
|
||||
// Increment the matrix stack, If we fail to do so. Just return.
|
||||
if (!increment_mat_stack()) { return; }
|
||||
|
||||
|
||||
if (node->displayList != NULL) {
|
||||
geo_append_display_list(node->displayList, node->node.flags >> 8);
|
||||
}
|
||||
|
@ -590,7 +612,7 @@ static void geo_process_rotation(struct GraphNodeRotation *node) {
|
|||
static void geo_process_scale(struct GraphNodeScale *node) {
|
||||
Vec3f scaleVec;
|
||||
Vec3f prevScaleVec;
|
||||
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return top prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
|
||||
|
@ -603,7 +625,7 @@ static void geo_process_scale(struct GraphNodeScale *node) {
|
|||
|
||||
// Increment the matrix stack, If we fail to do so. Just return.
|
||||
if (!increment_mat_stack()) { return; }
|
||||
|
||||
|
||||
if (node->displayList != NULL) {
|
||||
geo_append_display_list(node->displayList, node->node.flags >> 8);
|
||||
}
|
||||
|
@ -621,12 +643,12 @@ static void geo_process_scale(struct GraphNodeScale *node) {
|
|||
*/
|
||||
static void geo_process_billboard(struct GraphNodeBillboard *node) {
|
||||
Vec3f translation;
|
||||
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return top prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
|
||||
|
||||
s16 nextMatStackIndex = gMatStackIndex + 1;
|
||||
|
||||
|
||||
vec3s_to_vec3f(translation, node->translation);
|
||||
mtxf_billboard(gMatStack[nextMatStackIndex], gMatStack[gMatStackIndex], translation,
|
||||
gCurGraphNodeCamera->roll);
|
||||
|
@ -646,7 +668,7 @@ static void geo_process_billboard(struct GraphNodeBillboard *node) {
|
|||
|
||||
// Increment the matrix stack, If we fail to do so. Just return.
|
||||
if (!increment_mat_stack()) { return; }
|
||||
|
||||
|
||||
if (node->displayList != NULL) {
|
||||
geo_append_display_list(node->displayList, node->node.flags >> 8);
|
||||
}
|
||||
|
@ -792,10 +814,10 @@ static void geo_process_animated_part(struct GraphNodeAnimatedPart *node) {
|
|||
Vec3f translation;
|
||||
Vec3s rotationPrev;
|
||||
Vec3f translationPrev;
|
||||
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return top prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
|
||||
|
||||
u16 *animAttribute = gCurrAnimAttribute;
|
||||
u8 animType = gCurAnimType;
|
||||
|
||||
|
@ -813,7 +835,7 @@ static void geo_process_animated_part(struct GraphNodeAnimatedPart *node) {
|
|||
|
||||
mtxf_rotate_xyz_and_translate(matrix, translationPrev, rotationPrev);
|
||||
mtxf_mul(gMatStackPrev[gMatStackIndex + 1], matrix, gMatStackPrev[gMatStackIndex]);
|
||||
|
||||
|
||||
// Increment the matrix stack, If we fail to do so. Just return.
|
||||
if (!increment_mat_stack()) { return; }
|
||||
|
||||
|
@ -886,7 +908,7 @@ static void geo_process_shadow(struct GraphNodeShadow *node) {
|
|||
Vec3f shadowPosPrev;
|
||||
Vec3f animOffset;
|
||||
f32 shadowScale;
|
||||
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return top prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
|
||||
|
@ -949,30 +971,44 @@ 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);
|
||||
|
||||
|
||||
// Increment the matrix stack, If we fail to do so. Just return.
|
||||
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--;
|
||||
|
@ -1034,7 +1070,7 @@ static s32 obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) {
|
|||
// This multiplication should really be performed on 4:3 as well,
|
||||
// but the issue will be more apparent on widescreen.
|
||||
hScreenEdge *= GFX_DIMENSIONS_ASPECT_RATIO;
|
||||
|
||||
|
||||
s16 cullingRadius = 300;
|
||||
struct GraphNode *geo = node->sharedChild;
|
||||
if (geo != NULL && geo->type == GRAPH_NODE_TYPE_CULLING_RADIUS) {
|
||||
|
@ -1260,7 +1296,7 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
|
|||
Mat4 mat;
|
||||
Vec3f translation;
|
||||
Vec3f scalePrev;
|
||||
|
||||
|
||||
// Sanity check our stack index, If we above or equal to our stack size. Return top prevent OOB.
|
||||
if (gMatStackIndex >= MATRIX_STACK_SIZE) { return; }
|
||||
|
||||
|
@ -1304,10 +1340,10 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
|
|||
if (node->fnNode.func != NULL) {
|
||||
node->fnNode.func(GEO_CONTEXT_HELD_OBJ, &node->fnNode.node, (struct AllocOnlyPool *) gMatStack[gMatStackIndex + 1]);
|
||||
}
|
||||
|
||||
|
||||
// Increment the matrix stack, If we fail to do so. Just return.
|
||||
if (!increment_mat_stack()) { return; }
|
||||
|
||||
|
||||
gGeoTempState.type = gCurAnimType;
|
||||
gGeoTempState.enabled = gCurAnimEnabled;
|
||||
gGeoTempState.frame = gCurrAnimFrame;
|
||||
|
@ -1461,7 +1497,7 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
|
|||
|
||||
Mtx *initialMatrix = alloc_display_list(sizeof(*initialMatrix));
|
||||
if (initialMatrix == NULL) { return; }
|
||||
|
||||
|
||||
gMatStackIndex = 0;
|
||||
gCurAnimType = 0;
|
||||
vec3s_set(viewport->vp.vtrans, node->x * 4, node->y * 4, 511);
|
||||
|
@ -1493,7 +1529,7 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
|
|||
|
||||
gSPViewport(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&sViewportPrev));
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(gMatStackFixed[gMatStackIndex]), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
|
||||
|
||||
gCurGraphNodeRoot = node;
|
||||
if (node->node.children != NULL) {
|
||||
geo_process_node_and_siblings(node->node.children);
|
||||
|
|
|
@ -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