142 lines
4.7 KiB
C++
142 lines
4.7 KiB
C++
// Port a l'API de callbacks de SDL3: el runtime posseïx el main loop i ens
|
|
// crida a SDL_AppInit/SDL_AppIterate/SDL_AppEvent/SDL_AppQuit. Imprescindible
|
|
// per al port a emscripten on no podem tindre un bucle while propi al hilo
|
|
// principal. Funciona igual en build natiu (Linux/macOS/Windows) perquè
|
|
// SDL3 embolcalla el seu propi main loop darrere d'aquestes callbacks.
|
|
|
|
#define SDL_MAIN_USE_CALLBACKS
|
|
#include <SDL3/SDL.h>
|
|
#include <SDL3/SDL_main.h>
|
|
|
|
#include <ctime>
|
|
#include <string>
|
|
|
|
#include "core/input/key_config.hpp"
|
|
#include "core/jail/jail_audio.hpp"
|
|
#include "core/jail/jdraw8.hpp"
|
|
#include "core/jail/jfile.hpp"
|
|
#include "core/jail/jgame.hpp"
|
|
#include "core/locale/locale.hpp"
|
|
#include "core/rendering/menu.hpp"
|
|
#include "core/rendering/overlay.hpp"
|
|
#include "core/rendering/screen.hpp"
|
|
#include "core/resources/resource_helper.hpp"
|
|
#include "core/system/director.hpp"
|
|
#include "game/options.hpp"
|
|
|
|
SDL_AppResult SDL_AppInit(void** /*appstate*/, int /*argc*/, char* /*argv*/[]) {
|
|
srand(unsigned(time(nullptr)));
|
|
|
|
// Crea la carpeta de configuració i carrega les opcions
|
|
file_setconfigfolder("jailgames/aee");
|
|
|
|
// Ruta absoluta a data/ basada en la ubicació de l'executable.
|
|
// SDL_GetBasePath() detecta automàticament si estem dins d'un .app bundle
|
|
// (retorna Contents/Resources/) o en un executable normal (carpeta del binari).
|
|
const char* base_path = SDL_GetBasePath();
|
|
std::string resource_pack_path;
|
|
if (base_path) {
|
|
const std::string data_path = std::string(base_path) + "data/";
|
|
file_setresourcefolder(data_path.c_str());
|
|
resource_pack_path = std::string(base_path) + "resources.pack";
|
|
} else {
|
|
resource_pack_path = "resources.pack";
|
|
}
|
|
|
|
// Sistema de recursos: prova el pack i cau a fitxers solts dins data/.
|
|
// Release natiu exigix el pack (sense fallback); Debug i WASM mantenen
|
|
// el fallback actiu per a desenvolupament i per al build amb MEMFS.
|
|
#if defined(NDEBUG) && !defined(__EMSCRIPTEN__)
|
|
const bool enable_fallback = false;
|
|
#else
|
|
const bool enable_fallback = true;
|
|
#endif
|
|
if (!ResourceHelper::initializeResourceSystem(resource_pack_path, enable_fallback)) {
|
|
return SDL_APP_FAILURE;
|
|
}
|
|
|
|
Options::setConfigFile(std::string(file_getconfigfolder()) + "config.yaml");
|
|
Options::loadFromFile();
|
|
|
|
// KeyConfig: defaults des de data/input/keys.yaml + overrides de l'usuari
|
|
KeyConfig::init("input/keys.yaml",
|
|
std::string(file_getconfigfolder()) + "keys.yaml");
|
|
|
|
#ifndef NDEBUG
|
|
// debug.yaml: estat inicial de gameplay per a tests ràpids,
|
|
// només en builds de debug.
|
|
Options::setDebugFile(std::string(file_getconfigfolder()) + "debug.yaml");
|
|
Options::loadDebugFromFile();
|
|
#endif
|
|
|
|
#ifdef __EMSCRIPTEN__
|
|
// MEMFS no persistix entre recàrregues: força valors sensats per a web.
|
|
Options::window.fullscreen = false;
|
|
Options::window.zoom = 1;
|
|
Options::video.aspect_ratio_4_3 = true;
|
|
Options::video.scaling_mode = Options::ScalingMode::INTEGER;
|
|
Options::video.texture_filter = Options::TextureFilter::LINEAR;
|
|
#endif
|
|
|
|
// Carrega textos (idioma per defecte: valencià)
|
|
Locale::load("locale/ca.yaml");
|
|
|
|
// Carrega presets de shaders
|
|
Options::setPostFXFile(std::string(file_getconfigfolder()) + "postfx.yaml");
|
|
Options::loadPostFXFromFile();
|
|
Options::setCrtPiFile(std::string(file_getconfigfolder()) + "crtpi.yaml");
|
|
Options::loadCrtPiFromFile();
|
|
|
|
JG_Init();
|
|
Screen::init();
|
|
JD8_Init();
|
|
JA_Init(48000, SDL_AUDIO_S16, 2);
|
|
Options::applyAudio();
|
|
Overlay::init();
|
|
Menu::init();
|
|
Director::init();
|
|
Director::get()->setup();
|
|
|
|
return SDL_APP_CONTINUE;
|
|
}
|
|
|
|
SDL_AppResult SDL_AppIterate(void* /*appstate*/) {
|
|
// Una iteració del bucle del Director. Abans els events es drenaven
|
|
// amb SDL_PollEvent dins d'aquesta funció; ara SDL ens els lliura
|
|
// d'un en un via SDL_AppEvent, així que iterate() no els toca.
|
|
if (!Director::get()->iterate()) {
|
|
return SDL_APP_SUCCESS;
|
|
}
|
|
return SDL_APP_CONTINUE;
|
|
}
|
|
|
|
SDL_AppResult SDL_AppEvent(void* /*appstate*/, SDL_Event* event) {
|
|
if (!event) return SDL_APP_CONTINUE;
|
|
Director::get()->handleEvent(*event);
|
|
if (Director::get()->isQuitRequested()) {
|
|
return SDL_APP_SUCCESS;
|
|
}
|
|
return SDL_APP_CONTINUE;
|
|
}
|
|
|
|
void SDL_AppQuit(void* /*appstate*/, SDL_AppResult /*result*/) {
|
|
// Neteja en ordre invers al de SDL_AppInit.
|
|
Director::get()->teardown();
|
|
|
|
Options::saveToFile();
|
|
KeyConfig::saveOverrides();
|
|
#ifndef NDEBUG
|
|
Options::saveDebugToFile();
|
|
#endif
|
|
|
|
Director::destroy();
|
|
KeyConfig::destroy();
|
|
Menu::destroy();
|
|
Overlay::destroy();
|
|
JA_Quit();
|
|
JD8_Quit();
|
|
Screen::destroy();
|
|
JG_Finalize();
|
|
ResourceHelper::shutdownResourceSystem();
|
|
}
|