256 lines
5.5 KiB
Plaintext
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
|
|
}
|