#ifndef SPL_RESOURCE_H #define SPL_RESOURCE_H #include #include "struct_defs/struct_020147B8.h" #define SPL_TEX_ANIM_MAX_FRAMES 8 enum SPLDrawType { SPL_DRAW_TYPE_BILLBOARD = 0, SPL_DRAW_TYPE_DIRECTIONAL_BILLBOARD, SPL_DRAW_TYPE_POLYGON, SPL_DRAW_TYPE_DIRECTIONAL_POLYGON, SPL_DRAW_TYPE_DIRECTIONAL_POLYGON_CENTER, }; enum SPLCircleAxis { SPL_CIRCLE_AXIS_Z = 0, SPL_CIRCLE_AXIS_Y, SPL_CIRCLE_AXIS_X, SPL_CIRCLE_AXIS_EMITTER, }; enum SPLEmissionType { SPL_EMISSION_TYPE_POINT = 0, // A single point SPL_EMISSION_TYPE_SPHERE_SURFACE, // Any point on the surface of a sphere SPL_EMISSION_TYPE_CIRCLE_BORDER, // Any point on a circle around an axis (specified by flags) SPL_EMISSION_TYPE_CIRCLE_BORDER_UNIFORM, // Uniform distribution of points on a circle around an axis (specified by flags) SPL_EMISSION_TYPE_SPHERE, // Any point inside a sphere SPL_EMISSION_TYPE_CIRCLE, // Any point inside a circle around an axis (specified by flags) SPL_EMISSION_TYPE_CYLINDER_SURFACE, // Any point on the surface of a cylinder SPL_EMISSION_TYPE_CYLINDER, // Any point inside a cylinder SPL_EMISSION_TYPE_HEMISPHERE_SURFACE, // Any point on the surface of a hemisphere (direction specified by flags) SPL_EMISSION_TYPE_HEMISPHERE, // Any point inside a hemisphere (direction specified by flags) }; enum SPLChildRotationType { SPL_CHILD_ROT_NONE = 0, SPL_CHILD_ROT_INHERIT_ANGLE, SPL_CHILD_ROT_INHERIT_ANGLE_AND_VELOCITY, }; enum SPLScaleAnimDir { SPL_SCALE_ANIM_DIR_XY = 0, SPL_SCALE_ANIM_DIR_X, SPL_SCALE_ANIM_DIR_Y, }; enum SPLPolygonRotAxis { SPL_POLYGON_ROT_AXIS_Y = 0, SPL_POLYGON_ROT_AXIS_XYZ, }; typedef struct SPLFileHeader { u32 magic; u32 version; u16 resCount; u16 texCount; u32 reserved0; u32 resSize; u32 texSize; u32 texOffset; u32 reserved1; } SPLFileHeader; typedef union SPLResourceFlags { u32 all; struct { u32 emissionType : 4; // Maps to SPLEmissionType u32 drawType : 2; u32 circleAxis : 2; // Maps to SPLCircleAxis u32 hasScaleAnim : 1; u32 hasColorAnim : 1; u32 hasAlphaAnim : 1; u32 hasTexAnim : 1; u32 hasRotation : 1; u32 randomInitAngle : 1; // Whether the emitter manages itself or not. // If set, the emitter will automatically terminate when it reaches the end of its life // and all of its particles have died u32 selfMaintaining : 1; u32 followEmitter : 1; u32 hasChildResource : 1; u32 polygonRotAxis : 2; // The axis to rotate the polygon around when using the 'polygon' draw types u32 polygonReferencePlane : 1; u32 randomizeLoopedAnim : 1; u32 drawChildrenFirst : 1; // If set, child particles will be rendered before parent particles u32 hideParent : 1; // If set, only child particles will be rendered u32 useViewSpace : 1; // If set, the rendering calculations will be done in view space u32 hasGravityBehavior : 1; u32 hasRandomBehavior : 1; u32 hasMagnetBehavior : 1; u32 hasSpinBehavior : 1; u32 hasCollisionPlaneBehavior : 1; u32 hasConvergenceBehavior : 1; u32 hasFixedPolygonID : 1; u32 childHasFixedPolygonID : 1; }; } SPLResourceFlags; typedef union SPLChildResourceFlags { u16 all; struct { u16 usesBehaviors : 1; u16 hasScaleAnim : 1; u16 hasAlphaAnim : 1; u16 rotationType : 2; u16 followEmitter : 1; u16 useChildColor : 1; u16 drawType : 2; u16 polygonRotAxis : 2; u16 polygonReferencePlane : 1; u16 : 4; }; } SPLChildResourceFlags; typedef union SPLCurveInOut { u16 all; struct { u16 in : 8; u16 out : 8; }; } SPLCurveInOut; typedef union SPLCurveInPeakOut { u32 all; struct { u32 in : 8; u32 peak : 8; u32 out : 8; u32 : 8; }; } SPLCurveInPeakOut; typedef struct SPLResourceHeader { SPLResourceFlags flags; VecFx32 emitterBasePos; fx32 emissionCount; // Number of particles to emit per emission interval fx32 radius; // Used for circle, sphere, and cylinder emissions fx32 length; // Used for cylinder emission VecFx16 axis; GXRgb color; fx32 initVelPosAmplifier; fx32 initVelAxisAmplifier; fx32 baseScale; fx16 aspectRatio; u16 startDelay; // Delay, in frames, before the emitter starts emitting particles s16 minRotation; s16 maxRotation; u16 initAngle; u16 reserved; u16 emitterLifeTime; u16 particleLifeTime; // All of these values are mapped to the range [0, 1] // They are used to attenuate the particle's properties at initialization, // acting as a sort of randomization factor which scales down the initial values struct { u32 baseScale : 8; // Damping factor for the base scale of the particles (0 = no damping) u32 lifeTime : 8; u32 initVel : 8; // Attenuation factor for the initial velocity of the particles (0 = no attenuation) u32 : 8; } randomAttenuation; struct { u32 emissionInterval : 8; u32 baseAlpha : 8; u32 airResistance : 8; u32 textureIndex : 8; u32 loopFrames : 8; u32 dbbScale : 16; u32 textureTileCountS : 2; // Number of times to tile the texture in the S direction u32 textureTileCountT : 2; // Number of times to tile the texture in the T direction u32 scaleAnimDir : 3; // Maps to SPLScaleAnimDir u32 dpolFaceEmitter : 1; // If set, the polygon will face the emitter u32 flipTextureS : 1; u32 flipTextureT : 1; u32 : 30; } misc; fx16 polygonX; fx16 polygonY; struct { u32 flags : 8; u32 : 24; } userData; } SPLResourceHeader; typedef struct SPLScaleAnim { fx16 start; fx16 mid; fx16 end; SPLCurveInOut curve; struct { u16 loop : 1; u16 : 15; } flags; u16 padding; } SPLScaleAnim; typedef struct SPLColorAnim { GXRgb start; GXRgb end; SPLCurveInPeakOut curve; struct { u16 randomStartColor : 1; u16 loop : 1; u16 interpolate : 1; u16 : 13; } flags; u16 padding; } SPLColorAnim; typedef struct SPLAlphaAnim { union { u16 all; struct { u16 start : 5; u16 mid : 5; u16 end : 5; u16 : 1; }; } alpha; struct { u16 randomRange : 8; u16 loop : 1; u16 : 7; } flags; SPLCurveInOut curve; u16 padding; } SPLAlphaAnim; typedef struct SPLTexAnim { u8 textures[SPL_TEX_ANIM_MAX_FRAMES]; struct { u32 frameCount : 8; u32 step : 8; // Number of frames between each texture frame u32 randomizeInit : 1; // Randomize the initial texture frame u32 loop : 1; u32 : 14; } param; } SPLTexAnim; typedef struct SPLChildResource { SPLChildResourceFlags flags; fx16 randomInitVelMag; // Randomization factor for the initial velocity magnitude (0 = no randomization) fx16 endScale; // For scaling animations u16 lifeTime; u8 velocityRatio; // Ratio of the parent particle's velocity to inherit (255 = 100%) u8 scaleRatio; // Ratio of the parent particle's scale to inherit (255 = 100%) GXRgb color; struct { u32 emissionCount : 8; // Number of particles to emit per emission interval u32 emissionDelay : 8; // Delay, as a fraction of the particle's lifetime, before the particle starts emitting u32 emissionInterval : 8; u32 texture : 8; u32 textureTileCountS : 2; u32 textureTileCountT : 2; u32 flipTextureS : 1; u32 flipTextureT : 1; u32 dpolFaceEmitter : 1; // If set, the polygon will face the emitter u32 : 25; } misc; } SPLChildResource; typedef struct SPLResource { SPLResourceHeader *header; SPLScaleAnim *scaleAnim; SPLColorAnim *colorAnim; SPLAlphaAnim *alphaAnim; SPLTexAnim *texAnim; SPLChildResource *childResource; SPLBehavior *behaviors; u16 behaviorCount; u16 reserved; } SPLResource; #endif // SPL_RESOURCE_H