summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/games/gb/dat.h10
-rw-r--r--sys/src/games/gb/mem.c2
-rw-r--r--sys/src/games/gb/ppu.c27
-rw-r--r--sys/src/games/gba/dat.h2
-rw-r--r--sys/src/games/gba/gba.c17
-rw-r--r--sys/src/games/gba/ppu.c3
6 files changed, 50 insertions, 11 deletions
diff --git a/sys/src/games/gb/dat.h b/sys/src/games/gb/dat.h
index 8ce259acb..787c8f839 100644
--- a/sys/src/games/gb/dat.h
+++ b/sys/src/games/gb/dat.h
@@ -22,7 +22,7 @@ extern u8int ppuy, ppustate;
extern u8int mode;
extern u8int mbc, feat;
-extern int keys;
+extern int keys, scale;
enum {
JOYP = 0x00,
@@ -69,10 +69,10 @@ enum {
WX = 0x4B,
KEY1 = 0x4D,
VBK = 0x4F,
- HDMASL = 0x51,
- HDMASH = 0x52,
- HDMADL = 0x53,
- HDMADH = 0x54,
+ HDMASH = 0x51,
+ HDMASL = 0x52,
+ HDMADH = 0x53,
+ HDMADL = 0x54,
HDMAC = 0x55,
BCPS = 0x68,
diff --git a/sys/src/games/gb/mem.c b/sys/src/games/gb/mem.c
index c5b4bd554..7f2894571 100644
--- a/sys/src/games/gb/mem.c
+++ b/sys/src/games/gb/mem.c
@@ -549,7 +549,7 @@ dmastep(void)
u16int sa, da;
sa = (reg[HDMASL] | reg[HDMASH] << 8) & 0xfff0;
- da = (reg[HDMADL] | reg[HDMADH] << 8) & 0x0ff0;
+ da = (reg[HDMADL] | reg[HDMADH] << 8) & 0x1ff0 | 0x8000;
for(i = 0; i < 16; i++)
memwrite(da++, memread(sa++));
reg[HDMASL] += 16;
diff --git a/sys/src/games/gb/ppu.c b/sys/src/games/gb/ppu.c
index 3dbd221d2..bd1ecf905 100644
--- a/sys/src/games/gb/ppu.c
+++ b/sys/src/games/gb/ppu.c
@@ -5,7 +5,7 @@
#include "fns.h"
u8int ppustate, ppuy;
-u32int pic[PICW*PICH];
+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;
+ picp = 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;
+ picp = pic + ppuy * PICW * scale;
for(q = spr; q < sprm; q++){
if(q->x <= ppux0 || q->x >= ppux + 8)
continue;
@@ -250,6 +250,25 @@ linelen(void)
return t*2;
}
+static void
+lineexpand(void)
+{
+ u32int *picp, *p, *q, l;
+ int i, s;
+
+ s = scale;
+ picp = pic + ppuy * PICW * s;
+ p = picp + PICW;
+ q = picp + PICW * scale;
+ for(i = PICW; --i >= 0; ){
+ l = *--p;
+ *--q = l;
+ *--q = l;
+ if(scale == 3)
+ *--q = l;
+ }
+}
+
void
hblanktick(void *)
{
@@ -298,6 +317,8 @@ hblanktick(void *)
ppusync();
if(!done) print("not done?!\n");
done = 0;
+ if(scale > 1)
+ lineexpand();
ppustate = 0;
if((reg[STAT] & IRQM0) != 0)
reg[IF] |= IRQLCDS;
diff --git a/sys/src/games/gba/dat.h b/sys/src/games/gba/dat.h
index 4f4651c0a..a609b850b 100644
--- a/sys/src/games/gba/dat.h
+++ b/sys/src/games/gba/dat.h
@@ -141,6 +141,8 @@ 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 bfb65c738..cebd1a830 100644
--- a/sys/src/games/gba/gba.c
+++ b/sys/src/games/gba/gba.c
@@ -317,6 +317,8 @@ 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)
@@ -347,7 +349,20 @@ flush(void)
flushimage(display, 1);
if(profile)
timing();
- audioout();
+ 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);
diff --git a/sys/src/games/gba/ppu.c b/sys/src/games/gba/ppu.c
index 85d1d0652..a87caba17 100644
--- a/sys/src/games/gba/ppu.c
+++ b/sys/src/games/gba/ppu.c
@@ -754,7 +754,8 @@ hblanktick(void *)
setif(IRQVCTR);
}else{
syncppu(240);
- linecopy();
+ if(ppuy < 160)
+ linecopy();
addevent(&evhblank, 68*4);
hblank = 1;
if((stat & IRQHBLEN) != 0)