mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-25 15:54:31 +01:00
Fix emscripten support
This commit is contained in:
@@ -17,5 +17,8 @@ file(GLOB_RECURSE OPENRCT2_CLI_SOURCES
|
||||
add_executable(${PROJECT_NAME} ${OPENRCT2_CLI_SOURCES})
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_LIST_DIR}/..")
|
||||
ipo_set_target_properties(${PROJECT_NAME})
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Emscripten")
|
||||
target_link_libraries(${PROJECT_NAME} ${ICU_DT_LIBRARY_RELEASE} ${ICU_DATA_LIBRARIES})
|
||||
endif ()
|
||||
target_link_libraries(${PROJECT_NAME} libopenrct2 Threads::Threads)
|
||||
target_link_platform_libraries(${PROJECT_NAME})
|
||||
|
||||
@@ -11,7 +11,18 @@ option(DISABLE_VORBIS "Disable OGG/VORBIS support.")
|
||||
option(DISABLE_OPENGL "Disable OpenGL support.")
|
||||
|
||||
# Third party libraries
|
||||
if (MSVC)
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Emscripten")
|
||||
set(USE_FLAGS "${EMSCRIPTEN_FLAGS}")
|
||||
set(SHARED_FLAGS "-fexceptions")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${USE_FLAGS} ${SHARED_FLAGS}")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${USE_FLAGS} ${SHARED_FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${EMSCRIPTEN_LDFLAGS} --bind ${SHARED_FLAGS}")
|
||||
find_package(SpeexDSP REQUIRED)
|
||||
if (NOT DISABLE_VORBIS)
|
||||
PKG_CHECK_MODULES(OGG REQUIRED IMPORTED_TARGET ogg)
|
||||
PKG_CHECK_MODULES(VORBISFILE REQUIRED IMPORTED_TARGET vorbisfile vorbisenc vorbis)
|
||||
endif ()
|
||||
elseif (MSVC)
|
||||
find_package(SDL2 REQUIRED)
|
||||
find_library(SPEEX_LDFLAGS libspeexdsp)
|
||||
if (NOT DISABLE_FLAC)
|
||||
@@ -33,7 +44,7 @@ else ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (NOT DISABLE_OPENGL)
|
||||
if (NOT DISABLE_OPENGL AND NOT CMAKE_SYSTEM_NAME MATCHES "Emscripten")
|
||||
# GL doesn't work nicely with macOS, while find_package doesn't work with multiarch on Ubuntu.
|
||||
if (APPLE)
|
||||
find_package(OpenGL REQUIRED)
|
||||
@@ -61,7 +72,12 @@ SET_CHECK_CXX_FLAGS(${PROJECT_NAME})
|
||||
ipo_set_target_properties(${PROJECT_NAME})
|
||||
|
||||
# mingw builds cannot use the PkgConfig imported targets
|
||||
if (NOT MSVC AND NOT WIN32)
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Emscripten")
|
||||
target_link_libraries(${PROJECT_NAME} "libopenrct2"
|
||||
${SPEEXDSP_LIBRARIES}
|
||||
${ICU_DATA_LIBRARIES}
|
||||
${ICU_DT_LIBRARY_RELEASE})
|
||||
elseif (NOT MSVC AND NOT WIN32)
|
||||
target_link_libraries(${PROJECT_NAME} "libopenrct2"
|
||||
PkgConfig::SDL2
|
||||
PkgConfig::SPEEX)
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
#include <openrct2/core/String.hpp>
|
||||
#include <openrct2/core/UTF8.h>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
#ifdef __MACOSX__
|
||||
// macOS uses COMMAND rather than CTRL for many keyboard shortcuts
|
||||
#define KEYBOARD_PRIMARY_MODIFIER KMOD_GUI
|
||||
@@ -170,7 +174,21 @@ void TextComposition::HandleMessage(const SDL_Event* e)
|
||||
case SDLK_c:
|
||||
if ((modifier & KEYBOARD_PRIMARY_MODIFIER) && _session.Length)
|
||||
{
|
||||
#ifndef __EMSCRIPTEN__
|
||||
SDL_SetClipboardText(_session.Buffer->c_str());
|
||||
#else
|
||||
MAIN_THREAD_EM_ASM(
|
||||
{
|
||||
try
|
||||
{
|
||||
navigator.clipboard.writeText(UTF8ToString($0));
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
};
|
||||
},
|
||||
_session.Buffer->c_str());
|
||||
#endif
|
||||
ContextShowError(STR_COPY_INPUT_TO_CLIPBOARD, STR_NONE, {});
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
#include <openrct2/platform/Platform.h>
|
||||
#include <openrct2/ui/UiContext.h>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
using namespace OpenRCT2;
|
||||
using namespace OpenRCT2::Audio;
|
||||
using namespace OpenRCT2::Ui;
|
||||
@@ -43,6 +47,12 @@ int NormalisedMain(int argc, const char** argv)
|
||||
int main(int argc, const char** argv)
|
||||
#endif
|
||||
{
|
||||
#ifdef __EMSCRIPTEN__
|
||||
MAIN_THREAD_EM_ASM({
|
||||
specialHTMLTargets["!canvas"] = Module.canvas;
|
||||
Module.canvas.addEventListener("contextmenu", (e) = > { e.preventDefault(); });
|
||||
});
|
||||
#endif
|
||||
std::unique_ptr<IContext> context;
|
||||
int32_t rc = EXIT_SUCCESS;
|
||||
int runGame = CommandLineRun(argv, argc);
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
#include <stdexcept>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
namespace OpenRCT2::Ui
|
||||
{
|
||||
enum class DIALOG_TYPE
|
||||
@@ -129,8 +133,12 @@ namespace OpenRCT2::Ui
|
||||
|
||||
void OpenURL(const std::string& url) override
|
||||
{
|
||||
#ifndef __EMSCRIPTEN__
|
||||
std::string cmd = String::stdFormat("xdg-open %s", url.c_str());
|
||||
Platform::Execute(cmd);
|
||||
#else
|
||||
MAIN_THREAD_EM_ASM({ window.open(UTF8ToString($0)); }, url.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string ShowFileDialog(SDL_Window* window, const FileDialogDesc& desc) override
|
||||
|
||||
@@ -49,6 +49,11 @@
|
||||
#include <openrct2/world/Location.hpp>
|
||||
#include <vector>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
#endif
|
||||
|
||||
using namespace OpenRCT2;
|
||||
using namespace OpenRCT2::Drawing;
|
||||
using namespace OpenRCT2::Scripting;
|
||||
@@ -713,7 +718,25 @@ public:
|
||||
|
||||
bool SetClipboardText(const utf8* target) override
|
||||
{
|
||||
#ifndef __EMSCRIPTEN__
|
||||
return (SDL_SetClipboardText(target) == 0);
|
||||
#else
|
||||
return (
|
||||
MAIN_THREAD_EM_ASM_INT(
|
||||
{
|
||||
try
|
||||
{
|
||||
navigator.clipboard.writeText(UTF8ToString($0));
|
||||
return 0;
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
return -1;
|
||||
};
|
||||
},
|
||||
gVersionInfoFull)
|
||||
== 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
ITitleSequencePlayer* GetTitleSequencePlayer() override
|
||||
@@ -753,9 +776,19 @@ private:
|
||||
|
||||
void CreateWindow(const ScreenCoordsXY& windowPos)
|
||||
{
|
||||
#ifdef __EMSCRIPTEN__
|
||||
MAIN_THREAD_EM_ASM({
|
||||
Module.canvas.width = window.innerWidth;
|
||||
Module.canvas.height = window.innerHeight;
|
||||
});
|
||||
int32_t width = 0;
|
||||
int32_t height = 0;
|
||||
emscripten_get_canvas_element_size("!canvas", &width, &height);
|
||||
#else
|
||||
// Get saved window size
|
||||
int32_t width = Config::Get().general.WindowWidth;
|
||||
int32_t height = Config::Get().general.WindowHeight;
|
||||
#endif
|
||||
if (width <= 0)
|
||||
width = 640;
|
||||
if (height <= 0)
|
||||
|
||||
@@ -1115,6 +1115,10 @@ namespace OpenRCT2
|
||||
STR_DRAWING_ENGINE_TIP = 5876,
|
||||
STR_EARLY_COMPLETION_TIP = 6227,
|
||||
STR_EDIT_ASSET_PACKS_BUTTON = 6640,
|
||||
#ifdef __EMSCRIPTEN__
|
||||
STR_EXPORT_EMSCRIPTEN = 6713,
|
||||
STR_IMPORT_EMSCRIPTEN = 6714,
|
||||
#endif
|
||||
STR_EDIT_THEMES_BUTTON = 5153,
|
||||
STR_EDIT_THEMES_BUTTON_TIP = 5837,
|
||||
STR_EFFECTS_GROUP = 6256,
|
||||
@@ -2282,4 +2286,4 @@ namespace OpenRCT2
|
||||
STR_ADJUST_SMALLER_WATER_TIP = 2380,
|
||||
STR_WATER = 2383,
|
||||
};
|
||||
}
|
||||
} // namespace OpenRCT2
|
||||
|
||||
@@ -42,7 +42,11 @@ OPENGL_PROC(PFNGLATTACHSHADERPROC, glAttachShader)
|
||||
OPENGL_PROC(PFNGLBINDBUFFERPROC, glBindBuffer)
|
||||
OPENGL_PROC(PFNGLBINDFRAGDATALOCATIONPROC, glBindFragDataLocation)
|
||||
OPENGL_PROC(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer)
|
||||
#ifndef FAKE__EMSCRIPTEN__
|
||||
OPENGL_PROC(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray)
|
||||
#else
|
||||
extern "C" void glBindVertexArray(GLuint array);
|
||||
#endif
|
||||
OPENGL_PROC(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer)
|
||||
OPENGL_PROC(PFNGLBUFFERDATAPROC, glBufferData)
|
||||
OPENGL_PROC(PFNGLBUFFERSUBDATAPROC, glBufferSubData)
|
||||
@@ -55,7 +59,11 @@ OPENGL_PROC(PFNGLDELETEBUFFERSPROC, glDeleteBuffers)
|
||||
OPENGL_PROC(PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers)
|
||||
OPENGL_PROC(PFNGLDELETEPROGRAMPROC, glDeleteProgram)
|
||||
OPENGL_PROC(PFNGLDELETESHADERPROC, glDeleteShader)
|
||||
#ifndef FAKE__EMSCRIPTEN__
|
||||
OPENGL_PROC(PFNGLDELETEVERTEXARRAYSPROC, glDeleteVertexArrays)
|
||||
#else
|
||||
extern "C" void glDeleteVertexArrays(GLsizei n, const GLuint* arrays);
|
||||
#endif
|
||||
OPENGL_PROC(PFNGLDETACHSHADERPROC, glDetachShader)
|
||||
OPENGL_PROC(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray)
|
||||
OPENGL_PROC(PFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D)
|
||||
@@ -67,7 +75,11 @@ OPENGL_PROC(PFNGLGETPROGRAMIVPROC, glGetProgramiv)
|
||||
OPENGL_PROC(PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog)
|
||||
OPENGL_PROC(PFNGLGETSHADERIVPROC, glGetShaderiv)
|
||||
OPENGL_PROC(PFNGLGETUNIFORMLOCATIONPROC, glGetUniformLocation)
|
||||
#ifndef FAKE__EMSCRIPTEN__
|
||||
OPENGL_PROC(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays)
|
||||
#else
|
||||
extern "C" void glGenVertexArrays(GLsizei n, GLuint* arrays);
|
||||
#endif
|
||||
OPENGL_PROC(PFNGLLINKPROGRAMPROC, glLinkProgram)
|
||||
OPENGL_PROC(PFNGLSHADERSOURCEPROC, glShaderSource)
|
||||
OPENGL_PROC(PFNGLUNIFORM1IPROC, glUniform1i)
|
||||
@@ -82,6 +94,11 @@ OPENGL_PROC(PFNGLUNIFORM4FVPROC, glUniform4fv)
|
||||
OPENGL_PROC(PFNGLUSEPROGRAMPROC, glUseProgram)
|
||||
OPENGL_PROC(PFNGLVERTEXATTRIBIPOINTERPROC, glVertexAttribIPointer)
|
||||
OPENGL_PROC(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer)
|
||||
#ifndef FAKE__EMSCRIPTEN__
|
||||
OPENGL_PROC(PFNGLDRAWARRAYSINSTANCEDPROC, glDrawArraysInstanced)
|
||||
OPENGL_PROC(PFNGLVERTEXATTRIBDIVISORPROC, glVertexAttribDivisor)
|
||||
#else
|
||||
extern "C" void glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
|
||||
extern "C" void glVertexAttribDivisor(GLuint index, GLuint divisor);
|
||||
#endif
|
||||
OPENGL_PROC(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate)
|
||||
|
||||
@@ -70,7 +70,9 @@ private:
|
||||
|
||||
int32_t _drawCount = 0;
|
||||
|
||||
#ifndef NO_TTF
|
||||
uint32_t _ttfGlId = 0;
|
||||
#endif
|
||||
|
||||
struct
|
||||
{
|
||||
|
||||
@@ -605,6 +605,7 @@ static void InputViewportDragContinue()
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __EMSCRIPTEN__
|
||||
const CursorState* cursorState = ContextGetCursorState();
|
||||
if (cursorState->touch || Config::Get().general.InvertViewportDrag)
|
||||
{
|
||||
@@ -614,6 +615,9 @@ static void InputViewportDragContinue()
|
||||
{
|
||||
ContextSetCursorPosition(gInputDragLast);
|
||||
}
|
||||
#else
|
||||
gInputDragLast = newDragCoords;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void InputViewportDragEnd()
|
||||
|
||||
@@ -21,6 +21,10 @@
|
||||
#include <openrct2/sprites.h>
|
||||
#include <openrct2/ui/UiContext.h>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
namespace OpenRCT2::Ui::Windows
|
||||
{
|
||||
static constexpr int32_t WW = 400;
|
||||
@@ -119,7 +123,22 @@ namespace OpenRCT2::Ui::Windows
|
||||
ContextOpenWindowView(WV_NEW_VERSION_INFO);
|
||||
break;
|
||||
case WIDX_COPY_BUILD_INFO:
|
||||
#ifndef __EMSCRIPTEN__
|
||||
SDL_SetClipboardText(gVersionInfoFull);
|
||||
#else
|
||||
MAIN_THREAD_EM_ASM(
|
||||
{
|
||||
try
|
||||
{
|
||||
navigator.clipboard.writeText(UTF8ToString($0));
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
// Ignore
|
||||
};
|
||||
},
|
||||
gVersionInfoFull);
|
||||
#endif
|
||||
break;
|
||||
case WIDX_CONTRIBUTORS_BUTTON:
|
||||
ContextOpenWindowView(WV_CONTRIBUTORS);
|
||||
|
||||
@@ -46,6 +46,10 @@
|
||||
#include <openrct2/sprites.h>
|
||||
#include <openrct2/ui/UiContext.h>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
using namespace OpenRCT2;
|
||||
using namespace OpenRCT2::Audio;
|
||||
|
||||
@@ -218,6 +222,10 @@ namespace OpenRCT2::Ui::Windows
|
||||
WIDX_PATH_TO_RCT1_BUTTON,
|
||||
WIDX_PATH_TO_RCT1_CLEAR,
|
||||
WIDX_ASSET_PACKS,
|
||||
#ifdef __EMSCRIPTEN__
|
||||
WIDX_EXPORT_EMSCRIPTEN_DATA,
|
||||
WIDX_IMPORT_EMSCRIPTEN_DATA,
|
||||
#endif
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
@@ -404,6 +412,10 @@ namespace OpenRCT2::Ui::Windows
|
||||
MakeWidget ({ 24, 160}, {266, 14}, WindowWidgetType::Button, WindowColour::Secondary, STR_NONE, STR_STRING_TOOLTIP ), // RCT 1 path button
|
||||
MakeWidget ({289, 160}, { 11, 14}, WindowWidgetType::Button, WindowColour::Secondary, STR_CLOSE_X, STR_PATH_TO_RCT1_CLEAR_TIP ), // RCT 1 path clear button
|
||||
MakeWidget ({150, 176}, {150, 14}, WindowWidgetType::Button, WindowColour::Secondary, STR_EDIT_ASSET_PACKS_BUTTON, STR_NONE ), // Asset packs
|
||||
#ifdef __EMSCRIPTEN__
|
||||
MakeWidget ({150, 192}, {150, 14}, WindowWidgetType::Button, WindowColour::Secondary, STR_EXPORT_EMSCRIPTEN, STR_NONE ), // Emscripten data export
|
||||
MakeWidget ({150, 208}, {150, 14}, WindowWidgetType::Button, WindowColour::Secondary, STR_IMPORT_EMSCRIPTEN, STR_NONE ), // Emscripten data import
|
||||
#endif
|
||||
kWidgetsEnd,
|
||||
};
|
||||
|
||||
@@ -1973,6 +1985,14 @@ namespace OpenRCT2::Ui::Windows
|
||||
case WIDX_ASSET_PACKS:
|
||||
ContextOpenWindow(WindowClass::AssetPacks);
|
||||
break;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
case WIDX_EXPORT_EMSCRIPTEN_DATA:
|
||||
MAIN_THREAD_EM_ASM({ Module.funcs.export(); });
|
||||
break;
|
||||
case WIDX_IMPORT_EMSCRIPTEN_DATA:
|
||||
MAIN_THREAD_EM_ASM({ Module.funcs.import(); });
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,19 @@ if (NOT DISABLE_GOOGLE_BENCHMARK)
|
||||
endif ()
|
||||
|
||||
# Third party libraries
|
||||
if (MSVC)
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Emscripten")
|
||||
target_include_directories(${PROJECT_NAME} SYSTEM PRIVATE ${ICU_INCLUDE_DIR})
|
||||
set(USE_FLAGS "${EMSCRIPTEN_FLAGS}")
|
||||
set(SHARED_FLAGS "-fexceptions")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${USE_FLAGS} ${SHARED_FLAGS}")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${USE_FLAGS} ${SHARED_FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${EMSCRIPTEN_LDFLAGS} --bind ${SHARED_FLAGS}")
|
||||
find_package(SpeexDSP REQUIRED)
|
||||
if (NOT DISABLE_VORBIS)
|
||||
PKG_CHECK_MODULES(OGG REQUIRED IMPORTED_TARGET ogg)
|
||||
PKG_CHECK_MODULES(VORBISFILE REQUIRED IMPORTED_TARGET vorbisfile vorbisenc vorbis)
|
||||
endif ()
|
||||
elseif (MSVC)
|
||||
find_package(png 1.6 REQUIRED)
|
||||
find_package(zlib REQUIRED)
|
||||
|
||||
@@ -142,7 +154,7 @@ if (STATIC)
|
||||
${ZLIB_STATIC_LIBRARIES}
|
||||
${LIBZIP_STATIC_LIBRARIES})
|
||||
else ()
|
||||
if (NOT MSVC)
|
||||
if (NOT MSVC AND NOT CMAKE_SYSTEM_NAME MATCHES "Emscripten")
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PkgConfig::PNG
|
||||
PkgConfig::ZLIB
|
||||
@@ -171,7 +183,7 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME} Threads::Threads)
|
||||
|
||||
if (NOT MINGW AND NOT MSVC)
|
||||
if (NOT MINGW AND NOT MSVC AND NOT CMAKE_SYSTEM_NAME MATCHES "Emscripten")
|
||||
if (APPLE AND NOT MACOS_USE_DEPENDENCIES)
|
||||
execute_process(COMMAND brew --prefix icu4c OUTPUT_VARIABLE HOMEBREW_PREFIX_ICU OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
# Needed for linking with non-broken icu on Apple platforms
|
||||
@@ -249,7 +261,7 @@ if (NOT OPENRCT2_COMMIT_SHA1_SHORT STREQUAL "HEAD" AND NOT OPENRCT2_COMMIT_SHA1_
|
||||
OPENRCT2_COMMIT_SHA1_SHORT="${OPENRCT2_COMMIT_SHA1_SHORT}")
|
||||
endif()
|
||||
|
||||
if((X86 OR X86_64) AND NOT MSVC)
|
||||
if((X86 OR X86_64) AND NOT MSVC AND NOT CMAKE_SYSTEM_NAME MATCHES "Emscripten")
|
||||
set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/drawing/SSE41Drawing.cpp PROPERTIES COMPILE_FLAGS -msse4.1)
|
||||
set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/drawing/AVX2Drawing.cpp PROPERTIES COMPILE_FLAGS -mavx2)
|
||||
endif()
|
||||
|
||||
@@ -1201,9 +1201,21 @@ namespace OpenRCT2
|
||||
{
|
||||
SwitchToStartUpScene();
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_set_main_loop_arg(
|
||||
[](void* vctx) {
|
||||
auto ctx = reinterpret_cast<Context*>(vctx);
|
||||
if (ctx->_finished)
|
||||
{
|
||||
emscripten_cancel_main_loop();
|
||||
}
|
||||
ctx->RunFrame();
|
||||
},
|
||||
this, 0, 1);
|
||||
#else
|
||||
_stdInOutConsole.Start();
|
||||
RunGameLoop();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ShouldDraw()
|
||||
@@ -1229,6 +1241,7 @@ namespace OpenRCT2
|
||||
/**
|
||||
* Run the main game loop until the finished flag is set.
|
||||
*/
|
||||
#ifndef __EMSCRIPTEN__
|
||||
void RunGameLoop()
|
||||
{
|
||||
PROFILED_FUNCTION();
|
||||
@@ -1236,22 +1249,14 @@ namespace OpenRCT2
|
||||
LOG_VERBOSE("begin openrct2 loop");
|
||||
_finished = false;
|
||||
|
||||
#ifndef __EMSCRIPTEN__
|
||||
_variableFrame = ShouldRunVariableFrame();
|
||||
do
|
||||
{
|
||||
RunFrame();
|
||||
} while (!_finished);
|
||||
#else
|
||||
emscripten_set_main_loop_arg(
|
||||
[](void* vctx) -> {
|
||||
auto ctx = reinterpret_cast<Context*>(vctx);
|
||||
ctx->RunFrame();
|
||||
},
|
||||
this, 0, 1);
|
||||
#endif // __EMSCRIPTEN__
|
||||
LOG_VERBOSE("finish openrct2 loop");
|
||||
}
|
||||
#endif // __EMSCRIPTEN__
|
||||
|
||||
void RunFrame()
|
||||
{
|
||||
|
||||
@@ -35,8 +35,10 @@
|
||||
#elif defined(__riscv)
|
||||
#define OPENRCT2_ARCHITECTURE "RISC-V"
|
||||
#endif
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#define OPENRCT2_ARCHITECTURE "Emscripten"
|
||||
#ifdef __wasm32__
|
||||
#define OPENRCT2_ARCHITECTURE "wasm32"
|
||||
#elif defined(__wasm64__)
|
||||
#define OPENRCT2_ARCHITECTURE "wasm64"
|
||||
#endif
|
||||
|
||||
#ifndef OPENRCT2_ARCHITECTURE
|
||||
|
||||
@@ -26,6 +26,12 @@
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
namespace OpenRCT2::Imaging
|
||||
{
|
||||
constexpr auto EXCEPTION_IMAGE_FORMAT_UNKNOWN = "Unknown image format.";
|
||||
@@ -334,8 +340,27 @@ namespace OpenRCT2::Imaging
|
||||
break;
|
||||
case IMAGE_FORMAT::PNG:
|
||||
{
|
||||
#ifndef __EMSCRIPTEN__
|
||||
std::ofstream fs(fs::u8path(path), std::ios::binary);
|
||||
WritePng(fs, image);
|
||||
#else
|
||||
std::ostringstream stream(std::ios::binary);
|
||||
WritePng(stream, image);
|
||||
std::string dataStr = stream.str();
|
||||
void* data = reinterpret_cast<void*>(dataStr.data());
|
||||
MAIN_THREAD_EM_ASM(
|
||||
{
|
||||
const a = document.createElement("a");
|
||||
// Blob requires the data must not be shared
|
||||
const data = new Uint8Array(HEAPU8.subarray($0, $0 + $1));
|
||||
a.href = URL.createObjectURL(new Blob([data]));
|
||||
a.download = UTF8ToString($2).split("/").pop();
|
||||
a.click();
|
||||
setTimeout(function(){ URL.revokeObjectURL(a.href) }, 1000);
|
||||
},
|
||||
data, dataStr.size(), std::string(path).c_str());
|
||||
free(data);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -24,7 +24,7 @@ using money64 = fixed64_1dp;
|
||||
// really tries to use a gigantic constant that can't fit in a double, they are
|
||||
// probably going to be breaking other things anyways.
|
||||
// For more details, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=26374
|
||||
constexpr money64 operator"" _GBP(long double money) noexcept
|
||||
constexpr money64 operator""_GBP(long double money) noexcept
|
||||
{
|
||||
return static_cast<double>(money) * 10;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <cstdint>
|
||||
|
||||
// Note: Only valid for 5 decimal places.
|
||||
constexpr int32_t operator"" _mph(long double speedMph)
|
||||
constexpr int32_t operator""_mph(long double speedMph)
|
||||
{
|
||||
uint32_t wholeNumber = speedMph;
|
||||
uint64_t fraction = (speedMph - wholeNumber) * 100000;
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace OpenRCT2::Platform
|
||||
{
|
||||
LOG_FATAL("failed to get process path");
|
||||
}
|
||||
#elif defined(__OpenBSD__)
|
||||
#elif defined(__OpenBSD__) || defined(__EMSCRIPTEN__)
|
||||
// There is no way to get the path name of a running executable.
|
||||
// If you are not using the port or package, you may have to change this line!
|
||||
strlcpy(exePath, "/usr/local/bin/", sizeof(exePath));
|
||||
|
||||
@@ -161,7 +161,7 @@ namespace OpenRCT2::Platform
|
||||
// Return exit code
|
||||
return pclose(fpipe);
|
||||
#else
|
||||
LOG_WARNING("Emscripten cannot execute processes. The commandline was '%s'.", command.c_str());
|
||||
LOG_WARNING("Emscripten cannot execute processes. The commandline was '%s'.", std::string(command).c_str());
|
||||
return -1;
|
||||
#endif // __EMSCRIPTEN__
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
constexpr int operator"" _MPH(unsigned long long x) noexcept
|
||||
constexpr int operator""_MPH(unsigned long long x) noexcept
|
||||
{
|
||||
return x * 29127;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user