mirror of
https://github.com/mattrberry/crab.git
synced 2025-02-14 20:48:18 +01:00
in-memory keybinding changes
This commit is contained in:
parent
2bcd5a3120
commit
40b485780c
10 changed files with 181 additions and 9 deletions
|
@ -36,6 +36,10 @@ abstract class Controller
|
|||
emu.handle_event(event)
|
||||
end
|
||||
|
||||
def handle_input(input : Input, pressed : Bool) : Nil
|
||||
emu.handle_input(input, pressed)
|
||||
end
|
||||
|
||||
def toggle_sync : Nil
|
||||
emu.toggle_sync
|
||||
end
|
||||
|
|
|
@ -22,6 +22,9 @@ class StubbedController < Controller
|
|||
def handle_event(event : SDL::Event) : Nil
|
||||
end
|
||||
|
||||
def handle_input(input : Input, pressed : Bool) : Nil
|
||||
end
|
||||
|
||||
def toggle_sync : Nil
|
||||
end
|
||||
|
||||
|
|
|
@ -48,9 +48,10 @@ class SDLOpenGLImGuiFrontend < Frontend
|
|||
LibGL.use_program(@shader_programs[@controller.class])
|
||||
@opengl_info = OpenGLInfo.new
|
||||
@io = setup_imgui
|
||||
LibSDL.gl_set_swap_interval(1) if @controller.class == StubbedController
|
||||
|
||||
@file_explorer = ImGui::FileExplorer.new
|
||||
LibSDL.gl_set_swap_interval(1) if @controller.class == StubbedController
|
||||
@keybindings = ImGui::Keybindings.new
|
||||
end
|
||||
|
||||
def run : NoReturn
|
||||
|
@ -115,11 +116,18 @@ class SDLOpenGLImGuiFrontend < Frontend
|
|||
when SDL::Event::JoyHat,
|
||||
SDL::Event::JoyButton then @controller.handle_event(event)
|
||||
when SDL::Event::Keyboard
|
||||
case event.sym
|
||||
when .tab? then @controller.toggle_sync if event.pressed?
|
||||
# when .m? then toggle_blending if event.pressed?
|
||||
when .q? then exit 0
|
||||
else @controller.handle_event(event)
|
||||
if @keybindings.wants_input?
|
||||
@keybindings.key_released(event.sym) unless event.pressed? # pass on key release
|
||||
else
|
||||
case event.sym
|
||||
when .tab? then @controller.toggle_sync if event.pressed?
|
||||
# when .m? then toggle_blending if event.pressed?
|
||||
when .q? then exit 0
|
||||
else
|
||||
if input = @keybindings[event.sym]?
|
||||
@controller.handle_input(input, event.pressed?)
|
||||
end
|
||||
end
|
||||
end
|
||||
else nil
|
||||
end
|
||||
|
@ -158,8 +166,9 @@ class SDLOpenGLImGuiFrontend < Frontend
|
|||
overlay_height = 10.0
|
||||
open_rom_selection = false
|
||||
open_bios_selection = false
|
||||
open_keybindings = false
|
||||
|
||||
if LibSDL.get_mouse_focus || @controller.class == StubbedController
|
||||
if (LibSDL.get_mouse_focus || @controller.class == StubbedController) && !@file_explorer.open? && !@keybindings.open?
|
||||
if ImGui.begin_main_menu_bar
|
||||
if ImGui.begin_menu "File"
|
||||
previously_paused = @pause
|
||||
|
@ -169,6 +178,7 @@ class SDLOpenGLImGuiFrontend < Frontend
|
|||
ImGui.menu_item "Overlay", "", pointerof(@enable_overlay)
|
||||
# ImGui.menu_item "Blend", "", pointerof(@enable_blend) todo: re-implement blending now that frames are cleared
|
||||
ImGui.menu_item "Pause", "", pointerof(@pause)
|
||||
open_keybindings = ImGui.menu_item "Keybindings"
|
||||
ImGui.end_menu
|
||||
|
||||
toggle_blending if @enable_blend ^ @blending
|
||||
|
@ -185,6 +195,8 @@ class SDLOpenGLImGuiFrontend < Frontend
|
|||
@file_explorer.render(:ROM, open_rom_selection, ROM_EXTENSIONS)
|
||||
@file_explorer.render(:BIOS, open_bios_selection)
|
||||
|
||||
@keybindings.render(open_keybindings)
|
||||
|
||||
if @enable_overlay
|
||||
ImGui.set_next_window_pos(ImGui::ImVec2.new 10, overlay_height)
|
||||
ImGui.set_next_window_bg_alpha(0.5)
|
||||
|
|
|
@ -5,6 +5,12 @@ module ImGui
|
|||
@selected_entry_idx = 0
|
||||
@match_hidden = false
|
||||
|
||||
@open = false
|
||||
|
||||
def open? : Bool
|
||||
@open
|
||||
end
|
||||
|
||||
getter selection : Tuple(Path, Symbol)? = nil
|
||||
|
||||
def initialize(@path = Path[explorer_dir].expand(home: true))
|
||||
|
@ -12,6 +18,7 @@ module ImGui
|
|||
end
|
||||
|
||||
def render(name : Symbol, open_popup : Bool, extensions : Array(String)? = nil) : Nil
|
||||
@open ||= open_popup
|
||||
ImGui.open_popup(name.to_s) if open_popup
|
||||
center = ImGui.get_main_viewport.get_center
|
||||
ImGui.set_next_window_pos(center, ImGui::ImGuiCond::Appearing, ImGui::ImVec2.new(0.5, 0.5))
|
||||
|
@ -51,7 +58,7 @@ module ImGui
|
|||
ImGui.begin_group
|
||||
open_file(name) if ImGui.button "Open"
|
||||
ImGui.same_line
|
||||
ImGui.close_current_popup if ImGui.button "Cancel"
|
||||
close if ImGui.button "Cancel"
|
||||
ImGui.same_line(spacing: 10)
|
||||
ImGui.checkbox("Show hidden files?", pointerof(@match_hidden))
|
||||
ImGui.end_group
|
||||
|
@ -59,13 +66,18 @@ module ImGui
|
|||
end
|
||||
end
|
||||
|
||||
def close : Nil
|
||||
@open = false
|
||||
ImGui.close_current_popup
|
||||
end
|
||||
|
||||
def clear_selection : Nil
|
||||
@selection = nil
|
||||
end
|
||||
|
||||
private def open_file(name : Symbol) : Nil
|
||||
@selection = {(@path / @matched_entries[@selected_entry_idx][:name]).normalize, name}
|
||||
ImGui.close_current_popup
|
||||
close
|
||||
set_explorer_dir @path.to_s
|
||||
end
|
||||
|
||||
|
|
92
src/crab/common/frontend/widgets/keybindings.cr
Normal file
92
src/crab/common/frontend/widgets/keybindings.cr
Normal file
|
@ -0,0 +1,92 @@
|
|||
module ImGui
|
||||
class Keybindings
|
||||
POPUP_NAME = "Keybindings"
|
||||
BUTTON_SIZE = ImGui::ImVec2.new(32, 0)
|
||||
|
||||
@open = false
|
||||
@selection : Input? = nil
|
||||
@keycodes : Hash(LibSDL::Keycode, Input) = {
|
||||
LibSDL::Keycode::E => Input::UP,
|
||||
LibSDL::Keycode::D => Input::DOWN,
|
||||
LibSDL::Keycode::S => Input::LEFT,
|
||||
LibSDL::Keycode::F => Input::RIGHT,
|
||||
LibSDL::Keycode::K => Input::A,
|
||||
LibSDL::Keycode::J => Input::B,
|
||||
LibSDL::Keycode::L => Input::SELECT,
|
||||
LibSDL::Keycode::SEMICOLON => Input::START,
|
||||
LibSDL::Keycode::W => Input::L,
|
||||
LibSDL::Keycode::R => Input::R,
|
||||
}
|
||||
@editing_keycodes : Hash(LibSDL::Keycode, Input) = {} of LibSDL::Keycode => Input
|
||||
|
||||
delegate :[]?, to: @keycodes
|
||||
|
||||
def initialize
|
||||
overwrite_hash(@editing_keycodes, @keycodes)
|
||||
end
|
||||
|
||||
def open? : Bool
|
||||
@open
|
||||
end
|
||||
|
||||
def wants_input? : Bool
|
||||
!@selection.nil?
|
||||
end
|
||||
|
||||
def key_released(keycode : LibSDL::Keycode) : Nil
|
||||
if selection = @selection
|
||||
@editing_keycodes.reject!(@editing_keycodes.key_for?(selection))
|
||||
@editing_keycodes[keycode] = selection
|
||||
@selection = nil
|
||||
else
|
||||
puts "Something went wrong when setting keybinding.."
|
||||
end
|
||||
end
|
||||
|
||||
def render(open_popup : Bool) : Nil
|
||||
@open ||= open_popup
|
||||
if open_popup
|
||||
overwrite_hash(@editing_keycodes, @keycodes)
|
||||
ImGui.open_popup(POPUP_NAME)
|
||||
end
|
||||
center = ImGui.get_main_viewport.get_center
|
||||
ImGui.set_next_window_pos(center, ImGui::ImGuiCond::Appearing, ImGui::ImVec2.new(0.5, 0.5))
|
||||
hovered_button_color = ImGui.get_style_color_vec4(ImGui::ImGuiCol::ButtonHovered)
|
||||
if ImGui.begin_popup_modal(POPUP_NAME, flags: ImGui::ImGuiWindowFlags::AlwaysAutoResize)
|
||||
Input.values.each do |input|
|
||||
selected = @selection == input
|
||||
keycode = @editing_keycodes.key_for?(input)
|
||||
button_text = keycode ? String.new(LibSDL.get_key_name(keycode)) : ""
|
||||
x_pos = ImGui.get_window_content_region_max.x - BUTTON_SIZE.x
|
||||
ImGui.text(input.to_s)
|
||||
ImGui.same_line(x_pos)
|
||||
ImGui.push_style_color(ImGui::ImGuiCol::Button, hovered_button_color) if selected
|
||||
if ImGui.button(button_text, BUTTON_SIZE)
|
||||
@selection = input
|
||||
end
|
||||
ImGui.pop_style_color if selected
|
||||
end
|
||||
apply if ImGui.button "Apply"
|
||||
ImGui.same_line
|
||||
close if ImGui.button "Cancel"
|
||||
ImGui.end_popup
|
||||
end
|
||||
end
|
||||
|
||||
private def apply : Nil
|
||||
overwrite_hash(@keycodes, @editing_keycodes)
|
||||
close
|
||||
end
|
||||
|
||||
private def overwrite_hash(to_hash : Hash(K, V), from_hash : Hash(K, V)) : Hash(K, V) forall K, V
|
||||
to_hash.clear
|
||||
from_hash.each { |key, val| to_hash[key] = val }
|
||||
to_hash
|
||||
end
|
||||
|
||||
private def close : Nil
|
||||
@open = false
|
||||
ImGui.close_current_popup
|
||||
end
|
||||
end
|
||||
end
|
12
src/crab/common/input.cr
Normal file
12
src/crab/common/input.cr
Normal file
|
@ -0,0 +1,12 @@
|
|||
enum Input
|
||||
UP
|
||||
DOWN
|
||||
LEFT
|
||||
RIGHT
|
||||
A
|
||||
B
|
||||
SELECT
|
||||
START
|
||||
L
|
||||
R
|
||||
end
|
|
@ -62,6 +62,10 @@ module GB
|
|||
joypad.handle_joypad_event event
|
||||
end
|
||||
|
||||
def handle_input(input : Input, pressed : Bool) : Nil
|
||||
joypad.handle_input(input, pressed)
|
||||
end
|
||||
|
||||
def toggle_sync : Nil
|
||||
apu.toggle_sync
|
||||
end
|
||||
|
|
|
@ -35,6 +35,20 @@ module GB
|
|||
@direction_keys = (value >> 4) & 0x1 == 0
|
||||
end
|
||||
|
||||
def handle_input(input : Input, pressed : Bool) : Nil
|
||||
case input
|
||||
in Input::UP then @up = pressed
|
||||
in Input::DOWN then @down = pressed
|
||||
in Input::LEFT then @left = pressed
|
||||
in Input::RIGHT then @right = pressed
|
||||
in Input::A then @a = pressed
|
||||
in Input::B then @b = pressed
|
||||
in Input::SELECT then @select = pressed
|
||||
in Input::START then @start = pressed
|
||||
in Input::L, Input::R then nil
|
||||
end
|
||||
end
|
||||
|
||||
def handle_joypad_event(event : SDL::Event) : Nil
|
||||
case event
|
||||
when SDL::Event::Keyboard
|
||||
|
|
|
@ -61,6 +61,10 @@ module GBA
|
|||
keypad.handle_keypad_event event
|
||||
end
|
||||
|
||||
def handle_input(input : Input, pressed : Bool) : Nil
|
||||
keypad.handle_input(input, pressed)
|
||||
end
|
||||
|
||||
def toggle_sync : Nil
|
||||
apu.toggle_sync
|
||||
end
|
||||
|
|
|
@ -54,6 +54,21 @@ module GBA
|
|||
end
|
||||
end
|
||||
|
||||
def handle_input(input : Input, pressed : Bool) : Nil
|
||||
case input
|
||||
in Input::UP then @keyinput.up = !pressed
|
||||
in Input::DOWN then @keyinput.down = !pressed
|
||||
in Input::LEFT then @keyinput.left = !pressed
|
||||
in Input::RIGHT then @keyinput.right = !pressed
|
||||
in Input::A then @keyinput.a = !pressed
|
||||
in Input::B then @keyinput.b = !pressed
|
||||
in Input::SELECT then @keyinput.select = !pressed
|
||||
in Input::START then @keyinput.start = !pressed
|
||||
in Input::L then @keyinput.l = !pressed
|
||||
in Input::R then @keyinput.r = !pressed
|
||||
end
|
||||
end
|
||||
|
||||
def handle_keypad_event(event : SDL::Event) : Nil
|
||||
case event
|
||||
when SDL::Event::Keyboard
|
||||
|
|
Loading…
Add table
Reference in a new issue