Combine shadow flags into gShadowFlags

This commit is contained in:
Arceveti
2021-09-27 15:45:28 -07:00
parent a5c1aef42b
commit 1e81412c4b
5 changed files with 110 additions and 180 deletions

View File

@@ -43,7 +43,7 @@ void bhv_manta_ray_init(void) {
static void manta_ray_move(void) {
s16 animFrame = o->header.gfx.animInfo.animFrame;
gCurrentObject->oPathedStartWaypoint = (struct Waypoint *) sMantaRayTraj;
s32 pathStatus = cur_obj_follow_path(pathStatus);
cur_obj_follow_path(0);
o->oMantaTargetYaw = o->oPathedTargetYaw;
o->oMantaTargetPitch = o->oPathedTargetPitch;
o->oForwardVel = 10.0f;

View File

@@ -792,27 +792,22 @@ void geo_set_animation_globals(struct AnimInfo *node, s32 hasAnimation) {
* the floor below it.
*/
void geo_process_shadow(struct GraphNodeShadow *node) {
Gfx *shadowList;
Mat4 mtxf;
Vec3f shadowPos;
Vec3f animOffset;
f32 objScale;
f32 shadowScale;
f32 sinAng;
f32 cosAng;
struct GraphNode *geo;
if (gCurGraphNodeCamera != NULL && gCurGraphNodeObject != NULL) {
if (gCurGraphNodeHeldObject != NULL) {
get_pos_from_transform_mtx(shadowPos, gMatStack[gMatStackIndex],
*gCurGraphNodeCamera->matrixPtr);
get_pos_from_transform_mtx(shadowPos, gMatStack[gMatStackIndex], *gCurGraphNodeCamera->matrixPtr);
shadowScale = node->shadowScale;
} else {
vec3f_copy(shadowPos, gCurGraphNodeObject->pos);
shadowScale = node->shadowScale * gCurGraphNodeObject->scale[0];
}
objScale = 1.0f;
f32 objScale = 1.0f;
if (gCurAnimEnabled) {
if (gCurAnimType == ANIM_TYPE_TRANSLATION
|| gCurAnimType == ANIM_TYPE_LATERAL_TRANSLATION) {
@@ -820,32 +815,26 @@ void geo_process_shadow(struct GraphNodeShadow *node) {
if (geo != NULL && geo->type == GRAPH_NODE_TYPE_SCALE) {
objScale = ((struct GraphNodeScale *) geo)->scale;
}
animOffset[0] =
gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]
* gCurAnimTranslationMultiplier * objScale;
animOffset[0] = gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] * gCurAnimTranslationMultiplier * objScale;
animOffset[1] = 0.0f;
gCurrAnimAttribute += 2;
animOffset[2] =
gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]
* gCurAnimTranslationMultiplier * objScale;
animOffset[2] = gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)] * gCurAnimTranslationMultiplier * objScale;
gCurrAnimAttribute -= 6;
// simple matrix rotation so the shadow offset rotates along with the object
sinAng = sins(gCurGraphNodeObject->angle[1]);
cosAng = coss(gCurGraphNodeObject->angle[1]);
f32 sinAng = sins(gCurGraphNodeObject->angle[1]);
f32 cosAng = coss(gCurGraphNodeObject->angle[1]);
shadowPos[0] += animOffset[0] * cosAng + animOffset[2] * sinAng;
shadowPos[0] += animOffset[0] * cosAng + animOffset[2] * sinAng;
shadowPos[2] += -animOffset[0] * sinAng + animOffset[2] * cosAng;
}
}
shadowList = create_shadow_below_xyz(shadowPos[0], shadowPos[1], shadowPos[2], shadowScale,
node->shadowSolidity, node->shadowType);
Gfx *shadowList = create_shadow_below_xyz(shadowPos[0], shadowPos[1], shadowPos[2], shadowScale, node->shadowSolidity, node->shadowType);
if (shadowList != NULL) {
mtxf_translate(mtxf, shadowPos);
mtxf_mul(gMatStack[gMatStackIndex+1], mtxf, *gCurGraphNodeCamera->matrixPtr);
incrementMatStack();
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), ((gShadowAboveWaterOrLava || gShadowAboveCustomWater || gMarioOnIceOrCarpet) ? LAYER_TRANSPARENT : LAYER_TRANSPARENT_DECAL));
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), ((gShadowFlags & (SHADOW_FLAG_WATER_BOX | SHADOW_FLAG_WATER_SURFACE | SHADOW_FLAG_ICE_CARPET)) ? LAYER_TRANSPARENT : LAYER_TRANSPARENT_DECAL));
gMatStackIndex--;
}
}

View File

@@ -101,10 +101,7 @@ shadowRectangle rectangles[2] = {
};
// See shadow.h for documentation.
s8 gShadowAboveWaterOrLava;
s8 gShadowAboveCustomWater;
s8 gMarioOnIceOrCarpet;
s8 sMarioOnFlyingCarpet;
s8 gShadowFlags;
s16 sSurfaceTypeBelowShadow;
/**
@@ -185,7 +182,7 @@ f32 get_water_level_below_shadow(struct Shadow *s, struct Surface **waterFloor)
if (waterLevel < FLOOR_LOWER_LIMIT_SHADOW) {
return 0;
} else if (s->parentY >= waterLevel && s->floorHeight <= waterLevel) {
gShadowAboveWaterOrLava = TRUE;
gShadowFlags |= SHADOW_FLAG_WATER_BOX;
return waterLevel;
}
return waterLevel;
@@ -200,8 +197,6 @@ f32 get_water_level_below_shadow(struct Shadow *s, struct Surface **waterFloor)
* be dimmed based on its distance to the floor
*/
s32 init_shadow(struct Shadow *s, f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, u8 overwriteSolidity) {
f32 waterLevel = FLOOR_LOWER_LIMIT_SHADOW;
f32 floorSteepness;
struct Surface *floor;
struct Surface *waterFloor = NULL;
@@ -209,16 +204,15 @@ s32 init_shadow(struct Shadow *s, f32 xPos, f32 yPos, f32 zPos, s16 shadowScale,
s->parentY = yPos;
s->parentZ = zPos;
s->floorHeight = find_floor(s->parentX, s->parentY, s->parentZ, &floor);
waterLevel = get_water_level_below_shadow(s, &waterFloor);
f32 waterLevel = get_water_level_below_shadow(s, &waterFloor);
// if (gEnvironmentRegions != 0) {
// waterLevel = get_water_level_below_shadow(s);
// }
if (gShadowAboveWaterOrLava) {
if (gShadowFlags & SHADOW_FLAG_WATER_BOX) {
s->floorHeight = waterLevel;
if (waterFloor != NULL) {
@@ -226,11 +220,11 @@ s32 init_shadow(struct Shadow *s, f32 xPos, f32 yPos, f32 zPos, s16 shadowScale,
s->floorNormalY = waterFloor->normal.y;
s->floorNormalZ = waterFloor->normal.z;
s->floorOriginOffset = waterFloor->originOffset;
gShadowAboveWaterOrLava = FALSE;
gShadowAboveCustomWater = TRUE;
gShadowFlags &= ~SHADOW_FLAG_WATER_BOX;
gShadowFlags |= SHADOW_FLAG_WATER_SURFACE;
s->solidity = 200;
} else {
gShadowAboveCustomWater = FALSE;
gShadowFlags &= ~SHADOW_FLAG_WATER_SURFACE;
// Assume that the water is flat.
s->floorNormalX = 0.0f;
s->floorNormalY = 1.0f;
@@ -259,7 +253,7 @@ s32 init_shadow(struct Shadow *s, f32 xPos, f32 yPos, f32 zPos, s16 shadowScale,
s->floorDownwardAngle = atan2_deg(s->floorNormalZ, s->floorNormalX);
floorSteepness = sqrtf(s->floorNormalX * s->floorNormalX + s->floorNormalZ * s->floorNormalZ);
f32 floorSteepness = sqrtf(sqr(s->floorNormalX) + sqr(s->floorNormalZ));
// This if-statement avoids dividing by 0.
if (floorSteepness == 0.0f) {
@@ -302,8 +296,7 @@ void get_texture_coords_4_vertices(s8 vertexNum, s16 *textureX, s16 *textureY) {
* @param alpha Opacity of the vertex
* @param shadowVertexType One of SHADOW_WITH_9_VERTS or SHADOW_WITH_4_VERTS
*/
void make_shadow_vertex_at_xyz(Vtx *vertices, s8 index, f32 relX, f32 relY, f32 relZ, u8 alpha,
s8 shadowVertexType) {
void make_shadow_vertex_at_xyz(Vtx *vertices, s8 index, f32 relX, f32 relY, f32 relZ, u8 alpha, s8 shadowVertexType) {
s16 vtxX = round_float(relX);
s16 vtxY = round_float(relY);
s16 vtxZ = round_float(relZ);
@@ -320,14 +313,12 @@ void make_shadow_vertex_at_xyz(Vtx *vertices, s8 index, f32 relX, f32 relY, f32
}
// Move the shadow up and over slightly while standing on a flying carpet.
if (sMarioOnFlyingCarpet) {
if (gShadowFlags & SHADOW_FLAG_RAISED) {
vtxX += 5;
vtxY += 5;
vtxZ += 5;
}
make_vertex(vertices, index, vtxX, vtxY, vtxZ, textureX << 5, textureY << 5, 255, 255, 255,
alpha // shadows are black
);
make_vertex(vertices, index, vtxX, vtxY, vtxZ, textureX << 5, textureY << 5, 255, 255, 255, alpha); // shadows are black
}
/**
@@ -349,15 +340,10 @@ void get_vertex_coords(s8 index, s8 shadowVertexType, s8 *xCoord, s8 *zCoord) {
*xCoord = index % (3 - shadowVertexType) - 1;
*zCoord = index / (3 - shadowVertexType) - 1;
// This just corrects the 4-vertex case to have consistent results with the
// 9-vertex case.
// This just corrects the 4-vertex case to have consistent results with the 9-vertex case.
if (shadowVertexType == SHADOW_WITH_4_VERTS) {
if (*xCoord == 0) {
*xCoord = 1;
}
if (*zCoord == 0) {
*zCoord = 1;
}
if (*xCoord == 0) *xCoord = 1;
if (*zCoord == 0) *zCoord = 1;
}
}
@@ -375,21 +361,18 @@ void get_vertex_coords(s8 index, s8 shadowVertexType, s8 *xCoord, s8 *zCoord) {
void calculate_vertex_xyz(s8 index, struct Shadow s, f32 *xPosVtx, f32 *yPosVtx, f32 *zPosVtx, s8 shadowVertexType) {
f32 tiltedScale = cosf(s.floorTilt * M_PI / 180.0) * s.shadowScale;
f32 downwardAngle = s.floorDownwardAngle * M_PI / 180.0;
f32 halfScale;
f32 halfTiltedScale;
s8 xCoordUnit;
s8 zCoordUnit;
s8 xCoordUnit, zCoordUnit;
// This makes xCoordUnit and yCoordUnit each one of -1, 0, or 1.
get_vertex_coords(index, shadowVertexType, &xCoordUnit, &zCoordUnit);
halfScale = (xCoordUnit * s.shadowScale) / 2.0f;
halfTiltedScale = (zCoordUnit * tiltedScale) / 2.0f;
f32 halfScale = (xCoordUnit * s.shadowScale) / 2.0f;
f32 halfTiltedScale = (zCoordUnit * tiltedScale) / 2.0f;
*xPosVtx = (halfTiltedScale * sinf(downwardAngle)) + (halfScale * cosf(downwardAngle)) + s.parentX;
*zPosVtx = (halfTiltedScale * cosf(downwardAngle)) - (halfScale * sinf(downwardAngle)) + s.parentZ;
if (gShadowAboveWaterOrLava) {
if (gShadowFlags & SHADOW_FLAG_WATER_BOX) {
*yPosVtx = s.floorHeight;
} else {
switch (shadowVertexType) {
@@ -428,8 +411,7 @@ s16 floor_local_tilt(struct Shadow s, f32 vtxX, f32 vtxY, f32 vtxZ) {
f32 relY = vtxY - s.floorHeight;
f32 relZ = vtxZ - s.parentZ;
f32 ret = (relX * s.floorNormalX) + (relY * s.floorNormalY) + (relZ * s.floorNormalZ);
return ret;
return ((relX * s.floorNormalX) + (relY * s.floorNormalY) + (relZ * s.floorNormalZ));
}
/**
@@ -440,7 +422,7 @@ void make_shadow_vertex(Vtx *vertices, s8 index, struct Shadow s, s8 shadowVerte
f32 relX, relY, relZ;
u8 solidity = s.solidity;
if (gShadowAboveWaterOrLava) {
if (gShadowFlags & SHADOW_FLAG_WATER_BOX) {
solidity = 200;
}
@@ -460,8 +442,7 @@ void make_shadow_vertex(Vtx *vertices, s8 index, struct Shadow s, s8 shadowVerte
* The gShadowAboveWaterOrLava check is redundant, since `floor_local_tilt`
* will always be 0 over water or lava (since they are always flat).
*/
if (shadowVertexType == SHADOW_WITH_9_VERTS && !gShadowAboveWaterOrLava
&& floor_local_tilt(s, xPosVtx, yPosVtx, zPosVtx) != 0) {
if (shadowVertexType == SHADOW_WITH_9_VERTS && !(gShadowFlags & SHADOW_FLAG_WATER_BOX) && floor_local_tilt(s, xPosVtx, yPosVtx, zPosVtx) != 0) {
yPosVtx = extrapolate_vertex_y_position(s, xPosVtx, zPosVtx);
solidity = 0;
}
@@ -501,8 +482,7 @@ void add_shadow_to_display_list(Gfx *displayListHead, Vtx *verts, s8 shadowVerte
* Linearly interpolate a shadow's solidity between zero and finalSolidity
* depending on curr's relation to start and end.
*/
void linearly_interpolate_solidity_positive(struct Shadow *s, u8 finalSolidity, s16 curr, s16 start,
s16 end) {
void linearly_interpolate_solidity_positive(struct Shadow *s, u8 finalSolidity, s16 curr, s16 start, s16 end) {
if (curr >= 0 && curr < start) {
s->solidity = 0;
} else if (end < curr) {
@@ -517,8 +497,7 @@ void linearly_interpolate_solidity_positive(struct Shadow *s, u8 finalSolidity,
* depending on curr's relation to start and end. Note that if curr < start,
* the solidity will be zero.
*/
void linearly_interpolate_solidity_negative(struct Shadow *s, u8 initialSolidity, s16 curr, s16 start,
s16 end) {
void linearly_interpolate_solidity_negative(struct Shadow *s, u8 initialSolidity, s16 curr, s16 start, s16 end) {
// The curr < start case is not handled. Thus, if start != 0, this function
// will have the surprising behavior of hiding the shadow until start.
// This is not necessarily a bug, since this function is only used once,
@@ -538,22 +517,18 @@ s32 correct_shadow_solidity_for_animations(s32 isLuigi, u8 initialSolidity, stru
s8 ret;
s16 animFrame;
switch (isLuigi) {
case 1:
/**
* This is evidence of a removed second player, likely Luigi.
* This variable lies in memory just after the gMarioObject and
* has the same type of shadow that Mario does. The `isLuigi`
* variable is never 1 in the game. Note that since this was a
* switch-case, not an if-statement, the programmers possibly
* intended there to be even more than 2 characters.
*/
player = gLuigiObject;
break;
case 0:
default:
player = gMarioObject;
break;
if (isLuigi) {
/**
* This is evidence of a removed second player, likely Luigi.
* This variable lies in memory just after the gMarioObject and
* has the same type of shadow that Mario does. The `isLuigi`
* variable is never 1 in the game. Note that since this was a
* switch-case, not an if-statement, the programmers possibly
* intended there to be even more than 2 characters.
*/
player = gLuigiObject;
} else {
player = gMarioObject;
}
animFrame = player->header.gfx.animInfo.animFrame;
@@ -562,7 +537,7 @@ s32 correct_shadow_solidity_for_animations(s32 isLuigi, u8 initialSolidity, stru
ret = SHADOW_SOLIDITY_NO_SHADOW;
break;
case MARIO_ANIM_FAST_LEDGE_GRAB:
linearly_interpolate_solidity_positive(shadow, initialSolidity, animFrame, 5, 14);
linearly_interpolate_solidity_positive(shadow, initialSolidity, animFrame, 5, 14);
ret = SHADOW_SOILDITY_ALREADY_SET;
break;
case MARIO_ANIM_SLOW_LEDGE_GRAB:
@@ -570,7 +545,7 @@ s32 correct_shadow_solidity_for_animations(s32 isLuigi, u8 initialSolidity, stru
ret = SHADOW_SOILDITY_ALREADY_SET;
break;
case MARIO_ANIM_CLIMB_DOWN_LEDGE:
linearly_interpolate_solidity_negative(shadow, initialSolidity, animFrame, 0, 5);
linearly_interpolate_solidity_negative(shadow, initialSolidity, animFrame, 0, 5);
ret = SHADOW_SOILDITY_ALREADY_SET;
break;
default:
@@ -587,15 +562,14 @@ void correct_lava_shadow_height(struct Shadow *s) {
if (gCurrLevelNum == LEVEL_BITFS && sSurfaceTypeBelowShadow == SURFACE_BURNING) {
if (s->floorHeight < -3000.0f) {
s->floorHeight = -3062.0f;
gShadowAboveWaterOrLava = TRUE;
gShadowFlags |= SHADOW_FLAG_WATER_BOX;
} else if (s->floorHeight > 3400.0f) {
s->floorHeight = 3492.0f;
gShadowAboveWaterOrLava = TRUE;
gShadowFlags |= SHADOW_FLAG_WATER_BOX;
}
} else if (gCurrLevelNum == LEVEL_LLL && gCurrAreaIndex == 1
&& sSurfaceTypeBelowShadow == SURFACE_BURNING) {
} else if (gCurrLevelNum == LEVEL_LLL && gCurrAreaIndex == 1 && sSurfaceTypeBelowShadow == SURFACE_BURNING) {
s->floorHeight = 5.0f;
gShadowAboveWaterOrLava = TRUE;
gShadowFlags |= SHADOW_FLAG_WATER_BOX;
}
}
@@ -604,8 +578,6 @@ void correct_lava_shadow_height(struct Shadow *s) {
* appropriate animations and other states.
*/
Gfx *create_shadow_player(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, u8 solidity, s32 isLuigi) {
Vtx *verts;
Gfx *displayList;
struct Shadow shadow;
s8 ret = 0;
s32 i;
@@ -614,11 +586,10 @@ Gfx *create_shadow_player(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, u8 soli
if (gCurrLevelNum == LEVEL_RR && sSurfaceTypeBelowShadow != SURFACE_DEATH_PLANE) {
switch (gFlyingCarpetState) {
case FLYING_CARPET_MOVING_WITHOUT_MARIO:
gMarioOnIceOrCarpet = 1;
sMarioOnFlyingCarpet = 1;
gShadowFlags |= (SHADOW_FLAG_ICE_CARPET | SHADOW_FLAG_RAISED);
break;
case FLYING_CARPET_MOVING_WITH_MARIO:
gMarioOnIceOrCarpet = 1;
gShadowFlags = SHADOW_FLAG_ICE_CARPET;
break;
}
}
@@ -636,8 +607,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));
Vtx *verts = alloc_display_list(9 * sizeof(Vtx));
Gfx *displayList = alloc_display_list(5 * sizeof(Gfx));
if (verts == NULL || displayList == NULL) {
return NULL;
}
@@ -655,8 +626,6 @@ Gfx *create_shadow_player(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, u8 soli
* Create a circular shadow composed of 9 vertices.
*/
Gfx *create_shadow_circle_9_verts(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, u8 solidity) {
Vtx *verts;
Gfx *displayList;
struct Shadow shadow;
s32 i;
@@ -664,8 +633,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));
Vtx *verts = alloc_display_list(9 * sizeof(Vtx));
Gfx *displayList = alloc_display_list(5 * sizeof(Gfx));
if (verts == NULL || displayList == NULL) {
return 0;
@@ -681,8 +650,6 @@ Gfx *create_shadow_circle_9_verts(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale,
* Create a circular shadow composed of 4 vertices.
*/
Gfx *create_shadow_circle_4_verts(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, u8 solidity) {
Vtx *verts;
Gfx *displayList;
struct Shadow shadow;
s32 i;
@@ -690,8 +657,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));
Vtx *verts = alloc_display_list(4 * sizeof(Vtx));
Gfx *displayList = alloc_display_list(5 * sizeof(Gfx));
if (verts == NULL || displayList == NULL) {
return 0;
@@ -708,20 +675,14 @@ Gfx *create_shadow_circle_4_verts(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale,
* Create a circular shadow composed of 4 vertices and assume that the ground
* underneath it is totally flat.
*/
Gfx *create_shadow_circle_assuming_flat_ground(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale,
u8 solidity) {
Vtx *verts;
Gfx *displayList;
Gfx *create_shadow_circle_assuming_flat_ground(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, u8 solidity) {
f32 distBelowFloor;
f32 floorHeight;
f32 radius = shadowScale / 2;
if (gCurGraphNodeObjectNode->oFloor != NULL)
{
if (gCurGraphNodeObjectNode->oFloor != NULL) {
floorHeight = gCurGraphNodeObjectNode->oFloorHeight;
}
else
{
} else {
floorHeight = find_floor_height(xPos, yPos, zPos);
}
@@ -731,17 +692,17 @@ 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));
Vtx *verts = alloc_display_list(4 * sizeof(Vtx));
Gfx *displayList = alloc_display_list(5 * sizeof(Gfx));
if (verts == NULL || displayList == NULL) {
return 0;
}
make_shadow_vertex_at_xyz(verts, 0, -radius, distBelowFloor, -radius, solidity, 1);
make_shadow_vertex_at_xyz(verts, 1, radius, distBelowFloor, -radius, solidity, 1);
make_shadow_vertex_at_xyz(verts, 2, -radius, distBelowFloor, radius, solidity, 1);
make_shadow_vertex_at_xyz(verts, 3, radius, distBelowFloor, radius, solidity, 1);
make_shadow_vertex_at_xyz(verts, 1, radius, distBelowFloor, -radius, solidity, 1);
make_shadow_vertex_at_xyz(verts, 2, -radius, distBelowFloor, radius, solidity, 1);
make_shadow_vertex_at_xyz(verts, 3, radius, distBelowFloor, radius, solidity, 1);
add_shadow_to_display_list(displayList, verts, SHADOW_WITH_4_VERTS, SHADOW_SHAPE_CIRCLE);
return displayList;
@@ -761,15 +722,15 @@ Gfx *create_shadow_rectangle(f32 halfWidth, f32 halfLength, f32 relY, u8 solidit
}
// Rotate the shadow based on the parent object's face angle.
rotate_rectangle(&frontLeftZ, &frontLeftX, -halfLength, -halfWidth);
rotate_rectangle(&frontRightZ, &frontRightX, -halfLength, halfWidth);
rotate_rectangle(&backLeftZ, &backLeftX, halfLength, -halfWidth);
rotate_rectangle(&backRightZ, &backRightX, halfLength, halfWidth);
rotate_rectangle(&frontLeftZ, &frontLeftX, -halfLength, -halfWidth);
rotate_rectangle(&frontRightZ, &frontRightX, -halfLength, halfWidth);
rotate_rectangle(&backLeftZ, &backLeftX, halfLength, -halfWidth);
rotate_rectangle(&backRightZ, &backRightX, halfLength, halfWidth);
make_shadow_vertex_at_xyz(verts, 0, frontLeftX, relY, frontLeftZ, solidity, 1);
make_shadow_vertex_at_xyz(verts, 0, frontLeftX, relY, frontLeftZ, solidity, 1);
make_shadow_vertex_at_xyz(verts, 1, frontRightX, relY, frontRightZ, solidity, 1);
make_shadow_vertex_at_xyz(verts, 2, backLeftX, relY, backLeftZ, solidity, 1);
make_shadow_vertex_at_xyz(verts, 3, backRightX, relY, backRightZ, solidity, 1);
make_shadow_vertex_at_xyz(verts, 2, backLeftX, relY, backLeftZ, solidity, 1);
make_shadow_vertex_at_xyz(verts, 3, backRightX, relY, backRightZ, solidity, 1);
add_shadow_to_display_list(displayList, verts, SHADOW_WITH_4_VERTS, SHADOW_SHAPE_SQUARE);
return displayList;
@@ -780,31 +741,25 @@ Gfx *create_shadow_rectangle(f32 halfWidth, f32 halfLength, f32 relY, u8 solidit
* value is 200. Return 0 if a shadow should be drawn, 1 if not.
*/
s32 get_shadow_height_solidity(f32 xPos, f32 yPos, f32 zPos, f32 *shadowHeight, u8 *solidity) {
f32 waterLevel;
if (gCurGraphNodeObjectNode->oFloor != NULL)
{
if (gCurGraphNodeObjectNode->oFloor != NULL) {
*shadowHeight = gCurGraphNodeObjectNode->oFloorHeight;
}
else
{
} else {
*shadowHeight = find_floor_height(xPos, yPos, zPos);
}
if (*shadowHeight < FLOOR_LOWER_LIMIT_SHADOW) {
return 1;
return TRUE;
} else {
waterLevel = find_water_level(xPos, zPos);
f32 waterLevel = find_water_level(xPos, zPos);
if (waterLevel < FLOOR_LOWER_LIMIT_SHADOW) {
// Dead if-statement. There may have been an assert here.
} else if (yPos >= waterLevel && waterLevel >= *shadowHeight) {
gShadowAboveWaterOrLava = TRUE;
gShadowFlags |= SHADOW_FLAG_WATER_BOX;
*shadowHeight = waterLevel;
*solidity = 200;
}
}
return 0;
return FALSE;
}
/**
@@ -812,14 +767,13 @@ s32 get_shadow_height_solidity(f32 xPos, f32 yPos, f32 zPos, f32 *shadowHeight,
*/
Gfx *create_shadow_square(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, u8 solidity, s8 shadowType) {
f32 shadowHeight;
f32 distFromShadow;
f32 shadowRadius;
if (get_shadow_height_solidity(xPos, yPos, zPos, &shadowHeight, &solidity) != 0) {
if (get_shadow_height_solidity(xPos, yPos, zPos, &shadowHeight, &solidity)) {
return NULL;
}
distFromShadow = yPos - shadowHeight;
f32 distFromShadow = yPos - shadowHeight;
switch (shadowType) {
case SHADOW_SQUARE_PERMANENT: shadowRadius = shadowScale / 2; break;
case SHADOW_SQUARE_SCALABLE: shadowRadius = scale_shadow_with_distance(shadowScale, distFromShadow) / 2.0f; break;
@@ -834,19 +788,16 @@ Gfx *create_shadow_square(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, u8 soli
* Create a rectangular shadow whose parameters have been hardcoded in the
* `rectangles` array.
*/
Gfx *create_shadow_hardcoded_rectangle(f32 xPos, f32 yPos, f32 zPos, UNUSED s16 shadowScale,
u8 solidity, s8 shadowType) {
Gfx *create_shadow_hardcoded_rectangle(f32 xPos, f32 yPos, f32 zPos, UNUSED s16 shadowScale, u8 solidity, s8 shadowType) {
f32 shadowHeight;
f32 distFromShadow;
f32 halfWidth;
f32 halfLength;
f32 halfWidth, halfLength;
s8 idx = shadowType - SHADOW_RECTANGLE_HARDCODED_OFFSET;
if (get_shadow_height_solidity(xPos, yPos, zPos, &shadowHeight, &solidity) != 0) {
if (get_shadow_height_solidity(xPos, yPos, zPos, &shadowHeight, &solidity)) {
return NULL;
}
distFromShadow = yPos - shadowHeight;
f32 distFromShadow = yPos - shadowHeight;
/**
* Note that idx could be negative or otherwise out of the bounds of
* the `rectangles` array. In practice, it never is, because this was
@@ -856,8 +807,7 @@ Gfx *create_shadow_hardcoded_rectangle(f32 xPos, f32 yPos, f32 zPos, UNUSED s16
halfWidth = scale_shadow_with_distance(rectangles[idx].halfWidth, distFromShadow);
halfLength = scale_shadow_with_distance(rectangles[idx].halfLength, distFromShadow);
} else {
// This code is never used because the third element of the rectangle
// struct is always TRUE.
// This code is never used because the third element of the rectangle struct is always TRUE.
halfWidth = rectangles[idx].halfWidth;
halfLength = rectangles[idx].halfLength;
}
@@ -868,19 +818,14 @@ Gfx *create_shadow_hardcoded_rectangle(f32 xPos, f32 yPos, f32 zPos, UNUSED s16
* Create a shadow at the absolute position given, with the given parameters.
* Return a pointer to the display list representing the shadow.
*/
Gfx *create_shadow_below_xyz(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, u8 shadowSolidity,
s8 shadowType) {
Gfx *create_shadow_below_xyz(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, u8 shadowSolidity, s8 shadowType) {
Gfx *displayList = NULL;
struct Surface *pfloor;
find_floor(xPos, yPos, zPos, &pfloor);
gShadowAboveWaterOrLava = FALSE;
gShadowAboveCustomWater = FALSE;
gMarioOnIceOrCarpet = 0;
sMarioOnFlyingCarpet = 0;
gShadowFlags = SHADOW_FLAGS_NONE;
if (pfloor != NULL) {
if (pfloor->type == SURFACE_ICE) {
gMarioOnIceOrCarpet = 1;
gShadowFlags |= SHADOW_FLAG_ICE_CARPET;
}
sSurfaceTypeBelowShadow = pfloor->type;
}

View File

@@ -10,41 +10,42 @@
*/
enum ShadowType
{
SHADOW_CIRCLE_9_VERTS = 0,
SHADOW_CIRCLE_4_VERTS = 1,
SHADOW_CIRCLE_4_VERTS_FLAT_UNUSED = 2,
SHADOW_SQUARE_PERMANENT = 10,
SHADOW_SQUARE_SCALABLE = 11,
SHADOW_SQUARE_TOGGLABLE = 12,
SHADOW_CIRCLE_9_VERTS = 0,
SHADOW_CIRCLE_4_VERTS = 1,
SHADOW_CIRCLE_4_VERTS_FLAT_UNUSED = 2,
SHADOW_SQUARE_PERMANENT = 10,
SHADOW_SQUARE_SCALABLE = 11,
SHADOW_SQUARE_TOGGLABLE = 12,
/**
* This defines an offset after which rectangular shadows with custom
* widths and heights can be defined.
*/
SHADOW_RECTANGLE_HARDCODED_OFFSET = 50,
SHADOW_CIRCLE_PLAYER = 99
SHADOW_CIRCLE_PLAYER = 99
};
#define SHADOW_FLAGS_NONE (0 << 0)
/**
* Flag for if the current shadow is above water or lava.
*/
#define SHADOW_FLAG_WATER_BOX (1 << 0)
#define SHADOW_FLAG_WATER_SURFACE (1 << 1)
/**
* Flag for if Mario is on ice or a flying carpet.
*/
#define SHADOW_FLAG_ICE_CARPET (1 << 2)
/**
* Flag for if Mario is on a flying carpet.
*/
extern s8 sMarioOnFlyingCarpet;
#define SHADOW_FLAG_RAISED (1 << 3)
extern s8 gShadowFlags;
/**
* The surface type below the current shadow.
*/
extern s16 sSurfaceTypeBelowShadow;
/**
* Flag for if the current shadow is above water or lava.
*/
extern s8 gShadowAboveWaterOrLava;
extern s8 gShadowAboveCustomWater;
/**
* Flag for if Mario is on ice or a flying carpet.
*/
extern s8 gMarioOnIceOrCarpet;
/**
* Given the (x, y, z) location of an object, create a shadow below that object
* with the given initial solidity and "shadowType" (described above).

View File

@@ -19,10 +19,6 @@
#include "skin.h"
#include "skin_movement.h"
// data
static s32 D_801A82D0 = 0;
static struct ObjBone *gGdTempBone = NULL; // @ 801A82D4
// bss
s32 sResetWeightVtxNum; // WTF? why is this not in skin_movement.c?
@@ -711,7 +707,6 @@ void func_80190574(s32 a0, struct ObjJoint *a1, struct ObjJoint *a2, f32 x, f32
void func_801909B4(void) {
struct ObjJoint *node;
D_801A82D0 = 0;
node = gGdJointList;
while (node != NULL) {
node->unk1C0 = 0;