fix: arrancar amb el borde desactivat feia crash al activarlo

This commit is contained in:
2026-04-13 11:57:01 +02:00
parent 023bbb224b
commit d9c41f420b
6 changed files with 38 additions and 15 deletions

View File

@@ -277,6 +277,9 @@ elseif(EMSCRIPTEN)
-sMAX_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2
-sINITIAL_MEMORY=67108864 -sINITIAL_MEMORY=67108864
-sASSERTIONS=1 -sASSERTIONS=1
# ASYNCIFY només per permetre emscripten_sleep(0) durant la precàrrega de recursos
# (el bucle principal del joc ja usa SDL3 Callback API, no depèn d'ASYNCIFY).
-sASYNCIFY=1
) )
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".html") set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".html")
elseif(UNIX AND NOT APPLE) elseif(UNIX AND NOT APPLE)

View File

@@ -20,11 +20,8 @@ namespace GlobalInputs {
// Funciones internas // Funciones internas
namespace { namespace {
void handleQuit() { void handleQuit() {
#ifdef __EMSCRIPTEN__ // En la escena GAME el comportamiento es siempre el mismo (con o sin modo kiosko):
// A la versió web no es pot eixir del joc // Escape torna al menu principal. Això també és vàlid en la versió web.
return;
#else
// En la escena GAME el comportamiento es siempre el mismo (con o sin modo kiosko)
if (SceneManager::current == SceneManager::Scene::GAME) { if (SceneManager::current == SceneManager::Scene::GAME) {
const std::string CODE = "PRESS AGAIN TO RETURN TO MENU"; const std::string CODE = "PRESS AGAIN TO RETURN TO MENU";
if (stringInVector(Notifier::get()->getCodes(), CODE)) { if (stringInVector(Notifier::get()->getCodes(), CODE)) {
@@ -45,6 +42,11 @@ namespace GlobalInputs {
return; return;
} }
#ifdef __EMSCRIPTEN__
// A la versió web no es pot eixir del joc des de fora de l'escena GAME
// (el navegador gestiona la pestanya; Escape no tanca res).
return;
#else
// Comportamiento normal fuera del modo kiosko // Comportamiento normal fuera del modo kiosko
const std::string CODE = "PRESS AGAIN TO EXIT"; const std::string CODE = "PRESS AGAIN TO EXIT";
if (stringInVector(Notifier::get()->getCodes(), CODE)) { if (stringInVector(Notifier::get()->getCodes(), CODE)) {

View File

@@ -295,16 +295,16 @@ void Screen::adjustWindowSize() {
window_width_ = Options::game.width + (Options::video.border.enabled ? Options::video.border.width * 2 : 0); window_width_ = Options::game.width + (Options::video.border.enabled ? Options::video.border.width * 2 : 0);
window_height_ = Options::game.height + (Options::video.border.enabled ? Options::video.border.height * 2 : 0); window_height_ = Options::game.height + (Options::video.border.enabled ? Options::video.border.height * 2 : 0);
// Reservamos memoria una sola vez. // border_surface_ sempre té el tamany complet del borde (game + 2*border_w/h),
// Si el buffer es más pequeño que la superficie, crash asegurado. // independentment de si el borde està visible o no. El buffer ARGB que l'ombra
border_pixel_buffer_.resize(static_cast<size_t>(window_width_ * window_height_)); // ha de ser ALMENYS tan gran com la surface; si no, toARGBBuffer() escriu fora
// de bounds i corromp el heap (bug latent a desktop fins a disparar-lo un toggleBorder).
const size_t FULL_BORDER_BUFFER_SIZE =
static_cast<size_t>(Options::game.width + (Options::video.border.width * 2)) *
static_cast<size_t>(Options::game.height + (Options::video.border.height * 2));
border_pixel_buffer_.resize(FULL_BORDER_BUFFER_SIZE);
game_pixel_buffer_.resize(static_cast<size_t>(Options::game.width * Options::game.height)); game_pixel_buffer_.resize(static_cast<size_t>(Options::game.width * Options::game.height));
// border_pixel_buffer_ es el buffer que se sube a la GPU (tamaño total ventana).
if (Options::video.border.enabled) {
border_pixel_buffer_.resize(static_cast<size_t>(window_width_ * window_height_));
}
// Lógica de centrado y redimensionado de ventana SDL // Lógica de centrado y redimensionado de ventana SDL
if (static_cast<int>(Options::video.fullscreen) == 0) { if (static_cast<int>(Options::video.fullscreen) == 0) {
int old_w; int old_w;

View File

@@ -2,6 +2,10 @@
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h> // Para emscripten_sleep
#endif
#include <algorithm> // Para find_if #include <algorithm> // Para find_if
#include <cstdlib> // Para exit, size_t #include <cstdlib> // Para exit, size_t
#include <fstream> // Para ifstream, istreambuf_iterator #include <fstream> // Para ifstream, istreambuf_iterator
@@ -530,6 +534,12 @@ namespace Resource {
#if defined(__EMSCRIPTEN__) || defined(_DEBUG) #if defined(__EMSCRIPTEN__) || defined(_DEBUG)
renderProgress(); renderProgress();
checkEvents(); checkEvents();
#endif
#ifdef __EMSCRIPTEN__
// Cedeix el control al navegador perquè pinte el canvas i processe
// events. Sense això, el thread principal queda bloquejat durant tota
// la precàrrega i el jugador només veu pantalla negra.
emscripten_sleep(0);
#endif #endif
} }

View File

@@ -147,9 +147,12 @@ Director::Director() {
Options::loadFromFile(); Options::loadFromFile();
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__
// A la versió web el navegador gestiona la finestra: res de fullscreen ni zoom. // A la versió web el navegador gestiona la finestra: forcem zoom x3
// perquè la textura 256x192 no es vegi minúscula al canvas HTML,
// i desactivem el borde per aprofitar al màxim l'espai del canvas.
Options::video.fullscreen = false; Options::video.fullscreen = false;
Options::window.zoom = 1; Options::window.zoom = 4;
Options::video.border.enabled = false;
#endif #endif
// Configura la ruta y carga los presets de PostFX // Configura la ruta y carga los presets de PostFX

View File

@@ -948,11 +948,16 @@ static auto cmdKiosk(const std::vector<std::string>& args) -> std::string {
// EXIT / QUIT // EXIT / QUIT
static auto cmdExit(const std::vector<std::string>& args) -> std::string { static auto cmdExit(const std::vector<std::string>& args) -> std::string {
#ifdef __EMSCRIPTEN__
(void)args;
return "Not allowed in web version";
#else
if (Options::kiosk.enabled && (args.empty() || args[0] != "PLEASE")) { if (Options::kiosk.enabled && (args.empty() || args[0] != "PLEASE")) {
return "Not allowed in kiosk mode"; return "Not allowed in kiosk mode";
} }
SceneManager::current = SceneManager::Scene::QUIT; SceneManager::current = SceneManager::Scene::QUIT;
return "Quitting..."; return "Quitting...";
#endif
} }
// SIZE // SIZE