9 typedef struct Kfn Kfn;
21 static int profile, framestep;
22 static int vwdx, vwdy, vwbpp;
43 sysfatal("malloc: %r");
44 setmalloctag(v, getcallerpc(&sz));
59 n = read(0, buf, sizeof(buf) - 1);
63 n = getfields(buf, down, nelem(down), 1, " ");
65 for(n--; n >= 0; n--){
67 if(strcmp(s, "joy1") == 0)
69 else if(strcmp(s, "joy2") == 0)
71 for(kp=kkn.n; kp!=nil; kp=kp->n){
72 if(strcmp(kp->joyk, s) == 0)
92 fd = open("/dev/kbd", OREAD);
98 memmove(buf, buf+n, sizeof(buf)-n);
101 n = read(fd, buf, sizeof(buf)-1);
103 sysfatal("read /dev/kbd: %r");
108 if(utfrune(buf, Kdel)){
112 if(utfrune(buf, KF|5))
114 if(utfrune(buf, KF|6))
116 if(utfrune(buf, KF|12))
118 if(utfrune(buf, 't'))
120 for(kp=kfn.n; kp!=nil; kp=kp->n){
121 if(utfrune(buf, kp->r))
125 if(buf[0] != 'k' && buf[0] != 'K')
130 s += chartorune(&r, s);
132 case Kdel: close(fd); threadexitsall(nil);
145 framestep = !framestep;
151 for(kp=kkn.n; kp!=nil; kp=kp->n){
152 if(utfrune(buf, kp->r))
178 sprint(buf, "%6.2f%%", 1e11 / (new - old));
181 draw(screen, rectaddpt(Rect(10, 10, vwdx-40, 30), screen->r.min), bg, nil, ZP);
182 string(screen, addpt(screen->r.min, Pt(10, 10)), display->black, ZP, display->defaultfont, buf);
191 scale = Dx(screen->r) / vwdx;
196 p = divpt(addpt(screen->r.min, screen->r.max), 2);
197 picr = Rpt(subpt(p, Pt(scale * vwdx/2, scale * vwdy/2)),
198 addpt(p, Pt(scale * vwdx/2, scale * vwdy/2)));
200 fb = allocimage(display, Rect(0, 0, scale * vwdx, scale > 1 ? 1 : scale * vwdy),
201 vwchan, scale > 1, 0);
203 pic = emalloc(vwdx * vwdy * vwbpp * scale);
204 draw(screen, screen->r, bg, nil, ZP);
208 flushmouse(int discard)
212 if(nbrecvul(mc->resizec) > 0){
213 if(getwindow(display, Refnone) < 0)
214 sysfatal("resize failed: %r");
218 while(nbrecv(mc->c, &m) > 0)
226 loadimage(fb, fb->r, pic, vwdx * vwdy * vwbpp);
227 draw(screen, picr, fb, nil, ZP);
235 w = vwdx * vwbpp * scale;
236 while(r.min.y < picr.max.y){
237 loadimage(fb, fb->r, s, w);
239 r.max.y = r.min.y+scale;
240 draw(screen, r, fb, nil, ZP);
244 flushimage(display, 1);
250 flushaudio(int (*audioout)(void))
252 static vlong old, delta;
255 if(audioout == nil || audioout() < 0 && !warp10){
259 diff = BILLION/60 - (new - old) - delta;
265 diff = (old - new) - (diff / MILLION) * MILLION;
266 delta += (diff - delta) / 100;
277 regkeyfn(Rune r, void (*fn)(void))
281 for(kp=&kfn; kp->n!=nil; kp=kp->n)
283 kp->n = emalloc(sizeof *kp);
289 regkey(char *joyk, Rune r, int k)
293 for(kp=&kkn; kp->n!=nil; kp=kp->n)
295 kp->n = emalloc(sizeof *kp);
296 strncpy(kp->n->joyk, joyk, sizeof(kp->n->joyk)-1);
297 if(strcmp(joyk, "up") == 0 || strcmp(joyk, "down") == 0)
299 if(strcmp(joyk, "left") == 0 || strcmp(joyk, "right") == 0)
306 initemu(int dx, int dy, int bpp, ulong chan, int dokey, void(*kproc)(void*))
312 if(initdraw(nil, nil, nil) < 0)
313 sysfatal("initdraw: %r");
314 mc = initmouse(nil, screen);
316 sysfatal("initmouse: %r");
318 proccreate(kproc != nil ? kproc : keyproc, nil, mainstacksize);
320 proccreate(joyproc, nil, mainstacksize);
321 bg = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF);