Joypad support
This commit is contained in:
parent
a86523e03d
commit
22fed0fea1
14
include/gb.h
14
include/gb.h
|
@ -21,17 +21,27 @@ typedef struct gb_timers_t {
|
||||||
} GBTimers;
|
} GBTimers;
|
||||||
|
|
||||||
GBTimers *gb_timers_open(RIO *io);
|
GBTimers *gb_timers_open(RIO *io);
|
||||||
void gb_timers_close(RIO *io, GBTimers *timers);
|
|
||||||
void gb_timers_update(GBTimers *timers, ut32 cycles);
|
void gb_timers_update(GBTimers *timers, ut32 cycles);
|
||||||
|
void gb_timers_close(RIO *io, GBTimers *timers);
|
||||||
|
|
||||||
typedef struct gb_joypad_t {
|
typedef struct gb_joypad_t {
|
||||||
ut8 *keys;
|
ut8 *keys;
|
||||||
int fd;
|
int fd;
|
||||||
|
ut16 up;
|
||||||
|
ut16 down;
|
||||||
|
ut16 left;
|
||||||
|
ut16 right;
|
||||||
|
ut16 a;
|
||||||
|
ut16 b;
|
||||||
|
ut16 start;
|
||||||
|
ut16 select;
|
||||||
ut8 data;
|
ut8 data;
|
||||||
ut8 odata;
|
ut8 odata;
|
||||||
} GBJoypad;
|
} GBJoypad;
|
||||||
|
|
||||||
GBJoypad *gb_joypad_open(RIO *io)
|
GBJoypad *gb_joypad_open(RIO *io);
|
||||||
|
void gb_joypad_update(GBJoypad *joypad);
|
||||||
|
void gb_joypad_close(RIO *io, GBJoypad *joypad);
|
||||||
|
|
||||||
//int gb_mbc1_open(RIO *io, char *path);
|
//int gb_mbc1_open(RIO *io, char *path);
|
||||||
|
|
||||||
|
|
74
io/joypad.c
74
io/joypad.c
|
@ -19,22 +19,41 @@ static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ut64 __lseek(RIO* io, RIODesc *desc, ut64 offset, int whence) {
|
||||||
|
GBJoypad *joypad = (GBTimers *)desc->data;
|
||||||
|
ut64 seek = (joypad->odata & 0x40) >> 6;
|
||||||
|
switch (whence) {
|
||||||
|
case R_IO_SEEK_SET:
|
||||||
|
seek = R_MIN (1, offset);
|
||||||
|
break;
|
||||||
|
case R_IO_SEEK_CUR:
|
||||||
|
seek = R_MIN (1, seek + offset);
|
||||||
|
break;
|
||||||
|
case R_IO_SEEK_END:
|
||||||
|
seek = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
joypad->odata = (joypad->odata & 0x3f) |
|
||||||
|
return seek;
|
||||||
|
}
|
||||||
|
|
||||||
static int __read(RIO *io, RIODesc *desc, ut8 *buf, int len) {
|
static int __read(RIO *io, RIODesc *desc, ut8 *buf, int len) {
|
||||||
GBJoypad *joypad = (GBJoypad *)desc->data;
|
GBJoypad *joypad = (GBJoypad *)desc->data;
|
||||||
if (!len || (joypad->odata & 0x10)) {
|
if (!len || (joypad->odata & 0x40)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
joypad->data = buf[0] & 0xf;
|
joypad->data = buf[0] & 0xf;
|
||||||
joypad->odata |= 0x10;
|
joypad->odata |= 0x40;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __write(RIO *io, RIODesc *desc, const ut8 *buf, int len) {
|
static int __write(RIO *io, RIODesc *desc, const ut8 *buf, int len) {
|
||||||
GBJoypad *joypad = (GBJoypad *)desc->data;
|
GBJoypad *joypad = (GBJoypad *)desc->data;
|
||||||
if (!len || (joypad->odata & 0x10)) {
|
if (!len || (joypad->odata & 0x40)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
joypad->odata |= 0x10;
|
joypad->odata |= 0x40;
|
||||||
|
joypad->data = (buf[0] & 0x30) | (joypad->data & 0xf);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,5 +92,52 @@ GBJoypad *gb_joypad_open (RIO *io) {
|
||||||
}
|
}
|
||||||
joypad->fd = desc->fd;
|
joypad->fd = desc->fd;
|
||||||
joypad->keys = SDL_GetKeyboardState (NULL);
|
joypad->keys = SDL_GetKeyboardState (NULL);
|
||||||
|
joypad->up = SDL_SCANCODE_W;
|
||||||
|
joypad->down = SDL_SCANCODE_S;
|
||||||
|
joypad->left = SDL_SCANCODE_A;
|
||||||
|
joypad->right = SDL_SCANCODE_D;
|
||||||
|
joypad->a = SDL_SCANCODE_L;
|
||||||
|
joypad->b = SDL_SCANCODE_K;
|
||||||
|
joypad->start = SDL_SCANCODE_SPACE;
|
||||||
|
joypad->select = SDL_SCANCODE_KP_ENTER;
|
||||||
return joypad;
|
return joypad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gb_joypad_update(GBJoypad *joypad) {
|
||||||
|
joypad->odata &= 0xc0;
|
||||||
|
joypad->odata |= joypad->data & 0x3f;
|
||||||
|
SDL_PumpEvents ();
|
||||||
|
ut8 ndata = 0;
|
||||||
|
if (!(joypad->data & 0x8)) { //d-pad
|
||||||
|
const ut8 data = (~joypad->data) & 0xf;
|
||||||
|
ndata = !!joypad->keys[joypad->right];
|
||||||
|
ndata |= (!!joypad->keys[joypad->left]) << 1;
|
||||||
|
ndata |= (!!joypad->keys[joypad->up]) << 2;
|
||||||
|
ndata |= (!!joypad->keys[joypad->down]) << 3;
|
||||||
|
// on a real gameboy you cannot press up and down, or left and right at the same time
|
||||||
|
if ((ndata & 0x3) == 0x3) {
|
||||||
|
ndata = (ndata & 0xc) | (data & 0x3);
|
||||||
|
}
|
||||||
|
if ((ndata & 0xc) == 0xc) {
|
||||||
|
ndata = (ndata & 0x3) | (data & 0xc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(joypad->data & 0x10)) {
|
||||||
|
ndata |= !!joypad->keys[joypad->a];
|
||||||
|
ndata |= (!!joypad->keys[joypad->b]) << 1;
|
||||||
|
ndata |= (!!joypad->keys[joypad->select]) << 2;
|
||||||
|
ndata |= (!!joypad->keys[joypad->start]) << 3;
|
||||||
|
}
|
||||||
|
joypad->data = (joypad->data & 0x30) | (ndata ^ 0xf);
|
||||||
|
if (joypad->odata & ndata) {
|
||||||
|
//TODO: request interrupt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gb_joypad_close (RIO *io, GBJoypad *joypad) {
|
||||||
|
if (!io || !joypad) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
r_io_fd_close (io, joypad->fd);
|
||||||
|
free (joypad);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user