From caab92960899156304e5e658eec60c64b5c1c538 Mon Sep 17 00:00:00 2001 From: Fazana <52551480+FazanaJ@users.noreply.github.com> Date: Thu, 9 Sep 2021 14:12:35 +0100 Subject: [PATCH 1/7] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4e02802f..4bd39bd7 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ This is a fork of the ultrasm64 repo by CrashOveride which includes the followin **Lighting Engine by Wiseguy** - Lighting Engine is available on a separate branch `(lighting-engine)`. Instructions on how to use it are in the readme of that branch. +- Alternatively, the main repo has `Puppylights` available, which is a more lightweight, but limited lighting library intended to be used to modify existing light properties. You can look at `puppylights.c` to find out how to use it. **Puppycam** - Puppycam is available on the master branch now, you can toogle it in config.h. * From b80529d0e97fe35ed394d6caf62c2d1cd118ee58 Mon Sep 17 00:00:00 2001 From: Arceveti <73617174+Arceveti@users.noreply.github.com> Date: Thu, 9 Sep 2021 12:09:13 -0700 Subject: [PATCH 2/7] Add OBJ_FLAG_VELOCITY_PLATFORM for velocity-based platform displacement for certain objects like the TTC treadmills --- data/behavior_data.c | 12 ++- include/object_constants.h | 4 +- src/game/platform_displacement.c | 172 +++++++++++++++---------------- 3 files changed, 95 insertions(+), 93 deletions(-) diff --git a/data/behavior_data.c b/data/behavior_data.c index 584b4402..344e8f8f 100644 --- a/data/behavior_data.c +++ b/data/behavior_data.c @@ -115,7 +115,7 @@ // Often used to end behavior scripts that do not contain an infinite loop. #define BREAK() \ BC_B(0x0A) - + // Exits the behavior script, unused. #define BREAK_UNUSED() \ BC_B(0x0B) @@ -176,15 +176,15 @@ #define ADD_INT_RAND_RSHIFT(field, min, rshift) \ BC_BBH(0x17, field, min), \ BC_H(rshift) - + // No operation. Unused. #define CMD_NOP_1(field) \ BC_BB(0x18, field) - + // No operation. Unused. #define CMD_NOP_2(field) \ BC_BB(0x19, field) - + // No operation. Unused. #define CMD_NOP_3(field) \ BC_BB(0x1A, field) @@ -5473,7 +5473,11 @@ const BehaviorScript bhvTTCPendulum[] = { const BehaviorScript bhvTTCTreadmill[] = { BEGIN(OBJ_LIST_SURFACE), +#ifdef PLATFORM_DISPLACEMENT_2 + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE | OBJ_FLAG_VELOCITY_PLATFORM)), +#else OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), +#endif SET_FLOAT(oCollisionDistance, 750), CALL_NATIVE(bhv_ttc_treadmill_init), DELAY(1), diff --git a/include/object_constants.h b/include/object_constants.h index 17a18c01..ac73b2d5 100644 --- a/include/object_constants.h +++ b/include/object_constants.h @@ -43,10 +43,8 @@ #define OBJ_FLAG_1000 (1 << 12) // 0x00001000 #define OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO (1 << 13) // 0x00002000 #define OBJ_FLAG_PERSISTENT_RESPAWN (1 << 14) // 0x00004000 -#define OBJ_FLAG_8000 (1 << 15) // 0x00008000 -#ifdef AUTO_COLLISION_DISTANCE +#define OBJ_FLAG_VELOCITY_PLATFORM (1 << 15) // 0x00008000 #define OBJ_FLAG_DONT_CALC_COLL_DIST (1 << 16) // 0x00010000 -#endif #define OBJ_FLAG_EMIT_LIGHT (1 << 17) // 0x00020000 #define OBJ_FLAG_HITBOX_WAS_SET (1 << 30) // 0x40000000 diff --git a/src/game/platform_displacement.c b/src/game/platform_displacement.c index 61859bf6..d2556960 100644 --- a/src/game/platform_displacement.c +++ b/src/game/platform_displacement.c @@ -97,15 +97,15 @@ extern s32 gGlobalTimer; * Upscale or downscale a vector by another vector. */ static void scale_vec3f(Vec3f dst, Vec3f src, Vec3f scale, u32 doInverted) { - if (doInverted) { - dst[0] = src[0] / scale[0]; - dst[1] = src[1] / scale[1]; - dst[2] = src[2] / scale[2]; - } else { - dst[0] = src[0] * scale[0]; - dst[1] = src[1] * scale[1]; - dst[2] = src[2] * scale[2]; - } + if (doInverted) { + dst[0] = src[0] / scale[0]; + dst[1] = src[1] / scale[1]; + dst[2] = src[2] / scale[2]; + } else { + dst[0] = src[0] * scale[0]; + dst[1] = src[1] * scale[1]; + dst[2] = src[2] * scale[2]; + } } /** @@ -113,74 +113,74 @@ static void scale_vec3f(Vec3f dst, Vec3f src, Vec3f scale, u32 doInverted) { * platform. */ void apply_platform_displacement(struct PlatformDisplacementInfo *displaceInfo, Vec3f pos, s16 *yaw, struct Object *platform) { - Vec3f platformPos; - Vec3f posDifference; - Vec3f yawVec; - Vec3f scaledPos; - // Determine how much Mario turned on his own since last frame - s16 yawDifference = *yaw - displaceInfo->prevYaw; + Vec3f platformPos; + Vec3f posDifference; + Vec3f yawVec; + Vec3f scaledPos; + // Determine how much Mario turned on his own since last frame + s16 yawDifference = *yaw - displaceInfo->prevYaw; - // Avoid a crash if the platform unloaded its collision while stood on - if (platform->header.gfx.throwMatrix == NULL) return; + // Avoid a crash if the platform unloaded its collision while stood on + if (platform->header.gfx.throwMatrix == NULL) return; - vec3f_copy(platformPos, (*platform->header.gfx.throwMatrix)[3]); + vec3f_copy(platformPos, (*platform->header.gfx.throwMatrix)[3]); - // Determine how far Mario moved on his own since last frame - vec3f_copy(posDifference, pos); - vec3f_sub(posDifference, displaceInfo->prevPos); + // Determine how far Mario moved on his own since last frame + vec3f_copy(posDifference, pos); + vec3f_sub(posDifference, displaceInfo->prevPos); - if ((platform == displaceInfo->prevPlatform) && (gGlobalTimer == displaceInfo->prevTimer + 1)) { - // Transform from relative positions to world positions - scale_vec3f(scaledPos, displaceInfo->prevTransformedPos, platform->header.gfx.scale, FALSE); - linear_mtxf_mul_vec3f(*platform->header.gfx.throwMatrix, pos, scaledPos); + if ((platform == displaceInfo->prevPlatform) && (gGlobalTimer == displaceInfo->prevTimer + 1)) { + // Transform from relative positions to world positions + scale_vec3f(scaledPos, displaceInfo->prevTransformedPos, platform->header.gfx.scale, FALSE); + linear_mtxf_mul_vec3f(*platform->header.gfx.throwMatrix, pos, scaledPos); - // Add on how much Mario moved in the previous frame - vec3f_add(pos, posDifference); + // Add on how much Mario moved in the previous frame + vec3f_add(pos, posDifference); - // Calculate new yaw - linear_mtxf_mul_vec3f(*platform->header.gfx.throwMatrix, yawVec, displaceInfo->prevTransformedYawVec); - *yaw = atan2s(yawVec[2], yawVec[0]) + yawDifference; - } else { - // First frame of standing on the platform, don't calculate a new position - vec3f_sub(pos, platformPos); - } + // Calculate new yaw + linear_mtxf_mul_vec3f(*platform->header.gfx.throwMatrix, yawVec, displaceInfo->prevTransformedYawVec); + *yaw = atan2s(yawVec[2], yawVec[0]) + yawDifference; + } else { + // First frame of standing on the platform, don't calculate a new position + vec3f_sub(pos, platformPos); + } - // Apply displacement specifically for TTC Treadmills - if (platform->behavior == segmented_to_virtual(bhvTTCTreadmill)) { + // Apply velocity-based displacement for certain objects (like the TTC Treadmills) + if (platform->oFlags & OBJ_FLAG_VELOCITY_PLATFORM) { pos[0] += platform->oVelX; pos[1] += platform->oVelY; pos[2] += platform->oVelZ; } - - // Transform from world positions to relative positions for use next frame - linear_mtxf_transpose_mul_vec3f(*platform->header.gfx.throwMatrix, scaledPos, pos); - scale_vec3f(displaceInfo->prevTransformedPos, scaledPos, platform->header.gfx.scale, TRUE); - vec3f_add(pos, platformPos); - // If the object is Mario, set inertia - if (pos == gMarioState->pos) { - vec3f_copy(sMarioAmountDisplaced, pos); - vec3f_sub(sMarioAmountDisplaced, displaceInfo->prevPos); - vec3f_sub(sMarioAmountDisplaced, posDifference); + // Transform from world positions to relative positions for use next frame + linear_mtxf_transpose_mul_vec3f(*platform->header.gfx.throwMatrix, scaledPos, pos); + scale_vec3f(displaceInfo->prevTransformedPos, scaledPos, platform->header.gfx.scale, TRUE); + vec3f_add(pos, platformPos); - // Make sure inertia isn't set on the first frame otherwise the previous value isn't cleared - if ((platform != displaceInfo->prevPlatform) || (gGlobalTimer != displaceInfo->prevTimer + 1)) { - vec3f_set(sMarioAmountDisplaced, 0.f, 0.f, 0.f); - } - } + // If the object is Mario, set inertia + if (pos == gMarioState->pos) { + vec3f_copy(sMarioAmountDisplaced, pos); + vec3f_sub(sMarioAmountDisplaced, displaceInfo->prevPos); + vec3f_sub(sMarioAmountDisplaced, posDifference); - // Update info for next frame - // Update position - vec3f_copy(displaceInfo->prevPos, pos); + // Make sure inertia isn't set on the first frame otherwise the previous value isn't cleared + if ((platform != displaceInfo->prevPlatform) || (gGlobalTimer != displaceInfo->prevTimer + 1)) { + vec3f_set(sMarioAmountDisplaced, 0.f, 0.f, 0.f); + } + } - // Set yaw info - vec3f_set(yawVec, sins(*yaw), 0, coss(*yaw)); - linear_mtxf_transpose_mul_vec3f(*platform->header.gfx.throwMatrix, displaceInfo->prevTransformedYawVec, yawVec); - displaceInfo->prevYaw = *yaw; + // Update info for next frame + // Update position + vec3f_copy(displaceInfo->prevPos, pos); - // Update platform and timer - displaceInfo->prevPlatform = platform; - displaceInfo->prevTimer = gGlobalTimer; + // Set yaw info + vec3f_set(yawVec, sins(*yaw), 0, coss(*yaw)); + linear_mtxf_transpose_mul_vec3f(*platform->header.gfx.throwMatrix, displaceInfo->prevTransformedYawVec, yawVec); + displaceInfo->prevYaw = *yaw; + + // Update platform and timer + displaceInfo->prevPlatform = platform; + displaceInfo->prevTimer = gGlobalTimer; } // Doesn't change in the code, set this to FALSE if you don't want inertia @@ -193,23 +193,23 @@ static u8 sInertiaFirstFrame = FALSE; * Apply inertia based on Mario's last platform. */ static void apply_mario_inertia(void) { - // On the first frame of leaving the ground, boost Mario's y velocity - if (sInertiaFirstFrame) { - gMarioState->vel[1] += sMarioAmountDisplaced[1]; - } + // On the first frame of leaving the ground, boost Mario's y velocity + if (sInertiaFirstFrame) { + gMarioState->vel[1] += sMarioAmountDisplaced[1]; + } - // Apply sideways inertia - gMarioState->pos[0] += sMarioAmountDisplaced[0]; - gMarioState->pos[2] += sMarioAmountDisplaced[2]; + // Apply sideways inertia + gMarioState->pos[0] += sMarioAmountDisplaced[0]; + gMarioState->pos[2] += sMarioAmountDisplaced[2]; - // Drag - sMarioAmountDisplaced[0] *= 0.97f; - sMarioAmountDisplaced[2] *= 0.97f; + // Drag + sMarioAmountDisplaced[0] *= 0.97f; + sMarioAmountDisplaced[2] *= 0.97f; - // Stop applying inertia once Mario has landed, or when ground pounding - if (!(gMarioState->action & ACT_FLAG_AIR) || (gMarioState->action == ACT_GROUND_POUND)) { - sShouldApplyInertia = FALSE; - } + // Stop applying inertia once Mario has landed, or when ground pounding + if (!(gMarioState->action & ACT_FLAG_AIR) || (gMarioState->action == ACT_GROUND_POUND)) { + sShouldApplyInertia = FALSE; + } } /** @@ -220,14 +220,14 @@ void apply_mario_platform_displacement(void) { platform = gMarioPlatform; if (!(gTimeStopState & TIME_STOP_ACTIVE) && gMarioObject != NULL) { - if (platform != NULL) { - apply_platform_displacement(&sMarioDisplacementInfo, gMarioState->pos, &gMarioState->faceAngle[1], platform); - sShouldApplyInertia = TRUE; - sInertiaFirstFrame = TRUE; - } else if (sShouldApplyInertia && gDoInertia) { - apply_mario_inertia(); - sInertiaFirstFrame = FALSE; - } + if (platform != NULL) { + apply_platform_displacement(&sMarioDisplacementInfo, gMarioState->pos, &gMarioState->faceAngle[1], platform); + sShouldApplyInertia = TRUE; + sInertiaFirstFrame = TRUE; + } else if (sShouldApplyInertia && gDoInertia) { + apply_mario_inertia(); + sInertiaFirstFrame = FALSE; + } } } #else @@ -271,9 +271,9 @@ void apply_platform_displacement(u32 isMario, struct Object *platform) { unused1 = rotation[0]; unused2 = rotation[2]; unused3 = platform->oFaceAngleYaw; - if (isMario) { - gMarioStates[0].faceAngle[1] += rotation[1]; - } + if (isMario) { + gMarioStates[0].faceAngle[1] += rotation[1]; + } platformPosX = platform->oPosX; platformPosY = platform->oPosY; platformPosZ = platform->oPosZ; From 99daddfc1d2002fe7a11bb50c8cc4589aff4305d Mon Sep 17 00:00:00 2001 From: CrashOveride95 Date: Fri, 10 Sep 2021 06:40:52 -0400 Subject: [PATCH 3/7] Add F3DEX2_Rej --- lib/PR/f3dex2/F3DEX2_Rej.bin | Bin 0 -> 4488 bytes lib/PR/f3dex2/F3DEX2_Rej_data.bin | Bin 0 -> 1040 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 lib/PR/f3dex2/F3DEX2_Rej.bin create mode 100644 lib/PR/f3dex2/F3DEX2_Rej_data.bin diff --git a/lib/PR/f3dex2/F3DEX2_Rej.bin b/lib/PR/f3dex2/F3DEX2_Rej.bin new file mode 100644 index 0000000000000000000000000000000000000000..d752acf3329273aa4b54187fa428178c841de76c GIT binary patch literal 4488 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 Date: Fri, 10 Sep 2021 12:16:58 +0100 Subject: [PATCH 4/7] Puppylight crash fix --- src/game/object_list_processor.c | 3 +++ src/game/puppylights.c | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/game/object_list_processor.c b/src/game/object_list_processor.c index 455190a3..d9818895 100644 --- a/src/game/object_list_processor.c +++ b/src/game/object_list_processor.c @@ -20,6 +20,7 @@ #include "profiler.h" #include "spawn_object.h" #include "puppyprint.h" +#include "puppylights.h" /** @@ -386,6 +387,8 @@ s32 unload_deactivated_objects_in_list(struct ObjectNode *objList) { obj = obj->next; if ((gCurrentObject->activeFlags & ACTIVE_FLAG_ACTIVE) != ACTIVE_FLAG_ACTIVE) { + if (gCurrentObject->oLightID != 0xFFFF) + obj_disable_light(gCurrentObject); // Prevent object from respawning after exiting and re-entering the // area if (!(gCurrentObject->oFlags & OBJ_FLAG_PERSISTENT_RESPAWN)) { diff --git a/src/game/puppylights.c b/src/game/puppylights.c index 441abf5c..3e07edd7 100644 --- a/src/game/puppylights.c +++ b/src/game/puppylights.c @@ -187,6 +187,7 @@ void puppylights_iterate(struct PuppyLight *light, Lights1 *src, struct Object * void puppylights_run(Lights1 *src, struct Object *obj, s32 flags, u32 baseColour) { s32 i; + s32 numlights = 0; if (gCurrLevelNum < 4) return; @@ -222,7 +223,10 @@ void puppylights_run(Lights1 *src, struct Object *obj, s32 flags, u32 baseColour for (i = 0; i < gNumLights; i++) { if (gPuppyLights[i]->rgba[3] > 0 && gPuppyLights[i]->active == TRUE && gPuppyLights[i]->area == gCurrAreaIndex && (gPuppyLights[i]->room == -1 || gPuppyLights[i]->room == gMarioCurrentRoom)) + { puppylights_iterate(gPuppyLights[i], src, obj); + numlights++; + } } } @@ -248,7 +252,7 @@ void puppylights_object_emit(struct Object *obj) { if (ABS(gNumLights - gDynLightStart) < MAX_LIGHTS_DYNAMIC) goto deallocate; - for (i = gDynLightStart; i < MAX_LIGHTS; i++) + for (i = gDynLightStart; i < MIN(gDynLightStart+MAX_LIGHTS_DYNAMIC, MAX_LIGHTS); i++) { if (gPuppyLights[i]->active == TRUE) continue; @@ -272,7 +276,10 @@ void puppylights_object_emit(struct Object *obj) { deallocate: if (obj->oLightID != 0xFFFF) + { gPuppyLights[obj->oLightID]->active = FALSE; + gPuppyLights[obj->oLightID]->flags = 0; + } obj->oLightID = 0xFFFF; } } From f34cb5dd3dfe9d61452eab15a185bce56f2b9fc8 Mon Sep 17 00:00:00 2001 From: Fazana <52551480+FazanaJ@users.noreply.github.com> Date: Sat, 11 Sep 2021 15:24:10 +0100 Subject: [PATCH 5/7] Puppylights Bugfixes Distance scaling is now correct on every axis, and there is a new flag, that will ignore the Y axis completely when calculating distance scaling. Additionally, ambient lights will now only apply brightening once for directional lights, and the light diffuse now approaches the correct value, eliminating light clipping. --- src/game/puppylights.c | 104 +++++++++++++++++++++++++++-------------- src/game/puppylights.h | 3 ++ 2 files changed, 71 insertions(+), 36 deletions(-) diff --git a/src/game/puppylights.c b/src/game/puppylights.c index 3e07edd7..9b5ee0b9 100644 --- a/src/game/puppylights.c +++ b/src/game/puppylights.c @@ -73,34 +73,57 @@ void puppylights_allocate(void) extern Mat4 gMatStack[32]; //Function that iterates through each light. -void puppylights_iterate(struct PuppyLight *light, Lights1 *src, struct Object *obj) +void puppylights_iterate(struct PuppyLight *light, Lights1 *src, struct Object *obj, s32 flags) { Lights1 *tempLight; s32 lightPos[2]; Vec3i lightRelative; Vec3i lightDir = {0, 0, 0}; - s32 lightIntensity = 0; s32 i; s32 colour; s32 ambient; - f64 scale = 1.0f; + f64 scaleOrig; + f32 scale; f32 scale2; f64 scaleVal = 1.0f; + Vec3f debugPos[2]; - //Relative positions of the object vs the centre of the node. + //Relative positions of the object vs. the centre of the node. lightRelative[0] = light->pos[0][0] - obj->oPosX; lightRelative[1] = light->pos[0][1] - obj->oPosY; lightRelative[2] = light->pos[0][2] - obj->oPosZ; + //If the nodes X and Z values are equal, then a check is made if the angle is a derivative of 90. + //If so, then it will completely skip over the calculation that figures out position from rotation. + //If it's a cylinder, then it ignores that check, simply because an equal sided cylinder will have the + //same result no matter the yaw. If neither is true, then it simply checks if it's 180 degrees, since + //That will just be the same as 0. + if (light->pos[1][0] == light->pos[1][2]) + { + if (light->yaw % 0x4000 == 0 || light->flags & PUPPYLIGHT_SHAPE_CYLINDER) + { + lightPos[0] = lightRelative[0]; + lightPos[1] = lightRelative[2]; + goto skippingTrig; + } + } + else + if (light->yaw % 0x8000 == 0) + { + lightPos[0] = lightRelative[0]; + lightPos[1] = lightRelative[2]; + goto skippingTrig; + } + //Get the position based off the rotation of the box. lightPos[0] = lightRelative[2] * sins(-light->yaw) + lightRelative[0] * coss(-light->yaw); lightPos[1] = lightRelative[2] * coss(-light->yaw) - lightRelative[0] * sins(-light->yaw); + skippingTrig: #ifdef VISUAL_DEBUG - Vec3f debugPos[2]; vec3f_set(debugPos[0], light->pos[0][0], light->pos[0][1], light->pos[0][2]); vec3f_set(debugPos[1], light->pos[1][0], light->pos[1][1], light->pos[1][2]); - debug_box_color(0x00FF0040); + debug_box_color(0x08FF00FF); if (light->flags & PUPPYLIGHT_SHAPE_CYLINDER) debug_box_rot(debugPos[0], debugPos[1], light->yaw, DEBUG_SHAPE_CYLINDER); else @@ -116,40 +139,39 @@ void puppylights_iterate(struct PuppyLight *light, Lights1 *src, struct Object * //This way, the colour value will scale correctly, no matter which side is entered. //Because positions are a vector, and Y is up, it means tempID needs to be multiplied //By 2 in order to reach the X and Z axis. Thanks SM64. - s32 lightPos2[2]; - lightPos2[0] = light->pos[1][2] * sins(-light->yaw) + light->pos[1][0] * coss(-light->yaw); - lightPos2[1] = light->pos[1][2] * coss(-light->yaw) - light->pos[1][0] * sins(-light->yaw); - s32 tempID; - f32 scaleFac; - if (ABS(lightPos2[0]) > ABS(lightPos2[1])) - tempID = 0; + //It will skip scaling the opposite axis if there's no need to. + + //Every axis needs to be the same as Z, so X and Y, if necessary, will be scaled to match it. + //This is done, so that when calculating scale, it's done spherically. + if (light->pos[1][0] != light->pos[1][2]) + lightPos[0] /= ((f32)light->pos[1][0]/light->pos[1][2]); + //Same for Y axis. + if (light->pos[1][1] != light->pos[1][2]) + lightRelative[1] /= ((f32)light->pos[1][1]/light->pos[1][2]); + + if (light->flags & PUPPYLIGHT_IGNORE_Y) + scaleOrig = (lightPos[0] * lightPos[0]) + (lightPos[1] * lightPos[1]); else - tempID = 1; - scaleFac = (f32)light->pos[1][(tempID^1)*2]/(f32)light->pos[1][tempID*2]; - lightPos[tempID] *= scaleFac; - scale = (lightPos[0] * lightPos[0]) + (lightRelative[1] * lightRelative[1]) + (lightPos[1] * lightPos[1]); - scaleVal = (light->pos[1][0] + light->pos[1][1] + light->pos[1][2])/3; - scaleVal *= scaleVal; + scaleOrig = (lightPos[0] * lightPos[0]) + (lightRelative[1] * lightRelative[1]) + (lightPos[1] * lightPos[1]); + scaleVal = (light->pos[1][2]*light->pos[1][2]); //If it's a cylinder, then bin anything outside it. if (light->flags & PUPPYLIGHT_SHAPE_CYLINDER) { - if (scale > scaleVal) + if (scaleOrig > scaleVal) return; } } else return; + f32 epc = (f32)(light->epicentre/100.0f); tempLight = segmented_to_virtual(src); //Now we have a scale value and a scale factor, we can start lighting things up. //Convert to a percentage. - scale /= scaleVal; - scale = CLAMP(scale, 0.0f, 1.0f); + scale = CLAMP(scaleOrig/scaleVal, 0.0f, 1.0f); //Reduce scale2 by the epicentre. - scale2 = (scale - (f32)(light->epicentre/100.0f)) * (1+(f32)(light->epicentre/100.0f)); - scale2 = CLAMP(scale2, 0.0f, 1.0f); - //Normalise the light brightness. - lightIntensity = (tempLight->a.l.col[0]+tempLight->a.l.col[1]+tempLight->a.l.col[2])/3.0f; + scale2 = CLAMP((scale - epc) * (1+epc), 0.0f, 1.0f); + //Get the direction numbers we want by applying some maths to the relative positions. We use 64 because light directions range from -64 to 63. //Note: can this be optimised further? Simply squaring lightRelative and then dividing it by preScale doesn't work. if (light->flags & PUPPYLIGHT_DIRECTIONAL) @@ -162,19 +184,25 @@ void puppylights_iterate(struct PuppyLight *light, Lights1 *src, struct Object * for (i = 0; i < 3; i++) { //So it works by starting from the final colour, and then lerping to the original colour, by a factor of the epicentre corrected scale. Light opacity affects this further. - colour = approach_f32_asymptotic(light->rgba[i], sLightBase->l[0].l.col[i], scale2*((f32)light->rgba[3]/255.0f)); + colour = approach_f32_asymptotic(light->rgba[i], tempLight->l[0].l.col[i], scale2*((f32)light->rgba[3]/255.0f)); //If it's a directional light, then increase the current ambient by 50%, to give the effect better. //Otherwise, just normalise the brightness to keep it in line with the current ambient. - if (light->flags & PUPPYLIGHT_DIRECTIONAL) - ambient = approach_f32_asymptotic(MIN(tempLight->a.l.col[i]*1.5f, 0xFF), tempLight->a.l.col[i], scale*((f32)light->rgba[3]/255.0f)); - else - ambient = approach_f32_asymptotic(lightIntensity, tempLight->a.l.col[i], scale*((f32)light->rgba[3]/255.0f)); //And now to apply the values. tempLight->l[0].l.col[i] = colour; tempLight->l[0].l.colc[i] = colour; //Ambient, too. - tempLight->a.l.col[i] = ambient; - tempLight->a.l.colc[i] = ambient; + if (!(light->flags & PUPPYLIGHT_DIRECTIONAL)) + { + ambient = approach_f32_asymptotic(light->rgba[i]/2, tempLight->a.l.col[i], scale*((f32)light->rgba[3]/255.0f)); + tempLight->a.l.col[i] = ambient; + tempLight->a.l.colc[i] = ambient; + } + //A slightly hacky way to offset the ambient lighting in order to prevent directional lighting from having a noticeable change in ambient brightness. + if (flags & LIGHTFLAG_DIRECTIONAL_OFFSET) + { + tempLight->a.l.col[i] *= 1.5f; + tempLight->a.l.colc[i] *= 1.5f; + } //Apply direction. It takes the relative positions, and then multiplies them with the perspective matrix to get a correct direction. //Index 1 of the first dimension of gMatStack is perspective. Note that if you ever decide to cheat your way into rendering things after the game does :^) if (light->flags & PUPPYLIGHT_DIRECTIONAL) @@ -188,6 +216,7 @@ void puppylights_run(Lights1 *src, struct Object *obj, s32 flags, u32 baseColour { s32 i; s32 numlights = 0; + s32 lightFlags = flags; if (gCurrLevelNum < 4) return; @@ -206,8 +235,7 @@ void puppylights_run(Lights1 *src, struct Object *obj, s32 flags, u32 baseColour else { s32 colour; - Lights1 tempLight; - sLightBase = &tempLight; + sLightBase = (levelAmbient) ? &gLevelLight : &sDefaultLights; for (i = 0; i < 3; i++) { colour = (((baseColour >> (24-(i*8)))) & 0xFF); @@ -224,7 +252,11 @@ void puppylights_run(Lights1 *src, struct Object *obj, s32 flags, u32 baseColour { if (gPuppyLights[i]->rgba[3] > 0 && gPuppyLights[i]->active == TRUE && gPuppyLights[i]->area == gCurrAreaIndex && (gPuppyLights[i]->room == -1 || gPuppyLights[i]->room == gMarioCurrentRoom)) { - puppylights_iterate(gPuppyLights[i], src, obj); + if (i == gDynLightStart) + lightFlags |= LIGHTFLAG_DIRECTIONAL_OFFSET; + else + lightFlags &= ~LIGHTFLAG_DIRECTIONAL_OFFSET; + puppylights_iterate(gPuppyLights[i], src, obj, lightFlags); numlights++; } } diff --git a/src/game/puppylights.h b/src/game/puppylights.h index bf428b56..c8a642a7 100644 --- a/src/game/puppylights.h +++ b/src/game/puppylights.h @@ -18,6 +18,9 @@ #define PUPPYLIGHT_SHADOW 0x10 #define PUPPYLIGHT_WET 0x20 #define PUPPYLIGHT_DELETE 0x40 +#define PUPPYLIGHT_IGNORE_Y 0x80 + +#define LIGHTFLAG_DIRECTIONAL_OFFSET 0x1 #define PUPPYLIGHT_ENVIRONMENT(ambientR, ambientG, ambientB, diffuseR, diffuseG, diffuseB, diffuseX, diffuseY, diffuseZ) \ CMD_BBBB(0x3F, 0x0C, ambientR, ambientG), \ From a1b2080b26aacdbbb984d039e9c3fdcfd769a32d Mon Sep 17 00:00:00 2001 From: Arceveti <73617174+Arceveti@users.noreply.github.com> Date: Sat, 11 Sep 2021 10:58:54 -0700 Subject: [PATCH 6/7] Fix build & build warnings --- include/eu_translation.h | 7 +------ src/engine/level_script.c | 2 +- src/game/crash_screen.c | 2 +- src/game/ingame_menu.c | 2 +- src/game/object_list_processor.c | 2 ++ src/menu/file_select.c | 4 ++-- 6 files changed, 8 insertions(+), 11 deletions(-) diff --git a/include/eu_translation.h b/include/eu_translation.h index 90f62ff4..ab04abfb 100644 --- a/include/eu_translation.h +++ b/include/eu_translation.h @@ -3,12 +3,7 @@ // EU changes most text to arrays for each language. This define allows these // differences to be combined. -#ifdef VERSION_EU - //#define LANGUAGE_ARRAY(cmd) cmd[LANGUAGE_FUNCTION] - #define LANGUAGE_ARRAY(cmd) cmd -#else - #define LANGUAGE_ARRAY(cmd) cmd -#endif +#define LANGUAGE_ARRAY(cmd) cmd extern void *dialog_table_eu_en[]; extern void *course_name_table_eu_en[]; diff --git a/src/engine/level_script.c b/src/engine/level_script.c index 4d76ee82..239e79f5 100644 --- a/src/engine/level_script.c +++ b/src/engine/level_script.c @@ -307,7 +307,7 @@ static void level_cmd_load_yay0_texture(void) { sCurrentCmd = CMD_NEXT; } -static void level_cmd_change_area_skybox(int area, u8 *start, u8 *end) { +static void level_cmd_change_area_skybox(void) { u8 areaCheck = CMD_GET(s16, 2); gAreaSkyboxStart[areaCheck-1] = CMD_GET(void *, 4); gAreaSkyboxEnd[areaCheck-1] = CMD_GET(void *, 8); diff --git a/src/game/crash_screen.c b/src/game/crash_screen.c index f412496e..2b85b42a 100644 --- a/src/game/crash_screen.c +++ b/src/game/crash_screen.c @@ -108,7 +108,7 @@ void crash_screen_print(s32 x, s32 y, const char *fmt, ...) { u32 glyph; s32 size; char buf[0x108]; - s32 i = 0; + UNUSED s32 i = 0; memset(buf, 0, sizeof(buf)); diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index 7d3175b6..46966786 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -281,7 +281,7 @@ u8 *alloc_ia4_tex_from_i1(u8 *in, s16 width, s16 height) { void render_generic_char(u8 c) { void **fontLUT; void *packedTexture; - void *unpackedTexture; + UNUSED void *unpackedTexture; fontLUT = segmented_to_virtual(main_font_lut); packedTexture = segmented_to_virtual(fontLUT[c]); diff --git a/src/game/object_list_processor.c b/src/game/object_list_processor.c index d9818895..cb66d761 100644 --- a/src/game/object_list_processor.c +++ b/src/game/object_list_processor.c @@ -387,8 +387,10 @@ s32 unload_deactivated_objects_in_list(struct ObjectNode *objList) { obj = obj->next; if ((gCurrentObject->activeFlags & ACTIVE_FLAG_ACTIVE) != ACTIVE_FLAG_ACTIVE) { +#ifdef PUPPYLIGHTS if (gCurrentObject->oLightID != 0xFFFF) obj_disable_light(gCurrentObject); +#endif // Prevent object from respawning after exiting and re-entering the // area if (!(gCurrentObject->oFlags & OBJ_FLAG_PERSISTENT_RESPAWN)) { diff --git a/src/menu/file_select.c b/src/menu/file_select.c index 7f7dfb9e..aa9f2a44 100644 --- a/src/menu/file_select.c +++ b/src/menu/file_select.c @@ -116,7 +116,7 @@ s8 sScoreFileCoinScoreMode = 0; // In EU, if no save file exists, open the language menu so the user can find it. -unsigned char textReturn[][8] = { {TEXT_RETURN}, }; +unsigned char textReturn[] = { TEXT_RETURN }; unsigned char textViewScore[] = { TEXT_CHECK_SCORE }; @@ -130,7 +130,7 @@ unsigned char textSoundModes[][8] = { { TEXT_STEREO }, { TEXT_MONO }, { TEXT_HEA unsigned char textLanguageSelect[][17] = { { TEXT_LANGUAGE_SELECT }}; #endif -unsigned char textSoundSelect[][13] = { { TEXT_SOUND_SELECT },}; +unsigned char textSoundSelect[] = { TEXT_SOUND_SELECT }; unsigned char textMarioA[] = { TEXT_FILE_MARIO_A }; unsigned char textMarioB[] = { TEXT_FILE_MARIO_B }; From df0e11f6a195b58db82b3501d008f14642545159 Mon Sep 17 00:00:00 2001 From: Fazana <52551480+FazanaJ@users.noreply.github.com> Date: Sat, 11 Sep 2021 22:29:53 +0100 Subject: [PATCH 7/7] Puppyprint CPU reading tweak --- src/boot/main.c | 6 ++++++ src/game/puppyprint.c | 6 +++++- src/game/puppyprint.h | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/boot/main.c b/src/boot/main.c index c4e3b8f6..76ffce96 100644 --- a/src/boot/main.c +++ b/src/boot/main.c @@ -352,6 +352,9 @@ void thread3_main(UNUSED void *arg) { while (TRUE) { OSMesg msg; +#if PUPPYPRINT_DEBUG + OSTime first = osGetTime(); +#endif osRecvMesg(&gIntrMesgQueue, &msg, OS_MESG_BLOCK); switch ((uintptr_t) msg) { @@ -371,6 +374,9 @@ void thread3_main(UNUSED void *arg) { handle_nmi_request(); break; } +#if PUPPYPRINT_DEBUG + profiler_update(taskTime, first); +#endif } } diff --git a/src/game/puppyprint.c b/src/game/puppyprint.c index ee1e37b6..9b761a36 100644 --- a/src/game/puppyprint.c +++ b/src/game/puppyprint.c @@ -76,6 +76,8 @@ OSTime graphTime[NUM_PERF_ITERATIONS+1]; OSTime audioTime[NUM_PERF_ITERATIONS+1]; OSTime dmaTime[NUM_PERF_ITERATIONS+1]; OSTime dmaAudioTime[NUM_PERF_ITERATIONS+1]; +OSTime faultTime[NUM_PERF_ITERATIONS+1]; +OSTime taskTime[NUM_PERF_ITERATIONS+1]; //RSP OSTime audioTime[NUM_PERF_ITERATIONS+1]; OSTime rspGenTime[NUM_PERF_ITERATIONS+1]; @@ -359,7 +361,7 @@ void puppyprint_render_profiler(void) s32 perfPercentage[5]; s32 graphPos; s32 prevGraph; - OSTime cpuCount = OS_CYCLES_TO_USEC(cpuTime+audioTime[NUM_PERF_ITERATIONS]+dmaAudioTime[NUM_PERF_ITERATIONS]); + OSTime cpuCount = OS_CYCLES_TO_USEC(cpuTime+audioTime[NUM_PERF_ITERATIONS]+dmaAudioTime[NUM_PERF_ITERATIONS]+faultTime[NUM_PERF_ITERATIONS]+taskTime[NUM_PERF_ITERATIONS]); char textBytes[80]; if (!fDebug) @@ -484,6 +486,8 @@ void puppyprint_profiler_process(void) get_average_perf_time(audioTime); get_average_perf_time(dmaTime); get_average_perf_time(dmaAudioTime); + get_average_perf_time(faultTime); + get_average_perf_time(taskTime); dmaTime[NUM_PERF_ITERATIONS] += dmaAudioTime[NUM_PERF_ITERATIONS]; diff --git a/src/game/puppyprint.h b/src/game/puppyprint.h index a563388d..ca738286 100644 --- a/src/game/puppyprint.h +++ b/src/game/puppyprint.h @@ -45,6 +45,8 @@ extern OSTime graphTime[NUM_PERF_ITERATIONS+1]; extern OSTime audioTime[NUM_PERF_ITERATIONS+1]; extern OSTime dmaTime[NUM_PERF_ITERATIONS+1]; extern OSTime dmaAudioTime[NUM_PERF_ITERATIONS+1]; +extern OSTime faultTime[NUM_PERF_ITERATIONS+1]; +extern OSTime taskTime[NUM_PERF_ITERATIONS+1]; //RSP extern OSTime rspGenTime[NUM_PERF_ITERATIONS+1]; //RDP