Compare commits
10 Commits
a653dad7b0
...
2026-04-03
| Author | SHA1 | Date | |
|---|---|---|---|
| 8538a1047f | |||
| e150097edc | |||
| 5f0d1f9577 | |||
| 6d8d02f0e4 | |||
| 5f7fb8625d | |||
| ce2fcefd71 | |||
| 6f31751d42 | |||
| 43de2c0b35 | |||
| 1ca9d0c01b | |||
| 90d5e6c3cc |
200
CHANGELOG.md
Normal file
200
CHANGELOG.md
Normal file
@@ -0,0 +1,200 @@
|
||||
# CHANGELOG
|
||||
|
||||
Historial de canvis i novetats de Coffee Crisis Arcade Edition.
|
||||
|
||||
---
|
||||
|
||||
## 2026-04-03
|
||||
|
||||
- **Nova intro cinematogràfica**: les tarjetes s'llancen des dels costats de la pantalla amb zoom, rotació i rebot, simulant tirar cartes sobre una mesa. Les anteriors ixen despedides girant quan arriba la següent. Sombra amb efecte de perspectiva 2D→3D.
|
||||
- **Efectes sonors i visuals en la intro**: shake de pantalla i sons configurables a cada impacte de tarjeta.
|
||||
- **Migració a SDL3 GPU API**: postfx i crtpi migrats a SDL3GPU (Vulkan/Metal/D3D12).
|
||||
- **Migració de configuració a YAML**: eliminat el format antic, ara tot en YAML.
|
||||
- **Afegides opcions al Service Menu**.
|
||||
- **HUD de FPS retocat**, presets per defecte ajustats, finestra a 2x i shader off per defecte.
|
||||
- **Corregit bug d'input**: revertit un canvi que causava bucle infinit en F3 (pantalla completa) i F12 (service menu) en totes les escenes excepte Game.
|
||||
- Neteja de codi: eliminades referencies a OpenGL, fitxers GLSL sobrants, normalitzada la carpeta release i el caption de la finestra.
|
||||
|
||||
---
|
||||
|
||||
## 2025-10-25
|
||||
|
||||
- **Migració a delta_time pur** en credits, instructions i hiscore_table. Eliminat un bug que feia que els credits no acabaren mai si no passaves a mà.
|
||||
- **Corregida deformació subpixel** de textures en instructions i hiscore_table.
|
||||
- **Detecció de fitxers de puntuació corruptes**.
|
||||
- **Efecte de pulsos** afegit al scoreboard.
|
||||
- Al posar nom, el carrusel apareix directament en el caràcter d'acabar si ja havies posat nom abans.
|
||||
- Integrat jail_audio en la càrrega de resources.pack.
|
||||
- Pasaeta de linter en múltiples fitxers.
|
||||
- Nou icon per al joc.
|
||||
- Corregida la versió release de macOS per a funcionar correctament amb resources.pack.
|
||||
|
||||
---
|
||||
|
||||
## 2025-08-21
|
||||
|
||||
- **Integració amb resources.pack**: textures, animacions, textos, dades de la demo i jail_audio integrats amb ResourceHelper.
|
||||
- Actualitzat Makefile per a Windows, Linux i macOS.
|
||||
- Neteja de temporals al acabar.
|
||||
|
||||
---
|
||||
|
||||
## 2025-08-17
|
||||
|
||||
- **Afegit fade RANDOM_SQUARE2** amb timings canviats a mil·lisegons.
|
||||
- **Outline parametritzat** per als textos dels items.
|
||||
- **Colors de camiseta parametritzats** per defecte i quan pillen café.
|
||||
- Creat `defaults.h` amb els valors per defecte de Param.
|
||||
- Afegit `param_red.txt` amb guardes en setParams.
|
||||
- Fix: items que es quedaven engantxats a la part de dalt.
|
||||
- Fix: en el modo demo, assignava cafés al jugador que no jugava.
|
||||
- Fix: bug en l'estat pre del fade.
|
||||
- Fix: globos apareixien un frame mal situats al crear-se des d'un pare.
|
||||
- Afegit suport per a mapejar botons tipus trigger.
|
||||
|
||||
---
|
||||
|
||||
## 2025-08-10
|
||||
|
||||
- **Service Menu complet**: animació d'apertura/tancament, callback per a posar pausa en el joc, refresc visual al canviar mandos.
|
||||
- **Mandos en calent**: es poden connectar i desconnectar mandos durant el joc, amb notificació visual.
|
||||
- **PauseManager** afegit al joc.
|
||||
- **Càrrega de recursos on_demand**.
|
||||
- Afegit `shutdown.h` i `system_utils.h`.
|
||||
- Fix: el nom apareixia duplicat en la tabla de records.
|
||||
- Fix: Game no es desregistrava de ServiceMenu al destruir-se.
|
||||
- Precàrrega de textures del jugador amb variants de paleta.
|
||||
- Actualitzats frameworks per a macOS.
|
||||
|
||||
---
|
||||
|
||||
## 2025-03-25
|
||||
|
||||
- **Nova secció Intro** amb escenes seqüencials, animacions de tarjetes i text narratiu.
|
||||
- **Shaders respecten l'escalat sencer** i SDL_RenderSetLogicalSize en pantalla completa.
|
||||
- **Tecla per canviar l'integer scale** (F-key).
|
||||
- Afegit intro03.png i intro04.png.
|
||||
- Renomenat InputType a InputActions.
|
||||
- Actualitzat gamecontrollerdb.txt amb mappings de la recreativa.
|
||||
- Fix: al fer reset des de Game, en Intro no sonava la música.
|
||||
- Fix: al acabar la partida i vore els records, torna al títol.
|
||||
- Fix: amb l'àudio mutat, el fade per al soroll de boles el tornava a deixar activat.
|
||||
|
||||
---
|
||||
|
||||
## 2025-02-07
|
||||
|
||||
- **EnterName millorat**: si has omplit tots els slots, apretar una volta mes fixa el nom.
|
||||
- **Control de repetició per als eixos del joystick**.
|
||||
- **La tabla de puntuació** mostra amb altre color la puntuació acabada d'afegir i les aconseguides amb 1CC.
|
||||
- Nova font per a la intro.
|
||||
- Afegit efecte d'eixida a les instruccions.
|
||||
- Afegit disparador per a l'aparició de l'enemic nou.
|
||||
- Duplicada la font 04b_25 per a versió gris i versió negra.
|
||||
|
||||
---
|
||||
|
||||
## 2025-01-05
|
||||
|
||||
- **Optimitzat el circuit de render** en pantalla.
|
||||
- **Atenuat de pantalla restaurat**: Fade feia dos SDL_SetRenderDrawBlendMode sense restaurar.
|
||||
- Fix: es podia polsar per a jugar mentre feia el fade cap a la demo.
|
||||
- Fix: error en la seqüència final de retrocedir en el temps.
|
||||
- Calibrats els polsos al gust.
|
||||
- Afegida una lluna i un sol al fondo.
|
||||
- La powerball ja no es pot destruir fins que no ha fet un rebot.
|
||||
- Modificada la cadència de foc sense autofire.
|
||||
- Afegit botó per a activar o desactivar el ratolí.
|
||||
|
||||
---
|
||||
|
||||
## 2024-12-31
|
||||
|
||||
- **Enemic nou** complet: gràfics, comportament, àudio i veus.
|
||||
- **Fade out sincronitzat** de vídeo i àudio en el títol i el joc.
|
||||
- **Roidets de col·lisió** per als globos en certs moments.
|
||||
- La finestra ja es pot fer tan gran com permeta la pantalla (zoom dinàmic).
|
||||
- Afegides veus al jugador i efectes de so al rebotar quan mor.
|
||||
- Afegit delay opcional al flash de Screen.
|
||||
- Afegit botó per activar o desactivar l'autofire.
|
||||
- Fix: mode demo desactivava els sons permanentment.
|
||||
- Actualitzat jail_audio.
|
||||
|
||||
---
|
||||
|
||||
## 2024-12-05
|
||||
|
||||
- **Secció Credits acabada** a 320x240 (i per extensió, a qualsevol resolució).
|
||||
- **Zoom afegit a la classe Sprite** i al subtítol ARCADE EDITION.
|
||||
- Duplicats fitxers de shaders per a resolucions verticals de 256 i 240.
|
||||
- Afegit globalInputs::update() a totes les seccions.
|
||||
- Fix: faltava corregir el flash de destroyAllBalloons().
|
||||
- Fix: si saltes el logo, talla el so a meitat sonar.
|
||||
- Canvi d'idioma amb una tecla (i reinicia).
|
||||
|
||||
---
|
||||
|
||||
## 2024-11-27
|
||||
|
||||
- **Secció Credits**: disseny, música, globos amb play_area definida, opció de canviar la paleta al text.
|
||||
- Afegides traduccions dels credits.
|
||||
|
||||
---
|
||||
|
||||
## 2024-11-20
|
||||
|
||||
- **Nova animació de mort del personatge**: rebots, llengua fora, ulls en X, gràfics de caure derrotat per al segon jugador.
|
||||
- **Powerball redissenyada**: nous gràfics, nou comportament, ja no mata directament.
|
||||
- **Globos fills** ja no ixen centrats al pare (evita apilar-se).
|
||||
- Arreglos en el nom al obtindre la màxima puntuació.
|
||||
- Acabat BalloonManager.
|
||||
- CMakeLists.txt crea l'executable en l'arrel del projecte.
|
||||
- Nova font de text gran amb el doble de definició.
|
||||
- Fix: paleta verda del primer jugador ajustada a l'original.
|
||||
|
||||
---
|
||||
|
||||
## 2024-11-03
|
||||
|
||||
- **Teclat com a control independent**: ja pot jugar un jugador amb teclat i altre amb mando, o assignar el teclat a qualsevol jugador.
|
||||
- **Implementat el final del joc** i l'Attract Mode.
|
||||
- **Nou motor per a textos en pantalla** (game_text amb textures precarregades).
|
||||
- **Noves animacions** per a deixar de disparar.
|
||||
- Al redefinir botons, ja no pots repetir botó.
|
||||
- Fix: l'animació de morir s'actualitzava dos voltes per frame.
|
||||
- Fix: l'efecte de flash tenia un valor massa xicotet.
|
||||
|
||||
---
|
||||
|
||||
## 2024-10-28
|
||||
|
||||
- **Classe PathSprite completada**: el game_text gasta PathSprites en lloc de SmartSprites.
|
||||
- **Time stopper redissenyat**.
|
||||
- La partida sempre comença igual (createTwoBigBalloons).
|
||||
- Revisades les classes Balloon i Bullet.
|
||||
- Millorada l'aparició dels game_text.
|
||||
- Fix: la paleta dels jugadors no s'iniciava correctament.
|
||||
|
||||
---
|
||||
|
||||
## 2024-10-20
|
||||
|
||||
- **Classe Resource creada**: precàrrega de tots els recursos (textures, música, sons, animacions).
|
||||
- **Paletes de color** per a textures GIF amb shared_ptr.
|
||||
- Precàrrega i assignació de paletes.
|
||||
- Implementat comptador per a posar el nom al acabar la partida.
|
||||
- Classe Notifier independitzada de Screen amb codis identificadors.
|
||||
- Afegit codi per a apagar el sistema al eixir del joc.
|
||||
- Fix: globos verds tenien setters mal assignats i velocitat incorrecta.
|
||||
- Fix: no guardar el fitxer de puntuacions en el mode demo.
|
||||
|
||||
---
|
||||
|
||||
## 2024-10-14
|
||||
|
||||
- **Versió inicial**: clon del repositori de Coffee Crisis, adaptat per a Arcade Edition.
|
||||
- Pasaeta de include-what-you-use i cppcheck.
|
||||
- Estandarització de noms segons convencions (CamelCase, camelBack, snake_case).
|
||||
- Herències de les classes Sprite corregides.
|
||||
- Canvi a C++ modern amb smart pointers per a la càrrega de surfaces des de GIF.
|
||||
- Eliminats últims defines i passats a enum class.
|
||||
16
CLAUDE.md
16
CLAUDE.md
@@ -16,17 +16,15 @@ cmake -B build -DCMAKE_BUILD_TYPE=Debug # configure
|
||||
cmake --build build # build
|
||||
```
|
||||
|
||||
### Makefile (direct compilation, platform-specific targets)
|
||||
### Makefile (delegates to CMake)
|
||||
```bash
|
||||
make linux # build for Linux
|
||||
make linux_debug # debug build with -DDEBUG -DVERBOSE
|
||||
make # build Release via cmake
|
||||
make debug # build Debug via cmake
|
||||
make release # create release package (auto-detects OS)
|
||||
make linux_release # release tar.gz with resources.pack
|
||||
make windows # build for Windows (cross-compile or native)
|
||||
make windows_debug # Windows debug build
|
||||
make macos # build for macOS (arm64)
|
||||
make raspi # build for Raspberry Pi
|
||||
make anbernic # build for Anbernic (no shaders, arcade mode)
|
||||
make no_audio # build without audio system
|
||||
make windows_release # release zip for Windows
|
||||
make macos_release # release dmg for macOS (Intel + Apple Silicon)
|
||||
make raspi_release # release tar.gz for Raspberry Pi
|
||||
```
|
||||
|
||||
### Tools & Resources
|
||||
|
||||
@@ -81,6 +81,7 @@ set(APP_SOURCES
|
||||
# --- Sprites y Gráficos ---
|
||||
source/animated_sprite.cpp
|
||||
source/background.cpp
|
||||
source/card_sprite.cpp
|
||||
source/fade.cpp
|
||||
source/moving_sprite.cpp
|
||||
source/path_sprite.cpp
|
||||
@@ -203,7 +204,17 @@ if(WIN32)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ws2_32 mingw32)
|
||||
elseif(APPLE)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE MACOS_BUILD)
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64")
|
||||
if(NOT CMAKE_OSX_ARCHITECTURES)
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64")
|
||||
endif()
|
||||
if(MACOS_BUNDLE)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE MACOS_BUNDLE)
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
-framework SDL3
|
||||
-F ${CMAKE_SOURCE_DIR}/release/macos/frameworks/SDL3.xcframework/macos-arm64_x86_64
|
||||
-rpath @executable_path/../Frameworks/
|
||||
)
|
||||
endif()
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE LINUX_BUILD)
|
||||
endif()
|
||||
|
||||
415
Makefile
415
Makefile
@@ -1,233 +1,168 @@
|
||||
# Directorios
|
||||
# ==============================================================================
|
||||
# DIRECTORIES
|
||||
# ==============================================================================
|
||||
DIR_ROOT := $(dir $(abspath $(MAKEFILE_LIST)))
|
||||
DIR_SOURCES := $(addsuffix /, $(DIR_ROOT)source)
|
||||
DIR_BIN := $(addsuffix /, $(DIR_ROOT))
|
||||
DIR_BUILD := $(addsuffix /, $(DIR_ROOT)build)
|
||||
DIR_TOOLS := $(addsuffix /, $(DIR_ROOT)tools)
|
||||
|
||||
# Variables
|
||||
# ==============================================================================
|
||||
# TARGET NAMES
|
||||
# ==============================================================================
|
||||
TARGET_NAME := coffee_crisis_arcade_edition
|
||||
TARGET_FILE := $(DIR_BIN)$(TARGET_NAME)
|
||||
TARGET_FILE := $(DIR_ROOT)$(TARGET_NAME)
|
||||
APP_NAME := Coffee Crisis Arcade Edition
|
||||
DIST_DIR := dist
|
||||
RELEASE_FOLDER := dist/_tmp
|
||||
RELEASE_FILE := $(RELEASE_FOLDER)/$(TARGET_NAME)
|
||||
RESOURCE_FILE := release/windows/coffee.res
|
||||
|
||||
# Variables para herramienta de empaquetado
|
||||
ifeq ($(OS),Windows_NT)
|
||||
PACK_TOOL := $(DIR_TOOLS)pack_resources/pack_resources.exe
|
||||
PACK_CXX := $(CXX)
|
||||
else
|
||||
PACK_TOOL := $(DIR_TOOLS)pack_resources/pack_resources
|
||||
PACK_CXX := $(CXX)
|
||||
endif
|
||||
PACK_SOURCES := $(DIR_TOOLS)pack_resources/pack_resources.cpp $(DIR_SOURCES)resource_pack.cpp
|
||||
PACK_INCLUDES := -I$(DIR_ROOT) -I$(DIR_BUILD)
|
||||
# ==============================================================================
|
||||
# TOOLS
|
||||
# ==============================================================================
|
||||
DIR_PACK_TOOL := $(DIR_TOOLS)pack_resources
|
||||
SHADER_SCRIPT := $(DIR_ROOT)tools/shaders/compile_spirv.sh
|
||||
|
||||
# Versión automática basada en la fecha actual (específica por SO)
|
||||
# ==============================================================================
|
||||
# VERSION (fecha actual)
|
||||
# ==============================================================================
|
||||
ifeq ($(OS),Windows_NT)
|
||||
VERSION := $(shell powershell -Command "Get-Date -Format 'yyyy-MM-dd'")
|
||||
else
|
||||
VERSION := $(shell date +%Y-%m-%d)
|
||||
endif
|
||||
|
||||
# Variables específicas para Windows (usando APP_NAME)
|
||||
# ==============================================================================
|
||||
# SHELL (Windows usa cmd.exe)
|
||||
# ==============================================================================
|
||||
ifeq ($(OS),Windows_NT)
|
||||
WIN_TARGET_FILE := $(DIR_BIN)$(APP_NAME)
|
||||
SHELL := cmd.exe
|
||||
endif
|
||||
|
||||
# ==============================================================================
|
||||
# WINDOWS-SPECIFIC VARIABLES
|
||||
# ==============================================================================
|
||||
ifeq ($(OS),Windows_NT)
|
||||
WIN_TARGET_FILE := $(DIR_ROOT)$(APP_NAME)
|
||||
WIN_RELEASE_FILE := $(RELEASE_FOLDER)/$(APP_NAME)
|
||||
else
|
||||
WIN_TARGET_FILE := $(TARGET_FILE)
|
||||
WIN_RELEASE_FILE := $(RELEASE_FILE)
|
||||
endif
|
||||
|
||||
# Nombres para los ficheros de lanzamiento
|
||||
# ==============================================================================
|
||||
# RELEASE NAMES
|
||||
# ==============================================================================
|
||||
WINDOWS_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-win32-x64.zip
|
||||
MACOS_INTEL_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-macos-intel.dmg
|
||||
MACOS_APPLE_SILICON_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-macos-apple-silicon.dmg
|
||||
LINUX_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-linux.tar.gz
|
||||
RASPI_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-raspberry.tar.gz
|
||||
|
||||
# Lista completa de archivos fuente (basada en CMakeLists.txt)
|
||||
APP_SOURCES := \
|
||||
source/asset.cpp \
|
||||
source/audio.cpp \
|
||||
source/director.cpp \
|
||||
source/global_events.cpp \
|
||||
source/global_inputs.cpp \
|
||||
source/input.cpp \
|
||||
source/lang.cpp \
|
||||
source/main.cpp \
|
||||
source/param.cpp \
|
||||
source/resource.cpp \
|
||||
source/resource_helper.cpp \
|
||||
source/resource_loader.cpp \
|
||||
source/resource_pack.cpp \
|
||||
source/screen.cpp \
|
||||
source/text.cpp \
|
||||
source/writer.cpp \
|
||||
source/ui/menu_option.cpp \
|
||||
source/ui/menu_renderer.cpp \
|
||||
source/ui/notifier.cpp \
|
||||
source/ui/service_menu.cpp \
|
||||
source/ui/ui_message.cpp \
|
||||
source/ui/window_message.cpp \
|
||||
source/balloon_formations.cpp \
|
||||
source/balloon_manager.cpp \
|
||||
source/balloon.cpp \
|
||||
source/bullet.cpp \
|
||||
source/bullet_manager.cpp \
|
||||
source/enter_name.cpp \
|
||||
source/explosions.cpp \
|
||||
source/game_logo.cpp \
|
||||
source/item.cpp \
|
||||
source/manage_hiscore_table.cpp \
|
||||
source/player.cpp \
|
||||
source/scoreboard.cpp \
|
||||
source/tabe.cpp \
|
||||
source/sections/credits.cpp \
|
||||
source/sections/game.cpp \
|
||||
source/sections/hiscore_table.cpp \
|
||||
source/sections/instructions.cpp \
|
||||
source/sections/intro.cpp \
|
||||
source/sections/logo.cpp \
|
||||
source/sections/title.cpp \
|
||||
source/animated_sprite.cpp \
|
||||
source/background.cpp \
|
||||
source/fade.cpp \
|
||||
source/moving_sprite.cpp \
|
||||
source/path_sprite.cpp \
|
||||
source/smart_sprite.cpp \
|
||||
source/sprite.cpp \
|
||||
source/texture.cpp \
|
||||
source/tiled_bg.cpp \
|
||||
source/color.cpp \
|
||||
source/demo.cpp \
|
||||
source/define_buttons.cpp \
|
||||
source/difficulty.cpp \
|
||||
source/input_types.cpp \
|
||||
source/mouse.cpp \
|
||||
source/options.cpp \
|
||||
source/shutdown.cpp \
|
||||
source/stage.cpp \
|
||||
source/system_utils.cpp \
|
||||
source/utils.cpp \
|
||||
source/external/jail_audio.cpp \
|
||||
source/external/gif.cpp \
|
||||
source/rendering/sdl3gpu/sdl3gpu_shader.cpp
|
||||
|
||||
# Includes
|
||||
INCLUDES := -Isource -Isource/external -Isource/rendering -Isource/rendering/sdl3gpu -I$(DIR_BUILD)
|
||||
|
||||
# Variables según el sistema operativo
|
||||
# ==============================================================================
|
||||
# PLATAFORMA
|
||||
# ==============================================================================
|
||||
ifeq ($(OS),Windows_NT)
|
||||
FixPath = $(subst /,\\,$1)
|
||||
CXXFLAGS := -std=c++20 -Wall -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -static-libgcc -Wl,-Bstatic -lpthread -Wl,-Bdynamic -Wl,-subsystem,windows -DWINDOWS_BUILD
|
||||
CXXFLAGS_DEBUG := -std=c++20 -Wall -g -D_DEBUG -DWINDOWS_BUILD
|
||||
LDFLAGS := -lmingw32 -lws2_32 -lSDL3
|
||||
RM := del /Q
|
||||
MKDIR := mkdir
|
||||
else
|
||||
FixPath = $1
|
||||
CXXFLAGS := -std=c++20 -Wall -Os -ffunction-sections -fdata-sections
|
||||
CXXFLAGS_DEBUG := -std=c++20 -Wall -g -D_DEBUG
|
||||
LDFLAGS := -lSDL3
|
||||
RMFILE := rm -f
|
||||
RMDIR := rm -rdf
|
||||
MKDIR := mkdir -p
|
||||
UNAME_S := $(shell uname -s)
|
||||
ifeq ($(UNAME_S),Linux)
|
||||
CXXFLAGS += -DLINUX_BUILD
|
||||
endif
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
CXXFLAGS += -DMACOS_BUILD
|
||||
CXXFLAGS_DEBUG += -DMACOS_BUILD
|
||||
# Configurar arquitectura (por defecto arm64, como en CMake)
|
||||
CXXFLAGS += -arch arm64
|
||||
CXXFLAGS_DEBUG += -arch arm64
|
||||
endif
|
||||
endif
|
||||
|
||||
# Reglas para herramienta de empaquetado y resources.pack
|
||||
$(PACK_TOOL): FORCE
|
||||
@echo "Compilando herramienta de empaquetado..."
|
||||
$(PACK_CXX) -std=c++20 -Wall -Os $(PACK_INCLUDES) $(PACK_SOURCES) -o $(PACK_TOOL)
|
||||
@echo "✓ Herramienta de empaquetado lista: $(PACK_TOOL)"
|
||||
# ==============================================================================
|
||||
# COMPILACIÓN CON CMAKE
|
||||
# ==============================================================================
|
||||
all:
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build
|
||||
|
||||
pack_tool: $(PACK_TOOL)
|
||||
debug:
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
|
||||
@cmake --build build
|
||||
|
||||
resources.pack: $(PACK_TOOL)
|
||||
@echo "Generando resources.pack desde directorio data/..."
|
||||
$(PACK_TOOL) data resources.pack
|
||||
@echo "✓ resources.pack generado exitosamente"
|
||||
# ==============================================================================
|
||||
# RELEASE AUTOMÁTICO (detecta SO)
|
||||
# ==============================================================================
|
||||
release:
|
||||
ifeq ($(OS),Windows_NT)
|
||||
@"$(MAKE)" windows_release
|
||||
else
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
@$(MAKE) macos_release
|
||||
else
|
||||
@$(MAKE) linux_release
|
||||
endif
|
||||
endif
|
||||
|
||||
# Reglas para compilación
|
||||
windows:
|
||||
@echo off
|
||||
@echo Compilando para Windows con nombre: "$(APP_NAME).exe"
|
||||
windres release/windows/coffee.rc -O coff -o $(RESOURCE_FILE)
|
||||
$(CXX) $(APP_SOURCES) $(RESOURCE_FILE) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(WIN_TARGET_FILE).exe"
|
||||
strip -s -R .comment -R .gnu.version "$(WIN_TARGET_FILE).exe" --strip-unneeded
|
||||
# ==============================================================================
|
||||
# REGLAS PARA HERRAMIENTA DE EMPAQUETADO Y RESOURCES.PACK
|
||||
# ==============================================================================
|
||||
pack_tool:
|
||||
@$(MAKE) -C $(DIR_PACK_TOOL)
|
||||
|
||||
windows_rec:
|
||||
@echo off
|
||||
@echo Compilando version de grabacion para Windows: "$(APP_NAME)_rec.exe"
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DRECORDING $(CXXFLAGS) $(LDFLAGS) -o "$(WIN_TARGET_FILE)_rec.exe"
|
||||
resources.pack:
|
||||
@$(MAKE) -C $(DIR_PACK_TOOL) pack
|
||||
|
||||
windows_debug:
|
||||
@echo off
|
||||
@echo Compilando version debug para Windows: "$(APP_NAME)_debug.exe"
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DDEBUG -DVERBOSE $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(WIN_TARGET_FILE)_debug.exe"
|
||||
# ==============================================================================
|
||||
# COMPILACIÓN DE SHADERS
|
||||
# ==============================================================================
|
||||
spirv:
|
||||
@echo "Compilando shaders SPIR-V..."
|
||||
$(SHADER_SCRIPT)
|
||||
|
||||
# ==============================================================================
|
||||
# COMPILACIÓN PARA WINDOWS (RELEASE)
|
||||
# ==============================================================================
|
||||
windows_release:
|
||||
@$(MAKE) pack_tool
|
||||
@$(MAKE) resources.pack
|
||||
@echo off
|
||||
@echo Creando release para Windows - Version: $(VERSION)
|
||||
|
||||
# Compila con cmake
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build
|
||||
|
||||
# Crea carpeta de distribución y carpeta temporal 'RELEASE_FOLDER'
|
||||
powershell if (-not (Test-Path "$(DIST_DIR)")) {New-Item "$(DIST_DIR)" -ItemType Directory}
|
||||
powershell if (Test-Path "$(RELEASE_FOLDER)") {Remove-Item "$(RELEASE_FOLDER)" -Recurse -Force}
|
||||
powershell if (-not (Test-Path "$(RELEASE_FOLDER)")) {New-Item "$(RELEASE_FOLDER)" -ItemType Directory}
|
||||
@powershell -Command "if (-not (Test-Path '$(DIST_DIR)')) {New-Item '$(DIST_DIR)' -ItemType Directory}"
|
||||
@powershell -Command "if (Test-Path '$(RELEASE_FOLDER)') {Remove-Item '$(RELEASE_FOLDER)' -Recurse -Force}"
|
||||
@powershell -Command "if (-not (Test-Path '$(RELEASE_FOLDER)')) {New-Item '$(RELEASE_FOLDER)' -ItemType Directory}"
|
||||
|
||||
# Copia la carpeta 'config' y el archivo 'resources.pack'
|
||||
powershell Copy-Item -Path "config" -Destination "$(RELEASE_FOLDER)" -recurse -Force
|
||||
powershell Copy-Item -Path "resources.pack" -Destination "$(RELEASE_FOLDER)"
|
||||
@powershell -Command "Copy-Item -Path 'config' -Destination '$(RELEASE_FOLDER)' -recurse -Force"
|
||||
@powershell -Command "Copy-Item -Path 'resources.pack' -Destination '$(RELEASE_FOLDER)'"
|
||||
|
||||
# Copia los ficheros que estan en la raíz del proyecto
|
||||
powershell Copy-Item "LICENSE" -Destination "$(RELEASE_FOLDER)"
|
||||
powershell Copy-Item "README.md" -Destination "$(RELEASE_FOLDER)"
|
||||
powershell Copy-Item "release\windows\dll\*.dll" -Destination "$(RELEASE_FOLDER)"
|
||||
|
||||
# Compila
|
||||
windres release/windows/coffee.rc -O coff -o $(RESOURCE_FILE)
|
||||
$(CXX) $(APP_SOURCES) $(RESOURCE_FILE) $(INCLUDES) -DRELEASE_BUILD $(CXXFLAGS) $(LDFLAGS) -o "$(WIN_RELEASE_FILE).exe"
|
||||
@powershell -Command "Copy-Item 'LICENSE' -Destination '$(RELEASE_FOLDER)'"
|
||||
@powershell -Command "Copy-Item 'README.md' -Destination '$(RELEASE_FOLDER)'"
|
||||
@powershell -Command "Copy-Item 'release\windows\dll\*.dll' -Destination '$(RELEASE_FOLDER)'"
|
||||
@powershell -Command "Copy-Item -Path '$(TARGET_FILE)' -Destination '\"$(WIN_RELEASE_FILE).exe\"'"
|
||||
strip -s -R .comment -R .gnu.version "$(WIN_RELEASE_FILE).exe" --strip-unneeded
|
||||
|
||||
# Crea el fichero .zip
|
||||
powershell if (Test-Path "$(WINDOWS_RELEASE)") {Remove-Item "$(WINDOWS_RELEASE)"}
|
||||
powershell Compress-Archive -Path "$(RELEASE_FOLDER)"/* -DestinationPath "$(WINDOWS_RELEASE)"
|
||||
@powershell -Command "if (Test-Path '$(WINDOWS_RELEASE)') {Remove-Item '$(WINDOWS_RELEASE)'}"
|
||||
@powershell -Command "Compress-Archive -Path '$(RELEASE_FOLDER)/*' -DestinationPath '$(WINDOWS_RELEASE)'"
|
||||
@echo Release creado: $(WINDOWS_RELEASE)
|
||||
|
||||
# Elimina la carpeta temporal 'RELEASE_FOLDER'
|
||||
powershell if (Test-Path "$(RELEASE_FOLDER)") {Remove-Item "$(RELEASE_FOLDER)" -Recurse -Force}
|
||||
|
||||
macos:
|
||||
@echo "Compilando para macOS: $(TARGET_NAME)"
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE)"
|
||||
|
||||
macos_debug:
|
||||
@echo "Compilando version debug para macOS: $(TARGET_NAME)_debug"
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DDEBUG -DVERBOSE $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
||||
@powershell -Command "if (Test-Path '$(RELEASE_FOLDER)') {Remove-Item '$(RELEASE_FOLDER)' -Recurse -Force}"
|
||||
|
||||
# ==============================================================================
|
||||
# COMPILACIÓN PARA MACOS (RELEASE)
|
||||
# ==============================================================================
|
||||
macos_release:
|
||||
@$(MAKE) pack_tool
|
||||
@$(MAKE) resources.pack
|
||||
@echo "Creando release para macOS - Version: $(VERSION)"
|
||||
|
||||
# Verificar e instalar create-dmg si es necesario
|
||||
@which create-dmg > /dev/null || (echo "Instalando create-dmg..." && brew install create-dmg)
|
||||
|
||||
# Compila la versión para procesadores Intel con cmake
|
||||
@cmake -S . -B build/intel -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DMACOS_BUNDLE=ON
|
||||
@cmake --build build/intel
|
||||
|
||||
# Elimina datos de compilaciones anteriores
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
$(RMFILE) tmp.dmg
|
||||
@@ -250,9 +185,8 @@ macos_release:
|
||||
cp LICENSE "$(RELEASE_FOLDER)"
|
||||
cp README.md "$(RELEASE_FOLDER)"
|
||||
|
||||
# Compila la versión para procesadores Intel
|
||||
ifdef ENABLE_MACOS_X86_64
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DMACOS_BUNDLE -DMACOS_BUILD -DRELEASE_BUILD -std=c++20 -Wall -Os -Wno-deprecated -framework SDL3 -F release/macos/frameworks/SDL3.xcframework/macos-arm64_x86_64 -ffunction-sections -fdata-sections -o "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)" -rpath @executable_path/../Frameworks/ -target x86_64-apple-macos10.15
|
||||
# Copia el ejecutable Intel al bundle
|
||||
cp "$(TARGET_FILE)" "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)"
|
||||
|
||||
# Firma la aplicación
|
||||
codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app"
|
||||
@@ -273,10 +207,11 @@ ifdef ENABLE_MACOS_X86_64
|
||||
"$(MACOS_INTEL_RELEASE)" \
|
||||
"$(RELEASE_FOLDER)" || true
|
||||
@echo "Release Intel creado: $(MACOS_INTEL_RELEASE)"
|
||||
endif
|
||||
|
||||
# Compila la versión para procesadores Apple Silicon
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DMACOS_BUNDLE -DMACOS_BUILD -DRELEASE_BUILD -DSDL_DISABLE_IMMINTRIN_H -std=c++20 -Wall -Os -Wno-deprecated -framework SDL3 -F release/macos/frameworks/SDL3.xcframework/macos-arm64_x86_64 -ffunction-sections -fdata-sections -o "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)" -rpath @executable_path/../Frameworks/ -target arm64-apple-macos11
|
||||
# Compila la versión para procesadores Apple Silicon con cmake
|
||||
@cmake -S . -B build/arm -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 -DMACOS_BUNDLE=ON
|
||||
@cmake --build build/arm
|
||||
cp "$(TARGET_FILE)" "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)"
|
||||
|
||||
# Firma la aplicación
|
||||
codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app"
|
||||
@@ -300,22 +235,22 @@ endif
|
||||
|
||||
# Elimina las carpetas temporales
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
$(RMDIR) build/intel
|
||||
$(RMDIR) build/arm
|
||||
$(RMFILE) "$(DIST_DIR)"/rw.*
|
||||
|
||||
linux:
|
||||
@echo "Compilando para Linux: $(TARGET_NAME)"
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE)"
|
||||
strip -s -R .comment -R .gnu.version "$(TARGET_FILE)" --strip-unneeded
|
||||
|
||||
linux_debug:
|
||||
@echo "Compilando version debug para Linux: $(TARGET_NAME)_debug"
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DDEBUG -DVERBOSE $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
||||
|
||||
# ==============================================================================
|
||||
# COMPILACIÓN PARA LINUX (RELEASE)
|
||||
# ==============================================================================
|
||||
linux_release:
|
||||
@$(MAKE) pack_tool
|
||||
@$(MAKE) resources.pack
|
||||
@echo "Creando release para Linux - Version: $(VERSION)"
|
||||
# Elimina carpetas previas y recrea (crea dist/ si no existe)
|
||||
|
||||
# Compila con cmake
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build
|
||||
|
||||
# Elimina carpeta temporal previa y la recrea (crea dist/ si no existe)
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
$(MKDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
@@ -324,9 +259,7 @@ linux_release:
|
||||
cp resources.pack "$(RELEASE_FOLDER)"
|
||||
cp LICENSE "$(RELEASE_FOLDER)"
|
||||
cp README.md "$(RELEASE_FOLDER)"
|
||||
|
||||
# Compila
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DRELEASE_BUILD $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FILE)"
|
||||
cp "$(TARGET_FILE)" "$(RELEASE_FILE)"
|
||||
strip -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded
|
||||
|
||||
# Empaqueta ficheros
|
||||
@@ -337,10 +270,17 @@ linux_release:
|
||||
# Elimina la carpeta temporal
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
# ==============================================================================
|
||||
# COMPILACIÓN PARA LINUX (RELEASE CON INTEGRACIÓN DESKTOP)
|
||||
# ==============================================================================
|
||||
linux_release_desktop:
|
||||
@$(MAKE) pack_tool
|
||||
@$(MAKE) resources.pack
|
||||
@echo "Creando release con integracion desktop para Linux - Version: $(VERSION)"
|
||||
|
||||
# Compila con cmake
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build
|
||||
|
||||
# Elimina carpetas previas y recrea (crea dist/ si no existe)
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
@@ -357,8 +297,8 @@ linux_release_desktop:
|
||||
cp LICENSE "$(RELEASE_FOLDER)/$(TARGET_NAME)/"
|
||||
cp README.md "$(RELEASE_FOLDER)/$(TARGET_NAME)/"
|
||||
|
||||
# Compila el ejecutable
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DRELEASE_BUILD $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FOLDER)/$(TARGET_NAME)/bin/$(TARGET_NAME)"
|
||||
# Copia el ejecutable
|
||||
cp "$(TARGET_FILE)" "$(RELEASE_FOLDER)/$(TARGET_NAME)/bin/$(TARGET_NAME)"
|
||||
strip -s -R .comment -R .gnu.version "$(RELEASE_FOLDER)/$(TARGET_NAME)/bin/$(TARGET_NAME)" --strip-unneeded
|
||||
|
||||
# Crea el archivo .desktop
|
||||
@@ -432,19 +372,17 @@ linux_release_desktop:
|
||||
# Elimina la carpeta temporal
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
raspi:
|
||||
@echo "Compilando para Raspberry Pi: $(TARGET_NAME)"
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DVERBOSE $(CXXFLAGS) $(LDFLAGS) -o $(TARGET_FILE)
|
||||
strip -s -R .comment -R .gnu.version $(TARGET_FILE) --strip-unneeded
|
||||
|
||||
raspi_debug:
|
||||
@echo "Compilando version debug para Raspberry Pi: $(TARGET_NAME)_debug"
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DVERBOSE -DDEBUG $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
||||
|
||||
# ==============================================================================
|
||||
# COMPILACIÓN PARA RASPBERRY PI (RELEASE)
|
||||
# ==============================================================================
|
||||
raspi_release:
|
||||
@$(MAKE) pack_tool
|
||||
@$(MAKE) resources.pack
|
||||
@echo "Creando release para Raspberry Pi - Version: $(VERSION)"
|
||||
|
||||
# Compila con cmake
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build
|
||||
|
||||
# Elimina carpetas previas y recrea (crea dist/ si no existe)
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
$(MKDIR) "$(RELEASE_FOLDER)"
|
||||
@@ -454,9 +392,7 @@ raspi_release:
|
||||
cp resources.pack "$(RELEASE_FOLDER)"
|
||||
cp LICENSE "$(RELEASE_FOLDER)"
|
||||
cp README.md "$(RELEASE_FOLDER)"
|
||||
|
||||
# Compila
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DRELEASE_BUILD -DVERBOSE $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FILE)"
|
||||
cp "$(TARGET_FILE)" "$(RELEASE_FILE)"
|
||||
strip -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded
|
||||
|
||||
# Empaqueta ficheros
|
||||
@@ -467,59 +403,60 @@ raspi_release:
|
||||
# Elimina la carpeta temporal
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
anbernic:
|
||||
@$(MAKE) pack_tool
|
||||
@$(MAKE) resources.pack
|
||||
@echo "Compilando para Anbernic: $(TARGET_NAME)"
|
||||
# Elimina carpetas previas
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"_anbernic
|
||||
# ==============================================================================
|
||||
# CODE QUALITY (delegados a cmake)
|
||||
# ==============================================================================
|
||||
format:
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build --target format
|
||||
|
||||
# Crea la carpeta temporal para realizar el lanzamiento
|
||||
$(MKDIR) "$(RELEASE_FOLDER)"_anbernic
|
||||
format-check:
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build --target format-check
|
||||
|
||||
# Copia ficheros
|
||||
cp -R config "$(RELEASE_FOLDER)"_anbernic
|
||||
cp resources.pack "$(RELEASE_FOLDER)"_anbernic
|
||||
tidy:
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build --target tidy
|
||||
|
||||
# Compila
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DRELEASE_BUILD -DANBERNIC -DNO_SHADERS -DARCADE -DVERBOSE $(CXXFLAGS) $(LDFLAGS) -o $(RELEASE_FOLDER)_anbernic/$(TARGET_NAME)
|
||||
tidy-fix:
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build --target tidy-fix
|
||||
|
||||
# Opción para deshabilitar audio (equivalente a la opción DISABLE_AUDIO de CMake)
|
||||
no_audio:
|
||||
@echo "Compilando sin audio: $(TARGET_NAME)_no_audio"
|
||||
$(CXX) $(filter-out source/external/jail_audio.cpp,$(APP_SOURCES)) $(INCLUDES) -DNO_AUDIO $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE)_no_audio"
|
||||
|
||||
# Regla para mostrar la versión actual
|
||||
# ==============================================================================
|
||||
# REGLAS ESPECIALES
|
||||
# ==============================================================================
|
||||
show_version:
|
||||
@echo "Version actual: $(VERSION)"
|
||||
|
||||
# Regla de ayuda
|
||||
help:
|
||||
@echo "Makefile para Coffee Crisis Arcade Edition"
|
||||
@echo "Comandos disponibles:"
|
||||
@echo " windows - Compilar para Windows"
|
||||
@echo " windows_debug - Compilar debug para Windows"
|
||||
@echo " windows_release - Crear release completo para Windows"
|
||||
@echo " linux - Compilar para Linux"
|
||||
@echo " linux_debug - Compilar debug para Linux"
|
||||
@echo " linux_release - Crear release basico para Linux"
|
||||
@echo " linux_release_desktop - Crear release con integracion desktop para Linux"
|
||||
@echo " macos - Compilar para macOS"
|
||||
@echo " macos_debug - Compilar debug para macOS"
|
||||
@echo " macos_release - Crear release completo para macOS"
|
||||
@echo " raspi - Compilar para Raspberry Pi"
|
||||
@echo " raspi_release - Crear release completo para Raspberry Pi"
|
||||
@echo " anbernic - Compilar para Anbernic"
|
||||
@echo " no_audio - Compilar sin sistema de audio"
|
||||
@echo " pack_tool - Compilar herramienta de empaquetado"
|
||||
@echo " resources.pack - Generar pack de recursos desde data/"
|
||||
@echo " show_version - Mostrar version actual ($(VERSION))"
|
||||
@echo " help - Mostrar esta ayuda"
|
||||
@echo ""
|
||||
@echo " Compilacion:"
|
||||
@echo " make - Compilar con cmake (Release)"
|
||||
@echo " make debug - Compilar con cmake (Debug)"
|
||||
@echo ""
|
||||
@echo " Release:"
|
||||
@echo " make release - Crear release (detecta SO automaticamente)"
|
||||
@echo " make windows_release - Crear release para Windows"
|
||||
@echo " make linux_release - Crear release basico para Linux"
|
||||
@echo " make linux_release_desktop - Crear release con integracion desktop para Linux"
|
||||
@echo " make macos_release - Crear release para macOS"
|
||||
@echo " make raspi_release - Crear release para Raspberry Pi"
|
||||
@echo ""
|
||||
@echo " Herramientas:"
|
||||
@echo " make spirv - Compilar shaders SPIR-V"
|
||||
@echo " make pack_tool - Compilar herramienta de empaquetado"
|
||||
@echo " make resources.pack - Generar pack de recursos desde data/"
|
||||
@echo ""
|
||||
@echo " Calidad de codigo:"
|
||||
@echo " make format - Formatear codigo con clang-format"
|
||||
@echo " make format-check - Verificar formato sin modificar"
|
||||
@echo " make tidy - Analisis estatico con clang-tidy"
|
||||
@echo " make tidy-fix - Analisis estatico con auto-fix"
|
||||
@echo ""
|
||||
@echo " Otros:"
|
||||
@echo " make show_version - Mostrar version actual ($(VERSION))"
|
||||
@echo " make help - Mostrar esta ayuda"
|
||||
|
||||
spirv:
|
||||
@echo "Compilando shaders SPIR-V..."
|
||||
tools/shaders/compile_spirv.sh
|
||||
|
||||
.PHONY: windows windows_rec windows_debug windows_release macos macos_debug macos_release linux linux_debug linux_release linux_release_desktop raspi raspi_debug raspi_release anbernic no_audio show_version help pack_tool resources.pack spirv
|
||||
|
||||
FORCE:
|
||||
.PHONY: all debug release windows_release macos_release linux_release linux_release_desktop raspi_release pack_tool resources.pack spirv format format-check tidy tidy-fix show_version help
|
||||
|
||||
@@ -90,7 +90,7 @@ service_menu.window_message.text_safety_margin 15.0f # Margen de segu
|
||||
service_menu.window_message.animation_duration 0.3f # Duración de animaciones de ventanas (segundos)
|
||||
|
||||
# --- INTRO ---
|
||||
intro.bg_color 4664BD # Color de fondo de la intro
|
||||
intro.bg_color 41526F # Color de fondo de la intro
|
||||
intro.card_color CBDBFC # Color de las tarjetas en la intro
|
||||
intro.shadow_color 00000080 # Color de la sombra de las tarjetas en la intro
|
||||
intro.text_distance_from_bottom 48 # Posicion del texto
|
||||
|
||||
@@ -90,7 +90,7 @@ service_menu.window_message.text_safety_margin 15.0f # Margen de segu
|
||||
service_menu.window_message.animation_duration 0.3f # Duración de animaciones de ventanas (segundos)
|
||||
|
||||
# --- INTRO ---
|
||||
intro.bg_color 4664BD # Color de fondo de la intro
|
||||
intro.bg_color 41526F # Color de fondo de la intro
|
||||
intro.card_color CBDBFC # Color de las tarjetas en la intro
|
||||
intro.shadow_color 00000080 # Color de la sombra de las tarjetas en la intro
|
||||
intro.text_distance_from_bottom 48 # Posición del texto desde la parte inferior
|
||||
|
||||
255
source/card_sprite.cpp
Normal file
255
source/card_sprite.cpp
Normal file
@@ -0,0 +1,255 @@
|
||||
#include "card_sprite.hpp"
|
||||
|
||||
#include <algorithm> // Para std::clamp
|
||||
#include <functional> // Para function
|
||||
#include <utility> // Para move
|
||||
|
||||
#include "texture.hpp" // Para Texture
|
||||
#include "utils.hpp" // Para easeOutBounce, easeOutCubic
|
||||
|
||||
// Constructor
|
||||
CardSprite::CardSprite(std::shared_ptr<Texture> texture)
|
||||
: MovingSprite(std::move(texture)),
|
||||
entry_easing_(easeOutBounce) {}
|
||||
|
||||
// Inicia la animación de entrada (solo si está en IDLE)
|
||||
auto CardSprite::enable() -> bool {
|
||||
if (state_ != CardState::IDLE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
state_ = CardState::ENTERING;
|
||||
entry_elapsed_ = 0.0F;
|
||||
first_touch_ = false;
|
||||
|
||||
// Posición inicial (borde de pantalla)
|
||||
setPos(entry_start_x_, entry_start_y_);
|
||||
|
||||
// Zoom inicial grande (como si estuviera cerca de la cámara)
|
||||
horizontal_zoom_ = start_zoom_;
|
||||
vertical_zoom_ = start_zoom_;
|
||||
|
||||
// Ángulo inicial
|
||||
rotate_.angle = start_angle_;
|
||||
rotate_.center = {pos_.w / 2.0F, pos_.h / 2.0F};
|
||||
|
||||
shadow_visible_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Inicia la animación de salida (solo si está en LANDED)
|
||||
void CardSprite::startExit() {
|
||||
if (state_ != CardState::LANDED) {
|
||||
return;
|
||||
}
|
||||
|
||||
state_ = CardState::EXITING;
|
||||
shadow_visible_ = true;
|
||||
|
||||
// Velocidad y aceleración de salida
|
||||
vx_ = exit_vx_;
|
||||
vy_ = exit_vy_;
|
||||
ax_ = exit_ax_;
|
||||
ay_ = exit_ay_;
|
||||
|
||||
// Rotación continua
|
||||
rotate_.enabled = true;
|
||||
rotate_.amount = exit_rotate_amount_;
|
||||
rotate_.center = {pos_.w / 2.0F, pos_.h / 2.0F};
|
||||
}
|
||||
|
||||
// Actualiza según el estado
|
||||
void CardSprite::update(float delta_time) {
|
||||
switch (state_) {
|
||||
case CardState::ENTERING:
|
||||
updateEntering(delta_time);
|
||||
break;
|
||||
case CardState::EXITING:
|
||||
updateExiting(delta_time);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Animación de entrada: interpola posición, zoom y ángulo
|
||||
void CardSprite::updateEntering(float delta_time) {
|
||||
entry_elapsed_ += delta_time;
|
||||
|
||||
float progress = std::clamp(entry_elapsed_ / entry_duration_s_, 0.0F, 1.0F);
|
||||
double eased = entry_easing_(static_cast<double>(progress));
|
||||
|
||||
// Zoom: de start_zoom_ a 1.0 con rebote
|
||||
auto current_zoom = static_cast<float>(start_zoom_ + (1.0 - start_zoom_) * eased);
|
||||
horizontal_zoom_ = current_zoom;
|
||||
vertical_zoom_ = current_zoom;
|
||||
|
||||
// Ángulo: de start_angle_ a 0 con rebote
|
||||
rotate_.angle = start_angle_ * (1.0 - eased);
|
||||
|
||||
// Posición: de entry_start a landing con easing suave (sin rebote)
|
||||
// Usamos easeOutCubic para que el desplazamiento sea fluido
|
||||
double pos_eased = easeOutCubic(static_cast<double>(progress));
|
||||
auto current_x = static_cast<float>(entry_start_x_ + (landing_x_ - entry_start_x_) * pos_eased);
|
||||
auto current_y = static_cast<float>(entry_start_y_ + (landing_y_ - entry_start_y_) * pos_eased);
|
||||
setPos(current_x, current_y);
|
||||
|
||||
// Detecta el primer toque (cuando el easing alcanza ~1.0 por primera vez)
|
||||
if (!first_touch_ && eased >= FIRST_TOUCH_THRESHOLD) {
|
||||
first_touch_ = true;
|
||||
}
|
||||
|
||||
// Transición a LANDED cuando termina la animación completa
|
||||
if (progress >= 1.0F) {
|
||||
horizontal_zoom_ = 1.0F;
|
||||
vertical_zoom_ = 1.0F;
|
||||
rotate_.angle = 0.0;
|
||||
setPos(landing_x_, landing_y_);
|
||||
state_ = CardState::LANDED;
|
||||
first_touch_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Animación de salida: movimiento + rotación continua + zoom opcional
|
||||
void CardSprite::updateExiting(float delta_time) {
|
||||
move(delta_time);
|
||||
rotate(delta_time);
|
||||
|
||||
// Ganar altura gradualmente (zoom hacia el objetivo)
|
||||
if (exit_zoom_speed_ > 0.0F && horizontal_zoom_ < exit_target_zoom_) {
|
||||
float new_zoom = horizontal_zoom_ + exit_zoom_speed_ * delta_time;
|
||||
if (new_zoom > exit_target_zoom_) {
|
||||
new_zoom = exit_target_zoom_;
|
||||
}
|
||||
horizontal_zoom_ = new_zoom;
|
||||
vertical_zoom_ = new_zoom;
|
||||
}
|
||||
|
||||
if (isOffScreen()) {
|
||||
state_ = CardState::FINISHED;
|
||||
}
|
||||
}
|
||||
|
||||
// Renderiza el sprite y su sombra
|
||||
void CardSprite::render() {
|
||||
if (state_ == CardState::IDLE || state_ == CardState::FINISHED) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Sombra primero (debajo de la tarjeta)
|
||||
if (shadow_visible_ && shadow_texture_) {
|
||||
renderShadow();
|
||||
}
|
||||
|
||||
// Tarjeta
|
||||
MovingSprite::render();
|
||||
}
|
||||
|
||||
// Renderiza la sombra con efecto de perspectiva 2D→3D (efecto helicóptero)
|
||||
//
|
||||
// Fuente de luz en la esquina superior izquierda (0,0).
|
||||
// La sombra se mueve con la tarjeta pero desplazada en dirección opuesta a la luz
|
||||
// (abajo-derecha a 45°). Cuanto más alta la tarjeta (zoom > 1.0):
|
||||
// - Más separada de la tarjeta (offset grande)
|
||||
// - Más pequeña (proyección lejana)
|
||||
// Cuando la tarjeta está en la mesa (zoom=1.0):
|
||||
// - Sombra pegada con offset base
|
||||
// - Tamaño real
|
||||
void CardSprite::renderShadow() {
|
||||
// Altura sobre la mesa: 0.0 = en la mesa, 0.8 = alta (zoom 1.8)
|
||||
float height = horizontal_zoom_ - 1.0F;
|
||||
|
||||
// Escala: más pequeña cuanto más alta
|
||||
float shadow_zoom = 1.0F / horizontal_zoom_;
|
||||
|
||||
// Offset respecto a la tarjeta: base + extra proporcional a la altura
|
||||
// La sombra se aleja en diagonal abajo-derecha (opuesta a la luz en 0,0)
|
||||
float offset_x = shadow_offset_x_ + height * SHADOW_HEIGHT_MULTIPLIER;
|
||||
float offset_y = shadow_offset_y_ + height * SHADOW_HEIGHT_MULTIPLIER;
|
||||
|
||||
shadow_texture_->render(
|
||||
pos_.x + offset_x,
|
||||
pos_.y + offset_y,
|
||||
&sprite_clip_,
|
||||
shadow_zoom,
|
||||
shadow_zoom,
|
||||
rotate_.angle,
|
||||
&rotate_.center,
|
||||
flip_);
|
||||
}
|
||||
|
||||
// Comprueba si el sprite está fuera de pantalla
|
||||
auto CardSprite::isOffScreen() const -> bool {
|
||||
float effective_width = pos_.w * horizontal_zoom_;
|
||||
float effective_height = pos_.h * vertical_zoom_;
|
||||
return (pos_.x + effective_width < -OFF_SCREEN_MARGIN ||
|
||||
pos_.x > screen_width_ + OFF_SCREEN_MARGIN ||
|
||||
pos_.y + effective_height < -OFF_SCREEN_MARGIN ||
|
||||
pos_.y > screen_height_ + OFF_SCREEN_MARGIN);
|
||||
}
|
||||
|
||||
// --- Consultas de estado ---
|
||||
auto CardSprite::hasLanded() const -> bool {
|
||||
return state_ == CardState::LANDED || state_ == CardState::EXITING || state_ == CardState::FINISHED;
|
||||
}
|
||||
|
||||
auto CardSprite::hasFirstTouch() const -> bool {
|
||||
return first_touch_;
|
||||
}
|
||||
|
||||
auto CardSprite::hasFinished() const -> bool {
|
||||
return state_ == CardState::FINISHED;
|
||||
}
|
||||
|
||||
auto CardSprite::isExiting() const -> bool {
|
||||
return state_ == CardState::EXITING;
|
||||
}
|
||||
|
||||
auto CardSprite::getState() const -> CardState {
|
||||
return state_;
|
||||
}
|
||||
|
||||
// --- Configuración ---
|
||||
void CardSprite::setEntryParams(float start_zoom, double start_angle, float duration_s, std::function<double(double)> easing) {
|
||||
start_zoom_ = start_zoom;
|
||||
start_angle_ = start_angle;
|
||||
entry_duration_s_ = duration_s;
|
||||
entry_easing_ = std::move(easing);
|
||||
}
|
||||
|
||||
void CardSprite::setEntryPosition(float start_x, float start_y) {
|
||||
entry_start_x_ = start_x;
|
||||
entry_start_y_ = start_y;
|
||||
}
|
||||
|
||||
void CardSprite::setLandingPosition(float x, float y) {
|
||||
landing_x_ = x;
|
||||
landing_y_ = y;
|
||||
}
|
||||
|
||||
void CardSprite::setExitParams(float vx, float vy, float ax, float ay, double rotate_amount) {
|
||||
exit_vx_ = vx;
|
||||
exit_vy_ = vy;
|
||||
exit_ax_ = ax;
|
||||
exit_ay_ = ay;
|
||||
exit_rotate_amount_ = rotate_amount;
|
||||
}
|
||||
|
||||
void CardSprite::setExitLift(float target_zoom, float zoom_speed) {
|
||||
exit_target_zoom_ = target_zoom;
|
||||
exit_zoom_speed_ = zoom_speed;
|
||||
}
|
||||
|
||||
void CardSprite::setShadowTexture(std::shared_ptr<Texture> texture) {
|
||||
shadow_texture_ = std::move(texture);
|
||||
}
|
||||
|
||||
void CardSprite::setShadowOffset(float offset_x, float offset_y) {
|
||||
shadow_offset_x_ = offset_x;
|
||||
shadow_offset_y_ = offset_y;
|
||||
}
|
||||
|
||||
void CardSprite::setScreenBounds(float width, float height) {
|
||||
screen_width_ = width;
|
||||
screen_height_ = height;
|
||||
}
|
||||
109
source/card_sprite.hpp
Normal file
109
source/card_sprite.hpp
Normal file
@@ -0,0 +1,109 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL.h> // Para SDL_FPoint
|
||||
|
||||
#include <functional> // Para function
|
||||
#include <memory> // Para shared_ptr
|
||||
|
||||
#include "moving_sprite.hpp" // Para MovingSprite
|
||||
|
||||
class Texture;
|
||||
|
||||
// --- Estados de la tarjeta ---
|
||||
enum class CardState {
|
||||
IDLE, // No activada todavía
|
||||
ENTERING, // Animación de entrada (zoom + rotación + desplazamiento con rebote)
|
||||
LANDED, // En reposo sobre la mesa
|
||||
EXITING, // Saliendo de pantalla girando
|
||||
FINISHED, // Fuera de pantalla
|
||||
};
|
||||
|
||||
// --- Clase CardSprite: tarjeta animada con zoom, rotación y sombra integrada ---
|
||||
//
|
||||
// Simula una tarjeta lanzada sobre una mesa desde un borde de la pantalla.
|
||||
// Durante la entrada, interpola posición, zoom y rotación con easing (rebote).
|
||||
// Durante la salida, se desplaza fuera de pantalla girando, sin sombra.
|
||||
class CardSprite : public MovingSprite {
|
||||
public:
|
||||
explicit CardSprite(std::shared_ptr<Texture> texture);
|
||||
~CardSprite() override = default;
|
||||
|
||||
// --- Ciclo principal ---
|
||||
void update(float delta_time) override;
|
||||
void render() override;
|
||||
|
||||
// --- Control de estado ---
|
||||
auto enable() -> bool; // Inicia la animación de entrada (true si se activó)
|
||||
void startExit(); // Inicia la animación de salida
|
||||
|
||||
// --- Consultas de estado ---
|
||||
[[nodiscard]] auto hasLanded() const -> bool; // ¿Ha aterrizado definitivamente?
|
||||
[[nodiscard]] auto hasFirstTouch() const -> bool; // ¿Ha tocado la mesa por primera vez? (primer rebote)
|
||||
[[nodiscard]] auto hasFinished() const -> bool; // ¿Ha terminado completamente?
|
||||
[[nodiscard]] auto isExiting() const -> bool; // ¿Está saliendo de pantalla?
|
||||
[[nodiscard]] auto getState() const -> CardState; // Estado actual
|
||||
|
||||
// --- Configuración de entrada ---
|
||||
void setEntryParams(float start_zoom, double start_angle, float duration_s, std::function<double(double)> easing);
|
||||
void setEntryPosition(float start_x, float start_y); // Posición inicial (borde de pantalla)
|
||||
void setLandingPosition(float x, float y); // Posición final centrada
|
||||
|
||||
// --- Configuración de salida ---
|
||||
void setExitParams(float vx, float vy, float ax, float ay, double rotate_amount);
|
||||
void setExitLift(float target_zoom, float zoom_speed); // Ganar altura al salir (zoom > 1.0)
|
||||
|
||||
// --- Sombra ---
|
||||
void setShadowTexture(std::shared_ptr<Texture> texture);
|
||||
void setShadowOffset(float offset_x, float offset_y);
|
||||
|
||||
// --- Limites de pantalla (para detectar salida) ---
|
||||
void setScreenBounds(float width, float height);
|
||||
|
||||
private:
|
||||
// --- Estado ---
|
||||
CardState state_ = CardState::IDLE;
|
||||
bool first_touch_ = false; // Primer contacto con la mesa (eased >= umbral)
|
||||
|
||||
// --- Umbral para detectar el primer toque ---
|
||||
static constexpr double FIRST_TOUCH_THRESHOLD = 0.98;
|
||||
|
||||
// --- Parámetros de entrada ---
|
||||
float start_zoom_ = 1.8F;
|
||||
double start_angle_ = 15.0;
|
||||
float entry_duration_s_ = 1.5F;
|
||||
float entry_elapsed_ = 0.0F;
|
||||
std::function<double(double)> entry_easing_;
|
||||
float entry_start_x_ = 0.0F; // Posición inicial X (borde)
|
||||
float entry_start_y_ = 0.0F; // Posición inicial Y (borde)
|
||||
float landing_x_ = 0.0F;
|
||||
float landing_y_ = 0.0F;
|
||||
|
||||
// --- Parámetros de salida ---
|
||||
float exit_vx_ = 0.0F;
|
||||
float exit_vy_ = 0.0F;
|
||||
float exit_ax_ = 0.0F;
|
||||
float exit_ay_ = 0.0F;
|
||||
double exit_rotate_amount_ = 0.0;
|
||||
float exit_target_zoom_ = 1.0F; // Zoom objetivo al salir (>1.0 = se eleva)
|
||||
float exit_zoom_speed_ = 0.0F; // Velocidad de cambio de zoom por segundo
|
||||
|
||||
// --- Sombra ---
|
||||
std::shared_ptr<Texture> shadow_texture_;
|
||||
float shadow_offset_x_ = 8.0F;
|
||||
float shadow_offset_y_ = 8.0F;
|
||||
bool shadow_visible_ = true;
|
||||
|
||||
// --- Límites de pantalla ---
|
||||
float screen_width_ = 320.0F;
|
||||
float screen_height_ = 240.0F;
|
||||
|
||||
// --- Constantes ---
|
||||
static constexpr float OFF_SCREEN_MARGIN = 50.0F; // Margen fuera de pantalla para considerar FINISHED
|
||||
static constexpr float SHADOW_HEIGHT_MULTIPLIER = 400.0F; // Pixels de separación de sombra por unidad de altura
|
||||
|
||||
// --- Métodos internos ---
|
||||
void updateEntering(float delta_time);
|
||||
void updateExiting(float delta_time);
|
||||
void renderShadow();
|
||||
[[nodiscard]] auto isOffScreen() const -> bool;
|
||||
};
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <cstdlib> // Para srand, exit, rand, EXIT_FAILURE
|
||||
#include <ctime> // Para time
|
||||
#include <filesystem> // Para path, absolute
|
||||
#include <fstream> // Para ifstream, ofstream
|
||||
#include <iostream> // Para basic_ostream, operator<<, cerr
|
||||
#include <memory> // Para make_unique, unique_ptr
|
||||
#include <span> // Para span
|
||||
@@ -14,6 +15,7 @@
|
||||
|
||||
#include "asset.hpp" // Para Asset
|
||||
#include "audio.hpp" // Para Audio
|
||||
#include "external/fkyaml_node.hpp" // Para fkyaml::node
|
||||
#include "input.hpp" // Para Input
|
||||
#include "lang.hpp" // Para setLanguage
|
||||
#include "manage_hiscore_table.hpp" // Para ManageHiScoreTable
|
||||
@@ -40,16 +42,6 @@
|
||||
|
||||
// Constructor
|
||||
Director::Director(int argc, std::span<char*> argv) {
|
||||
#ifdef RECORDING
|
||||
Section::name = Section::Name::GAME;
|
||||
Section::options = Section::Options::GAME_PLAY_1P;
|
||||
#elif _DEBUG
|
||||
Section::name = Section::Name::GAME;
|
||||
Section::options = Section::Options::GAME_PLAY_1P;
|
||||
#else // NORMAL GAME
|
||||
Section::name = Section::Name::LOGO;
|
||||
Section::options = Section::Options::NONE;
|
||||
#endif
|
||||
Section::attract_mode = Section::AttractMode::TITLE_TO_DEMO;
|
||||
|
||||
// Establece el nivel de prioridad de la categoría de registro
|
||||
@@ -68,6 +60,17 @@ Director::Director(int argc, std::span<char*> argv) {
|
||||
createSystemFolder("jailgames");
|
||||
createSystemFolder("jailgames/coffee_crisis_arcade_edition");
|
||||
|
||||
// Establecer sección inicial según modo de compilación
|
||||
#ifdef RECORDING
|
||||
Section::name = Section::Name::GAME;
|
||||
Section::options = Section::Options::GAME_PLAY_1P;
|
||||
#elif _DEBUG
|
||||
loadDebugConfig();
|
||||
#else
|
||||
Section::name = Section::Name::LOGO;
|
||||
Section::options = Section::Options::NONE;
|
||||
#endif
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
@@ -124,9 +127,9 @@ void Director::init() {
|
||||
|
||||
Logger::section("INIT RESOURCES");
|
||||
#ifdef _DEBUG
|
||||
Resource::init(Resource::LoadingMode::PRELOAD); // Inicializa el sistema de gestión de recursos
|
||||
Resource::init(debug_config.resource_loading == "lazy" ? Resource::LoadingMode::LAZY_LOAD : Resource::LoadingMode::PRELOAD);
|
||||
#else
|
||||
Resource::init(Resource::LoadingMode::PRELOAD); // Inicializa el sistema de gestión de recursos
|
||||
Resource::init(Resource::LoadingMode::PRELOAD);
|
||||
#endif
|
||||
ServiceMenu::init(); // Inicializa el menú de servicio
|
||||
Notifier::init(std::string(), Resource::get()->getText("8bithud")); // Inicialización del sistema de notificaciones
|
||||
@@ -224,6 +227,103 @@ void Director::checkProgramArguments(int argc, std::span<char*> argv) {
|
||||
}
|
||||
}
|
||||
|
||||
// Carga debug.yaml desde la carpeta del sistema (solo en _DEBUG)
|
||||
void Director::loadDebugConfig() {
|
||||
const std::string DEBUG_FILE = system_folder_ + "/debug.yaml";
|
||||
|
||||
std::ifstream file(DEBUG_FILE);
|
||||
if (!file.good()) {
|
||||
// Crear fichero por defecto
|
||||
std::ofstream out(DEBUG_FILE);
|
||||
if (out.is_open()) {
|
||||
out << "# Coffee Crisis Arcade Edition - Debug Configuration\n";
|
||||
out << "# This file is only read in DEBUG builds.\n";
|
||||
out << "#\n";
|
||||
out << "# initial_section: logo, intro, title, game, credits, instructions, hiscore\n";
|
||||
out << "# initial_options: none, 1p, 2p, both\n";
|
||||
out << "# initial_stage: 0-based stage index (only when section is game)\n";
|
||||
out << "# show_render_info: show FPS/driver/preset overlay\n";
|
||||
out << "# resource_loading: preload, lazy\n";
|
||||
out << "\n";
|
||||
out << "initial_section: game\n";
|
||||
out << "initial_options: 1p\n";
|
||||
out << "initial_stage: 0\n";
|
||||
out << "show_render_info: true\n";
|
||||
out << "resource_loading: preload\n";
|
||||
out.close();
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Debug config created: %s", DEBUG_FILE.c_str());
|
||||
}
|
||||
// Usar defaults de DebugConfig
|
||||
} else {
|
||||
std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||
file.close();
|
||||
try {
|
||||
auto yaml = fkyaml::node::deserialize(content);
|
||||
if (yaml.contains("initial_section")) {
|
||||
try {
|
||||
debug_config.initial_section = yaml["initial_section"].get_value<std::string>();
|
||||
} catch (...) {}
|
||||
}
|
||||
if (yaml.contains("initial_options")) {
|
||||
try {
|
||||
debug_config.initial_options = yaml["initial_options"].get_value<std::string>();
|
||||
} catch (...) {}
|
||||
}
|
||||
if (yaml.contains("initial_stage")) {
|
||||
try {
|
||||
debug_config.initial_stage = yaml["initial_stage"].get_value<int>();
|
||||
} catch (...) {}
|
||||
}
|
||||
if (yaml.contains("show_render_info")) {
|
||||
try {
|
||||
debug_config.show_render_info = yaml["show_render_info"].get_value<bool>();
|
||||
} catch (...) {}
|
||||
}
|
||||
if (yaml.contains("resource_loading")) {
|
||||
try {
|
||||
debug_config.resource_loading = yaml["resource_loading"].get_value<std::string>();
|
||||
} catch (...) {}
|
||||
}
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Debug config loaded: section=%s options=%s stage=%d", debug_config.initial_section.c_str(), debug_config.initial_options.c_str(), debug_config.initial_stage);
|
||||
} catch (...) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Error parsing debug.yaml, using defaults");
|
||||
}
|
||||
}
|
||||
|
||||
// Mapear strings a enums
|
||||
const auto& sec = debug_config.initial_section;
|
||||
if (sec == "logo") {
|
||||
Section::name = Section::Name::LOGO;
|
||||
} else if (sec == "intro") {
|
||||
Section::name = Section::Name::INTRO;
|
||||
} else if (sec == "title") {
|
||||
Section::name = Section::Name::TITLE;
|
||||
} else if (sec == "game") {
|
||||
Section::name = Section::Name::GAME;
|
||||
} else if (sec == "credits") {
|
||||
Section::name = Section::Name::CREDITS;
|
||||
} else if (sec == "instructions") {
|
||||
Section::name = Section::Name::INSTRUCTIONS;
|
||||
} else if (sec == "hiscore") {
|
||||
Section::name = Section::Name::HI_SCORE_TABLE;
|
||||
} else {
|
||||
Section::name = Section::Name::GAME;
|
||||
}
|
||||
|
||||
const auto& opt = debug_config.initial_options;
|
||||
if (opt == "none") {
|
||||
Section::options = Section::Options::NONE;
|
||||
} else if (opt == "1p") {
|
||||
Section::options = Section::Options::GAME_PLAY_1P;
|
||||
} else if (opt == "2p") {
|
||||
Section::options = Section::Options::GAME_PLAY_2P;
|
||||
} else if (opt == "both") {
|
||||
Section::options = Section::Options::GAME_PLAY_BOTH;
|
||||
} else {
|
||||
Section::options = Section::Options::GAME_PLAY_1P;
|
||||
}
|
||||
}
|
||||
|
||||
// Crea la carpeta del sistema donde guardar datos
|
||||
void Director::createSystemFolder(const std::string& folder) {
|
||||
auto result = SystemUtils::createApplicationFolder(folder, system_folder_);
|
||||
@@ -272,7 +372,7 @@ void Director::runGame() {
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
constexpr int CURRENT_STAGE = 0;
|
||||
const int CURRENT_STAGE = debug_config.initial_stage;
|
||||
#else
|
||||
constexpr int CURRENT_STAGE = 0;
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,21 @@ class Director {
|
||||
// --- Bucle principal ---
|
||||
static auto run() -> int;
|
||||
|
||||
// --- Debug config (accesible desde otras clases) ---
|
||||
struct DebugConfig {
|
||||
std::string initial_section;
|
||||
std::string initial_options;
|
||||
int initial_stage = 0;
|
||||
bool show_render_info = true;
|
||||
std::string resource_loading;
|
||||
|
||||
DebugConfig()
|
||||
: initial_section("game"),
|
||||
initial_options("1p"),
|
||||
resource_loading("preload") {}
|
||||
};
|
||||
static inline DebugConfig debug_config;
|
||||
|
||||
private:
|
||||
// --- Variables internas ---
|
||||
std::string executable_path_; // Ruta del ejecutable
|
||||
@@ -30,6 +45,7 @@ class Director {
|
||||
static void loadParams(); // Carga los parámetros del programa
|
||||
static void loadScoreFile(); // Carga el fichero de puntuaciones
|
||||
void createSystemFolder(const std::string& folder); // Crea la carpeta del sistema
|
||||
void loadDebugConfig(); // Carga debug.yaml (solo en _DEBUG)
|
||||
|
||||
// --- Gestión de entrada y archivos ---
|
||||
void loadAssets(); // Crea el índice de archivos disponibles
|
||||
|
||||
@@ -325,17 +325,6 @@ void Input::initSDLGamePad() {
|
||||
}
|
||||
}
|
||||
|
||||
void Input::resetJustPressed() {
|
||||
for (auto& key : keyboard_.bindings) {
|
||||
key.second.just_pressed = false;
|
||||
}
|
||||
for (auto& gamepad : gamepads_) {
|
||||
for (auto& binding : gamepad->bindings) {
|
||||
binding.second.just_pressed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Input::resetInputStates() {
|
||||
// Resetear todos los KeyBindings.active a false
|
||||
for (auto& key : keyboard_.bindings) {
|
||||
@@ -360,7 +349,7 @@ void Input::update() {
|
||||
bool key_is_down_now = key_states[binding.second.scancode];
|
||||
|
||||
// El estado .is_held del fotograma anterior nos sirve para saber si es un pulso nuevo
|
||||
binding.second.just_pressed = binding.second.just_pressed || (key_is_down_now && !binding.second.is_held);
|
||||
binding.second.just_pressed = key_is_down_now && !binding.second.is_held;
|
||||
binding.second.is_held = key_is_down_now;
|
||||
}
|
||||
|
||||
@@ -378,16 +367,6 @@ void Input::update() {
|
||||
|
||||
auto Input::handleEvent(const SDL_Event& event) -> std::string {
|
||||
switch (event.type) {
|
||||
case SDL_EVENT_KEY_DOWN:
|
||||
if (!event.key.repeat) {
|
||||
for (auto& [action, binding] : keyboard_.bindings) {
|
||||
if (binding.scancode == event.key.scancode) {
|
||||
binding.just_pressed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_GAMEPAD_ADDED:
|
||||
return addGamepad(event.gdevice.which);
|
||||
case SDL_EVENT_GAMEPAD_REMOVED:
|
||||
|
||||
@@ -177,7 +177,6 @@ class Input {
|
||||
|
||||
// --- Métodos de reseteo de estado de entrada ---
|
||||
void resetInputStates();
|
||||
void resetJustPressed();
|
||||
|
||||
// --- Eventos ---
|
||||
auto handleEvent(const SDL_Event& event) -> std::string;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <vector> // Para vector
|
||||
|
||||
#include "asset.hpp" // Para Asset
|
||||
#include "director.hpp" // Para Director::debug_config
|
||||
#include "mouse.hpp" // Para updateCursorVisibility
|
||||
#include "options.hpp" // Para Video, video, Window, window
|
||||
#include "param.hpp" // Para Param, param, ParamGame, ParamDebug
|
||||
@@ -60,7 +61,7 @@ Screen::Screen()
|
||||
|
||||
#ifdef _DEBUG
|
||||
debug_info_.text = text_;
|
||||
setDebugInfoEnabled(true);
|
||||
setDebugInfoEnabled(Director::debug_config.show_render_info);
|
||||
#endif
|
||||
|
||||
// Renderizar una vez la textura vacía para que tenga contenido válido antes de inicializar los shaders (evita pantalla negra)
|
||||
|
||||
@@ -1128,7 +1128,6 @@ auto Game::allPlayersAreNotPlaying() -> bool {
|
||||
|
||||
// Comprueba los eventos que hay en cola
|
||||
void Game::handleEvents() {
|
||||
input_->resetJustPressed();
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
|
||||
@@ -2,26 +2,25 @@
|
||||
|
||||
#include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_SetRenderDrawColor, SDL_FRect, SDL_RenderFillRect, SDL_GetRenderTarget, SDL_RenderClear, SDL_RenderRect, SDL_SetRenderTarget, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_PollEvent, SDL_RenderTexture, SDL_TextureAccess, SDL_Event, Uint64
|
||||
|
||||
#include <array> // Para array
|
||||
#include <functional> // Para function
|
||||
#include <string> // Para basic_string, string
|
||||
#include <utility> // Para move
|
||||
#include <array> // Para array
|
||||
#include <string> // Para basic_string, string
|
||||
#include <utility> // Para move
|
||||
|
||||
#include "audio.hpp" // Para Audio
|
||||
#include "card_sprite.hpp" // Para CardSprite
|
||||
#include "color.hpp" // Para Color
|
||||
#include "global_events.hpp" // Para handle
|
||||
#include "global_inputs.hpp" // Para check
|
||||
#include "input.hpp" // Para Input
|
||||
#include "lang.hpp" // Para getText
|
||||
#include "param.hpp" // Para Param, param, ParamGame, ParamIntro, ParamTitle
|
||||
#include "path_sprite.hpp" // Para PathSprite, PathType
|
||||
#include "resource.hpp" // Para Resource
|
||||
#include "screen.hpp" // Para Screen
|
||||
#include "section.hpp" // Para Name, name, Options, options
|
||||
#include "text.hpp" // Para Text
|
||||
#include "texture.hpp" // Para Texture
|
||||
#include "tiled_bg.hpp" // Para TiledBG, TiledBGMode
|
||||
#include "utils.hpp" // Para Zone, easeInOutExpo, easeInElastic, easeOutBounce, easeOutElastic, easeOutQuad, easeOutQuint
|
||||
#include "utils.hpp" // Para easeOutBounce
|
||||
#include "writer.hpp" // Para Writer
|
||||
|
||||
// Constructor
|
||||
@@ -31,7 +30,7 @@ Intro::Intro()
|
||||
Section::name = Section::Name::INTRO;
|
||||
Section::options = Section::Options::NONE;
|
||||
|
||||
// Inicializa las imagens
|
||||
// Inicializa las tarjetas
|
||||
initSprites();
|
||||
|
||||
// Inicializa los textos
|
||||
@@ -58,6 +57,22 @@ void Intro::checkInput() {
|
||||
|
||||
// Actualiza las escenas de la intro
|
||||
void Intro::updateScenes() {
|
||||
// Sonido al lanzar la tarjeta (enable() devuelve true solo la primera vez)
|
||||
if (card_sprites_.at(scene_)->enable()) {
|
||||
Audio::get()->playSound(SFX_CARD_THROW);
|
||||
}
|
||||
|
||||
// Cuando la tarjeta actual toca la mesa por primera vez: shake + sonido + la anterior sale despedida
|
||||
if (!shake_done_ && card_sprites_.at(scene_)->hasFirstTouch()) {
|
||||
Screen::get()->shake();
|
||||
Audio::get()->playSound(SFX_CARD_IMPACT);
|
||||
shake_done_ = true;
|
||||
|
||||
if (scene_ > 0) {
|
||||
card_sprites_.at(scene_ - 1)->startExit();
|
||||
}
|
||||
}
|
||||
|
||||
switch (scene_) {
|
||||
case 0:
|
||||
updateScene0();
|
||||
@@ -83,37 +98,32 @@ void Intro::updateScenes() {
|
||||
}
|
||||
|
||||
void Intro::updateScene0() {
|
||||
// Primera imagen - UPV
|
||||
enableCardAndShadow(0);
|
||||
|
||||
// Primer texto de la primera imagen
|
||||
if (card_sprites_.at(0)->hasFinished() && !texts_.at(0)->hasFinished()) {
|
||||
// Primer texto cuando aterriza
|
||||
if (card_sprites_.at(0)->hasLanded() && !texts_.at(0)->hasFinished()) {
|
||||
texts_.at(0)->setEnabled(true);
|
||||
}
|
||||
|
||||
// Segundo texto de la primera imagen
|
||||
// Segundo texto
|
||||
if (texts_.at(0)->hasFinished() && !texts_.at(1)->hasFinished()) {
|
||||
switchText(0, 1);
|
||||
}
|
||||
|
||||
// Tercer texto de la primera imagen
|
||||
// Tercer texto
|
||||
if (texts_.at(1)->hasFinished() && !texts_.at(2)->hasFinished()) {
|
||||
switchText(1, 2);
|
||||
}
|
||||
|
||||
// Fin de la primera escena
|
||||
// Fin de la primera escena: la tarjeta sale despedida
|
||||
if (texts_.at(2)->hasFinished()) {
|
||||
texts_.at(2)->setEnabled(false);
|
||||
scene_++;
|
||||
shake_done_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Intro::updateScene1() {
|
||||
// Segunda imagen - Máquina
|
||||
enableCardAndShadow(1);
|
||||
|
||||
// Primer texto de la segunda imagen
|
||||
if (card_sprites_.at(1)->hasFinished() && !texts_.at(3)->hasFinished()) {
|
||||
// Texto cuando aterriza
|
||||
if (card_sprites_.at(1)->hasLanded() && !texts_.at(3)->hasFinished()) {
|
||||
texts_.at(3)->setEnabled(true);
|
||||
}
|
||||
|
||||
@@ -121,63 +131,59 @@ void Intro::updateScene1() {
|
||||
if (texts_.at(3)->hasFinished()) {
|
||||
texts_.at(3)->setEnabled(false);
|
||||
scene_++;
|
||||
shake_done_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Intro::updateScene2() {
|
||||
// Tercera imagen junto con primer texto - GRITO
|
||||
// Tercera imagen - GRITO: tarjeta y texto a la vez
|
||||
if (!texts_.at(4)->hasFinished()) {
|
||||
enableCardAndShadow(2);
|
||||
texts_.at(4)->setEnabled(true);
|
||||
}
|
||||
|
||||
// Fin de la tercera escena
|
||||
if (card_sprites_.at(2)->hasFinished() && texts_.at(4)->hasFinished()) {
|
||||
if (card_sprites_.at(2)->hasLanded() && texts_.at(4)->hasFinished()) {
|
||||
texts_.at(4)->setEnabled(false);
|
||||
scene_++;
|
||||
shake_done_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Intro::updateScene3() {
|
||||
// Cuarta imagen junto con primer texto - Reflexión
|
||||
enableCardAndShadow(3);
|
||||
|
||||
// Cuarta imagen - Reflexión
|
||||
if (!texts_.at(5)->hasFinished()) {
|
||||
texts_.at(5)->setEnabled(true);
|
||||
}
|
||||
|
||||
// Segundo texto de la cuarta imagen
|
||||
// Segundo texto
|
||||
if (texts_.at(5)->hasFinished() && !texts_.at(6)->hasFinished()) {
|
||||
switchText(5, 6);
|
||||
}
|
||||
|
||||
// Fin de la cuarta escena
|
||||
if (card_sprites_.at(3)->hasFinished() && texts_.at(6)->hasFinished()) {
|
||||
if (card_sprites_.at(3)->hasLanded() && texts_.at(6)->hasFinished()) {
|
||||
texts_.at(6)->setEnabled(false);
|
||||
scene_++;
|
||||
shake_done_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Intro::updateScene4() {
|
||||
// Quinta imagen - Patada
|
||||
enableCardAndShadow(4);
|
||||
|
||||
// Primer texto de la quinta imagen
|
||||
if (!texts_.at(7)->hasFinished()) {
|
||||
texts_.at(7)->setEnabled(true);
|
||||
}
|
||||
|
||||
// Fin de la quinta escena
|
||||
if (card_sprites_.at(4)->hasFinished() && texts_.at(7)->hasFinished()) {
|
||||
if (card_sprites_.at(4)->hasLanded() && texts_.at(7)->hasFinished()) {
|
||||
texts_.at(7)->setEnabled(false);
|
||||
scene_++;
|
||||
shake_done_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Intro::updateScene5() {
|
||||
// Sexta imagen junto con texto - Globos de café
|
||||
enableCardAndShadow(5);
|
||||
|
||||
// Sexta imagen - Globos de café
|
||||
if (!texts_.at(8)->hasFinished()) {
|
||||
texts_.at(8)->setEnabled(true);
|
||||
}
|
||||
@@ -187,19 +193,14 @@ void Intro::updateScene5() {
|
||||
texts_.at(8)->setEnabled(false);
|
||||
}
|
||||
|
||||
// Acaba la ultima imagen
|
||||
if (card_sprites_.at(5)->hasFinished() && texts_.at(8)->hasFinished()) {
|
||||
// Última tarjeta: sale "como si se la llevara el viento" y transición a POST
|
||||
if (card_sprites_.at(5)->hasLanded() && texts_.at(8)->hasFinished()) {
|
||||
card_sprites_.at(5)->startExit();
|
||||
state_ = State::POST;
|
||||
state_start_time_ = SDL_GetTicks() / 1000.0F;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper methods to reduce code duplication
|
||||
void Intro::enableCardAndShadow(int index) {
|
||||
card_sprites_.at(index)->enable();
|
||||
shadow_sprites_.at(index)->enable();
|
||||
}
|
||||
|
||||
void Intro::switchText(int from_index, int to_index) {
|
||||
texts_.at(from_index)->setEnabled(false);
|
||||
texts_.at(to_index)->setEnabled(true);
|
||||
@@ -215,12 +216,18 @@ void Intro::update(float delta_time) {
|
||||
|
||||
switch (state_) {
|
||||
case State::SCENES:
|
||||
// Pausa inicial antes de empezar
|
||||
if (initial_elapsed_ < INITIAL_DELAY_S) {
|
||||
initial_elapsed_ += delta_time;
|
||||
break;
|
||||
}
|
||||
updateSprites(delta_time);
|
||||
updateTexts(delta_time);
|
||||
updateScenes();
|
||||
break;
|
||||
|
||||
case State::POST:
|
||||
updateSprites(delta_time); // La última tarjeta puede estar saliendo durante POST
|
||||
updatePostState();
|
||||
break;
|
||||
}
|
||||
@@ -243,6 +250,7 @@ void Intro::render() {
|
||||
break;
|
||||
}
|
||||
case State::POST:
|
||||
renderSprites(); // La última tarjeta puede estar saliendo
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -272,7 +280,7 @@ void Intro::run() {
|
||||
}
|
||||
}
|
||||
|
||||
// Inicializa las imagens
|
||||
// Inicializa las tarjetas
|
||||
void Intro::initSprites() {
|
||||
// Listado de imagenes a usar
|
||||
const std::array<std::string, 6> TEXTURE_LIST = {
|
||||
@@ -291,24 +299,21 @@ void Intro::initSprites() {
|
||||
const float CARD_WIDTH = texture->getWidth() + (BORDER * 2);
|
||||
const float CARD_HEIGHT = texture->getHeight() + (BORDER * 2);
|
||||
|
||||
// Crea las texturas para las tarjetas
|
||||
// Crea las texturas para las tarjetas (imagen con marco)
|
||||
std::vector<std::shared_ptr<Texture>> card_textures;
|
||||
|
||||
for (int i = 0; i < TOTAL_SPRITES; ++i) {
|
||||
// Crea la textura
|
||||
auto card_texture = std::make_unique<Texture>(Screen::get()->getRenderer());
|
||||
card_texture->createBlank(CARD_WIDTH, CARD_HEIGHT, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
|
||||
card_texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||
|
||||
// Apuntamos el renderizador a la textura
|
||||
auto* temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
|
||||
card_texture->setAsRenderTarget(Screen::get()->getRenderer());
|
||||
|
||||
// Limpia la textura
|
||||
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 0);
|
||||
SDL_RenderClear(Screen::get()->getRenderer());
|
||||
|
||||
// Pone color en el marco de la textura
|
||||
// Marco de la tarjeta
|
||||
auto color = param.intro.card_color;
|
||||
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, color.a);
|
||||
SDL_FRect rect1 = {.x = 1, .y = 0, .w = CARD_WIDTH - 2, .h = CARD_HEIGHT};
|
||||
@@ -316,85 +321,108 @@ void Intro::initSprites() {
|
||||
SDL_RenderRect(Screen::get()->getRenderer(), &rect1);
|
||||
SDL_RenderRect(Screen::get()->getRenderer(), &rect2);
|
||||
|
||||
// Copia la textura con la imagen dentro del marco
|
||||
// Imagen dentro del marco
|
||||
SDL_FRect dest = {.x = BORDER, .y = BORDER, .w = CARD_WIDTH - (BORDER * 2), .h = CARD_HEIGHT - (BORDER * 2)};
|
||||
SDL_RenderTexture(Screen::get()->getRenderer(), Resource::get()->getTexture(TEXTURE_LIST.at(i))->getSDLTexture(), nullptr, &dest);
|
||||
|
||||
// Deja el renderizador como estaba y añade la textura a la lista
|
||||
SDL_SetRenderTarget(Screen::get()->getRenderer(), temp);
|
||||
card_textures.push_back(std::move(card_texture));
|
||||
}
|
||||
|
||||
// Inicializa los sprites para las tarjetas
|
||||
for (int i = 0; i < TOTAL_SPRITES; ++i) {
|
||||
auto sprite = std::make_unique<PathSprite>(card_textures.at(i));
|
||||
sprite->setWidth(CARD_WIDTH);
|
||||
sprite->setHeight(CARD_HEIGHT);
|
||||
sprite->setSpriteClip(0, 0, CARD_WIDTH, CARD_HEIGHT);
|
||||
card_sprites_.push_back(std::move(sprite));
|
||||
}
|
||||
|
||||
const float X_DEST = param.game.game_area.center_x - (CARD_WIDTH / 2);
|
||||
const float Y_DEST = param.game.game_area.first_quarter_y - (CARD_HEIGHT / 4);
|
||||
|
||||
card_sprites_.at(0)->addPath(-CARD_WIDTH - CARD_OFFSET_MARGIN, X_DEST, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_NORMAL, easeInOutExpo, 0.0F);
|
||||
card_sprites_.at(1)->addPath(param.game.width, X_DEST, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_NORMAL, easeOutBounce, 0.0F);
|
||||
card_sprites_.at(2)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_FAST, easeOutQuint, 0.0F);
|
||||
card_sprites_.at(3)->addPath(param.game.height, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_VERY_SLOW, easeInOutExpo, 0.0F);
|
||||
card_sprites_.at(4)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_MEDIUM, easeOutElastic, 0.0F);
|
||||
card_sprites_.at(5)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_SLOW, easeOutQuad, CARD_ANIM_DELAY_LONG_S);
|
||||
card_sprites_.at(5)->addPath(X_DEST, -CARD_WIDTH, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_SHORT, easeInElastic, 0.0F);
|
||||
|
||||
// Constantes
|
||||
const float DESP = SHADOW_OFFSET;
|
||||
const float SHADOW_SPRITE_WIDTH = CARD_WIDTH;
|
||||
const float SHADOW_SPRITE_HEIGHT = CARD_HEIGHT;
|
||||
|
||||
// Crea la textura para las sombras de las tarjetas
|
||||
// Crea la textura de sombra (compartida entre todas las tarjetas)
|
||||
auto shadow_texture = std::make_shared<Texture>(Screen::get()->getRenderer());
|
||||
shadow_texture->createBlank(SHADOW_SPRITE_WIDTH, SHADOW_SPRITE_HEIGHT, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
|
||||
shadow_texture->createBlank(CARD_WIDTH, CARD_HEIGHT, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
|
||||
shadow_texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||
|
||||
// Apuntamos el renderizador a la textura
|
||||
auto* temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
|
||||
shadow_texture->setAsRenderTarget(Screen::get()->getRenderer());
|
||||
|
||||
// Limpia la textura
|
||||
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 0);
|
||||
SDL_RenderClear(Screen::get()->getRenderer());
|
||||
|
||||
// Dibuja la sombra sobre la textura
|
||||
auto shadow_color = param.intro.shadow_color;
|
||||
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), shadow_color.r, shadow_color.g, shadow_color.b, Color::MAX_ALPHA_VALUE);
|
||||
SDL_FRect rect1 = {.x = 1, .y = 0, .w = SHADOW_SPRITE_WIDTH - 2, .h = SHADOW_SPRITE_HEIGHT};
|
||||
SDL_FRect rect2 = {.x = 0, .y = 1, .w = SHADOW_SPRITE_WIDTH, .h = SHADOW_SPRITE_HEIGHT - 2};
|
||||
SDL_RenderFillRect(Screen::get()->getRenderer(), &rect1);
|
||||
SDL_RenderFillRect(Screen::get()->getRenderer(), &rect2);
|
||||
SDL_FRect shadow_rect1 = {.x = 1, .y = 0, .w = CARD_WIDTH - 2, .h = CARD_HEIGHT};
|
||||
SDL_FRect shadow_rect2 = {.x = 0, .y = 1, .w = CARD_WIDTH, .h = CARD_HEIGHT - 2};
|
||||
SDL_RenderFillRect(Screen::get()->getRenderer(), &shadow_rect1);
|
||||
SDL_RenderFillRect(Screen::get()->getRenderer(), &shadow_rect2);
|
||||
|
||||
// Deja el renderizador como estaba y añade la textura a la lista
|
||||
SDL_SetRenderTarget(Screen::get()->getRenderer(), temp);
|
||||
shadow_texture->setAlpha(shadow_color.a);
|
||||
|
||||
// Inicializa los sprites para la sombras usando la texturas con la sombra
|
||||
// Posición de aterrizaje (centro de la zona de juego)
|
||||
const float X_DEST = param.game.game_area.center_x - (CARD_WIDTH / 2);
|
||||
const float Y_DEST = param.game.game_area.first_quarter_y - (CARD_HEIGHT / 4);
|
||||
|
||||
// Configuración por tarjeta: posición de entrada, ángulo, salida
|
||||
// Cada tarjeta viene de un borde diferente (gente alrededor de una mesa lanzando cartas al centro)
|
||||
struct CardConfig {
|
||||
float entry_x; // Posición inicial X
|
||||
float entry_y; // Posición inicial Y
|
||||
double entry_angle; // Ángulo de entrada
|
||||
float exit_vx; // Velocidad de salida X
|
||||
float exit_vy; // Velocidad de salida Y
|
||||
float exit_ax; // Aceleración de salida X
|
||||
float exit_ay; // Aceleración de salida Y
|
||||
double exit_rotation; // Velocidad de rotación de salida
|
||||
};
|
||||
|
||||
const float W = param.game.width;
|
||||
const float H = param.game.height;
|
||||
const float S = CARD_EXIT_SPEED;
|
||||
const float A = CARD_EXIT_ACCEL;
|
||||
const double R = CARD_EXIT_ROTATION;
|
||||
|
||||
const CardConfig CARD_CONFIGS[] = {
|
||||
// 0: Entra desde la izquierda. La 1 entra desde la derecha → sale empujada hacia la izquierda
|
||||
{-CARD_WIDTH, Y_DEST - 20.0F, CARD_ANGLE_0, -S, S * 0.1F, -A, 0.0F, -R},
|
||||
// 1: Entra desde la derecha. La 2 entra desde arriba → sale empujada hacia abajo
|
||||
{W + CARD_WIDTH, Y_DEST + 15.0F, CARD_ANGLE_1, S * 0.15F, S, 0.0F, A, R * 1.1},
|
||||
// 2: Entra desde arriba. La 3 entra desde abajo → sale empujada hacia arriba
|
||||
{X_DEST + 30.0F, -CARD_HEIGHT, CARD_ANGLE_2, -S * 0.15F, -S, 0.0F, -A, -R * 0.9},
|
||||
// 3: Entra desde abajo. La 4 entra desde arriba-izquierda → sale empujada hacia abajo-derecha
|
||||
{X_DEST - 25.0F, H + CARD_HEIGHT, CARD_ANGLE_3, S * 0.8F, S * 0.6F, A * 0.5F, A * 0.4F, R},
|
||||
// 4: Entra desde arriba-izquierda. La 5 entra desde derecha-abajo → sale empujada hacia arriba-izquierda
|
||||
{-CARD_WIDTH * 0.5F, -CARD_HEIGHT, CARD_ANGLE_4, -S * 0.7F, -S * 0.5F, -A * 0.5F, -A * 0.3F, -R * 1.2},
|
||||
// 5: Entra desde la derecha-abajo. Última: sale hacia la izquierda suave (viento)
|
||||
{W + CARD_WIDTH, H * 0.6F, CARD_ANGLE_5, -S * 0.6F, -S * 0.1F, -A * 0.5F, 0.0F, -R * 0.7},
|
||||
};
|
||||
|
||||
// Inicializa los CardSprites
|
||||
for (int i = 0; i < TOTAL_SPRITES; ++i) {
|
||||
auto shadow_color = param.intro.shadow_color;
|
||||
auto sprite = std::make_unique<PathSprite>(shadow_texture);
|
||||
sprite->setWidth(SHADOW_SPRITE_WIDTH);
|
||||
sprite->setHeight(SHADOW_SPRITE_HEIGHT);
|
||||
sprite->setSpriteClip(0, 0, SHADOW_SPRITE_WIDTH, SHADOW_SPRITE_HEIGHT);
|
||||
sprite->getTexture()->setAlpha(shadow_color.a);
|
||||
shadow_sprites_.push_back(std::move(sprite));
|
||||
auto card = std::make_unique<CardSprite>(card_textures.at(i));
|
||||
card->setWidth(CARD_WIDTH);
|
||||
card->setHeight(CARD_HEIGHT);
|
||||
card->setSpriteClip(0, 0, CARD_WIDTH, CARD_HEIGHT);
|
||||
|
||||
const auto& cfg = CARD_CONFIGS[i];
|
||||
|
||||
// Posición de aterrizaje (centro)
|
||||
card->setLandingPosition(X_DEST, Y_DEST);
|
||||
|
||||
// Posición de entrada (borde de pantalla)
|
||||
card->setEntryPosition(cfg.entry_x, cfg.entry_y);
|
||||
|
||||
// Parámetros de entrada: zoom, ángulo, duración, easing
|
||||
card->setEntryParams(CARD_START_ZOOM, cfg.entry_angle, CARD_ENTRY_DURATION_S, easeOutBounce);
|
||||
|
||||
// Parámetros de salida
|
||||
card->setExitParams(cfg.exit_vx, cfg.exit_vy, cfg.exit_ax, cfg.exit_ay, cfg.exit_rotation);
|
||||
|
||||
// Sombra
|
||||
card->setShadowTexture(shadow_texture);
|
||||
card->setShadowOffset(SHADOW_OFFSET, SHADOW_OFFSET);
|
||||
|
||||
// Límites de pantalla
|
||||
card->setScreenBounds(param.game.width, param.game.height);
|
||||
|
||||
// Última tarjeta: gana algo de altura al salir (se la lleva el viento)
|
||||
if (i == TOTAL_SPRITES - 1) {
|
||||
card->setExitLift(1.2F, 0.15F); // Hasta zoom 1.2, a 0.15/s
|
||||
}
|
||||
|
||||
card_sprites_.push_back(std::move(card));
|
||||
}
|
||||
|
||||
const float S_X_DEST = X_DEST + DESP;
|
||||
const float S_Y_DEST = Y_DEST + DESP;
|
||||
|
||||
shadow_sprites_.at(0)->addPath(param.game.height + CARD_OFFSET_MARGIN, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_NORMAL, easeInOutExpo, 0.0F);
|
||||
shadow_sprites_.at(1)->addPath(-SHADOW_SPRITE_HEIGHT, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_NORMAL, easeOutBounce, 0.0F);
|
||||
shadow_sprites_.at(2)->addPath(-SHADOW_SPRITE_WIDTH, S_X_DEST, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_FAST, easeOutQuint, 0.0F);
|
||||
shadow_sprites_.at(3)->addPath(-SHADOW_SPRITE_HEIGHT, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_VERY_SLOW, easeInOutExpo, 0.0F);
|
||||
shadow_sprites_.at(4)->addPath(param.game.height, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_MEDIUM, easeOutElastic, 0.0F);
|
||||
shadow_sprites_.at(5)->addPath(param.game.width, S_X_DEST, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_SLOW, easeOutQuad, CARD_ANIM_DELAY_LONG_S);
|
||||
shadow_sprites_.at(5)->addPath(S_X_DEST, param.game.width, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_SHORT, easeInElastic, 0.0F);
|
||||
}
|
||||
|
||||
// Inicializa los textos
|
||||
@@ -420,7 +448,7 @@ void Intro::initTexts() {
|
||||
|
||||
// Fins que un desaprensiu...
|
||||
texts_.at(2)->setCaption(Lang::getText("[INTRO] 3"));
|
||||
texts_.at(2)->setSpeedS(TEXT_SPEED_FAST);
|
||||
texts_.at(2)->setSpeedS(TEXT_SPEED_SLOW);
|
||||
|
||||
// HEY! ME ANE A FERME UN CORTAET...
|
||||
texts_.at(3)->setCaption(Lang::getText("[INTRO] 4"));
|
||||
@@ -428,23 +456,23 @@ void Intro::initTexts() {
|
||||
|
||||
// UAAAAAAAAAAAAA!!!
|
||||
texts_.at(4)->setCaption(Lang::getText("[INTRO] 5"));
|
||||
texts_.at(4)->setSpeedS(TEXT_SPEED_VERY_SLOW);
|
||||
texts_.at(4)->setSpeedS(TEXT_SPEED_ULTRA_FAST);
|
||||
|
||||
// Espera un moment...
|
||||
texts_.at(5)->setCaption(Lang::getText("[INTRO] 6"));
|
||||
texts_.at(5)->setSpeedS(TEXT_SPEED_VERY_FAST);
|
||||
texts_.at(5)->setSpeedS(TEXT_SPEED_VERY_SLOW);
|
||||
|
||||
// Si resulta que no tinc solt!
|
||||
texts_.at(6)->setCaption(Lang::getText("[INTRO] 7"));
|
||||
texts_.at(6)->setSpeedS(TEXT_SPEED_SLOW);
|
||||
texts_.at(6)->setSpeedS(TEXT_SPEED_VERY_FAST);
|
||||
|
||||
// MERDA DE MAQUINA!
|
||||
texts_.at(7)->setCaption(Lang::getText("[INTRO] 8"));
|
||||
texts_.at(7)->setSpeedS(TEXT_SPEED_MEDIUM_SLOW);
|
||||
texts_.at(7)->setSpeedS(TEXT_SPEED_FAST);
|
||||
|
||||
// Blop... blop... blop...
|
||||
texts_.at(8)->setCaption(Lang::getText("[INTRO] 9"));
|
||||
texts_.at(8)->setSpeedS(TEXT_SPEED_ULTRA_FAST);
|
||||
texts_.at(8)->setSpeedS(TEXT_SPEED_ULTRA_SLOW);
|
||||
|
||||
for (auto& text : texts_) {
|
||||
text->center(param.game.game_area.center_x);
|
||||
@@ -456,10 +484,6 @@ void Intro::updateSprites(float delta_time) {
|
||||
for (auto& sprite : card_sprites_) {
|
||||
sprite->update(delta_time);
|
||||
}
|
||||
|
||||
for (auto& sprite : shadow_sprites_) {
|
||||
sprite->update(delta_time);
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza los textos
|
||||
@@ -469,10 +493,11 @@ void Intro::updateTexts(float delta_time) {
|
||||
}
|
||||
}
|
||||
|
||||
// Dibuja los sprites
|
||||
// Dibuja los sprites (todas las tarjetas activas, para que convivan la saliente y la entrante)
|
||||
void Intro::renderSprites() {
|
||||
shadow_sprites_.at(scene_)->render();
|
||||
card_sprites_.at(scene_)->render();
|
||||
for (auto& card : card_sprites_) {
|
||||
card->render();
|
||||
}
|
||||
}
|
||||
|
||||
// Dibuja los textos
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
#include <memory> // Para unique_ptr
|
||||
#include <vector> // Para vector
|
||||
|
||||
#include "card_sprite.hpp" // Para CardSprite
|
||||
#include "color.hpp" // Para Color
|
||||
#include "param.hpp" // Para Param, ParamIntro, param
|
||||
#include "path_sprite.hpp" // Para PathSprite
|
||||
#include "tiled_bg.hpp" // Para TiledBG
|
||||
#include "writer.hpp" // Para Writer
|
||||
|
||||
@@ -18,14 +18,11 @@
|
||||
//
|
||||
// Funcionalidades principales:
|
||||
// • Sistema de escenas secuencial: 6 escenas con transiciones automáticas
|
||||
// • Animaciones de tarjetas: efectos de entrada con diferentes tipos de easing
|
||||
// • Animaciones de tarjetas: efecto de lanzamiento sobre mesa con zoom, rotación y rebote
|
||||
// • Texto narrativo: velocidades de escritura configurables por escena
|
||||
// • Efectos visuales: sombras, bordes y transiciones de color
|
||||
// • Audio sincronizado: música de fondo durante toda la secuencia
|
||||
// • Estado POST: transición suave hacia el menú principal
|
||||
//
|
||||
// Todas las duraciones y velocidades están configuradas mediante constantes
|
||||
// para facilitar el ajuste fino de la experiencia cinematográfica.
|
||||
|
||||
class Intro {
|
||||
public:
|
||||
@@ -38,9 +35,14 @@ class Intro {
|
||||
|
||||
private:
|
||||
// --- Constantes de tiempo (en segundos) ---
|
||||
static constexpr float TEXT_DISPLAY_DURATION_S = 3.0F; // Duración de visualización de texto (180 frames a 60fps)
|
||||
static constexpr float TEXT_DISPLAY_DURATION_S = 3.0F; // Duración de visualización de texto
|
||||
static constexpr float POST_BG_STOP_DELAY_S = 1.0F; // Retraso antes de detener el fondo
|
||||
static constexpr float POST_END_DELAY_S = 1.0F; // Retraso antes de finalizar intro
|
||||
static constexpr float INITIAL_DELAY_S = 2.0F; // Pausa antes de empezar las escenas
|
||||
|
||||
// --- Constantes de sonido ---
|
||||
static constexpr const char* SFX_CARD_THROW = "service_menu_select.wav"; // Sonido al lanzar una tarjeta
|
||||
static constexpr const char* SFX_CARD_IMPACT = "player_collision.wav"; // Sonido al impactar en la mesa
|
||||
|
||||
// --- Constantes de layout ---
|
||||
static constexpr float CARD_BORDER_SIZE = 2.0F; // Tamaño del borde de tarjetas
|
||||
@@ -48,25 +50,29 @@ class Intro {
|
||||
static constexpr float TILED_BG_SPEED = 18.0F; // Velocidad del fondo mosaico (pixels/segundo)
|
||||
static constexpr int TEXT_KERNING = -2; // Espaciado entre caracteres
|
||||
|
||||
// --- Constantes de velocidades de texto (segundos entre caracteres) ---
|
||||
static constexpr float TEXT_SPEED_NORMAL = 0.133F; // Velocidad normal (8 frames * 16.67ms = 133ms)
|
||||
static constexpr float TEXT_SPEED_FAST = 0.2F; // Velocidad rápida (12 frames * 16.67ms = 200ms)
|
||||
static constexpr float TEXT_SPEED_VERY_SLOW = 0.0167F; // Velocidad muy lenta (1 frame * 16.67ms = 16.7ms)
|
||||
static constexpr float TEXT_SPEED_VERY_FAST = 0.267F; // Velocidad muy rápida (16 frames * 16.67ms = 267ms)
|
||||
static constexpr float TEXT_SPEED_SLOW = 0.033F; // Velocidad lenta (2 frames * 16.67ms = 33ms)
|
||||
static constexpr float TEXT_SPEED_MEDIUM_SLOW = 0.05F; // Velocidad medio-lenta (3 frames * 16.67ms = 50ms)
|
||||
static constexpr float TEXT_SPEED_ULTRA_FAST = 0.333F; // Velocidad ultra rápida (20 frames * 16.67ms = 333ms)
|
||||
// --- Constantes de velocidades de texto (segundos entre caracteres, menor = más rápido) ---
|
||||
static constexpr float TEXT_SPEED_ULTRA_FAST = 0.0167F; // Ultra rápida (1 frame a 60fps)
|
||||
static constexpr float TEXT_SPEED_VERY_FAST = 0.033F; // Muy rápida (2 frames a 60fps)
|
||||
static constexpr float TEXT_SPEED_FAST = 0.05F; // Rápida (3 frames a 60fps)
|
||||
static constexpr float TEXT_SPEED_NORMAL = 0.133F; // Normal (8 frames a 60fps)
|
||||
static constexpr float TEXT_SPEED_SLOW = 0.2F; // Lenta (12 frames a 60fps)
|
||||
static constexpr float TEXT_SPEED_VERY_SLOW = 0.267F; // Muy lenta (16 frames a 60fps)
|
||||
static constexpr float TEXT_SPEED_ULTRA_SLOW = 0.333F; // Ultra lenta (20 frames a 60fps)
|
||||
|
||||
// --- Constantes de animaciones de tarjetas (duraciones en segundos) ---
|
||||
static constexpr float CARD_ANIM_DURATION_NORMAL = 100.0F / 60.0F; // ≈ 1.6667 s
|
||||
static constexpr float CARD_ANIM_DURATION_FAST = 40.0F / 60.0F; // ≈ 0.6667 s
|
||||
static constexpr float CARD_ANIM_DURATION_MEDIUM = 70.0F / 60.0F; // ≈ 1.1667 s
|
||||
static constexpr float CARD_ANIM_DURATION_SHORT = 80.0F / 60.0F; // ≈ 1.3333 s
|
||||
static constexpr float CARD_ANIM_DURATION_SLOW = 250.0F / 60.0F; // ≈ 4.1667 s
|
||||
static constexpr float CARD_ANIM_DURATION_VERY_SLOW = 300.0F / 60.0F; // ≈ 5.0000 s
|
||||
// --- Constantes de animaciones de tarjetas ---
|
||||
static constexpr float CARD_ENTRY_DURATION_S = 1.5F; // Duración de la animación de entrada
|
||||
static constexpr float CARD_START_ZOOM = 1.8F; // Zoom inicial (como si estuviera cerca)
|
||||
static constexpr float CARD_EXIT_SPEED = 400.0F; // Velocidad base de salida (pixels/s)
|
||||
static constexpr float CARD_EXIT_ACCEL = 200.0F; // Aceleración de salida (pixels/s²)
|
||||
static constexpr double CARD_EXIT_ROTATION = 450.0; // Velocidad de rotación en salida (grados/s)
|
||||
|
||||
static constexpr float CARD_ANIM_DELAY_LONG_S = 7.5F; // Retraso largo antes de animación
|
||||
static constexpr float CARD_OFFSET_MARGIN = 10.0F; // Margen fuera de pantalla
|
||||
// --- Ángulos iniciales de entrada por tarjeta (grados) ---
|
||||
static constexpr double CARD_ANGLE_0 = 12.0;
|
||||
static constexpr double CARD_ANGLE_1 = -15.0;
|
||||
static constexpr double CARD_ANGLE_2 = 8.0;
|
||||
static constexpr double CARD_ANGLE_3 = -10.0;
|
||||
static constexpr double CARD_ANGLE_4 = 18.0;
|
||||
static constexpr double CARD_ANGLE_5 = -7.0;
|
||||
|
||||
// --- Estados internos ---
|
||||
enum class State {
|
||||
@@ -80,18 +86,19 @@ class Intro {
|
||||
};
|
||||
|
||||
// --- Objetos ---
|
||||
std::vector<std::unique_ptr<PathSprite>> card_sprites_; // Vector con los sprites inteligentes para los dibujos de la intro
|
||||
std::vector<std::unique_ptr<PathSprite>> shadow_sprites_; // Vector con los sprites inteligentes para las sombras
|
||||
std::vector<std::unique_ptr<Writer>> texts_; // Textos de la intro
|
||||
std::unique_ptr<TiledBG> tiled_bg_; // Fondo en mosaico
|
||||
std::vector<std::unique_ptr<CardSprite>> card_sprites_; // Tarjetas animadas con sombra integrada
|
||||
std::vector<std::unique_ptr<Writer>> texts_; // Textos de la intro
|
||||
std::unique_ptr<TiledBG> tiled_bg_; // Fondo en mosaico
|
||||
|
||||
// --- Variables ---
|
||||
Uint64 last_time_ = 0; // Último timestamp para calcular delta-time
|
||||
int scene_ = 0; // Indica qué escena está activa
|
||||
State state_ = State::SCENES; // Estado principal de la intro
|
||||
PostState post_state_ = PostState::STOP_BG; // Estado POST
|
||||
float state_start_time_; // Tiempo de inicio del estado actual (segundos)
|
||||
float state_start_time_ = 0.0F; // Tiempo de inicio del estado actual (segundos)
|
||||
Color bg_color_ = param.intro.bg_color; // Color de fondo
|
||||
bool shake_done_ = false; // Evita shake repetido en la misma escena
|
||||
float initial_elapsed_ = 0.0F; // Tiempo acumulado antes de empezar
|
||||
|
||||
// --- Métodos internos ---
|
||||
void update(float delta_time); // Actualiza las variables del objeto
|
||||
@@ -99,13 +106,13 @@ class Intro {
|
||||
static void checkInput(); // Comprueba las entradas
|
||||
static void checkEvents(); // Comprueba los eventos
|
||||
void updateScenes(); // Actualiza las escenas de la intro
|
||||
void initSprites(); // Inicializa las imágenes
|
||||
void initSprites(); // Inicializa las tarjetas
|
||||
void initTexts(); // Inicializa los textos
|
||||
void updateSprites(float delta_time); // Actualiza los sprites
|
||||
void updateTexts(float delta_time); // Actualiza los textos
|
||||
void renderSprites(); // Dibuja los sprites
|
||||
void renderTexts(); // Dibuja los textos
|
||||
static void renderTextRect(); // Dibuja el rectangulo de fondo del texto;
|
||||
static void renderTextRect(); // Dibuja el rectángulo de fondo del texto
|
||||
void updatePostState(); // Actualiza el estado POST
|
||||
auto calculateDeltaTime() -> float; // Calcula el tiempo transcurrido desde el último frame
|
||||
|
||||
@@ -117,7 +124,6 @@ class Intro {
|
||||
void updateScene4();
|
||||
void updateScene5();
|
||||
|
||||
// --- Métodos auxiliares para reducir duplicación de código ---
|
||||
void enableCardAndShadow(int index);
|
||||
// --- Métodos auxiliares ---
|
||||
void switchText(int from_index, int to_index);
|
||||
};
|
||||
|
||||
@@ -30,11 +30,6 @@
|
||||
|
||||
class Texture;
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include <iomanip> // Para operator<<, setfill, setw
|
||||
#include <iostream> // Para basic_ostream, basic_ostream::operator<<, operator<<, cout, hex
|
||||
#endif
|
||||
|
||||
// Constructor
|
||||
Title::Title()
|
||||
: text_(Resource::get()->getText("smb2_grad")),
|
||||
@@ -43,12 +38,7 @@ Title::Title()
|
||||
game_logo_(std::make_unique<GameLogo>(param.game.game_area.center_x, param.title.title_c_c_position)),
|
||||
mini_logo_sprite_(std::make_unique<Sprite>(Resource::get()->getTexture("logo_jailgames_mini.png"))),
|
||||
state_(State::LOGO_ANIMATING),
|
||||
num_controllers_(Input::get()->getNumGamepads())
|
||||
#ifdef _DEBUG
|
||||
,
|
||||
debug_color_(param.title.bg_color)
|
||||
#endif
|
||||
{
|
||||
num_controllers_(Input::get()->getNumGamepads()) {
|
||||
// Configura objetos
|
||||
tiled_bg_->setColor(param.title.bg_color);
|
||||
tiled_bg_->setSpeed(0.0F);
|
||||
@@ -132,88 +122,9 @@ void Title::checkEvents() {
|
||||
}
|
||||
}
|
||||
|
||||
void Title::handleKeyDownEvent(const SDL_Event& event) {
|
||||
#ifdef _DEBUG
|
||||
bool is_repeat = static_cast<int>(event.key.repeat) == 1;
|
||||
if (is_repeat) {
|
||||
handleDebugColorKeys(event.key.key);
|
||||
}
|
||||
#endif
|
||||
void Title::handleKeyDownEvent(const SDL_Event& /*event*/) {
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
void Title::handleDebugColorKeys(SDL_Keycode key) {
|
||||
adjustColorComponent(key, debug_color_);
|
||||
|
||||
counter_time_ = 0.0F;
|
||||
tiled_bg_->setColor(debug_color_);
|
||||
printColorValue(debug_color_);
|
||||
}
|
||||
|
||||
void Title::adjustColorComponent(SDL_Keycode key, Color& color) {
|
||||
switch (key) {
|
||||
case SDLK_A:
|
||||
incrementColorComponent(color.r);
|
||||
break;
|
||||
case SDLK_Z:
|
||||
decrementColorComponent(color.r);
|
||||
break;
|
||||
case SDLK_S:
|
||||
incrementColorComponent(color.g);
|
||||
break;
|
||||
case SDLK_X:
|
||||
decrementColorComponent(color.g);
|
||||
break;
|
||||
case SDLK_D:
|
||||
incrementColorComponent(color.b);
|
||||
break;
|
||||
case SDLK_C:
|
||||
decrementColorComponent(color.b);
|
||||
break;
|
||||
case SDLK_F:
|
||||
incrementAllComponents(color);
|
||||
break;
|
||||
case SDLK_V:
|
||||
decrementAllComponents(color);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Title::incrementColorComponent(uint8_t& component) {
|
||||
if (component < 255) {
|
||||
++component;
|
||||
}
|
||||
}
|
||||
|
||||
void Title::decrementColorComponent(uint8_t& component) {
|
||||
if (component > 0) {
|
||||
--component;
|
||||
}
|
||||
}
|
||||
|
||||
void Title::incrementAllComponents(Color& color) {
|
||||
incrementColorComponent(color.r);
|
||||
incrementColorComponent(color.g);
|
||||
incrementColorComponent(color.b);
|
||||
}
|
||||
|
||||
void Title::decrementAllComponents(Color& color) {
|
||||
decrementColorComponent(color.r);
|
||||
decrementColorComponent(color.g);
|
||||
decrementColorComponent(color.b);
|
||||
}
|
||||
|
||||
void Title::printColorValue(const Color& color) {
|
||||
std::cout << "#"
|
||||
<< std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(color.r)
|
||||
<< std::setw(2) << std::setfill('0') << static_cast<int>(color.g)
|
||||
<< std::setw(2) << std::setfill('0') << static_cast<int>(color.b)
|
||||
<< '\n';
|
||||
}
|
||||
#endif
|
||||
|
||||
// Comprueba las entradas
|
||||
void Title::checkInput() {
|
||||
Input::get()->update();
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
|
||||
#include <SDL3/SDL.h> // Para SDL_Keycode, SDL_Event, Uint64
|
||||
|
||||
#include <cstdint> // Para uint8_t
|
||||
#include <memory> // Para shared_ptr, unique_ptr
|
||||
#include <string_view> // Para string_view
|
||||
#include <vector> // Para vector
|
||||
|
||||
#include "color.hpp" // for Color
|
||||
#include "player.hpp" // for Player
|
||||
#include "section.hpp" // for Options, Name (ptr only)
|
||||
|
||||
@@ -33,7 +31,6 @@ namespace Options {
|
||||
// • Efectos visuales: parpadeos, transiciones y efectos de fondo
|
||||
// • Gestión de controles: soporte para teclado y múltiples gamepads
|
||||
// • Timeouts automáticos: transición automática si no hay interacción
|
||||
// • Debug de colores: herramientas de depuración para ajustes visuales
|
||||
//
|
||||
// La clase utiliza un sistema de tiempo basado en segundos para garantizar
|
||||
// comportamiento consistente independientemente del framerate.
|
||||
@@ -101,10 +98,6 @@ class Title {
|
||||
bool player1_start_pressed_ = false; // Indica si se ha pulsado el botón de empezar para el jugador 1
|
||||
bool player2_start_pressed_ = false; // Indica si se ha pulsado el botón de empezar para el jugador 2
|
||||
|
||||
#ifdef _DEBUG
|
||||
Color debug_color_; // Color para depuración en modo debug
|
||||
#endif
|
||||
|
||||
// --- Ciclo de vida del título ---
|
||||
void update(float delta_time); // Actualiza las variables del objeto
|
||||
auto calculateDeltaTime() -> float; // Calcula el tiempo transcurrido desde el último frame
|
||||
@@ -142,15 +135,4 @@ class Title {
|
||||
static void swapControllers(); // Intercambia la asignación de mandos a los jugadores
|
||||
static void swapKeyboard(); // Intercambia el teclado de jugador
|
||||
static void showControllers(); // Muestra información sobre los controles y los jugadores
|
||||
|
||||
// --- Depuración (solo en modo DEBUG) ---
|
||||
#ifdef _DEBUG
|
||||
void handleDebugColorKeys(SDL_Keycode key); // Maneja las teclas de depuración para colores
|
||||
static void adjustColorComponent(SDL_Keycode key, Color& color); // Ajusta un componente del color según la tecla
|
||||
static void incrementColorComponent(uint8_t& component); // Incrementa un componente de color
|
||||
static void decrementColorComponent(uint8_t& component); // Decrementa un componente de color
|
||||
static void incrementAllComponents(Color& color); // Incrementa todos los componentes del color
|
||||
static void decrementAllComponents(Color& color); // Decrementa todos los componentes del color
|
||||
static void printColorValue(const Color& color); // Imprime el valor actual del color en consola
|
||||
#endif
|
||||
};
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
# Variables
|
||||
CXX := g++
|
||||
CXXFLAGS := -std=c++20 -Wall -Os -I../../
|
||||
CXXFLAGS := -std=c++20 -Wall -Os
|
||||
SOURCES := pack_resources.cpp ../../source/resource_pack.cpp
|
||||
TARGET := pack_resources
|
||||
CLEAN_FILES := pack_resources *.pack *.o
|
||||
@@ -21,7 +21,7 @@ else
|
||||
endif
|
||||
|
||||
# Reglas principales
|
||||
.PHONY: all pack_tool clean help test_pack
|
||||
.PHONY: all pack_tool pack clean help test_pack
|
||||
|
||||
# Compilar herramienta de empaquetado
|
||||
all: pack_tool
|
||||
@@ -37,6 +37,14 @@ clean:
|
||||
$(CLEAN_CMD) $(call FixPath,$(CLEAN_FILES))
|
||||
@echo "✓ Archivos limpiados"
|
||||
|
||||
# Crear pack de recursos final (invocado desde Makefile raíz)
|
||||
pack: pack_tool
|
||||
ifeq ($(OS),Windows_NT)
|
||||
.\$(TARGET) ..\..\data ..\..\resources.pack
|
||||
else
|
||||
./$(TARGET) ../../data ../../resources.pack
|
||||
endif
|
||||
|
||||
# Crear pack de recursos de prueba
|
||||
test_pack: pack_tool
|
||||
@echo "Creando pack de recursos de prueba..."
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "../source/resource_pack.hpp"
|
||||
#include "../build/version.h" // Para Version::APP_NAME
|
||||
#include "../../source/resource_pack.hpp"
|
||||
#include "../../build/version.h" // Para Version::APP_NAME
|
||||
#include <iostream>
|
||||
#include <filesystem>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user