9 typedef struct Kfn Kfn;
21 static int profile, framestep;
22 static int vwdx, vwdy, vwbpp;
42 sysfatal("malloc: %r");
43 setmalloctag(v, getcallerpc(&sz));
58 n = read(0, buf, sizeof(buf) - 1);
62 n = getfields(buf, down, nelem(down), 1, " ");
64 for(n--; n >= 0; n--){
66 if(strcmp(s, "joy1") == 0)
68 else if(strcmp(s, "joy2") == 0)
70 for(kp=kkn.n; kp!=nil; kp=kp->n){
71 if(strcmp(kp->joyk, s) == 0)
91 fd = open("/dev/kbd", OREAD);
97 memmove(buf, buf+n, sizeof(buf)-n);
100 n = read(fd, buf, sizeof(buf)-1);
102 sysfatal("read /dev/kbd: %r");
107 if(utfrune(buf, Kdel)){
111 if(utfrune(buf, KF|5))
113 if(utfrune(buf, KF|6))
115 if(utfrune(buf, KF|12))
117 if(utfrune(buf, 't'))
119 for(kp=kfn.n; kp!=nil; kp=kp->n){
120 if(utfrune(buf, kp->r))
124 if(buf[0] != 'k' && buf[0] != 'K')
129 s += chartorune(&r, s);
131 case Kdel: close(fd); threadexitsall(nil);
144 framestep = !framestep;
150 for(kp=kkn.n; kp!=nil; kp=kp->n){
151 if(utfrune(buf, kp->r))
155 k &= ~(k << 1 & 0xa0 | k >> 1 & 0x50);
174 sprint(buf, "%6.2f%%", 1e11 / (new - old));
177 draw(screen, rectaddpt(Rect(10, 10, vwdx-40, 30), screen->r.min), bg, nil, ZP);
178 string(screen, addpt(screen->r.min, Pt(10, 10)), display->black, ZP, display->defaultfont, buf);
187 scale = Dx(screen->r) / vwdx;
192 p = divpt(addpt(screen->r.min, screen->r.max), 2);
193 picr = Rpt(subpt(p, Pt(scale * vwdx/2, scale * vwdy/2)),
194 addpt(p, Pt(scale * vwdx/2, scale * vwdy/2)));
196 fb = allocimage(display, Rect(0, 0, scale * vwdx, scale > 1 ? 1 : scale * vwdy),
197 vwchan, scale > 1, 0);
199 pic = emalloc(vwdx * vwdy * vwbpp * scale);
200 draw(screen, screen->r, bg, nil, ZP);
204 flushmouse(int discard)
208 if(nbrecvul(mc->resizec) > 0){
209 if(getwindow(display, Refnone) < 0)
210 sysfatal("resize failed: %r");
214 while(nbrecv(mc->c, &m) > 0)
223 loadimage(fb, fb->r, pic, vwdx * vwdy * vwbpp);
224 draw(screen, picr, fb, nil, ZP);
232 w = vwdx * vwbpp * scale;
233 while(r.min.y < picr.max.y){
234 loadimage(fb, fb->r, s, w);
236 r.max.y = r.min.y+scale;
237 draw(screen, r, fb, nil, ZP);
241 flushimage(display, 1);
247 flushaudio(int (*audioout)(void))
249 static vlong old, delta;
252 if(audioout == nil || audioout() < 0 && !warp10){
256 diff = BILLION/60 - (new - old) - delta;
262 diff = (old - new) - (diff / MILLION) * MILLION;
263 delta += (diff - delta) / 100;
274 regkeyfn(Rune r, void (*fn)(void))
278 for(kp=&kfn; kp->n!=nil; kp=kp->n)
280 kp->n = emalloc(sizeof *kp);
286 regkey(char *joyk, Rune r, int k)
290 for(kp=&kkn; kp->n!=nil; kp=kp->n)
292 kp->n = emalloc(sizeof *kp);
293 strncpy(kp->n->joyk, joyk, sizeof(kp->n->joyk)-1);
299 initemu(int dx, int dy, int bpp, ulong chan, int dokey, void(*kproc)(void*))
305 if(initdraw(nil, nil, nil) < 0)
306 sysfatal("initdraw: %r");
307 mc = initmouse(nil, screen);
309 sysfatal("initmouse: %r");
311 proccreate(kproc != nil ? kproc : keyproc, nil, mainstacksize);
313 proccreate(joyproc, nil, mainstacksize*2);
314 bg = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF);