9 typedef struct Kfn Kfn;
15 int scale, fixscale, warp10;
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);
192 scale = Dx(screen->r) / vwdx;
193 if(Dy(screen->r) / vwdy < scale)
194 scale = Dy(screen->r) / vwdy;
200 p = divpt(addpt(screen->r.min, screen->r.max), 2);
201 picr = Rpt(subpt(p, Pt(scale * vwdx/2, scale * vwdy/2)),
202 addpt(p, Pt(scale * vwdx/2, scale * vwdy/2)));
204 fb = allocimage(display, Rect(0, 0, scale * vwdx, scale > 1 ? 1 : scale * vwdy),
205 vwchan, scale > 1, 0);
207 pic = emalloc(vwdx * vwdy * vwbpp * scale);
208 draw(screen, screen->r, bg, nil, ZP);
212 flushmouse(int discard)
216 if(nbrecvul(mc->resizec) > 0){
217 if(getwindow(display, Refnone) < 0)
218 sysfatal("resize failed: %r");
222 while(nbrecv(mc->c, &m) > 0)
230 loadimage(fb, fb->r, pic, vwdx * vwdy * vwbpp);
231 draw(screen, picr, fb, nil, ZP);
239 w = vwdx * vwbpp * scale;
240 while(r.min.y < picr.max.y){
241 loadimage(fb, fb->r, s, w);
243 r.max.y = r.min.y+scale;
244 draw(screen, r, fb, nil, ZP);
248 flushimage(display, 1);
254 flushaudio(int (*audioout)(void))
256 static vlong old, delta;
259 if(audioout == nil || audioout() < 0 && !warp10){
263 diff = BILLION/60 - (new - old) - delta;
269 diff = (old - new) - (diff / MILLION) * MILLION;
270 delta += (diff - delta) / 100;
281 regkeyfn(Rune r, void (*fn)(void))
285 for(kp=&kfn; kp->n!=nil; kp=kp->n)
287 kp->n = emalloc(sizeof *kp);
293 regkey(char *joyk, Rune r, int k)
297 for(kp=&kkn; kp->n!=nil; kp=kp->n)
299 kp->n = emalloc(sizeof *kp);
300 strncpy(kp->n->joyk, joyk, sizeof(kp->n->joyk)-1);
301 if(strcmp(joyk, "up") == 0 || strcmp(joyk, "down") == 0)
303 if(strcmp(joyk, "left") == 0 || strcmp(joyk, "right") == 0)
310 initemu(int dx, int dy, int bpp, ulong chan, int dokey, void(*kproc)(void*))
316 if(initdraw(nil, nil, nil) < 0)
317 sysfatal("initdraw: %r");
318 mc = initmouse(nil, screen);
320 sysfatal("initmouse: %r");
322 proccreate(kproc != nil ? kproc : keyproc, nil, mainstacksize);
324 proccreate(joyproc, nil, mainstacksize);
325 bg = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF);