diff --git a/src/crab.cr b/src/crab.cr index 292c290..5dcaf2f 100644 --- a/src/crab.cr +++ b/src/crab.cr @@ -47,14 +47,12 @@ module Crab end if rom.not_nil!.ends_with?(".gba") - gba = GBA::GBA.new bios.not_nil!, rom.not_nil! - gba.post_init - gba.run + emu = GBA::GBA.new bios.not_nil!, rom.not_nil! else - gb = GB::GB.new bios, rom.not_nil!, fifo, sync, headless - gb.post_init - gb.run + emu = GB::GB.new bios, rom.not_nil!, fifo, sync, headless end + emu.post_init + emu.run end end diff --git a/src/crab/common/emu.cr b/src/crab/common/emu.cr new file mode 100644 index 0000000..3213fae --- /dev/null +++ b/src/crab/common/emu.cr @@ -0,0 +1,29 @@ +abstract class Emu + def post_init : Nil + end + + abstract def scheduler : Scheduler + abstract def run : Nil + abstract def handle_event(event : SDL::Event) : Nil + abstract def toggle_sync : Nil + abstract def toggle_blending : Nil + + def handle_events(interval : Int) : Nil + scheduler.schedule interval, Proc(Nil).new { handle_events interval } + while event = SDL::Event.poll + case event + when SDL::Event::Quit then exit 0 + when SDL::Event::JoyHat, + SDL::Event::JoyButton then handle_event(event) + when SDL::Event::Keyboard + case event.sym + when .tab? then toggle_sync if event.pressed? + when .m? then toggle_blending if event.pressed? + when .q? then exit 0 + else handle_event(event) + end + else nil + end + end + end +end diff --git a/src/crab/gb/apu.cr b/src/crab/gb/apu.cr index 22d06d2..ba45a8a 100644 --- a/src/crab/gb/apu.cr +++ b/src/crab/gb/apu.cr @@ -29,7 +29,7 @@ module GB @audiospec : LibSDL::AudioSpec @obtained_spec : LibSDL::AudioSpec - setter sync : Bool + @sync : Bool = true def initialize(@gb : GB, headless : Bool, @sync : Bool) @sync = false if headless @@ -57,6 +57,10 @@ module GB LibSDL.pause_audio 0 unless headless end + def toggle_sync : Nil + @sync = !@sync + end + def tick_frame_sequencer : Nil @first_half_of_length_period = @frame_sequencer_stage & 1 == 0 case @frame_sequencer_stage diff --git a/src/crab/gb/gb.cr b/src/crab/gb/gb.cr index 72640b5..29c7cbc 100644 --- a/src/crab/gb/gb.cr +++ b/src/crab/gb/gb.cr @@ -16,7 +16,7 @@ require "./timer" DISPLAY_SCALE = {% unless flag? :graphics_test %} 4 {% else %} 1 {% end %} module GB - class GB + class GB < Emu getter bootrom : String? getter cgb_ptr : Pointer(Bool) { pointerof(@cgb_enabled) } getter cartridge : Cartridge @@ -60,24 +60,23 @@ module GB timer.skip_boot end - def handle_events : Nil - while event = SDL::Event.poll - case event - when SDL::Event::Quit then exit 0 - when SDL::Event::Keyboard, - SDL::Event::JoyHat, - SDL::Event::JoyButton then joypad.handle_joypad_event event - else nil - end - end - scheduler.schedule_gb 70224, ->handle_events, Scheduler::EventType::HandleInput - end - def run : Nil - handle_events + handle_events(70224) loop do cpu.tick end end + + def handle_event(event : SDL::Event) : Nil + joypad.handle_joypad_event event + end + + def toggle_sync : Nil + apu.toggle_sync + end + + def toggle_blending : Nil + puts "Blending not implemented for gb/gbc" + end end end diff --git a/src/crab/gb/joypad.cr b/src/crab/gb/joypad.cr index fbaa909..fe4ca2c 100644 --- a/src/crab/gb/joypad.cr +++ b/src/crab/gb/joypad.cr @@ -47,7 +47,6 @@ module GB when .l? then @select = event.pressed? when .b?, .j? then @b = event.pressed? when .a?, .k? then @a = event.pressed? - when .tab? then @gb.apu.sync = !event.pressed? else nil end when SDL::Event::JoyHat diff --git a/src/crab/gba/apu.cr b/src/crab/gba/apu.cr index 33293a7..f22fd4a 100644 --- a/src/crab/gba/apu.cr +++ b/src/crab/gba/apu.cr @@ -51,7 +51,7 @@ module GBA LibSDL.pause_audio 0 end - def toggle_sync + def toggle_sync : Nil @sync = !@sync end diff --git a/src/crab/gba/gba.cr b/src/crab/gba/gba.cr index 133b1e1..92297bb 100644 --- a/src/crab/gba/gba.cr +++ b/src/crab/gba/gba.cr @@ -16,7 +16,7 @@ require "./dma" require "./debugger" module GBA - class GBA + class GBA < Emu getter! scheduler : Scheduler getter! cartridge : Cartridge getter! storage : Storage @@ -36,7 +36,6 @@ module GBA @scheduler = Scheduler.new @cartridge = Cartridge.new rom_path @storage = Storage.new rom_path - handle_events handle_saves SDL.init(SDL::Init::VIDEO | SDL::Init::AUDIO | SDL::Init::JOYSTICK) @@ -58,29 +57,29 @@ module GBA @debugger = Debugger.new self end - def handle_events : Nil - scheduler.schedule 280896, ->handle_events - while event = SDL::Event.poll - case event - when SDL::Event::Quit then exit 0 - when SDL::Event::Keyboard, - SDL::Event::JoyHat, - SDL::Event::JoyButton then keypad.handle_keypad_event event - else nil - end + def run : Nil + handle_events(280896) + loop do + {% if flag? :debugger %} debugger.check_debug {% end %} + cpu.tick end end + def handle_event(event : SDL::Event) : Nil + keypad.handle_keypad_event event + end + + def toggle_sync : Nil + apu.toggle_sync + end + + def toggle_blending : Nil + display.toggle_blending + end + def handle_saves : Nil scheduler.schedule 280896, ->handle_saves storage.write_save end - - def run : Nil - loop do - {% if flag? :debugger %} debugger.check_debug {% end %} - cpu.tick - end - end end end diff --git a/src/crab/gba/keypad.cr b/src/crab/gba/keypad.cr index 462fc38..e329c06 100644 --- a/src/crab/gba/keypad.cr +++ b/src/crab/gba/keypad.cr @@ -69,10 +69,7 @@ module GBA when .a?, .k? then @keyinput.a = bit when .w? then @keyinput.l = bit when .r? then @keyinput.r = bit - # Extras - when .tab? then @gba.apu.toggle_sync if event.pressed? - when .m? then @gba.display.toggle_blending if event.pressed? - else nil + else nil end when SDL::Event::JoyHat @keyinput.value |= 0x00F0