sameboy: lag flag / inputcallback
This commit is contained in:
parent
09672a6bf9
commit
7d2ee60ade
|
@ -57,6 +57,13 @@ static uint8_t SerialEndCallback(GB_gameboy_t *gb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void (*FrontendInputCallback)();
|
||||
|
||||
static void InputCallback(GB_gameboy_t *gb)
|
||||
{
|
||||
FrontendInputCallback();
|
||||
}
|
||||
|
||||
static blip_t *leftblip;
|
||||
static blip_t *rightblip;
|
||||
const int SOUND_RATE_GB = 2097152;
|
||||
|
@ -146,6 +153,7 @@ ECL_EXPORT void FrameAdvance(MyFrameInfo &f)
|
|||
}
|
||||
sound_start_clock = GB_epoch(&GB);
|
||||
CurrentFramebuffer = f.VideoBuffer;
|
||||
GB_set_lagged(&GB, true);
|
||||
|
||||
uint32_t target = 35112 - FrameOverflow;
|
||||
f.Cycles = GB_run_cycles(&GB, target);
|
||||
|
@ -166,6 +174,7 @@ ECL_EXPORT void FrameAdvance(MyFrameInfo &f)
|
|||
f.Samples = blip_read_samples(leftblip, f.SoundBuffer, 2048, 1);
|
||||
blip_read_samples(rightblip, f.SoundBuffer + 1, 2048, 1);
|
||||
CurrentFramebuffer = NULL;
|
||||
f.Lagged = GB_get_lagged(&GB);
|
||||
}
|
||||
|
||||
static void SetMemoryArea(MemoryArea *m, GB_direct_access_t access, const char *name, int32_t flags)
|
||||
|
@ -194,7 +203,8 @@ ECL_EXPORT void GetMemoryAreas(MemoryArea *m)
|
|||
|
||||
ECL_EXPORT void SetInputCallback(void (*callback)())
|
||||
{
|
||||
// TODO
|
||||
FrontendInputCallback = callback;
|
||||
GB_set_input_callback(&GB, callback ? InputCallback : nullptr);
|
||||
}
|
||||
|
||||
int main()
|
||||
|
|
|
@ -43,54 +43,11 @@ void GB_log(GB_gameboy_t *gb, const char *fmt, ...)
|
|||
va_end(args);
|
||||
}
|
||||
|
||||
static char *default_input_callback(GB_gameboy_t *gb)
|
||||
{
|
||||
char *expression = NULL;
|
||||
size_t size = 0;
|
||||
|
||||
if (getline(&expression, &size, stdin) == -1) {
|
||||
/* The user doesn't have STDIN or used ^D. We make sure the program keeps running. */
|
||||
GB_set_async_input_callback(gb, NULL); /* Disable async input */
|
||||
return strdup("c");
|
||||
}
|
||||
|
||||
if (!expression) {
|
||||
return strdup("");
|
||||
}
|
||||
|
||||
size_t length = strlen(expression);
|
||||
if (expression[length - 1] == '\n') {
|
||||
expression[length - 1] = 0;
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
static char *default_async_input_callback(GB_gameboy_t *gb)
|
||||
{
|
||||
#if 0
|
||||
fd_set set;
|
||||
FD_ZERO(&set);
|
||||
FD_SET(STDIN_FILENO, &set);
|
||||
struct timeval time = {0,};
|
||||
if (select(1, &set, NULL, NULL, &time) == 1) {
|
||||
if (feof(stdin)) {
|
||||
GB_set_async_input_callback(gb, NULL); /* Disable async input */
|
||||
return NULL;
|
||||
}
|
||||
return default_input_callback(gb);
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void GB_init(GB_gameboy_t *gb)
|
||||
{
|
||||
memset(gb, 0, sizeof(*gb));
|
||||
gb->ram = malloc(gb->ram_size = 0x2000);
|
||||
gb->vram = malloc(gb->vram_size = 0x2000);
|
||||
|
||||
gb->input_callback = default_input_callback;
|
||||
gb->async_input_callback = default_async_input_callback;
|
||||
gb->cartridge_type = &GB_cart_defs[0]; // Default cartridge type
|
||||
|
||||
GB_reset(gb);
|
||||
|
@ -102,9 +59,6 @@ void GB_init_sgb(GB_gameboy_t *gb)
|
|||
gb->ram = malloc(gb->ram_size = 0x2000);
|
||||
gb->vram = malloc(gb->vram_size = 0x2000);
|
||||
gb->is_sgb = true;
|
||||
|
||||
gb->input_callback = default_input_callback;
|
||||
gb->async_input_callback = default_async_input_callback;
|
||||
gb->cartridge_type = &GB_cart_defs[0]; // Default cartridge type
|
||||
|
||||
GB_reset(gb);
|
||||
|
@ -116,9 +70,6 @@ void GB_init_cgb(GB_gameboy_t *gb)
|
|||
gb->ram = malloc(gb->ram_size = 0x2000 * 8);
|
||||
gb->vram = malloc(gb->vram_size = 0x2000 * 2);
|
||||
gb->is_cgb = true;
|
||||
|
||||
gb->input_callback = default_input_callback;
|
||||
gb->async_input_callback = default_async_input_callback;
|
||||
gb->cartridge_type = &GB_cart_defs[0]; // Default cartridge type
|
||||
|
||||
GB_reset(gb);
|
||||
|
@ -298,17 +249,9 @@ void GB_set_log_callback(GB_gameboy_t *gb, GB_log_callback_t callback)
|
|||
|
||||
void GB_set_input_callback(GB_gameboy_t *gb, GB_input_callback_t callback)
|
||||
{
|
||||
if (gb->input_callback == default_input_callback) {
|
||||
gb->async_input_callback = NULL;
|
||||
}
|
||||
gb->input_callback = callback;
|
||||
}
|
||||
|
||||
void GB_set_async_input_callback(GB_gameboy_t *gb, GB_input_callback_t callback)
|
||||
{
|
||||
gb->async_input_callback = callback;
|
||||
}
|
||||
|
||||
void GB_set_rgb_encode_callback(GB_gameboy_t *gb, GB_rgb_encode_callback_t callback)
|
||||
{
|
||||
if (!gb->rgb_encode_callback && !gb->is_cgb) {
|
||||
|
@ -541,3 +484,14 @@ void *GB_get_direct_access(GB_gameboy_t *gb, GB_direct_access_t access, size_t *
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void GB_set_lagged(GB_gameboy_t *gb, bool lagged)
|
||||
{
|
||||
gb->lagged = lagged;
|
||||
}
|
||||
|
||||
bool GB_get_lagged(GB_gameboy_t *gb)
|
||||
{
|
||||
return gb->lagged;
|
||||
}
|
||||
|
||||
|
|
|
@ -165,7 +165,7 @@ typedef enum {
|
|||
|
||||
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 char *(*GB_input_callback_t)(GB_gameboy_t *gb);
|
||||
typedef void (*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 void (*GB_infrared_callback_t)(GB_gameboy_t *gb, bool on, long cycles_since_last_update);
|
||||
typedef void (*GB_rumble_callback_t)(GB_gameboy_t *gb, bool rumble_on);
|
||||
|
@ -382,6 +382,7 @@ struct GB_gameboy_internal_s {
|
|||
/* I/O */
|
||||
uint32_t *screen;
|
||||
int keys;
|
||||
bool lagged;
|
||||
|
||||
/* Timing */
|
||||
uint64_t cycles_since_epoch;
|
||||
|
@ -390,7 +391,6 @@ struct GB_gameboy_internal_s {
|
|||
void *user_data;
|
||||
GB_log_callback_t log_callback;
|
||||
GB_input_callback_t input_callback;
|
||||
GB_input_callback_t async_input_callback;
|
||||
GB_rgb_encode_callback_t rgb_encode_callback;
|
||||
GB_vblank_callback_t vblank_callback;
|
||||
GB_infrared_callback_t infrared_callback;
|
||||
|
@ -496,7 +496,6 @@ void GB_queue_infrared_input(GB_gameboy_t *gb, bool state, long cycles_after_pre
|
|||
void GB_set_vblank_callback(GB_gameboy_t *gb, GB_vblank_callback_t callback);
|
||||
void GB_set_log_callback(GB_gameboy_t *gb, GB_log_callback_t callback);
|
||||
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_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_rumble_callback(GB_gameboy_t *gb, GB_rumble_callback_t callback);
|
||||
|
@ -512,4 +511,7 @@ void GB_serial_set_data(GB_gameboy_t *gb, uint8_t data);
|
|||
|
||||
void GB_disconnect_serial(GB_gameboy_t *gb);
|
||||
|
||||
void GB_set_lagged(GB_gameboy_t *gb, bool lagged);
|
||||
bool GB_get_lagged(GB_gameboy_t *gb);
|
||||
|
||||
#endif /* GB_h */
|
||||
|
|
|
@ -137,6 +137,9 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr)
|
|||
if (addr < 0xFF80) {
|
||||
if (addr == 0xff00 && gb->is_sgb)
|
||||
{
|
||||
if (gb->input_callback)
|
||||
gb->input_callback(gb);
|
||||
gb->lagged = false;
|
||||
return sgb_read_ff00(gb->cycles_since_epoch);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue