diff --git a/patches/Makefile b/patches/Makefile index 99016bf..dea4de2 100644 --- a/patches/Makefile +++ b/patches/Makefile @@ -6,7 +6,7 @@ LD ?= ld.lld GBI_DEFINE := -DF3DEX_GBI CFLAGS := -target mips -mips2 -mabi=32 -O2 -G0 -mno-abicalls -mno-odd-spreg -mno-check-zero-division \ -fomit-frame-pointer -ffast-math -fno-unsafe-math-optimizations -fno-builtin-memset \ - -Wall -Wextra -Wno-incompatible-library-redeclaration -Wno-unused-parameter -Wno-unknown-pragmas -Wno-unused-variable -Wno-missing-braces -Wno-unsupported-floating-point-opt + -Wall -Wextra -Wno-incompatible-library-redeclaration -Wno-unused-parameter -Wno-unknown-pragmas -Wno-unused-variable -Wno-missing-braces -Wno-unsupported-floating-point-opt -Wno-cast-function-type-mismatch CPPFLAGS := -nostdinc -D_LANGUAGE_C -DMIPS -I ../lib/bk-decomp/include -I ../lib/bk-decomp/include/2.0L -I ../lib/bk-decomp/include/2.0L/PR -I../lib/rt64/include $(GBI_DEFINE) LDFLAGS := -nostdlib -T patches.ld -T syms.ld -Map patches.map --unresolved-symbols=ignore-all --emit-relocs diff --git a/patches/particle_transform_tagging.c b/patches/particle_transform_tagging.c new file mode 100644 index 0000000..63d4394 --- /dev/null +++ b/patches/particle_transform_tagging.c @@ -0,0 +1,226 @@ +#include "patches.h" +#include "transform_ids.h" +#include "functions.h" +#include "rand.h" +#include "core1/ml.h" +#include "core2/anctrl.h" +#include "core2/modelRender.h" +#include "core2/particle.h" +#include "core2/timedfunc.h" + +// 2 bytes of padding between alpha and particleAccerationRange_4C. Must be at least 16-bit to fit the full range of PARTICLE_EMITTER_MAX_ID. +#define PARTICLE_EMITTER_ID(x) (*(u16*)&((x)->pad4A)) + +// 2 bytes of padding between unk104 and unk108. Must be at least 16-bit to fit the full range of PARTICLE_EMITTER_TRANSFORM_ID_COUNT. +#define PARTICLE_EMITTER_SPAWN_COUNT(x) (*(u16*)&((x)->pad106)) + +// 2 bytes of padding after unk5C (skipping 1 byte for alignment). Must be at least as bit as the emitter spawn count field. +#define PARTICLE_ID(x) (*(u16*)&(&(x)->unk5C)[2]) + +u32 particle_emitter_spawn_count = 0; + +extern ParticleEmitter **partEmitMgr; +extern s32 partEmitMgrLength; + +typedef struct particle{ + f32 acceleration[3]; + f32 fade; + f32 frame; //frame + f32 framerate; //framerate + f32 position[3]; + f32 rotation[3]; + f32 scale; //size + f32 initialSize_34; //initial_size + f32 finalSizeDiff; //delta_size + f32 angluar_velocity[3]; + f32 age_48; + f32 lifetime_4C; + f32 velocity_50[3]; + u8 unk5C; + //u8 pad5D[3]; +} Particle; + +extern Gfx D_80368978[]; +extern Gfx D_80368940[]; + +void __particleEmitter_drawOnPass(ParticleEmitter *this, Gfx **gfx, Mtx **mtx, Vtx **vtx, u32 draw_pass); +void func_803382E4(s32); +void func_80338338(s32, s32, s32); +void func_803382B4(s32 arg0, s32 arg1, s32 arg2, s32 arg3); +void func_80338370(void); +void func_80335D30(Gfx **); +void func_802EED1C(ParticleEmitter *this, f32 age, f32 arg2[3]); +void func_80344C2C(bool arg0); +void func_80344720(BKSpriteDisplayData *arg0, s32 frame, bool mirrored, f32 position[3], f32 rotation[3], f32 scale[3], Gfx **gfx, Mtx **mtx); +void func_80344424(BKSpriteDisplayData *arg0, s32 frame, bool mirrored, f32 position[3], f32 scale[3], f32 rotation, Gfx **gfx, Mtx **mtx); +void func_8033687C(Gfx **); + +// @recomp Patched to tag particles as they're drawn. +RECOMP_PATCH void __particleEmitter_drawOnPass(ParticleEmitter *this, Gfx **gfx, Mtx **mtx, Vtx **vtx, u32 draw_pass){ + f32 position[3]; + f32 flat_rotation[3]; + f32 scale[3]; + Particle *iPtr; + + // @recomp Get the particle emitter's ID. + u32 cur_particle_emitter_index = PARTICLE_EMITTER_ID(this); + + if(reinterpret_cast(u32, draw_pass) != (this->draw_mode & 0x4) != 0) + return; + + if(this->model_20 != NULL){ + for(iPtr = this->pList_start_124; iPtr < this->pList_end_128; iPtr++){ + position[0] = iPtr->position[0] + this->unk4[0]; + position[1] = iPtr->position[1] + this->unk4[1]; + position[2] = iPtr->position[2] + this->unk4[2]; + if( 0.0f != this->fade_in || 1.0 != this->fade_out || this->alpha != 0xff ){ + modelRender_setAlpha((s32) (iPtr->fade*this->alpha)); + }//L802EEF5C + modelRender_setDepthMode((this->draw_mode & PART_EMIT_NO_DEPTH)? MODEL_RENDER_DEPTH_NONE : MODEL_RENDER_DEPTH_FULL); + // @recomp Get the particle's ID. Restrict it to the model particle emitter ID count to account for the smaller number of base transform IDs for + // model particle emitters. + u32 particle_id = PARTICLE_ID(iPtr) % PARTICLE_EMITTER_MODEL_ID_COUNT; + // @recomp Set the current model transform ID. Divide the total per-emitter transform ID count by the per-model transform ID count to get the + // base transform ID for the current model particle. + cur_drawn_model_transform_id = + PARTICLE_TRANSFORM_ID_START + + PARTICLE_EMITTER_TRANSFORM_ID_COUNT * cur_particle_emitter_index + + particle_id * PARTICLE_EMITTER_MODEL_ID_COUNT; + modelRender_draw(gfx, mtx, position, iPtr->rotation, iPtr->scale, NULL, this->model_20); + // @recomp Reset the current model transform ID. + cur_drawn_model_transform_id = 0; + } + return; + } + + if(this->unk34){//L802EEFC4 + if( this->rgb[0] != 0xff + || this->rgb[1] != 0xff + || this->rgb[2] != 0xff + || this->alpha != 0xff + ){ + func_803382E4((this->draw_mode & PART_EMIT_NO_DEPTH)? 9: 0xf); + func_80338338(this->rgb[0], this->rgb[1], this->rgb[2]); + func_803382B4( + (this->rgb[0] < 8)? 0 : this->rgb[0] - 8, + (this->rgb[1] < 8)? 0 : this->rgb[1] - 8, + (this->rgb[2] < 8)? 0 : this->rgb[2] - 8, + (this->draw_mode & PART_EMIT_NO_OPA)? 0xff : this->alpha + ); + func_80338370(); + func_80335D30(gfx); + } + else if(this->draw_mode & PART_EMIT_NO_DEPTH){//L802EF0C0 + gSPDisplayList((*gfx)++, D_80368978); + } + else{//L802EF0EC + gSPDisplayList((*gfx)++, D_80368940); + }//L802EF10C + flat_rotation[0] = 90.0f; + flat_rotation[1] = 0.0f; + flat_rotation[2] = 0.0f; + for(iPtr = this->pList_start_124; iPtr < this->pList_end_128; iPtr++){ + gDPSetPrimColor((*gfx)++, 0, 0, this->rgb[0], this->rgb[1], this->rgb[2], iPtr->fade*this->alpha); + position[0] = iPtr->position[0] + this->unk4[0]; + position[1] = iPtr->position[1] + this->unk4[1]; + position[2] = iPtr->position[2] + this->unk4[2]; + + scale[0] = iPtr->scale; + scale[1] = iPtr->scale; + scale[2] = iPtr->scale; + if(0.0f != this->unk108){ + func_802EED1C(this, iPtr->age_48, scale); + } + func_80344C2C(this->unk0_16); + // @recomp Set the matrix group for this particle. + u32 transform_id = + PARTICLE_TRANSFORM_ID_START + + PARTICLE_EMITTER_TRANSFORM_ID_COUNT * cur_particle_emitter_index + + PARTICLE_ID(iPtr); + gEXMatrixGroupDecomposedNormal((*gfx)++, transform_id, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW); + + if(this->draw_mode & PART_EMIT_ROTATABLE){ + func_80344720(this->unk34, (s32)iPtr->frame, 0, position, flat_rotation, scale, gfx, mtx); + }//L802EF2F8 + else{ + func_80344424(this->unk34, (s32)iPtr->frame, 0, position, scale, iPtr->rotation[2], gfx, mtx); + }//L802EF324 + + // @recomp Pop the particle's matrix group. + gEXPopMatrixGroup((*gfx)++, G_MTX_MODELVIEW); + }//L802EF338 + if( this->rgb[0] != 0xff || this->rgb[1] != 0xff || this->rgb[2] != 0xff || this->alpha != 0xff + ){ + func_8033687C(gfx); + } + } +} + +// @recomp Patched to set an incrementing ID for the emitter. +RECOMP_PATCH ParticleEmitter *partEmitMgr_newEmitter(u32 cnt){ + partEmitMgr = realloc(partEmitMgr, (++partEmitMgrLength)*4); + partEmitMgr[partEmitMgrLength - 1] = particleEmitter_new(cnt); + partEmitMgr[partEmitMgrLength - 1]->auto_free = TRUE; + // @recomp Set the particle emitter's ID based on the emitter spawn count and increment the spawn count. + PARTICLE_EMITTER_ID(partEmitMgr[partEmitMgrLength - 1]) = particle_emitter_spawn_count; + particle_emitter_spawn_count++; + particle_emitter_spawn_count = particle_emitter_spawn_count % PARTICLE_EMITTER_MAX_ID; + + return partEmitMgr[partEmitMgrLength - 1]; +} + +// @recomp Patched to set an incrementing ID for the particle. +RECOMP_PATCH void __particleEmitter_initParticle(ParticleEmitter *this, Particle *particle){ + particle->acceleration[0] = randf2(this->particleAccerationRange_4C_min_x, this->particleAccerationRange_4C_max_x); + particle->acceleration[1] = randf2(this->particleAccerationRange_4C_min_y, this->particleAccerationRange_4C_max_y); + particle->acceleration[2] = randf2(this->particleAccerationRange_4C_min_z, this->particleAccerationRange_4C_max_z); + particle->unk5C = this->unk64; + + particle->fade = (0.0f == this->fade_in) ? 1.0f : 0; + particle->frame = randf2((f32)this->particleStartingFrameRange_84_min, (f32)this->particleStartingFrameRange_84_max); + particle->framerate = randf2(this->particleFramerateRange_8C_min, this->particleFramerateRange_8C_max); + + particle->position[0] = this->postion_28[0]; + particle->position[1] = this->postion_28[1]; + particle->position[2] = this->postion_28[2]; + + particle->position[0] = particle->position[0] + randf2(this->particleSpawnPositionRange_94_min_x, this->particleSpawnPositionRange_94_max_x); + particle->position[1] = particle->position[1] + randf2(this->particleSpawnPositionRange_94_min_y, this->particleSpawnPositionRange_94_max_y); + particle->position[2] = particle->position[2] + randf2(this->particleSpawnPositionRange_94_min_z, this->particleSpawnPositionRange_94_max_z); + + particle->initialSize_34 = particle->scale = randf2(this->particleStartingScaleRange_AC_min, this->particleStartingScaleRange_AC_max); + if(0.0f == this->particleFinalScaleRange_B4_min && 0.0f == this->particleFinalScaleRange_B4_max) + particle->finalSizeDiff = 0.0f; + else + particle->finalSizeDiff = randf2(this->particleFinalScaleRange_B4_min, this->particleFinalScaleRange_B4_max)- particle->initialSize_34; + + particle->rotation[2] = 0.0f; + particle->rotation[1] = 0.0f; + particle->rotation[0] = 0.0f; + + particle->angluar_velocity[0] = randf2(this->unkBC[0], this->unkC8[0]); + particle->angluar_velocity[1] = randf2(this->unkBC[1], this->unkC8[1]); + particle->angluar_velocity[2] = randf2(this->unkBC[2], this->unkC8[2]); + + particle->age_48 = 0.0f; + particle->lifetime_4C = randf2(this->particleLifeTimeRange[0], this->particleLifeTimeRange[1]) + 0.001; + if(!this->sphericalParticleVelocity_48){ + particle->velocity_50[0] = randf2(this->particleVelocityRange_E4.cartisian_min_x, this->particleVelocityRange_E4.cartisian_max_x); + particle->velocity_50[1] = randf2(this->particleVelocityRange_E4.cartisian_min_y, this->particleVelocityRange_E4.cartisian_max_y); + particle->velocity_50[2] = randf2(this->particleVelocityRange_E4.cartisian_min_z, this->particleVelocityRange_E4.cartisian_max_z); + } + else{ + func_80256E24(particle->velocity_50, + mlNormalizeAngle(randf2(this->particleVelocityRange_E4.spherical.pitch_min, this->particleVelocityRange_E4.spherical.pitch_max)), + mlNormalizeAngle(randf2(this->particleVelocityRange_E4.spherical.yaw_min, this->particleVelocityRange_E4.spherical.yaw_max)), + 0.0f, + 0.0f, + randf2(this->particleVelocityRange_E4.spherical.radius_min, this->particleVelocityRange_E4.spherical.radius_max) + ); + } + + // @recomp Set the particle's ID based on the particle emitters's spawn count. + PARTICLE_ID(particle) = PARTICLE_EMITTER_SPAWN_COUNT(this); + // @recomp Increment the particle emitter's spawn count. + PARTICLE_EMITTER_SPAWN_COUNT(this)++; +} diff --git a/patches/transform_ids.h b/patches/transform_ids.h index dcd6ce5..23251ab 100644 --- a/patches/transform_ids.h +++ b/patches/transform_ids.h @@ -2,17 +2,48 @@ #define __TRANSFORM_IDS_H__ #include "PR/ultratypes.h" +#include "rt64_extended_gbi.h" -#define MAP_MODEL_OPA_TRANSFORM_ID_START 0x1000 -#define MAP_MODEL_XLU_TRANSFORM_ID_START 0x2000 +#define gEXMatrixGroupSimpleNormal(cmd, id, push, proj, edit) \ + gEXMatrixGroup(cmd, id, G_EX_INTERPOLATE_SIMPLE, push, proj, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR, edit, G_EX_ASPECT_AUTO) + +#define gEXMatrixGroupSimpleVerts(cmd, id, push, proj, edit) \ + gEXMatrixGroup(cmd, id, G_EX_INTERPOLATE_SIMPLE, push, proj, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR, edit, G_EX_ASPECT_AUTO) + + +#define PROJECTION_GAMEPLAY_TRANSFORM_ID 0x00001000 +#define PROJECTION_SKYBOX_TRANSFORM_ID 0x00001001 +#define PROJECTION_TRANSITION_TRANSFORM_ID 0x00001002 +#define PROJECTION_PRESS_START_TRANSFORM_ID 0x00001003 +#define PROJECTION_BOTTLES_BONUS_TRANSFORM_ID 0x00001004 +#define PROJECTION_PORTRAIT_TRANSFORM_ID_START 0x00001100 // 1 for each portrait ID + +#define MAP_MODEL_OPA_TRANSFORM_ID_START 0x00801000 +#define MAP_MODEL_XLU_TRANSFORM_ID_START 0x00802000 + +#define TRANSITION_MODEL_TRANSFORM_ID_START 0x00F00000 + +#define SKYBOX_MODEL_TRANSFORM_ID_COUNT 256 +#define SKYBOX_TRANSFORM_ID_START 0x00F20000 #define MARKER_TRANSFORM_ID_COUNT 256 // Number of transform IDs for each ActorMarker. #define BANJO_TRANSFORM_ID_START 0x01000000 #define MARKER_TRANSFORM_ID_START (BANJO_TRANSFORM_ID_START + MARKER_TRANSFORM_ID_COUNT) #define PROP_TRANSFORM_ID_COUNT 256 -#define PROP_TRANSFORM_ID_START 0x01200000 +#define PROP_TRANSFORM_ID_START 0x02000000 -extern u32 cur_drawn_model_transform_id; +#define PARTICLE_EMITTER_TRANSFORM_ID_COUNT (256 * 256) // Number of transform IDs for each particle manager. +#define PARTICLE_MODEL_TRANSFORM_ID_COUNT 256 // Number of transform IDs for each model particle. +#define PARTICLE_EMITTER_MODEL_ID_COUNT (PARTICLE_EMITTER_TRANSFORM_ID_COUNT / PARTICLE_MODEL_TRANSFORM_ID_COUNT) // Number of model transform IDs for a model particle emitter. +#define PARTICLE_TRANSFORM_ID_START 0x03000000 +#define PARTICLE_EMITTER_TRANSFORM_ID_TOTAL 0x02000000 +#define PARTICLE_EMITTER_MAX_ID (PARTICLE_EMITTER_TRANSFORM_ID_TOTAL / PARTICLE_EMITTER_TRANSFORM_ID_COUNT) + +void reset_projection_ids(); + +extern s32 cur_drawn_model_transform_id; +extern s32 cur_perspective_projection_transform_id; +extern s32 cur_ortho_projection_transform_id; #endif