From 671c2cac38ffada7f9185b87ec27b84566db8c2b Mon Sep 17 00:00:00 2001 From: rodri Date: Fri, 15 Nov 2024 16:41:59 +0000 Subject: =?UTF-8?q?forgot=20the=20vfx=20units=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sprite.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ vfx.c | 71 +++++++++++++++++++++++++++++++++++++ 2 files changed, 193 insertions(+) create mode 100644 sprite.c create mode 100644 vfx.c diff --git a/sprite.c b/sprite.c new file mode 100644 index 0000000..3766fe2 --- /dev/null +++ b/sprite.c @@ -0,0 +1,122 @@ +#include +#include +#include +#include +#include +#include +#include +#include "dat.h" +#include "fns.h" + +static void +sprite_step(Sprite *spr, ulong Δt) +{ + if(spr->nframes < 2) + return; + + spr->elapsed += Δt; + + if(spr->elapsed >= spr->period){ + spr->elapsed -= spr->period; + spr->curframe = ++spr->curframe % spr->nframes; + } +} + +static void +sprite_draw(Sprite *spr, Image *dst, Point dp) +{ + Point sp = (Point){ + spr->curframe * Dx(spr->r), + 0 + }; + sp = addpt(spr->sp, sp); + + draw(dst, rectaddpt(spr->r, dp), spr->sheet, nil, sp); +} + +static Sprite * +sprite_clone(Sprite *spr) +{ + return newsprite(spr->sheet, spr->sp, spr->r, spr->nframes, spr->period); +} + +Sprite * +newsprite(Image *sheet, Point sp, Rectangle r, int nframes, ulong period) +{ + Sprite *spr; + + spr = emalloc(sizeof(Sprite)); + spr->sheet = sheet; + spr->sp = sp; + spr->r = r; + spr->nframes = nframes; + spr->curframe = 0; + spr->period = period; + spr->elapsed = 0; + spr->step = sprite_step; + spr->draw = sprite_draw; + spr->clone = sprite_clone; + + return spr; +} + +Sprite * +readsprite(char *sheetfile, Point sp, Rectangle r, int nframes, ulong period) +{ + Image *sheet; + int fd; + + fd = open(sheetfile, OREAD); + if(fd < 0) + sysfatal("readsprite: %r"); + sheet = readimage(display, fd, 1); + close(fd); + + return newsprite(sheet, sp, r, nframes, period); +} + +static void +decproc(void *arg) +{ + int fd, *pfd; + + pfd = arg; + fd = pfd[2]; + + close(pfd[0]); + dup(fd, 0); + close(fd); + dup(pfd[1], 1); + close(pfd[1]); + + execl("/bin/png", "png", "-t9", nil); + threadexitsall("execl: %r"); +} + +Sprite * +readpngsprite(char *sheetfile, Point sp, Rectangle r, int nframes, ulong period) +{ + Image *sheet; + int fd, pfd[3]; + + if(pipe(pfd) < 0) + sysfatal("pipe: %r"); + fd = open(sheetfile, OREAD); + if(fd < 0) + sysfatal("readpngsprite: %r"); + pfd[2] = fd; + procrfork(decproc, pfd, mainstacksize, RFFDG|RFNAMEG|RFNOTEG); + close(pfd[1]); + sheet = readimage(display, pfd[0], 1); + close(pfd[0]); + close(fd); + + return newsprite(sheet, sp, r, nframes, period); +} + +void +delsprite(Sprite *spr) +{ + //freeimage(spr->sheet); + free(spr); +} diff --git a/vfx.c b/vfx.c new file mode 100644 index 0000000..787a67d --- /dev/null +++ b/vfx.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include +#include +#include "dat.h" +#include "fns.h" + +static void +vfx_step(Vfx *v, ulong Δt) +{ + if(v->times == 0 && v->a->curframe == 0){ + delvfx(v); + return; + } + + v->a->step(v->a, Δt); + + if(v->times > 0 && v->a->curframe == v->a->nframes-1) + v->times--; +} + +static void +vfx_draw(Vfx *v, Image *dst) +{ + if(v->times == 0 && v->a->curframe == 0) + return; + + v->a->draw(v->a, dst, subpt(v->p, divpt(subpt(v->a->r.max, v->a->r.min), 2))); +} + +Vfx * +newvfx(Sprite *spr, Point dp, int repeat) +{ + Vfx *v; + + v = emalloc(sizeof(Vfx)); + v->a = spr; + v->p = dp; + v->times = repeat; + v->step = vfx_step; + v->draw = vfx_draw; + + return v; +} + +void +delvfx(Vfx *v) +{ + v->next->prev = v->prev; + v->prev->next = v->next; + delsprite(v->a); + free(v); +} + +void +addvfx(Vfx *v, Vfx *nv) +{ + nv->prev = v->prev; + nv->next = v; + v->prev->next = nv; + v->prev = nv; +} + +void +initvfxq(Vfx *v) +{ + v->next = v->prev = v; +} -- cgit v1.2.3