Joypad support

This commit is contained in:
condret 2024-10-18 05:09:58 +02:00
parent a86523e03d
commit 22fed0fea1
2 changed files with 82 additions and 6 deletions

View File

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

View File

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