mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-22 23:49:50 +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 ($(TARGET),)
|
||||||
ifeq ($(LIBRETRO),)
|
ifeq ($(LIBRETRO),)
|
||||||
TARGET := retroarch.js
|
TARGET := retroarch.js
|
||||||
|
LIBRETRO = dummy
|
||||||
else
|
else
|
||||||
TARGET := $(LIBRETRO)_libretro.js
|
TARGET := $(LIBRETRO)_libretro.js
|
||||||
endif
|
endif
|
||||||
@ -48,7 +49,6 @@ HAVE_7ZIP = 1
|
|||||||
HAVE_BSV_MOVIE = 1
|
HAVE_BSV_MOVIE = 1
|
||||||
HAVE_AL = 1
|
HAVE_AL = 1
|
||||||
|
|
||||||
|
|
||||||
# WARNING -- READ BEFORE ENABLING
|
# WARNING -- READ BEFORE ENABLING
|
||||||
# The rwebaudio driver is known to have several audio bugs, such as
|
# The rwebaudio driver is known to have several audio bugs, such as
|
||||||
# minor crackling, or the entire page freezing/crashing.
|
# 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:
|
#if you compile with SDL2 flag add this Emscripten flag "-s USE_SDL=2" to LDFLAGS:
|
||||||
|
|
||||||
LIBS := -s USE_ZLIB=1
|
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']" \
|
LDFLAGS := -L. --no-heap-copy -s $(LIBS) -s TOTAL_MEMORY=$(MEMORY) -s NO_EXIT_RUNTIME=0 -s FULL_ES2=1 \
|
||||||
-s ALLOW_MEMORY_GROWTH=1 -s EXPORTED_FUNCTIONS="['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_load_state', '_cmd_take_screenshot']" \
|
-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_errno_codes.js \
|
||||||
--js-library emscripten/library_rwebcam.js
|
--js-library emscripten/library_rwebcam.js
|
||||||
|
|
||||||
@ -102,7 +105,10 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(ASYNC), 1)
|
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
|
endif
|
||||||
|
|
||||||
ifeq ($(HAVE_SDL2), 1)
|
ifeq ($(HAVE_SDL2), 1)
|
||||||
@ -127,8 +133,8 @@ ifneq ($(V), 1)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(DEBUG), 1)
|
ifeq ($(DEBUG), 1)
|
||||||
LDFLAGS += -O0 -g
|
LDFLAGS += -O0 -g -gsource-map -s SAFE_HEAP=1 -s STACK_OVERFLOW_CHECK=2 -s ASSERTIONS=1
|
||||||
CFLAGS += -O0 -g
|
CFLAGS += -O0 -g -gsource-map -s SAFE_HEAP=1 -s SAFE_HEAP_LOG=1 -s STACK_OVERFLOW_CHECK=2 -s ASSERTIONS=1
|
||||||
else
|
else
|
||||||
LDFLAGS += -O3 -s WASM=1
|
LDFLAGS += -O3 -s WASM=1
|
||||||
# WARNING: some optimizations can break some cores (ex: LTO breaks tyrquake)
|
# WARNING: some optimizations can break some cores (ex: LTO breaks tyrquake)
|
||||||
@ -139,7 +145,12 @@ else
|
|||||||
CFLAGS += -O3
|
CFLAGS += -O3
|
||||||
endif
|
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']"
|
# -s EXPORTED_FUNCTIONS="['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_take_screenshot']"
|
||||||
|
|
||||||
RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
|
RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
|
||||||
|
@ -247,8 +247,8 @@ for f in `ls -v *_${platform}.${EXT}`; do
|
|||||||
if [ $MAKEFILE_GRIFFIN = "yes" ]; then
|
if [ $MAKEFILE_GRIFFIN = "yes" ]; then
|
||||||
make -C ../ -f Makefile.griffin $OPTS platform=${platform} $whole_archive $big_stack -j3 || exit 1
|
make -C ../ -f Makefile.griffin $OPTS platform=${platform} $whole_archive $big_stack -j3 || exit 1
|
||||||
elif [ $PLATFORM = "emscripten" ]; then
|
elif [ $PLATFORM = "emscripten" ]; then
|
||||||
echo "BUILD COMMAND: make -C ../ -f Makefile.emscripten PTHREAD=$pthread ASYNC=$async LTO=$lto -j7 TARGET=${name}_libretro.js"
|
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 TARGET=${name}_libretro.js || exit 1
|
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
|
elif [ $PLATFORM = "unix" ]; then
|
||||||
make -C ../ -f Makefile LINK=g++ $whole_archive $big_stack -j3 || exit 1
|
make -C ../ -f Makefile LINK=g++ $whole_archive $big_stack -j3 || exit 1
|
||||||
elif [ $PLATFORM = "ctr" ]; then
|
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();
|
dummyErrnoCodes();
|
||||||
|
|
||||||
emscripten_set_canvas_element_size("#canvas", 800, 600);
|
EM_ASM({
|
||||||
emscripten_set_element_css_size("#canvas", 800.0, 600.0);
|
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);
|
emscripten_set_main_loop(emscripten_mainloop, 0, 0);
|
||||||
rarch_main(argc, argv, NULL);
|
rarch_main(argc, argv, NULL);
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ static void gfx_ctx_emscripten_get_canvas_size(int *width, int *height)
|
|||||||
|
|
||||||
if (!is_fullscreen)
|
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)
|
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)
|
if ( (input_width != emscripten->fb_width)
|
||||||
|| (input_height != emscripten->fb_height))
|
|| (input_height != emscripten->fb_height))
|
||||||
{
|
{
|
||||||
r = emscripten_set_canvas_element_size("#canvas",
|
r = emscripten_set_canvas_element_size("!canvas",
|
||||||
input_width, input_height);
|
input_width, input_height);
|
||||||
|
|
||||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||||
RARCH_ERR("[EMSCRIPTEN/EGL]: error resizing canvas: %d\n", r);
|
RARCH_ERR("[EMSCRIPTEN/EGL]: error resizing canvas: %d\n", r);
|
||||||
|
|
||||||
/* fix Module.requestFullscreen messing with the canvas size */
|
/* 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);
|
(double)input_width, (double)input_height);
|
||||||
|
|
||||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||||
@ -194,7 +194,7 @@ static void *gfx_ctx_emscripten_init(void *video_driver)
|
|||||||
* be grabbed? */
|
* be grabbed? */
|
||||||
if ( (emscripten->initial_width == 0)
|
if ( (emscripten->initial_width == 0)
|
||||||
|| (emscripten->initial_height == 0))
|
|| (emscripten->initial_height == 0))
|
||||||
emscripten_get_canvas_element_size("#canvas",
|
emscripten_get_canvas_element_size("!canvas",
|
||||||
&emscripten->initial_width,
|
&emscripten->initial_width,
|
||||||
&emscripten->initial_height);
|
&emscripten->initial_height);
|
||||||
|
|
||||||
|
@ -291,7 +291,7 @@ static void *rwebinput_input_init(const char *joypad_driver)
|
|||||||
rwebinput_generate_lut();
|
rwebinput_generate_lut();
|
||||||
|
|
||||||
r = emscripten_set_keydown_callback(
|
r = emscripten_set_keydown_callback(
|
||||||
EMSCRIPTEN_EVENT_TARGET_DOCUMENT, rwebinput, false,
|
"!canvas", rwebinput, false,
|
||||||
rwebinput_keyboard_cb);
|
rwebinput_keyboard_cb);
|
||||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||||
{
|
{
|
||||||
@ -300,7 +300,7 @@ static void *rwebinput_input_init(const char *joypad_driver)
|
|||||||
}
|
}
|
||||||
|
|
||||||
r = emscripten_set_keyup_callback(
|
r = emscripten_set_keyup_callback(
|
||||||
EMSCRIPTEN_EVENT_TARGET_DOCUMENT, rwebinput, false,
|
"!canvas", rwebinput, false,
|
||||||
rwebinput_keyboard_cb);
|
rwebinput_keyboard_cb);
|
||||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||||
{
|
{
|
||||||
@ -309,7 +309,7 @@ static void *rwebinput_input_init(const char *joypad_driver)
|
|||||||
}
|
}
|
||||||
|
|
||||||
r = emscripten_set_keypress_callback(
|
r = emscripten_set_keypress_callback(
|
||||||
EMSCRIPTEN_EVENT_TARGET_DOCUMENT, rwebinput, false,
|
"!canvas", rwebinput, false,
|
||||||
rwebinput_keyboard_cb);
|
rwebinput_keyboard_cb);
|
||||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
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);
|
"[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);
|
rwebinput_mouse_cb);
|
||||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
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);
|
"[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);
|
rwebinput_mouse_cb);
|
||||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
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);
|
"[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);
|
rwebinput_mouse_cb);
|
||||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
||||||
{
|
{
|
||||||
@ -342,7 +342,7 @@ static void *rwebinput_input_init(const char *joypad_driver)
|
|||||||
}
|
}
|
||||||
|
|
||||||
r = emscripten_set_wheel_callback(
|
r = emscripten_set_wheel_callback(
|
||||||
EMSCRIPTEN_EVENT_TARGET_DOCUMENT, rwebinput, false,
|
"!canvas", rwebinput, false,
|
||||||
rwebinput_wheel_cb);
|
rwebinput_wheel_cb);
|
||||||
if (r != EMSCRIPTEN_RESULT_SUCCESS)
|
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)
|
static void rwebinput_grab_mouse(void *data, bool state)
|
||||||
{
|
{
|
||||||
if (state)
|
if (state)
|
||||||
emscripten_request_pointerlock("#canvas", EM_TRUE);
|
emscripten_request_pointerlock("!canvas", EM_TRUE);
|
||||||
else
|
else
|
||||||
emscripten_exit_pointerlock();
|
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
|
#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
|
#define PATH_MAX_LENGTH 512
|
||||||
#else
|
#else
|
||||||
#define PATH_MAX_LENGTH 4096
|
#define PATH_MAX_LENGTH 4096
|
||||||
|
@ -6,6 +6,89 @@
|
|||||||
var BrowserFS = BrowserFS;
|
var BrowserFS = BrowserFS;
|
||||||
var afs;
|
var afs;
|
||||||
var initializationCount = 0;
|
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()
|
function cleanupStorage()
|
||||||
{
|
{
|
||||||
@ -119,8 +202,8 @@ function setupFileSystem(backend)
|
|||||||
mfs.mount('/home/web_user/retroarch/bundle', xfs1);
|
mfs.mount('/home/web_user/retroarch/bundle', xfs1);
|
||||||
mfs.mount('/home/web_user/retroarch/userdata/content/downloads', xfs2);
|
mfs.mount('/home/web_user/retroarch/userdata/content/downloads', xfs2);
|
||||||
BrowserFS.initialize(mfs);
|
BrowserFS.initialize(mfs);
|
||||||
var BFS = new BrowserFS.EmscriptenFS();
|
var BFS = new BrowserFS.EmscriptenFS(Module.FS, Module.PATH, Module.ERRNO_CODES);
|
||||||
FS.mount(BFS, {root: '/home'}, '/home');
|
Module.FS.mount(BFS, {root: '/home'}, '/home');
|
||||||
console.log("WEBPLAYER: " + backend + " filesystem initialization successful");
|
console.log("WEBPLAYER: " + backend + " filesystem initialization successful");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,11 +233,12 @@ function startRetroArch()
|
|||||||
document.getElementById("btnMenu").disabled = false;
|
document.getElementById("btnMenu").disabled = false;
|
||||||
document.getElementById("btnFullscreen").disabled = false;
|
document.getElementById("btnFullscreen").disabled = false;
|
||||||
|
|
||||||
|
Module["canvas"] = document.getElementById("canvas");
|
||||||
|
Module["canvas"].addEventListener("click", () => Module["canvas"].focus());
|
||||||
Module['callMain'](Module['arguments']);
|
Module['callMain'](Module['arguments']);
|
||||||
Module['resumeMainLoop']();
|
Module['resumeMainLoop']();
|
||||||
document.getElementById('canvas').focus();
|
Module['canvas'].focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectFiles(files)
|
function selectFiles(files)
|
||||||
{
|
{
|
||||||
$('#btnAdd').addClass('disabled');
|
$('#btnAdd').addClass('disabled');
|
||||||
@ -184,66 +268,13 @@ function selectFiles(files)
|
|||||||
function uploadData(data,name)
|
function uploadData(data,name)
|
||||||
{
|
{
|
||||||
var dataView = new Uint8Array(data);
|
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' });
|
var data = Module.FS.readFile(name,{ encoding: 'binary' });
|
||||||
FS.writeFile('/home/web_user/retroarch/userdata/content/' + name, data ,{ encoding: 'binary' });
|
Module.FS.writeFile('/home/web_user/retroarch/userdata/content/' + name, data ,{ encoding: 'binary' });
|
||||||
FS.unlink(name);
|
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) {
|
function switchCore(corename) {
|
||||||
localStorage.setItem("core", corename);
|
localStorage.setItem("core", corename);
|
||||||
}
|
}
|
||||||
@ -258,7 +289,7 @@ function switchStorage(backend) {
|
|||||||
|
|
||||||
// When the browser has loaded everything.
|
// When the browser has loaded everything.
|
||||||
$(function() {
|
$(function() {
|
||||||
// Enable all available ToolTips.
|
// Enable all available ToolTips.
|
||||||
$('.tooltip-enable').tooltip({
|
$('.tooltip-enable').tooltip({
|
||||||
placement: 'right'
|
placement: 'right'
|
||||||
});
|
});
|
||||||
@ -273,74 +304,77 @@ $(function() {
|
|||||||
/**
|
/**
|
||||||
* Attempt to disable some default browser keys.
|
* Attempt to disable some default browser keys.
|
||||||
*/
|
*/
|
||||||
var keys = {
|
var keys = {
|
||||||
9: "tab",
|
9: "tab",
|
||||||
13: "enter",
|
13: "enter",
|
||||||
16: "shift",
|
16: "shift",
|
||||||
18: "alt",
|
18: "alt",
|
||||||
27: "esc",
|
27: "esc",
|
||||||
33: "rePag",
|
33: "rePag",
|
||||||
34: "avPag",
|
34: "avPag",
|
||||||
35: "end",
|
35: "end",
|
||||||
36: "home",
|
36: "home",
|
||||||
37: "left",
|
37: "left",
|
||||||
38: "up",
|
38: "up",
|
||||||
39: "right",
|
39: "right",
|
||||||
40: "down",
|
40: "down",
|
||||||
112: "F1",
|
112: "F1",
|
||||||
113: "F2",
|
113: "F2",
|
||||||
114: "F3",
|
114: "F3",
|
||||||
115: "F4",
|
115: "F4",
|
||||||
116: "F5",
|
116: "F5",
|
||||||
117: "F6",
|
117: "F6",
|
||||||
118: "F7",
|
118: "F7",
|
||||||
119: "F8",
|
119: "F8",
|
||||||
120: "F9",
|
120: "F9",
|
||||||
121: "F10",
|
121: "F10",
|
||||||
122: "F11",
|
122: "F11",
|
||||||
123: "F12"
|
123: "F12"
|
||||||
};
|
};
|
||||||
window.addEventListener('keydown', function (e) {
|
window.addEventListener('keydown', function (e) {
|
||||||
if (keys[e.which]) {
|
if (keys[e.which]) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Switch the core when selecting one.
|
// Switch the core when selecting one.
|
||||||
$('#core-selector a').click(function () {
|
$('#core-selector a').click(function () {
|
||||||
var coreChoice = $(this).data('core');
|
var coreChoice = $(this).data('core');
|
||||||
switchCore(coreChoice);
|
switchCore(coreChoice);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Find which core to load.
|
// Find which core to load.
|
||||||
var core = localStorage.getItem("core", core);
|
var core = localStorage.getItem("core", core);
|
||||||
if (!core) {
|
if (!core) {
|
||||||
core = 'gambatte';
|
core = 'gambatte';
|
||||||
}
|
}
|
||||||
|
loadCore(core);
|
||||||
|
});
|
||||||
|
|
||||||
|
function loadCore(core) {
|
||||||
// Make the core the selected core in the UI.
|
// Make the core the selected core in the UI.
|
||||||
var coreTitle = $('#core-selector a[data-core="' + core + '"]').addClass('active').text();
|
var coreTitle = $('#core-selector a[data-core="' + core + '"]').addClass('active').text();
|
||||||
$('#dropdownMenu1').text(coreTitle);
|
$('#dropdownMenu1').text(coreTitle);
|
||||||
|
|
||||||
// Load the Core's related JavaScript.
|
// Load the Core's related JavaScript.
|
||||||
$.getScript(core + '_libretro.js', function ()
|
import("./"+core+"_libretro.js").then(script => {
|
||||||
{
|
script.default(Module).then(mod => {
|
||||||
$('#icnRun').removeClass('fa-spinner').removeClass('fa-spin');
|
Module = mod;
|
||||||
$('#icnRun').addClass('fa-play');
|
$('#icnRun').removeClass('fa-spinner').removeClass('fa-spin');
|
||||||
$('#lblDrop').removeClass('active');
|
$('#icnRun').addClass('fa-play');
|
||||||
$('#lblLocal').addClass('active');
|
$('#lblDrop').removeClass('active');
|
||||||
idbfsInit();
|
$('#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 keyPress(k)
|
||||||
{
|
{
|
||||||
|
function kp(k, event) {
|
||||||
|
var oEvent = new KeyboardEvent(event, { code: k });
|
||||||
|
|
||||||
|
document.dispatchEvent(oEvent);
|
||||||
|
document.getElementById('canvas').focus();
|
||||||
|
}
|
||||||
kp(k, "keydown");
|
kp(k, "keydown");
|
||||||
setTimeout(function(){kp(k, "keyup")}, 50);
|
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