Infrared API

This commit is contained in:
Lior Halphon 2016-07-18 22:05:11 +03:00
parent 0fbc72f197
commit 1d35c04ab1
3 changed files with 41 additions and 2 deletions

View File

@ -466,6 +466,16 @@ void GB_set_rgb_encode_callback(GB_gameboy_t *gb, GB_rgb_encode_callback_t callb
gb->rgb_encode_callback = callback; gb->rgb_encode_callback = callback;
} }
void GB_set_infrared_callback(GB_gameboy_t *gb, GB_infrared_callback_t callback)
{
gb->infrared_callback = callback;
}
void GB_set_infrared_input(GB_gameboy_t *gb, bool state)
{
gb->infrared_input = state;
}
void GB_set_sample_rate(GB_gameboy_t *gb, unsigned int sample_rate) void GB_set_sample_rate(GB_gameboy_t *gb, unsigned int sample_rate)
{ {
if (gb->audio_buffer) { if (gb->audio_buffer) {

View File

@ -155,6 +155,7 @@ typedef void (*GB_vblank_callback_t)(GB_gameboy_t *gb);
typedef void (*GB_log_callback_t)(GB_gameboy_t *gb, const char *string, GB_log_attributes attributes); typedef void (*GB_log_callback_t)(GB_gameboy_t *gb, const char *string, GB_log_attributes attributes);
typedef char *(*GB_input_callback_t)(GB_gameboy_t *gb); typedef char *(*GB_input_callback_t)(GB_gameboy_t *gb);
typedef uint32_t (*GB_rgb_encode_callback_t)(GB_gameboy_t *gb, uint8_t r, uint8_t g, uint8_t b); typedef uint32_t (*GB_rgb_encode_callback_t)(GB_gameboy_t *gb, uint8_t r, uint8_t g, uint8_t b);
typedef void (*GB_infrared_callback_t)(GB_gameboy_t *gb, bool on);
typedef struct { typedef struct {
enum { enum {
@ -210,6 +211,10 @@ typedef struct GB_gameboy_s {
bool halted; bool halted;
bool stopped; bool stopped;
bool boot_rom_finished; bool boot_rom_finished;
/* Misc state*/
/* IR */
bool infrared_input;
); );
/* HDMA */ /* HDMA */
@ -342,6 +347,7 @@ typedef struct GB_gameboy_s {
GB_input_callback_t async_input_callback; GB_input_callback_t async_input_callback;
GB_rgb_encode_callback_t rgb_encode_callback; GB_rgb_encode_callback_t rgb_encode_callback;
GB_vblank_callback_t vblank_callback; GB_vblank_callback_t vblank_callback;
GB_infrared_callback_t infrared_callback;
/*** Debugger ***/ /*** Debugger ***/
bool debug_stopped; bool debug_stopped;
@ -398,5 +404,6 @@ void GB_set_input_callback(GB_gameboy_t *gb, GB_input_callback_t callback);
void GB_set_async_input_callback(GB_gameboy_t *gb, GB_input_callback_t callback); void GB_set_async_input_callback(GB_gameboy_t *gb, GB_input_callback_t callback);
void GB_set_sample_rate(GB_gameboy_t *gb, unsigned int sample_rate); void GB_set_sample_rate(GB_gameboy_t *gb, unsigned int sample_rate);
void GB_set_rgb_encode_callback(GB_gameboy_t *gb, GB_rgb_encode_callback_t callback); void GB_set_rgb_encode_callback(GB_gameboy_t *gb, GB_rgb_encode_callback_t callback);
void GB_set_infrared_callback(GB_gameboy_t *gb, GB_infrared_callback_t callback);
void GB_set_infrared_input(GB_gameboy_t *gb, bool state);
#endif /* GB_h */ #endif /* GB_h */

View File

@ -160,7 +160,16 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr)
} }
return (gb->io_registers[GB_IO_KEY1] & 0x7F) | (gb->cgb_double_speed? 0xFE : 0x7E); return (gb->io_registers[GB_IO_KEY1] & 0x7F) | (gb->cgb_double_speed? 0xFE : 0x7E);
case GB_IO_RP: {
if (!gb->is_cgb) return 0xFF;
/* You will read your own IR LED if it's on. */
bool read_value = gb->infrared_input || (gb->io_registers[GB_IO_RP] & 1);
uint8_t ret = (gb->io_registers[GB_IO_RP] & 0xC1) | 0x3C;
if ((gb->io_registers[GB_IO_RP] & 0xC0) == 0xC0 && read_value) {
ret |= read_value;
}
return ret;
}
default: default:
if ((addr & 0xFF) >= GB_IO_NR10 && (addr & 0xFF) <= GB_IO_WAV_END) { if ((addr & 0xFF) >= GB_IO_NR10 && (addr & 0xFF) <= GB_IO_WAV_END) {
return GB_apu_read(gb, addr & 0xFF); return GB_apu_read(gb, addr & 0xFF);
@ -440,6 +449,19 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
} }
return; return;
case GB_IO_RP: {
if (!gb->is_cgb) {
return;
}
if ((value & 1) != (gb->io_registers[GB_IO_RP] & 1)) {
if (gb->infrared_callback) {
gb->infrared_callback(gb, value & 1);
}
}
gb->io_registers[GB_IO_RP] = value;
return;
}
default: default:
if ((addr & 0xFF) >= GB_IO_NR10 && (addr & 0xFF) <= GB_IO_WAV_END) { if ((addr & 0xFF) >= GB_IO_NR10 && (addr & 0xFF) <= GB_IO_WAV_END) {
GB_apu_write(gb, addr & 0xFF, value); GB_apu_write(gb, addr & 0xFF, value);