ref: 86318ae338e606247cfa057d141e6a974f4898a9
dir: /tbs.c/
#include <u.h> #include <libc.h> #include <draw.h> #include <mouse.h> #include <keyboard.h> #include <thread.h> #include "dat.h" #include "fns.h" extern Point pan; void select(Point); char *dbname, *prefix, *mapname = "map1.db"; static Keyboardctl *kctl; static Mousectl *mctl; void lmenu(char **i, void (*fn[])(void)) { int n; static Menu m; m.item = i; if((n = menuhit(1, mctl, &m, nil)) >= 0) fn[n](); } static void mmenu(void) { enum{ END, SPC, QUIT }; static char *i[] = { [END] "end turn", [SPC] "", [QUIT] "quit", nil }; Menu m = { .item = i }; if(gameover) m.item += 2; switch(menuhit(2, mctl, &m, nil)){ case END: if(!gameover){ endturn(); break; } /* wet floor */ case QUIT: threadexitsall(nil); } } char * estrdup(char *s) { if((s = strdup(s)) == nil) sysfatal("estrdup: %r"); setmalloctag(s, getcallerpc(&s)); return s; } void * emalloc(ulong n) { void *p; if((p = mallocz(n, 1)) == nil) sysfatal("emalloc: %r"); setmalloctag(p, getcallerpc(&n)); return p; } void * erealloc(void *p, ulong n, ulong on) { void *q; q = emalloc(n); if(p != nil && on > 0) memmove(q, p, on); free(p); return q; } static void usage(void) { fprint(2, "usage: %s [-d db] [-m map]\n", argv0); threadexits("usage"); } void threadmain(int argc, char **argv) { Rune r; Mouse om; ARGBEGIN{ case 'd': dbname = EARGF(usage()); break; case 'm': mapname = EARGF(usage()); break; default: usage(); }ARGEND if(dbname == nil) dbname = smprint("%s.db", progname); if(prefix == nil) prefix = smprint("/sys/games/lib/%s", progname); srand(time(nil)); init(); if(initdraw(nil, nil, progname) < 0) sysfatal("initdraw: %r"); if((kctl = initkeyboard(nil)) == nil) sysfatal("initkeyboard: %r"); if((mctl = initmouse(nil, screen)) == nil) sysfatal("initmouse: %r"); om.xy = ZP; initimages(); resetdraw(); Alt a[] = { {mctl->c, &mctl->Mouse, CHANRCV}, {mctl->resizec, nil, CHANRCV}, {kctl->c, &r, CHANRCV}, {nil, nil, CHANEND} }; for(;;){ switch(alt(a)){ default: sysfatal("alt: %r"); case 0: if(eqpt(om.xy, ZP)) om = mctl->Mouse; if((mctl->buttons & 1) == 1 && (om.buttons & 1) == 0) select(mctl->xy); if(mctl->buttons & 2) mmenu(); if(mctl->buttons & 4) dopan(mctl->xy.x - om.xy.x, mctl->xy.y - om.xy.y); om = mctl->Mouse; break; case 1: if(getwindow(display, Refnone) < 0) sysfatal("getwindow: %r"); om = mctl->Mouse; resetdraw(); break; case 2: switch(r){ case '+': case '=': if(scale < 16){ scale++; resetdraw(); } break; case '-': if(scale > 1){ scale--; resetdraw(); } break; case 'r': scale = 1; pan = ZP; resetdraw(); break; case Kesc: selected = nil; redraw(0); break; } break; } } }