freelist
This commit is contained in:
parent
1d491e694a
commit
e092599816
60
source/engine/freelist.h
Normal file
60
source/engine/freelist.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
#ifndef FREELIST_H
|
||||||
|
#define FREELIST_H
|
||||||
|
|
||||||
|
/* Given a pointer to a struct, create a free list
|
||||||
|
Struct must have a 'next' field
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct freelistheader
|
||||||
|
{
|
||||||
|
unsigned int first;
|
||||||
|
unsigned int len;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define freelist_header(p) ((struct freelistheader*)p-1)
|
||||||
|
static inline void *freelist_make(struct freelistheader *list, size_t elemsize, unsigned int n)
|
||||||
|
{
|
||||||
|
list = malloc(elemsize*n*sizeof(struct freelistheader));
|
||||||
|
list->first = 0;
|
||||||
|
list->len = n;
|
||||||
|
return list+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned int freelist_check(struct freelistheader *h, void *data, size_t elemsize)
|
||||||
|
{
|
||||||
|
if (h->first > h->len) return -1;
|
||||||
|
unsigned int id = h->first;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define freelist_size(p,l) do{p = freelist_make(p,sizeof(*p),l); for(int i = 0; i < l; i++) { p[i].next = i+1; }}while(0)
|
||||||
|
#define freelist_len(p) (freelist_header(p)->len)
|
||||||
|
#define freelist_first(p) (freelist_header(p)->first)
|
||||||
|
#define freelist_grab(i,p) do{i=freelist_header(p)->first; freelist_header(p)->first = p[i].next; p[i].next = -1;}while(0)
|
||||||
|
#define freelist_kill(p,i) do{p[i].next = freelist_first(p);freelist_first(p)=i;}while(0)
|
||||||
|
#define freelist_free(p) (free(freelist_header(p)))
|
||||||
|
|
||||||
|
struct link_header
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
void *head;
|
||||||
|
void *last;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void *add_link(struct link_header *h, size_t size)
|
||||||
|
{
|
||||||
|
void *n = malloc(size);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
#define link_header(p) ((struct link_header*)p-1)
|
||||||
|
#define link_head(p) (link_header(p)->head)
|
||||||
|
#define link_last(p) (link_header(p)->last)
|
||||||
|
#define link_add(p,v) do{
|
||||||
|
#define link_each(p,fn) do {void *f = p; while (link_header(p)->head != NULL) { fn(p); p = p->next; }; p = f; }while(0)
|
||||||
|
#define link_e(p,i) (
|
||||||
|
|
||||||
|
#define stack_size(p,n) (p = malloc(sizeof(p)*n))
|
||||||
|
#define stack_push(p,v) ()
|
||||||
|
#define stack_pop(p) ()
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,20 +1,10 @@
|
||||||
#include "particle.h"
|
#include "particle.h"
|
||||||
#include "stb_ds.h"
|
#include "stb_ds.h"
|
||||||
|
#include "freelist.h"
|
||||||
|
|
||||||
struct emitter make_emitter() {
|
struct emitter make_emitter() {
|
||||||
struct emitter e = {0};
|
struct emitter e = {0};
|
||||||
return e;
|
arrsetcap(e.particles, 200);
|
||||||
}
|
|
||||||
|
|
||||||
struct emitter set_emitter(struct emitter e) {
|
|
||||||
arrsetlen(e.particles, e.max);
|
|
||||||
|
|
||||||
e.first = &e.particles[0];
|
|
||||||
|
|
||||||
for (int i = 0; i < arrlen(e.particles) - 1; i++) {
|
|
||||||
e.particles[i].next = &e.particles[i + 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,26 +13,24 @@ void free_emitter(struct emitter e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_emitter(struct emitter e) {
|
void start_emitter(struct emitter e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pause_emitter(struct emitter e) {
|
void pause_emitter(struct emitter e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop_emitter(struct emitter e) {
|
void stop_emitter(struct emitter e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void emitter_step(struct emitter e, double dt) {
|
void emitter_step(struct emitter e, double dt) {
|
||||||
for (int i = 0; i < arrlen(e.particles); i++) {
|
for (int i = 0; i < arrlen(e.particles); i++) {
|
||||||
if (e.particles[i].life <= 0)
|
e.particles[i].pos = HMM_AddV3(e.particles[i].pos, HMM_MulV3F(e.particles[i].v, dt));
|
||||||
continue;
|
e.particles[i].angle = HMM_MulQ(e.particles[i].angle, HMM_MulQF(e.particles[i].angle, dt));
|
||||||
|
e.particles[i].life -= dt;
|
||||||
|
|
||||||
e.particles[i].pos = cpvadd(e.particles[i].pos, cpvmult(e.particles[i].v, dt));
|
if (e.particles[i].life <= 0)
|
||||||
e.particles[i].angle += e.particles[i].av * dt;
|
arrdelswap(e.particles, i);
|
||||||
e.particles[i].life -= dt;
|
|
||||||
|
|
||||||
if (e.particles[i].life <= 0) {
|
|
||||||
e.particles[i].next = e.first;
|
|
||||||
e.first = &e.particles[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,25 @@
|
||||||
#ifndef PARTICLE_H
|
#ifndef PARTICLE_H
|
||||||
#define PARTICLE_H
|
#define PARTICLE_H
|
||||||
|
|
||||||
#include <chipmunk/chipmunk.h>
|
#include "HandmadeMath.h"
|
||||||
|
|
||||||
struct particle {
|
struct particle {
|
||||||
cpVect pos;
|
HMM_Vec3 pos;
|
||||||
cpVect v; /* velocity */
|
HMM_Vec3 v; /* velocity */
|
||||||
double angle;
|
HMM_Quat angle;
|
||||||
double av; /* angular velocity */
|
HMM_Quat av; /* angular velocity */
|
||||||
|
|
||||||
|
union {
|
||||||
union {
|
double life;
|
||||||
double life;
|
unsigned int next;
|
||||||
struct particle *next;
|
};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct emitter {
|
struct emitter {
|
||||||
struct particle *particles;
|
struct particle *particles;
|
||||||
struct particle *first;
|
int max;
|
||||||
int max;
|
double life;
|
||||||
double life;
|
void (*seeder)(struct particle *p); /* Called to initialize each particle */
|
||||||
void (*seeder)(struct particle *p); /* Called to initialize each particle */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct emitter make_emitter();
|
struct emitter make_emitter();
|
||||||
|
@ -33,4 +31,4 @@ void stop_emitter(struct emitter e);
|
||||||
|
|
||||||
void emitter_step(struct emitter e, double dt);
|
void emitter_step(struct emitter e, double dt);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,14 +13,14 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include "HandmadeMath.h"
|
#include "HandmadeMath.h"
|
||||||
|
#include "freelist.h"
|
||||||
|
|
||||||
#include "sprite.sglsl.h"
|
#include "sprite.sglsl.h"
|
||||||
#include "9slice.sglsl.h"
|
#include "9slice.sglsl.h"
|
||||||
|
|
||||||
struct TextureOptions TEX_SPRITE = {1, 0, 0};
|
struct TextureOptions TEX_SPRITE = {1, 0, 0};
|
||||||
|
|
||||||
static struct sprite *sprites;
|
static struct sprite *sprites = NULL;
|
||||||
static int first = -1;
|
|
||||||
|
|
||||||
static sg_shader shader_sprite;
|
static sg_shader shader_sprite;
|
||||||
static sg_pipeline pip_sprite;
|
static sg_pipeline pip_sprite;
|
||||||
|
@ -59,29 +59,21 @@ int make_sprite(int go) {
|
||||||
.size = {1.f, 1.f},
|
.size = {1.f, 1.f},
|
||||||
.tex = texture_loadfromfile(NULL),
|
.tex = texture_loadfromfile(NULL),
|
||||||
.go = go,
|
.go = go,
|
||||||
.next = -1,
|
|
||||||
.layer = 0,
|
.layer = 0,
|
||||||
|
.next = -1,
|
||||||
.enabled = 1};
|
.enabled = 1};
|
||||||
|
|
||||||
int slot = 0;
|
int id;
|
||||||
if (first < 0) {
|
freelist_grab(id, sprites);
|
||||||
arrput(sprites, sprite);
|
sprites[id] = sprite;
|
||||||
slot = arrlen(sprites)-1;
|
return id;
|
||||||
} else {
|
|
||||||
slot = first;
|
|
||||||
first = id2sprite(first)->next;
|
|
||||||
*id2sprite(slot) = sprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
return slot;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprite_delete(int id) {
|
void sprite_delete(int id) {
|
||||||
struct sprite *sp = id2sprite(id);
|
struct sprite *sp = id2sprite(id);
|
||||||
sp->go = -1;
|
sp->go = -1;
|
||||||
sp->enabled = 0;
|
sp->enabled = 0;
|
||||||
sp->next = first;
|
freelist_kill(sprites,id);
|
||||||
first = id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprite_enabled(int id, int e) {
|
void sprite_enabled(int id, int e) {
|
||||||
|
@ -132,8 +124,9 @@ void sprite_draw_all() {
|
||||||
static int *layers;
|
static int *layers;
|
||||||
if (layers) arrfree(layers);
|
if (layers) arrfree(layers);
|
||||||
|
|
||||||
for (int i = 0; i < arrlen(sprites); i++)
|
for (int i = 0; i < freelist_len(sprites); i++)
|
||||||
if (sprites[i].go >= 0 && sprites[i].enabled) arrpush(layers, i);
|
if (sprites[i].next == -1 && sprites[i].go >= 0 && sprites[i].enabled)
|
||||||
|
arrpush(layers, i);
|
||||||
|
|
||||||
if (arrlen(layers) == 0) return;
|
if (arrlen(layers) == 0) return;
|
||||||
if (arrlen(layers) > 1)
|
if (arrlen(layers) > 1)
|
||||||
|
@ -144,6 +137,10 @@ void sprite_draw_all() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprite_loadtex(struct sprite *sprite, const char *path, struct glrect frame) {
|
void sprite_loadtex(struct sprite *sprite, const char *path, struct glrect frame) {
|
||||||
|
if (!sprite) {
|
||||||
|
YughWarn("NO SPRITE!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
sprite->tex = texture_loadfromfile(path);
|
sprite->tex = texture_loadfromfile(path);
|
||||||
sprite_setframe(sprite, &frame);
|
sprite_setframe(sprite, &frame);
|
||||||
}
|
}
|
||||||
|
@ -154,6 +151,8 @@ void sprite_settex(struct sprite *sprite, struct Texture *tex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprite_initialize() {
|
void sprite_initialize() {
|
||||||
|
freelist_size(sprites, 500);
|
||||||
|
|
||||||
shader_sprite = sg_make_shader(sprite_shader_desc(sg_query_backend()));
|
shader_sprite = sg_make_shader(sprite_shader_desc(sg_query_backend()));
|
||||||
|
|
||||||
pip_sprite = sg_make_pipeline(&(sg_pipeline_desc){
|
pip_sprite = sg_make_pipeline(&(sg_pipeline_desc){
|
||||||
|
|
Loading…
Reference in a new issue