mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
revamped Launcher
This commit is contained in:
+1018
-1117
File diff suppressed because it is too large
Load Diff
+18
-33
@@ -1,15 +1,13 @@
|
||||
// launcher.h — integrated RmlUi launcher front-end.
|
||||
// launcher.h — SDL2/OpenGL launcher front-end.
|
||||
//
|
||||
// Shown in the runtime's SDL/OpenGL window before the emulator boots: the user
|
||||
// picks renderer / supersampling / AA / colour model / SPU-HQ, the BIOS, disc,
|
||||
// memory cards and controllers, then presses LAUNCH. The chosen values are
|
||||
// written back into the UserSettings the runtime then applies (and persisted to
|
||||
// settings.toml by the caller).
|
||||
// Shown in a temporary SDL window before the emulator boots: the user
|
||||
// picks renderer / supersampling / AA / colour model / SPU-HQ, the BIOS,
|
||||
// disc, memory cards and controllers, then presses LAUNCH. The chosen
|
||||
// values are written back into the UserSettings the runtime then applies
|
||||
// (and persisted to settings.toml by the caller).
|
||||
//
|
||||
// Design note — the launcher does NOT create or own the window or GL context;
|
||||
// the caller passes an already-current GL 3.3 context. This keeps the module a
|
||||
// pure overlay so a future "re-open settings while the game is running" path can
|
||||
// reuse it without owning the window lifecycle.
|
||||
// This module creates its own SDL window + GL 3.3 core context — the
|
||||
// caller creates the window, calls run(), then tears everything down.
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -24,37 +22,24 @@ namespace PSXRecompV4 { struct UserSettings; }
|
||||
namespace psx_launcher {
|
||||
|
||||
enum class Result {
|
||||
Launch, // user pressed LAUNCH — proceed to boot with `io`
|
||||
Quit, // user closed the window — caller should exit
|
||||
Unavailable, // launcher could not initialise (assets/GL); caller boots as if skipped
|
||||
Launch, // user pressed LAUNCH — proceed to boot with `io`
|
||||
Quit, // user closed the window — caller should exit
|
||||
Unavailable, // launcher could not initialise (assets/GL); caller boots as if skipped
|
||||
};
|
||||
|
||||
// Static facts about the game the launcher is configuring. Drives the title and
|
||||
// the disc-verification badge. Extends naturally for later phases.
|
||||
struct GameInfo {
|
||||
const char* name = nullptr; // display name, e.g. "Tomba!"
|
||||
const char* expected_serial = nullptr; // game id "SCUS-94236" (null = no serial check)
|
||||
uint32_t expected_crc = 0; // full-file CRC32 of the data track
|
||||
bool has_expected_crc = false; // whether expected_crc is meaningful
|
||||
bool allow_hybrid = true; // offer the "Hybrid" pad mode (false => Analog | D-Pad only)
|
||||
bool lock_mode = false; // hide the whole pad-mode selector and force locked_mode (single-pad-type games)
|
||||
int locked_mode = 2; // PAD_MODE_DIGITAL; the mode forced when lock_mode is true
|
||||
bool lock_device = false; // hide the Player 1/2 controller cards entirely (fixed, auto-bound pad type; e.g. Ape Escape DualShock)
|
||||
bool ws_offered = true; // offer the EXPERIMENTAL Widescreen toggle (false = hidden, game ships 4:3 only)
|
||||
const char* name = nullptr;
|
||||
const char* expected_serial = nullptr;
|
||||
uint32_t expected_crc = 0;
|
||||
bool has_expected_crc = false;
|
||||
bool allow_hybrid = true;
|
||||
bool lock_mode = false;
|
||||
int locked_mode = 2; // PAD_MODE_DIGITAL
|
||||
|
||||
// Optional "Localization" dropdown. Populated from game.toml
|
||||
// [localization].languages. When non-empty the launcher shows a language
|
||||
// menu; empty => no menu (the general case — only Tsumu declares languages).
|
||||
// code feeds the runtime's translation layer ("off"/"jp"/"" = untranslated).
|
||||
struct Language { std::string code; std::string label; };
|
||||
std::vector<Language> languages;
|
||||
};
|
||||
|
||||
// Run the launcher loop to completion. `gl_context` is an SDL_GLContext (void*
|
||||
// to avoid leaking SDL types into this header) already created and current on
|
||||
// `window`. `io` is seeded with the effective settings (game.toml ∪ settings.toml)
|
||||
// and, on Result::Launch, updated in place with the user's choices. `assets_dir`
|
||||
// is the directory holding launcher.rml / .rcss / fonts.
|
||||
Result run(SDL_Window* window, void* gl_context,
|
||||
PSXRecompV4::UserSettings& io,
|
||||
const GameInfo& game, const char* assets_dir);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// stb_image implementation TU. Kept separate so the (large) decoder lives in
|
||||
// its own translation unit and launcher.cpp only sees the declarations.
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#define STBI_NO_STDIO // we feed it memory buffers via RmlUi's FileInterface
|
||||
#define STBI_ONLY_PNG // launcher art is PNG; keeps the decoder small
|
||||
#include "third_party/stb_image.h"
|
||||
|
||||
+5079
File diff suppressed because it is too large
Load Diff
+7
-65
@@ -95,55 +95,11 @@ else()
|
||||
option(PSX_STATIC_RUNTIME "Statically link SDL2 + libgcc/libstdc++ for a self-contained exe" OFF)
|
||||
endif()
|
||||
|
||||
# PSX_LAUNCHER: build the integrated RmlUi launcher UI (settings/disc/memcard/
|
||||
# controller front-end shown before the emulator boots). Needs the vendored
|
||||
# lib/RmlUi + lib/freetype submodules. ON by default; the oracle/beetle builds
|
||||
# never include it. Turn OFF for a launcher-less runtime (boots straight in).
|
||||
option(PSX_LAUNCHER "Build the integrated RmlUi launcher UI" ON)
|
||||
|
||||
# Build the vendored RmlUi + FreeType once per CMake project (idempotent — the
|
||||
# rmlui_core target guards re-entry). Both are linked statically into the exe so
|
||||
# the self-contained-binary guarantee (PSX_STATIC_RUNTIME) still holds.
|
||||
function(psxrecomp_ensure_launcher_libs)
|
||||
if(TARGET rmlui_core)
|
||||
return()
|
||||
endif()
|
||||
if(NOT EXISTS "${PSXRECOMP_ROOT}/lib/RmlUi/CMakeLists.txt" OR
|
||||
NOT EXISTS "${PSXRECOMP_ROOT}/lib/freetype/CMakeLists.txt")
|
||||
message(FATAL_ERROR
|
||||
"PSX_LAUNCHER=ON but lib/RmlUi or lib/freetype is missing. "
|
||||
"Run: git submodule update --init --recursive")
|
||||
endif()
|
||||
|
||||
# Static libs fold into the exe (keeps the self-contained binary intact).
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
|
||||
# FreeType — RmlUi's font engine. Disable every optional codec/dep so the
|
||||
# only thing we pull in is the core font rasteriser.
|
||||
set(FT_DISABLE_ZLIB TRUE CACHE BOOL "" FORCE)
|
||||
set(FT_DISABLE_BZIP2 TRUE CACHE BOOL "" FORCE)
|
||||
set(FT_DISABLE_PNG TRUE CACHE BOOL "" FORCE)
|
||||
set(FT_DISABLE_HARFBUZZ TRUE CACHE BOOL "" FORCE)
|
||||
set(FT_DISABLE_BROTLI TRUE CACHE BOOL "" FORCE)
|
||||
add_subdirectory("${PSXRECOMP_ROOT}/lib/freetype"
|
||||
"${CMAKE_BINARY_DIR}/_deps/freetype-build" EXCLUDE_FROM_ALL)
|
||||
# FreeType's add_subdirectory exports the target `freetype` but not the
|
||||
# namespaced alias (that's install-only). RmlUi's soft dependency check
|
||||
# looks for Freetype::Freetype, so create it here.
|
||||
if(NOT TARGET Freetype::Freetype)
|
||||
add_library(Freetype::Freetype ALIAS freetype)
|
||||
endif()
|
||||
|
||||
# RmlUi — core only, FreeType font engine, no samples/tests/PCH.
|
||||
set(RMLUI_SAMPLES OFF CACHE BOOL "" FORCE)
|
||||
set(RMLUI_FONT_ENGINE "freetype" CACHE STRING "" FORCE)
|
||||
set(RMLUI_PRECOMPILED_HEADERS OFF CACHE BOOL "" FORCE)
|
||||
# The bundled robin_hood hash map fails its bitness detection under MinGW
|
||||
# GCC ("#error Unsupported bitness"); use std:: containers instead.
|
||||
set(RMLUI_THIRDPARTY_CONTAINERS OFF CACHE BOOL "" FORCE)
|
||||
add_subdirectory("${PSXRECOMP_ROOT}/lib/RmlUi"
|
||||
"${CMAKE_BINARY_DIR}/_deps/RmlUi-build" EXCLUDE_FROM_ALL)
|
||||
endfunction()
|
||||
# PSX_LAUNCHER: build the integrated SDL2/OpenGL launcher (settings/disc/memcard/
|
||||
# controller front-end shown before the emulator boots). ON by default; the
|
||||
# oracle/beetle builds never include it. Turn OFF for a launcher-less runtime
|
||||
# (boots straight in).
|
||||
option(PSX_LAUNCHER "Build the integrated SDL2/OpenGL launcher UI" ON)
|
||||
|
||||
set(PSXRECOMP_RUNTIME_SOURCES
|
||||
${PSXRECOMP_ROOT}/runtime/src/main.cpp
|
||||
@@ -452,31 +408,17 @@ function(psxrecomp_add_runtime_target target)
|
||||
target_compile_definitions(${target} PRIVATE PSX_COSIM=1 PSX_NO_DEBUG_TOOLS=1)
|
||||
endif()
|
||||
|
||||
# Integrated RmlUi launcher (not in the oracle build — that's headless).
|
||||
# Integrated SDL2/OpenGL launcher (not in the oracle build — headless).
|
||||
if(PSX_LAUNCHER AND NOT PSXRT_ORACLE)
|
||||
psxrecomp_ensure_launcher_libs()
|
||||
target_sources(${target} PRIVATE
|
||||
${PSXRECOMP_ROOT}/runtime/launcher/launcher.cpp
|
||||
${PSXRECOMP_ROOT}/runtime/launcher/stb_image_impl.cpp
|
||||
${PSXRECOMP_ROOT}/lib/RmlUi/Backends/RmlUi_Platform_SDL.cpp
|
||||
${PSXRECOMP_ROOT}/lib/RmlUi/Backends/RmlUi_Renderer_GL3.cpp
|
||||
)
|
||||
# The vendored GL3 backend uses std::all_of without including
|
||||
# <algorithm>; force-include it rather than patching the pinned
|
||||
# submodule. (GCC/Clang only; MSVC pulls it in transitively.)
|
||||
if(NOT MSVC)
|
||||
set_source_files_properties(
|
||||
${PSXRECOMP_ROOT}/lib/RmlUi/Backends/RmlUi_Renderer_GL3.cpp
|
||||
PROPERTIES COMPILE_OPTIONS "-include;algorithm")
|
||||
endif()
|
||||
target_include_directories(${target} PRIVATE
|
||||
${PSXRECOMP_ROOT}/lib/RmlUi/Include
|
||||
${PSXRECOMP_ROOT}/lib/RmlUi/Backends
|
||||
${PSXRECOMP_ROOT}/runtime/launcher
|
||||
)
|
||||
target_link_libraries(${target} PRIVATE RmlUi::Core)
|
||||
target_compile_definitions(${target} PRIVATE PSX_LAUNCHER=1)
|
||||
# Ship the launcher assets (RML/RCSS/fonts) next to the exe.
|
||||
# Ship the launcher assets (fonts + images) next to the exe.
|
||||
add_custom_command(TARGET ${target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
"${PSXRECOMP_ROOT}/runtime/launcher/assets"
|
||||
|
||||
Reference in New Issue
Block a user