#include <libc.h>
#include <thread.h>
#include <draw.h>
-#include <mouse.h>
#include <keyboard.h>
+#include "../eui.h"
#include "dat.h"
#include "fns.h"
int cpuhalt;
-int scale, profile;
-Rectangle picr;
-Image *bg, *tmp;
-Mousectl *mc;
-int keys, paused, framestep, backup;
-QLock pauselock;
+int backup;
int savefd = -1, saveframes;
ulong clock;
-int savereq, loadreq;
u8int mbc, feat, mode;
extern MBC3Timer timer, timerl;
-void *
-emalloc(ulong sz)
+extern double TAU;
+void
+tauup(void)
{
- void *v;
-
- v = malloc(sz);
- if(v == nil)
- sysfatal("malloc: %r");
- setmalloctag(v, getcallerpc(&sz));
- return v;
+ TAU += 5000;
+}
+void
+taudn(void)
+{
+ TAU -= 5000;
}
void
}
void
-timerload(char *buf)
+timerload(uchar *buf)
{
timer.ns = buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24 | (uvlong)buf[4] << 32 | (uvlong)buf[5] << 40 | (uvlong)buf[6] << 48LL | (uvlong)buf[7] << 56LL;
timer.sec = buf[8];
}
void
-timersave(char *buf)
+timersave(uchar *buf)
{
buf[0] = timer.ns;
buf[1] = timer.ns >> 8;
void
flushback(void)
{
- char buf[TIMERSIZ];
+ uchar buf[TIMERSIZ];
if(savefd >= 0){
pwrite(savefd, back, nback, 0);
loadsave(char *file)
{
char *buf, *p;
- char tim[TIMERSIZ];
+ uchar tim[TIMERSIZ];
buf = emalloc(strlen(file) + 4);
strcpy(buf, file);
- p = strchr(buf, '.');
+ p = strrchr(buf, '.');
if(p == nil)
p = buf + strlen(buf);
strcpy(p, ".sav");
}
-void
-screeninit(void)
-{
- Point p;
-
- p = divpt(addpt(screen->r.min, screen->r.max), 2);
- picr = (Rectangle){subpt(p, Pt(scale * PICW/2, scale * PICH/2)), addpt(p, Pt(scale * PICW/2, scale * PICH/2))};
- tmp = allocimage(display, Rect(0, 0, scale * PICW, scale > 1 ? 1 : scale * PICH), XRGB32, scale > 1, 0);
- bg = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF);
- draw(screen, screen->r, bg, nil, ZP);
-}
-
-void
-keyproc(void *)
-{
- int fd, n, k;
- static char buf[256];
- char *s;
- Rune r;
- extern double TAU;
-
- fd = open("/dev/kbd", OREAD);
- if(fd < 0)
- sysfatal("open: %r");
- for(;;){
- if(buf[0] != 0){
- n = strlen(buf)+1;
- memmove(buf, buf+n, sizeof(buf)-n);
- }
- if(buf[0] == 0){
- n = read(fd, buf, sizeof(buf)-1);
- if(n <= 0)
- sysfatal("read /dev/kbd: %r");
- buf[n-1] = 0;
- buf[n] = 0;
- }
- if(buf[0] == 'c'){
- if(utfrune(buf, KF|5))
- savereq = 1;
- if(utfrune(buf, KF|6))
- loadreq = 1;
- if(utfrune(buf, Kdel)){
- close(fd);
- threadexitsall(nil);
- }
- if(utfrune(buf, 't'))
- trace = !trace;
- if(utfrune(buf, KF|9))
- TAU += 5000;
- if(utfrune(buf, KF|10))
- TAU -= 5000;
- }
- if(buf[0] != 'k' && buf[0] != 'K')
- continue;
- s = buf + 1;
- k = 0;
- while(*s != 0){
- s += chartorune(&r, s);
- switch(r){
- case Kdel: close(fd); threadexitsall(nil);
- case 'z': k |= 1<<5; break;
- case 'x': k |= 1<<4; break;
- case Kshift: k |= 1<<6; break;
- case 10: k |= 1<<7; break;
- case Kup: k |= 1<<2; break;
- case Kdown: k |= 1<<3; break;
- case Kleft: k |= 1<<1; break;
- case Kright: k |= 1<<0; break;
- case Kesc:
- if(paused)
- qunlock(&pauselock);
- else
- qlock(&pauselock);
- paused = !paused;
- break;
- case KF|1:
- if(paused){
- qunlock(&pauselock);
- paused=0;
- }
- framestep = !framestep;
- break;
- }
- }
- k &= ~(k << 1 & 0x0a | k >> 1 & 0x05);
- keys = k;
- }
-
-}
-
-void
-timing(void)
-{
- static int fcount;
- static vlong old;
- static char buf[32];
- vlong new;
-
- if(++fcount == 60)
- fcount = 0;
- else
- return;
- new = nsec();
- if(new != old)
- sprint(buf, "%6.2f%%", 1e11 / (new - old));
- else
- buf[0] = 0;
- draw(screen, rectaddpt(Rect(10, 10, 200, 30), screen->r.min), bg, nil, ZP);
- string(screen, addpt(screen->r.min, Pt(10, 10)), display->black, ZP, display->defaultfont, buf);
- old = nsec();
-}
-
void
flush(void)
{
extern uchar pic[];
- Mouse m;
static vlong old, delta;
- vlong new, diff;
-
- if(nbrecvul(mc->resizec) > 0){
- if(getwindow(display, Refnone) < 0)
- sysfatal("resize failed: %r");
- screeninit();
- }
- while(nbrecv(mc->c, &m) > 0)
- ;
- if(scale == 1){
- loadimage(tmp, tmp->r, pic, PICW*PICH*4);
- draw(screen, picr, tmp, nil, ZP);
- } else {
- Rectangle r;
- uchar *s;
- int w;
- s = pic;
- r = picr;
- w = PICW*4*scale;
- while(r.min.y < picr.max.y){
- loadimage(tmp, tmp->r, s, w);
- s += w;
- r.max.y = r.min.y+scale;
- draw(screen, r, tmp, nil, ZP);
- r.min.y = r.max.y;
- }
- }
- flushimage(display, 1);
- if(profile)
- timing();
- if(audioout() < 0){
- new = nsec();
- diff = 0;
- if(old != 0){
- diff = BILLION/60 - (new - old) - delta;
- if(diff >= MILLION)
- sleep(diff/MILLION);
- }
- old = nsec();
- if(diff != 0){
- diff = (old - new) - (diff / MILLION) * MILLION;
- delta += (diff - delta) / 100;
- }
- }
- if(framestep){
- paused = 1;
- qlock(&pauselock);
- framestep = 0;
- }
-
+ flushmouse(1);
+ flushscreen();
+ flushaudio(audioout);
if(saveframes > 0 && --saveframes == 0)
flushback();
if(savereq){
int t;
colinit();
- scale = 1;
ARGBEGIN {
- case '2':
- scale = 2;
- break;
- case '3':
- scale = 3;
- break;
case 'a':
audioinit();
break;
- case 'T':
- profile++;
- break;
case 'c':
mode |= CGB;
break;
usage();
loadrom(argv[0]);
-
- if(initdraw(nil, nil, nil) < 0)
- sysfatal("initdraw: %r");
- mc = initmouse(nil, screen);
- if(mc == nil)
- sysfatal("initmouse: %r");
- proccreate(keyproc, nil, mainstacksize);
- screeninit();
+ initemu(PICW, PICH, 4, XRGB32, 1, nil);
+ regkey("b", 'z', 1<<5);
+ regkey("a", 'x', 1<<4);
+ regkey("control", Kshift, 1<<6);
+ regkey("start", '\n', 1<<7);
+ regkey("up", Kup, 1<<2);
+ regkey("down", Kdown, 1<<3);
+ regkey("left", Kleft, 1<<1);
+ regkey("right", Kright, 1<<0);
+ regkeyfn(KF|9, tauup);
+ regkeyfn(KF|10, taudn);
eventinit();
meminit();