Li-Ri 3.1.6 for fredygames.com (GPL-2.0-or-later or GPL-3.0, like the game). Every change is active only when building with Emscripten (__EMSCRIPTEN__): - menu.cc: Sleeping() yields to the browser (emscripten_sleep(0)) when a frame is late, so the game's own loops never block the page (the build uses Asyncify; SDL_Delay already yields otherwise); - menu.cc, main.cc: the window is a fixed 800x600 canvas, never fullscreen (the page scales it and has its own fullscreen button), so the fullscreen option does nothing; - main.cc: fredygames_save(), which the page calls when the tab is hidden or closed: the game only writes li-ri.ini (options, unlocked levels, high scores) on exit; - sprite.cc: language files other than English are downloaded on demand from lang/.gz next to the page and decompressed with DecompressionStream, instead of being preloaded (about 6 MB each). diff --git a/src/main.cc b/src/main.cc index 1100443..486fbda 100644 --- a/src/main.cc +++ b/src/main.cc @@ -33,6 +33,9 @@ #include #include +#ifdef __EMSCRIPTEN__ +#include +#endif #include "config.h" #include "preference.h" #include "game.h" @@ -82,6 +85,15 @@ void InitPref() Utils::LoadPref(); } +#ifdef __EMSCRIPTEN__ +// Called by the page when the tab is hidden or closed: the game only writes its preferences (options, +// unlocked levels, high scores) on exit. +extern "C" EMSCRIPTEN_KEEPALIVE void fredygames_save() +{ + Utils::SauvePref(); +} +#endif + /*** Preogramme principale ***/ /*****************************/ int main(int narg, char *argv[]) @@ -108,6 +120,10 @@ int main(int narg, char *argv[]) // Demande la resolution Video int vOption = SDL_WINDOW_RESIZABLE; +#ifdef __EMSCRIPTEN__ + vOption = 0; + Pref.FullScreen = false; +#endif if (Pref.FullScreen) { vOption |= SDL_WINDOW_FULLSCREEN_DESKTOP; } diff --git a/src/menu.cc b/src/menu.cc index 6432693..9cee206 100644 --- a/src/menu.cc +++ b/src/menu.cc @@ -28,6 +28,9 @@ #include // for SDL_MIX_MAXVOLUME #include // for SDL_PollEvent, SDL_Event, SDL_KEYDOWN #include // for SDL_StopTextInput, SDL_StartTextInput +#ifdef __EMSCRIPTEN__ +#include +#endif #include // for SDLK_F12, SDLK_RETURN, SDLK_ESCAPE #include // for SDL_ShowCursor #include // for SDL_Rect @@ -73,6 +76,11 @@ void Sleeping() SDL_Delay(delay); Horloge = SDL_GetTicks(); } +#ifdef __EMSCRIPTEN__ + else { + emscripten_sleep(0); + } +#endif } /*** Ajoute une entrée dans le tableau des boutons ***/ @@ -93,6 +101,11 @@ void AddBouton(int Num, e_Sprite NumSp, int X, int Y) /***********************/ void ChangeVideo() { +#ifdef __EMSCRIPTEN__ + // The page has its own fullscreen button. + Pref.FullScreen = false; + return; +#endif Uint32 flag = SDL_WINDOW_RESIZABLE; if (Pref.FullScreen) { flag = SDL_WINDOW_FULLSCREEN_DESKTOP; diff --git a/src/sprite.cc b/src/sprite.cc index ea3b243..edacd05 100644 --- a/src/sprite.cc +++ b/src/sprite.cc @@ -30,6 +30,21 @@ #include "preference.h" #include "utils.h" +#ifdef __EMSCRIPTEN__ +#include +// Downloads lang/.gz next to the page, decompresses it and writes /. +EM_ASYNC_JS(void, fredygames_fetch, (const char *name), { + const file = UTF8ToString(name); + try { + const response = await fetch('lang/' + file + '.gz'); + if (!response.ok) return; + const data = await new Response(response.body.pipeThrough(new DecompressionStream('gzip'))).arrayBuffer(); + FS.writeFile('/' + file, new Uint8Array(data)); + } catch (e) { + } +}); +#endif + /*** Variables Globales ***/ /**************************/ extern SDL_Renderer *sdlRenderer; @@ -79,6 +94,11 @@ bool LoadLangue() char PathFile[512]; strcpy(PathFile, Langue[Pref.Langue]); +#ifdef __EMSCRIPTEN__ + if (Utils::FileExists(PathFile) == false) { + fredygames_fetch(PathFile); + } +#endif Utils::GetPath(PathFile); if (Utils::FileExists(PathFile) == false) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find '%s'", Langue[Pref.Langue]);