From 3070f8b6c4e359571027b93c140434f7bfd32a3f Mon Sep 17 00:00:00 2001 From: rgl Date: Wed, 5 Feb 2020 18:28:07 +0100 Subject: good sprite support with masking and initial rotation attempts. --- assets/bob.pic | Bin 3132 -> 3132 bytes assets/bob.spr | 8 +++--- assets/sod.pal | 2 +- dat.h | 15 +++++++++++ main.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 5 files changed, 88 insertions(+), 16 deletions(-) diff --git a/assets/bob.pic b/assets/bob.pic index 5ab4759..5eb79b4 100644 Binary files a/assets/bob.pic and b/assets/bob.pic differ diff --git a/assets/bob.spr b/assets/bob.spr index c9fd8d8..e384b08 100644 --- a/assets/bob.spr +++ b/assets/bob.spr @@ -10,10 +10,10 @@ sprite 32 32 sod.pal 0 0 0 0 0 0 0 0 0 0 0 202 202 0 0 0 0 0 202 202 202 202 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 202 202 202 202 202 0 202 202 202 15 15 202 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 202 202 15 15 15 202 202 202 15 15 15 15 15 202 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 202 202 15 15 15 202 202 202 15 15 0 15 15 202 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 202 202 15 0 15 202 202 202 15 15 0 15 15 202 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 202 202 15 0 15 202 202 202 15 15 0 15 15 202 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 202 202 15 15 15 202 202 15 15 0 15 15 202 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 202 202 15 15 15 202 202 202 15 15 31 15 15 202 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 202 202 15 31 15 202 202 202 15 15 31 15 15 202 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 202 202 15 31 15 202 202 202 15 15 31 15 15 202 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 202 202 15 15 15 202 202 15 15 31 15 15 202 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 202 202 202 15 15 202 202 202 202 15 15 15 15 202 202 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 202 202 47 202 202 15 202 202 202 202 15 15 15 202 202 202 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 202 202 47 48 202 202 202 202 202 202 202 202 202 202 47 202 202 0 0 0 0 0 0 0 diff --git a/assets/sod.pal b/assets/sod.pal index c589b72..4c1d35e 100644 --- a/assets/sod.pal +++ b/assets/sod.pal @@ -1,5 +1,5 @@ pal 256 -0x000000 +0x00ff00 0x0000aa 0x00aa00 0x00aaaa diff --git a/dat.h b/dat.h index 21e2891..31764b7 100644 --- a/dat.h +++ b/dat.h @@ -1,5 +1,9 @@ +#define DEG 0.01745329251994330 + enum { + KR↺, + KR↻, K↑, K↓, K←, @@ -7,10 +11,21 @@ enum Ke }; +enum +{ + Cmask, + Cbg, + Cfg, + NCOLOR, + + MASKCOLOR = 0x00FF00FF +}; + typedef struct Sprite Sprite; struct Sprite { Point p; Memimage *spr; + double roll; }; diff --git a/main.c b/main.c index 065d8cf..ffd5e1b 100644 --- a/main.c +++ b/main.c @@ -13,10 +13,12 @@ ulong kdown; double Δt; Image *screenb; Memimage *fb; -Memimage *bg, *fg; +Memimage *pal[NCOLOR]; Sprite bob; Rune keys[Ke] = { + [KR↺] 'q', + [KR↻] 'e', [K↑] Kup, [K↓] Kdown, [K←] Kleft, @@ -48,7 +50,7 @@ rgb(ulong c) } Memimage* -loadtexture(char *path) +loadsprite(char *path) { Memimage *i; int fd; @@ -63,6 +65,14 @@ loadtexture(char *path) return i; } +void +initpal(void) +{ + pal[Cmask] = rgb(MASKCOLOR); + pal[Cbg] = rgb(DWhite); + pal[Cfg] = rgb(DBlack); +} + void kbdproc(void*) { @@ -121,19 +131,63 @@ drawproc(void *arg) void resetfb(void) { + freememimage(fb); + fb = eallocmemimage(Rect(0,0,Dx(screen->r),Dy(screen->r)), screen->chan); freeimage(screenb); screenb = allocimage(display, Rect(0,0,Dx(screen->r),Dy(screen->r)), screen->chan, 0, DNofill); - freememimage(fb); - fb = eallocmemimage(Rect(0,0,Dx(screen->r),Dy(screen->r)), screen->chan); +} + +double +round(double n) +{ + return floor(n + 0.5); +} + +Point +rotatept(Point p, double θ, Point c) +{ + Point r; + + p = subpt(p, c); + r.x = round(p.x*cos(θ) - p.y*sin(θ)); + r.y = round(p.x*sin(θ) + p.y*cos(θ)); + r = addpt(r, c); + return r; +} + +void +toroidwarp(Point *p) +{ + if(p->x < 0) + p->x += fb->r.max.x; + if(p->x >= fb->r.max.x) + p->x -= fb->r.max.x; + if(p->y < 0) + p->y += fb->r.max.y; + if(p->y >= fb->r.max.y) + p->y -= fb->r.max.y; } void redraw(void) { Rectangle r; + Point p; + + memimagedraw(fb, fb->r, pal[Cbg], ZP, nil, ZP, SoverD); + for(r = ZR; r.min.y < bob.spr->r.max.y; r.min.y++){ + r.min.x = 0; + r.max.y = r.min.y+1; + for(; r.min.x < bob.spr->r.max.x; r.min.x++){ + r.max.x = r.min.x+1; + p = addpt(r.min,subpt(bob.p, Pt(Dx(bob.spr->r)/2,Dy(bob.spr->r)/2))); + p = rotatept(p, bob.roll, bob.p); + toroidwarp(&p); + if(memcmp(byteaddr(bob.spr, r.min), byteaddr(pal[Cmask], ZP), bob.spr->depth/8) != 0) - memimagedraw(fb, fb->r, bg, ZP, nil, ZP, SoverD); - memimagedraw(fb, Rpt(subpt(bob.p, Pt(Dx(bob.spr->r),Dy(bob.spr->r))), addpt(bob.p, Pt(32,32))), bob.spr, ZP, nil, ZP, SoverD); + memimagedraw(fb, Rpt(p,addpt(p,Pt(1,1))), bob.spr, r.min, nil, ZP, SoverD); + } + } for(r = fb->r; r.min.y < fb->r.max.y; r.min.y++){ r.max.y = r.min.y+1; loadimage(screenb, r, byteaddr(fb, r.min), bytesperline(r, fb->depth)); @@ -184,9 +238,8 @@ threadmain(int argc, char *argv[]) if((mctl = initmouse(nil, screen)) == nil) sysfatal("initmouse: %r"); resetfb(); - bg = rgb(DWhite); - fg = rgb(DBlack); - bob.spr = loadtexture("assets/bob.pic"); + initpal(); + bob.spr = loadsprite("assets/bob.pic"); bob.p = divpt(fb->r.max, 2); drawc = chancreate(1, 0); display->locking = 1; @@ -200,7 +253,7 @@ threadmain(int argc, char *argv[]) {mctl->c, &mctl->Mouse, CHANRCV}, {mctl->resizec, nil, CHANRCV}, {drawc, nil, CHANRCV}, - {nil, nil, CHANNOBLK} + {nil, nil, CHANEND} }; switch(alt(a)){ case MOUSE: mouse(); break; @@ -218,6 +271,10 @@ threadmain(int argc, char *argv[]) bob.p.x--; if(kdown & 1<