mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-26 17:50:56 +00:00
(Emscripten) Modularize the JavaScript and clean up the web build (#15688)
* Increase emscripten stack size and decrease path size to fix emscripten builds broken since de45fc2
* use modularize flags for better-behaved javascript output
* makefile and loader changes
* use specialHTMLTargets to support modular access to canvas
* bind key events to canvas, not document
This way focus means focus and we can have multiple RA instances in
one page.
* Work around an emscripten bug in strict mode
* (Emscripten) Use console.error() for error messages
* increase asyncify stack size
* Fix `-lm` flag-related compile warnings in emscripten
---------
Co-authored-by: Rob Loach <robloach@gmail.com>
This commit is contained in:
parent
8523eaf5c0
commit
862bebf687
@ -2,6 +2,7 @@ HAVE_STATIC_DUMMY ?= 0
|
||||
ifeq ($(TARGET),)
|
||||
ifeq ($(LIBRETRO),)
|
||||
TARGET := retroarch.js
|
||||
LIBRETRO = dummy
|
||||
else
|
||||
TARGET := $(LIBRETRO)_libretro.js
|
||||
endif
|
||||
@ -48,7 +49,6 @@ HAVE_7ZIP = 1
|
||||
HAVE_BSV_MOVIE = 1
|
||||
HAVE_AL = 1
|
||||
|
||||
|
||||
# WARNING -- READ BEFORE ENABLING
|
||||
# The rwebaudio driver is known to have several audio bugs, such as
|
||||
# minor crackling, or the entire page freezing/crashing.
|
||||
@ -78,8 +78,11 @@ OBJDIR := obj-emscripten
|
||||
#if you compile with SDL2 flag add this Emscripten flag "-s USE_SDL=2" to LDFLAGS:
|
||||
|
||||
LIBS := -s USE_ZLIB=1
|
||||
LDFLAGS := -L. --no-heap-copy -s $(LIBS) -s TOTAL_MEMORY=$(MEMORY) -s NO_EXIT_RUNTIME=0 -s FULL_ES2=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']" \
|
||||
-s ALLOW_MEMORY_GROWTH=1 -s EXPORTED_FUNCTIONS="['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_load_state', '_cmd_take_screenshot']" \
|
||||
LDFLAGS := -L. --no-heap-copy -s $(LIBS) -s TOTAL_MEMORY=$(MEMORY) -s NO_EXIT_RUNTIME=0 -s FULL_ES2=1 \
|
||||
-s "EXPORTED_RUNTIME_METHODS=['callMain', 'FS', 'PATH', 'ERRNO_CODES']" \
|
||||
-s ALLOW_MEMORY_GROWTH=1 -s "EXPORTED_FUNCTIONS=['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_load_state', '_cmd_take_screenshot']" \
|
||||
-s MODULARIZE=1 -s EXPORT_ES6=1 -s EXPORT_NAME="$(LIBRETRO)" \
|
||||
-s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 \
|
||||
--js-library emscripten/library_errno_codes.js \
|
||||
--js-library emscripten/library_rwebcam.js
|
||||
|
||||
@ -102,7 +105,10 @@ else
|
||||
endif
|
||||
|
||||
ifeq ($(ASYNC), 1)
|
||||
LDFLAGS += -s ASYNCIFY=$(ASYNC)
|
||||
LDFLAGS += -s ASYNCIFY=$(ASYNC) -s ASYNCIFY_STACK_SIZE=8192
|
||||
ifeq ($(DEBUG), 1)
|
||||
LDFLAGS += -s ASYNCIFY_DEBUG=1 # -s ASYNCIFY_ADVISE
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL2), 1)
|
||||
@ -127,8 +133,8 @@ ifneq ($(V), 1)
|
||||
endif
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
LDFLAGS += -O0 -g
|
||||
CFLAGS += -O0 -g
|
||||
LDFLAGS += -O0 -g -gsource-map -s SAFE_HEAP=1 -s STACK_OVERFLOW_CHECK=2 -s ASSERTIONS=1
|
||||
CFLAGS += -O0 -g -gsource-map -s SAFE_HEAP=1 -s SAFE_HEAP_LOG=1 -s STACK_OVERFLOW_CHECK=2 -s ASSERTIONS=1
|
||||
else
|
||||
LDFLAGS += -O3 -s WASM=1
|
||||
# WARNING: some optimizations can break some cores (ex: LTO breaks tyrquake)
|
||||
@ -139,7 +145,12 @@ else
|
||||
CFLAGS += -O3
|
||||
endif
|
||||
|
||||
CFLAGS += -Wall -I. -Ilibretro-common/include -std=gnu99 $(LIBS) #\
|
||||
# 128 * 1024, double the usual emscripten stack size
|
||||
LDFLAGS += -s STACK_SIZE=131072
|
||||
|
||||
LDFLAGS += --extern-pre-js emscripten/pre.js
|
||||
|
||||
CFLAGS += -Wall -I. -Ilibretro-common/include -std=gnu99 #\
|
||||
# -s EXPORTED_FUNCTIONS="['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_take_screenshot']"
|
||||
|
||||
RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
|
||||
|
@ -247,8 +247,8 @@ for f in `ls -v *_${platform}.${EXT}`; do
|
||||
if [ $MAKEFILE_GRIFFIN = "yes" ]; then
|
||||
make -C ../ -f Makefile.griffin $OPTS platform=${platform} $whole_archive $big_stack -j3 || exit 1
|
||||
elif [ $PLATFORM = "emscripten" ]; then
|
||||
echo "BUILD COMMAND: make -C ../ -f Makefile.emscripten PTHREAD=$pthread ASYNC=$async LTO=$lto -j7 TARGET=${name}_libretro.js"
|
||||
make -C ../ -f Makefile.emscripten $OPTS PTHREAD=$pthread ASYNC=$async LTO=$lto -j7 TARGET=${name}_libretro.js || exit 1
|
||||
echo "BUILD COMMAND: make -C ../ -f Makefile.emscripten PTHREAD=$pthread ASYNC=$async LTO=$lto -j7 LIBRETRO=${name} TARGET=${name}_libretro.js"
|
||||
make -C ../ -f Makefile.emscripten $OPTS PTHREAD=$pthread ASYNC=$async LTO=$lto -j7 LIBRETRO=${name} TARGET=${name}_libretro.js || exit 1
|
||||
elif [ $PLATFORM = "unix" ]; then
|
||||
make -C ../ -f Makefile LINK=g++ $whole_archive $big_stack -j3 || exit 1
|
||||
elif [ $PLATFORM = "ctr" ]; then
|
||||
|
2
emscripten/pre.js
Normal file
2
emscripten/pre.js
Normal file
@ -0,0 +1,2 @@
|
||||
// To work around a bug in emscripten's polyfills for setImmediate in strict mode
|
||||
var setImmediate;
|
@ -160,8 +160,12 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
dummyErrnoCodes();
|
||||
|
||||
emscripten_set_canvas_element_size("#canvas", 800, 600);
|
||||
emscripten_set_element_css_size("#canvas", 800.0, 600.0);
|
||||
EM_ASM({
|
||||
specialHTMLTargets["!canvas"] = Module.canvas;
|
||||
});
|
||||
|
||||
emscripten_set_canvas_element_size("!canvas", 800, 600);
|
||||
emscripten_set_element_css_size("!canvas", 800.0, 600.0);
|
||||
emscripten_set_main_loop(emscripten_mainloop, 0, 0);
|
||||
rarch_main(argc, argv, NULL);
|
||||
|
||||
|
@ -70,7 +70,7 @@ static void gfx_ctx_emscripten_get_canvas_size(int *width, int *height)
|
||||
|
||||
if (!is_fullscreen)
|
||||
{
|
||||
r = emscripten_get_canvas_element_size("#canvas", width, height);
|
||||
r = emscripten_get_canvas_element_size("!canvas", width, height);
|
||||
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
@ -105,14 +105,14 @@ static void gfx_ctx_emscripten_check_window(void *data, bool *quit,
|
||||
if ( (input_width != emscripten->fb_width)
|
||||
|| (input_height != emscripten->fb_height))
|
||||
{
|
||||
r = emscripten_set_canvas_element_size("#canvas",
|
||||
r = emscripten_set_canvas_element_size("!canvas",
|
||||
input_width, input_height);
|
||||
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
RARCH_ERR("[EMSCRIPTEN/EGL]: error resizing canvas: %d\n", r);
|
||||
|
||||
/* fix Module.requestFullscreen messing with the canvas size */
|
||||
r = emscripten_set_element_css_size("#canvas",
|
||||
r = emscripten_set_element_css_size("!canvas",
|
||||
(double)input_width, (double)input_height);
|
||||
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
@ -194,7 +194,7 @@ static void *gfx_ctx_emscripten_init(void *video_driver)
|
||||
* be grabbed? */
|
||||
if ( (emscripten->initial_width == 0)
|
||||
|| (emscripten->initial_height == 0))
|
||||
emscripten_get_canvas_element_size("#canvas",
|
||||
emscripten_get_canvas_element_size("!canvas",
|
||||
&emscripten->initial_width,
|
||||
&emscripten->initial_height);
|
||||
|
||||
|
@ -291,7 +291,7 @@ static void *rwebinput_input_init(const char *joypad_driver)
|
||||
rwebinput_generate_lut();
|
||||
|
||||
r = emscripten_set_keydown_callback(
|
||||
EMSCRIPTEN_EVENT_TARGET_DOCUMENT, rwebinput, false,
|
||||
"!canvas", rwebinput, false,
|
||||
rwebinput_keyboard_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
@ -300,7 +300,7 @@ static void *rwebinput_input_init(const char *joypad_driver)
|
||||
}
|
||||
|
||||
r = emscripten_set_keyup_callback(
|
||||
EMSCRIPTEN_EVENT_TARGET_DOCUMENT, rwebinput, false,
|
||||
"!canvas", rwebinput, false,
|
||||
rwebinput_keyboard_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
@ -309,7 +309,7 @@ static void *rwebinput_input_init(const char *joypad_driver)
|
||||
}
|
||||
|
||||
r = emscripten_set_keypress_callback(
|
||||
EMSCRIPTEN_EVENT_TARGET_DOCUMENT, rwebinput, false,
|
||||
"!canvas", rwebinput, false,
|
||||
rwebinput_keyboard_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
@ -317,7 +317,7 @@ static void *rwebinput_input_init(const char *joypad_driver)
|
||||
"[EMSCRIPTEN/INPUT] failed to create keypress callback: %d\n", r);
|
||||
}
|
||||
|
||||
r = emscripten_set_mousedown_callback("#canvas", rwebinput, false,
|
||||
r = emscripten_set_mousedown_callback("!canvas", rwebinput, false,
|
||||
rwebinput_mouse_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
@ -325,7 +325,7 @@ static void *rwebinput_input_init(const char *joypad_driver)
|
||||
"[EMSCRIPTEN/INPUT] failed to create mousedown callback: %d\n", r);
|
||||
}
|
||||
|
||||
r = emscripten_set_mouseup_callback("#canvas", rwebinput, false,
|
||||
r = emscripten_set_mouseup_callback("!canvas", rwebinput, false,
|
||||
rwebinput_mouse_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
@ -333,7 +333,7 @@ static void *rwebinput_input_init(const char *joypad_driver)
|
||||
"[EMSCRIPTEN/INPUT] failed to create mouseup callback: %d\n", r);
|
||||
}
|
||||
|
||||
r = emscripten_set_mousemove_callback("#canvas", rwebinput, false,
|
||||
r = emscripten_set_mousemove_callback("!canvas", rwebinput, false,
|
||||
rwebinput_mouse_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
@ -342,7 +342,7 @@ static void *rwebinput_input_init(const char *joypad_driver)
|
||||
}
|
||||
|
||||
r = emscripten_set_wheel_callback(
|
||||
EMSCRIPTEN_EVENT_TARGET_DOCUMENT, rwebinput, false,
|
||||
"!canvas", rwebinput, false,
|
||||
rwebinput_wheel_cb);
|
||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
@ -651,7 +651,7 @@ static void rwebinput_input_poll(void *data)
|
||||
static void rwebinput_grab_mouse(void *data, bool state)
|
||||
{
|
||||
if (state)
|
||||
emscripten_request_pointerlock("#canvas", EM_TRUE);
|
||||
emscripten_request_pointerlock("!canvas", EM_TRUE);
|
||||
else
|
||||
emscripten_exit_pointerlock();
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ static INLINE bool bits_any_different(uint32_t *a, uint32_t *b, uint32_t count)
|
||||
}
|
||||
|
||||
#ifndef PATH_MAX_LENGTH
|
||||
#if defined(_XBOX1) || defined(_3DS) || defined(PSP) || defined(PS2) || defined(GEKKO)|| defined(WIIU) || defined(__PSL1GHT__) || defined(__PS3__)
|
||||
#if defined(_XBOX1) || defined(_3DS) || defined(PSP) || defined(PS2) || defined(GEKKO)|| defined(WIIU) || defined(__PSL1GHT__) || defined(__PS3__) || defined(HAVE_EMSCRIPTEN)
|
||||
#define PATH_MAX_LENGTH 512
|
||||
#else
|
||||
#define PATH_MAX_LENGTH 4096
|
||||
|
@ -6,6 +6,89 @@
|
||||
var BrowserFS = BrowserFS;
|
||||
var afs;
|
||||
var initializationCount = 0;
|
||||
var setImmediate;
|
||||
|
||||
var Module = {
|
||||
noInitialRun: true,
|
||||
arguments: ["-v", "--menu"],
|
||||
|
||||
encoder: new TextEncoder(),
|
||||
message_queue:[],
|
||||
message_out:[],
|
||||
message_accum:"",
|
||||
|
||||
retroArchSend: function(msg) {
|
||||
let bytes = this.encoder.encode(msg+"\n");
|
||||
this.message_queue.push([bytes,0]);
|
||||
},
|
||||
retroArchRecv: function() {
|
||||
let out = this.message_out.shift();
|
||||
if(out == null && this.message_accum != "") {
|
||||
out = this.message_accum;
|
||||
this.message_accum = "";
|
||||
}
|
||||
return out;
|
||||
},
|
||||
preRun: [
|
||||
function(module) {
|
||||
function stdin() {
|
||||
// Return ASCII code of character, or null if no input
|
||||
while(module.message_queue.length > 0){
|
||||
var msg = module.message_queue[0][0];
|
||||
var index = module.message_queue[0][1];
|
||||
if(index >= msg.length) {
|
||||
module.message_queue.shift();
|
||||
} else {
|
||||
module.message_queue[0][1] = index+1;
|
||||
// assumption: msg is a uint8array
|
||||
return msg[index];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function stdout(c) {
|
||||
if(c == null) {
|
||||
// flush
|
||||
if(module.message_accum != "") {
|
||||
module.message_out.push(module.message_accum);
|
||||
module.message_accum = "";
|
||||
}
|
||||
} else {
|
||||
let s = String.fromCharCode(c);
|
||||
if(s == "\n") {
|
||||
if(module.message_accum != "") {
|
||||
module.message_out.push(module.message_accum);
|
||||
module.message_accum = "";
|
||||
}
|
||||
} else {
|
||||
module.message_accum = module.message_accum+s;
|
||||
}
|
||||
}
|
||||
}
|
||||
module.FS.init(stdin, stdout);
|
||||
}
|
||||
],
|
||||
postRun: [],
|
||||
onRuntimeInitialized: function()
|
||||
{
|
||||
appInitialized();
|
||||
},
|
||||
print: function(text)
|
||||
{
|
||||
console.log(text);
|
||||
},
|
||||
printErr: function(text)
|
||||
{
|
||||
console.error(text);
|
||||
},
|
||||
canvas: document.getElementById("canvas"),
|
||||
totalDependencies: 0,
|
||||
monitorRunDependencies: function(left)
|
||||
{
|
||||
this.totalDependencies = Math.max(this.totalDependencies, left);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function cleanupStorage()
|
||||
{
|
||||
@ -119,8 +202,8 @@ function setupFileSystem(backend)
|
||||
mfs.mount('/home/web_user/retroarch/bundle', xfs1);
|
||||
mfs.mount('/home/web_user/retroarch/userdata/content/downloads', xfs2);
|
||||
BrowserFS.initialize(mfs);
|
||||
var BFS = new BrowserFS.EmscriptenFS();
|
||||
FS.mount(BFS, {root: '/home'}, '/home');
|
||||
var BFS = new BrowserFS.EmscriptenFS(Module.FS, Module.PATH, Module.ERRNO_CODES);
|
||||
Module.FS.mount(BFS, {root: '/home'}, '/home');
|
||||
console.log("WEBPLAYER: " + backend + " filesystem initialization successful");
|
||||
}
|
||||
|
||||
@ -150,11 +233,12 @@ function startRetroArch()
|
||||
document.getElementById("btnMenu").disabled = false;
|
||||
document.getElementById("btnFullscreen").disabled = false;
|
||||
|
||||
Module["canvas"] = document.getElementById("canvas");
|
||||
Module["canvas"].addEventListener("click", () => Module["canvas"].focus());
|
||||
Module['callMain'](Module['arguments']);
|
||||
Module['resumeMainLoop']();
|
||||
document.getElementById('canvas').focus();
|
||||
Module['canvas'].focus();
|
||||
}
|
||||
|
||||
function selectFiles(files)
|
||||
{
|
||||
$('#btnAdd').addClass('disabled');
|
||||
@ -184,66 +268,13 @@ function selectFiles(files)
|
||||
function uploadData(data,name)
|
||||
{
|
||||
var dataView = new Uint8Array(data);
|
||||
FS.createDataFile('/', name, dataView, true, false);
|
||||
Module.FS.createDataFile('/', name, dataView, true, false);
|
||||
|
||||
var data = FS.readFile(name,{ encoding: 'binary' });
|
||||
FS.writeFile('/home/web_user/retroarch/userdata/content/' + name, data ,{ encoding: 'binary' });
|
||||
FS.unlink(name);
|
||||
var data = Module.FS.readFile(name,{ encoding: 'binary' });
|
||||
Module.FS.writeFile('/home/web_user/retroarch/userdata/content/' + name, data ,{ encoding: 'binary' });
|
||||
Module.FS.unlink(name);
|
||||
}
|
||||
|
||||
var encoder = new TextEncoder();
|
||||
var message_queue = [];
|
||||
|
||||
function retroArchSend(msg) {
|
||||
var bytes = encoder.encode(msg+"\n");
|
||||
message_queue.push([bytes,0]);
|
||||
}
|
||||
|
||||
var Module =
|
||||
{
|
||||
noInitialRun: true,
|
||||
arguments: ["-v", "--menu"],
|
||||
preRun: [
|
||||
function() {
|
||||
function stdin() {
|
||||
// Return ASCII code of character, or null if no input
|
||||
while(message_queue.length > 0){
|
||||
var msg = message_queue[0][0];
|
||||
var index = message_queue[0][1];
|
||||
if(index >= msg.length) {
|
||||
message_queue.shift();
|
||||
} else {
|
||||
message_queue[0][1] = index+1;
|
||||
// assumption: msg is a uint8array
|
||||
return msg[index];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
FS.init(stdin);
|
||||
}
|
||||
],
|
||||
postRun: [],
|
||||
onRuntimeInitialized: function()
|
||||
{
|
||||
appInitialized();
|
||||
},
|
||||
print: function(text)
|
||||
{
|
||||
console.log(text);
|
||||
},
|
||||
printErr: function(text)
|
||||
{
|
||||
console.log(text);
|
||||
},
|
||||
canvas: document.getElementById('canvas'),
|
||||
totalDependencies: 0,
|
||||
monitorRunDependencies: function(left)
|
||||
{
|
||||
this.totalDependencies = Math.max(this.totalDependencies, left);
|
||||
}
|
||||
};
|
||||
|
||||
function switchCore(corename) {
|
||||
localStorage.setItem("core", corename);
|
||||
}
|
||||
@ -258,7 +289,7 @@ function switchStorage(backend) {
|
||||
|
||||
// When the browser has loaded everything.
|
||||
$(function() {
|
||||
// Enable all available ToolTips.
|
||||
// Enable all available ToolTips.
|
||||
$('.tooltip-enable').tooltip({
|
||||
placement: 'right'
|
||||
});
|
||||
@ -273,74 +304,77 @@ $(function() {
|
||||
/**
|
||||
* Attempt to disable some default browser keys.
|
||||
*/
|
||||
var keys = {
|
||||
9: "tab",
|
||||
13: "enter",
|
||||
16: "shift",
|
||||
18: "alt",
|
||||
27: "esc",
|
||||
33: "rePag",
|
||||
34: "avPag",
|
||||
35: "end",
|
||||
36: "home",
|
||||
37: "left",
|
||||
38: "up",
|
||||
39: "right",
|
||||
40: "down",
|
||||
112: "F1",
|
||||
113: "F2",
|
||||
114: "F3",
|
||||
115: "F4",
|
||||
116: "F5",
|
||||
117: "F6",
|
||||
118: "F7",
|
||||
119: "F8",
|
||||
120: "F9",
|
||||
121: "F10",
|
||||
122: "F11",
|
||||
123: "F12"
|
||||
};
|
||||
window.addEventListener('keydown', function (e) {
|
||||
if (keys[e.which]) {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
var keys = {
|
||||
9: "tab",
|
||||
13: "enter",
|
||||
16: "shift",
|
||||
18: "alt",
|
||||
27: "esc",
|
||||
33: "rePag",
|
||||
34: "avPag",
|
||||
35: "end",
|
||||
36: "home",
|
||||
37: "left",
|
||||
38: "up",
|
||||
39: "right",
|
||||
40: "down",
|
||||
112: "F1",
|
||||
113: "F2",
|
||||
114: "F3",
|
||||
115: "F4",
|
||||
116: "F5",
|
||||
117: "F6",
|
||||
118: "F7",
|
||||
119: "F8",
|
||||
120: "F9",
|
||||
121: "F10",
|
||||
122: "F11",
|
||||
123: "F12"
|
||||
};
|
||||
window.addEventListener('keydown', function (e) {
|
||||
if (keys[e.which]) {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
// Switch the core when selecting one.
|
||||
$('#core-selector a').click(function () {
|
||||
var coreChoice = $(this).data('core');
|
||||
switchCore(coreChoice);
|
||||
});
|
||||
|
||||
// Find which core to load.
|
||||
var core = localStorage.getItem("core", core);
|
||||
if (!core) {
|
||||
core = 'gambatte';
|
||||
}
|
||||
loadCore(core);
|
||||
});
|
||||
|
||||
function loadCore(core) {
|
||||
// Make the core the selected core in the UI.
|
||||
var coreTitle = $('#core-selector a[data-core="' + core + '"]').addClass('active').text();
|
||||
$('#dropdownMenu1').text(coreTitle);
|
||||
|
||||
// Load the Core's related JavaScript.
|
||||
$.getScript(core + '_libretro.js', function ()
|
||||
{
|
||||
$('#icnRun').removeClass('fa-spinner').removeClass('fa-spin');
|
||||
$('#icnRun').addClass('fa-play');
|
||||
$('#lblDrop').removeClass('active');
|
||||
$('#lblLocal').addClass('active');
|
||||
idbfsInit();
|
||||
});
|
||||
});
|
||||
import("./"+core+"_libretro.js").then(script => {
|
||||
script.default(Module).then(mod => {
|
||||
Module = mod;
|
||||
$('#icnRun').removeClass('fa-spinner').removeClass('fa-spin');
|
||||
$('#icnRun').addClass('fa-play');
|
||||
$('#lblDrop').removeClass('active');
|
||||
$('#lblLocal').addClass('active');
|
||||
idbfsInit();
|
||||
}).catch(err => { console.error("Couldn't instantiate module",err); throw err; });
|
||||
}).catch(err => { console.error("Couldn't load script",err); throw err; });
|
||||
}
|
||||
|
||||
function keyPress(k)
|
||||
{
|
||||
function kp(k, event) {
|
||||
var oEvent = new KeyboardEvent(event, { code: k });
|
||||
|
||||
document.dispatchEvent(oEvent);
|
||||
document.getElementById('canvas').focus();
|
||||
}
|
||||
kp(k, "keydown");
|
||||
setTimeout(function(){kp(k, "keyup")}, 50);
|
||||
}
|
||||
|
||||
kp = function(k, event) {
|
||||
var oEvent = new KeyboardEvent(event, { code: k });
|
||||
|
||||
document.dispatchEvent(oEvent);
|
||||
document.getElementById('canvas').focus();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user