Files
prosperon/input/backends/sdl3.cm
2026-02-17 09:15:15 -06:00

256 lines
5.5 KiB
Plaintext

// SDL3 Backend - Translates SDL events to canonical input format
var sdl_input = use('sdl3/input')
// SDL keycode to lowercase key name
// SDL3 keycodes are based on their name strings
function keycode_to_control(keycode) {
var name = sdl_input.keyname(keycode)
if (!name) return null
return lower(name)
}
// Parse SDL mod bitmask to mods object
function parse_mods(mod) {
return {
ctrl: (mod & 0x00C0) != 0, // KMOD_CTRL
shift: (mod & 0x0003) != 0, // KMOD_SHIFT
alt: (mod & 0x0300) != 0, // KMOD_ALT
super: (mod & 0x0C00) != 0 // KMOD_GUI
}
}
// Translate SDL event to canonical format
// Returns canonical event or null if not translatable
function translate(evt) {
var control = null
// Keyboard
if (evt.type == 'key_down' || evt.type == 'key_up') {
if (evt.repeat) return null // Ignore key repeats
control = keycode_to_control(evt.key)
if (!control) return null
return {
kind: 'button',
device_id: 'kbm',
control: control,
pressed: evt.down == true,
released: evt.down != true,
mods: parse_mods(evt.mod),
which: evt.which,
time: evt.timestamp
}
}
// Mouse buttons
if (evt.type == 'mouse_button_down' || evt.type == 'mouse_button_up') {
return {
kind: 'button',
device_id: 'kbm',
control: 'mouse_button_' + evt.button,
pressed: evt.down == true,
released: evt.down != true,
pos: evt.pos,
clicks: evt.clicks,
which: evt.which,
time: evt.timestamp
}
}
// Mouse motion
if (evt.type == 'mouse_motion') {
return {
kind: 'axis',
device_id: 'kbm',
control: 'mouse_pos',
pos: evt.pos,
delta: evt.d_pos,
which: evt.which,
time: evt.timestamp
}
}
// Mouse wheel
if (evt.type == 'mouse_wheel') {
return {
kind: 'axis',
device_id: 'kbm',
control: 'mouse_wheel',
value: evt.scroll,
pos: evt.pos,
which: evt.which,
time: evt.timestamp
}
}
// Gamepad buttons
if (evt.type == 'gamepad_button_down' || evt.type == 'gamepad_button_up') {
return {
kind: 'button',
device_id: 'gp:' + evt.which,
control: 'gamepad_' + evt.button,
pressed: evt.down == true,
released: evt.down != true,
which: evt.which,
time: evt.timestamp
}
}
// Gamepad axes
if (evt.type == 'gamepad_axis_motion') {
return {
kind: 'axis',
device_id: 'gp:' + evt.which,
control: 'gamepad_' + evt.axis,
value: evt.value,
which: evt.which,
time: evt.timestamp
}
}
// Gamepad touchpad
if (evt.type == 'gamepad_touchpad_down') {
return {
kind: 'button',
device_id: 'gp:' + evt.which,
control: 'gamepad_touchpad',
pressed: true,
released: false,
touchpad: evt.touchpad,
finger: evt.finger,
pos: evt.pos,
pressure: evt.pressure,
which: evt.which,
time: evt.timestamp
}
}
if (evt.type == 'gamepad_touchpad_up') {
return {
kind: 'button',
device_id: 'gp:' + evt.which,
control: 'gamepad_touchpad',
pressed: false,
released: true,
touchpad: evt.touchpad,
finger: evt.finger,
pos: evt.pos,
which: evt.which,
time: evt.timestamp
}
}
if (evt.type == 'gamepad_touchpad_motion') {
return {
kind: 'axis',
device_id: 'gp:' + evt.which,
control: 'gamepad_touchpad',
touchpad: evt.touchpad,
finger: evt.finger,
pos: evt.pos,
pressure: evt.pressure,
which: evt.which,
time: evt.timestamp
}
}
// Touch events (screen touch, not gamepad)
if (evt.type == 'finger_down') {
return {
kind: 'button',
device_id: 'touch:' + evt.touch,
control: 'touch',
pressed: true,
released: false,
finger: evt.finger,
pos: evt.pos,
pressure: evt.pressure,
which: evt.touch,
time: evt.timestamp
}
}
if (evt.type == 'finger_up') {
return {
kind: 'button',
device_id: 'touch:' + evt.touch,
control: 'touch',
pressed: false,
released: true,
finger: evt.finger,
pos: evt.pos,
which: evt.touch,
time: evt.timestamp
}
}
if (evt.type == 'finger_motion') {
return {
kind: 'axis',
device_id: 'touch:' + evt.touch,
control: 'touch',
finger: evt.finger,
pos: evt.pos,
delta: evt.d_pos,
pressure: evt.pressure,
which: evt.touch,
time: evt.timestamp
}
}
// Text input
if (evt.type == 'text_input') {
return {
kind: 'text',
device_id: 'kbm',
control: 'text',
text: evt.text,
time: evt.timestamp
}
}
// Window events
if (starts_with(evt.type, 'window_')) {
return {
kind: 'window',
device_id: 'system',
control: evt.type,
width: evt.width,
height: evt.height,
which: evt.which,
time: evt.timestamp
}
}
// Device connect/disconnect
if (evt.type == 'gamepad_added') {
return {
kind: 'device',
device_id: 'gp:' + evt.which,
control: 'connected',
which: evt.which,
time: evt.timestamp
}
}
if (evt.type == 'gamepad_removed') {
return {
kind: 'device',
device_id: 'gp:' + evt.which,
control: 'disconnected',
which: evt.which,
time: evt.timestamp
}
}
// Not a translatable input event
return null
}
return {
translate: translate,
keycode_to_control: keycode_to_control,
parse_mods: parse_mods
}