Super Mario 64 Source
A Super Mario 64 decompilation, brought to you by a bunch of clever folks.
Data Structures | Functions | Variables
envfx_snow.c File Reference
#include <ultra64.h>
#include "sm64.h"
#include "display.h"
#include "memory.h"
#include "ingame_menu.h"
#include "envfx_snow.h"
#include "envfx_bubbles.h"
#include "engine/surface_collision.h"
#include "engine/math_util.h"
#include "engine/behavior_script.h"
#include "audio/external.h"
#include "obj_behaviors.h"

Data Structures

struct  SnowFlakeVertex
 This file contains the function that handles 'environment effects', which are particle effects related to the level type that, unlike object-based particle effects, are rendered more efficiently by manually generating display lists instead of drawing each particle separately. More...
 

Functions

s32 envfx_init_snow (s32 mode)
 Initialize snow particles by allocating a buffer for storing their state and setting a start amount. More...
 
void envfx_update_snowflake_count (s32 mode, Vec3s marioPos)
 Update the amount of snow particles on screen. More...
 
void envfx_cleanup_snow (void *snowParticleArray)
 Deallocate the buffer storing snow particles and set the environment effect to none. More...
 
void orbit_from_positions (Vec3s from, Vec3s to, s16 *radius, s16 *pitch, s16 *yaw)
 Given two points, return the vector from one to the other represented as euler angles and a length. More...
 
void pos_from_orbit (Vec3s origin, Vec3s result, s16 radius, s16 pitch, s16 yaw)
 Calculate the 'result' vector as the position of the 'origin' vector with a vector added represented by radius, pitch and yaw. More...
 
s32 envfx_is_snowflake_alive (s32 index, s32 snowCylinderX, s32 snowCylinderY, s32 snowCylinderZ)
 Check whether the snowflake with the given index is inside view, where 'view' is a cylinder of radius 300 and height 400 centered at the input x, y and z. More...
 
void envfx_update_snow_normal (s32 snowCylinderX, s32 snowCylinderY, s32 snowCylinderZ)
 Update the position of each snowflake. More...
 
void envfx_update_snow_blizzard (s32 snowCylinderX, s32 snowCylinderY, s32 snowCylinderZ)
 Unused function. More...
 
static s32 is_in_mystery_snow_area (s32 x, UNUSED s32 y, s32 z)
 
void envfx_update_snow_water (s32 snowCylinderX, s32 snowCylinderY, s32 snowCylinderZ)
 Update the position of underwater snow particles. More...
 
void rotate_triangle_vertices (Vec3s vertex1, Vec3s vertex2, Vec3s vertex3, s16 pitch, s16 yaw)
 Rotates the input vertices according to the give pitch and yaw. More...
 
void append_snowflake_vertex_buffer (Gfx *gfx, s32 index, Vec3s vertex1, Vec3s vertex2, Vec3s vertex3)
 Append 15 vertices to 'gfx', which is enough for 5 snowflakes starting at 'index' in the buffer. More...
 
Gfxenvfx_update_snow (s32 snowMode, Vec3s marioPos, Vec3s camFrom, Vec3s camTo)
 Updates positions of snow particles and returns a pointer to a display list drawing all snowflakes. More...
 
Gfxenvfx_update_particles (s32 mode, Vec3s marioPos, Vec3s camTo, Vec3s camFrom)
 Updates the environment effects (snow, flowers, bubbles) and returns a display list drawing them. More...
 

Variables

struct EnvFxParticlegEnvFxBuffer
 
Vec3i gSnowCylinderLastPos
 
s16 gSnowParticleCount
 
s16 gSnowParticleMaxCount
 
s8 gEnvFxMode = 0
 
UNUSED s32 D_80330644 = 0
 
Vtx gSnowTempVtx [3]
 Template for a snow particle triangle. More...
 
struct SnowFlakeVertex gSnowFlakeVertex1 = { -5, 5, 0 }
 
struct SnowFlakeVertex gSnowFlakeVertex2 = { -5, -5, 0 }
 
struct SnowFlakeVertex gSnowFlakeVertex3 = { 5, 5, 0 }
 
voidtiny_bubble_dl_0B006AB0
 
voidtiny_bubble_dl_0B006A50
 
voidtiny_bubble_dl_0B006CD8
 

Function Documentation

◆ append_snowflake_vertex_buffer()

void append_snowflake_vertex_buffer ( Gfx gfx,
s32  index,
Vec3s  vertex1,
Vec3s  vertex2,
Vec3s  vertex3 
)

Append 15 vertices to 'gfx', which is enough for 5 snowflakes starting at 'index' in the buffer.

The 3 input vertices represent the roated triangle around (0,0,0) that will be translated to snowflake positions to draw the snowflake image.

◆ envfx_cleanup_snow()

void envfx_cleanup_snow ( void snowParticleArray)

Deallocate the buffer storing snow particles and set the environment effect to none.

◆ envfx_init_snow()

s32 envfx_init_snow ( s32  mode)

Initialize snow particles by allocating a buffer for storing their state and setting a start amount.

◆ envfx_is_snowflake_alive()

s32 envfx_is_snowflake_alive ( s32  index,
s32  snowCylinderX,
s32  snowCylinderY,
s32  snowCylinderZ 
)

Check whether the snowflake with the given index is inside view, where 'view' is a cylinder of radius 300 and height 400 centered at the input x, y and z.

◆ envfx_update_particles()

Gfx* envfx_update_particles ( s32  mode,
Vec3s  marioPos,
Vec3s  camTo,
Vec3s  camFrom 
)

Updates the environment effects (snow, flowers, bubbles) and returns a display list drawing them.

◆ envfx_update_snow()

Gfx* envfx_update_snow ( s32  snowMode,
Vec3s  marioPos,
Vec3s  camFrom,
Vec3s  camTo 
)

Updates positions of snow particles and returns a pointer to a display list drawing all snowflakes.

◆ envfx_update_snow_blizzard()

void envfx_update_snow_blizzard ( s32  snowCylinderX,
s32  snowCylinderY,
s32  snowCylinderZ 
)

Unused function.

Basically a copy-paste of envfx_update_snow_normal, but an extra 20 units is added to each snowflake x and snowflakes can respawn in y-range [-200, 200] instead of [0, 200] relative to snowCylinderY They also fall a bit faster (with vertical speed -5 instead of -2).

◆ envfx_update_snow_normal()

void envfx_update_snow_normal ( s32  snowCylinderX,
s32  snowCylinderY,
s32  snowCylinderZ 
)

Update the position of each snowflake.

Snowflakes wiggle by having a random value added to their position each frame. If snowflakes get out of view (where view = a small cylinder in front of the camera) their position is reset to somewhere in view. Since the cylinder of snow is so close to the camera, snow flakes would move out of view very quickly when the camera moves. To mitigate this, a portion of the difference between the previous and current snowCylinder position is added to snowflakes to keep them in view for longer. That's why the snow looks a bit off in 3d, it's a lot closer than you'd think but appears to be further by means of hacky position updates. This might have been done because larger, further away snowflakes are occluded easily by level geometry, wasting many particles.

◆ envfx_update_snow_water()

void envfx_update_snow_water ( s32  snowCylinderX,
s32  snowCylinderY,
s32  snowCylinderZ 
)

Update the position of underwater snow particles.

Since they are stationary, they merely jump back into view when they are out of view.

◆ envfx_update_snowflake_count()

void envfx_update_snowflake_count ( s32  mode,
Vec3s  marioPos 
)

Update the amount of snow particles on screen.

Normal snow starts with few flakes and slowly increases to the maximum. For water snow, this is dependent on how deep underwater you are. Blizzard snows starts at the maximum amount and doesn't change.

◆ is_in_mystery_snow_area()

static s32 is_in_mystery_snow_area ( s32  x,
UNUSED s32  y,
s32  z 
)
static

Unused function. Checks whether a position is laterally within 3000 units to the point (x: 3380, z: -520). Considering there is an unused blizzard snow mode, this could have been used to check whether Mario is in a 'blizzard area'. In Cool Cool Mountain and Snowman's Land the area lies near the starting point and doesn't seem meaningfull. Notably, the point is close to the entrance of SL, so maybe there were plans for an extra hint to find it. The radius of 3000 units is quite large for that though, covering more than half of the mirror room.

◆ orbit_from_positions()

void orbit_from_positions ( Vec3s  from,
Vec3s  to,
s16 radius,
s16 pitch,
s16 yaw 
)

Given two points, return the vector from one to the other represented as euler angles and a length.

◆ pos_from_orbit()

void pos_from_orbit ( Vec3s  origin,
Vec3s  result,
s16  radius,
s16  pitch,
s16  yaw 
)

Calculate the 'result' vector as the position of the 'origin' vector with a vector added represented by radius, pitch and yaw.

◆ rotate_triangle_vertices()

void rotate_triangle_vertices ( Vec3s  vertex1,
Vec3s  vertex2,
Vec3s  vertex3,
s16  pitch,
s16  yaw 
)

Rotates the input vertices according to the give pitch and yaw.

This is needed for billboarding of particles.

Variable Documentation

◆ D_80330644

UNUSED s32 D_80330644 = 0

◆ gEnvFxBuffer

struct EnvFxParticle* gEnvFxBuffer

◆ gEnvFxMode

s8 gEnvFxMode = 0

◆ gSnowCylinderLastPos

Vec3i gSnowCylinderLastPos

◆ gSnowFlakeVertex1

struct SnowFlakeVertex gSnowFlakeVertex1 = { -5, 5, 0 }

◆ gSnowFlakeVertex2

struct SnowFlakeVertex gSnowFlakeVertex2 = { -5, -5, 0 }

◆ gSnowFlakeVertex3

struct SnowFlakeVertex gSnowFlakeVertex3 = { 5, 5, 0 }

◆ gSnowParticleCount

s16 gSnowParticleCount

◆ gSnowParticleMaxCount

s16 gSnowParticleMaxCount

◆ gSnowTempVtx

Vtx gSnowTempVtx[3]
Initial value:
= { { { { -5, 5, 0 }, 0, { 0, 0 }, { 0x7F, 0x7F, 0x7F, 0xFF } } },
{ { { -5, -5, 0 }, 0, { 0, 960 }, { 0x7F, 0x7F, 0x7F, 0xFF } } },
{ { { 5, 5, 0 }, 0, { 960, 0 }, { 0x7F, 0x7F, 0x7F, 0xFF } } } }

Template for a snow particle triangle.

◆ tiny_bubble_dl_0B006A50

void* tiny_bubble_dl_0B006A50

◆ tiny_bubble_dl_0B006AB0

void* tiny_bubble_dl_0B006AB0

◆ tiny_bubble_dl_0B006CD8

void* tiny_bubble_dl_0B006CD8