/* SPDX-License-Identifier: MIT */ /* * konparticles.h * * Copyright (c) 2026 KonAki * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef KONPARTICLES_H #define KONPARTICLES_H #include "konsofren.h" #ifdef __cplusplus extern "C" { #endif /*** definition ***/ typedef struct kon_particle { float x, y, vx, vy; float age, life; /* life is 0 for a free slot */ float size0, size1; uint32_t color0, color1; } kon_particle_t; /* a stream of small things, sparks, dust, rain, snow, smoke. one of these is one kind of thing, use several for several kinds. the particles live in a pool you give it, so nothing is allocated and a full pool just means no new ones are made. kon_particlesInit gives plain white specks, fill in the public fields to change them. everything is in pixels and seconds, a particle at a whole x and y sits on the middle of that pixel */ typedef struct kon_particles { kon_particle_t *pool; int capacity; /* where they are born: a random point in this rectangle */ float x, y, width, height; float rate; /* born every second, 0 for only bursts */ /* how they leave: the direction in radians with 0 to the right and a quarter turn down, a random speed and lifetime */ float angle, spread; /* spread is how far either side of the angle */ float speedMin, speedMax; float lifeMin, lifeMax; float ax, ay; /* acceleration, gravity and wind */ kon_rect_t area; /* if it has a size, particles die when they leave it */ /* how they look over their life, blended from the first to the last. size is in pixels and never goes under 1, fade with alpha */ float size0, size1; uint32_t color0, color1; float stretch; /* 0 for squares, otherwise they are long in the way they move, this many seconds of movement long */ kon_blend_t blend; const kon_image *image; /* NULL for squares, otherwise each is this picture (or the part of it in src) drawn size pixels wide */ kon_rect_t src; /* private */ float carry; uint32_t seed; } kon_particles_t; /* capacity is how many can be alive at once. seed any number, the same seed makes the same effect */ void kon_particlesInit(kon_particles_t *ps, kon_particle_t *pool, int capacity, uint32_t seed); /* makes count at once, as many as there is room for. returns how many */ int kon_particlesBurst(kon_particles_t *ps, int count); void kon_particlesUpdate(kon_particles_t *ps, float dt); /* how many are alive */ int kon_particlesCount(const kon_particles_t *ps); /* removes them all */ void kon_particlesClear(kon_particles_t *ps); /* offset is added to every position, for a camera that scrolls */ void kon_particlesDraw(const kon_particles_t *ps, kon_framebuffer_t *fb, int offsetX, int offsetY); /*** weather ***/ /* set the emitter up as rain, snow or a storm for a view of that size. power from 1 to 9 is how heavy, like RPG Maker's. they only change the public fields, so adjust them afterwards. call kon_particlesUpdate and kon_particlesDraw as usual, with a pool of a few hundred (power 9 on a large view wants more, particles that do not fit are skipped) */ void kon_weatherRain(kon_particles_t *ps, int viewWidth, int viewHeight, int power); void kon_weatherSnow(kon_particles_t *ps, int viewWidth, int viewHeight, int power); void kon_weatherStorm(kon_particles_t *ps, int viewWidth, int viewHeight, int power); #ifdef __cplusplus } #endif #endif