diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 79 |
1 files changed, 68 insertions, 11 deletions
@@ -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; @@ -64,6 +66,14 @@ loadtexture(char *path) } void +initpal(void) +{ + pal[Cmask] = rgb(MASKCOLOR); + pal[Cbg] = rgb(DWhite); + pal[Cfg] = rgb(DBlack); +} + +void kbdproc(void*) { Rune r, *a; @@ -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<<K→) bob.p.x++; - sleep(16); + if(kdown & 1<<KR↺) + bob.roll -= 1*DEG; + if(kdown & 1<<KR↻) + bob.roll += 1*DEG; + toroidwarp(&bob.p); } } |