mirror of
https://github.com/libretro/RetroArch
synced 2025-04-16 17:43:02 +00:00
use emscripten HTML5 API for keyboard events instead of old JS library
This commit is contained in:
parent
161d758b33
commit
1e212b4248
@ -42,7 +42,6 @@ LIBS := -s USE_SDL=2 -s USE_ZLIB=1
|
|||||||
LDFLAGS := -L. --no-heap-copy -s USE_ZLIB=1 -s TOTAL_MEMORY=$(MEMORY) \
|
LDFLAGS := -L. --no-heap-copy -s USE_ZLIB=1 -s TOTAL_MEMORY=$(MEMORY) \
|
||||||
-s EXPORTED_FUNCTIONS="['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_load_state', '_cmd_take_screenshot']" \
|
-s EXPORTED_FUNCTIONS="['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_load_state', '_cmd_take_screenshot']" \
|
||||||
--js-library emscripten/library_rwebaudio.js \
|
--js-library emscripten/library_rwebaudio.js \
|
||||||
--js-library emscripten/library_rwebinput.js \
|
|
||||||
--js-library emscripten/library_rwebcam.js
|
--js-library emscripten/library_rwebcam.js
|
||||||
ifneq ($(PTHREAD), 0)
|
ifneq ($(PTHREAD), 0)
|
||||||
LDFLAGS += -s USE_PTHREADS=$(PTHREAD) -s PTHREAD_POOL_SIZE=2
|
LDFLAGS += -s USE_PTHREADS=$(PTHREAD) -s PTHREAD_POOL_SIZE=2
|
||||||
|
@ -1,143 +0,0 @@
|
|||||||
//"use strict";
|
|
||||||
|
|
||||||
var LibraryRWebInput = {
|
|
||||||
$RI__deps: ['$Browser'],
|
|
||||||
$RI: {
|
|
||||||
temp: null,
|
|
||||||
contexts: [],
|
|
||||||
stateX: 0,
|
|
||||||
stateY: 0,
|
|
||||||
currentX: 0,
|
|
||||||
currentY: 0,
|
|
||||||
|
|
||||||
canvasEventHandler: function(event) {
|
|
||||||
switch (event.type) {
|
|
||||||
case 'mouseup':
|
|
||||||
case 'mousedown':
|
|
||||||
var value;
|
|
||||||
var offset;
|
|
||||||
if (event.button === 0) offset = 40;
|
|
||||||
else if (event.button === 2) offset = 41;
|
|
||||||
else break;
|
|
||||||
if (event.type === 'mouseup') value = 0;
|
|
||||||
else value = 1;
|
|
||||||
for (var i = 0; i < RI.contexts.length; i++) {
|
|
||||||
{{{ makeSetValue('RI.contexts[i].state', 'offset', 'value', 'i8') }}};
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
eventHandler: function(event) {
|
|
||||||
var i;
|
|
||||||
switch (event.type) {
|
|
||||||
case 'mousemove':
|
|
||||||
var x = 0;
|
|
||||||
var y = 0;
|
|
||||||
|
|
||||||
var newX = event['clientX'] - Module.canvas.offsetLeft;
|
|
||||||
var newY = event['clientY'] - Module.canvas.offsetTop;
|
|
||||||
|
|
||||||
if (newX < 0) {
|
|
||||||
newX = 0;
|
|
||||||
x = -Module.canvas.offsetWidth;
|
|
||||||
} else if (newX > Module.canvas.offsetWidth) {
|
|
||||||
newX = Module.canvas.offsetWidth;
|
|
||||||
x = Module.canvas.offsetWidth;
|
|
||||||
} else {
|
|
||||||
x = newX - RI.currentX;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newY < 0) {
|
|
||||||
newY = 0;
|
|
||||||
y = -Module.canvas.offsetHeight;
|
|
||||||
} else if (newY > Module.canvas.offsetHeight) {
|
|
||||||
newY = Module.canvas.offsetHeight;
|
|
||||||
y = Module.canvas.offsetHeight;
|
|
||||||
} else {
|
|
||||||
y = newY - RI.currentY;
|
|
||||||
}
|
|
||||||
|
|
||||||
RI.currentX = newX;
|
|
||||||
RI.currentY = newY;
|
|
||||||
|
|
||||||
for (i = 0; i < RI.contexts.length; i++) {
|
|
||||||
{{{ makeSetValue('RI.contexts[i].state', '32', 'x', 'i32') }}};
|
|
||||||
{{{ makeSetValue('RI.contexts[i].state', '36', 'y', 'i32') }}};
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'keyup':
|
|
||||||
case 'keydown':
|
|
||||||
var key = event.keyCode;
|
|
||||||
var offset = key >> 3;
|
|
||||||
var bit = 1 << (key & 7);
|
|
||||||
if (offset >= 32) throw 'key code error! bad code: ' + key;
|
|
||||||
for (i = 0; i < RI.contexts.length; i++) {
|
|
||||||
var value = {{{ makeGetValue('RI.contexts[i].state', 'offset', 'i8') }}};
|
|
||||||
if (event.type === 'keyup') value &= ~bit;
|
|
||||||
else value |= bit;
|
|
||||||
{{{ makeSetValue('RI.contexts[i].state', 'offset', 'value', 'i8') }}};
|
|
||||||
}
|
|
||||||
event.preventDefault();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'blur':
|
|
||||||
case 'visibilitychange':
|
|
||||||
for (i = 0; i < RI.contexts.length; i++) {
|
|
||||||
_memset(RI.contexts[i].state, 0, 42);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
RWebInputInit: function() {
|
|
||||||
if (RI.contexts.length === 0) {
|
|
||||||
document.addEventListener('keyup', RI.eventHandler, false);
|
|
||||||
document.addEventListener('keydown', RI.eventHandler, false);
|
|
||||||
document.addEventListener('mousemove', RI.eventHandler, false);
|
|
||||||
Module.canvas.addEventListener('mouseup', RI.canvasEventHandler, false);
|
|
||||||
Module.canvas.addEventListener('mousedown', RI.canvasEventHandler, false);
|
|
||||||
document.addEventListener('blur', RI.eventHandler, false);
|
|
||||||
document.addEventListener('onvisbilitychange', RI.eventHandler, false);
|
|
||||||
}
|
|
||||||
if (RI.temp === null) RI.temp = _malloc(42);
|
|
||||||
|
|
||||||
var s = _malloc(42);
|
|
||||||
_memset(s, 0, 42);
|
|
||||||
RI.contexts.push({
|
|
||||||
state: s
|
|
||||||
});
|
|
||||||
return RI.contexts.length;
|
|
||||||
},
|
|
||||||
|
|
||||||
RWebInputPoll: function(context) {
|
|
||||||
context -= 1;
|
|
||||||
var state = RI.contexts[context].state;
|
|
||||||
_memcpy(RI.temp, state, 42);
|
|
||||||
// reset mouse movements
|
|
||||||
{{{ makeSetValue('RI.contexts[context].state', '32', '0', 'i32') }}};
|
|
||||||
{{{ makeSetValue('RI.contexts[context].state', '36', '0', 'i32') }}};
|
|
||||||
return RI.temp;
|
|
||||||
},
|
|
||||||
|
|
||||||
RWebInputDestroy: function (context) {
|
|
||||||
if (context === RI.contexts.length) {
|
|
||||||
RI.contexts.pop();
|
|
||||||
if (RI.contexts.length === 0) {
|
|
||||||
document.removeEventListener('keyup', RI.eventHandler, false);
|
|
||||||
document.removeEventListener('keydown', RI.eventHandler, false);
|
|
||||||
document.removeEventListener('mousemove', RI.eventHandler, false);
|
|
||||||
Module.canvas.removeEventListener('mouseup', RI.canvasEventHandler, false);
|
|
||||||
Module.canvas.removeEventListener('mousedown', RI.canvasEventHandler, false);
|
|
||||||
document.removeEventListener('blur', RI.eventHandler, false);
|
|
||||||
document.removeEventListener('onvisbilitychange', RI.eventHandler, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
autoAddDeps(LibraryRWebInput, '$RI');
|
|
||||||
mergeInto(LibraryManager.library, LibraryRWebInput);
|
|
@ -19,49 +19,294 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <boolean.h>
|
#include <boolean.h>
|
||||||
|
#include <retro_assert.h>
|
||||||
|
#include <retro_miscellaneous.h>
|
||||||
|
#include <encodings/crc32.h>
|
||||||
|
#include <encodings/utf.h>
|
||||||
|
|
||||||
|
#include <emscripten/html5.h>
|
||||||
|
|
||||||
#include "../input_driver.h"
|
#include "../input_driver.h"
|
||||||
#include "../input_keymaps.h"
|
#include "../input_keymaps.h"
|
||||||
|
|
||||||
#include "../../tasks/tasks_internal.h"
|
#include "../../tasks/tasks_internal.h"
|
||||||
#include "../../configuration.h"
|
#include "../../configuration.h"
|
||||||
|
#include "../../verbosity.h"
|
||||||
|
|
||||||
typedef struct rwebinput_state
|
typedef struct rwebinput_key_to_code_map_entry
|
||||||
{
|
{
|
||||||
uint8_t keys[32];
|
const char *key;
|
||||||
|
enum retro_key rk;
|
||||||
|
} rwebinput_key_to_code_map_entry_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
bool keys[RETROK_LAST];
|
||||||
|
} rwebinput_key_states_t;
|
||||||
|
|
||||||
|
typedef struct rwebinput_input
|
||||||
|
{
|
||||||
|
rwebinput_key_states_t keyboard;
|
||||||
int mouse_x;
|
int mouse_x;
|
||||||
int mouse_y;
|
int mouse_y;
|
||||||
char mouse_l;
|
char mouse_l;
|
||||||
char mouse_r;
|
char mouse_r;
|
||||||
bool blocked;
|
bool blocked;
|
||||||
} rwebinput_state_t;
|
|
||||||
|
|
||||||
int RWebInputInit(void);
|
|
||||||
rwebinput_state_t *RWebInputPoll(int context);
|
|
||||||
void RWebInputDestroy(int context);
|
|
||||||
|
|
||||||
typedef struct rwebinput_input
|
|
||||||
{
|
|
||||||
rwebinput_state_t state;
|
|
||||||
int context;
|
|
||||||
} rwebinput_input_t;
|
} rwebinput_input_t;
|
||||||
|
|
||||||
|
/* KeyboardEvent.keyCode has been deprecated for a while and doesn't have
|
||||||
|
* separate left/right modifer codes, so we have to map string labels from
|
||||||
|
* KeyboardEvent.code to retro keys */
|
||||||
|
static const rwebinput_key_to_code_map_entry_t rwebinput_key_to_code_map[] =
|
||||||
|
{
|
||||||
|
{ "KeyA", RETROK_a },
|
||||||
|
{ "KeyB", RETROK_b },
|
||||||
|
{ "KeyC", RETROK_c },
|
||||||
|
{ "KeyD", RETROK_d },
|
||||||
|
{ "KeyE", RETROK_e },
|
||||||
|
{ "KeyF", RETROK_f },
|
||||||
|
{ "KeyG", RETROK_g },
|
||||||
|
{ "KeyH", RETROK_h },
|
||||||
|
{ "KeyI", RETROK_i },
|
||||||
|
{ "KeyJ", RETROK_j },
|
||||||
|
{ "KeyK", RETROK_k },
|
||||||
|
{ "KeyL", RETROK_l },
|
||||||
|
{ "KeyM", RETROK_m },
|
||||||
|
{ "KeyN", RETROK_n },
|
||||||
|
{ "KeyO", RETROK_o },
|
||||||
|
{ "KeyP", RETROK_p },
|
||||||
|
{ "KeyQ", RETROK_q },
|
||||||
|
{ "KeyR", RETROK_r },
|
||||||
|
{ "KeyS", RETROK_s },
|
||||||
|
{ "KeyT", RETROK_t },
|
||||||
|
{ "KeyU", RETROK_u },
|
||||||
|
{ "KeyV", RETROK_v },
|
||||||
|
{ "KeyW", RETROK_w },
|
||||||
|
{ "KeyX", RETROK_x },
|
||||||
|
{ "KeyY", RETROK_y },
|
||||||
|
{ "KeyZ", RETROK_z },
|
||||||
|
{ "ArrowLeft", RETROK_LEFT },
|
||||||
|
{ "ArrowRight", RETROK_RIGHT },
|
||||||
|
{ "ArrowUp", RETROK_UP },
|
||||||
|
{ "ArrowDown", RETROK_DOWN },
|
||||||
|
{ "Enter", RETROK_RETURN },
|
||||||
|
{ "NumpadEnter", RETROK_KP_ENTER },
|
||||||
|
{ "Tab", RETROK_TAB },
|
||||||
|
{ "Insert", RETROK_INSERT },
|
||||||
|
{ "Delete", RETROK_DELETE },
|
||||||
|
{ "End", RETROK_END },
|
||||||
|
{ "Home", RETROK_HOME },
|
||||||
|
{ "ShiftRight", RETROK_RSHIFT },
|
||||||
|
{ "ShiftLeft", RETROK_LSHIFT },
|
||||||
|
{ "ControlLeft", RETROK_LCTRL },
|
||||||
|
{ "AltLeft", RETROK_LALT },
|
||||||
|
{ "Space", RETROK_SPACE },
|
||||||
|
{ "Escape", RETROK_ESCAPE },
|
||||||
|
{ "NumpadAdd", RETROK_KP_PLUS },
|
||||||
|
{ "NumpadSubtract", RETROK_KP_MINUS },
|
||||||
|
{ "F1", RETROK_F1 },
|
||||||
|
{ "F2", RETROK_F2 },
|
||||||
|
{ "F3", RETROK_F3 },
|
||||||
|
{ "F4", RETROK_F4 },
|
||||||
|
{ "F5", RETROK_F5 },
|
||||||
|
{ "F6", RETROK_F6 },
|
||||||
|
{ "F7", RETROK_F7 },
|
||||||
|
{ "F8", RETROK_F8 },
|
||||||
|
{ "F9", RETROK_F9 },
|
||||||
|
{ "F10", RETROK_F10 },
|
||||||
|
{ "F11", RETROK_F11 },
|
||||||
|
{ "F12", RETROK_F12 },
|
||||||
|
{ "Digit0", RETROK_0 },
|
||||||
|
{ "Digit1", RETROK_1 },
|
||||||
|
{ "Digit2", RETROK_2 },
|
||||||
|
{ "Digit3", RETROK_3 },
|
||||||
|
{ "Digit4", RETROK_4 },
|
||||||
|
{ "Digit5", RETROK_5 },
|
||||||
|
{ "Digit6", RETROK_6 },
|
||||||
|
{ "Digit7", RETROK_7 },
|
||||||
|
{ "Digit8", RETROK_8 },
|
||||||
|
{ "Digit9", RETROK_9 },
|
||||||
|
{ "PageUp", RETROK_PAGEUP },
|
||||||
|
{ "PageDown", RETROK_PAGEDOWN },
|
||||||
|
{ "Numpad0", RETROK_KP0 },
|
||||||
|
{ "Numpad1", RETROK_KP1 },
|
||||||
|
{ "Numpad2", RETROK_KP2 },
|
||||||
|
{ "Numpad3", RETROK_KP3 },
|
||||||
|
{ "Numpad4", RETROK_KP4 },
|
||||||
|
{ "Numpad5", RETROK_KP5 },
|
||||||
|
{ "Numpad6", RETROK_KP6 },
|
||||||
|
{ "Numpad7", RETROK_KP7 },
|
||||||
|
{ "Numpad8", RETROK_KP8 },
|
||||||
|
{ "Numpad9", RETROK_KP9 },
|
||||||
|
{ "Period", RETROK_PERIOD },
|
||||||
|
{ "CapsLock", RETROK_CAPSLOCK },
|
||||||
|
{ "NumLock", RETROK_NUMLOCK },
|
||||||
|
{ "Backspace", RETROK_BACKSPACE },
|
||||||
|
{ "NumpadMultiply", RETROK_KP_MULTIPLY },
|
||||||
|
{ "NumpadDivide", RETROK_KP_DIVIDE },
|
||||||
|
{ "PrintScreen", RETROK_PRINT },
|
||||||
|
{ "ScrollLock", RETROK_SCROLLOCK },
|
||||||
|
{ "Backquote", RETROK_BACKQUOTE },
|
||||||
|
{ "Pause", RETROK_PAUSE },
|
||||||
|
{ "Quote", RETROK_QUOTE },
|
||||||
|
{ "Comma", RETROK_COMMA },
|
||||||
|
{ "Minus", RETROK_MINUS },
|
||||||
|
{ "Slash", RETROK_SLASH },
|
||||||
|
{ "Semicolon", RETROK_SEMICOLON },
|
||||||
|
{ "Equal", RETROK_EQUALS },
|
||||||
|
{ "BracketLeft", RETROK_LEFTBRACKET },
|
||||||
|
{ "Backslash", RETROK_BACKSLASH },
|
||||||
|
{ "BracketRight", RETROK_RIGHTBRACKET },
|
||||||
|
{ "NumpadDecimal", RETROK_KP_PERIOD },
|
||||||
|
{ "NumpadEqual", RETROK_KP_EQUALS },
|
||||||
|
{ "ControlRight", RETROK_RCTRL },
|
||||||
|
{ "AltRight", RETROK_RALT },
|
||||||
|
{ "F13", RETROK_F13 },
|
||||||
|
{ "F14", RETROK_F14 },
|
||||||
|
{ "F15", RETROK_F15 },
|
||||||
|
{ "MetaRight", RETROK_RMETA },
|
||||||
|
{ "MetaLeft", RETROK_LMETA },
|
||||||
|
{ "Help", RETROK_HELP },
|
||||||
|
{ "ContextMenu", RETROK_MENU },
|
||||||
|
{ "Power", RETROK_POWER },
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool g_initialized;
|
||||||
|
static rwebinput_key_states_t *g_keyboard;
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct rarch_key_map *key_map;
|
||||||
|
|
||||||
|
retro_assert(ARRAY_SIZE(rarch_key_map_rwebinput) ==
|
||||||
|
ARRAY_SIZE(rwebinput_key_to_code_map) + 1);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(rwebinput_key_to_code_map); i++)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
uint32_t crc;
|
||||||
|
const rwebinput_key_to_code_map_entry_t *key_to_code =
|
||||||
|
&rwebinput_key_to_code_map[i];
|
||||||
|
key_map = &rarch_key_map_rwebinput[i];
|
||||||
|
crc = encoding_crc32(0, (const uint8_t *)key_to_code->key,
|
||||||
|
strlen(key_to_code->key));
|
||||||
|
|
||||||
|
/* sanity check: make sure there's no collisions */
|
||||||
|
for (j = 0; j < i; j++)
|
||||||
|
{
|
||||||
|
retro_assert(rarch_key_map_rwebinput[j].sym != crc);
|
||||||
|
}
|
||||||
|
|
||||||
|
key_map->rk = key_to_code->rk;
|
||||||
|
key_map->sym = crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set terminating entry */
|
||||||
|
key_map = &rarch_key_map_rwebinput[ARRAY_SIZE(rarch_key_map_rwebinput) - 1];
|
||||||
|
key_map->rk = RETROK_UNKNOWN;
|
||||||
|
key_map->sym = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EM_BOOL rwebinput_input_cb(int event_type,
|
||||||
|
const EmscriptenKeyboardEvent *key_event, void *user_data)
|
||||||
|
{
|
||||||
|
uint32_t crc;
|
||||||
|
uint32_t keycode;
|
||||||
|
unsigned translated_keycode;
|
||||||
|
uint32_t character = 0;
|
||||||
|
uint16_t mod = 0;
|
||||||
|
bool keydown = event_type == EMSCRIPTEN_EVENT_KEYDOWN;
|
||||||
|
|
||||||
|
(void)user_data;
|
||||||
|
|
||||||
|
/* capture keypress events and silence them */
|
||||||
|
if (event_type == EMSCRIPTEN_EVENT_KEYPRESS)
|
||||||
|
return EM_TRUE;
|
||||||
|
|
||||||
|
/* a printable key: populate character field */
|
||||||
|
if (utf8len(key_event->key) == 1)
|
||||||
|
{
|
||||||
|
const char *key_ptr = &key_event->key[0];
|
||||||
|
character = utf8_walk(&key_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key_event->ctrlKey)
|
||||||
|
mod |= RETROKMOD_CTRL;
|
||||||
|
if (key_event->altKey)
|
||||||
|
mod |= RETROKMOD_ALT;
|
||||||
|
if (key_event->shiftKey)
|
||||||
|
mod |= RETROKMOD_SHIFT;
|
||||||
|
if (key_event->metaKey)
|
||||||
|
mod |= RETROKMOD_META;
|
||||||
|
|
||||||
|
keycode = encoding_crc32(0, (const uint8_t *)key_event->code,
|
||||||
|
strnlen(key_event->code, sizeof(key_event->code)));
|
||||||
|
translated_keycode = input_keymaps_translate_keysym_to_rk(keycode);
|
||||||
|
|
||||||
|
input_keyboard_event(keydown, translated_keycode, character, mod,
|
||||||
|
RETRO_DEVICE_KEYBOARD);
|
||||||
|
|
||||||
|
if (translated_keycode < RETROK_LAST)
|
||||||
|
{
|
||||||
|
g_keyboard->keys[translated_keycode] = keydown;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EM_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void *rwebinput_input_init(const char *joypad_driver)
|
static void *rwebinput_input_init(const char *joypad_driver)
|
||||||
{
|
{
|
||||||
rwebinput_input_t *rwebinput = (rwebinput_input_t*)calloc(1, sizeof(*rwebinput));
|
rwebinput_input_t *rwebinput =
|
||||||
if (!rwebinput)
|
(rwebinput_input_t*)calloc(1, sizeof(*rwebinput));
|
||||||
|
g_keyboard =
|
||||||
|
(rwebinput_key_states_t*)calloc(1, sizeof(rwebinput_key_states_t));
|
||||||
|
|
||||||
|
if (!rwebinput || !g_keyboard)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
rwebinput->context = RWebInputInit();
|
if (!g_initialized)
|
||||||
if (!rwebinput->context)
|
{
|
||||||
goto error;
|
EMSCRIPTEN_RESULT r;
|
||||||
|
|
||||||
|
g_initialized = true;
|
||||||
|
rwebinput_generate_lut();
|
||||||
|
|
||||||
|
/* emscripten currently doesn't have an API to remove handlers, so make
|
||||||
|
* once and reuse it */
|
||||||
|
r = emscripten_set_keydown_callback("#document", NULL, false,
|
||||||
|
rwebinput_input_cb);
|
||||||
|
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||||
|
{
|
||||||
|
RARCH_ERR(
|
||||||
|
"[EMSCRIPTEN/INPUT] failed to create keydown callback: %d\n", r);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = emscripten_set_keyup_callback("#document", NULL, false,
|
||||||
|
rwebinput_input_cb);
|
||||||
|
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||||
|
{
|
||||||
|
RARCH_ERR(
|
||||||
|
"[EMSCRIPTEN/INPUT] failed to create keydown callback: %d\n", r);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = emscripten_set_keypress_callback("#document", NULL, false,
|
||||||
|
rwebinput_input_cb);
|
||||||
|
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||||
|
{
|
||||||
|
RARCH_ERR(
|
||||||
|
"[EMSCRIPTEN/INPUT] failed to create keypress callback: %d\n", r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
input_keymaps_init_keyboard_lut(rarch_key_map_rwebinput);
|
input_keymaps_init_keyboard_lut(rarch_key_map_rwebinput);
|
||||||
|
|
||||||
return rwebinput;
|
return rwebinput;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (rwebinput)
|
free(g_keyboard);
|
||||||
free(rwebinput);
|
free(rwebinput);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -75,10 +320,7 @@ static bool rwebinput_key_pressed(void *data, int key)
|
|||||||
if (key >= RETROK_LAST)
|
if (key >= RETROK_LAST)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
sym = rarch_keysym_lut[(enum retro_key)key];
|
return rwebinput->keyboard.keys[key];
|
||||||
ret = rwebinput->state.keys[sym >> 3] & (1 << (sym & 7));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool rwebinput_is_pressed(rwebinput_input_t *rwebinput,
|
static bool rwebinput_is_pressed(rwebinput_input_t *rwebinput,
|
||||||
@ -100,13 +342,13 @@ static int16_t rwebinput_mouse_state(rwebinput_input_t *rwebinput, unsigned id)
|
|||||||
switch (id)
|
switch (id)
|
||||||
{
|
{
|
||||||
case RETRO_DEVICE_ID_MOUSE_X:
|
case RETRO_DEVICE_ID_MOUSE_X:
|
||||||
return (int16_t) rwebinput->state.mouse_x;
|
return (int16_t) rwebinput->mouse_x;
|
||||||
case RETRO_DEVICE_ID_MOUSE_Y:
|
case RETRO_DEVICE_ID_MOUSE_Y:
|
||||||
return (int16_t) rwebinput->state.mouse_y;
|
return (int16_t) rwebinput->mouse_y;
|
||||||
case RETRO_DEVICE_ID_MOUSE_LEFT:
|
case RETRO_DEVICE_ID_MOUSE_LEFT:
|
||||||
return rwebinput->state.mouse_l;
|
return rwebinput->mouse_l;
|
||||||
case RETRO_DEVICE_ID_MOUSE_RIGHT:
|
case RETRO_DEVICE_ID_MOUSE_RIGHT:
|
||||||
return rwebinput->state.mouse_r;
|
return rwebinput->mouse_r;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -155,11 +397,12 @@ static void rwebinput_input_free(void *data)
|
|||||||
{
|
{
|
||||||
rwebinput_input_t *rwebinput = (rwebinput_input_t*)data;
|
rwebinput_input_t *rwebinput = (rwebinput_input_t*)data;
|
||||||
|
|
||||||
|
free(g_keyboard);
|
||||||
|
g_keyboard = NULL;
|
||||||
|
|
||||||
if (!rwebinput)
|
if (!rwebinput)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RWebInputDestroy(rwebinput->context);
|
|
||||||
|
|
||||||
free(rwebinput);
|
free(rwebinput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,29 +410,8 @@ static void rwebinput_input_poll(void *data)
|
|||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
rwebinput_input_t *rwebinput = (rwebinput_input_t*)data;
|
rwebinput_input_t *rwebinput = (rwebinput_input_t*)data;
|
||||||
rwebinput_state_t *state = RWebInputPoll(rwebinput->context);
|
|
||||||
|
|
||||||
/* Get new keys. */
|
memcpy(&rwebinput->keyboard, g_keyboard, sizeof(*g_keyboard));
|
||||||
for (i = 0; i < 32; i++)
|
|
||||||
{
|
|
||||||
unsigned k;
|
|
||||||
uint8_t diff;
|
|
||||||
|
|
||||||
if (state->keys[i] == rwebinput->state.keys[i])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
diff = state->keys[i] ^ rwebinput->state.keys[i];
|
|
||||||
|
|
||||||
for (k = 0; diff; diff >>= 1, k++)
|
|
||||||
{
|
|
||||||
if (diff & 1)
|
|
||||||
input_keyboard_event((state->keys[i] & (1 << k)) != 0,
|
|
||||||
input_keymaps_translate_keysym_to_rk(i * 8 + k), 0, 0,
|
|
||||||
RETRO_DEVICE_KEYBOARD);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&rwebinput->state, state, sizeof(rwebinput->state));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rwebinput_grab_mouse(void *data, bool state)
|
static void rwebinput_grab_mouse(void *data, bool state)
|
||||||
@ -226,7 +448,7 @@ static bool rwebinput_keyboard_mapping_is_blocked(void *data)
|
|||||||
rwebinput_input_t *rwebinput = (rwebinput_input_t*)data;
|
rwebinput_input_t *rwebinput = (rwebinput_input_t*)data;
|
||||||
if (!rwebinput)
|
if (!rwebinput)
|
||||||
return false;
|
return false;
|
||||||
return rwebinput->state.blocked;
|
return rwebinput->blocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rwebinput_keyboard_mapping_set_block(void *data, bool value)
|
static void rwebinput_keyboard_mapping_set_block(void *data, bool value)
|
||||||
@ -234,7 +456,7 @@ static void rwebinput_keyboard_mapping_set_block(void *data, bool value)
|
|||||||
rwebinput_input_t *rwebinput = (rwebinput_input_t*)data;
|
rwebinput_input_t *rwebinput = (rwebinput_input_t*)data;
|
||||||
if (!rwebinput)
|
if (!rwebinput)
|
||||||
return;
|
return;
|
||||||
rwebinput->state.blocked = value;
|
rwebinput->blocked = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
input_driver_t input_rwebinput = {
|
input_driver_t input_rwebinput = {
|
||||||
|
@ -579,109 +579,8 @@ const struct rarch_key_map rarch_key_map_dinput[] = {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN
|
#ifdef EMSCRIPTEN
|
||||||
const struct rarch_key_map rarch_key_map_rwebinput[] = {
|
/* this is generated at runtime, so it isn't constant */
|
||||||
{ 37, RETROK_LEFT },
|
struct rarch_key_map rarch_key_map_rwebinput[RARCH_KEY_MAP_RWEBINPUT_SIZE];
|
||||||
{ 39, RETROK_RIGHT },
|
|
||||||
{ 38, RETROK_UP },
|
|
||||||
{ 40, RETROK_DOWN },
|
|
||||||
{ 13, RETROK_RETURN },
|
|
||||||
{ 9, RETROK_TAB },
|
|
||||||
{ 45, RETROK_INSERT },
|
|
||||||
{ 46, RETROK_DELETE },
|
|
||||||
{ 16, RETROK_RSHIFT },
|
|
||||||
{ 16, RETROK_LSHIFT },
|
|
||||||
{ 17, RETROK_LCTRL },
|
|
||||||
{ 35, RETROK_END },
|
|
||||||
{ 36, RETROK_HOME },
|
|
||||||
{ 34, RETROK_PAGEDOWN },
|
|
||||||
{ 33, RETROK_PAGEUP },
|
|
||||||
{ 18, RETROK_LALT },
|
|
||||||
{ 32, RETROK_SPACE },
|
|
||||||
{ 27, RETROK_ESCAPE },
|
|
||||||
{ 8, RETROK_BACKSPACE },
|
|
||||||
{ 13, RETROK_KP_ENTER },
|
|
||||||
{ 107, RETROK_KP_PLUS },
|
|
||||||
{ 109, RETROK_KP_MINUS },
|
|
||||||
{ 106, RETROK_KP_MULTIPLY },
|
|
||||||
{ 111, RETROK_KP_DIVIDE },
|
|
||||||
{ 192, RETROK_BACKQUOTE },
|
|
||||||
{ 19, RETROK_PAUSE },
|
|
||||||
{ 96, RETROK_KP0 },
|
|
||||||
{ 97, RETROK_KP1 },
|
|
||||||
{ 98, RETROK_KP2 },
|
|
||||||
{ 99, RETROK_KP3 },
|
|
||||||
{ 100, RETROK_KP4 },
|
|
||||||
{ 101, RETROK_KP5 },
|
|
||||||
{ 102, RETROK_KP6 },
|
|
||||||
{ 103, RETROK_KP7 },
|
|
||||||
{ 104, RETROK_KP8 },
|
|
||||||
{ 105, RETROK_KP9 },
|
|
||||||
{ 48, RETROK_0 },
|
|
||||||
{ 49, RETROK_1 },
|
|
||||||
{ 50, RETROK_2 },
|
|
||||||
{ 51, RETROK_3 },
|
|
||||||
{ 52, RETROK_4 },
|
|
||||||
{ 53, RETROK_5 },
|
|
||||||
{ 54, RETROK_6 },
|
|
||||||
{ 55, RETROK_7 },
|
|
||||||
{ 56, RETROK_8 },
|
|
||||||
{ 57, RETROK_9 },
|
|
||||||
{ 112, RETROK_F1 },
|
|
||||||
{ 113, RETROK_F2 },
|
|
||||||
{ 114, RETROK_F3 },
|
|
||||||
{ 115, RETROK_F4 },
|
|
||||||
{ 116, RETROK_F5 },
|
|
||||||
{ 117, RETROK_F6 },
|
|
||||||
{ 118, RETROK_F7 },
|
|
||||||
{ 119, RETROK_F8 },
|
|
||||||
{ 120, RETROK_F9 },
|
|
||||||
{ 121, RETROK_F10 },
|
|
||||||
{ 122, RETROK_F11 },
|
|
||||||
{ 123, RETROK_F12 },
|
|
||||||
{ 65, RETROK_a },
|
|
||||||
{ 66, RETROK_b },
|
|
||||||
{ 67, RETROK_c },
|
|
||||||
{ 68, RETROK_d },
|
|
||||||
{ 69, RETROK_e },
|
|
||||||
{ 70, RETROK_f },
|
|
||||||
{ 71, RETROK_g },
|
|
||||||
{ 72, RETROK_h },
|
|
||||||
{ 73, RETROK_i },
|
|
||||||
{ 74, RETROK_j },
|
|
||||||
{ 75, RETROK_k },
|
|
||||||
{ 76, RETROK_l },
|
|
||||||
{ 77, RETROK_m },
|
|
||||||
{ 78, RETROK_n },
|
|
||||||
{ 79, RETROK_o },
|
|
||||||
{ 80, RETROK_p },
|
|
||||||
{ 81, RETROK_q },
|
|
||||||
{ 82, RETROK_r },
|
|
||||||
{ 83, RETROK_s },
|
|
||||||
{ 84, RETROK_t },
|
|
||||||
{ 85, RETROK_u },
|
|
||||||
{ 86, RETROK_v },
|
|
||||||
{ 87, RETROK_w },
|
|
||||||
{ 88, RETROK_x },
|
|
||||||
{ 89, RETROK_y },
|
|
||||||
{ 90, RETROK_z },
|
|
||||||
{ 222, RETROK_QUOTE },
|
|
||||||
{ 188, RETROK_COMMA },
|
|
||||||
{ 173, RETROK_MINUS },
|
|
||||||
{ 191, RETROK_SLASH },
|
|
||||||
{ 59, RETROK_SEMICOLON },
|
|
||||||
{ 61, RETROK_EQUALS },
|
|
||||||
{ 219, RETROK_LEFTBRACKET },
|
|
||||||
{ 220, RETROK_BACKSLASH },
|
|
||||||
{ 221, RETROK_RIGHTBRACKET },
|
|
||||||
{ 188, RETROK_KP_PERIOD },
|
|
||||||
{ 17, RETROK_RCTRL },
|
|
||||||
{ 18, RETROK_RALT },
|
|
||||||
{ 190, RETROK_PERIOD },
|
|
||||||
{ 145, RETROK_SCROLLOCK },
|
|
||||||
{ 20, RETROK_CAPSLOCK },
|
|
||||||
{ 144, RETROK_NUMLOCK },
|
|
||||||
{ 0, RETROK_UNKNOWN },
|
|
||||||
};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIIU
|
#ifdef WIIU
|
||||||
|
@ -46,13 +46,18 @@ struct apple_key_name_map_entry
|
|||||||
extern const struct apple_key_name_map_entry apple_key_name_map[];
|
extern const struct apple_key_name_map_entry apple_key_name_map[];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define RARCH_KEY_MAP_RWEBINPUT_SIZE 111
|
||||||
|
|
||||||
extern const struct input_key_map input_config_key_map[];
|
extern const struct input_key_map input_config_key_map[];
|
||||||
|
|
||||||
extern const struct rarch_key_map rarch_key_map_x11[];
|
extern const struct rarch_key_map rarch_key_map_x11[];
|
||||||
extern const struct rarch_key_map rarch_key_map_sdl[];
|
extern const struct rarch_key_map rarch_key_map_sdl[];
|
||||||
extern const struct rarch_key_map rarch_key_map_sdl2[];
|
extern const struct rarch_key_map rarch_key_map_sdl2[];
|
||||||
extern const struct rarch_key_map rarch_key_map_dinput[];
|
extern const struct rarch_key_map rarch_key_map_dinput[];
|
||||||
extern const struct rarch_key_map rarch_key_map_rwebinput[];
|
|
||||||
|
/* is generated at runtime so can't be const */
|
||||||
|
extern struct rarch_key_map rarch_key_map_rwebinput[RARCH_KEY_MAP_RWEBINPUT_SIZE];
|
||||||
|
|
||||||
extern const struct rarch_key_map rarch_key_map_linux[];
|
extern const struct rarch_key_map rarch_key_map_linux[];
|
||||||
extern const struct rarch_key_map rarch_key_map_apple_hid[];
|
extern const struct rarch_key_map rarch_key_map_apple_hid[];
|
||||||
extern const struct rarch_key_map rarch_key_map_android[];
|
extern const struct rarch_key_map rarch_key_map_android[];
|
||||||
@ -96,4 +101,3 @@ extern enum retro_key rarch_keysym_lut[RETROK_LAST];
|
|||||||
RETRO_END_DECLS
|
RETRO_END_DECLS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user