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 "stb_ds.h"
|
||||
#include "freelist.h"
|
||||
|
||||
struct emitter make_emitter() {
|
||||
struct emitter e = {0};
|
||||
return e;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
arrsetcap(e.particles, 200);
|
||||
return e;
|
||||
}
|
||||
|
||||
|
@ -23,26 +13,24 @@ void free_emitter(struct emitter e) {
|
|||
}
|
||||
|
||||
void start_emitter(struct emitter e) {
|
||||
|
||||
}
|
||||
|
||||
void pause_emitter(struct emitter e) {
|
||||
|
||||
}
|
||||
|
||||
void stop_emitter(struct emitter e) {
|
||||
|
||||
}
|
||||
|
||||
void emitter_step(struct emitter e, double dt) {
|
||||
for (int i = 0; i < arrlen(e.particles); i++) {
|
||||
if (e.particles[i].life <= 0)
|
||||
continue;
|
||||
|
||||
e.particles[i].pos = cpvadd(e.particles[i].pos, cpvmult(e.particles[i].v, dt));
|
||||
e.particles[i].angle += e.particles[i].av * dt;
|
||||
e.particles[i].pos = HMM_AddV3(e.particles[i].pos, HMM_MulV3F(e.particles[i].v, dt));
|
||||
e.particles[i].angle = HMM_MulQ(e.particles[i].angle, HMM_MulQF(e.particles[i].angle, dt));
|
||||
e.particles[i].life -= dt;
|
||||
|
||||
if (e.particles[i].life <= 0) {
|
||||
e.particles[i].next = e.first;
|
||||
e.first = &e.particles[i];
|
||||
}
|
||||
if (e.particles[i].life <= 0)
|
||||
arrdelswap(e.particles, i);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,22 @@
|
|||
#ifndef PARTICLE_H
|
||||
#define PARTICLE_H
|
||||
|
||||
#include <chipmunk/chipmunk.h>
|
||||
#include "HandmadeMath.h"
|
||||
|
||||
struct particle {
|
||||
cpVect pos;
|
||||
cpVect v; /* velocity */
|
||||
double angle;
|
||||
double av; /* angular velocity */
|
||||
|
||||
HMM_Vec3 pos;
|
||||
HMM_Vec3 v; /* velocity */
|
||||
HMM_Quat angle;
|
||||
HMM_Quat av; /* angular velocity */
|
||||
|
||||
union {
|
||||
double life;
|
||||
struct particle *next;
|
||||
unsigned int next;
|
||||
};
|
||||
};
|
||||
|
||||
struct emitter {
|
||||
struct particle *particles;
|
||||
struct particle *first;
|
||||
int max;
|
||||
double life;
|
||||
void (*seeder)(struct particle *p); /* Called to initialize each particle */
|
||||
|
|
|
@ -13,14 +13,14 @@
|
|||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include "HandmadeMath.h"
|
||||
#include "freelist.h"
|
||||
|
||||
#include "sprite.sglsl.h"
|
||||
#include "9slice.sglsl.h"
|
||||
|
||||
struct TextureOptions TEX_SPRITE = {1, 0, 0};
|
||||
|
||||
static struct sprite *sprites;
|
||||
static int first = -1;
|
||||
static struct sprite *sprites = NULL;
|
||||
|
||||
static sg_shader shader_sprite;
|
||||
static sg_pipeline pip_sprite;
|
||||
|
@ -59,29 +59,21 @@ int make_sprite(int go) {
|
|||
.size = {1.f, 1.f},
|
||||
.tex = texture_loadfromfile(NULL),
|
||||
.go = go,
|
||||
.next = -1,
|
||||
.layer = 0,
|
||||
.next = -1,
|
||||
.enabled = 1};
|
||||
|
||||
int slot = 0;
|
||||
if (first < 0) {
|
||||
arrput(sprites, sprite);
|
||||
slot = arrlen(sprites)-1;
|
||||
} else {
|
||||
slot = first;
|
||||
first = id2sprite(first)->next;
|
||||
*id2sprite(slot) = sprite;
|
||||
}
|
||||
|
||||
return slot;
|
||||
int id;
|
||||
freelist_grab(id, sprites);
|
||||
sprites[id] = sprite;
|
||||
return id;
|
||||
}
|
||||
|
||||
void sprite_delete(int id) {
|
||||
struct sprite *sp = id2sprite(id);
|
||||
sp->go = -1;
|
||||
sp->enabled = 0;
|
||||
sp->next = first;
|
||||
first = id;
|
||||
freelist_kill(sprites,id);
|
||||
}
|
||||
|
||||
void sprite_enabled(int id, int e) {
|
||||
|
@ -132,8 +124,9 @@ void sprite_draw_all() {
|
|||
static int *layers;
|
||||
if (layers) arrfree(layers);
|
||||
|
||||
for (int i = 0; i < arrlen(sprites); i++)
|
||||
if (sprites[i].go >= 0 && sprites[i].enabled) arrpush(layers, i);
|
||||
for (int i = 0; i < freelist_len(sprites); i++)
|
||||
if (sprites[i].next == -1 && sprites[i].go >= 0 && sprites[i].enabled)
|
||||
arrpush(layers, i);
|
||||
|
||||
if (arrlen(layers) == 0) return;
|
||||
if (arrlen(layers) > 1)
|
||||
|
@ -144,6 +137,10 @@ void sprite_draw_all() {
|
|||
}
|
||||
|
||||
void sprite_loadtex(struct sprite *sprite, const char *path, struct glrect frame) {
|
||||
if (!sprite) {
|
||||
YughWarn("NO SPRITE!");
|
||||
return;
|
||||
}
|
||||
sprite->tex = texture_loadfromfile(path);
|
||||
sprite_setframe(sprite, &frame);
|
||||
}
|
||||
|
@ -154,6 +151,8 @@ void sprite_settex(struct sprite *sprite, struct Texture *tex) {
|
|||
}
|
||||
|
||||
void sprite_initialize() {
|
||||
freelist_size(sprites, 500);
|
||||
|
||||
shader_sprite = sg_make_shader(sprite_shader_desc(sg_query_backend()));
|
||||
|
||||
pip_sprite = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
|
|
Loading…
Reference in a new issue