Files
cell-sdl3/input.c
2026-02-23 19:45:49 -06:00

633 lines
23 KiB
C

#include "cell.h"
#include <SDL3/SDL.h>
#include "sdl.h"
void SDL_Event_free(JSRuntime *rt, SDL_Event *e)
{
free(e);
}
QJSCLASS(SDL_Event,)
// Internal keymod function for input module
static JSValue js_keymod(JSContext *js)
{
SDL_Keymod modstate = SDL_GetModState();
JS_FRAME(js);
JS_LOCAL(ret, JS_NewObject(js));
if (SDL_KMOD_CTRL & modstate)
JS_SetPropertyStr(js,ret,"ctrl", JS_NewBool(js,1));
if (SDL_KMOD_SHIFT & modstate)
JS_SetPropertyStr(js,ret,"shift", JS_NewBool(js,1));
if (SDL_KMOD_ALT & modstate)
JS_SetPropertyStr(js,ret,"alt", JS_NewBool(js,1));
if (SDL_KMOD_GUI & modstate)
JS_SetPropertyStr(js,ret,"super", JS_NewBool(js,1));
if (SDL_KMOD_NUM & modstate)
JS_SetPropertyStr(js,ret,"numlock", JS_NewBool(js,1));
if (SDL_KMOD_CAPS & modstate)
JS_SetPropertyStr(js,ret,"caps", JS_NewBool(js,1));
if (SDL_KMOD_SCROLL & modstate)
JS_SetPropertyStr(js,ret,"scrolllock", JS_NewBool(js,1));
if (SDL_KMOD_MODE & modstate)
JS_SetPropertyStr(js,ret,"mode", JS_NewBool(js,1));
JS_RETURN(ret);
}
// INPUT FUNCTIONS
JSC_CCALL(input_mouse_lock, SDL_CaptureMouse(JS_ToBool(js,argv[0])))
JSC_CCALL(input_mouse_show,
if (JS_ToBool(js,argv[0]))
SDL_ShowCursor();
else
SDL_HideCursor();
)
JSC_CCALL(input_keyname,
return JS_NewString(js, SDL_GetKeyName(js2number(js,argv[0])));
)
JSC_CCALL(input_keymod,
return js_keymod(js);
)
JSC_CCALL(input_mousestate,
float x,y;
SDL_MouseButtonFlags flags = SDL_GetMouseState(&x,&y);
JS_FRAME(js);
JS_LOCAL(m, JS_NewObject(js));
JS_SetPropertyStr(js,m,"x", number2js(js,x));
JS_SetPropertyStr(js,m,"y", number2js(js,y));
if (flags & SDL_BUTTON_LMASK)
JS_SetPropertyStr(js, m, "left", JS_NewBool(js, 1));
if (flags & SDL_BUTTON_MMASK)
JS_SetPropertyStr(js, m, "middle", JS_NewBool(js, 1));
if (flags & SDL_BUTTON_RMASK)
JS_SetPropertyStr(js, m, "right", JS_NewBool(js, 1));
if (flags & SDL_BUTTON_X1MASK)
JS_SetPropertyStr(js, m, "x1", JS_NewBool(js, 1));
if (flags & SDL_BUTTON_X2MASK)
JS_SetPropertyStr(js, m, "x2", JS_NewBool(js, 1));
JS_RETURN(m);
)
// Event processing functions
const char* event_type_to_string(Uint32 event_type) {
switch (event_type) {
// Application events
case SDL_EVENT_QUIT: return "quit";
case SDL_EVENT_TERMINATING: return "terminating";
case SDL_EVENT_LOW_MEMORY: return "low_memory";
case SDL_EVENT_WILL_ENTER_BACKGROUND: return "will_enter_background";
case SDL_EVENT_DID_ENTER_BACKGROUND: return "did_enter_background";
case SDL_EVENT_WILL_ENTER_FOREGROUND: return "will_enter_foreground";
case SDL_EVENT_DID_ENTER_FOREGROUND: return "did_enter_foreground";
case SDL_EVENT_LOCALE_CHANGED: return "locale_changed";
case SDL_EVENT_SYSTEM_THEME_CHANGED: return "system_theme_changed";
// Display events
case SDL_EVENT_DISPLAY_ORIENTATION: return "display_orientation";
case SDL_EVENT_DISPLAY_ADDED: return "display_added";
case SDL_EVENT_DISPLAY_REMOVED: return "display_removed";
case SDL_EVENT_DISPLAY_MOVED: return "display_moved";
case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED: return "display_desktop_mode_changed";
case SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED: return "display_current_mode_changed";
case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED: return "display_content_scale_changed";
// Window events
case SDL_EVENT_WINDOW_SHOWN: return "window_shown";
case SDL_EVENT_WINDOW_HIDDEN: return "window_hidden";
case SDL_EVENT_WINDOW_EXPOSED: return "window_exposed";
case SDL_EVENT_WINDOW_MOVED: return "window_moved";
case SDL_EVENT_WINDOW_RESIZED: return "window_resized";
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: return "window_pixel_size_changed";
case SDL_EVENT_WINDOW_METAL_VIEW_RESIZED: return "window_metal_view_resized";
case SDL_EVENT_WINDOW_MINIMIZED: return "window_minimized";
case SDL_EVENT_WINDOW_MAXIMIZED: return "window_maximized";
case SDL_EVENT_WINDOW_RESTORED: return "window_restored";
case SDL_EVENT_WINDOW_MOUSE_ENTER: return "window_mouse_enter";
case SDL_EVENT_WINDOW_MOUSE_LEAVE: return "window_mouse_leave";
case SDL_EVENT_WINDOW_FOCUS_GAINED: return "window_focus_gained";
case SDL_EVENT_WINDOW_FOCUS_LOST: return "window_focus_lost";
case SDL_EVENT_WINDOW_CLOSE_REQUESTED: return "window_close_requested";
case SDL_EVENT_WINDOW_HIT_TEST: return "window_hit_test";
case SDL_EVENT_WINDOW_ICCPROF_CHANGED: return "window_iccprof_changed";
case SDL_EVENT_WINDOW_DISPLAY_CHANGED: return "window_display_changed";
case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED: return "window_display_scale_changed";
case SDL_EVENT_WINDOW_SAFE_AREA_CHANGED: return "window_safe_area_changed";
case SDL_EVENT_WINDOW_OCCLUDED: return "window_occluded";
case SDL_EVENT_WINDOW_ENTER_FULLSCREEN: return "window_enter_fullscreen";
case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN: return "window_leave_fullscreen";
case SDL_EVENT_WINDOW_DESTROYED: return "window_destroyed";
case SDL_EVENT_WINDOW_HDR_STATE_CHANGED: return "window_hdr_state_changed";
// Keyboard events
case SDL_EVENT_KEY_DOWN: return "key_down";
case SDL_EVENT_KEY_UP: return "key_up";
case SDL_EVENT_TEXT_EDITING: return "text_editing";
case SDL_EVENT_TEXT_INPUT: return "text_input";
case SDL_EVENT_KEYMAP_CHANGED: return "keymap_changed";
case SDL_EVENT_KEYBOARD_ADDED: return "keyboard_added";
case SDL_EVENT_KEYBOARD_REMOVED: return "keyboard_removed";
case SDL_EVENT_TEXT_EDITING_CANDIDATES: return "text_editing_candidates";
// Mouse events
case SDL_EVENT_MOUSE_MOTION: return "mouse_motion";
case SDL_EVENT_MOUSE_BUTTON_DOWN: return "mouse_button_down";
case SDL_EVENT_MOUSE_BUTTON_UP: return "mouse_button_up";
case SDL_EVENT_MOUSE_WHEEL: return "mouse_wheel";
case SDL_EVENT_MOUSE_ADDED: return "mouse_added";
case SDL_EVENT_MOUSE_REMOVED: return "mouse_removed";
// Joystick events
case SDL_EVENT_JOYSTICK_AXIS_MOTION: return "joystick_axis_motion";
case SDL_EVENT_JOYSTICK_BALL_MOTION: return "joystick_ball_motion";
case SDL_EVENT_JOYSTICK_HAT_MOTION: return "joystick_hat_motion";
case SDL_EVENT_JOYSTICK_BUTTON_DOWN: return "joystick_button_down";
case SDL_EVENT_JOYSTICK_BUTTON_UP: return "joystick_button_up";
case SDL_EVENT_JOYSTICK_ADDED: return "joystick_added";
case SDL_EVENT_JOYSTICK_REMOVED: return "joystick_removed";
case SDL_EVENT_JOYSTICK_BATTERY_UPDATED: return "joystick_battery_updated";
case SDL_EVENT_JOYSTICK_UPDATE_COMPLETE: return "joystick_update_complete";
// Gamepad events
case SDL_EVENT_GAMEPAD_AXIS_MOTION: return "gamepad_axis_motion";
case SDL_EVENT_GAMEPAD_BUTTON_DOWN: return "gamepad_button_down";
case SDL_EVENT_GAMEPAD_BUTTON_UP: return "gamepad_button_up";
case SDL_EVENT_GAMEPAD_ADDED: return "gamepad_added";
case SDL_EVENT_GAMEPAD_REMOVED: return "gamepad_removed";
case SDL_EVENT_GAMEPAD_REMAPPED: return "gamepad_remapped";
case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN: return "gamepad_touchpad_down";
case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION: return "gamepad_touchpad_motion";
case SDL_EVENT_GAMEPAD_TOUCHPAD_UP: return "gamepad_touchpad_up";
case SDL_EVENT_GAMEPAD_SENSOR_UPDATE: return "gamepad_sensor_update";
case SDL_EVENT_GAMEPAD_UPDATE_COMPLETE: return "gamepad_update_complete";
case SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED: return "gamepad_steam_handle_updated";
// Touch events
case SDL_EVENT_FINGER_DOWN: return "finger_down";
case SDL_EVENT_FINGER_UP: return "finger_up";
case SDL_EVENT_FINGER_MOTION: return "finger_motion";
// Clipboard events
case SDL_EVENT_CLIPBOARD_UPDATE: return "clipboard_update";
// Drag and drop events
case SDL_EVENT_DROP_FILE: return "drop_file";
case SDL_EVENT_DROP_TEXT: return "drop_text";
case SDL_EVENT_DROP_BEGIN: return "drop_begin";
case SDL_EVENT_DROP_COMPLETE: return "drop_complete";
case SDL_EVENT_DROP_POSITION: return "drop_position";
// Audio device events
case SDL_EVENT_AUDIO_DEVICE_ADDED: return "audio_device_added";
case SDL_EVENT_AUDIO_DEVICE_REMOVED: return "audio_device_removed";
case SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED: return "audio_device_format_changed";
// Sensor events
case SDL_EVENT_SENSOR_UPDATE: return "sensor_update";
// Pen events
case SDL_EVENT_PEN_PROXIMITY_IN: return "pen_proximity_in";
case SDL_EVENT_PEN_PROXIMITY_OUT: return "pen_proximity_out";
case SDL_EVENT_PEN_DOWN: return "pen_down";
case SDL_EVENT_PEN_UP: return "pen_up";
case SDL_EVENT_PEN_BUTTON_DOWN: return "pen_button_down";
case SDL_EVENT_PEN_BUTTON_UP: return "pen_button_up";
case SDL_EVENT_PEN_MOTION: return "pen_motion";
case SDL_EVENT_PEN_AXIS: return "pen_axis";
// Camera events
case SDL_EVENT_CAMERA_DEVICE_ADDED: return "camera_device_added";
case SDL_EVENT_CAMERA_DEVICE_REMOVED: return "camera_device_removed";
case SDL_EVENT_CAMERA_DEVICE_APPROVED: return "camera_device_approved";
case SDL_EVENT_CAMERA_DEVICE_DENIED: return "camera_device_denied";
// Render events
case SDL_EVENT_RENDER_TARGETS_RESET: return "render_targets_reset";
case SDL_EVENT_RENDER_DEVICE_RESET: return "render_device_reset";
case SDL_EVENT_RENDER_DEVICE_LOST: return "render_device_lost";
// User event (assuming it should be included)
case SDL_EVENT_USER: return "user";
default: return "unknown";
}
}
const char* mouse_button_to_string(int mouse) {
switch (mouse) {
case SDL_BUTTON_LEFT: return "left";
case SDL_BUTTON_MIDDLE: return "middle";
case SDL_BUTTON_RIGHT: return "right";
case SDL_BUTTON_X1: return "x1";
case SDL_BUTTON_X2: return "x2";
default: return "left";
}
}
static JSValue js_vec2(JSContext *js, double x, double y) {
JS_FRAME(js);
JS_LOCAL(arr, JS_NewArray(js));
JS_SetPropertyNumber(js, arr, 0, number2js(js, x));
JS_SetPropertyNumber(js, arr, 1, number2js(js, y));
JS_RETURN(arr);
}
static JSValue event2js(JSContext *js, const SDL_Event *e) {
JS_FRAME(js);
JS_LOCAL(obj, JS_NewObject(js));
JSValue tmp;
tmp = JS_NewString(js, event_type_to_string(e->type));
JS_SetPropertyStr(js, obj, "type", tmp);
JS_SetPropertyStr(js, obj, "timestamp",
number2js(js, (double)e->common.timestamp));
switch (e->type) {
case SDL_EVENT_AUDIO_DEVICE_ADDED:
case SDL_EVENT_AUDIO_DEVICE_REMOVED:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->adevice.which));
JS_SetPropertyStr(js, obj, "recording",
JS_NewBool(js, e->adevice.recording));
break;
case SDL_EVENT_DISPLAY_ORIENTATION:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->display.displayID));
JS_SetPropertyStr(js, obj, "orientation",
number2js(js, (double)e->display.data1));
JS_SetPropertyStr(js, obj, "data2",
number2js(js, (double)e->display.data2));
break;
case SDL_EVENT_DISPLAY_ADDED:
case SDL_EVENT_DISPLAY_REMOVED:
case SDL_EVENT_DISPLAY_MOVED:
case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED:
case SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED:
case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->display.displayID));
JS_SetPropertyStr(js, obj, "data1",
number2js(js, (double)e->display.data1));
JS_SetPropertyStr(js, obj, "data2",
number2js(js, (double)e->display.data2));
break;
case SDL_EVENT_MOUSE_MOTION:
JS_SetPropertyStr(js, obj, "window",
number2js(js, (double)e->motion.windowID));
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->motion.which));
JS_SetPropertyStr(js, obj, "state",
number2js(js, (double)e->motion.state));
tmp = js_vec2(js, (double)e->motion.x, (double)e->motion.y);
JS_SetPropertyStr(js, obj, "pos", tmp);
tmp = js_vec2(js, (double)e->motion.xrel, (double)e->motion.yrel);
JS_SetPropertyStr(js, obj, "d_pos", tmp);
break;
case SDL_EVENT_MOUSE_WHEEL:
JS_SetPropertyStr(js, obj, "window",
number2js(js, (double)e->wheel.windowID));
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->wheel.which));
tmp = js_vec2(js, (double)e->wheel.x, (double)e->wheel.y);
JS_SetPropertyStr(js, obj, "scroll", tmp);
tmp = js_vec2(js, (double)e->wheel.mouse_x, (double)e->wheel.mouse_y);
JS_SetPropertyStr(js, obj, "pos", tmp);
break;
case SDL_EVENT_MOUSE_BUTTON_UP:
case SDL_EVENT_MOUSE_BUTTON_DOWN:
JS_SetPropertyStr(js, obj, "window",
number2js(js, (double)e->button.windowID));
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->button.which));
JS_SetPropertyStr(js, obj, "down",
JS_NewBool(js, e->button.down));
tmp = JS_NewString(js, mouse_button_to_string(e->button.button));
JS_SetPropertyStr(js, obj, "button", tmp);
JS_SetPropertyStr(js, obj, "clicks",
number2js(js, (double)e->button.clicks));
tmp = js_vec2(js, (double)e->button.x, (double)e->button.y);
JS_SetPropertyStr(js, obj, "pos", tmp);
break;
case SDL_EVENT_SENSOR_UPDATE:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->sensor.which));
JS_SetPropertyStr(js, obj, "sensor_timestamp",
number2js(js, (double)e->sensor.sensor_timestamp));
break;
case SDL_EVENT_KEY_DOWN:
case SDL_EVENT_KEY_UP:
JS_SetPropertyStr(js, obj, "window",
number2js(js, (double)e->key.windowID));
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->key.which));
JS_SetPropertyStr(js, obj, "down",
JS_NewBool(js, e->key.down));
JS_SetPropertyStr(js, obj, "repeat",
JS_NewBool(js, e->key.repeat));
JS_SetPropertyStr(js, obj, "key",
number2js(js, (double)e->key.key));
JS_SetPropertyStr(js, obj, "scancode",
number2js(js, (double)e->key.scancode));
JS_SetPropertyStr(js, obj, "mod",
number2js(js, (double)e->key.mod));
break;
case SDL_EVENT_FINGER_MOTION:
case SDL_EVENT_FINGER_DOWN:
case SDL_EVENT_FINGER_UP:
JS_SetPropertyStr(js, obj, "touch",
number2js(js, (double)e->tfinger.touchID));
JS_SetPropertyStr(js, obj, "finger",
number2js(js, (double)e->tfinger.fingerID));
tmp = js_vec2(js, (double)e->tfinger.x, (double)e->tfinger.y);
JS_SetPropertyStr(js, obj, "pos", tmp);
tmp = js_vec2(js, (double)e->tfinger.dx, (double)e->tfinger.dy);
JS_SetPropertyStr(js, obj, "d_pos", tmp);
JS_SetPropertyStr(js, obj, "pressure",
number2js(js, (double)e->tfinger.pressure));
JS_SetPropertyStr(js, obj, "window",
number2js(js, (double)e->key.windowID));
break;
case SDL_EVENT_DROP_BEGIN:
case SDL_EVENT_DROP_FILE:
case SDL_EVENT_DROP_TEXT:
case SDL_EVENT_DROP_COMPLETE:
case SDL_EVENT_DROP_POSITION:
JS_SetPropertyStr(js, obj, "window",
number2js(js, (double)e->drop.windowID));
tmp = js_vec2(js, (double)e->drop.x, (double)e->drop.y);
JS_SetPropertyStr(js, obj, "pos", tmp);
tmp = JS_NewString(js, e->drop.data ? e->drop.data : "");
JS_SetPropertyStr(js, obj, "data", tmp);
tmp = JS_NewString(js, e->drop.source ? e->drop.source : "");
JS_SetPropertyStr(js, obj, "source", tmp);
break;
case SDL_EVENT_TEXT_INPUT:
JS_SetPropertyStr(js, obj, "window",
number2js(js, (double)e->text.windowID));
tmp = JS_NewString(js, e->text.text);
JS_SetPropertyStr(js, obj, "text", tmp);
JS_SetPropertyStr(js, obj, "mod", number2js(js, 0));
break;
case SDL_EVENT_CAMERA_DEVICE_APPROVED:
case SDL_EVENT_CAMERA_DEVICE_REMOVED:
case SDL_EVENT_CAMERA_DEVICE_ADDED:
case SDL_EVENT_CAMERA_DEVICE_DENIED:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->cdevice.which));
break;
case SDL_EVENT_CLIPBOARD_UPDATE:
JS_SetPropertyStr(js, obj, "owner",
JS_NewBool(js, e->clipboard.owner));
break;
case SDL_EVENT_WINDOW_EXPOSED:
case SDL_EVENT_WINDOW_FOCUS_GAINED:
case SDL_EVENT_WINDOW_FOCUS_LOST:
case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->window.windowID));
break;
case SDL_EVENT_WINDOW_SHOWN:
case SDL_EVENT_WINDOW_HIDDEN:
case SDL_EVENT_WINDOW_MINIMIZED:
case SDL_EVENT_WINDOW_MAXIMIZED:
case SDL_EVENT_WINDOW_RESTORED:
case SDL_EVENT_WINDOW_MOUSE_ENTER:
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
case SDL_EVENT_WINDOW_HIT_TEST:
case SDL_EVENT_WINDOW_ICCPROF_CHANGED:
case SDL_EVENT_WINDOW_OCCLUDED:
case SDL_EVENT_WINDOW_ENTER_FULLSCREEN:
case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN:
case SDL_EVENT_WINDOW_DESTROYED:
case SDL_EVENT_WINDOW_HDR_STATE_CHANGED:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->window.windowID));
JS_SetPropertyStr(js, obj, "data1",
number2js(js, (double)e->window.data1));
JS_SetPropertyStr(js, obj, "data2",
number2js(js, (double)e->window.data2));
break;
case SDL_EVENT_WINDOW_SAFE_AREA_CHANGED: {
SDL_Window *window = SDL_GetWindowFromID(e->window.windowID);
SDL_Rect safe_area = {0, 0, 0, 0};
if (window && SDL_GetWindowSafeArea(window, &safe_area)) {
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->window.windowID));
JS_SetPropertyStr(js, obj, "x",
number2js(js, (double)safe_area.x));
JS_SetPropertyStr(js, obj, "y",
number2js(js, (double)safe_area.y));
JS_SetPropertyStr(js, obj, "width",
number2js(js, (double)safe_area.w));
JS_SetPropertyStr(js, obj, "height",
number2js(js, (double)safe_area.h));
} else {
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->window.windowID));
JS_SetPropertyStr(js, obj, "data1",
number2js(js, (double)e->window.data1));
JS_SetPropertyStr(js, obj, "data2",
number2js(js, (double)e->window.data2));
}
break;
}
case SDL_EVENT_WINDOW_MOVED:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->window.windowID));
JS_SetPropertyStr(js, obj, "x",
number2js(js, (double)e->window.data1));
JS_SetPropertyStr(js, obj, "y",
number2js(js, (double)e->window.data2));
break;
case SDL_EVENT_WINDOW_RESIZED:
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
case SDL_EVENT_WINDOW_METAL_VIEW_RESIZED:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->window.windowID));
JS_SetPropertyStr(js, obj, "width",
number2js(js, (double)e->window.data1));
JS_SetPropertyStr(js, obj, "height",
number2js(js, (double)e->window.data2));
break;
case SDL_EVENT_WINDOW_DISPLAY_CHANGED:
case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->window.windowID));
JS_SetPropertyStr(js, obj, "display_index",
number2js(js, (double)e->window.data1));
JS_SetPropertyStr(js, obj, "data2",
number2js(js, (double)e->window.data2));
break;
case SDL_EVENT_JOYSTICK_ADDED:
case SDL_EVENT_JOYSTICK_REMOVED:
case SDL_EVENT_JOYSTICK_UPDATE_COMPLETE:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->jdevice.which));
break;
case SDL_EVENT_JOYSTICK_AXIS_MOTION:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->jaxis.which));
JS_SetPropertyStr(js, obj, "axis",
number2js(js, (double)e->jaxis.axis));
JS_SetPropertyStr(js, obj, "value",
number2js(js, (double)e->jaxis.value));
break;
case SDL_EVENT_JOYSTICK_BALL_MOTION:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->jball.which));
JS_SetPropertyStr(js, obj, "ball",
number2js(js, (double)e->jball.ball));
tmp = js_vec2(js, (double)e->jball.xrel, (double)e->jball.yrel);
JS_SetPropertyStr(js, obj, "rel", tmp);
break;
case SDL_EVENT_JOYSTICK_BUTTON_DOWN:
case SDL_EVENT_JOYSTICK_BUTTON_UP:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->jbutton.which));
JS_SetPropertyStr(js, obj, "button",
number2js(js, (double)e->jbutton.button));
JS_SetPropertyStr(js, obj, "down",
JS_NewBool(js, e->jbutton.down));
break;
case SDL_EVENT_GAMEPAD_ADDED:
case SDL_EVENT_GAMEPAD_REMOVED:
case SDL_EVENT_GAMEPAD_REMAPPED:
case SDL_EVENT_GAMEPAD_UPDATE_COMPLETE:
case SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->gdevice.which));
break;
case SDL_EVENT_GAMEPAD_AXIS_MOTION: {
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->gaxis.which));
tmp = JS_NewString(js, SDL_GetGamepadStringForAxis(e->gaxis.axis));
JS_SetPropertyStr(js, obj, "axis", tmp);
double normalized_value = (double)e->gaxis.value / 32767.0;
JS_SetPropertyStr(js, obj, "value",
number2js(js, normalized_value));
break;
}
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
case SDL_EVENT_GAMEPAD_BUTTON_UP:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->gbutton.which));
tmp = JS_NewString(js, SDL_GetGamepadStringForButton(e->gbutton.button));
JS_SetPropertyStr(js, obj, "button", tmp);
JS_SetPropertyStr(js, obj, "down",
JS_NewBool(js, e->gbutton.down));
break;
case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN:
case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION:
case SDL_EVENT_GAMEPAD_TOUCHPAD_UP:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->gtouchpad.which));
JS_SetPropertyStr(js, obj, "touchpad",
number2js(js, (double)e->gtouchpad.touchpad));
JS_SetPropertyStr(js, obj, "finger",
number2js(js, (double)e->gtouchpad.finger));
tmp = js_vec2(js, (double)e->gtouchpad.x, (double)e->gtouchpad.y);
JS_SetPropertyStr(js, obj, "pos", tmp);
JS_SetPropertyStr(js, obj, "pressure",
number2js(js, (double)e->gtouchpad.pressure));
break;
case SDL_EVENT_GAMEPAD_SENSOR_UPDATE:
JS_SetPropertyStr(js, obj, "which",
number2js(js, (double)e->gsensor.which));
JS_SetPropertyStr(js, obj, "sensor",
number2js(js, (double)e->gsensor.sensor));
JS_SetPropertyStr(js, obj, "sensor_timestamp",
number2js(js, (double)e->gsensor.sensor_timestamp));
break;
case SDL_EVENT_USER:
JS_SetPropertyStr(js, obj, "cb",
number2js(js, (double)(uintptr_t)e->user.data1));
break;
}
JS_RETURN(obj);
}
// Get all events directly from SDL event queue
JSC_CCALL(input_get_events,
JS_FRAME(js);
JS_LOCAL(events_array, JS_NewArray(js));
SDL_Event event;
int event_count = 0;
while (SDL_PollEvent(&event)) {
SDL_Event *e = (SDL_Event *)malloc(sizeof(SDL_Event));
memcpy(e, &event, sizeof(SDL_Event));
JS_SetPropertyNumber(js, events_array, event_count, SDL_Event2js(js, e));
event_count++;
}
JS_RETURN(events_array);
)
JSC_CCALL(input_objectify,
SDL_Event *e = js2SDL_Event(js, argv[0]);
if (!e) return JS_ThrowTypeError(js, "Expected SDL_Event object");
return event2js(js, e);
)
JSC_CCALL(input_gamepad_id_to_type,
int id = js2number(js, argv[0]);
return JS_NewString(js, SDL_GetGamepadStringForType(SDL_GetGamepadTypeForID(id)));
)
static const JSCFunctionListEntry js_input_funcs[] = {
MIST_FUNC_DEF(input, mouse_show, 1),
MIST_FUNC_DEF(input, mouse_lock, 1),
MIST_FUNC_DEF(input, keyname, 1),
MIST_FUNC_DEF(input, keymod, 0),
MIST_FUNC_DEF(input, mousestate, 0),
MIST_FUNC_DEF(input, get_events, 0),
MIST_FUNC_DEF(input, objectify, 1),
MIST_FUNC_DEF(input, gamepad_id_to_type, 1),
};
CELL_USE_INIT(
QJSCLASSPREP_NO_FUNCS(SDL_Event);
JS_FRAME(js);
JS_LOCAL(mod, JS_NewObject(js));
JS_SetPropertyFunctionList(js, mod, js_input_funcs, countof(js_input_funcs));
JS_RETURN(mod);
)