diff options
author | aiju <devnull@localhost> | 2014-03-14 16:49:52 +0100 |
---|---|---|
committer | aiju <devnull@localhost> | 2014-03-14 16:49:52 +0100 |
commit | 8d11fd6d274a0792ebb64dcc89e2b8c087888fab (patch) | |
tree | a775e70d8f7df9d93cb101d4045ab248ef60f626 /sys/src/games | |
parent | e8e04281402b697c0568ce5e35dbd7fc1d0c0935 (diff) |
games/snes: mouse support
Diffstat (limited to 'sys/src/games')
-rw-r--r-- | sys/src/games/snes/dat.h | 4 | ||||
-rw-r--r-- | sys/src/games/snes/mem.c | 48 | ||||
-rw-r--r-- | sys/src/games/snes/ppu.c | 8 | ||||
-rw-r--r-- | sys/src/games/snes/snes.c | 51 |
4 files changed, 83 insertions, 28 deletions
diff --git a/sys/src/games/snes/dat.h b/sys/src/games/snes/dat.h index 0df6db465..b64a6ceea 100644 --- a/sys/src/games/snes/dat.h +++ b/sys/src/games/snes/dat.h @@ -6,7 +6,7 @@ extern int trace; extern uchar *prg, *sram; extern int nprg, nsram, keys; -extern u16int keylatch; +extern u32int keylatch, lastkeys; extern u8int reg[32768], spcmem[65536], vram[65536], oam[544]; extern u16int cgram[256]; @@ -14,7 +14,7 @@ extern int ppux, ppuy; extern u16int vtime, htime, subcolor, oamaddr; extern u16int m7[6], hofs[4], vofs[4]; -extern int battery, saveclock, scale; +extern int battery, saveclock, scale, mouse; enum { FLAGC = 1<<0, diff --git a/sys/src/games/snes/mem.c b/sys/src/games/snes/mem.c index dcf136e3d..3cb44ee35 100644 --- a/sys/src/games/snes/mem.c +++ b/sys/src/games/snes/mem.c @@ -8,7 +8,8 @@ u8int reg[32768]; u8int mem[131072]; u8int oam[544], vram[65536]; u16int cgram[256]; -u16int oamaddr, vramlatch, keylatch; +u16int oamaddr, vramlatch; +u32int keylatch, lastkeys; enum { OAMLATCH, CGLATCH, @@ -62,6 +63,31 @@ swaprb(u16int a) return (a & 0x83e0) | (a & 0x7c00) >> 10 | (a & 0x001f) << 10; } +static void +mouselatch(void) +{ + int x, y; + u32int v; + + v = keys & 0xffff0000; + x = (keys & 0xff) - (lastkeys & 0xff); + y = (keys >> 8 & 0xff) - (lastkeys >> 8 & 0xff); + if(x < 0){ + v |= 0x80; + x = -x; + } + if(y < 0){ + v |= 0x8000; + y = -y; + } + if(x > 127) + x = 127; + if(y > 127) + y = 127; + keylatch = v | x | y << 8; + lastkeys = keys; +} + u8int regread(u16int p) { @@ -124,9 +150,15 @@ regread(u16int p) reg[0x2181]++; return v; case 0x4016: - if((reg[0x4016] & 1) != 0) - return keylatch >> 15; - v = keylatch >> 15; + if((reg[0x4016] & 1) != 0){ + if(mouse) + if((keys & 0x300000) == 0x300000) + keys &= ~0x300000; + else + keys += 0x100000; + return keys >> 31; + } + v = keylatch >> 31; keylatch = (keylatch << 1) | 1; return v; case 0x4017: @@ -235,8 +267,12 @@ regwrite(u16int p, u8int v) case 0x213e: return; case 0x4016: - if((reg[0x4016] & 1) != 0 && (v & 1) == 0) - keylatch = keys; + if((reg[0x4016] & 1) != 0 && (v & 1) == 0){ + if(mouse) + mouselatch(); + else + keylatch = keys; + } break; case 0x4200: if((reg[0x4200] & 0x80) == 0 && (v & 0x80) != 0 && (reg[RDNMI] & 0x80) != 0) diff --git a/sys/src/games/snes/ppu.c b/sys/src/games/snes/ppu.c index b00982649..a0c82443e 100644 --- a/sys/src/games/snes/ppu.c +++ b/sys/src/games/snes/ppu.c @@ -579,9 +579,11 @@ ppustep(void) if((reg[NMITIMEN] & VBLANK) != 0) nmi = 2; if((reg[NMITIMEN] & AUTOJOY) != 0){ - reg[0x4218] = keys; - reg[0x4219] = keys >> 8; - keylatch = 0xffff; + memwrite(0x4016, 1); + memwrite(0x4016, 0); + reg[0x4218] = keylatch >> 16; + reg[0x4219] = keylatch >> 24; + keylatch = keylatch << 16 | 0xffff; } } if((reg[NMITIMEN] & (HCNTIRQ|VCNTIRQ)) == VCNTIRQ && vtime == ppuy) diff --git a/sys/src/games/snes/snes.c b/sys/src/games/snes/snes.c index 86d20d003..bac02e9d1 100644 --- a/sys/src/games/snes/snes.c +++ b/sys/src/games/snes/snes.c @@ -15,7 +15,7 @@ int ppuclock, spcclock, stimerclock, saveclock, msgclock, paused, perfclock; Mousectl *mc; QLock pauselock; int keys, savefd; -int scale, profile; +int scale, profile, mouse; Rectangle picr; Image *tmp, *bg; @@ -126,23 +126,23 @@ keyproc(void *) if(buf[0] != 'k' && buf[0] != 'K') continue; s = buf + 1; - k = 0; + k = 0xffff; while(*s != 0){ s += chartorune(&r, s); switch(r){ case Kdel: close(fd); threadexitsall(nil); - case 'z': k |= 1<<15; break; - case 'x': k |= 1<<7; break; - case 'a': k |= 1<<14; break; - case 's': k |= 1<<6; break; - case 'q': k |= 1<<5; break; - case 'w': k |= 1<<4; break; - case Kshift: k |= 1<<13; break; - case 10: k |= 1<<12; break; - case Kup: k |= 1<<11; break; - case Kdown: k |= 1<<10; break; - case Kleft: k |= 1<<9; break; - case Kright: k |= 1<<8; break; + 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); @@ -152,7 +152,8 @@ keyproc(void *) break; } } - keys = k; + if(!mouse) + keys = k; } } @@ -203,6 +204,10 @@ threadmain(int argc, char **argv) case 's': battery++; break; + case 'm': + mouse++; + keys = 1<<16; + break; case 'T': profile++; break; @@ -272,14 +277,26 @@ flush(void) { extern uchar pic[256*240*2*9]; Mouse m; + Point p; - while(nbrecv(mc->c, &m) > 0) - ; if(nbrecvul(mc->resizec) > 0){ if(getwindow(display, Refnone) < 0) sysfatal("resize failed: %r"); screeninit(); } + while(nbrecv(mc->c, &m) > 0) + 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; + } loadimage(tmp, tmp->r, pic, 256*239*2*scale*scale); draw(screen, picr, tmp, nil, ZP); flushimage(display, 1); |