diff --git a/binding-mruby/binding-mruby.cpp b/binding-mruby/binding-mruby.cpp index 7cb0b64..52f88c6 100644 --- a/binding-mruby/binding-mruby.cpp +++ b/binding-mruby/binding-mruby.cpp @@ -52,6 +52,10 @@ #include +#ifdef __EMSCRIPTEN__ +#include +#endif + static void mrbBindingExecute(); static void mrbBindingTerminate(); static void mrbBindingReset(); @@ -244,6 +248,57 @@ runMrbFile(mrb_state *mrb, const char *filename) fclose(f); } +mrb_state * static_mrb; + +#ifdef __EMSCRIPTEN__ +EM_JS(int, jsSkipFrame, (), { + // Initialize + const targetRate = window.skfTargetFrameRate || 40; + if (!window.skfFrameTimings) { + window.skfFrameTimings = []; + window.skfPreviousRate = targetRate; + } + + // Get current time + const ctime = performance.now(); + + // Wait till we have n elements + if (window.skfFrameTimings.length < (window.skfNumFrames || 8)) { + window.skfFrameTimings.push(ctime); + return 0; + } + + // Get average framerate + const framerate = 1000 / ((ctime - window.skfFrameTimings[0]) / window.skfFrameTimings.length); + + // Proportional error + const Pe = framerate - targetRate; + + // Derivative error + const De = (window.skfPreviousRate - framerate); + + // Set previous rate + window.skfPreviousRate = framerate; + + // Drop frame if necessary + if (Pe - De - 1 > 0) { + return 1; + } + + // Add the timing + window.skfFrameTimings.shift(); + window.skfFrameTimings.push(ctime); + return 0; +}); +#endif + +void main_update_loop() { +#ifdef __EMSCRIPTEN__ + if (jsSkipFrame() == 1) return; +#endif + mrb_load_nstring_cxt(static_mrb, "main_update_loop", 16, NULL); +} + static void runRMXPScripts(mrb_state *mrb, mrbc_context *ctx) { @@ -368,6 +423,11 @@ runRMXPScripts(mrb_state *mrb, mrbc_context *ctx) } } +#ifdef __EMSCRIPTEN__ + static_mrb = mrb; + emscripten_set_main_loop(main_update_loop, 0, true); +#endif + mrb_close(scriptMrb); } diff --git a/shell.html b/shell.html index 7bb360c..e32ed46 100644 --- a/shell.html +++ b/shell.html @@ -171,7 +171,7 @@ } window.onerror = function() { - alert("An error occured!") + console.error("An error occured!") }; window.fileLoadedAsync = function(file) { diff --git a/src/config.cpp b/src/config.cpp index a782f61..f7f5f6e 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -191,7 +191,7 @@ void Config::read(int argc, char *argv[]) PO_DESC_ALL; gameFolder = "game"; - fixedFramerate = 40; + fixedFramerate = -1; syncToRefreshrate = false; rgssVersion = 1; defScreenW = 640; @@ -199,6 +199,7 @@ void Config::read(int argc, char *argv[]) enableBlitting = false; winResizable = false; windowTitle = "KN_E"; + frameSkip = false; #undef PO_DESC #undef PO_DESC_ALL diff --git a/src/main.cpp b/src/main.cpp index 59cde9d..c7ff82a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -159,6 +159,10 @@ int rgssThreadFun(void *userdata) /* Start script execution */ scriptBinding->execute(); +#ifdef __EMSCRIPTEN + return 0; +#endif + threadData->rqTermAck.set(); threadData->ethread->requestTerminate();