Flow E: Libretro host-driven frame
The libretro core inverts control: RetroArch calls retro_run() once per host frame, and SameBoy must produce exactly one emulated frame of video and audio per call.
Trigger
RetroArch (or any libretro frontend) calls retro_run() at display refresh rate.
Lifecycle vs SDL
Initialization — retro_load_game
retro_init()— one-time setupretro_load_game(info)— allocategameboy[0],GB_init, load ROM frominfo->datainit_for_current_model()— register callbacks, set options fromcheck_variables()- Boot ROM from
retro_system_directoryor embedded C arrays (dmg_boot.c, etc.) retro_load_game_special— 2-player link:emulated_devices = 2, serial callbacks wired
Libretro build disables rewind, debugger, cheats via compile flags in libretro/Makefile.common.
retro_run — single player
void retro_run(void) {
if (variable_update) check_variables();
GB_update_keys_status(); // input_poll_cb + input_state_cb
GB_run_frame(&gameboy[0]); // loops GB_run until vblank
video_cb(frame_buf, width, height, pitch);
upload_output_audio_buffer(); // audio_batch_cb
}
GB_run_frame (gb.c:1228) temporarily enables turbo without frame skip, loops GB_run until vblank_just_occured, returns nanoseconds elapsed.
Pixels written during emulation to frame_buf slice via GB_set_pixels_output.
retro_run — link cable (2 players)
Alternates GB_run on GB0 and GB1 using cycle debt (delta) until both vblank1_occurred and vblank2_occurred:
while (!vblank1_occurred || !vblank2_occurred) {
if (delta >= 0) delta -= GB_run(&gameboy[0]);
else delta += GB_run(&gameboy[1]);
}
Serial bit callbacks connect the two instances for link cable games. Frame buffer composited side-by-side into frame_buf.
Configuration — core options
Options defined in libretro_core_options.inc, read in check_variables():
- Model (DMG/CGB/SGB/auto)
- Color correction, palette, border mode
- RTC mode, link cable enable
- Audio output (mono/stereo), rumble
- Screen layout (1×, 2× side-by-side)
Applied via GB_set_* API — same as other frontends, different config source.
Audio and video output
Video: rgb_encode_callback writes to frame_buf; after frame, video_cb hands buffer to RetroArch (with pitch). lcd_status_callback retains last frame when LCD turned off.
Audio: audio_callback accumulates interleaved int16 samples in output_audio_buffer; flushed at end of retro_run via audio_batch_cb.
Rumble: retro_rumble_interface queried in rumble_callback.
Failure modes
- Host calls
retro_runwithoutretro_load_game→ undefined (guarded by static state) - Link cable with only one loaded game → serial callbacks no-op
- Option change mid-frame → applied at start of next
retro_runwhenGET_VARIABLE_UPDATE