ref: ef9b582868430fefaf733b7dc13ed6e9dc303bac
dir: /city.c/
#include <u.h> #include <libc.h> #include <thread.h> #include <draw.h> #include <mouse.h> #include <keyboard.h> #include "dat.h" #include "fns.h" static int tdiv; static Keyboardctl *kc; static Mousectl *mc; static Channel *tmc; void * emalloc(ulong n) { void *p; if((p = mallocz(n, 1)) == nil) sysfatal("emalloc: %r"); setmalloctag(p, getcallerpc(&n)); return p; } int max(int a, int b) { return a > b ? a : b; } int min(int a, int b) { return a < b ? a : b; } static void timeproc(void *) { tdiv = 1000 / AnimHz; for(;;){ sleep(tdiv); nbsendul(tmc, 0); } } void threadmain(int argc, char **argv) { Rune r; Mouse mo; ARGBEGIN{ }ARGEND init(); initdrw(); if((kc = initkeyboard(nil)) == nil) sysfatal("initkeyboard: %r"); if((mc = initmouse(nil, screen)) == nil) sysfatal("initmouse: %r"); if((tmc = chancreate(sizeof(ulong), 0)) == nil) sysfatal("chancreate: %r"); if(proccreate(timeproc, nil, 8192) < 0) sysfatal("init: %r"); readfs(); resetdraw(); startsim(); mo.xy = ZP; enum{ Aresize, Amouse, Akbd, Aanim, }; Alt a[] = { {mc->resizec, nil, CHANRCV}, {mc->c, &mc->Mouse, CHANRCV}, {kc->c, &r, CHANRCV}, {tmc, nil, CHANRCV}, {nil, nil, CHANEND} }; for(;;){ switch(alt(a)){ case Aresize: if(getwindow(display, Refnone) < 0) sysfatal("resize failed: %r"); mo = mc->Mouse; resetdraw(); break; case Amouse: if(eqpt(mo.xy, ZP)) mo = mc->Mouse; if(mc->buttons & 1<<0) mouseselect(mc->xy); break; case Akbd: switch(r){ case Kdel: case 'q': threadexitsall(nil); case ' ': paused ^= 1; break; case '+': case '=': if(scale < 16){ scale++; resetdraw(); } break; case '-': if(scale > 1){ scale--; resetdraw(); } break; } break; case Aanim: updatedraw(); break; } } }