games/snes: mouse support
This commit is contained in:
parent
e8e0428140
commit
8d11fd6d27
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue