mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-01-21 06:31:17 +00:00
Extended full screen capabilities for Web port (#584)
* Extended full screen capabilities for Web port * Add Emscripten patches * Add back newline
This commit is contained in:
parent
0e95e6d521
commit
7c91a14875
@ -553,6 +553,7 @@ if (ISLE_BUILD_APP)
|
|||||||
ISLE/emscripten/events.cpp
|
ISLE/emscripten/events.cpp
|
||||||
ISLE/emscripten/filesystem.cpp
|
ISLE/emscripten/filesystem.cpp
|
||||||
ISLE/emscripten/messagebox.cpp
|
ISLE/emscripten/messagebox.cpp
|
||||||
|
ISLE/emscripten/window.cpp
|
||||||
)
|
)
|
||||||
target_compile_definitions(isle PRIVATE "ISLE_EMSCRIPTEN_HOST=\"${ISLE_EMSCRIPTEN_HOST}\"")
|
target_compile_definitions(isle PRIVATE "ISLE_EMSCRIPTEN_HOST=\"${ISLE_EMSCRIPTEN_HOST}\"")
|
||||||
set_property(TARGET isle PROPERTY SUFFIX ".html")
|
set_property(TARGET isle PROPERTY SUFFIX ".html")
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "filesystem.h"
|
#include "filesystem.h"
|
||||||
|
#include "window.h"
|
||||||
|
|
||||||
#include <SDL3/SDL_log.h>
|
#include <SDL3/SDL_log.h>
|
||||||
#include <emscripten.h>
|
#include <emscripten.h>
|
||||||
@ -16,6 +17,10 @@ void Emscripten_SetupDefaultConfigOverrides(dictionary* p_dictionary)
|
|||||||
iniparser_set(p_dictionary, "isle:Full Screen", "false");
|
iniparser_set(p_dictionary, "isle:Full Screen", "false");
|
||||||
iniparser_set(p_dictionary, "isle:Flip Surfaces", "true");
|
iniparser_set(p_dictionary, "isle:Flip Surfaces", "true");
|
||||||
|
|
||||||
|
// Emscripten-only for now
|
||||||
|
Emscripten_SetScaleAspect(iniparser_getboolean(p_dictionary, "isle:Original Aspect Ratio", true));
|
||||||
|
Emscripten_SetOriginalResolution(iniparser_getboolean(p_dictionary, "isle:Original Resolution", true));
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
MAIN_THREAD_EM_ASM({JSEvents.fullscreenEnabled = function() { return false; }});
|
MAIN_THREAD_EM_ASM({JSEvents.fullscreenEnabled = function() { return false; }});
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|||||||
@ -1,3 +1,28 @@
|
|||||||
|
diff --git a/src/lib/libhtml5.js b/src/lib/libhtml5.js
|
||||||
|
index da08765e7..24e5da22e 100644
|
||||||
|
--- a/src/lib/libhtml5.js
|
||||||
|
+++ b/src/lib/libhtml5.js
|
||||||
|
@@ -1182,6 +1182,7 @@ var LibraryHTML5 = {
|
||||||
|
|
||||||
|
$registerRestoreOldStyle__deps: ['$getCanvasElementSize', '$setCanvasElementSize', '$currentFullscreenStrategy'],
|
||||||
|
$registerRestoreOldStyle: (canvas) => {
|
||||||
|
+ return;
|
||||||
|
var canvasSize = getCanvasElementSize(canvas);
|
||||||
|
var oldWidth = canvasSize[0];
|
||||||
|
var oldHeight = canvasSize[1];
|
||||||
|
@@ -1326,9 +1327,9 @@ var LibraryHTML5 = {
|
||||||
|
var topMargin;
|
||||||
|
|
||||||
|
if (inAspectRatioFixedFullscreenMode) {
|
||||||
|
- if (w*y < x*h) h = (w * y / x) | 0;
|
||||||
|
- else if (w*y > x*h) w = (h * x / y) | 0;
|
||||||
|
- topMargin = ((screenHeight - h) / 2) | 0;
|
||||||
|
+ if (w*y < x*h) h = Math.round(w * y / x) | 0;
|
||||||
|
+ else if (w*y > x*h) w = Math.round(h * x / y) | 0;
|
||||||
|
+ topMargin = Math.round((screenHeight - h) / 2) | 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inPixelPerfectFullscreenMode) {
|
||||||
diff --git a/src/lib/libpthread.js b/src/lib/libpthread.js
|
diff --git a/src/lib/libpthread.js b/src/lib/libpthread.js
|
||||||
index 6d979627e..97e3f8684 100644
|
index 6d979627e..97e3f8684 100644
|
||||||
--- a/src/lib/libpthread.js
|
--- a/src/lib/libpthread.js
|
||||||
|
|||||||
98
ISLE/emscripten/window.cpp
Normal file
98
ISLE/emscripten/window.cpp
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#include "window.h"
|
||||||
|
|
||||||
|
#include "mxtypes.h"
|
||||||
|
|
||||||
|
#include <SDL3/SDL_log.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <emscripten/html5.h>
|
||||||
|
|
||||||
|
double g_fullWidth;
|
||||||
|
double g_fullHeight;
|
||||||
|
bool g_scaleAspect = true;
|
||||||
|
bool g_originalResolution = true;
|
||||||
|
|
||||||
|
extern MxS32 g_targetWidth;
|
||||||
|
extern MxS32 g_targetHeight;
|
||||||
|
|
||||||
|
void Emscripten_SetupWindow(SDL_Window* p_window)
|
||||||
|
{
|
||||||
|
EmscriptenFullscreenStrategy strategy;
|
||||||
|
strategy.scaleMode = g_scaleAspect ? EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT : EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH;
|
||||||
|
strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF;
|
||||||
|
strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
|
||||||
|
strategy.canvasResizedCallbackUserData = p_window;
|
||||||
|
strategy.canvasResizedCallback = [](int eventType, const void* reserved, void* userData) -> bool {
|
||||||
|
int width, height;
|
||||||
|
emscripten_get_canvas_element_size("canvas", &width, &height);
|
||||||
|
emscripten_get_element_css_size("#canvas", &g_fullWidth, &g_fullHeight);
|
||||||
|
|
||||||
|
if (g_originalResolution) {
|
||||||
|
SDL_SetWindowSize((SDL_Window*) userData, g_targetWidth, g_targetHeight);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_SetWindowSize((SDL_Window*) userData, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Log(
|
||||||
|
"Emscripten: window size %dx%d, canvas size %dx%d, scale aspect %s, original resolution %s",
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
(int) g_fullWidth,
|
||||||
|
(int) g_fullHeight,
|
||||||
|
g_scaleAspect ? "TRUE" : "FALSE",
|
||||||
|
g_originalResolution ? "TRUE" : "FALSE"
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
emscripten_enter_soft_fullscreen("canvas", &strategy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emscripten_SetScaleAspect(bool p_scaleAspect)
|
||||||
|
{
|
||||||
|
g_scaleAspect = p_scaleAspect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emscripten_SetOriginalResolution(bool p_originalResolution)
|
||||||
|
{
|
||||||
|
g_originalResolution = p_originalResolution;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emscripten_ConvertEventToRenderCoordinates(SDL_Event* event)
|
||||||
|
{
|
||||||
|
if (!g_scaleAspect) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event->type) {
|
||||||
|
case SDL_EVENT_MOUSE_MOTION: {
|
||||||
|
const float scale = std::min(g_fullWidth / g_targetWidth, g_fullHeight / g_targetHeight);
|
||||||
|
const float widthRatio = (g_targetWidth * scale) / g_fullWidth;
|
||||||
|
const float heightRatio = (g_targetHeight * scale) / g_fullHeight;
|
||||||
|
event->motion.x = (event->motion.x - (g_targetWidth * (1.0f - widthRatio) / 2.0f)) / widthRatio;
|
||||||
|
event->motion.y = (event->motion.y - (g_targetHeight * (1.0f - heightRatio) / 2.0f)) / heightRatio;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||||
|
case SDL_EVENT_MOUSE_BUTTON_UP: {
|
||||||
|
const float scale = std::min(g_fullWidth / g_targetWidth, g_fullHeight / g_targetHeight);
|
||||||
|
const float widthRatio = (g_targetWidth * scale) / g_fullWidth;
|
||||||
|
const float heightRatio = (g_targetHeight * scale) / g_fullHeight;
|
||||||
|
event->button.x = (event->button.x - (g_targetWidth * (1.0f - widthRatio) / 2.0f)) / widthRatio;
|
||||||
|
event->button.y = (event->button.y - (g_targetHeight * (1.0f - heightRatio) / 2.0f)) / heightRatio;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_EVENT_FINGER_MOTION:
|
||||||
|
case SDL_EVENT_FINGER_DOWN:
|
||||||
|
case SDL_EVENT_FINGER_UP: {
|
||||||
|
const float scale = std::min(g_fullWidth / g_targetWidth, g_fullHeight / g_targetHeight);
|
||||||
|
const float widthRatio = (g_targetWidth * scale) / g_fullWidth;
|
||||||
|
const float heightRatio = (g_targetHeight * scale) / g_fullHeight;
|
||||||
|
event->tfinger.x = (event->tfinger.x * g_targetWidth - (g_targetWidth * (1.0f - widthRatio) / 2.0f)) /
|
||||||
|
widthRatio / g_targetWidth;
|
||||||
|
event->tfinger.y = (event->tfinger.y * g_targetHeight - (g_targetHeight * (1.0f - heightRatio) / 2.0f)) /
|
||||||
|
heightRatio / g_targetHeight;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
ISLE/emscripten/window.h
Normal file
11
ISLE/emscripten/window.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef EMSCRIPTEN_WINDOW_H
|
||||||
|
#define EMSCRIPTEN_WINDOW_H
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
void Emscripten_SetupWindow(SDL_Window* p_window);
|
||||||
|
void Emscripten_SetScaleAspect(bool p_scaleAspect);
|
||||||
|
void Emscripten_SetOriginalResolution(bool p_originalResolution);
|
||||||
|
void Emscripten_ConvertEventToRenderCoordinates(SDL_Event* event);
|
||||||
|
|
||||||
|
#endif // EMSCRIPTEN_WINDOW_H
|
||||||
@ -53,6 +53,7 @@
|
|||||||
#include "emscripten/events.h"
|
#include "emscripten/events.h"
|
||||||
#include "emscripten/filesystem.h"
|
#include "emscripten/filesystem.h"
|
||||||
#include "emscripten/messagebox.h"
|
#include "emscripten/messagebox.h"
|
||||||
|
#include "emscripten/window.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __3DS__
|
#ifdef __3DS__
|
||||||
@ -441,6 +442,10 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
|||||||
if (device && !device->ConvertEventToRenderCoordinates(event)) {
|
if (device && !device->ConvertEventToRenderCoordinates(event)) {
|
||||||
SDL_Log("Failed to convert event coordinates: %s", SDL_GetError());
|
SDL_Log("Failed to convert event coordinates: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
Emscripten_ConvertEventToRenderCoordinates(event);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -641,8 +646,8 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
|||||||
#endif
|
#endif
|
||||||
g_mousemoved = TRUE;
|
g_mousemoved = TRUE;
|
||||||
|
|
||||||
float x = SDL_clamp(event->tfinger.x, 0, 1) * 640;
|
float x = SDL_clamp(event->tfinger.x, 0, 1) * g_targetWidth;
|
||||||
float y = SDL_clamp(event->tfinger.y, 0, 1) * 480;
|
float y = SDL_clamp(event->tfinger.y, 0, 1) * g_targetHeight;
|
||||||
|
|
||||||
if (InputManager()) {
|
if (InputManager()) {
|
||||||
InputManager()->QueueEvent(c_notificationMouseMove, LegoEventNotificationParam::c_lButtonState, x, y, 0);
|
InputManager()->QueueEvent(c_notificationMouseMove, LegoEventNotificationParam::c_lButtonState, x, y, 0);
|
||||||
@ -682,8 +687,8 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
|||||||
#endif
|
#endif
|
||||||
g_mousedown = TRUE;
|
g_mousedown = TRUE;
|
||||||
|
|
||||||
float x = SDL_clamp(event->tfinger.x, 0, 1) * 640;
|
float x = SDL_clamp(event->tfinger.x, 0, 1) * g_targetWidth;
|
||||||
float y = SDL_clamp(event->tfinger.y, 0, 1) * 480;
|
float y = SDL_clamp(event->tfinger.y, 0, 1) * g_targetHeight;
|
||||||
|
|
||||||
if (InputManager()) {
|
if (InputManager()) {
|
||||||
InputManager()->QueueEvent(c_notificationButtonDown, LegoEventNotificationParam::c_lButtonState, x, y, 0);
|
InputManager()->QueueEvent(c_notificationButtonDown, LegoEventNotificationParam::c_lButtonState, x, y, 0);
|
||||||
@ -729,8 +734,8 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
|||||||
#endif
|
#endif
|
||||||
g_mousedown = FALSE;
|
g_mousedown = FALSE;
|
||||||
|
|
||||||
float x = SDL_clamp(event->tfinger.x, 0, 1) * 640;
|
float x = SDL_clamp(event->tfinger.x, 0, 1) * g_targetWidth;
|
||||||
float y = SDL_clamp(event->tfinger.y, 0, 1) * 480;
|
float y = SDL_clamp(event->tfinger.y, 0, 1) * g_targetHeight;
|
||||||
|
|
||||||
if (InputManager()) {
|
if (InputManager()) {
|
||||||
InputManager()->QueueEvent(c_notificationButtonUp, 0, x, y, 0);
|
InputManager()->QueueEvent(c_notificationButtonUp, 0, x, y, 0);
|
||||||
@ -770,6 +775,11 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
|||||||
if (!g_isle->GetGameStarted() && action && state == MxPresenter::e_ready &&
|
if (!g_isle->GetGameStarted() && action && state == MxPresenter::e_ready &&
|
||||||
!SDL_strncmp(action->GetObjectName(), "Lego_Smk", 8)) {
|
!SDL_strncmp(action->GetObjectName(), "Lego_Smk", 8)) {
|
||||||
g_isle->SetGameStarted(TRUE);
|
g_isle->SetGameStarted(TRUE);
|
||||||
|
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
Emscripten_SetupWindow((SDL_Window*) g_isle->GetWindowHandle());
|
||||||
|
#endif
|
||||||
|
|
||||||
SDL_Log("Game started");
|
SDL_Log("Game started");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1413,8 +1423,8 @@ void IsleApp::MoveVirtualMouseViaJoystick()
|
|||||||
if (moveX != 0 || moveY != 0) {
|
if (moveX != 0 || moveY != 0) {
|
||||||
g_mousemoved = TRUE;
|
g_mousemoved = TRUE;
|
||||||
|
|
||||||
g_lastMouseX = SDL_clamp(g_lastMouseX + moveX, 0, 640);
|
g_lastMouseX = SDL_clamp(g_lastMouseX + moveX, 0, g_targetWidth);
|
||||||
g_lastMouseY = SDL_clamp(g_lastMouseY + moveY, 0, 480);
|
g_lastMouseY = SDL_clamp(g_lastMouseY + moveY, 0, g_targetHeight);
|
||||||
|
|
||||||
if (InputManager()) {
|
if (InputManager()) {
|
||||||
InputManager()->QueueEvent(
|
InputManager()->QueueEvent(
|
||||||
|
|||||||
@ -173,31 +173,21 @@ bool Direct3DRMDevice2Impl::ConvertEventToRenderCoordinates(SDL_Event* event)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SDL_EVENT_MOUSE_MOTION: {
|
case SDL_EVENT_MOUSE_MOTION: {
|
||||||
int rawX = event->motion.x;
|
event->motion.x = (event->motion.x - m_viewportTransform.offsetX) / m_viewportTransform.scale;
|
||||||
int rawY = event->motion.y;
|
event->motion.y = (event->motion.y - m_viewportTransform.offsetY) / m_viewportTransform.scale;
|
||||||
float x = (rawX - m_viewportTransform.offsetX) / m_viewportTransform.scale;
|
|
||||||
float y = (rawY - m_viewportTransform.offsetY) / m_viewportTransform.scale;
|
|
||||||
event->motion.x = static_cast<Sint32>(x);
|
|
||||||
event->motion.y = static_cast<Sint32>(y);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||||
case SDL_EVENT_MOUSE_BUTTON_UP: {
|
case SDL_EVENT_MOUSE_BUTTON_UP: {
|
||||||
int rawX = event->button.x;
|
event->button.x = (event->button.x - m_viewportTransform.offsetX) / m_viewportTransform.scale;
|
||||||
int rawY = event->button.y;
|
event->button.y = (event->button.y - m_viewportTransform.offsetY) / m_viewportTransform.scale;
|
||||||
float x = (rawX - m_viewportTransform.offsetX) / m_viewportTransform.scale;
|
|
||||||
float y = (rawY - m_viewportTransform.offsetY) / m_viewportTransform.scale;
|
|
||||||
event->button.x = static_cast<Sint32>(x);
|
|
||||||
event->button.y = static_cast<Sint32>(y);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SDL_EVENT_FINGER_MOTION:
|
case SDL_EVENT_FINGER_MOTION:
|
||||||
case SDL_EVENT_FINGER_DOWN:
|
case SDL_EVENT_FINGER_DOWN:
|
||||||
case SDL_EVENT_FINGER_UP: {
|
case SDL_EVENT_FINGER_UP: {
|
||||||
int rawX = event->tfinger.x * m_windowWidth;
|
float x = (event->tfinger.x * m_windowWidth - m_viewportTransform.offsetX) / m_viewportTransform.scale;
|
||||||
int rawY = event->tfinger.y * m_windowHeight;
|
float y = (event->tfinger.y * m_windowHeight - m_viewportTransform.offsetY) / m_viewportTransform.scale;
|
||||||
float x = (rawX - m_viewportTransform.offsetX) / m_viewportTransform.scale;
|
|
||||||
float y = (rawY - m_viewportTransform.offsetY) / m_viewportTransform.scale;
|
|
||||||
event->tfinger.x = x / m_virtualWidth;
|
event->tfinger.x = x / m_virtualWidth;
|
||||||
event->tfinger.y = y / m_virtualHeight;
|
event->tfinger.y = y / m_virtualHeight;
|
||||||
break;
|
break;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user