games/snes: mouse support

This commit is contained in:
aiju 2014-03-14 16:49:52 +01:00
parent e8e0428140
commit 8d11fd6d27
4 changed files with 83 additions and 28 deletions

View file

@ -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,

View file

@ -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)

View file

@ -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)

View file

@ -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);