summaryrefslogtreecommitdiff
path: root/sys/src/games
diff options
context:
space:
mode:
authorqwx <devnull@localhost>2018-05-12 19:20:53 +0200
committerqwx <devnull@localhost>2018-05-12 19:20:53 +0200
commit1195ca910c393e542d6aa23035fa75719af1107e (patch)
treec53f3d829d787834610367a9c4d41b5d29dcbb25 /sys/src/games
parent70c7a9eb07516843da083b6231d55a07d28b9350 (diff)
add libemu
move redundant code from emulators to a common library
Diffstat (limited to 'sys/src/games')
-rw-r--r--sys/src/games/c64/c64.c97
-rw-r--r--sys/src/games/c64/cpu.c3
-rw-r--r--sys/src/games/c64/dat.h9
-rw-r--r--sys/src/games/c64/mem.c1
-rw-r--r--sys/src/games/c64/vic.c42
-rw-r--r--sys/src/games/gb/apu.c3
-rw-r--r--sys/src/games/gb/cpu.c1
-rw-r--r--sys/src/games/gb/dat.h7
-rw-r--r--sys/src/games/gb/gb.c224
-rw-r--r--sys/src/games/gb/mem.c1
-rw-r--r--sys/src/games/gb/ppu.c33
-rw-r--r--sys/src/games/gba/apu.c5
-rw-r--r--sys/src/games/gba/cpu.c3
-rw-r--r--sys/src/games/gba/dat.h10
-rw-r--r--sys/src/games/gba/gba.c220
-rw-r--r--sys/src/games/gba/mem.c1
-rw-r--r--sys/src/games/gba/ppu.c75
-rw-r--r--sys/src/games/md/cpu.c3
-rw-r--r--sys/src/games/md/dat.h9
-rw-r--r--sys/src/games/md/md.c184
-rw-r--r--sys/src/games/md/mem.c3
-rw-r--r--sys/src/games/md/vdp.c43
-rw-r--r--sys/src/games/md/ym.c5
-rw-r--r--sys/src/games/nes/apu.c3
-rw-r--r--sys/src/games/nes/dat.h6
-rw-r--r--sys/src/games/nes/mem.c1
-rw-r--r--sys/src/games/nes/nes.c159
-rw-r--r--sys/src/games/nes/ppu.c93
-rw-r--r--sys/src/games/snes/cpu.c3
-rw-r--r--sys/src/games/snes/dat.h8
-rw-r--r--sys/src/games/snes/dsp.c3
-rw-r--r--sys/src/games/snes/mem.c1
-rw-r--r--sys/src/games/snes/ppu.c39
-rw-r--r--sys/src/games/snes/snes.c252
-rw-r--r--sys/src/games/snes/spc.c1
35 files changed, 321 insertions, 1230 deletions
diff --git a/sys/src/games/c64/c64.c b/sys/src/games/c64/c64.c
index c20333760..9b4e0504b 100644
--- a/sys/src/games/c64/c64.c
+++ b/sys/src/games/c64/c64.c
@@ -4,18 +4,15 @@
#include <draw.h>
#include <mouse.h>
#include <keyboard.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
char *bindir = "/sys/lib/c64";
-Image *tmp, *bg, *red;
-Rectangle picr, progr;
-Mousectl *mc;
-QLock pauselock;
-int paused, scale;
+Image *red;
+Rectangle progr;
u8int *rom;
int nrom;
-u64int keys;
u16int joys;
uchar *tape, tapever, tapeplay;
ulong tapelen;
@@ -26,7 +23,8 @@ progress(int a, int b)
{
static int cur;
int w;
-
+
+ extern Image *bg;
if(b == 0 || a == 0){
if(cur != 0){
draw(screen, progr, bg, nil, ZP);
@@ -212,21 +210,6 @@ keyproc(void *)
}
static void
-screeninit(void)
-{
- Point p, q;
-
- p = divpt(addpt(screen->r.min, screen->r.max), 2);
- picr = (Rectangle){subpt(p, Pt(picw/2*scale, pich/2*scale)), addpt(p, Pt(picw/2*scale, pich/2*scale))};
- p.y += pich*scale*3/4;
- q = Pt(Dx(screen->r) * 2/5, 8);
- progr = (Rectangle){subpt(p, q), addpt(p, q)};
- freeimage(tmp);
- tmp = allocimage(display, Rect(0, 0, picw*scale, scale > 1 ? 1 : pich), XRGB32, 1, 0);
- draw(screen, screen->r, bg, nil, ZP);
-}
-
-static void
usage(void)
{
fprint(2, "usage: %s [ -23a ] [ rom ]\n", argv0);
@@ -236,17 +219,9 @@ usage(void)
void
threadmain(int argc, char **argv)
{
- scale = 1;
-
memreset();
ARGBEGIN {
- case '2':
- scale = 2;
- break;
- case '3':
- scale = 3;
- break;
case 'c':
loadcart(EARGF(usage()));
break;
@@ -272,16 +247,8 @@ threadmain(int argc, char **argv)
loadsys("crom.bin", crom, 4096);
vicreset();
-
- if(initdraw(nil, nil, nil) < 0)
- sysfatal("initdraw: %r");
- mc = initmouse(nil, screen);
- if(mc == nil)
- sysfatal("initmouse: %r");
- bg = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF);
+ initemu(picw, pich, 4, XRGB32, 1, keyproc);
red = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xFF0000FF);
- screeninit();
- proccreate(keyproc, nil, mainstacksize);
nmien = IRQRESTORE;
pc = memread(0xFFFC) | memread(0xFFFD) << 8;
@@ -309,7 +276,8 @@ menu(void)
static Menu m = {
items, nil, 0
};
-
+
+ extern Mousectl *mc;
switch(menuhit(3, mc, &m, nil)){
case JOY:
joymode = (joymode + 1) % 3;
@@ -332,52 +300,11 @@ menu(void)
void
flush(void)
{
- extern u8int pic[];
-// vlong new, diff;
-// static vlong old, delta;
-
- if(nbrecvul(mc->resizec) > 0){
- if(getwindow(display, Refnone) < 0)
- sysfatal("resize failed: %r");
- screeninit();
- }
+ extern Mousectl *mc;
+ flushmouse(0);
while(nbrecv(mc->c, &mc->Mouse) > 0)
if((mc->buttons & 4) != 0)
menu();
- 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(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;
- }
- }
-*/
+ flushscreen();
+ flushaudio(nil);
}
diff --git a/sys/src/games/c64/cpu.c b/sys/src/games/c64/cpu.c
index 5f77ff92f..cafd8e333 100644
--- a/sys/src/games/c64/cpu.c
+++ b/sys/src/games/c64/cpu.c
@@ -1,5 +1,6 @@
#include <u.h>
#include <libc.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
@@ -289,8 +290,6 @@ interrupt(int nmi, int brk)
rP |= FLAGI;
}
-int trace;
-
void
step(void)
{
diff --git a/sys/src/games/c64/dat.h b/sys/src/games/c64/dat.h
index f8f1de1ce..723053d75 100644
--- a/sys/src/games/c64/dat.h
+++ b/sys/src/games/c64/dat.h
@@ -1,10 +1,8 @@
-typedef char s8int;
-
extern u8int reg[47], crom[4096], krom[8192], brom[8192], cram[1024], cart[16384];
extern u16int pc, curpc;
extern u8int rP;
-extern int nrdy, irq, nmi, irqen, nmien, trace;
+extern int nrdy, irq, nmi, irqen, nmien;
extern u8int pla;
@@ -12,9 +10,8 @@ extern uchar *tape, tapever, tapeplay;
extern ulong tapelen;
extern u16int ppux, ppuy, picw, pich;
-extern u64int keys;
extern u16int joys;
-extern int scale, region;
+extern int region;
enum {
FLAGC = 1<<0,
@@ -81,8 +78,6 @@ enum {
};
enum {
- BILLION = 1000*1000*1000,
- MILLION = 1000*1000,
HZ = 3579545,
RATE = 44100,
SAMPDIV = HZ / 3 / RATE,
diff --git a/sys/src/games/c64/mem.c b/sys/src/games/c64/mem.c
index 5245a55e9..8e00bec4b 100644
--- a/sys/src/games/c64/mem.c
+++ b/sys/src/games/c64/mem.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
diff --git a/sys/src/games/c64/vic.c b/sys/src/games/c64/vic.c
index 8233f38c8..c181b2446 100644
--- a/sys/src/games/c64/vic.c
+++ b/sys/src/games/c64/vic.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
@@ -9,7 +10,6 @@ u16int ppux, ppuy, lastx, wrapx, maxy, lvis, rvis, uvis, dvis, picw, pich, lbord
u16int vc, vcbase, vmli;
u8int badln, rc, displ, fract, visreg, hbord, vbord, rbord0, lbord0;
u16int chrp[40];
-u8int pic[420*263*4*3];
u64int pxs, npxs, npxs0, opxs;
u8int fg;
@@ -92,24 +92,40 @@ vicreset(void)
void
pixeldraw(u64int p, int n)
{
- int i, j;
+ int i;
+ union { u8int c[4]; u32int l; } u;
static u8int cr[] = {0, 255, 136, 170, 204, 0, 0, 238, 221, 102, 255, 51, 119, 170, 0, 187};
static u8int cg[] = {0, 255, 0, 255, 68, 204, 0, 238, 136, 68, 119, 51, 119, 255, 136, 187};
static u8int cb[] = {0, 255, 0, 238, 204, 85, 170, 119, 85, 0, 119, 51, 119, 102, 255, 187};
- u8int *q, c;
-
- q = pic + picidx * 4 * scale;
+ u8int c;
+ u32int *q;
+
+ q = (u32int *)pic + picidx * scale;
for(i = 0; i < n; i++){
c = p >> 56;
p <<= 8;
-
- j = scale;
- do{
- *q++ = cb[c];
- *q++ = cg[c];
- *q++ = cr[c];
- q++;
- }while(--j);
+ u.c[0] = cb[c];
+ u.c[1] = cg[c];
+ u.c[2] = cr[c];
+ u.c[3] = 0;
+ switch(scale){
+ case 16: *q++ = u.l;
+ case 15: *q++ = u.l;
+ case 14: *q++ = u.l;
+ case 13: *q++ = u.l;
+ case 12: *q++ = u.l;
+ case 11: *q++ = u.l;
+ case 10: *q++ = u.l;
+ case 9: *q++ = u.l;
+ case 8: *q++ = u.l;
+ case 7: *q++ = u.l;
+ case 6: *q++ = u.l;
+ case 5: *q++ = u.l;
+ case 4: *q++ = u.l;
+ case 3: *q++ = u.l;
+ case 2: *q++ = u.l;
+ default: *q++ = u.l;
+ }
}
picidx += n;
}
diff --git a/sys/src/games/gb/apu.c b/sys/src/games/gb/apu.c
index b01c2f80d..dc78992ac 100644
--- a/sys/src/games/gb/apu.c
+++ b/sys/src/games/gb/apu.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
@@ -475,7 +476,7 @@ audioout(void)
if(sbufp == sbuf)
return 0;
cl = clock;
- rc = write(fd, sbuf, (sbufp - sbuf) * 2);
+ rc = warp10 ? (sbufp - sbuf) * 2 : write(fd, sbuf, (sbufp - sbuf) * 2);
if(rc > 0)
sbufp -= (rc+1)/2;
if(sbufp < sbuf)
diff --git a/sys/src/games/gb/cpu.c b/sys/src/games/gb/cpu.c
index 88900ea0b..81c45a034 100644
--- a/sys/src/games/gb/cpu.c
+++ b/sys/src/games/gb/cpu.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
diff --git a/sys/src/games/gb/dat.h b/sys/src/games/gb/dat.h
index 428cfffb9..68c03372c 100644
--- a/sys/src/games/gb/dat.h
+++ b/sys/src/games/gb/dat.h
@@ -1,10 +1,6 @@
-typedef char s8int;
-typedef short s16int;
-typedef long s32int;
typedef struct Event Event;
typedef struct MBC3Timer MBC3Timer;
-extern int trace;
extern u16int curpc;
extern uchar *rom, *back, reg[256], oam[256];
@@ -24,7 +20,6 @@ extern u8int apustatus;
extern u8int mode;
extern u8int mbc, feat;
-extern int keys, scale;
enum {
JOYP = 0x00,
@@ -129,8 +124,6 @@ enum {
TIMERSIZ = 18,
PICW = 160,
PICH = 144,
- MILLION = 1000000,
- BILLION = 1000000000,
FREQ = 1<<23
};
diff --git a/sys/src/games/gb/gb.c b/sys/src/games/gb/gb.c
index 374af931a..55ced730a 100644
--- a/sys/src/games/gb/gb.c
+++ b/sys/src/games/gb/gb.c
@@ -2,34 +2,28 @@
#include <libc.h>
#include <thread.h>
#include <draw.h>
-#include <mouse.h>
#include <keyboard.h>
+#include <emu.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
@@ -204,174 +198,14 @@ loadrom(char *file)
}
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))};
- freeimage(tmp);
- tmp = allocimage(display, Rect(0, 0, scale * PICW, scale > 1 ? 1 : scale * PICH), XRGB32, scale > 1, 0);
- 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){
@@ -430,20 +264,10 @@ threadmain(int argc, char **argv)
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;
@@ -460,15 +284,17 @@ threadmain(int argc, char **argv)
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);
- bg = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF);
- 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();
diff --git a/sys/src/games/gb/mem.c b/sys/src/games/gb/mem.c
index a9c629a13..a6c6c7599 100644
--- a/sys/src/games/gb/mem.c
+++ b/sys/src/games/gb/mem.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
diff --git a/sys/src/games/gb/ppu.c b/sys/src/games/gb/ppu.c
index bd1ecf905..389581621 100644
--- a/sys/src/games/gb/ppu.c
+++ b/sys/src/games/gb/ppu.c
@@ -1,11 +1,11 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
u8int ppustate, ppuy;
-u32int pic[PICW*PICH*3];
ulong hblclock, rendclock;
jmp_buf mainjmp, renderjmp;
static int cyc, done, ppux, ppux0;
@@ -63,7 +63,7 @@ ppurender(void)
}
ppux = 0;
ppux0 = 0;
- picp = pic + ppuy * PICW * scale;
+ picp = (u32int*)pic + ppuy * PICW * scale;
y = ppuy + reg[SCY] << 1 & 14;
ta = 0x1800 | reg[LCDC] << 7 & 0x400 | ppuy + reg[SCY] << 2 & 0x3e0 | reg[SCX] >> 3;
x = -(reg[SCX] & 7);
@@ -197,7 +197,7 @@ sprites(void)
int x, x1;
u16int chr;
- picp = pic + ppuy * PICW * scale;
+ picp = (u32int*)pic + ppuy * PICW * scale;
for(q = spr; q < sprm; q++){
if(q->x <= ppux0 || q->x >= ppux + 8)
continue;
@@ -254,18 +254,31 @@ static void
lineexpand(void)
{
u32int *picp, *p, *q, l;
- int i, s;
+ int i;
- s = scale;
- picp = pic + ppuy * PICW * s;
+ picp = (u32int*)pic + ppuy * PICW * scale;
p = picp + PICW;
q = picp + PICW * scale;
for(i = PICW; --i >= 0; ){
l = *--p;
- *--q = l;
- *--q = l;
- if(scale == 3)
- *--q = l;
+ switch(scale){
+ case 16: *--q = l;
+ case 15: *--q = l;
+ case 14: *--q = l;
+ case 13: *--q = l;
+ case 12: *--q = l;
+ case 11: *--q = l;
+ case 10: *--q = l;
+ case 9: *--q = l;
+ case 8: *--q = l;
+ case 7: *--q = l;
+ case 6: *--q = l;
+ case 5: *--q = l;
+ case 4: *--q = l;
+ case 3: *--q = l;
+ case 2: *--q = l;
+ case 1: *--q = l;
+ }
}
}
diff --git a/sys/src/games/gba/apu.c b/sys/src/games/gba/apu.c
index 3e8883572..4858aced9 100644
--- a/sys/src/games/gba/apu.c
+++ b/sys/src/games/gba/apu.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
@@ -350,7 +351,7 @@ sndwrite(u16int a, u16int v)
void
audioinit(void)
{
- fd = open("/dev/audio", OWRITE);
+ fd = open("/dev/audio", OWRITE);
if(fd < 0)
sysfatal("open: %r");
sbufp = sbuf;
@@ -370,7 +371,7 @@ audioout(void)
if(sbufp == sbuf)
return 0;
cl = clock;
- rc = write(fd, sbuf, (sbufp - sbuf) * 2);
+ rc = warp10 ? (sbufp - sbuf) * 2 : write(fd, sbuf, (sbufp - sbuf) * 2);
if(rc > 0)
sbufp -= (rc+1)/2;
if(sbufp < sbuf)
diff --git a/sys/src/games/gba/cpu.c b/sys/src/games/gba/cpu.c
index c92e4ff9d..a8354324f 100644
--- a/sys/src/games/gba/cpu.c
+++ b/sys/src/games/gba/cpu.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
@@ -34,7 +35,7 @@ u32int curpc;
int irq;
u32int instr0, instr1, pipel = -1;
-int cyc, trace;
+int cyc;
Var cpuvars[] = {
ARR(r), VAR(cpsr), VAR(spsr), ARR(saver), VAR(irq),
diff --git a/sys/src/games/gba/dat.h b/sys/src/games/gba/dat.h
index a609b850b..d930c7b28 100644
--- a/sys/src/games/gba/dat.h
+++ b/sys/src/games/gba/dat.h
@@ -1,9 +1,4 @@
-typedef char s8int;
-typedef short s16int;
-typedef long s32int;
-typedef vlong s64int;
-
-extern int cpuhalt, trace, keys;
+extern int cpuhalt;
extern u32int curpc;
extern int irq;
@@ -18,7 +13,6 @@ extern int nrom, nback, backup;
extern int hblank, ppuy;
extern int clock;
-extern int scale;
typedef struct Event Event;
struct Event {
@@ -141,8 +135,6 @@ enum {
KB = 1024,
BACKTYPELEN = 64,
HZ = 16777216,
- MILLION = 1000000,
- BILLION = 1000000000,
};
typedef struct Var Var;
diff --git a/sys/src/games/gba/gba.c b/sys/src/games/gba/gba.c
index 5a53b68b3..06e90b998 100644
--- a/sys/src/games/gba/gba.c
+++ b/sys/src/games/gba/gba.c
@@ -2,36 +2,19 @@
#include <libc.h>
#include <thread.h>
#include <draw.h>
-#include <mouse.h>
#include <keyboard.h>
+#include <emu.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;
+Image *tmp;
+int backup;
int savefd, saveframes;
int clock;
-int savereq, loadreq;
char *biosfile = "/sys/games/lib/gbabios.bin";
-void *
-emalloc(ulong sz)
-{
- void *v;
-
- v = malloc(sz);
- if(v == nil)
- sysfatal("malloc: %r");
- setmalloctag(v, getcallerpc(&sz));
- return v;
-}
-
void
writeback(void)
{
@@ -212,172 +195,14 @@ loadrom(char *file)
}
void
-screeninit(void)
-{
- Point p;
-
- p = divpt(addpt(screen->r.min, screen->r.max), 2);
- picr = (Rectangle){subpt(p, Pt(scale * 120, scale * 80)), addpt(p, Pt(scale * 120, scale * 80))};
- freeimage(tmp);
- tmp = allocimage(display, Rect(0, 0, scale * 240, scale > 1 ? 1 : scale * 160), CHAN4(CIgnore, 1, CBlue, 5, CGreen, 5, CRed, 5), scale > 1, 0);
- draw(screen, screen->r, bg, nil, ZP);
-}
-
-void
-keyproc(void *)
-{
- int fd, n, k;
- static char buf[256];
- char *s;
- Rune r;
-
- 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(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<<1; break;
- case 'x': k |= 1<<0; break;
- case 'a': k |= 1<<9; break;
- case 's': k |= 1<<8; break;
- case Kshift: k |= 1<<2; break;
- case 10: k |= 1<<3; break;
- case Kup: k |= 1<<6; break;
- case Kdown: k |= 1<<7; break;
- case Kleft: k |= 1<<5; break;
- case Kright: k |= 1<<4; 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 & 0xa0 | k >> 1 & 0x50);
- 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;
int x;
- 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, 240*160*2);
- draw(screen, picr, tmp, nil, ZP);
- } else {
- Rectangle r;
- uchar *s;
- int w;
+ flushmouse(1);
+ flushscreen();
+ flushaudio(audioout);
- s = pic;
- r = picr;
- w = 240*2*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;
- }
-
if(saveframes > 0 && --saveframes == 0)
flushback();
@@ -395,7 +220,7 @@ flush(void)
void
usage(void)
{
- fprint(2, "usage: %s [-23aT] [-s savetype] [-b biosfile] rom\n", argv0);
+ fprint(2, "usage: %s [-aT] [-s savetype] [-b biosfile] rom\n", argv0);
exits("usage");
}
@@ -405,14 +230,7 @@ threadmain(int argc, char **argv)
char *s;
int t;
- scale = 1;
ARGBEGIN {
- case '2':
- scale = 2;
- break;
- case '3':
- scale = 3;
- break;
case 'a':
audioinit();
break;
@@ -425,9 +243,6 @@ threadmain(int argc, char **argv)
case 'b':
biosfile = strdup(EARGF(usage()));
break;
- case 'T':
- profile++;
- break;
default:
usage();
} ARGEND;
@@ -436,16 +251,17 @@ threadmain(int argc, char **argv)
loadbios();
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);
- bg = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF);
- screeninit();
-
+ initemu(240, 160, 2, CHAN4(CIgnore, 1, CBlue, 5, CGreen, 5, CRed, 5), 1, nil);
+ regkey("b", 'z', 1<<1);
+ regkey("a", 'x', 1<<0);
+ regkey("l1", 'a', 1<<9);
+ regkey("r1", 's', 1<<8);
+ regkey("control", Kshift, 1<<2);
+ regkey("start", '\n', 1<<3);
+ regkey("up", Kup, 1<<6);
+ regkey("down", Kdown, 1<<7);
+ regkey("left", Kleft, 1<<5);
+ regkey("right", Kright, 1<<4);
eventinit();
memreset();
reset();
diff --git a/sys/src/games/gba/mem.c b/sys/src/games/gba/mem.c
index 75ff9d31c..032f35eae 100644
--- a/sys/src/games/gba/mem.c
+++ b/sys/src/games/gba/mem.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
diff --git a/sys/src/games/gba/ppu.c b/sys/src/games/gba/ppu.c
index a87caba17..7de5a1e7b 100644
--- a/sys/src/games/gba/ppu.c
+++ b/sys/src/games/gba/ppu.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
@@ -11,7 +12,6 @@ int ppux0;
u32int pixcol[480];
u8int pixpri[480];
u8int pixwin[240];
-uchar pic[240*160*3*2];
int objalpha;
typedef struct bg bg;
@@ -643,40 +643,6 @@ colormath(int x1)
}
void
-linecopy(void)
-{
- u32int *p;
- uchar *q;
- u16int *r;
- u16int v;
- union { u16int w; u8int b[2]; } u;
- int n;
-
- p = pixcol;
- q = pic + ppuy * 240 * 2 * scale;
- r = (u16int*)q;
- n = 240;
- while(n--){
- v = *p++;
- if(scale == 1){
- *q++ = v;
- *q++ = v >> 8;
- continue;
- }
- u.b[0] = v;
- u.b[1] = v >> 8;
- if(scale == 2){
- *r++ = u.w;
- *r++ = u.w;
- }else{
- *r++ = u.w;
- *r++ = u.w;
- *r++ = u.w;
- }
- }
-}
-
-void
syncppu(int x1)
{
int i;
@@ -725,6 +691,43 @@ syncppu(int x1)
}
void
+linecopy(u32int *p, int y)
+{
+ uchar *q;
+ u16int *r;
+ u16int v;
+ union { u16int w; u8int b[2]; } u;
+ int n;
+
+ q = pic + y * 240 * 2 * scale;
+ r = (u16int*)q;
+ n = 240;
+ while(n--){
+ v = *p++;
+ u.b[0] = v;
+ u.b[1] = v >> 8;
+ switch(scale){
+ case 16: *r++ = u.w;
+ case 15: *r++ = u.w;
+ case 14: *r++ = u.w;
+ case 13: *r++ = u.w;
+ case 12: *r++ = u.w;
+ case 11: *r++ = u.w;
+ case 10: *r++ = u.w;
+ case 9: *r++ = u.w;
+ case 8: *r++ = u.w;
+ case 7: *r++ = u.w;
+ case 6: *r++ = u.w;
+ case 5: *r++ = u.w;
+ case 4: *r++ = u.w;
+ case 3: *r++ = u.w;
+ case 2: *r++ = u.w;
+ default: *r++ = u.w;
+ }
+ }
+}
+
+void
hblanktick(void *)
{
extern Event evhblank;
@@ -755,7 +758,7 @@ hblanktick(void *)
}else{
syncppu(240);
if(ppuy < 160)
- linecopy();
+ linecopy(pixcol, ppuy);
addevent(&evhblank, 68*4);
hblank = 1;
if((stat & IRQHBLEN) != 0)
diff --git a/sys/src/games/md/cpu.c b/sys/src/games/md/cpu.c
index 8a7e8db86..1a0325f52 100644
--- a/sys/src/games/md/cpu.c
+++ b/sys/src/games/md/cpu.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
@@ -19,7 +20,7 @@ extern u32int irql[8];
u32int irqla[8];
u16int rS;
static u32int op;
-int trace, tim;
+int tim;
#define ra (r+8)
static void
diff --git a/sys/src/games/md/dat.h b/sys/src/games/md/dat.h
index f61e9a13e..5323a7d79 100644
--- a/sys/src/games/md/dat.h
+++ b/sys/src/games/md/dat.h
@@ -1,9 +1,4 @@
-typedef signed char s8int;
-typedef signed short s16int;
-typedef signed long s32int;
-
extern u32int curpc, irq;
-extern int trace, debug;
extern u8int reg[32];
extern u8int dma;
@@ -18,8 +13,6 @@ extern u8int *sram;
extern u32int sramctl, sram0, sram1;
extern int savefd, saveclock;
-extern int keys, scale;
-
extern u16int vram[32768], vsram[40];
extern u32int cramc[64];
extern u16int vdpstat;
@@ -82,8 +75,6 @@ enum {
RATE = 44100,
SAMPDIV = FREQ / RATE,
SAVEFREQ = FREQ / 4,
- MILLION = 1000 * 1000,
- BILLION = 1000 * 1000 * 1000,
};
enum {
diff --git a/sys/src/games/md/md.c b/sys/src/games/md/md.c
index f8ffcc52c..557668dc7 100644
--- a/sys/src/games/md/md.c
+++ b/sys/src/games/md/md.c
@@ -3,29 +3,18 @@
#include <thread.h>
#include <draw.h>
#include <keyboard.h>
-#include <mouse.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
-int debug;
-
u16int *prg;
int nprg;
u8int *sram;
u32int sramctl, nsram, sram0, sram1;
int savefd = -1;
-int keys;
-
int dmaclock, vdpclock, z80clock, audioclock, ymclock, saveclock;
-int scale, paused;
-QLock pauselock;
-Mousectl *mc;
-Channel *flushc;
-Rectangle picr;
-Image *tmp, *bg;
-
void
flushram(void)
{
@@ -114,146 +103,14 @@ loadrom(char *file)
}
void
-screeninit(void)
-{
- Point p;
-
- originwindow(screen, Pt(0, 0), screen->r.min);
- p = divpt(addpt(screen->r.min, screen->r.max), 2);
- picr = (Rectangle){subpt(p, Pt(scale * 160, scale * 112)), addpt(p, Pt(scale * 160, scale * 112))};
- if(tmp != nil) freeimage(tmp);
- tmp = allocimage(display, Rect(0, 0, scale * 320, scale > 1 ? 1 : scale * 224), XRGB32, scale > 1, 0);
- if(bg != nil) freeimage(bg);
- bg = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF);
- draw(screen, screen->r, bg, nil, ZP);
-}
-
-void
-screenproc(void *)
-{
- extern u8int pic[320*224*4*4];
- extern int intla;
- Rectangle r;
- uchar *s;
- int w, h;
-
- enum { AMOUSE, ARESIZE, AFLUSH, AEND };
- Alt a[AEND+1] = {
- { mc->c, nil, CHANRCV },
- { mc->resizec, nil, CHANRCV },
- { flushc, nil, CHANRCV },
- { nil, nil, CHANEND }
- };
-
- for(;;){
- switch(alt(a)){
- case ARESIZE:
- if(getwindow(display, Refnone) < 0)
- sysfatal("resize failed: %r");
- screeninit();
- /* wet floor */
- case AFLUSH:
- if(scale == 1){
- loadimage(tmp, tmp->r, pic, 320*224*4);
- draw(screen, picr, tmp, nil, ZP);
- }else{
- s = pic;
- r = picr;
- w = 320*4*scale;
- h = scale;
- if(intla && (h & 1) == 0)
- h >>= 1;
- while(r.min.y < picr.max.y){
- loadimage(tmp, tmp->r, s, w);
- s += w;
- r.max.y = r.min.y+h;
- draw(screen, r, tmp, nil, ZP);
- r.min.y = r.max.y;
- }
- }
- flushimage(display, 1);
- break;
- }
- }
-}
-
-void
-keyproc(void *)
-{
- int fd, n, k;
- static char buf[256];
- char *s;
- Rune r;
-
- 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, Kdel)){
- close(fd);
- threadexitsall(nil);
- }
- if(utfrune(buf, 't'))
- trace = !trace;
- }
- if(buf[0] != 'k' && buf[0] != 'K')
- continue;
- s = buf + 1;
- k = 0xc00;
- while(*s != 0){
- s += chartorune(&r, s);
- if(r >= '0' && r <= '9') debug = r - '0';
- switch(r){
- case Kdel: close(fd); threadexitsall(nil);
- case 'c': k |= 0x0020; break;
- case 'x': k |= 0x0010; break;
- case 'z': k |= 0x1000; break;
- case 10: k |= 0x2000; break;
- case Kup: k |= 0x0101; break;
- case Kdown: k |= 0x0202; break;
- case Kleft: k |= 0x0004; break;
- case Kright: k |= 0x0008; break;
- case Kesc:
- if(paused)
- qunlock(&pauselock);
- else
- qlock(&pauselock);
- paused = !paused;
- break;
- }
- }
- keys = ~k;
- }
-}
-
-void
threadmain(int argc, char **argv)
{
int t;
- scale = 1;
ARGBEGIN{
case 'a':
initaudio();
break;
- case '2':
- scale = 2;
- break;
- case '3':
- scale = 3;
- break;
default:
;
} ARGEND;
@@ -263,15 +120,15 @@ threadmain(int argc, char **argv)
threadexitsall("usage");
}
loadrom(*argv);
- if(initdraw(nil, nil, argv0) < 0)
- sysfatal("initdraw: %r");
- flushc = chancreate(sizeof(ulong), 1);
- mc = initmouse(nil, screen);
- if(mc == nil)
- sysfatal("initmouse: %r");
- screeninit();
- proccreate(keyproc, nil, 8192);
- proccreate(screenproc, nil, 8192);
+ initemu(320, 224, 4, XRGB32, 1, nil);
+ regkey("a", 'c', 1<<5);
+ regkey("b", 'x', 1<<4);
+ regkey("y", 'z', 1<<12);
+ regkey("start", '\n', 1<<13);
+ regkey("up", Kup, 0x101);
+ regkey("down", Kdown, 0x202);
+ regkey("left", Kleft, 1<<2);
+ regkey("right", Kright, 1<<3);
cpureset();
vdpmode();
ymreset();
@@ -320,22 +177,7 @@ threadmain(int argc, char **argv)
void
flush(void)
{
- static vlong old, delta;
- vlong new, diff;
-
- sendul(flushc, 1); /* flush screen */
- 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;
- }
- }
+ flushmouse(1);
+ flushscreen();
+ flushaudio(audioout);
}
diff --git a/sys/src/games/md/mem.c b/sys/src/games/md/mem.c
index f3b6ede8f..083abaa29 100644
--- a/sys/src/games/md/mem.c
+++ b/sys/src/games/md/mem.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
@@ -31,7 +32,7 @@ regread(u16int a)
switch(a | 1){
case 0x0001: return 0xa0;
case 0x0003:
- v = keys;
+ v = ~(keys & 0xffff);
if((ctl[0] & 0x40) == 0)
v >>= 8;
return ctl[0] & 0xc0 | v & 0x3f;
diff --git a/sys/src/games/md/vdp.c b/sys/src/games/md/vdp.c
index e87306559..51d5f20a1 100644
--- a/sys/src/games/md/vdp.c
+++ b/sys/src/games/md/vdp.c
@@ -1,10 +1,10 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
-u8int pic[320*224*4*4];
u16int vdpstat = 0x3400;
int vdpx, vdpy, vdpyy, frame, intla;
u16int hctr;
@@ -29,32 +29,31 @@ vdpmode(void)
static void
pixeldraw(int x, int y, int v)
{
- u8int *p;
- u32int *q;
- union { u32int w; u8int b[4]; } u;
+ u32int *p;
+ union { u32int l; u8int b[4]; } u;
- if(scale == 1){
- p = pic + (x + y * 320) * 4;
- p[0] = v >> 16;
- p[1] = v >> 8;
- p[2] = v;
- return;
- }
+ p = (u32int *)pic + (x + y * 320) * scale;
u.b[0] = v >> 16;
u.b[1] = v >> 8;
u.b[2] = v;
u.b[3] = 0;
- if(scale == 2){
- if(intla)
- y = y << 1 | frame;
- q = (u32int*)pic + (x + y * 320) * 2;
- q[0] = u.w;
- q[1] = u.w;
- }else{
- q = (u32int*)pic + (x + y * 320) * 3;
- q[0] = u.w;
- q[1] = u.w;
- q[2] = u.w;
+ switch(scale){
+ case 16: *p++ = u.l;
+ case 15: *p++ = u.l;
+ case 14: *p++ = u.l;
+ case 13: *p++ = u.l;
+ case 12: *p++ = u.l;
+ case 11: *p++ = u.l;
+ case 10: *p++ = u.l;
+ case 9: *p++ = u.l;
+ case 8: *p++ = u.l;
+ case 7: *p++ = u.l;
+ case 6: *p++ = u.l;
+ case 5: *p++ = u.l;
+ case 4: *p++ = u.l;
+ case 3: *p++ = u.l;
+ case 2: *p++ = u.l; /* intla ignored */
+ default: *p = u.l;
}
}
diff --git a/sys/src/games/md/ym.c b/sys/src/games/md/ym.c
index 2bd83af0a..ca3988433 100644
--- a/sys/src/games/md/ym.c
+++ b/sys/src/games/md/ym.c
@@ -1,11 +1,10 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
-extern int debug;
-
u8int ym[512];
enum {
MODE = 0x27,
@@ -436,7 +435,7 @@ audioout(void)
return -1;
if(sbufp == sbuf)
return 0;
- rc = write(fd, sbuf, (sbufp - sbuf) * 2);
+ rc = warp10 ? (sbufp - sbuf) * 2 : write(fd, sbuf, (sbufp - sbuf) * 2);
if(rc > 0)
sbufp -= (rc+1)/2;
if(sbufp < sbuf)
diff --git a/sys/src/games/nes/apu.c b/sys/src/games/nes/apu.c
index cd0a642b2..52e8e36b5 100644
--- a/sys/src/games/nes/apu.c
+++ b/sys/src/games/nes/apu.c
@@ -2,6 +2,7 @@
#include <libc.h>
#include <thread.h>
#include <draw.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
@@ -279,7 +280,7 @@ audioout(void)
return -1;
if(sbufp == sbuf)
return 0;
- rc = write(fd, sbuf, (sbufp - sbuf) * 2);
+ rc = warp10 ? (sbufp - sbuf) * 2 : write(fd, sbuf, (sbufp - sbuf) * 2);
if(rc > 0)
sbufp -= (rc+1)/2;
if(sbufp < sbuf)
diff --git a/sys/src/games/nes/dat.h b/sys/src/games/nes/dat.h
index 8da07fa84..4162f0904 100644
--- a/sys/src/games/nes/dat.h
+++ b/sys/src/games/nes/dat.h
@@ -6,14 +6,14 @@ extern u16int pput, ppuv;
extern u8int ppusx, vrambuf;
extern int mirr, ppux, ppuy, odd, vramlatch, keylatch, keylatch2;
-extern int map, scale, mmc3hack, oflag;
+extern int map, mmc3hack, oflag;
extern uchar *prg, *chr;
extern int nprg, nchr, map, chrram;
extern u8int apuseq, apuctr[13];
extern u16int dmcaddr, dmccnt;
-extern int keys, keys2, clock, ppuclock, apuclock, dmcclock, dmcfreq, saveclock, paused;
+extern int clock, ppuclock, apuclock, dmcclock, dmcfreq, saveclock;
extern void (*mapper[])(int, u8int);
@@ -78,8 +78,6 @@ enum {
enum {
FREQ = 21477272,
- MILLION = 1000000,
- BILLION = 1000000000,
APUDIV = 89490,
RATE = 44100,
SAMPDIV = FREQ / RATE,
diff --git a/sys/src/games/nes/mem.c b/sys/src/games/nes/mem.c
index 575cf0c0e..52e3162ba 100644
--- a/sys/src/games/nes/mem.c
+++ b/sys/src/games/nes/mem.c
@@ -2,6 +2,7 @@
#include <libc.h>
#include <thread.h>
#include <draw.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
diff --git a/sys/src/games/nes/nes.c b/sys/src/games/nes/nes.c
index aa9c4fa2a..2b4988aec 100644
--- a/sys/src/games/nes/nes.c
+++ b/sys/src/games/nes/nes.c
@@ -2,22 +2,17 @@
#include <libc.h>
#include <draw.h>
#include <thread.h>
-#include <mouse.h>
#include <keyboard.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
extern uchar ppuram[16384];
int nprg, nchr, map, chrram;
uchar *prg, *chr;
-int scale;
-Rectangle picr;
-Image *tmp, *bg;
int clock, ppuclock, apuclock, dmcclock, dmcfreq, sampclock, msgclock, saveclock;
-Mousectl *mc;
-int keys, keys2, paused, savereq, loadreq, oflag, savefd = -1;
+int oflag, savefd = -1;
int mirr;
-QLock pauselock;
void
message(char *fmt, ...)
@@ -122,139 +117,18 @@ loadrom(char *file, int sflag)
mapper[map](INIT, 0);
}
-extern int trace;
-
-void
-joyproc(void *)
-{
- char *s, *down[9];
- static char buf[64];
- int n, k, j;
-
- j = 1;
- for(;;){
- n = read(0, buf, sizeof(buf) - 1);
- if(n <= 0)
- sysfatal("read: %r");
- buf[n] = 0;
- n = getfields(buf, down, nelem(down), 1, " ");
- k = 0;
- for(n--; n >= 0; n--){
- s = down[n];
- if(strcmp(s, "joy1") == 0)
- j = 1;
- else if(strcmp(s, "joy2") == 0)
- j = 2;
- else if(strcmp(s, "a") == 0)
- k |= 1<<0;
- else if(strcmp(s, "b") == 0)
- k |= 1<<1;
- else if(strcmp(s, "control") == 0)
- k |= 1<<2;
- else if(strcmp(s, "start") == 0)
- k |= 1<<3;
- else if(strcmp(s, "up") == 0)
- k |= 1<<4;
- else if(strcmp(s, "down") == 0)
- k |= 1<<5;
- else if(strcmp(s, "left") == 0)
- k |= 1<<6;
- else if(strcmp(s, "right") == 0)
- k |= 1<<7;
- }
- if(j == 2)
- keys2 = k;
- else
- keys = k;
- }
-}
-
-void
-keyproc(void *)
-{
- int fd, n, k;
- static char buf[256];
- char *s;
- Rune r;
-
- 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, Kdel)){
- close(fd);
- threadexitsall(nil);
- }
- if(utfrune(buf, KF|5))
- savereq = 1;
- if(utfrune(buf, KF|6))
- loadreq = 1;
- if(utfrune(buf, 't'))
- trace ^= 1;
- }
- 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 'x': k |= 1<<0; break;
- case 'z': k |= 1<<1; break;
- case Kshift: k |= 1<<2; break;
- case 10: k |= 1<<3; break;
- case Kup: k |= 1<<4; break;
- case Kdown: k |= 1<<5; break;
- case Kleft: k |= 1<<6; break;
- case Kright: k |= 1<<7; break;
- case Kesc:
- if(paused)
- qunlock(&pauselock);
- else
- qlock(&pauselock);
- paused = !paused;
- break;
- }
- }
- keys = k;
- }
-}
-
void
threadmain(int argc, char **argv)
{
- int t, h, sflag;
- Point p;
+ int t, sflag;
- scale = 1;
- h = 240;
sflag = 0;
ARGBEGIN {
case 'a':
initaudio();
break;
- case '2':
- scale = 2;
- break;
- case '3':
- scale = 3;
- break;
case 'o':
oflag = 1;
- h -= 16;
break;
case 's':
sflag = 1;
@@ -269,20 +143,16 @@ threadmain(int argc, char **argv)
threadexitsall("usage");
}
loadrom(argv[0], sflag);
- if(initdraw(nil, nil, nil) < 0)
- sysfatal("initdraw: %r");
- mc = initmouse(nil, screen);
- if(mc == nil)
- sysfatal("initmouse: %r");
- proccreate(joyproc, nil, 8192);
- proccreate(keyproc, nil, 8192);
- originwindow(screen, Pt(0, 0), screen->r.min);
- p = divpt(addpt(screen->r.min, screen->r.max), 2);
- picr = (Rectangle){subpt(p, Pt(scale * 128, scale * h/2)), addpt(p, Pt(scale * 128, scale * h/2))};
- tmp = allocimage(display, Rect(0, 0, scale * 256, scale * h), XRGB32, 0, 0);
- bg = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF);
- draw(screen, screen->r, bg, nil, ZP);
-
+ initemu(256, 240 - oflag * 16, 4, XRGB32, 1, nil);
+ regkey("b", 'z', 1<<1);
+ regkey("a", 'x', 1<<0);
+ regkey("control", Kshift, 1<<2);
+ regkey("start", '\n', 1<<3);
+ regkey("up", Kup, 1<<4);
+ regkey("down", Kdown, 1<<5);
+ regkey("left", Kleft, 1<<6);
+ regkey("right", Kright, 1<<7);
+
pc = memread(0xFFFC) | memread(0xFFFD) << 8;
rP = FLAGI;
dmcfreq = 12 * 428;
@@ -324,7 +194,8 @@ threadmain(int argc, char **argv)
if(msgclock > 0){
msgclock -= t;
if(msgclock <= 0){
- draw(screen, screen->r, bg, nil, ZP);
+ extern Image *bg;
+ draw(screen, screen->r, bg, nil, ZP);
msgclock = 0;
}
}
diff --git a/sys/src/games/nes/ppu.c b/sys/src/games/nes/ppu.c
index 5c1756a19..498c20082 100644
--- a/sys/src/games/nes/ppu.c
+++ b/sys/src/games/nes/ppu.c
@@ -3,18 +3,17 @@
#include <thread.h>
#include <draw.h>
#include <mouse.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
int ppuy, ppux, odd;
-uchar pic[256*240*4*9];
static void
pixel(int x, int y, int val, int back)
{
- int Y;
union { u8int c[4]; u32int l; } u;
- u32int *p, l;
+ u32int *p;
static u8int palred[64] = {
0x7C, 0x00, 0x00, 0x44, 0x94, 0xA8, 0xA8, 0x88,
0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -50,32 +49,31 @@ pixel(int x, int y, int val, int back)
u.c[1] = palgreen[val];
u.c[2] = palred[val];
u.c[3] = back ? 0 : 0xFF;
- l = u.l;
- if(scale == 3){
- p = ((u32int*)pic) + y * 3 * 3 * 256 + 3 * x;
- for(Y = 0; Y < 3; Y++){
- *p++ = l;
- *p++ = l;
- *p = l;
- p += 3 * 256 - 2;
- }
- }else if(scale == 2){
- p = ((u32int*)pic) + y * 2 * 2 * 256 + 2 * x;
- *p++ = l;
- *p = l;
- p += 2 * 256 - 1;
- *p++ = l;
- *p = l;
- }else{
- p = ((u32int*)pic) + y * 256 + x;
- *p = l;
+ p = (u32int *)pic + y * 256 * scale + x * scale;
+ switch(scale){
+ case 16: *p++ = u.l;
+ case 15: *p++ = u.l;
+ case 14: *p++ = u.l;
+ case 13: *p++ = u.l;
+ case 12: *p++ = u.l;
+ case 11: *p++ = u.l;
+ case 10: *p++ = u.l;
+ case 9: *p++ = u.l;
+ case 8: *p++ = u.l;
+ case 7: *p++ = u.l;
+ case 6: *p++ = u.l;
+ case 5: *p++ = u.l;
+ case 4: *p++ = u.l;
+ case 3: *p++ = u.l;
+ case 2: *p++ = u.l;
+ default: *p = u.l;
}
}
static int
iscolor(int x, int y)
{
- return pic[y * scale * scale * 256 * 4 + x * scale * 4 + 3] != 0;
+ return pic[(scale * 4) * (y * 256 + x) + 3] != 0;
}
static int
@@ -252,52 +250,9 @@ drawsprites(int show)
static void
flush(void)
{
- extern Rectangle picr;
- extern Image *tmp, *bg;
- extern Mousectl *mc;
- static vlong old, delta;
- vlong new, diff;
- Mouse m;
- Point p;
- int h;
-
- h = 240;
- if(oflag)
- h -= 16;
- while(nbrecv(mc->c, &m) > 0)
- ;
- if(nbrecvul(mc->resizec) > 0){
- if(getwindow(display, Refnone) < 0)
- sysfatal("resize failed: %r");
- p = divpt(addpt(screen->r.min, screen->r.max), 2);
- picr = (Rectangle){subpt(p, Pt(scale * 128, scale * h/2)), addpt(p, Pt(scale * 128, scale * h/2))};
- if(bg->chan != screen->chan){
- freeimage(bg);
- bg = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF);
- }
- draw(screen, screen->r, bg, nil, ZP);
- }
- if(screen->chan != tmp->chan || !rectinrect(picr, screen->r)){
- loadimage(tmp, tmp->r, pic + oflag*8*256*4*scale*scale, 256*h*4*scale*scale);
- draw(screen, picr, tmp, nil, ZP);
- }else
- loadimage(screen, picr, pic + oflag*8*256*4*scale*scale, 256*h*4*scale*scale);
- flushimage(display, 1);
- memset(pic, sizeof pic, 0);
- 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;
- }
- }
+ flushmouse(1);
+ flushscreen();
+ flushaudio(audioout);
}
void
diff --git a/sys/src/games/snes/cpu.c b/sys/src/games/snes/cpu.c
index 602d4ca8f..dbec220a4 100644
--- a/sys/src/games/snes/cpu.c
+++ b/sys/src/games/snes/cpu.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
@@ -640,8 +641,6 @@ cpureset(void)
rP = 0x35;
}
-int trace;
-
int
cpustep(void)
{
diff --git a/sys/src/games/snes/dat.h b/sys/src/games/snes/dat.h
index 86a14a5a4..971ea724c 100644
--- a/sys/src/games/snes/dat.h
+++ b/sys/src/games/snes/dat.h
@@ -1,14 +1,10 @@
-typedef signed char s8int;
-typedef signed short s16int;
-
extern u8int rP, dma, nmi, irq, emu, wai;
extern u16int rA, rX, rY, rS, rD, pc;
extern u32int rPB, rDB, curpc, hdma;
-extern int trace;
extern uchar *prg, *sram;
extern int nprg, nsram, hirom;
-extern u32int keys, keylatch, lastkeys;
+extern u32int keylatch, lastkeys;
extern u8int reg[32768], mem[131072], spcmem[65536], vram[65536], oam[544];
extern u16int cgram[256], vramlatch;
extern u8int mdr, mdr1, mdr2;
@@ -25,7 +21,7 @@ extern u8int dspstate;
extern u16int dspcounter, noise;
extern int ppuclock, spcclock, dspclock, stimerclock, cpupause;
-extern int battery, saveclock, scale, mouse;
+extern int battery, saveclock, mouse;
enum {
FLAGC = 1<<0,
diff --git a/sys/src/games/snes/dsp.c b/sys/src/games/snes/dsp.c
index b4ad1e7f1..991c45316 100644
--- a/sys/src/games/snes/dsp.c
+++ b/sys/src/games/snes/dsp.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
@@ -77,7 +78,7 @@ audioout(void)
return -1;
if(sbufp == sbuf)
return 0;
- rc = write(fd, sbuf, (sbufp - sbuf) * 2);
+ rc = warp10 ? (sbufp - sbuf) * 2 : write(fd, sbuf, (sbufp - sbuf) * 2);
if(rc > 0)
sbufp -= (rc+1)/2;
if(sbufp < sbuf)
diff --git a/sys/src/games/snes/mem.c b/sys/src/games/snes/mem.c
index 6fea74bfd..885713a85 100644
--- a/sys/src/games/snes/mem.c
+++ b/sys/src/games/snes/mem.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
diff --git a/sys/src/games/snes/ppu.c b/sys/src/games/snes/ppu.c
index 0ae2ccfb9..5819e032c 100644
--- a/sys/src/games/snes/ppu.c
+++ b/sys/src/games/snes/ppu.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
@@ -8,7 +9,6 @@ int ppux, ppuy, rx;
static u8int mode, bright, pixelpri[2], hires;
static u32int pixelcol[2];
u16int vtime = 0x1ff, htime = 0x1ff, subcolor;
-uchar pic[256*239*2*3];
u16int hofs[5], vofs[5];
s16int m7[6];
@@ -40,30 +40,31 @@ darken(u16int v)
static void
pixeldraw(int x, int y, u16int v, int s)
{
- uchar *p;
- u16int *q;
+ u16int *p;
union { u16int w; u8int b[2]; } u;
if(bright != 0xf && s >= 0)
v = darken(v);
- if(scale == 1){
- p = pic + (x + y * 256) * 2;
- p[0] = v;
- p[1] = v >> 8;
- return;
- }
+ p = (u16int *)pic + (x + y * 256) * scale;
u.b[0] = v;
u.b[1] = v >> 8;
- if(scale == 2){
- q = (u16int*)pic + (x + y * 256) * 2;
- if(s < 1)
- q[0] = u.w;
- q[1] = u.w;
- }else{
- q = (u16int*)pic + (x + y * 256) * 3;
- q[0] = u.w;
- q[1] = u.w;
- q[2] = u.w;
+ switch(scale){
+ case 16: *p++ = u.w;
+ case 15: *p++ = u.w;
+ case 14: *p++ = u.w;
+ case 13: *p++ = u.w;
+ case 12: *p++ = u.w;
+ case 11: *p++ = u.w;
+ case 10: *p++ = u.w;
+ case 9: *p++ = u.w;
+ case 8: *p++ = u.w;
+ case 7: *p++ = u.w;
+ case 6: *p++ = u.w;
+ case 5: *p++ = u.w;
+ case 4: *p++ = u.w;
+ case 3: *p++ = u.w;
+ case 2: if(s < 1) *p++ = u.w;
+ default: *p = u.w;
}
}
diff --git a/sys/src/games/snes/snes.c b/sys/src/games/snes/snes.c
index 863247fef..3e43b631d 100644
--- a/sys/src/games/snes/snes.c
+++ b/sys/src/games/snes/snes.c
@@ -4,21 +4,16 @@
#include <draw.h>
#include <keyboard.h>
#include <mouse.h>
-#include <ctype.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"
uchar *prg, *sram;
int nprg, nsram, hirom, battery;
-int ppuclock, spcclock, dspclock, stimerclock, saveclock, msgclock, paused, perfclock, cpupause;
-Mousectl *mc;
-Channel *flushc, *msgc;
-QLock pauselock;
-u32int keys;
-int savefd, scale, profile, mouse, loadreq, savereq;
-Rectangle picr;
-Image *tmp, *bg;
+int ppuclock, spcclock, dspclock, stimerclock, saveclock, msgclock, cpupause;
+Channel *msgc;
+int savefd, mouse;
void
flushram(void)
@@ -114,187 +109,13 @@ loadbat(char *file)
}
void
-keyproc(void *)
-{
- int fd, n, k;
- static char buf[256];
- char *s;
- Rune r;
-
- 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(buf[0] != 'k' && buf[0] != 'K')
- continue;
- s = buf + 1;
- k = 0xffff;
- while(*s != 0){
- s += chartorune(&r, s);
- switch(r){
- case Kdel: close(fd); threadexitsall(nil);
- case 'z': k |= 1<<31; break;
- case 'x': k |= 1<<23; break;
- case 'a': k |= 1<<30; break;
- case 's': k |= 1<<22; break;
- case 'q': k |= 1<<21; break;
- case 'w': k |= 1<<20; break;
- case Kshift: k |= 1<<29; break;
- case 10: k |= 1<<28; break;
- case Kup: k |= 1<<27; break;
- case Kdown: k |= 1<<26; break;
- case Kleft: k |= 1<<25; break;
- case Kright: k |= 1<<24; break;
- case Kesc:
- if(paused)
- qunlock(&pauselock);
- else
- qlock(&pauselock);
- paused = !paused;
- break;
- }
- }
- if(!mouse)
- keys = k;
- }
-}
-
-void
-screeninit(void)
-{
- Point p;
-
- p = divpt(addpt(screen->r.min, screen->r.max), 2);
- picr = (Rectangle){subpt(p, Pt(scale * 128, scale * 112)), addpt(p, Pt(scale * 128, scale * 127))};
- if(tmp != nil) freeimage(tmp);
- tmp = allocimage(display, Rect(0, 0, scale * 256, scale > 1 ? 1 : scale * 239), RGB15, scale > 1, 0);
- if(bg != nil) freeimage(bg);
- bg = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF);
- draw(screen, screen->r, bg, nil, ZP);
-}
-
-void
-screenproc(void *)
-{
- extern uchar pic[256*239*2*3];
- char *s;
- Mouse m;
- Point p;
-
- enum { AMOUSE, ARESIZE, AFLUSH, AMSG, AEND };
- Alt a[AEND+1] = {
- { mc->c, &m, CHANRCV },
- { mc->resizec, nil, CHANRCV },
- { flushc, nil, CHANRCV },
- { msgc, &s, CHANRCV },
- { nil, nil, CHANEND }
- };
-
- for(;;){
- switch(alt(a)){
- case AMOUSE:
- if(mouse && ptinrect(m.xy, picr)){
- p = subpt(m.xy, picr.min);
- p.x /= scale;
- p.y /= scale;
- keys = keys & 0xff3f0000 | p.x | p.y << 8;
- if((m.buttons & 1) != 0)
- keys |= 1<<22;
- if((m.buttons & 4) != 0)
- keys |= 1<<23;
- if((m.buttons & 2) != 0)
- lastkeys = keys;
- }
- break;
- case ARESIZE:
- if(getwindow(display, Refnone) < 0)
- sysfatal("resize failed: %r");
- screeninit();
- /* wet floor */
- case AFLUSH:
- if(scale == 1){
- loadimage(tmp, tmp->r, pic, 256*239*2);
- draw(screen, picr, tmp, nil, ZP);
- } else {
- Rectangle r;
- uchar *s;
- int w;
-
- s = pic;
- r = picr;
- w = 256*2*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);
- break;
- case AMSG:
- draw(screen, rectaddpt(Rect(10, 10, 200, 30), screen->r.min), bg, nil, ZP);
- if(s != nil){
- string(screen, addpt(screen->r.min, Pt(10, 10)), display->black, ZP,
- display->defaultfont, s);
- free(s);
- }
- break;
- }
- }
-}
-
-void
-timing(void)
-{
- static vlong old;
- vlong new;
-
- new = nsec();
- if(new != old)
- message("%6.2f%%", 1e11 / (new - old));
- old = nsec();
-}
-
-void
threadmain(int argc, char **argv)
{
int t;
extern u16int pc;
- scale = 1;
hirom = -1;
ARGBEGIN {
- case '2':
- scale = 2;
- break;
- case '3':
- scale = 3;
- break;
case 'a':
audioinit();
break;
@@ -308,9 +129,6 @@ threadmain(int argc, char **argv)
case 'h':
hirom++;
break;
- case 'T':
- profile++;
- break;
default:
goto usage;
} ARGEND;
@@ -321,16 +139,20 @@ usage:
threadexitsall("usage");
}
loadrom(argv[0]);
- if(initdraw(nil, nil, argv0) < 0)
- sysfatal("initdraw: %r");
- flushc = chancreate(sizeof(ulong), 1);
- msgc = chancreate(sizeof(char*), 0);
- mc = initmouse(nil, screen);
- if(mc == nil)
- sysfatal("initmouse: %r");
- screeninit();
- proccreate(keyproc, 0, 8192);
- proccreate(screenproc, 0, 8192);
+ initemu(256, 239, 2, RGB15, !mouse, nil);
+ regkey("b", 'z', 1<<31);
+ regkey("a", 'x', 1<<23);
+ regkey("y", 'a', 1<<30);
+ regkey("x", 's', 1<<22);
+ regkey("l1", 'q', 1<<21);
+ regkey("r1", 'w', 1<<20);
+ regkey("control", Kshift, 1<<29);
+ regkey("start", '\n', 1<<28);
+ regkey("up", Kup, 1<<27);
+ regkey("down", Kdown, 1<<26);
+ regkey("left", Kleft, 1<<25);
+ regkey("right", Kright, 1<<24);
+ msgc = chancreate(sizeof(char*), 1);
loadbat(argv[0]);
cpureset();
memreset();
@@ -358,7 +180,6 @@ usage:
stimerclock += t;
ppuclock += t;
dspclock += t;
- perfclock -= t;
while(ppuclock >= 4){
ppustep();
@@ -386,18 +207,43 @@ usage:
msgclock = 0;
}
}
- if(profile && perfclock <= 0){
- perfclock = FREQ;
- timing();
- }
}
}
void
flush(void)
{
- sendul(flushc, 1); /* flush screen */
- audioout();
+ char *s;
+ Mouse m;
+ Point p;
+
+ extern Rectangle picr;
+ extern Mousectl *mc;
+ flushmouse(!mouse);
+ while(nbrecv(mc->c, &m) > 0){
+ if(ptinrect(m.xy, picr)){
+ p = subpt(m.xy, picr.min);
+ p.x /= scale;
+ p.y /= scale;
+ keys = keys & 0xff3f0000 | p.x | p.y << 8;
+ if((m.buttons & 1) != 0)
+ keys |= 1<<22;
+ if((m.buttons & 4) != 0)
+ keys |= 1<<23;
+ if((m.buttons & 2) != 0)
+ lastkeys = keys;
+ }
+ }
+ flushscreen();
+ while(nbrecv(msgc, &s) > 0){
+ if(s != nil){
+ string(screen, addpt(screen->r.min, Pt(10, 10)), display->black, ZP,
+ display->defaultfont, s);
+ free(s);
+ flushimage(display, 1);
+ }
+ }
+ flushaudio(audioout);
}
void
diff --git a/sys/src/games/snes/spc.c b/sys/src/games/snes/spc.c
index 43c1b7695..a5fc7ab8a 100644
--- a/sys/src/games/snes/spc.c
+++ b/sys/src/games/snes/spc.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
+#include <emu.h>
#include "dat.h"
#include "fns.h"