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. * 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/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/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/lib/PR/f3dex2/F3DEX2_Rej.bin b/lib/PR/f3dex2/F3DEX2_Rej.bin new file mode 100644 index 00000000..d752acf3 Binary files /dev/null and b/lib/PR/f3dex2/F3DEX2_Rej.bin differ diff --git a/lib/PR/f3dex2/F3DEX2_Rej_data.bin b/lib/PR/f3dex2/F3DEX2_Rej_data.bin new file mode 100644 index 00000000..4211afd4 Binary files /dev/null and b/lib/PR/f3dex2/F3DEX2_Rej_data.bin differ diff --git a/src/boot/main.c b/src/boot/main.c index 7a6851bf..a6656c0e 100644 --- a/src/boot/main.c +++ b/src/boot/main.c @@ -354,6 +354,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) { @@ -373,6 +376,9 @@ void thread3_main(UNUSED void *arg) { handle_nmi_request(); break; } +#if PUPPYPRINT_DEBUG + profiler_update(taskTime, first); +#endif } } 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 8b516d4f..4aabb66d 100644 --- a/src/game/crash_screen.c +++ b/src/game/crash_screen.c @@ -111,7 +111,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 33782742..ff23c907 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -282,7 +282,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 455190a3..cb66d761 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,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/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; diff --git a/src/game/puppylights.c b/src/game/puppylights.c index 441abf5c..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) @@ -187,6 +215,8 @@ 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; + s32 lightFlags = flags; if (gCurrLevelNum < 4) return; @@ -205,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); @@ -222,7 +251,14 @@ 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); + { + if (i == gDynLightStart) + lightFlags |= LIGHTFLAG_DIRECTIONAL_OFFSET; + else + lightFlags &= ~LIGHTFLAG_DIRECTIONAL_OFFSET; + puppylights_iterate(gPuppyLights[i], src, obj, lightFlags); + numlights++; + } } } @@ -248,7 +284,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 +308,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; } } 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), \ diff --git a/src/game/puppyprint.c b/src/game/puppyprint.c index 1f36f420..0a2ad4d7 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]; @@ -362,7 +364,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) @@ -487,6 +489,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 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 };