diff --git a/src/particles.c b/src/particles.c index 265c6db0..829f9501 100644 --- a/src/particles.c +++ b/src/particles.c @@ -956,6 +956,7 @@ void obj_spawn_particle(Object *obj, s32 updateRate) { } else { if (obj->particleEmitter[i].flags & PARTICLE_EMITTER_ENABLED) { if (obj->particleEmitter[i].flags & PARTICLE_LINE) { + // Line particles are not immediately disabled, but instead, they gradually fade away over a few frames. ParticleEmitter *emitter = &obj->particleEmitter[i]; new_opacity = emitter->lineOpacity - 64; if (new_opacity < 0) { @@ -982,6 +983,10 @@ void obj_spawn_particle(Object *obj, s32 updateRate) { } } +/** + * Generates particles from a specific emitter attached to the object. + * The particles are created according to the emitter's settings and behavior. + */ void obj_trigger_emitter(Object *obj, ParticleEmitter *emitter) { s32 i; ParticleBehavior *behavior; @@ -1005,7 +1010,7 @@ void obj_trigger_emitter(Object *obj, ParticleEmitter *emitter) { if (particle != NULL) { add_particle_to_entity_list((Object *) particle); particle->pointIndex = emitter->pointCount; - particle->base.miscFlags |= PARTICLE_F40_2000; + particle->base.descFlags |= PARTICLE_F40_2000; emitter->refPoints[emitter->pointCount] = particle; emitter->pointCount++; } @@ -1025,6 +1030,9 @@ void obj_trigger_emitter(Object *obj, ParticleEmitter *emitter) { } } +/** + * Initializes the particle velocity. + */ void setup_particle_velocity(Particle *particle, Object *obj, ParticleEmitter *emitter, ParticleBehavior *behavior) { s32 randomizationFlags; Vec3f sourceVel; @@ -1110,6 +1118,9 @@ void setup_particle_velocity(Particle *particle, Object *obj, ParticleEmitter *e } } +/** + * Initializes the particle position. + */ void setup_particle_position(Particle *particle, Object *obj, ParticleEmitter *emitter, ParticleBehavior *behaviour) { s32 randomizationFlags; Vec3f sourcePos; @@ -1165,11 +1176,15 @@ void setup_particle_position(Particle *particle, Object *obj, ParticleEmitter *e if (particle->movementType == PARTICLE_MOVEMENT_BASIC_PARENT) { f32_vec3_apply_object_rotation((ObjectTransform *) obj, &particle->trans.x_position); } + particle->trans.x_position += obj->segment.trans.x_position; particle->trans.y_position += obj->segment.trans.y_position; particle->trans.z_position += obj->segment.trans.z_position; } +/** + * Create point particle and initialize it's fields. + */ PointParticle *create_point_particle(Object *obj, ParticleEmitter *emitter) { ParticleDescriptor *descriptor; PointParticle *particle; @@ -1189,7 +1204,7 @@ PointParticle *create_point_particle(Object *obj, ParticleEmitter *emitter) { particle->base.segmentID = obj->segment.object.segmentID; particle->base.trans.flags = OBJ_FLAGS_PARTICLE; particle->base.movementType = descriptor->movementType; - particle->base.miscFlags = descriptor->unk2; + particle->base.descFlags = descriptor->flags; particle->base.parentObj = obj; particle->pointEmitter = emitter; particle->base.trans.scale = descriptor->scale * behavior->scale; @@ -1202,20 +1217,20 @@ PointParticle *create_point_particle(Object *obj, ParticleEmitter *emitter) { particle->base.colour.b = descriptor->colour.b; particle->base.colour.a = descriptor->colour.a; - if (particle->base.miscFlags & PARTICLE_F40_800 && obj->shading != NULL) { + if (particle->base.descFlags & PARTICLE_SHADED && obj->shading != NULL) { particle->base.brightness = obj->shading->unk0 * 255.0f; } else { particle->base.brightness = 255; } particle->base.opacityTimer = descriptor->opacityTimer; - if (emitter->flags & PARTICLE_BEHAVIOR_FLAG_100) { + if (emitter->flags & PARTICLE_OVERRIDE_OPACITY_FROM_DESCRIPTOR) { particle->base.opacity = emitter->point_opacity; } else { particle->base.opacity = descriptor->opacity << 8; } if (descriptor->opacity < 255) { - if (particle->base.miscFlags & PARTICLE_F40_1000) { + if (particle->base.descFlags & PARTICLE_DESC_FLAG_1000) { particle->base.trans.flags |= OBJ_FLAGS_UNK_0100; } else { particle->base.trans.flags |= OBJ_FLAGS_UNK_0080; @@ -1249,7 +1264,8 @@ PointParticle *create_point_particle(Object *obj, ParticleEmitter *emitter) { setup_particle_velocity(&particle->base, obj, emitter, behavior); - particle->base.gravity = gParticleGravityTable[(particle->base.miscFlags >> 4) & 7]; + particle->base.gravity = gParticleGravityTable[(particle->base.descFlags >> 4) & 7]; + if (particle->base.movementType == PARTICLE_MOVEMENT_FORWARD) { particle->base.forwardVel = sqrtf((particle->base.velocity.x * particle->base.velocity.x) + (particle->base.velocity.y * particle->base.velocity.y) + @@ -1275,13 +1291,13 @@ PointParticle *create_point_particle(Object *obj, ParticleEmitter *emitter) { model->texture = load_texture(descriptor->textureID); if (model->texture != NULL) { if (model->texture->flags & 4) { - if (particle->base.miscFlags & PARTICLE_F40_1000) { + if (particle->base.descFlags & PARTICLE_DESC_FLAG_1000) { particle->base.trans.flags |= OBJ_FLAGS_UNK_0100; } else { particle->base.trans.flags |= OBJ_FLAGS_UNK_0080; } } - if ((particle->base.miscFlags & + if ((particle->base.descFlags & (PARTICLE_TEXTURE_ANIM_FORWARD_ENABLED | PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED)) == PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED) { particle->base.textureFrame = model->texture->numOfTextures - 1; @@ -1289,28 +1305,32 @@ PointParticle *create_point_particle(Object *obj, ParticleEmitter *emitter) { } } particle->modelFrame = 0; - particle->unk76 = descriptor->qwe; - particle->unk77 = 0; + particle->unused_76 = descriptor->unused_point_field; + particle->meshRegenerated = FALSE; if (model->texture == NULL) { + // Only point particles with textures are supported particle_deallocate(&particle->base); return NULL; } return particle; } +/** + * Create line particle and initialize its fields. + */ Particle *create_line_particle(Object *obj, ParticleEmitter *emitter) { ParticleDescriptor *descriptor; Particle *particle; ParticleModel *model; - ParticleBehavior *sp28; + ParticleBehavior *behaviour; ColorLoopEntry *colorLoop; descriptor = gParticlesAssetTable[emitter->descriptorID]; if (descriptor->kind != PARTICLE_KIND_LINE) { return NULL; } - sp28 = emitter->behaviour; - colorLoop = sp28->colorLoop; + behaviour = emitter->behaviour; + colorLoop = behaviour->colorLoop; particle = particle_allocate(PARTICLE_KIND_LINE); if (particle == NULL) { return NULL; @@ -1318,14 +1338,16 @@ Particle *create_line_particle(Object *obj, ParticleEmitter *emitter) { particle->segmentID = obj->segment.object.segmentID; particle->trans.flags = OBJ_FLAGS_PARTICLE; particle->movementType = descriptor->movementType; - particle->miscFlags = descriptor->unk2; + particle->descFlags = descriptor->flags; particle->parentObj = obj; particle->lineEmitter = emitter; - particle->trans.scale = descriptor->scale * sp28->scale; - particle->scaleVelocity = descriptor->scale * sp28->scaleVelocity; + particle->trans.scale = descriptor->scale * behaviour->scale; + particle->scaleVelocity = descriptor->scale * behaviour->scaleVelocity; particle->destroyTimer = descriptor->lifeTime; + particle->unk34 = 0.0f; particle->unk38 = 0; + if (gParticleOverrideColor->word != 0) { particle->colour.word = gParticleOverrideColor->word; } else { @@ -1334,15 +1356,17 @@ Particle *create_line_particle(Object *obj, ParticleEmitter *emitter) { particle->colour.b = descriptor->colour.b; } particle->colour.a = descriptor->colour.a; - if (particle->miscFlags & PARTICLE_F40_800 && obj->shading != NULL) { + + if (particle->descFlags & PARTICLE_SHADED && obj->shading != NULL) { particle->brightness = obj->shading->unk0 * 255.0f; } else { - particle->brightness = 0xFF; + particle->brightness = 255; } + particle->opacityTimer = descriptor->opacityTimer; particle->opacity = descriptor->opacity << 8; if (descriptor->opacity < 255) { - if (particle->miscFlags & PARTICLE_F40_1000) { + if (particle->descFlags & PARTICLE_DESC_FLAG_1000) { particle->trans.flags |= OBJ_FLAGS_UNK_0100; } else { particle->trans.flags |= OBJ_FLAGS_UNK_0080; @@ -1363,11 +1387,13 @@ Particle *create_line_particle(Object *obj, ParticleEmitter *emitter) { emitter->lineRefPoint.y += obj->segment.trans.y_position; emitter->lineRefPoint.z += obj->segment.trans.z_position; - particle->unk68b = 0; - particle->unk6Ab = 0; - particle->unk6Bb = -1; + particle->lineCreationPhase = 0; + particle->lineOrientation = 0; + particle->line_unused_6B = -1; + particle->textureFrameStep = descriptor->textureFrameStep; particle->textureFrame = 0; + model = particle->model; if (descriptor->textureID == -1) { model->texture = NULL; @@ -1375,13 +1401,13 @@ Particle *create_line_particle(Object *obj, ParticleEmitter *emitter) { model->texture = load_texture(descriptor->textureID); if (model->texture != NULL) { if (model->texture->flags & 4) { - if (particle->miscFlags & PARTICLE_F40_1000) { + if (particle->descFlags & PARTICLE_DESC_FLAG_1000) { particle->trans.flags |= OBJ_FLAGS_UNK_0100; } else { particle->trans.flags |= OBJ_FLAGS_UNK_0080; } } - if ((particle->miscFlags & + if ((particle->descFlags & (PARTICLE_TEXTURE_ANIM_FORWARD_ENABLED | PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED)) == PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED) { particle->textureFrame = model->texture->numOfTextures - 1; @@ -1391,6 +1417,7 @@ Particle *create_line_particle(Object *obj, ParticleEmitter *emitter) { model->vertices[0].x = emitter->lineRefPoint.x; model->vertices[0].y = emitter->lineRefPoint.y; model->vertices[0].z = emitter->lineRefPoint.z; + if ((u32) colorLoop != -1U) { emitter->colorIndex++; if (emitter->colorIndex >= colorLoop[0].unk0) { @@ -1406,8 +1433,8 @@ Particle *create_line_particle(Object *obj, ParticleEmitter *emitter) { model->vertices[0].b = particle->colour.b; model->vertices[0].a = emitter->lineOpacity; } - particle->unk6Ab = descriptor->unkA; - particle->unk6Bb = descriptor->unkB; + particle->lineOrientation = descriptor->lineOrientation; + particle->line_unused_6B = descriptor->line_unused_B; particle->trans.x_position = obj->segment.trans.x_position; particle->trans.y_position = obj->segment.trans.y_position; particle->trans.z_position = obj->segment.trans.z_position; @@ -1415,6 +1442,9 @@ Particle *create_line_particle(Object *obj, ParticleEmitter *emitter) { return particle; } +/** + * Creates a triangle, rectangle, or sprite particle and initializes its fields. + */ Particle *create_general_particle(Object *obj, ParticleEmitter *emitter) { s32 randomizationFlags; ParticleDescriptor *descriptor; @@ -1429,6 +1459,7 @@ Particle *create_general_particle(Object *obj, ParticleEmitter *emitter) { if (descriptor->kind == PARTICLE_KIND_LINE || descriptor->kind == PARTICLE_KIND_POINT) { return NULL; } + behaviour = emitter->behaviour; colorLoop = behaviour->colorLoop; @@ -1439,9 +1470,9 @@ Particle *create_general_particle(Object *obj, ParticleEmitter *emitter) { particle->segmentID = obj->segment.object.segmentID; particle->trans.flags = OBJ_FLAGS_PARTICLE; particle->movementType = descriptor->movementType; - particle->miscFlags = descriptor->unk2; + particle->descFlags = descriptor->flags; particle->parentObj = obj; - if ((particle->miscFlags & PARTICLE_F40_800) && obj->shading != NULL) { + if ((particle->descFlags & PARTICLE_SHADED) && obj->shading != NULL) { particle->brightness = obj->shading->unk0 * 255.0f; } else { particle->brightness = 255; @@ -1506,41 +1537,43 @@ Particle *create_general_particle(Object *obj, ParticleEmitter *emitter) { particle->colour.a += get_random_number_from_range(-behaviour->colourRangeA, behaviour->colourRangeA); } } + particle->opacityTimer = descriptor->opacityTimer; particle->opacity = descriptor->opacity * gCurrentHovercraftParticleOpacity; if (descriptor->opacity < 255) { - if (particle->miscFlags & PARTICLE_F40_1000) { + if (particle->descFlags & PARTICLE_DESC_FLAG_1000) { particle->trans.flags |= OBJ_FLAGS_UNK_0100; } else { particle->trans.flags |= OBJ_FLAGS_UNK_0080; } } if (particle->opacityTimer < particle->destroyTimer) { - particle->opacityVel = (s16) (((descriptor->opacityVel - descriptor->opacity) * gCurrentHovercraftParticleOpacity) / - (particle->destroyTimer - particle->opacityTimer)); + particle->opacityVel = (descriptor->opacityVel - descriptor->opacity) * gCurrentHovercraftParticleOpacity / + (particle->destroyTimer - particle->opacityTimer); } else { particle->opacityVel = 0; } + noTexture = FALSE; particle->textureFrameStep = descriptor->textureFrameStep; if (particle->kind == PARTICLE_KIND_SPRITE) { particle->sprite = (Sprite *) func_8007C12C(descriptor->textureID, 0); if (particle->sprite != NULL) { if (particle->sprite->frames[0]->flags & 4) { - if (particle->miscFlags & PARTICLE_F40_1000) { + if (particle->descFlags & PARTICLE_DESC_FLAG_1000) { particle->trans.flags |= OBJ_FLAGS_UNK_0100; } else { particle->trans.flags |= OBJ_FLAGS_UNK_0080; } } - if (behaviour->flags & PARTICLE_BEHAVIOR_FLAG_800) { + if (behaviour->flags & PARTICLE_RANDOM_TEXTURE_FRAME) { particle->textureFrame = get_random_number_from_range(0, particle->sprite->baseTextureId - 1) << 8; - if ((particle->miscFlags & + if ((particle->descFlags & (PARTICLE_TEXTURE_ANIM_FORWARD_ENABLED | PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED)) == PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED) { particle->textureFrame |= 0xFF; } - } else if ((particle->miscFlags & + } else if ((particle->descFlags & (PARTICLE_TEXTURE_ANIM_FORWARD_ENABLED | PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED)) == PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED) { particle->textureFrame = (particle->sprite->baseTextureId << 8) - 1; @@ -1550,26 +1583,26 @@ Particle *create_general_particle(Object *obj, ParticleEmitter *emitter) { } else { noTexture = TRUE; } - } else if ((particle->kind == PARTICLE_KIND_RECTANGLE) || (particle->kind == PARTICLE_KIND_TRIANGLE)) { + } else if (particle->kind == PARTICLE_KIND_RECTANGLE || particle->kind == PARTICLE_KIND_TRIANGLE) { texture = &particle->model->texture; if (texture) { *texture = load_texture(descriptor->textureID); if (*texture != NULL) { if ((*texture)->flags & 4) { - if (particle->miscFlags & PARTICLE_F40_1000) { + if (particle->descFlags & PARTICLE_DESC_FLAG_1000) { particle->trans.flags |= OBJ_FLAGS_UNK_0100; } else { particle->trans.flags |= OBJ_FLAGS_UNK_0080; } } - if (behaviour->flags & PARTICLE_BEHAVIOR_FLAG_800) { + if (behaviour->flags & PARTICLE_RANDOM_TEXTURE_FRAME) { particle->textureFrame = get_random_number_from_range(0, ((*texture)->numOfTextures >> 8) - 1) << 8; - if ((particle->miscFlags & + if ((particle->descFlags & (PARTICLE_TEXTURE_ANIM_FORWARD_ENABLED | PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED)) == PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED) { particle->textureFrame |= 0xFF; } - } else if ((particle->miscFlags & + } else if ((particle->descFlags & (PARTICLE_TEXTURE_ANIM_FORWARD_ENABLED | PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED)) == PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED) { particle->textureFrame = (*texture)->numOfTextures - 1; @@ -1592,6 +1625,7 @@ Particle *create_general_particle(Object *obj, ParticleEmitter *emitter) { setup_particle_position(particle, obj, emitter, behaviour); + // Setup particle rotation if (behaviour->flags & PARTICLE_ROTATION_ABSOLUTE) { particle->trans.rotation.y_rotation = behaviour->rotation.y_rotation; particle->trans.rotation.x_rotation = behaviour->rotation.x_rotation; @@ -1641,12 +1675,13 @@ Particle *create_general_particle(Object *obj, ParticleEmitter *emitter) { setup_particle_velocity(particle, obj, emitter, behaviour); - particle->gravity = gParticleGravityTable[(particle->miscFlags >> 4) & 7]; + particle->gravity = gParticleGravityTable[(particle->descFlags >> 4) & 7]; if (particle->movementType == PARTICLE_MOVEMENT_FORWARD) { particle->forwardVel = sqrtf((particle->velocity.x * particle->velocity.x) + (particle->velocity.y * particle->velocity.y) + (particle->velocity.z * particle->velocity.z)); } + if (behaviour->flags & PARTICLE_SOURCE_ROTATION_ENABLED) { emitter->sourceRotationCounter++; if (emitter->sourceRotationCounter >= behaviour->maxParticlesFromSamePos) { @@ -1665,6 +1700,7 @@ Particle *create_general_particle(Object *obj, ParticleEmitter *emitter) { emitter->emissionDirRotationCounter -= behaviour->maxParticlesInSameDir; } } + if (particle->model == NULL) { particle_deallocate(particle); return NULL; @@ -1673,6 +1709,10 @@ Particle *create_general_particle(Object *obj, ParticleEmitter *emitter) { } } +/** + * Allocates a particle of the given kind from the buffer. + * Returns NULL if the buffer is full. + */ Particle *particle_allocate(s32 kind) { s32 i; Particle *particle; @@ -1768,6 +1808,9 @@ Particle *particle_allocate(s32 kind) { return particle; } +/** + * Deallocates the specified particle and frees its associated resources. + */ void particle_deallocate(Particle *particle) { TextureHeader *tex; @@ -1815,7 +1858,7 @@ void particle_deallocate(Particle *particle) { break; case PARTICLE_KIND_POINT: if (gNumPointParticles > 0) { - func_800B263C((PointParticle *) particle); + delete_point_particle_from_sequence((PointParticle *) particle); tex = particle->model->texture; if (tex != NULL) { free_texture(tex); @@ -1827,6 +1870,9 @@ void particle_deallocate(Particle *particle) { } } +/** + * Frees all memory associated with the emitter. + */ void emitter_cleanup(ParticleEmitter *emitter) { PointParticle *pointParticle; s32 i; @@ -1859,7 +1905,7 @@ void particle_update(Particle *particle, s32 updateRate) { return; } - if (particle->miscFlags & (PARTICLE_TEXTURE_ANIM_FORWARD_ENABLED | PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED)) { + if (particle->descFlags & (PARTICLE_TEXTURE_ANIM_FORWARD_ENABLED | PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED)) { if (gParticleUpdateRate > 0) { update_particle_texture_frame(particle); } @@ -1867,7 +1913,7 @@ void particle_update(Particle *particle, s32 updateRate) { if (particle->kind == PARTICLE_KIND_POINT) { pointParticle = (PointParticle *) particle; pointParticle->modelFrame = 1 - pointParticle->modelFrame; - pointParticle->unk77 = 0; + pointParticle->meshRegenerated = 0; } if (pointParticle == NULL || (pointParticle != NULL && pointParticle->pointEmitter != NULL)) { if (particle->movementType == PARTICLE_MOVEMENT_ACCELERATION) { @@ -1905,7 +1951,7 @@ void particle_update(Particle *particle, s32 updateRate) { if (particle->opacityTimer == 0) { particle->opacity += gParticleUpdateRate * particle->opacityVel; if (particle->opacity < 255) { - if (particle->miscFlags & PARTICLE_F40_1000) { + if (particle->descFlags & PARTICLE_DESC_FLAG_1000) { particle->trans.flags |= OBJ_FLAGS_UNK_0100; } else { particle->trans.flags |= OBJ_FLAGS_UNK_0080; @@ -1920,19 +1966,22 @@ void particle_update(Particle *particle, s32 updateRate) { } } -void func_800B263C(PointParticle *arg0) { +/** + * Removes a point particle from the array managed by its parent emitter. + */ +void delete_point_particle_from_sequence(PointParticle *particle) { ParticleEmitter *new_var; PointParticle *new_var2; - ParticleEmitter *temp_v0; + ParticleEmitter *emitter; s32 i; - temp_v0 = arg0->pointEmitter; - if (temp_v0 != NULL) { - new_var = temp_v0; - if (temp_v0->pointCount != 0) { - if (arg0 == temp_v0->refPoints[arg0->pointIndex]) { - temp_v0->pointCount--; - for (i = arg0->pointIndex; i < temp_v0->pointCount; i++) { + emitter = particle->pointEmitter; + if (emitter != NULL) { + new_var = emitter; + if (emitter->pointCount != 0) { + if (particle == emitter->refPoints[particle->pointIndex]) { + emitter->pointCount--; + for (i = particle->pointIndex; i < emitter->pointCount; i++) { new_var->refPoints[i] = new_var->refPoints[i + 1]; new_var2 = new_var->refPoints[i]; new_var2->pointIndex = i; @@ -1942,26 +1991,50 @@ void func_800B263C(PointParticle *arg0) { } } +/** + * Line particles have their own update function because they behave differently from other particle types. + * Instead of moving, they generate their mesh in three steps and remain stationary until their lifetime ends. + */ void update_line_particle(Particle *particle) { - Vec3f sp44; + Vec3f vtxOffset; f32 tempf; f32 scale; ParticleModel *model; Object *obj; ParticleEmitter *emitter; ColorLoopEntry *colorLoop; - ColorLoopEntry **sp2C_ptr; + ColorLoopEntry **colorLoopPtr; obj = particle->parentObj; model = NULL; - sp2C_ptr = &colorLoop; + colorLoopPtr = &colorLoop; if (obj != NULL) { emitter = particle->lineEmitter; colorLoop = emitter->behaviour->colorLoop; model = particle->model; } - if (particle->unk68b < 2 && obj != NULL) { + + /* + This is a description of how it works. + + In the first step, only vertex 0 exists and nothing is rendered. + + In the second step, the vehicle (and therefore the emitter) moves some distance, + and three more vertices are added: one at the current emitter position, and two others + to the sides of it (depending on orientation). + + In the third step, the emitter moves further and two more side vertices are added. + + Eventually, all vertices form a chevron shape, so when multiple particles from the same + emitter are spawned, they merge into one continuous line. + + However, the developers either made a mistake or did it intentionally — only a triangle + from the first phase is rendered, which makes the line appear as a sequence of triangles. + */ + + if (particle->lineCreationPhase < 2 && obj != NULL) { + if (emitter->behaviour->flags & PARTICLE_SCALE_VELOCITY_INHERITS_PARENT_SPEED) { scale = sqrtf((obj->segment.x_velocity * obj->segment.x_velocity) + (obj->segment.y_velocity * obj->segment.y_velocity) + @@ -1970,52 +2043,54 @@ void update_line_particle(Particle *particle) { } else { scale = particle->trans.scale; } - if (!(particle->miscFlags & PARTICLE_F40_4000)) { - sp44.x = 0.0f; - sp44.y = 0.0f; - sp44.z = 0.0f; - switch (particle->unk6Ab) { + if (!(particle->descFlags & PARTICLE_LINE_ALONG_VELOCITY)) { + vtxOffset.x = 0.0f; + vtxOffset.y = 0.0f; + vtxOffset.z = 0.0f; + switch (particle->lineOrientation) { default: - sp44.x = scale; + vtxOffset.x = scale; break; case 2: - sp44.z = scale; + vtxOffset.z = scale; break; case 1: - sp44.y = scale; + vtxOffset.y = scale; break; } - f32_vec3_apply_object_rotation((ObjectTransform *) obj, &sp44.x); + f32_vec3_apply_object_rotation((ObjectTransform *) obj, &vtxOffset.x); } else { - sp44.x = obj->segment.x_velocity; - sp44.y = obj->segment.y_velocity; - sp44.z = obj->segment.z_velocity; - tempf = ((sp44.x * sp44.x) + (sp44.y * sp44.y)) + (sp44.z * sp44.f[2]); + vtxOffset.x = obj->segment.x_velocity; + vtxOffset.y = obj->segment.y_velocity; + vtxOffset.z = obj->segment.z_velocity; + tempf = ((vtxOffset.x * vtxOffset.x) + (vtxOffset.y * vtxOffset.y)) + (vtxOffset.z * vtxOffset.f[2]); if (tempf < 0.01f) { tempf = 1.0f; } else { tempf = scale / sqrtf(tempf); } - sp44.x *= tempf; - sp44.y *= tempf; - sp44.z *= tempf; - switch (particle->unk6Ab) { + vtxOffset.x *= tempf; + vtxOffset.y *= tempf; + vtxOffset.z *= tempf; + switch (particle->lineOrientation) { case 0: - tempf = sp44.x; - sp44.x = -sp44.z; - sp44.z = tempf; + tempf = vtxOffset.x; + vtxOffset.x = -vtxOffset.z; + vtxOffset.z = tempf; break; case 1: - tempf = sp44.y; - sp44.y = -sp44.z; - sp44.z = tempf; + tempf = vtxOffset.y; + vtxOffset.y = -vtxOffset.z; + vtxOffset.z = tempf; break; } } - if (model != NULL && particle->unk68b == 0) { - model->vertices[1].x = sp44.f[0] + emitter->lineRefPoint.x; - model->vertices[1].y = sp44.f[1] + emitter->lineRefPoint.y; - model->vertices[1].z = sp44.f[2] + emitter->lineRefPoint.z; + if (model != NULL && particle->lineCreationPhase == 0) { + // Phase 2: add three more vertices + + model->vertices[1].x = vtxOffset.f[0] + emitter->lineRefPoint.x; + model->vertices[1].y = vtxOffset.f[1] + emitter->lineRefPoint.y; + model->vertices[1].z = vtxOffset.f[2] + emitter->lineRefPoint.z; model->vertices[1].r = model->vertices->r; model->vertices[1].g = model->vertices->g; model->vertices[1].b = model->vertices->b; @@ -2024,10 +2099,10 @@ void update_line_particle(Particle *particle) { model->vertices[2].x = emitter->lineRefPoint.x; model->vertices[2].y = emitter->lineRefPoint.y; model->vertices[2].z = emitter->lineRefPoint.z; - if ((s32) *sp2C_ptr != -1) { - model->vertices[2].r = (*sp2C_ptr)[emitter->colorIndex + 2].r; - model->vertices[2].g = (*sp2C_ptr)[emitter->colorIndex + 2].g; - model->vertices[2].b = (*sp2C_ptr)[emitter->colorIndex + 2].b; + if ((s32) *colorLoopPtr != -1) { + model->vertices[2].r = (*colorLoopPtr)[emitter->colorIndex + 2].r; + model->vertices[2].g = (*colorLoopPtr)[emitter->colorIndex + 2].g; + model->vertices[2].b = (*colorLoopPtr)[emitter->colorIndex + 2].b; model->vertices[2].a = emitter->lineOpacity; } else { model->vertices[2].r = particle->colour.r; @@ -2035,31 +2110,33 @@ void update_line_particle(Particle *particle) { model->vertices[2].b = particle->colour.b; model->vertices[2].a = emitter->lineOpacity; } - model->vertices[3].x = emitter->lineRefPoint.x - sp44.f[0]; - model->vertices[3].y = emitter->lineRefPoint.y - sp44.f[1]; - model->vertices[3].z = emitter->lineRefPoint.z - sp44.f[2]; + model->vertices[3].x = emitter->lineRefPoint.x - vtxOffset.f[0]; + model->vertices[3].y = emitter->lineRefPoint.y - vtxOffset.f[1]; + model->vertices[3].z = emitter->lineRefPoint.z - vtxOffset.f[2]; model->vertices[3].r = model->vertices->r; model->vertices[3].g = model->vertices->g; model->vertices[3].b = model->vertices->b; model->vertices[3].a = emitter->lineOpacity; - particle->unk68b = 1; + particle->lineCreationPhase = 1; } else if (model != NULL) { - model->vertices[4].x = sp44.f[0] + emitter->lineRefPoint.x; - model->vertices[4].y = sp44.f[1] + emitter->lineRefPoint.y; - model->vertices[4].z = sp44.f[2] + emitter->lineRefPoint.z; + // Phase 3: add two more vertices + + model->vertices[4].x = vtxOffset.f[0] + emitter->lineRefPoint.x; + model->vertices[4].y = vtxOffset.f[1] + emitter->lineRefPoint.y; + model->vertices[4].z = vtxOffset.f[2] + emitter->lineRefPoint.z; model->vertices[4].r = model->vertices[2].r; model->vertices[4].g = model->vertices[2].g; model->vertices[4].b = model->vertices[2].b; model->vertices[4].a = emitter->lineOpacity; - model->vertices[5].x = emitter->lineRefPoint.x - sp44.f[0]; - model->vertices[5].y = emitter->lineRefPoint.y - sp44.f[1]; - model->vertices[5].z = emitter->lineRefPoint.z - sp44.f[2]; + model->vertices[5].x = emitter->lineRefPoint.x - vtxOffset.f[0]; + model->vertices[5].y = emitter->lineRefPoint.y - vtxOffset.f[1]; + model->vertices[5].z = emitter->lineRefPoint.z - vtxOffset.f[2]; model->vertices[5].r = model->vertices[2].r; model->vertices[5].g = model->vertices[2].g; model->vertices[5].b = model->vertices[2].b; model->vertices[5].a = emitter->lineOpacity; - particle->unk68b = 2; + particle->lineCreationPhase = 2; } } else { particle->destroyTimer -= gParticleUpdateRate; @@ -2068,7 +2145,7 @@ void update_line_particle(Particle *particle) { } else if (particle->opacityTimer == 0) { particle->opacity += gParticleUpdateRate * particle->opacityVel; if (particle->opacity < 255) { - if (particle->miscFlags & PARTICLE_F40_1000) { + if (particle->descFlags & PARTICLE_DESC_FLAG_1000) { particle->trans.flags |= OBJ_FLAGS_UNK_0100; } else { particle->trans.flags |= OBJ_FLAGS_UNK_0080; @@ -2083,7 +2160,7 @@ void update_line_particle(Particle *particle) { } } if (model != NULL && model->texture != NULL && - (particle->miscFlags & (PARTICLE_TEXTURE_ANIM_FORWARD_ENABLED | PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED)) && + (particle->descFlags & (PARTICLE_TEXTURE_ANIM_FORWARD_ENABLED | PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED)) && gParticleUpdateRate > 0) { update_particle_texture_frame(particle); } @@ -2106,10 +2183,10 @@ void update_particle_texture_frame(Particle *particle) { textureCount = particle->kind == PARTICLE_KIND_SPRITE ? particle->sprite->baseTextureId * 256 : particle->model->texture->numOfTextures; - forwardEnabled = particle->miscFlags & PARTICLE_TEXTURE_ANIM_FORWARD_ENABLED; - backwardEnabled = particle->miscFlags & PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED; - isLooped = particle->miscFlags & PARTICLE_TEXTURE_ANIM_LOOP; - currentlyBackward = particle->miscFlags & PARTICLE_CURRENT_ANIMATION_BACKWARD; + forwardEnabled = particle->descFlags & PARTICLE_TEXTURE_ANIM_FORWARD_ENABLED; + backwardEnabled = particle->descFlags & PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED; + isLooped = particle->descFlags & PARTICLE_TEXTURE_ANIM_LOOP; + currentlyBackward = particle->descFlags & PARTICLE_CURRENT_ANIMATION_BACKWARD; for (i = 0; (i++ < gParticleUpdateRate) && keepGoing;) { if (!currentlyBackward) { @@ -2119,13 +2196,13 @@ void update_particle_texture_frame(Particle *particle) { //!@bug the last frame is displayed twice particle->textureFrame = 2 * textureCount - 1 - particle->textureFrame; currentlyBackward = TRUE; - particle->miscFlags |= PARTICLE_CURRENT_ANIMATION_BACKWARD; + particle->descFlags |= PARTICLE_CURRENT_ANIMATION_BACKWARD; } else if (isLooped) { particle->textureFrame -= textureCount; } else { particle->textureFrame = textureCount - 1; keepGoing = FALSE; - particle->miscFlags &= + particle->descFlags &= ~(PARTICLE_TEXTURE_ANIM_FORWARD_ENABLED | PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED); } } @@ -2136,14 +2213,14 @@ void update_particle_texture_frame(Particle *particle) { if (forwardEnabled) { particle->textureFrame = -particle->textureFrame; currentlyBackward = FALSE; - particle->miscFlags &= ~PARTICLE_CURRENT_ANIMATION_BACKWARD; + particle->descFlags &= ~PARTICLE_CURRENT_ANIMATION_BACKWARD; } else { particle->textureFrame += textureCount; } } else { particle->textureFrame = 0; keepGoing = FALSE; - particle->miscFlags &= + particle->descFlags &= ~(PARTICLE_TEXTURE_ANIM_FORWARD_ENABLED | PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED); } } @@ -2298,7 +2375,7 @@ UNUSED void render_active_particles(Gfx **dList, MatrixS **mtx, Vertex **vtx) { objects = (Particle **) objGetObjList(&minObjIndex, &maxObjIndex); for (; minObjIndex < maxObjIndex; minObjIndex++) { if (objects[minObjIndex]->trans.flags & OBJ_FLAGS_PARTICLE) { - if (objects[minObjIndex]->miscFlags & PARTICLE_UNK_FLAG_8000) { + if (objects[minObjIndex]->descFlags & PARTICLE_UNK_FLAG_8000) { render_particle(objects[minObjIndex], dList, mtx, vtx, 0); } } @@ -2318,7 +2395,7 @@ void render_particle(Particle *particle, Gfx **dList, MatrixS **mtx, Vertex **vt renderFlags = (RENDER_FOG_ACTIVE | RENDER_Z_COMPARE); // Never true - if ((particle->miscFlags & flags) && D_800E2CDC < 512) { + if ((particle->descFlags & flags) && D_800E2CDC < 512) { return; } alpha = (particle->opacity >> 8) & 0xFF; @@ -2365,8 +2442,8 @@ void render_particle(Particle *particle, Gfx **dList, MatrixS **mtx, Vertex **vt if (particle->destroyTimer > 0) { gDPSetPrimColor((*dList)++, 0, 0, particle->brightness, particle->brightness, particle->brightness, 255); - if (((PointParticle *) particle)->unk77 == 0) { - func_800B3E64((PointParticle *) particle); + if (((PointParticle *) particle)->meshRegenerated == 0) { + regenerate_point_particles_mesh((PointParticle *) particle); } model = particle->model; temp = ((PointParticle *) particle)->modelFrame; @@ -2381,12 +2458,12 @@ void render_particle(Particle *particle, Gfx **dList, MatrixS **mtx, Vertex **vt } } else if (particle->kind == PARTICLE_KIND_LINE) { gDPSetPrimColor((*dList)++, 0, 0, particle->brightness, particle->brightness, particle->brightness, alpha); - if (particle->unk68b >= 2) { + if (particle->lineCreationPhase >= 2) { model = particle->model; load_and_set_texture(dList, model->texture, renderFlags, particle->textureFrame << 8); gSPVertexDKR((*dList)++, OS_K0_TO_PHYSICAL(model->vertices), model->vertexCount, 0); gSPPolygon((*dList)++, OS_K0_TO_PHYSICAL(model->triangles), model->triangleCount, TRIN_ENABLE_TEXTURE); - } else if (particle->unk68b > 0) { + } else if (particle->lineCreationPhase > 0) { model = particle->model; load_and_set_texture(dList, model->texture, renderFlags, particle->textureFrame << 8); gSPVertexDKR((*dList)++, OS_K0_TO_PHYSICAL(model->vertices), 4, 0); @@ -2400,7 +2477,11 @@ void render_particle(Particle *particle, Gfx **dList, MatrixS **mtx, Vertex **vt } } -void func_800B3E64(PointParticle *obj) { +/** + * Sets the position and colors of all vertices for all particles spawned by a single emitter. + * Together, they form the shape of a continuous pipe-like structure. + */ +void regenerate_point_particles_mesh(PointParticle *obj) { UNUSED s32 pad; s32 index; Vec3f vec_up; @@ -2530,7 +2611,7 @@ void func_800B3E64(PointParticle *obj) { prev_particle = particle; prev_model = model; - particle->unk77 = -1; + particle->meshRegenerated = -1; } } } @@ -2580,7 +2661,11 @@ UNUSED ParticleBehavior *get_particle_behaviour(s32 idx) { return gParticleBehavioursAssetTable[gParticleBehavioursAssetTableCount - 1]; } -UNUSED ParticleBehavior *func_800B45C4(s32 *idx) { +/** + * Return the next particle behaviour ID from the behaviour table. + * Make sure the index is in range by wrapping it. + */ +UNUSED ParticleBehavior *get_next_particle_behaviour(s32 *idx) { *idx += 1; while (*idx >= gParticleBehavioursAssetTableCount) { *idx -= gParticleBehavioursAssetTableCount; @@ -2588,7 +2673,11 @@ UNUSED ParticleBehavior *func_800B45C4(s32 *idx) { return gParticleBehavioursAssetTable[*idx]; } -UNUSED ParticleBehavior *func_800B461C(s32 *idx) { +/** + * Return the previous particle behaviour ID from the behaviour table. + * Make sure the index is in range by wrapping it. + */ +UNUSED ParticleBehavior *get_previous_particle_behaviour(s32 *idx) { *idx -= 1; while (*idx < 0) { *idx += gParticleBehavioursAssetTableCount; @@ -2596,28 +2685,34 @@ UNUSED ParticleBehavior *func_800B461C(s32 *idx) { return gParticleBehavioursAssetTable[*idx]; } -void func_800B4668(Object *obj, s32 idx, s32 arg2, s32 arg3) { - s32 temp_v0; +/** + * Increases the opacity of all point particles spawned by the emitter. + */ +void increase_emitter_opacity(Object *obj, s32 idx, s32 delta, s32 maxOpacity) { + s32 newOpacity; - arg3 <<= 8; - temp_v0 = (obj->particleEmitter[idx].point_opacity & 0xFFFF) + arg2; - if (arg3 < temp_v0) { - obj->particleEmitter[idx].point_opacity = arg3; + maxOpacity <<= 8; + newOpacity = (obj->particleEmitter[idx].point_opacity & 0xFFFF) + delta; + if (maxOpacity < newOpacity) { + obj->particleEmitter[idx].point_opacity = maxOpacity; } else { - obj->particleEmitter[idx].point_opacity = temp_v0; + obj->particleEmitter[idx].point_opacity = newOpacity; } - obj->particleEmitter[idx].flags |= PARTICLE_BEHAVIOR_FLAG_100; + obj->particleEmitter[idx].flags |= PARTICLE_OVERRIDE_OPACITY_FROM_DESCRIPTOR; } -void func_800B46BC(Object *obj, s32 idx, s32 arg2, s32 arg3) { - s32 temp_v0; +/** + * Decreases the opacity of all point particles spawned by the emitter. + */ +void decrease_emitter_opacity(Object *obj, s32 idx, s32 delta, s32 maxOpacity) { + s32 newOpacity; - arg3 <<= 8; - temp_v0 = (obj->particleEmitter[idx].point_opacity & 0xFFFF) - arg2; - if (temp_v0 < arg3) { - obj->particleEmitter[idx].point_opacity = arg3; + maxOpacity <<= 8; + newOpacity = (obj->particleEmitter[idx].point_opacity & 0xFFFF) - delta; + if (newOpacity < maxOpacity) { + obj->particleEmitter[idx].point_opacity = maxOpacity; } else { - obj->particleEmitter[idx].point_opacity = temp_v0; + obj->particleEmitter[idx].point_opacity = newOpacity; } - obj->particleEmitter[idx].flags |= PARTICLE_BEHAVIOR_FLAG_100; + obj->particleEmitter[idx].flags |= PARTICLE_OVERRIDE_OPACITY_FROM_DESCRIPTOR; } diff --git a/src/particles.h b/src/particles.h index 021b8560..55138f18 100644 --- a/src/particles.h +++ b/src/particles.h @@ -76,10 +76,10 @@ enum ParticleBehaviorFlags { PARTICLE_VELOCITY_ABSOLUTE = 0x20, PARTICLE_VELOCITY_SCALED_FROM_PARENT = 0x40, PARTICLE_ROTATION_ABSOLUTE = 0x80, - PARTICLE_BEHAVIOR_FLAG_100 = 0x100, + PARTICLE_OVERRIDE_OPACITY_FROM_DESCRIPTOR = 0x100, PARTICLE_POINT_EMITTER_DISABLED = 0x200, PARTICLE_POINT = 0x400, - PARTICLE_BEHAVIOR_FLAG_800 = 0x800, + PARTICLE_RANDOM_TEXTURE_FRAME = 0x800, PARTICLE_SCALE_VELOCITY_INHERITS_PARENT_SPEED = 0x1000, PARTICLE_EMITTER_AWAITING_SPAWN = 0x2000, PARTICLE_LINE = 0x4000, @@ -95,7 +95,7 @@ enum ParticleMovement { PARTICLE_MOVEMENT_FORWARD, }; -enum ParticleField40 { +enum ParticleDescriptorFlags { PARTICLE_TEXTURE_ANIM_FORWARD_ENABLED = 0x1, PARTICLE_TEXTURE_ANIM_BACKWARD_ENABLED = 0x2, PARTICLE_TEXTURE_ANIM_LOOP = 0x4, @@ -103,27 +103,27 @@ enum ParticleField40 { PARTICLE_F40_GRAVITY_1 = 0x10, PARTICLE_F40_GRAVITY_2 = 0x20, PARTICLE_F40_GRAVITY_3 = 0x40, - PARTICLE_F40_800 = 0x800, - PARTICLE_F40_1000 = 0x1000, + PARTICLE_SHADED = 0x800, + PARTICLE_DESC_FLAG_1000 = 0x1000, PARTICLE_F40_2000 = 0x2000, - PARTICLE_F40_4000 = 0x4000, + PARTICLE_LINE_ALONG_VELOCITY = 0x4000, PARTICLE_UNK_FLAG_8000 = 0x8000, }; typedef struct ParticleDescriptor { /* 0x00 */ u8 kind; // ParticleKind /* 0x01 */ u8 movementType; // ParticleMovement - /* 0x02 */ u16 unk2; - /* 0x04 */ s16 textureID; + /* 0x02 */ u16 flags; // ParticleDescriptorFlags + /* 0x04 */ s16 textureID; // -1 if texture is not assigned /* 0x06 */ s16 textureFrameStep; /* 0x08 */ s16 lifeTime; union { /* 0x0A */ s16 lifeTimeRange; // Used by general particle struct { - /* 0x0A */ u16 unkA : 6; // Used by line particle - /* 0x0A */ u16 unkB : 6; // Used by line particle + /* 0x0A */ u16 lineOrientation : 6; // Used by line particle + /* 0x0A */ u16 line_unused_B : 6; // (Not) Used by line particle }; - /* 0x0A */ u16 qwe : 6; // Used by point particle + /* 0x0A */ u16 unused_point_field : 6; // (Not) Used by point particle }; /* 0x0C */ u8 opacity; /* 0x0D */ u8 opacityVel; @@ -249,12 +249,12 @@ typedef struct Particle { /* 0x002C */ s16 kind; /* 0x002E */ s16 segmentID; /* 0x0030 */ f32 unk30; - /* 0x0034 */ f32 unk34; - /* 0x0038 */ u8 unk38; + /* 0x0034 */ f32 unk34; // set to zero but never used + /* 0x0038 */ u8 unk38; // set to zero but never used /* 0x0039 */ u8 movementType; /* 0x003A */ s16 destroyTimer; /* 0x003C */ Object *parentObj; - /* 0x0040 */ s32 miscFlags; + /* 0x0040 */ s32 descFlags; union { /* 0x0044 */ ParticleModel *model; /* 0x0044 */ Sprite *sprite; // Unclear whether this is the same as unk80068514_arg4 @@ -276,10 +276,10 @@ typedef struct Particle { union { /* 0x0068 */ f32 gravity; struct { - /* 0x0068 */ u8 unk68b; - /* 0x0069 */ u8 unk69b; - /* 0x006A */ s8 unk6Ab; - /* 0x006B */ s8 unk6Bb; + /* 0x0068 */ u8 lineCreationPhase; + /* 0x0069 */ u8 line_unused_69; + /* 0x006A */ s8 lineOrientation; + /* 0x006B */ s8 line_unused_6B; // set on particle creation but never used }; }; /* 0x006C */ ColourRGBA colour; @@ -290,8 +290,8 @@ typedef struct PointParticle { /* 0x0070 */ ParticleEmitter *pointEmitter; /* 0x0074 */ u8 pointIndex; /* 0x0075 */ u8 modelFrame; - /* 0x0076 */ u8 unk76; - /* 0x0077 */ s8 unk77; + /* 0x0076 */ u8 unused_76; + /* 0x0077 */ s8 meshRegenerated; } PointParticle; void reset_particles(void); @@ -310,7 +310,7 @@ void emitter_init(ParticleEmitter *emitter, s32 behaviourID, s32 particleID); void emitter_init_with_pos(ParticleEmitter *emitter, s32 behaviourID, s32 particleID, s16 posX, s16 posY, s16 posZ); void obj_disable_emitter(Object *obj, s32 emitterIndex); void emitter_cleanup(ParticleEmitter *emitter); -void func_800B263C(PointParticle *arg0); +void delete_point_particle_from_sequence(PointParticle *arg0); void init_particle_assets(void); void update_particle_texture_frame(Particle *particle); void setup_particle_position(Particle *particle, Object *obj, ParticleEmitter *emitter, ParticleBehavior *behaviour); @@ -324,10 +324,10 @@ Particle *create_general_particle(Object *obj, ParticleEmitter *emitter); void obj_enable_emitter(Object *obj, s32 emitterIndex); void emitter_change_settings(ParticleEmitter *emitter, s32 behaviourID, s32 particleID, s16 posX, s16 posY, s16 posZ); void render_particle(Particle *particle, Gfx **dList, MatrixS **mtx, Vertex **vtx, s32 flags); -void func_800B4668(Object *obj, s32 idx, s32 arg2, s32 arg3); -void func_800B46BC(Object *obj, s32 idx, s32 arg2, s32 arg3); +void increase_emitter_opacity(Object *obj, s32 idx, s32 arg2, s32 arg3); +void decrease_emitter_opacity(Object *obj, s32 idx, s32 arg2, s32 arg3); void obj_spawn_particle(Object *obj, s32 updateRate); -void func_800B3E64(PointParticle *obj); +void regenerate_point_particles_mesh(PointParticle *obj); void update_line_particle(Particle *particle); void update_vehicle_particles(Object *racerObj, s32 updateRate); Particle* create_line_particle(Object* obj, ParticleEmitter* emitter); diff --git a/src/racer.c b/src/racer.c index 38b3a382..a4367eb0 100644 --- a/src/racer.c +++ b/src/racer.c @@ -1487,9 +1487,9 @@ void func_80046524(s32 updateRate, f32 updateRateF, Object *obj, Object_Racer *r if (gNumViewports < 2 && obj->segment.header->particleCount >= 9) { if ((gCurrentRacerInput & (A_BUTTON | R_TRIG)) == (A_BUTTON | R_TRIG) && (gCurrentStickX < -30 || gCurrentStickX > 30)) { - func_800B4668(obj, 8, updateRate << 10, 0x80); + increase_emitter_opacity(obj, 8, updateRate << 10, 0x80); } else { - func_800B46BC(obj, 8, updateRate << 9, 0x20); + decrease_emitter_opacity(obj, 8, updateRate << 9, 0x20); } } if (gCurrentPlayerIndex >= PLAYER_ONE && racer->buoyancy > 0.0) { diff --git a/ver/symbols/symbol_addrs.jpn.v79.txt b/ver/symbols/symbol_addrs.jpn.v79.txt index 52cf6e40..9afa5c8a 100644 --- a/ver/symbols/symbol_addrs.jpn.v79.txt +++ b/ver/symbols/symbol_addrs.jpn.v79.txt @@ -1654,7 +1654,7 @@ particle_allocate = 0x800B22B8; particle_deallocate = 0x800B2640; emitter_cleanup = 0x800B2860; particle_update = 0x800B28FC; -func_800B263C = 0x800B2C3C; +delete_point_particle_from_sequence = 0x800B2C3C; update_line_particle = 0x800B2CE0; update_particle_texture_frame = 0x800B35BC; move_particle_basic_parent = 0x800B3740; @@ -1664,15 +1664,15 @@ move_particle_basic = 0x800B3AB0; move_particle_forward = 0x800B3B64; render_active_particles = 0x800B3C78; render_particle = 0x800B3D40; -func_800B3E64 = 0x800B4464; +regenerate_point_particles_mesh = 0x800B4464; get_particle_asset_table = 0x800B4A88; get_next_particle_table = 0x800B4AD4; get_previous_particle_table = 0x800B4B2C; get_particle_behaviour = 0x800B4B78; -func_800B45C4 = 0x800B4BC4; -func_800B461C = 0x800B4C1C; -func_800B4668 = 0x800B4C68; -func_800B46BC = 0x800B4CBC; +get_next_particle_behaviour = 0x800B4BC4; +get_previous_particle_behaviour = 0x800B4C1C; +increase_emitter_opacity = 0x800B4C68; +decrease_emitter_opacity = 0x800B4CBC; // unused_string.c .text strcpy = 0x800B4D10; diff --git a/ver/symbols/symbol_addrs.pal.v77.txt b/ver/symbols/symbol_addrs.pal.v77.txt index 5a0394cd..84c3b3ea 100644 --- a/ver/symbols/symbol_addrs.pal.v77.txt +++ b/ver/symbols/symbol_addrs.pal.v77.txt @@ -1643,7 +1643,7 @@ particle_allocate = 0x800B1D48; particle_deallocate = 0x800B20D0; emitter_cleanup = 0x800B22F0; particle_update = 0x800B238C; -func_800B263C = 0x800B26CC; +delete_point_particle_from_sequence = 0x800B26CC; update_line_particle = 0x800B2770; update_particle_texture_frame = 0x800B304C; move_particle_basic_parent = 0x800B31D0; @@ -1653,15 +1653,15 @@ move_particle_basic = 0x800B3540; move_particle_forward = 0x800B35F4; render_active_particles = 0x800B3708; render_particle = 0x800B37D0; -func_800B3E64 = 0x800B3EF4; +regenerate_point_particles_mesh = 0x800B3EF4; get_particle_asset_table = 0x800B4518; get_next_particle_table = 0x800B4564; get_previous_particle_table = 0x800B45BC; get_particle_behaviour = 0x800B4608; -func_800B45C4 = 0x800B4654; -func_800B461C = 0x800B46AC; -func_800B4668 = 0x800B46F8; -func_800B46BC = 0x800B474C; +get_next_particle_behaviour = 0x800B4654; +get_previous_particle_behaviour = 0x800B46AC; +increase_emitter_opacity = 0x800B46F8; +decrease_emitter_opacity = 0x800B474C; strcpy = 0x800B47A0; strcat = 0x800B47D4; strcasecmp = 0x800B4824; diff --git a/ver/symbols/symbol_addrs.pal.v80.txt b/ver/symbols/symbol_addrs.pal.v80.txt index 42a5a036..51ff8ea7 100644 --- a/ver/symbols/symbol_addrs.pal.v80.txt +++ b/ver/symbols/symbol_addrs.pal.v80.txt @@ -1564,7 +1564,7 @@ particle_allocate = 0x800B22A8; particle_deallocate = 0x800B2630; emitter_cleanup = 0x800B2850; particle_update = 0x800B28EC; -func_800B263C = 0x800B2C2C; +delete_point_particle_from_sequence = 0x800B2C2C; update_line_particle = 0x800B2CD0; update_particle_texture_frame = 0x800B35AC; move_particle_basic_parent = 0x800B3730; @@ -1574,15 +1574,15 @@ move_particle_basic = 0x800B3AA0; move_particle_forward = 0x800B3B54; render_active_particles = 0x800B3C68; render_particle = 0x800B3D30; -func_800B3E64 = 0x800B4454; +regenerate_point_particles_mesh = 0x800B4454; get_particle_asset_table = 0x800B4A78; get_next_particle_table = 0x800B4AC4; get_previous_particle_table = 0x800B4B1C; get_particle_behaviour = 0x800B4B68; -func_800B45C4 = 0x800B4BB4; -func_800B461C = 0x800B4C0C; -func_800B4668 = 0x800B4C58; -func_800B46BC = 0x800B4CAC; +get_next_particle_behaviour = 0x800B4BB4; +get_previous_particle_behaviour = 0x800B4C0C; +increase_emitter_opacity = 0x800B4C58; +decrease_emitter_opacity = 0x800B4CAC; strcpy = 0x800B4D00; strcat = 0x800B4D34; strcasecmp = 0x800B4D84; diff --git a/ver/symbols/symbol_addrs.us.v77.txt b/ver/symbols/symbol_addrs.us.v77.txt index 09ebea8d..94c59e44 100644 --- a/ver/symbols/symbol_addrs.us.v77.txt +++ b/ver/symbols/symbol_addrs.us.v77.txt @@ -1649,7 +1649,7 @@ particle_allocate = 0x800B1CB8; particle_deallocate = 0x800B2040; emitter_cleanup = 0x800B2260; particle_update = 0x800B22FC; -func_800B263C = 0x800B263C; +delete_point_particle_from_sequence = 0x800B263C; update_line_particle = 0x800B26E0; update_particle_texture_frame = 0x800B2FBC; move_particle_basic_parent = 0x800B3140; @@ -1659,15 +1659,15 @@ move_particle_basic = 0x800B34B0; move_particle_forward = 0x800B3564; render_active_particles = 0x800B3678; render_particle = 0x800B3740; -func_800B3E64 = 0x800B3E64; +regenerate_point_particles_mesh = 0x800B3E64; get_particle_asset_table = 0x800B4488; get_next_particle_table = 0x800B44D4; get_previous_particle_table = 0x800B452C; get_particle_behaviour = 0x800B4578; -func_800B45C4 = 0x800B45C4; -func_800B461C = 0x800B461C; -func_800B4668 = 0x800B4668; -func_800B46BC = 0x800B46BC; +get_next_particle_behaviour = 0x800B45C4; +get_previous_particle_behaviour = 0x800B461C; +increase_emitter_opacity = 0x800B4668; +decrease_emitter_opacity = 0x800B46BC; // unused_string.c .text strcpy = 0x800B4710; diff --git a/ver/symbols/symbol_addrs.us.v80.txt b/ver/symbols/symbol_addrs.us.v80.txt index 74703da7..473f906f 100644 --- a/ver/symbols/symbol_addrs.us.v80.txt +++ b/ver/symbols/symbol_addrs.us.v80.txt @@ -1563,7 +1563,7 @@ particle_allocate = 0x800B2218; particle_deallocate = 0x800B25A0; emitter_cleanup = 0x800B27C0; particle_update = 0x800B285C; -func_800B263C = 0x800B2B9C; +delete_point_particle_from_sequence = 0x800B2B9C; update_line_particle = 0x800B2C40; update_particle_texture_frame = 0x800B351C; move_particle_basic_parent = 0x800B36A0; @@ -1573,15 +1573,15 @@ move_particle_basic = 0x800B3A10; move_particle_forward = 0x800B3AC4; render_active_particles = 0x800B3BD8; render_particle = 0x800B3CA0; -func_800B3E64 = 0x800B43C4; +regenerate_point_particles_mesh = 0x800B43C4; get_particle_asset_table = 0x800B49E8; get_next_particle_table = 0x800B4A34; get_previous_particle_table = 0x800B4A8C; get_particle_behaviour = 0x800B4AD8; -func_800B45C4 = 0x800B4B24; -func_800B461C = 0x800B4B7C; -func_800B4668 = 0x800B4BC8; -func_800B46BC = 0x800B4C1C; +get_next_particle_behaviour = 0x800B4B24; +get_previous_particle_behaviour = 0x800B4B7C; +increase_emitter_opacity = 0x800B4BC8; +decrease_emitter_opacity = 0x800B4C1C; strcpy = 0x800B4C70; strcat = 0x800B4CA4; strcasecmp = 0x800B4CF4;