From 4344da65ab83b0ffbee3eaf04be7389a83324e69 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 27 Mar 2026 23:43:42 -0700
Subject: [PATCH] Use automatic persistent storage for Emscripten in the latest
SDL
---
CMakeLists.txt | 5 +++-
game/Maelstrom_Globals.h | 3 --
game/init.cpp | 40 +++++++-------------------
game/main.cpp | 7 +++++
utils/files.c | 61 ----------------------------------------
utils/files.h | 1 -
utils/prefs.cpp | 3 --
7 files changed, 21 insertions(+), 99 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2fa92b61..673e9088 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,6 +17,9 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIGURATION>")
# on Web targets, we need CMake to generate a HTML webpage.
if(EMSCRIPTEN)
set(CMAKE_EXECUTABLE_SUFFIX_CXX ".html" CACHE INTERNAL "")
+
+ # Enable persistent storage
+ set(SDL_EMSCRIPTEN_PERSISTENT_PATH /storage)
endif()
add_subdirectory(maclib)
@@ -203,7 +206,7 @@ target_link_libraries(${TARGET_NAME} PRIVATE SDL3::SDL3)
if(EMSCRIPTEN)
# Increase the default stack size
- target_link_options(${TARGET_NAME} PRIVATE -sSTACK_SIZE=1048576 -lidbfs.js)
+ target_link_options(${TARGET_NAME} PRIVATE -sSTACK_SIZE=1048576)
# on the web, we have to put the files inside of the webassembly
# somewhat unintuitively, this is done via a linker argument.
diff --git a/game/Maelstrom_Globals.h b/game/Maelstrom_Globals.h
index 51ede40d..69b239e0 100644
--- a/game/Maelstrom_Globals.h
+++ b/game/Maelstrom_Globals.h
@@ -43,9 +43,6 @@
#include "gameinfo.h"
#include "steam.h"
-#define MAELSTROM_ORGANIZATION "Ambrosia Software"
-#define MAELSTROM_NAME "Maelstrom"
-
// Preferences keys
#define PREFERENCES_RESOLUTION "Resolution"
#define PREFERENCES_HANDLE "Handle"
diff --git a/game/init.cpp b/game/init.cpp
index a590a35b..01e71c59 100644
--- a/game/init.cpp
+++ b/game/init.cpp
@@ -107,7 +107,6 @@ enum LoadingStage
LOAD_STAGE_BLITS25,
LOAD_STAGE_SHOTS,
LOAD_STAGE_SPRITES,
- LOAD_STAGE_FILESYSTEM,
LOAD_STAGE_COMPLETE
};
static int gLoadingStage = LOAD_STAGE_WAITING;
@@ -826,12 +825,18 @@ bool StartInitialization(int window_width, int window_height, Uint32 window_flag
gNetworkAvailable = NET_Init();
// -- Initialize some variables
- prefs = new Prefs(GAME_PREFS_FILE);
gLastHigh = -1;
- if (!InitFilesystem(MAELSTROM_ORGANIZATION, MAELSTROM_NAME)) {
- return false;
- }
+ // -- Create our scores file
+ LoadScores();
+
+ // -- Load our preferences files
+ prefs = new Prefs(GAME_PREFS_FILE);
+ prefs->Load();
+
+ // -- Load our controls
+ LoadControls();
+ InitPlayerControls();
/* Load the Maelstrom icon */
if (!LoadIcon(&icon)) {
@@ -904,8 +909,6 @@ bool StartInitialization(int window_width, int window_height, Uint32 window_flag
bool ContinueInitialization()
{
- bool failed;
-
switch (gLoadingStage) {
case LOAD_STAGE_STARTING:
/* -- Load in the prize CICN's */
@@ -968,29 +971,6 @@ bool ContinueInitialization()
return false;
}
- gLoadingStage = LOAD_STAGE_FILESYSTEM;
-
- // Fallthrough...
- //break;
-
- case LOAD_STAGE_FILESYSTEM:
- if (!FilesystemReady(&failed)) {
- if (failed) {
- return false;
- }
- break;
- }
-
- // -- Create our scores file
- LoadScores();
-
- // -- Load our preferences files
- prefs->Load();
-
- // -- Load our controls
- LoadControls();
- InitPlayerControls();
-
gLoadingStage = LOAD_STAGE_COMPLETE;
// Fallthrough...
diff --git a/game/main.cpp b/game/main.cpp
index 3c4a545c..40dae1b0 100644
--- a/game/main.cpp
+++ b/game/main.cpp
@@ -49,6 +49,9 @@
#include "../screenlib/UIElementCheckbox.h"
#include "../screenlib/UIElementEditbox.h"
+#define MAELSTROM_ORGANIZATION "Ambrosia Software"
+#define MAELSTROM_NAME "Maelstrom"
+
static const char *Version =
"Maelstrom v1.4.3 (GPL version 4.0.0) -- 10/08/2011 by Sam Lantinga\n";
@@ -158,6 +161,10 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
/* Initializing Steam can set up environment variables, so do this first */
InitSteam();
+ if ( !InitFilesystem(MAELSTROM_ORGANIZATION, MAELSTROM_NAME) ) {
+ return SDL_APP_FAILURE;
+ }
+
/* Seed the random number generator */
SeedRandom(0L);
diff --git a/utils/files.c b/utils/files.c
index 25ad7e44..1f057ff7 100644
--- a/utils/files.c
+++ b/utils/files.c
@@ -20,10 +20,6 @@
#include "files.h"
-#ifdef SDL_PLATFORM_EMSCRIPTEN
-#include <emscripten/emscripten.h>
-#endif
-
#ifndef PATH_MAX
#define PATH_MAX 256
#endif
@@ -39,29 +35,6 @@ bool InitFilesystem(const char *org, const char *app)
storage_org = org;
storage_app = app;
-#ifdef SDL_PLATFORM_EMSCRIPTEN
- char *prefpath = SDL_GetPrefPath(org, app);
- if (prefpath) {
- MAIN_THREAD_EM_ASM({
- const prefpath = UTF8ToString($0);
- FS.mkdirTree(prefpath);
- FS.mount(IDBFS, {}, prefpath);
- filesystem_ready = 0;
- FS.syncfs(true, function(err) {
- if (err) {
- console.log("Couldn't mount " + prefpath + ": " + err);
- filesystem_ready = -1;
- } else {
- //console.log("Filesystem ready");
- filesystem_ready = 1;
- }
- });
- }, prefpath);
-
- SDL_free(prefpath);
- }
-#endif // SDL_PLATFORM_EMSCRIPTEN
-
if (env) {
SDL_strlcpy(datapath, env, sizeof(datapath));
return true;
@@ -96,25 +69,6 @@ bool InitFilesystem(const char *org, const char *app)
#endif // MAELSTROM_DATA
}
-bool FilesystemReady(bool *failed)
-{
- *failed = false;
-
-#ifdef SDL_PLATFORM_EMSCRIPTEN
- int result = MAIN_THREAD_EM_ASM_INT({ return filesystem_ready; });
- switch (result) {
- case -1:
- *failed = true;
- return false;
- case 0:
- return false;
- default:
- return true;
- }
-#endif
- return true;
-}
-
SDL_IOStream *OpenRead(const char *file)
{
char path[PATH_MAX];
@@ -231,20 +185,5 @@ bool SaveUserFile(const char *file, SDL_IOStream *src)
result = false;
}
SDL_CloseIO(src);
-
-#ifdef SDL_PLATFORM_EMSCRIPTEN
- if (result) {
- MAIN_THREAD_EM_ASM({
- FS.syncfs(false, function(err) {
- if (err) {
- console.log("Couldn't save file: " + err);
- } else {
- //console.log("File saved!");
- }
- });
- });
- }
-#endif // SDL_PLATFORM_EMSCRIPTEN
-
return result;
}
diff --git a/utils/files.h b/utils/files.h
index d391f986..8f9cbe92 100644
--- a/utils/files.h
+++ b/utils/files.h
@@ -28,7 +28,6 @@ extern "C" {
#endif
bool InitFilesystem(const char *org, const char *app);
-bool FilesystemReady(bool *failed);
SDL_IOStream *OpenRead(const char *file);
diff --git a/utils/prefs.cpp b/utils/prefs.cpp
index 3d686c51..8f5de9ff 100644
--- a/utils/prefs.cpp
+++ b/utils/prefs.cpp
@@ -163,9 +163,6 @@ Prefs::SetString(const char *key, const char *value, bool dirty)
if (dirty) {
m_dirty = true;
-
- // Save immediately, in case we crash or are unloaded
- Save();
}
}