mirror of
https://github.com/libretro/RetroArch
synced 2025-03-05 19:13:45 +00:00
emscripten: recreate input event listeners properly
There's a new (undocumented -_-) API for removing event listeners in emscripten now, so use that when recreating input listeners. Fixes mouse events breaking when loading cores.
This commit is contained in:
parent
142503d3b5
commit
14c67fde7f
@ -63,9 +63,13 @@ typedef struct rwebinput_mouse_states
|
||||
{
|
||||
signed x;
|
||||
signed y;
|
||||
signed pending_delta_x;
|
||||
signed pending_delta_y;
|
||||
signed delta_x;
|
||||
signed delta_y;
|
||||
uint8_t buttons;
|
||||
double pending_scroll_x;
|
||||
double pending_scroll_y;
|
||||
double scroll_x;
|
||||
double scroll_y;
|
||||
} rwebinput_mouse_state_t;
|
||||
@ -74,6 +78,7 @@ typedef struct rwebinput_input
|
||||
{
|
||||
bool keys[RETROK_LAST];
|
||||
rwebinput_mouse_state_t mouse;
|
||||
rwebinput_keyboard_event_queue_t keyboard;
|
||||
const input_device_driver_t *joypad;
|
||||
} rwebinput_input_t;
|
||||
|
||||
@ -194,10 +199,6 @@ static const rwebinput_key_to_code_map_entry_t rwebinput_key_to_code_map[] =
|
||||
{ "Power", RETROK_POWER },
|
||||
};
|
||||
|
||||
static bool g_rwebinput_initialized;
|
||||
static rwebinput_keyboard_event_queue_t *g_rwebinput_keyboard;
|
||||
static rwebinput_mouse_state_t *g_rwebinput_mouse;
|
||||
|
||||
/* to make the string labels for codes from JavaScript work, we convert them
|
||||
* to CRC32 hashes for the LUT */
|
||||
static void rwebinput_generate_lut(void)
|
||||
@ -237,22 +238,24 @@ static void rwebinput_generate_lut(void)
|
||||
static EM_BOOL rwebinput_keyboard_cb(int event_type,
|
||||
const EmscriptenKeyboardEvent *key_event, void *user_data)
|
||||
{
|
||||
rwebinput_input_t *rwebinput = (rwebinput_input_t*)user_data;
|
||||
|
||||
if (event_type == EMSCRIPTEN_EVENT_KEYPRESS)
|
||||
return EM_TRUE;
|
||||
|
||||
if (g_rwebinput_keyboard->count >= g_rwebinput_keyboard->max_size)
|
||||
if (rwebinput->keyboard.count >= rwebinput->keyboard.max_size)
|
||||
{
|
||||
size_t new_max = MAX(1, g_rwebinput_keyboard->max_size << 1);
|
||||
g_rwebinput_keyboard->events = realloc(g_rwebinput_keyboard->events,
|
||||
new_max * sizeof(g_rwebinput_keyboard->events[0]));
|
||||
retro_assert(g_rwebinput_keyboard->events != NULL);
|
||||
g_rwebinput_keyboard->max_size = new_max;
|
||||
size_t new_max = MAX(1, rwebinput->keyboard.max_size << 1);
|
||||
rwebinput->keyboard.events = realloc(rwebinput->keyboard.events,
|
||||
new_max * sizeof(rwebinput->keyboard.events[0]));
|
||||
retro_assert(rwebinput->keyboard.events != NULL);
|
||||
rwebinput->keyboard.max_size = new_max;
|
||||
}
|
||||
|
||||
g_rwebinput_keyboard->events[g_rwebinput_keyboard->count].type = event_type;
|
||||
memcpy(&g_rwebinput_keyboard->events[g_rwebinput_keyboard->count].event,
|
||||
rwebinput->keyboard.events[rwebinput->keyboard.count].type = event_type;
|
||||
memcpy(&rwebinput->keyboard.events[rwebinput->keyboard.count].event,
|
||||
key_event, sizeof(*key_event));
|
||||
g_rwebinput_keyboard->count++;
|
||||
rwebinput->keyboard.count++;
|
||||
|
||||
return EM_TRUE;
|
||||
}
|
||||
@ -260,22 +263,22 @@ static EM_BOOL rwebinput_keyboard_cb(int event_type,
|
||||
static EM_BOOL rwebinput_mouse_cb(int event_type,
|
||||
const EmscriptenMouseEvent *mouse_event, void *user_data)
|
||||
{
|
||||
(void)user_data;
|
||||
rwebinput_input_t *rwebinput = (rwebinput_input_t*)user_data;
|
||||
|
||||
uint8_t mask = 1 << mouse_event->button;
|
||||
|
||||
g_rwebinput_mouse->x = mouse_event->targetX;
|
||||
g_rwebinput_mouse->y = mouse_event->targetY;
|
||||
g_rwebinput_mouse->delta_x += mouse_event->movementX;
|
||||
g_rwebinput_mouse->delta_y += mouse_event->movementY;
|
||||
rwebinput->mouse.x = mouse_event->targetX;
|
||||
rwebinput->mouse.y = mouse_event->targetY;
|
||||
rwebinput->mouse.pending_delta_x += mouse_event->movementX;
|
||||
rwebinput->mouse.pending_delta_y += mouse_event->movementY;
|
||||
|
||||
if (event_type == EMSCRIPTEN_EVENT_MOUSEDOWN)
|
||||
{
|
||||
g_rwebinput_mouse->buttons |= mask;
|
||||
rwebinput->mouse.buttons |= mask;
|
||||
}
|
||||
else if (event_type == EMSCRIPTEN_EVENT_MOUSEUP)
|
||||
{
|
||||
g_rwebinput_mouse->buttons &= ~mask;
|
||||
rwebinput->mouse.buttons &= ~mask;
|
||||
}
|
||||
|
||||
return EM_TRUE;
|
||||
@ -284,91 +287,80 @@ static EM_BOOL rwebinput_mouse_cb(int event_type,
|
||||
static EM_BOOL rwebinput_wheel_cb(int event_type,
|
||||
const EmscriptenWheelEvent *wheel_event, void *user_data)
|
||||
{
|
||||
rwebinput_input_t *rwebinput = (rwebinput_input_t*)user_data;
|
||||
(void)event_type;
|
||||
(void)user_data;
|
||||
|
||||
g_rwebinput_mouse->scroll_x += wheel_event->deltaX;
|
||||
g_rwebinput_mouse->scroll_y += wheel_event->deltaY;
|
||||
rwebinput->mouse.pending_scroll_x += wheel_event->deltaX;
|
||||
rwebinput->mouse.pending_scroll_y += wheel_event->deltaY;
|
||||
|
||||
return EM_TRUE;
|
||||
}
|
||||
|
||||
static void *rwebinput_input_init(const char *joypad_driver)
|
||||
{
|
||||
EMSCRIPTEN_RESULT r;
|
||||
rwebinput_input_t *rwebinput =
|
||||
(rwebinput_input_t*)calloc(1, sizeof(*rwebinput));
|
||||
g_rwebinput_keyboard = (rwebinput_keyboard_event_queue_t*)
|
||||
calloc(1, sizeof(rwebinput_keyboard_event_queue_t));
|
||||
g_rwebinput_mouse = (rwebinput_mouse_state_t*)
|
||||
calloc(1, sizeof(rwebinput_mouse_state_t));
|
||||
|
||||
if (!rwebinput || !g_rwebinput_keyboard || !g_rwebinput_mouse)
|
||||
if (!rwebinput)
|
||||
goto error;
|
||||
|
||||
if (!g_rwebinput_initialized)
|
||||
rwebinput_generate_lut();
|
||||
|
||||
r = emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, rwebinput, false,
|
||||
rwebinput_keyboard_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
EMSCRIPTEN_RESULT r;
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/INPUT] failed to create keydown callback: %d\n", r);
|
||||
}
|
||||
|
||||
g_rwebinput_initialized = true;
|
||||
rwebinput_generate_lut();
|
||||
r = emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, rwebinput, false,
|
||||
rwebinput_keyboard_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/INPUT] failed to create keydown callback: %d\n", r);
|
||||
}
|
||||
|
||||
/* emscripten currently doesn't have an API to remove handlers, so make
|
||||
* once and reuse it */
|
||||
r = emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, false,
|
||||
rwebinput_keyboard_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/INPUT] failed to create keydown callback: %d\n", r);
|
||||
}
|
||||
r = emscripten_set_keypress_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, rwebinput, false,
|
||||
rwebinput_keyboard_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/INPUT] failed to create keypress callback: %d\n", r);
|
||||
}
|
||||
|
||||
r = emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, false,
|
||||
rwebinput_keyboard_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/INPUT] failed to create keydown callback: %d\n", r);
|
||||
}
|
||||
r = emscripten_set_mousedown_callback("#canvas", rwebinput, false,
|
||||
rwebinput_mouse_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/INPUT] failed to create mousedown callback: %d\n", r);
|
||||
}
|
||||
|
||||
r = emscripten_set_keypress_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, false,
|
||||
rwebinput_keyboard_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/INPUT] failed to create keypress callback: %d\n", r);
|
||||
}
|
||||
r = emscripten_set_mouseup_callback("#canvas", rwebinput, false,
|
||||
rwebinput_mouse_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/INPUT] failed to create mouseup callback: %d\n", r);
|
||||
}
|
||||
|
||||
r = emscripten_set_mousedown_callback("#canvas", NULL, false,
|
||||
rwebinput_mouse_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/INPUT] failed to create mousedown callback: %d\n", r);
|
||||
}
|
||||
r = emscripten_set_mousemove_callback("#canvas", rwebinput, false,
|
||||
rwebinput_mouse_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/INPUT] failed to create mousemove callback: %d\n", r);
|
||||
}
|
||||
|
||||
r = emscripten_set_mouseup_callback("#canvas", NULL, false,
|
||||
rwebinput_mouse_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/INPUT] failed to create mouseup callback: %d\n", r);
|
||||
}
|
||||
|
||||
r = emscripten_set_mousemove_callback("#canvas", NULL, false,
|
||||
rwebinput_mouse_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/INPUT] failed to create mousemove callback: %d\n", r);
|
||||
}
|
||||
|
||||
r = emscripten_set_wheel_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, false,
|
||||
rwebinput_wheel_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/INPUT] failed to create wheel callback: %d\n", r);
|
||||
}
|
||||
r = emscripten_set_wheel_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, rwebinput, false,
|
||||
rwebinput_wheel_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/INPUT] failed to create wheel callback: %d\n", r);
|
||||
}
|
||||
|
||||
input_keymaps_init_keyboard_lut(rarch_key_map_rwebinput);
|
||||
@ -378,8 +370,6 @@ static void *rwebinput_input_init(const char *joypad_driver)
|
||||
return rwebinput;
|
||||
|
||||
error:
|
||||
free(g_rwebinput_keyboard);
|
||||
free(g_rwebinput_mouse);
|
||||
free(rwebinput);
|
||||
return NULL;
|
||||
}
|
||||
@ -526,7 +516,7 @@ static int16_t rwebinput_input_state(void *data,
|
||||
const struct retro_keybind **binds,
|
||||
unsigned port, unsigned device, unsigned idx, unsigned id)
|
||||
{
|
||||
rwebinput_input_t *rwebinput = (rwebinput_input_t*)data;
|
||||
rwebinput_input_t *rwebinput = (rwebinput_input_t*)data;
|
||||
|
||||
switch (device)
|
||||
{
|
||||
@ -584,14 +574,15 @@ static void rwebinput_input_free(void *data)
|
||||
{
|
||||
rwebinput_input_t *rwebinput = (rwebinput_input_t*)data;
|
||||
|
||||
if (g_rwebinput_keyboard)
|
||||
free(g_rwebinput_keyboard->events);
|
||||
free(g_rwebinput_keyboard);
|
||||
g_rwebinput_keyboard = NULL;
|
||||
free(g_rwebinput_mouse);
|
||||
g_rwebinput_mouse = NULL;
|
||||
emscripten_html5_remove_all_event_listeners();
|
||||
|
||||
if (rwebinput->joypad)
|
||||
rwebinput->joypad->destroy();
|
||||
|
||||
free(rwebinput->keyboard.events);
|
||||
free(rwebinput);
|
||||
}
|
||||
|
||||
static void rwebinput_process_keyboard_events(rwebinput_input_t *rwebinput,
|
||||
rwebinput_keyboard_event_t *event)
|
||||
{
|
||||
@ -644,14 +635,20 @@ static void rwebinput_input_poll(void *data)
|
||||
size_t i;
|
||||
rwebinput_input_t *rwebinput = (rwebinput_input_t*)data;
|
||||
|
||||
for (i = 0; i < g_rwebinput_keyboard->count; i++)
|
||||
for (i = 0; i < rwebinput->keyboard.count; i++)
|
||||
rwebinput_process_keyboard_events(rwebinput,
|
||||
&g_rwebinput_keyboard->events[i]);
|
||||
g_rwebinput_keyboard->count = 0;
|
||||
&rwebinput->keyboard.events[i]);
|
||||
rwebinput->keyboard.count = 0;
|
||||
|
||||
memcpy(&rwebinput->mouse, g_rwebinput_mouse, sizeof(*g_rwebinput_mouse));
|
||||
g_rwebinput_mouse->delta_x = g_rwebinput_mouse->delta_y = 0;
|
||||
g_rwebinput_mouse->scroll_x = g_rwebinput_mouse->scroll_y = 0.0;
|
||||
rwebinput->mouse.delta_x = rwebinput->mouse.pending_delta_x;
|
||||
rwebinput->mouse.delta_y = rwebinput->mouse.pending_delta_y;
|
||||
rwebinput->mouse.pending_delta_x = 0;
|
||||
rwebinput->mouse.pending_delta_y = 0;
|
||||
|
||||
rwebinput->mouse.scroll_x = rwebinput->mouse.pending_scroll_x;
|
||||
rwebinput->mouse.scroll_y = rwebinput->mouse.pending_scroll_y;
|
||||
rwebinput->mouse.pending_scroll_x = 0;
|
||||
rwebinput->mouse.pending_scroll_y = 0;
|
||||
|
||||
if (rwebinput->joypad)
|
||||
rwebinput->joypad->poll();
|
||||
|
@ -27,8 +27,6 @@
|
||||
|
||||
#define CLAMPDOUBLE(x) MIN(1.0, MAX(-1.0, (x)))
|
||||
|
||||
static bool g_rwebpad_initialized;
|
||||
|
||||
static EM_BOOL rwebpad_gamepad_cb(int event_type,
|
||||
const EmscriptenGamepadEvent *gamepad_event, void *user_data)
|
||||
{
|
||||
@ -64,34 +62,28 @@ static EM_BOOL rwebpad_gamepad_cb(int event_type,
|
||||
|
||||
static bool rwebpad_joypad_init(void *data)
|
||||
{
|
||||
EMSCRIPTEN_RESULT supported;
|
||||
EMSCRIPTEN_RESULT r;
|
||||
(void)data;
|
||||
|
||||
supported = emscripten_sample_gamepad_data();
|
||||
if (supported == EMSCRIPTEN_RESULT_NOT_SUPPORTED)
|
||||
r = emscripten_sample_gamepad_data();
|
||||
if (r == EMSCRIPTEN_RESULT_NOT_SUPPORTED)
|
||||
return false;
|
||||
|
||||
if (!g_rwebpad_initialized)
|
||||
/* callbacks needs to be registered for gamepads to connect */
|
||||
r = emscripten_set_gamepadconnected_callback(NULL, false,
|
||||
rwebpad_gamepad_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
EMSCRIPTEN_RESULT r;
|
||||
g_rwebpad_initialized = true;
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/PAD] failed to create connect callback: %d\n", r);
|
||||
}
|
||||
|
||||
/* callbacks needs to be registered for gamepads to connect */
|
||||
r = emscripten_set_gamepadconnected_callback(NULL, false,
|
||||
rwebpad_gamepad_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/PAD] failed to create connect callback: %d\n", r);
|
||||
}
|
||||
|
||||
r = emscripten_set_gamepaddisconnected_callback(NULL, false,
|
||||
rwebpad_gamepad_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/PAD] failed to create disconnect callback: %d\n", r);
|
||||
}
|
||||
r = emscripten_set_gamepaddisconnected_callback(NULL, false,
|
||||
rwebpad_gamepad_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
RARCH_ERR(
|
||||
"[EMSCRIPTEN/PAD] failed to create disconnect callback: %d\n", r);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -50,11 +50,11 @@
|
||||
</button>
|
||||
|
||||
<input class="btn btn-primary disabled" style="display: none" type="file" id="btnRom" name="upload" onclick="document.getElementById('btnAdd').click();" onchange="selectFiles(event.target.files)" multiple />
|
||||
<button class="btn btn-primary disabled tooltip-enable" id="btnMenu" onclick="keyPress(112);" title="Menu toggle" disabled>
|
||||
<button class="btn btn-primary disabled tooltip-enable" id="btnMenu" onclick="keyPress('F1');" title="Menu toggle" disabled>
|
||||
<span class="fa fa-bars" id="btnMenu"></span> <span class="sr-only">Menu</span>
|
||||
</button>
|
||||
|
||||
<button class="btn btn-primary disabled tooltip-enable" id="btnFullscreen" onclick="Module.requestFullscreen()" title="Fullscreen" disabled>
|
||||
<button class="btn btn-primary disabled tooltip-enable" id="btnFullscreen" onclick="Module.requestFullscreen(false)" title="Fullscreen" disabled>
|
||||
<span class="fa fa-desktop" id="icnAdd"></span> <span class="sr-only">Fullscreen</span>
|
||||
</button>
|
||||
|
||||
|
@ -93,7 +93,7 @@
|
||||
<button class="btn btn-primary disabled tooltip-enable" id="btnMenu" onclick="keyPress('F1');" title="Menu toggle" disabled>
|
||||
<span class="fa fa-bars" id="btnMenu"></span> <span class="sr-only">Menu</span>
|
||||
</button>
|
||||
<button class="btn btn-primary disabled tooltip-enable" id="btnFullscreen" onclick="Module.requestFullscreen()" title="Fullscreen" disabled>
|
||||
<button class="btn btn-primary disabled tooltip-enable" id="btnFullscreen" onclick="Module.requestFullscreen(false)" title="Fullscreen" disabled>
|
||||
<span class="fa fa-desktop" id="icnAdd"></span> <span class="sr-only">Fullscreen</span>
|
||||
</button>
|
||||
</button>
|
||||
|
Loading…
x
Reference in New Issue
Block a user