summaryrefslogtreecommitdiff
path: root/src/video/sdl2_v.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video/sdl2_v.cpp')
-rw-r--r--src/video/sdl2_v.cpp45
1 files changed, 41 insertions, 4 deletions
diff --git a/src/video/sdl2_v.cpp b/src/video/sdl2_v.cpp
index 09d0e8a0b..68b0aa983 100644
--- a/src/video/sdl2_v.cpp
+++ b/src/video/sdl2_v.cpp
@@ -27,6 +27,10 @@
#include <mutex>
#include <condition_variable>
#include <algorithm>
+#ifdef __EMSCRIPTEN__
+# include <emscripten.h>
+# include <emscripten/html5.h>
+#endif
#include "../safeguards.h"
@@ -673,7 +677,19 @@ void VideoDriver_SDL::LoopOnce()
InteractiveRandom(); // randomness
while (PollEvent() == -1) {}
- if (_exit_game) return;
+ if (_exit_game) {
+#ifdef __EMSCRIPTEN__
+ /* Emscripten is event-driven, and as such the main loop is inside
+ * the browser. So if _exit_game goes true, the main loop ends (the
+ * cancel call), but we still have to call the cleanup that is
+ * normally done at the end of the main loop for non-Emscripten.
+ * After that, Emscripten just halts, and the HTML shows a nice
+ * "bye, see you next time" message. */
+ emscripten_cancel_main_loop();
+ MainLoopCleanup();
+#endif
+ return;
+ }
mod = SDL_GetModState();
keys = SDL_GetKeyboardState(&numkeys);
@@ -722,9 +738,17 @@ void VideoDriver_SDL::LoopOnce()
_local_palette = _cur_palette;
} else {
/* Release the thread while sleeping */
- if (_draw_mutex != nullptr) draw_lock.unlock();
- CSleep(1);
- if (_draw_mutex != nullptr) draw_lock.lock();
+ if (_draw_mutex != nullptr) {
+ draw_lock.unlock();
+ CSleep(1);
+ draw_lock.lock();
+ } else {
+/* Emscripten is running an event-based mainloop; there is already some
+ * downtime between each iteration, so no need to sleep. */
+#ifndef __EMSCRIPTEN__
+ CSleep(1);
+#endif
+ }
NetworkDrawChatMessage();
DrawMouseCursor();
@@ -778,6 +802,10 @@ void VideoDriver_SDL::MainLoop()
DEBUG(driver, 1, "SDL2: using %sthreads", _draw_threaded ? "" : "no ");
+#ifdef __EMSCRIPTEN__
+ /* Run the main loop event-driven, based on RequestAnimationFrame. */
+ emscripten_set_main_loop_arg(&this->EmscriptenLoop, this, 0, 1);
+#else
while (!_exit_game) {
LoopOnce();
}
@@ -803,6 +831,15 @@ void VideoDriver_SDL::MainLoopCleanup()
_draw_mutex = nullptr;
_draw_signal = nullptr;
}
+
+#ifdef __EMSCRIPTEN__
+ emscripten_exit_pointerlock();
+ /* In effect, the game ends here. As emscripten_set_main_loop() caused
+ * the stack to be unwound, the code after MainLoop() in
+ * openttd_main() is never executed. */
+ EM_ASM(if (window["openttd_syncfs"]) openttd_syncfs());
+ EM_ASM(if (window["openttd_exit"]) openttd_exit());
+#endif
}
bool VideoDriver_SDL::ChangeResolution(int w, int h)