/* * * Singe 3 * Copyright (C) 2006-2026 Scott Duensing * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * */ // Singe - Particles: emitters that spawn, move and age particles for the 2D overlay and the 3D scene. #ifndef PARTICLES_H #define PARTICLES_H #include #include #include #include "math3d.h" #define PARTICLES_QUEUE_MAX 256 // 2D emitters that may be queued for drawing in one frame typedef enum ParticleBlendE { PARTICLE_ALPHA = 0, // Normal alpha blending PARTICLE_ADD = 1 // Additive: light on light } ParticleBlendE; typedef enum ParticleLayerE { PARTICLE_OVER = 0, // 2D: drawn above the overlay PARTICLE_UNDER = 1 // 2D: drawn beneath the overlay, above the video and the scene } ParticleLayerE; typedef enum ParticleCollideE { COLLIDE_NONE = 0, COLLIDE_FLOOR = 1, // A horizontal plane at a given height COLLIDE_SCENE = 2 // The physics world, by ray casts (3D only, capped per frame) } ParticleCollideE; // One particle, as handed to a renderer: world or overlay position, size, rotation, tint and frame. typedef struct ParticleViewT { Vec3T position; float size; float angle; // Degrees float colour[4]; // 0..1 int32_t frame; } ParticleViewT; // Renderers ask an emitter for its live particles; the texture per frame is theirs to keep. typedef struct EmitterViewT { int32_t id; int32_t node; // -1 for a 2D emitter ParticleBlendE blend; ParticleLayerE layer; int32_t frameCount; SDL_Surface **frames; // frameCount surfaces (the built-in disc when no sprite is set) uint32_t textureVersion; // Bumped whenever the frames change int32_t count; ParticleViewT *particles; // count entries, valid until the next update bool lit; // 3D: shaded by the scene's lights float softness; // 3D: distance over which a particle fades where it meets geometry; 0 for none int32_t trailLength; // Points kept behind each particle; 0 for no trails float trailWidth; // World or overlay units const float *trailPoints; // Per particle, trailLength points of x, y, z, oldest first const int32_t *trailCounts; // Per particle, how many of those are valid Vec3T trailOffset; // Added to trail points (a local emitter's origin) } EmitterViewT; void particlesClearQueue2D(void); void particlesInit(void); void particlesQueue2D(int32_t emitter); // Draw this emitter this frame int32_t particlesQueued2D(ParticleLayerE layer, int32_t *emitters, int32_t max); void particlesQuit(void); void particlesUpdate(bool advance); int32_t particlesView3D(EmitterViewT *views, int32_t max); // Every 3D emitter with live particles, up to max; returns how many bool particlesViewEmitter(int32_t emitter, EmitterViewT *view); void emitterBurst(int32_t emitter, int32_t count); void emitterClear(int32_t emitter); void emitterDelete(int32_t emitter); int32_t emitterGetCount(int32_t emitter); bool emitterIs3D(int32_t emitter); bool emitterIsActive(int32_t emitter); int32_t emitterNew(int32_t node); void emitterSetBlend(int32_t emitter, ParticleBlendE blend); void emitterSetCollide(int32_t emitter, ParticleCollideE mode, float bounce, float friction, float floor); void emitterSetColor(int32_t emitter, const float *start, const float *finish); void emitterSetDirection(int32_t emitter, Vec3T direction); void emitterSetDrag(int32_t emitter, float perSecond); void emitterSetFrames(int32_t emitter, int32_t first, int32_t last); void emitterSetGravity(int32_t emitter, Vec3T acceleration); void emitterSetLayer(int32_t emitter, ParticleLayerE layer); void emitterSetLife(int32_t emitter, float minSeconds, float maxSeconds); void emitterSetLit(int32_t emitter, bool lit); void emitterSetLocal(int32_t emitter, bool local); void emitterSetMax(int32_t emitter, int32_t count); void emitterSetPosition(int32_t emitter, Vec3T position); void emitterSetRadius(int32_t emitter, float radius); void emitterSetRate(int32_t emitter, float perSecond); void emitterSetSize(int32_t emitter, float start, float finish, float variation); void emitterSetSoftness(int32_t emitter, float distance); void emitterSetSpeed(int32_t emitter, float min, float max); void emitterSetSpin(int32_t emitter, float min, float max); void emitterSetSpread(int32_t emitter, float degrees); void emitterSetTexture(int32_t emitter, SDL_Surface **frames, int32_t frameCount); // Copies the surfaces; NULL restores the disc void emitterSetTrail(int32_t emitter, int32_t length, float width); void emitterStart(int32_t emitter); void emitterStop(int32_t emitter); bool emitterValid(int32_t emitter); #endif