You've already forked Microtransactions64
mirror of
https://github.com/Print-and-Panic/Microtransactions64.git
synced 2026-01-21 10:17:19 -08:00
Merge branch 'master' into experimental
This commit is contained in:
@@ -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. *
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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[];
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
BIN
lib/PR/f3dex2/F3DEX2_Rej.bin
Normal file
BIN
lib/PR/f3dex2/F3DEX2_Rej.bin
Normal file
Binary file not shown.
BIN
lib/PR/f3dex2/F3DEX2_Rej_data.bin
Normal file
BIN
lib/PR/f3dex2/F3DEX2_Rej_data.bin
Normal file
Binary file not shown.
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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), \
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 };
|
||||
|
||||
Reference in New Issue
Block a user