diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml
index dda4bfb1c4..f5eec2847c 100644
--- a/.github/workflows/ci-build.yml
+++ b/.github/workflows/ci-build.yml
@@ -90,20 +90,20 @@ jobs:
- name: Clang
compiler: clang
cxxcompiler: clang++
- libraries: libsdl2-dev nlohmann-json3-dev
+ libraries: libsdl2-dev
- name: GCC - SDL2
compiler: gcc
cxxcompiler: g++
- libraries: libsdl2-dev nlohmann-json3-dev
+ libraries: libsdl2-dev
- name: GCC - SDL1.2
compiler: gcc
cxxcompiler: g++
- libraries: libsdl1.2-dev nlohmann-json3-dev
+ libraries: libsdl1.2-dev
- name: GCC - Dedicated
compiler: gcc
cxxcompiler: g++
extra-cmake-parameters: -DOPTION_DEDICATED=ON -DCMAKE_CXX_FLAGS_INIT="-DRANDOM_DEBUG"
- # Compile without SDL / SDL2 / nlohmann-json, as that should compile fine too.
+ # Compile without SDL / SDL2, as that should compile fine too.
name: Linux (${{ matrix.name }})
@@ -139,6 +139,7 @@ jobs:
liblzma-dev \
libzstd-dev \
liblzo2-dev \
+ nlohmann-json3-dev \
${{ matrix.libraries }} \
zlib1g-dev \
# EOF
diff --git a/.github/workflows/release-source.yml b/.github/workflows/release-source.yml
index 4aac6414b8..e662f94caa 100644
--- a/.github/workflows/release-source.yml
+++ b/.github/workflows/release-source.yml
@@ -152,14 +152,18 @@ jobs:
- name: Generate survey key
id: survey_key
run: |
- #PAYLOAD='{"version":"${{ steps.metadata.outputs.version }}","type":"${{ vars.SURVEY_TYPE }}"}'
- #
- #echo "${{ secrets.SURVEY_SIGNING_KEY }}" > survey_signing_key.pem
- #SIGNATURE=$(echo -n "${PAYLOAD}" | openssl dgst -sha256 -sign survey_signing_key.pem | base64 -w0)
- #rm -f survey_signing_key.pem
- #
- #SURVEY_KEY=$(curl -f -s -X POST -d "${PAYLOAD}" -H "Content-Type: application/json" -H "X-Signature: ${SIGNATURE}" https://survey-participate.openttd.org/create-survey-key/${{ vars.SURVEY_TYPE }})
- SURVEY_KEY=""
+ if [ -z "${{ vars.SURVEY_TYPE }}" ]; then
+ echo "SURVEY_TYPE variable not found; most likely running in a fork. Skipping step."
+ SURVEY_KEY=""
+ else
+ PAYLOAD='{"version":"${{ steps.metadata.outputs.version }}","type":"${{ vars.SURVEY_TYPE }}"}'
+
+ echo "${{ secrets.SURVEY_SIGNING_KEY }}" > survey_signing_key.pem
+ SIGNATURE=$(echo -n "${PAYLOAD}" | openssl dgst -sha256 -sign survey_signing_key.pem | base64 -w0)
+ rm -f survey_signing_key.pem
+
+ SURVEY_KEY=$(curl -f -s -X POST -d "${PAYLOAD}" -H "Content-Type: application/json" -H "X-Signature: ${SIGNATURE}" https://survey-participate.openttd.org/create-survey-key/${{ vars.SURVEY_TYPE }})
+ fi
echo "survey_key=${SURVEY_KEY}" >> $GITHUB_OUTPUT
diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml
index 592ab3464b..7140c4a223 100644
--- a/.github/workflows/release-windows.yml
+++ b/.github/workflows/release-windows.yml
@@ -73,6 +73,13 @@ jobs:
zstd \
# EOF
+ # arm64-windows-static is not (yet) supported for breakpad.
+ if [ "${{ matrix.arch }}" != "arm64" ]; then
+ vcpkg install --triplet=${{ matrix.arch }}-windows-static \
+ breakpad \
+ # EOF
+ fi
+
- name: Install MSVC problem matcher
uses: ammaraskar/msvc-problem-matcher@master
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e1f9705447..a0f6ca71d6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -114,13 +114,14 @@ endif()
set(CMAKE_THREAD_PREFER_PTHREAD YES)
# Make sure we have Threads available.
find_package(Threads REQUIRED)
+# nlohmann is used for all our JSON needs.
+find_package(nlohmann_json REQUIRED)
find_package(ZLIB)
find_package(LibLZMA)
find_package(LZO)
find_package(ZSTD 1.4)
find_package(PNG)
-find_package(nlohmann_json)
if(WIN32 OR EMSCRIPTEN)
# Windows uses WinHttp for HTTP requests.
@@ -362,7 +363,7 @@ link_package(ZLIB TARGET ZLIB::ZLIB ENCOURAGED)
link_package(LIBLZMA TARGET LibLZMA::LibLZMA ENCOURAGED)
link_package(LZO)
link_package(ZSTD TARGET ZSTD::ZSTD RECOMMENDED)
-link_package(nlohmann_json ENCOURAGED)
+link_package(nlohmann_json)
if(NOT WIN32 AND NOT EMSCRIPTEN)
link_package(CURL ENCOURAGED)
diff --git a/COMPILING.md b/COMPILING.md
index df2e961c71..178b1fbaae 100644
--- a/COMPILING.md
+++ b/COMPILING.md
@@ -4,7 +4,7 @@
OpenTTD makes use of the following external libraries:
-- (encouraged) nlohmann-json: JSON handling
+- (required) nlohmann-json: JSON handling
- (encouraged) zlib: (de)compressing of old (0.3.0-1.0.5) savegames, content downloads,
heightmaps
- (encouraged) liblzma: (de)compressing of savegames (1.1.0 and later)
diff --git a/os/emscripten/pre.js b/os/emscripten/pre.js
index 31858b1894..8e46ae3460 100644
--- a/os/emscripten/pre.js
+++ b/os/emscripten/pre.js
@@ -1,4 +1,4 @@
-Module.arguments.push('-mnull', '-snull', '-vsdl:relative_mode');
+Module.arguments.push('-mnull', '-snull', '-vsdl');
Module['websocket'] = { url: function(host, port, proto) {
/* openttd.org hosts a WebSocket proxy for the content service. */
if (host == "content.openttd.org" && port == 3978 && proto == "tcp") {
@@ -30,46 +30,47 @@ Module.preRun.push(function() {
Module.addRunDependency('syncfs');
FS.syncfs(true, function (err) {
- /* FS.mkdir() tends to fail if parent folders do not exist. */
- if (!FS.analyzePath(content_download_dir).exists) {
- FS.mkdir(content_download_dir);
- }
- if (!FS.analyzePath(content_download_dir + '/baseset').exists) {
- FS.mkdir(content_download_dir + '/baseset');
- }
-
- /* Check if the OpenGFX baseset is already downloaded. */
- if (!FS.analyzePath(content_download_dir + '/baseset/opengfx-0.6.0.tar').exists) {
- window.openttd_downloaded_opengfx = true;
- FS.createPreloadedFile(content_download_dir + '/baseset', 'opengfx-0.6.0.tar', 'https://binaries.openttd.org/installer/emscripten/opengfx-0.6.0.tar', true, true);
- } else {
- /* Fake dependency increase, so the counter is stable. */
- Module.addRunDependency('opengfx');
- Module.removeRunDependency('opengfx');
- }
-
Module.removeRunDependency('syncfs');
});
window.openttd_syncfs_shown_warning = false;
- window.openttd_syncfs = function() {
+ window.openttd_syncfs = function(callback) {
/* Copy the virtual FS to the persistent storage. */
- FS.syncfs(false, function (err) { });
-
- /* On first time, warn the user about the volatile behaviour of
- * persistent storage. */
- if (!window.openttd_syncfs_shown_warning) {
- window.openttd_syncfs_shown_warning = true;
- Module.onWarningFs();
- }
+ FS.syncfs(false, function (err) {
+ /* On first time, warn the user about the volatile behaviour of
+ * persistent storage. */
+ if (!window.openttd_syncfs_shown_warning) {
+ window.openttd_syncfs_shown_warning = true;
+ Module.onWarningFs();
+ }
+
+ if (callback) callback();
+ });
}
window.openttd_exit = function() {
- Module.onExit();
+ window.openttd_syncfs(Module.onExit);
}
window.openttd_abort = function() {
- Module.onAbort();
+ window.openttd_syncfs(Module.onAbort);
+ }
+
+ window.openttd_bootstrap = function(current, total) {
+ Module.onBootstrap(current, total);
+ }
+
+ window.openttd_bootstrap_failed = function() {
+ Module.onBootstrapFailed();
+ }
+
+ window.openttd_bootstrap_reload = function() {
+ window.openttd_syncfs(function() {
+ Module.onBootstrapReload();
+ setTimeout(function() {
+ location.reload();
+ }, 1000);
+ });
}
window.openttd_server_list = function() {
@@ -123,11 +124,3 @@ Module.preRun.push(function() {
return ret;
}
});
-
-Module.postRun.push(function() {
- /* Check if we downloaded OpenGFX; if so, sync the virtual FS back to the
- * IDBFS so OpenGFX is stored persistent. */
- if (window['openttd_downloaded_opengfx']) {
- FS.syncfs(false, function (err) { });
- }
-});
diff --git a/os/emscripten/shell.html b/os/emscripten/shell.html
index af031c6df8..21f720e7e4 100644
--- a/os/emscripten/shell.html
+++ b/os/emscripten/shell.html
@@ -75,7 +75,6 @@
}
#message {
color: #101010;
- height: 54px;
padding: 4px 4px;
}
@@ -144,6 +143,8 @@
})(),
setStatus: function(text) {
+ if (document.getElementById("canvas").style.display == "none") return;
+
var m = text.match(/^([^(]+)\((\d+(\.\d+)?)\/(\d+)\)$/);
if (m) {
@@ -171,6 +172,27 @@
document.getElementById("message").innerHTML = "Preparing game ...";
},
+ onBootstrap: function(current, total) {
+ document.getElementById("canvas").style.display = "none";
+
+ document.getElementById("title").innerHTML = "Missing base graphics";
+ document.getElementById("message").innerHTML = "OpenTTD is downloading base graphics.
" + current + " / " + total + " bytes downloaded.";
+ },
+
+ onBootstrapFailed: function(current, total) {
+ document.getElementById("canvas").style.display = "none";
+
+ document.getElementById("title").innerHTML = "Missing base graphics";
+ document.getElementById("message").innerHTML = "Failed to download base graphics.
The game cannot start without base graphics.
Please check your Internet connection and/or the console log.
Reload your browser to try again.";
+ },
+
+ onBootstrapReload: function() {
+ document.getElementById("canvas").style.display = "none";
+
+ document.getElementById("title").innerHTML = "Missing base graphics";
+ document.getElementById("message").innerHTML = "Downloading base graphics done.
Your browser will reload to start the game.";
+ },
+
onExit: function() {
document.getElementById("canvas").style.display = "none";
diff --git a/src/bootstrap_gui.cpp b/src/bootstrap_gui.cpp
index 2399f318d4..2ebf6eab68 100644
--- a/src/bootstrap_gui.cpp
+++ b/src/bootstrap_gui.cpp
@@ -285,6 +285,76 @@ public:
#endif /* defined(WITH_FREETYPE) */
+#if defined(__EMSCRIPTEN__)
+# include
+# include "network/network.h"
+# include "network/network_content.h"
+# include "openttd.h"
+# include "video/video_driver.hpp"
+
+class BootstrapEmscripten : public ContentCallback {
+ bool downloading{false};
+ uint total_files{0};
+ uint total_bytes{0};
+ uint downloaded_bytes{0};
+
+public:
+ BootstrapEmscripten()
+ {
+ _network_content_client.AddCallback(this);
+ _network_content_client.Connect();
+ }
+
+ ~BootstrapEmscripten()
+ {
+ _network_content_client.RemoveCallback(this);
+ }
+
+ void OnConnect(bool success) override
+ {
+ if (!success) {
+ EM_ASM({ if (window["openttd_bootstrap_failed"]) openttd_bootstrap_failed(); });
+ return;
+ }
+
+ /* Once connected, request the metadata. */
+ _network_content_client.RequestContentList(CONTENT_TYPE_BASE_GRAPHICS);
+ }
+
+ void OnReceiveContentInfo(const ContentInfo *ci) override
+ {
+ if (this->downloading) return;
+
+ /* And once the metadata is received, start downloading it. */
+ _network_content_client.Select(ci->id);
+ _network_content_client.DownloadSelectedContent(this->total_files, this->total_bytes);
+ this->downloading = true;
+
+ EM_ASM({ if (window["openttd_bootstrap"]) openttd_bootstrap($0, $1); }, this->downloaded_bytes, this->total_bytes);
+ }
+
+ void OnDownloadProgress(const ContentInfo *ci, int bytes) override
+ {
+ /* A negative value means we are resetting; for example, when retrying or using a fallback. */
+ if (bytes < 0) {
+ this->downloaded_bytes = 0;
+ } else {
+ this->downloaded_bytes += bytes;
+ }
+
+ EM_ASM({ if (window["openttd_bootstrap"]) openttd_bootstrap($0, $1); }, this->downloaded_bytes, this->total_bytes);
+ }
+
+ void OnDownloadComplete(ContentID cid) override
+ {
+ /* _exit_game is used to break out of the outer video driver's MainLoop. */
+ _exit_game = true;
+
+ delete this;
+ }
+};
+#endif /* __EMSCRIPTEN__ */
+
/**
* Handle all procedures for bootstrapping OpenTTD without a base graphics set.
* This requires all kinds of trickery that is needed to avoid the use of
@@ -299,12 +369,15 @@ bool HandleBootstrap()
if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) goto failure;
/* If there is no network or no non-sprite font, then there is nothing we can do. Go straight to failure. */
-#if (defined(_WIN32) && defined(WITH_UNISCRIBE)) || (defined(WITH_FREETYPE) && (defined(WITH_FONTCONFIG) || defined(__APPLE__))) || defined(WITH_COCOA)
+#if defined(__EMSCRIPTEN__) || (defined(_WIN32) && defined(WITH_UNISCRIBE)) || (defined(WITH_FREETYPE) && (defined(WITH_FONTCONFIG) || defined(__APPLE__))) || defined(WITH_COCOA)
if (!_network_available) goto failure;
/* First tell the game we're bootstrapping. */
_game_mode = GM_BOOTSTRAP;
+#if defined(__EMSCRIPTEN__)
+ new BootstrapEmscripten();
+#else
/* Initialise the font cache. */
InitializeUnicodeGlyphMap();
/* Next "force" finding a suitable non-sprite font as the local font is missing. */
@@ -323,6 +396,7 @@ bool HandleBootstrap()
/* Finally ask the question. */
new BootstrapBackground();
new BootstrapAskForDownloadWindow();
+#endif /* __EMSCRIPTEN__ */
/* Process the user events. */
VideoDriver::GetInstance()->MainLoop();
diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt
index e2de39349c..733dbd40df 100644
--- a/src/lang/catalan.txt
+++ b/src/lang/catalan.txt
@@ -1187,7 +1187,7 @@ STR_TERRAIN_TYPE_CUSTOM :Alçada persona
STR_TERRAIN_TYPE_CUSTOM_VALUE :Alçada personalitzada ({NUM})
###length 4
-STR_CITY_APPROVAL_LENIENT :Tolerant
+STR_CITY_APPROVAL_LENIENT :Indulgent
STR_CITY_APPROVAL_TOLERANT :Tolerant
STR_CITY_APPROVAL_HOSTILE :Hostil
STR_CITY_APPROVAL_PERMISSIVE :Permissiva (les accions de les companyies no l'afecten)
@@ -2651,6 +2651,7 @@ STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Commuta
STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Commuta la transparència dels ponts. Ctrl+Clic per bloquejar
STR_TRANSPARENT_STRUCTURES_TOOLTIP :{BLACK}Commuta la transparència de les estructures com ara fars i antenes. Ctrl+Clic per bloquejar
STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Commuta la transparència de la catenària. CTRL+clic per bloquejar
+STR_TRANSPARENT_TEXT_TOOLTIP :{BLACK}Commuta la transparència dels indicadors de càrrega i el text de despesa/ingrés. Ctrl+Clic per a blocar.
STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Alternar entre transparència i invisibilitat dels objectes
# Linkgraph legend window
diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt
index 80f03de4a3..e23d49287b 100644
--- a/src/lang/dutch.txt
+++ b/src/lang/dutch.txt
@@ -2650,6 +2650,7 @@ STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Transpar
STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Transparantie voor bruggen aan-uit. Ctrl+klik om vast te zetten.
STR_TRANSPARENT_STRUCTURES_TOOLTIP :{BLACK}Transparantie voor gebouwen zoals vuurtorens en zendmasten aan-uit. Ctrl+klik om vast te zetten.
STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Transparantie voor bovenleiding aan-uit. Ctrl+klik om vast te zetten.
+STR_TRANSPARENT_TEXT_TOOLTIP :{BLACK}Transparantie omschakelen voor teksten bij laden en kosten/inkomsten. Ctrl+klik om vast te zetten
STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Maak objecten onzichtbaar in plaats van transparant
# Linkgraph legend window
diff --git a/src/network/network_survey.cpp b/src/network/network_survey.cpp
index 1b173931a3..c3c2bd5753 100644
--- a/src/network/network_survey.cpp
+++ b/src/network/network_survey.cpp
@@ -37,9 +37,7 @@
#include "../base_media_base.h"
#include "../blitter/factory.hpp"
-#ifdef WITH_NLOHMANN_JSON
#include
-#endif /* WITH_NLOHMANN_JSON */
#include "../safeguards.h"
@@ -47,8 +45,6 @@ extern std::string _savegame_id;
NetworkSurveyHandler _survey = {};
-#ifdef WITH_NLOHMANN_JSON
-
NLOHMANN_JSON_SERIALIZE_ENUM(NetworkSurveyHandler::Reason, {
{NetworkSurveyHandler::Reason::PREVIEW, "preview"},
{NetworkSurveyHandler::Reason::LEAVE, "leave"},
@@ -114,8 +110,12 @@ static void SurveySettings(nlohmann::json &survey)
*/
static void SurveyOpenTTD(nlohmann::json &survey)
{
- survey["version"] = std::string(_openttd_revision);
- survey["newgrf_version"] = _openttd_newgrf_version;
+ survey["version"]["revision"] = std::string(_openttd_revision);
+ survey["version"]["modified"] = _openttd_revision_modified;
+ survey["version"]["tagged"] = _openttd_revision_tagged;
+ survey["version"]["hash"] = std::string(_openttd_revision_hash);
+ survey["version"]["newgrf"] = fmt::format("{:X}", _openttd_newgrf_version);
+ survey["version"]["content"] = std::string(_openttd_content_version);
survey["build_date"] = std::string(_openttd_build_date);
survey["bits"] =
#ifdef POINTER_IS_64BIT
@@ -227,6 +227,21 @@ static void SurveyCompanies(nlohmann::json &survey)
}
}
+/**
+ * Convert timer information to JSON.
+ *
+ * @param survey The JSON object.
+ */
+static void SurveyTimers(nlohmann::json &survey)
+{
+ survey["ticks"] = _scaled_tick_counter;
+ survey["seconds"] = std::chrono::duration_cast(std::chrono::steady_clock::now() - _switch_mode_time).count();
+
+ YearMonthDay ymd;
+ ConvertDateToYMD(_date, &ymd);
+ survey["calendar"] = fmt::format("{:04}-{:02}-{:02} ({})", ymd.year, ymd.month + 1, ymd.day, _date_fract);
+}
+
/**
* Convert GRF information to JSON.
*
@@ -298,8 +313,6 @@ std::string SurveyMemoryToText(uint64_t memory)
return fmt::format("{} MiB", Ceil(memory, 4));
}
-#endif /* WITH_NLOHMANN_JSON */
-
/**
* Create the payload for the survey.
*
@@ -309,9 +322,6 @@ std::string SurveyMemoryToText(uint64_t memory)
*/
std::string NetworkSurveyHandler::CreatePayload(Reason reason, bool for_preview)
{
-#ifndef WITH_NLOHMANN_JSON
- return "";
-#else
nlohmann::json survey;
survey["schema"] = NETWORK_SURVEY_VERSION;
@@ -335,8 +345,7 @@ std::string NetworkSurveyHandler::CreatePayload(Reason reason, bool for_preview)
{
auto &game = survey["game"];
- game["ticks"] = _scaled_tick_counter;
- game["time"] = std::chrono::duration_cast(std::chrono::steady_clock::now() - _switch_mode_time).count();
+ SurveyTimers(game["timers"]);
SurveyCompanies(game["companies"]);
SurveySettings(game["settings"]);
SurveyGrfs(game["grfs"]);
@@ -346,7 +355,6 @@ std::string NetworkSurveyHandler::CreatePayload(Reason reason, bool for_preview)
/* For preview, we indent with 4 whitespaces to make things more readable. */
int indent = for_preview ? 4 : -1;
return survey.dump(indent);
-#endif /* WITH_NLOHMANN_JSON */
}
/**
diff --git a/src/network/network_survey.h b/src/network/network_survey.h
index 59815c8006..a705c0143e 100644
--- a/src/network/network_survey.h
+++ b/src/network/network_survey.h
@@ -40,12 +40,12 @@ public:
constexpr static bool IsSurveyPossible()
{
-#if !(defined(WITH_NLOHMANN_JSON) && defined(SURVEY_KEY))
- /* Without JSON library, we cannot send a payload; so we disable the survey. */
+#if !defined(SURVEY_KEY)
+ /* Without a survey key, we cannot send a payload; so we disable the survey. */
return false;
#else
return true;
-#endif /* WITH_NLOHMANN_JSON */
+#endif /* SURVEY_KEY */
}
private:
diff --git a/src/openttd.cpp b/src/openttd.cpp
index 7c4e91811e..ec5698c0c4 100644
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -164,7 +164,6 @@ void CDECL usererror(const char *s, ...)
/* 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_abort"]) openttd_abort());
#endif
@@ -682,6 +681,22 @@ struct AfterNewGRFScan : NewGRFScanCallback {
}
};
+void PostMainLoop()
+{
+ WaitTillSaved();
+
+ /* only save config if we have to */
+ if (_save_config) {
+ SaveToConfig(STCF_ALL);
+ SaveHotkeysToConfig();
+ WindowDesc::SaveToConfig();
+ SaveToHighScore();
+ }
+
+ /* Reset windowing system, stop drivers, free used memory, ... */
+ ShutdownGame();
+}
+
#if defined(UNIX)
extern void DedicatedFork();
#endif
@@ -1040,18 +1055,7 @@ int openttd_main(int argc, char *argv[])
_general_worker_pool.Stop();
- WaitTillSaved();
-
- /* only save config if we have to */
- if (_save_config) {
- SaveToConfig(STCF_ALL);
- SaveHotkeysToConfig();
- WindowDesc::SaveToConfig();
- SaveToHighScore();
- }
-
- /* Reset windowing system, stop drivers, free used memory, ... */
- ShutdownGame();
+ PostMainLoop();
return ret;
}
diff --git a/src/os/macosx/survey_osx.cpp b/src/os/macosx/survey_osx.cpp
index 8affddd34b..5f214906e8 100644
--- a/src/os/macosx/survey_osx.cpp
+++ b/src/os/macosx/survey_osx.cpp
@@ -7,8 +7,6 @@
/** @file survey_osx.cpp OSX implementation of OS-specific survey information. */
-#ifdef WITH_NLOHMANN_JSON
-
#include "../../stdafx.h"
#include "../../core/format.hpp"
@@ -38,5 +36,3 @@ void SurveyOS(nlohmann::json &json)
json["memory"] = SurveyMemoryToText(MacOSGetPhysicalMemory());
json["hardware_concurrency"] = std::thread::hardware_concurrency();
}
-
-#endif /* WITH_NLOHMANN_JSON */
diff --git a/src/os/unix/survey_unix.cpp b/src/os/unix/survey_unix.cpp
index d831a78390..fea37d89da 100644
--- a/src/os/unix/survey_unix.cpp
+++ b/src/os/unix/survey_unix.cpp
@@ -7,8 +7,6 @@
/** @file survey_unix.cpp Unix implementation of OS-specific survey information. */
-#ifdef WITH_NLOHMANN_JSON
-
#include "../../stdafx.h"
#include
@@ -38,5 +36,3 @@ void SurveyOS(nlohmann::json &json)
json["memory"] = SurveyMemoryToText(pages * page_size);
json["hardware_concurrency"] = std::thread::hardware_concurrency();
}
-
-#endif /* WITH_NLOHMANN_JSON */
diff --git a/src/os/windows/survey_win.cpp b/src/os/windows/survey_win.cpp
index 07505f74e7..6476bcb1ab 100644
--- a/src/os/windows/survey_win.cpp
+++ b/src/os/windows/survey_win.cpp
@@ -7,8 +7,6 @@
/** @file survey_win.cpp Windows implementation of OS-specific survey information. */
-#ifdef WITH_NLOHMANN_JSON
-
#include "../../stdafx.h"
#include "../../core/format.hpp"
@@ -41,5 +39,3 @@ void SurveyOS(nlohmann::json &json)
json["memory"] = SurveyMemoryToText(status.ullTotalPhys);
json["hardware_concurrency"] = std::thread::hardware_concurrency();
}
-
-#endif /* WITH_NLOHMANN_JSON */
diff --git a/src/script/api/script_admin.cpp b/src/script/api/script_admin.cpp
index 48b52bea9b..6c52df374c 100644
--- a/src/script/api/script_admin.cpp
+++ b/src/script/api/script_admin.cpp
@@ -130,7 +130,10 @@
}
std::string json;
- ScriptAdmin::MakeJSON(vm, -1, SQUIRREL_MAX_DEPTH, json);
+ if (!ScriptAdmin::MakeJSON(vm, -1, SQUIRREL_MAX_DEPTH, json)) {
+ sq_pushinteger(vm, 0);
+ return 1;
+ }
if (json.length() > NETWORK_GAMESCRIPT_JSON_LENGTH) {
ScriptLog::Error("You are trying to send a table that is too large to the AdminPort. No data sent.");
diff --git a/src/script/api/script_admin.hpp b/src/script/api/script_admin.hpp
index 95b7218eb0..8e07985d03 100644
--- a/src/script/api/script_admin.hpp
+++ b/src/script/api/script_admin.hpp
@@ -37,7 +37,7 @@ public:
static bool Send(void *table);
#endif /* DOXYGEN_API */
-private:
+protected:
/**
* Convert a Squirrel structure into a JSON string.
* @param vm The VM to operate on.
diff --git a/src/script/api/script_event_types.cpp b/src/script/api/script_event_types.cpp
index 2d388e8012..ff3fa70951 100644
--- a/src/script/api/script_event_types.cpp
+++ b/src/script/api/script_event_types.cpp
@@ -220,11 +220,11 @@ const char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, const char *p)
SKIP_EMPTY(p);
if (strncmp(p, "false", 5) == 0) {
- sq_pushinteger(vm, 0);
+ sq_pushbool(vm, 0);
return p + 5;
}
if (strncmp(p, "true", 4) == 0) {
- sq_pushinteger(vm, 1);
+ sq_pushbool(vm, 1);
return p + 4;
}
if (strncmp(p, "null", 4) == 0) {
diff --git a/src/script/api/script_object.hpp b/src/script/api/script_object.hpp
index b865bac777..cee1a17ec7 100644
--- a/src/script/api/script_object.hpp
+++ b/src/script/api/script_object.hpp
@@ -44,6 +44,7 @@ typedef bool (ScriptAsyncModeProc)();
class ScriptObject : public SimpleCountedObject {
friend class ScriptInstance;
friend class ScriptController;
+friend class TestScriptController;
protected:
/**
* A class that handles the current active instance. By instantiating it at
diff --git a/src/video/sdl2_v.cpp b/src/video/sdl2_v.cpp
index 1431a4a5c1..962511aceb 100644
--- a/src/video/sdl2_v.cpp
+++ b/src/video/sdl2_v.cpp
@@ -947,13 +947,19 @@ void VideoDriver_SDL_Base::LoopOnce()
* 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. */
+ extern void PostMainLoop();
+ PostMainLoop();
+
emscripten_cancel_main_loop();
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());
+ if (_game_mode == GM_BOOTSTRAP) {
+ EM_ASM(if (window["openttd_bootstrap_reload"]) openttd_bootstrap_reload());
+ } else {
+ EM_ASM(if (window["openttd_exit"]) openttd_exit());
+ }
#endif
return;
}