Add: support for emscripten (play-OpenTTD-in-the-browser)
Emscripten compiles to WASM, which can be loaded via HTML / JavaScript. This allows you to play OpenTTD inside a browser. Co-authored-by: milek7 <me@milek7.pl>
This commit is contained in:

committed by
Patric Stout

parent
2da07f7615
commit
d15dc9f40f
@@ -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)
|
||||
|
Reference in New Issue
Block a user