Compare commits
12 Commits
f25cb96a91
...
2025-10-25
| Author | SHA1 | Date | |
|---|---|---|---|
| fa285519b2 | |||
| 8285a8fafe | |||
| 1a555e03f7 | |||
| af3ed6c2b3 | |||
| a9d7b66e83 | |||
| a929df6b73 | |||
| 3f027d953c | |||
| 1354ed82d2 | |||
| 2fd6d99a61 | |||
| 2fa1684f01 | |||
| 41c76316ef | |||
| ce50a29019 |
19
.gitignore
vendored
19
.gitignore
vendored
@@ -93,4 +93,21 @@ Thumbs.db
|
|||||||
*.temp
|
*.temp
|
||||||
|
|
||||||
# Claude Code
|
# Claude Code
|
||||||
.claude/
|
.claude/
|
||||||
|
|
||||||
|
# Archivos de recursos empaquetados
|
||||||
|
resources.pack
|
||||||
|
|
||||||
|
# Archivos de distribución (resultados de release)
|
||||||
|
*.zip
|
||||||
|
*.dmg
|
||||||
|
*.tar.gz
|
||||||
|
*.AppImage
|
||||||
|
|
||||||
|
# Carpetas temporales de empaquetado
|
||||||
|
vibe3_release/
|
||||||
|
Frameworks/
|
||||||
|
|
||||||
|
# Binarios de herramientas
|
||||||
|
tools/pack_resources
|
||||||
|
tools/*.exe
|
||||||
@@ -48,6 +48,9 @@ endif()
|
|||||||
# Incluir directorios de SDL3 y SDL3_ttf
|
# Incluir directorios de SDL3 y SDL3_ttf
|
||||||
include_directories(${SDL3_INCLUDE_DIRS} ${SDL3_ttf_INCLUDE_DIRS})
|
include_directories(${SDL3_INCLUDE_DIRS} ${SDL3_ttf_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
# Incluir directorio source/ para poder usar includes desde la raíz del proyecto
|
||||||
|
include_directories(${CMAKE_SOURCE_DIR}/source)
|
||||||
|
|
||||||
# Añadir el ejecutable reutilizando el nombre del proyecto
|
# Añadir el ejecutable reutilizando el nombre del proyecto
|
||||||
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
|
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
|
||||||
|
|
||||||
|
|||||||
93
Makefile
93
Makefile
@@ -42,8 +42,8 @@ endif
|
|||||||
|
|
||||||
# Nombres para los ficheros de lanzamiento
|
# Nombres para los ficheros de lanzamiento
|
||||||
WINDOWS_RELEASE := $(TARGET_NAME)-$(VERSION)-win32-x64.zip
|
WINDOWS_RELEASE := $(TARGET_NAME)-$(VERSION)-win32-x64.zip
|
||||||
MACOS_INTEL_RELEASE := $(TARGET_FILE)-$(VERSION)-macos-intel.dmg
|
MACOS_INTEL_RELEASE := $(TARGET_NAME)-$(VERSION)-macos-intel.dmg
|
||||||
MACOS_APPLE_SILICON_RELEASE := $(TARGET_FILE)-$(VERSION)-macos-apple-silicon.dmg
|
MACOS_APPLE_SILICON_RELEASE := $(TARGET_NAME)-$(VERSION)-macos-apple-silicon.dmg
|
||||||
LINUX_RELEASE := $(TARGET_FILE)-$(VERSION)-linux.tar.gz
|
LINUX_RELEASE := $(TARGET_FILE)-$(VERSION)-linux.tar.gz
|
||||||
RASPI_RELEASE := $(TARGET_FILE)-$(VERSION)-raspberry.tar.gz
|
RASPI_RELEASE := $(TARGET_FILE)-$(VERSION)-raspberry.tar.gz
|
||||||
|
|
||||||
@@ -121,6 +121,13 @@ resources.pack: $(PACK_TOOL) $(DATA_FILES)
|
|||||||
$(PACK_TOOL) data resources.pack
|
$(PACK_TOOL) data resources.pack
|
||||||
@echo "✓ resources.pack generado exitosamente"
|
@echo "✓ resources.pack generado exitosamente"
|
||||||
|
|
||||||
|
# Target para forzar regeneración de resources.pack (usado por releases)
|
||||||
|
.PHONY: force_resource_pack
|
||||||
|
force_resource_pack: $(PACK_TOOL)
|
||||||
|
@echo "Regenerando resources.pack para release..."
|
||||||
|
$(PACK_TOOL) data resources.pack
|
||||||
|
@echo "✓ resources.pack regenerado exitosamente"
|
||||||
|
|
||||||
# Reglas para compilación
|
# Reglas para compilación
|
||||||
windows:
|
windows:
|
||||||
@echo off
|
@echo off
|
||||||
@@ -139,7 +146,7 @@ windows_debug:
|
|||||||
@echo Compilando version debug para Windows: "$(APP_NAME)_debug.exe"
|
@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"
|
$(CXX) $(APP_SOURCES) $(INCLUDES) -DDEBUG -DVERBOSE $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(WIN_TARGET_FILE)_debug.exe"
|
||||||
|
|
||||||
windows_release: resources.pack
|
windows_release: force_resource_pack
|
||||||
@echo "Creando release para Windows - Version: $(VERSION)"
|
@echo "Creando release para Windows - Version: $(VERSION)"
|
||||||
|
|
||||||
# Crea carpeta temporal 'RELEASE_FOLDER'
|
# Crea carpeta temporal 'RELEASE_FOLDER'
|
||||||
@@ -175,15 +182,24 @@ macos_debug:
|
|||||||
@echo "Compilando version debug para macOS: $(TARGET_NAME)_debug"
|
@echo "Compilando version debug para macOS: $(TARGET_NAME)_debug"
|
||||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DDEBUG -DVERBOSE $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
$(CXX) $(APP_SOURCES) $(INCLUDES) -DDEBUG -DVERBOSE $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
||||||
|
|
||||||
macos_release: resources.pack
|
macos_release: force_resource_pack
|
||||||
@echo "Creando release para macOS - Version: $(VERSION)"
|
@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)
|
||||||
|
|
||||||
# Elimina datos de compilaciones anteriores
|
# Elimina datos de compilaciones anteriores
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
$(RMDIR) Frameworks
|
$(RMDIR) Frameworks
|
||||||
$(RMFILE) tmp.dmg
|
|
||||||
$(RMFILE) "$(MACOS_INTEL_RELEASE)"
|
$(RMFILE) "$(MACOS_INTEL_RELEASE)"
|
||||||
$(RMFILE) "$(MACOS_APPLE_SILICON_RELEASE)"
|
$(RMFILE) "$(MACOS_APPLE_SILICON_RELEASE)"
|
||||||
|
|
||||||
|
# Limpia archivos temporales de create-dmg y desmonta volúmenes
|
||||||
|
@echo "Limpiando archivos temporales y volúmenes montados..."
|
||||||
|
@rm -f rw.*.dmg 2>/dev/null || true
|
||||||
|
@hdiutil detach "/Volumes/$(APP_NAME)" 2>/dev/null || true
|
||||||
|
@hdiutil detach "/Volumes/ViBe3 Physics" 2>/dev/null || true
|
||||||
|
|
||||||
# Crea la carpeta temporal para hacer el trabajo y las carpetas obligatorias para crear una app de macos
|
# Crea la carpeta temporal para hacer el trabajo y las carpetas obligatorias para crear una app de macos
|
||||||
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
|
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
|
||||||
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS"
|
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS"
|
||||||
@@ -201,8 +217,8 @@ macos_release: resources.pack
|
|||||||
cp LICENSE "$(RELEASE_FOLDER)"
|
cp LICENSE "$(RELEASE_FOLDER)"
|
||||||
cp README.md "$(RELEASE_FOLDER)"
|
cp README.md "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
# Crea enlaces
|
# NOTA: create-dmg crea automáticamente el enlace a /Applications con --app-drop-link
|
||||||
ln -s /Applications "$(RELEASE_FOLDER)"/Applications
|
# No es necesario crearlo manualmente aquí
|
||||||
|
|
||||||
# Compila la versión para procesadores Intel
|
# Compila la versión para procesadores Intel
|
||||||
ifdef ENABLE_MACOS_X86_64
|
ifdef ENABLE_MACOS_X86_64
|
||||||
@@ -211,11 +227,28 @@ ifdef ENABLE_MACOS_X86_64
|
|||||||
# Firma la aplicación
|
# Firma la aplicación
|
||||||
codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app"
|
codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app"
|
||||||
|
|
||||||
# Empaqueta el .dmg de la versión Intel
|
# Empaqueta el .dmg de la versión Intel con create-dmg
|
||||||
hdiutil create tmp.dmg -ov -volname "$(APP_NAME)" -fs HFS+ -srcfolder "$(RELEASE_FOLDER)"
|
@echo "Creando DMG Intel con iconos de 96x96..."
|
||||||
hdiutil convert tmp.dmg -format UDZO -o "$(MACOS_INTEL_RELEASE)"
|
@create-dmg \
|
||||||
$(RMFILE) tmp.dmg
|
--volname "$(APP_NAME)" \
|
||||||
@echo "Release Intel creado: $(MACOS_INTEL_RELEASE)"
|
--window-pos 200 120 \
|
||||||
|
--window-size 720 300 \
|
||||||
|
--icon-size 96 \
|
||||||
|
--text-size 12 \
|
||||||
|
--icon "$(APP_NAME).app" 278 102 \
|
||||||
|
--icon "LICENSE" 441 102 \
|
||||||
|
--icon "README.md" 604 102 \
|
||||||
|
--app-drop-link 115 102 \
|
||||||
|
--hide-extension "$(APP_NAME).app" \
|
||||||
|
"$(MACOS_INTEL_RELEASE)" \
|
||||||
|
"$(RELEASE_FOLDER)"
|
||||||
|
@if [ -f "$(MACOS_INTEL_RELEASE)" ]; then \
|
||||||
|
echo "✓ Release Intel creado exitosamente: $(MACOS_INTEL_RELEASE)"; \
|
||||||
|
else \
|
||||||
|
echo "✗ Error: No se pudo crear el DMG Intel"; \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
|
@rm -f rw.*.dmg 2>/dev/null || true
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Compila la versión para procesadores Apple Silicon
|
# Compila la versión para procesadores Apple Silicon
|
||||||
@@ -224,11 +257,28 @@ endif
|
|||||||
# Firma la aplicación
|
# Firma la aplicación
|
||||||
codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app"
|
codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app"
|
||||||
|
|
||||||
# Empaqueta el .dmg de la versión Apple Silicon
|
# Empaqueta el .dmg de la versión Apple Silicon con create-dmg
|
||||||
hdiutil create tmp.dmg -ov -volname "$(APP_NAME)" -fs HFS+ -srcfolder "$(RELEASE_FOLDER)"
|
@echo "Creando DMG Apple Silicon con iconos de 96x96..."
|
||||||
hdiutil convert tmp.dmg -format UDZO -o "$(MACOS_APPLE_SILICON_RELEASE)"
|
@create-dmg \
|
||||||
$(RMFILE) tmp.dmg
|
--volname "$(APP_NAME)" \
|
||||||
@echo "Release Apple Silicon creado: $(MACOS_APPLE_SILICON_RELEASE)"
|
--window-pos 200 120 \
|
||||||
|
--window-size 720 300 \
|
||||||
|
--icon-size 96 \
|
||||||
|
--text-size 12 \
|
||||||
|
--icon "$(APP_NAME).app" 278 102 \
|
||||||
|
--icon "LICENSE" 441 102 \
|
||||||
|
--icon "README.md" 604 102 \
|
||||||
|
--app-drop-link 115 102 \
|
||||||
|
--hide-extension "$(APP_NAME).app" \
|
||||||
|
"$(MACOS_APPLE_SILICON_RELEASE)" \
|
||||||
|
"$(RELEASE_FOLDER)"
|
||||||
|
@if [ -f "$(MACOS_APPLE_SILICON_RELEASE)" ]; then \
|
||||||
|
echo "✓ Release Apple Silicon creado exitosamente: $(MACOS_APPLE_SILICON_RELEASE)"; \
|
||||||
|
else \
|
||||||
|
echo "✗ Error: No se pudo crear el DMG Apple Silicon"; \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
|
@rm -f rw.*.dmg 2>/dev/null || true
|
||||||
|
|
||||||
# Elimina las carpetas temporales
|
# Elimina las carpetas temporales
|
||||||
$(RMDIR) Frameworks
|
$(RMDIR) Frameworks
|
||||||
@@ -243,7 +293,7 @@ linux_debug:
|
|||||||
@echo "Compilando version debug para Linux: $(TARGET_NAME)_debug"
|
@echo "Compilando version debug para Linux: $(TARGET_NAME)_debug"
|
||||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DDEBUG -DVERBOSE $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
$(CXX) $(APP_SOURCES) $(INCLUDES) -DDEBUG -DVERBOSE $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
||||||
|
|
||||||
linux_release: resources.pack
|
linux_release: force_resource_pack
|
||||||
@echo "Creando release para Linux - Version: $(VERSION)"
|
@echo "Creando release para Linux - Version: $(VERSION)"
|
||||||
# Elimina carpetas previas
|
# Elimina carpetas previas
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
@@ -268,7 +318,7 @@ linux_release: resources.pack
|
|||||||
# Elimina la carpeta temporal
|
# Elimina la carpeta temporal
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
linux_release_desktop: resources.pack
|
linux_release_desktop: force_resource_pack
|
||||||
@echo "Creando release con integracion desktop para Linux - Version: $(VERSION)"
|
@echo "Creando release con integracion desktop para Linux - Version: $(VERSION)"
|
||||||
# Elimina carpetas previas
|
# Elimina carpetas previas
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
@@ -372,7 +422,7 @@ raspi_debug:
|
|||||||
@echo "Compilando version debug para Raspberry Pi: $(TARGET_NAME)_debug"
|
@echo "Compilando version debug para Raspberry Pi: $(TARGET_NAME)_debug"
|
||||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DVERBOSE -DDEBUG $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
$(CXX) $(APP_SOURCES) $(INCLUDES) -DVERBOSE -DDEBUG $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
||||||
|
|
||||||
raspi_release: resources.pack
|
raspi_release: force_resource_pack
|
||||||
@echo "Creando release para Raspberry Pi - Version: $(VERSION)"
|
@echo "Creando release para Raspberry Pi - Version: $(VERSION)"
|
||||||
# Elimina carpetas previas
|
# Elimina carpetas previas
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
@@ -397,7 +447,7 @@ raspi_release: resources.pack
|
|||||||
# Elimina la carpeta temporal
|
# Elimina la carpeta temporal
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
anbernic: resources.pack
|
anbernic: force_resource_pack
|
||||||
@echo "Compilando para Anbernic: $(TARGET_NAME)"
|
@echo "Compilando para Anbernic: $(TARGET_NAME)"
|
||||||
# Elimina carpetas previas
|
# Elimina carpetas previas
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"_anbernic
|
$(RMDIR) "$(RELEASE_FOLDER)"_anbernic
|
||||||
@@ -436,6 +486,7 @@ help:
|
|||||||
@echo " macos_release - Crear release completo para macOS (.dmg)"
|
@echo " macos_release - Crear release completo para macOS (.dmg)"
|
||||||
@echo " pack_tool - Compilar herramienta de empaquetado"
|
@echo " pack_tool - Compilar herramienta de empaquetado"
|
||||||
@echo " resources.pack - Generar pack de recursos desde data/"
|
@echo " resources.pack - Generar pack de recursos desde data/"
|
||||||
|
@echo " force_resource_pack - Regenerar resources.pack (usado por releases)"
|
||||||
@echo " show_version - Mostrar version actual ($(VERSION))"
|
@echo " show_version - Mostrar version actual ($(VERSION))"
|
||||||
@echo " help - Mostrar esta ayuda"
|
@echo " help - Mostrar esta ayuda"
|
||||||
|
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -1,6 +1,8 @@
|
|||||||
# ViBe3 Physics - Simulador de Sprites con Física Avanzada
|
# ViBe3 Physics - Simulador de Sprites con Física Avanzada
|
||||||
|
|
||||||
**ViBe3 Physics** es una demo experimental de **vibe-coding** que implementa **físicas avanzadas** con sistema de delta time independiente del framerate. Utiliza **SDL3** para renderizado optimizado con batch geometry de hasta 100,000 sprites simultáneos.
|
**ViBe3 Physics** es una demo experimental de **vibe-coding** que implementa **físicas avanzadas** con sistema de delta time independiente del framerate. Utiliza **SDL3** para renderizado optimizado con batch geometry de hasta 50,000 sprites simultáneos.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
El nombre refleja su propósito: **ViBe** (vibe-coding experimental) + **Physics** (nuevas físicas experimentales). La demo sirve como sandbox para probar bucles de juego con timing independiente, comportamientos emergentes (boids), figuras 3D procedurales y efectos demoscene.
|
El nombre refleja su propósito: **ViBe** (vibe-coding experimental) + **Physics** (nuevas físicas experimentales). La demo sirve como sandbox para probar bucles de juego con timing independiente, comportamientos emergentes (boids), figuras 3D procedurales y efectos demoscene.
|
||||||
|
|
||||||
@@ -154,6 +156,8 @@ Controlan el comportamiento físico de las pelotas:
|
|||||||
|
|
||||||
ViBe3 Physics incluye **15 temas visuales** organizados en **2 páginas** (9 estáticos + 1 dinámico en Página 1, 5 dinámicos en Página 2). Los temas dinámicos tienen animación de colores en tiempo real.
|
ViBe3 Physics incluye **15 temas visuales** organizados en **2 páginas** (9 estáticos + 1 dinámico en Página 1, 5 dinámicos en Página 2). Los temas dinámicos tienen animación de colores en tiempo real.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
### Controles de Temas
|
### Controles de Temas
|
||||||
|
|
||||||
- **`B`**: Ciclar entre TODOS los temas (adelante)
|
- **`B`**: Ciclar entre TODOS los temas (adelante)
|
||||||
@@ -407,8 +411,8 @@ vibe3_physics [opciones]
|
|||||||
|
|
||||||
### Validaciones
|
### Validaciones
|
||||||
|
|
||||||
- **Ancho mínimo**: 640px
|
- **Ancho mínimo**: 320px
|
||||||
- **Alto mínimo**: 480px
|
- **Alto mínimo**: 240px
|
||||||
- **Zoom automático**: Si resolución > pantalla, usa default
|
- **Zoom automático**: Si resolución > pantalla, usa default
|
||||||
- **Zoom máximo**: Ajustado según pantalla disponible
|
- **Zoom máximo**: Ajustado según pantalla disponible
|
||||||
|
|
||||||
|
|||||||
BIN
resources.pack
BIN
resources.pack
Binary file not shown.
@@ -1,12 +1,12 @@
|
|||||||
#include "app_logo.h"
|
#include "app_logo.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL_render.h> // for SDL_DestroyTexture, SDL_RenderGeometry, SDL_SetTextureAlphaMod
|
#include <SDL3/SDL_render.h> // for SDL_DestroyTexture, SDL_RenderGeometry, SDL_SetTextureAlphaMod
|
||||||
#include <cmath> // for powf, sinf, cosf
|
#include <cmath> // for powf, sinf, cosf
|
||||||
#include <cstdlib> // for free()
|
#include <cstdlib> // for free()
|
||||||
#include <iostream> // for std::cout
|
#include <iostream> // for std::cout
|
||||||
|
|
||||||
#include "logo_scaler.h" // for LogoScaler
|
#include "logo_scaler.hpp" // for LogoScaler
|
||||||
#include "defines.h" // for APPLOGO_HEIGHT_PERCENT, getResourcesDirectory
|
#include "defines.hpp" // for APPLOGO_HEIGHT_PERCENT, getResourcesDirectory
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Destructor - Liberar las 4 texturas SDL
|
// Destructor - Liberar las 4 texturas SDL
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include <memory> // for unique_ptr, shared_ptr
|
#include <memory> // for unique_ptr, shared_ptr
|
||||||
|
|
||||||
#include "defines.h" // for AppMode
|
#include "defines.hpp" // for AppMode
|
||||||
|
|
||||||
class Texture;
|
class Texture;
|
||||||
class Sprite;
|
class Sprite;
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
#include "ball.h"
|
#include "ball.hpp"
|
||||||
|
|
||||||
#include <stdlib.h> // for rand
|
#include <stdlib.h> // for rand
|
||||||
|
|
||||||
#include <cmath> // for fabs
|
#include <cmath> // for fabs
|
||||||
|
|
||||||
#include "defines.h" // for Color, SCREEN_HEIGHT, GRAVITY_FORCE
|
#include "defines.hpp" // for Color, SCREEN_HEIGHT, GRAVITY_FORCE
|
||||||
class Texture;
|
class Texture;
|
||||||
|
|
||||||
// Función auxiliar para generar pérdida aleatoria en rebotes
|
// Función auxiliar para generar pérdida aleatoria en rebotes
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
#include <memory> // for shared_ptr, unique_ptr
|
#include <memory> // for shared_ptr, unique_ptr
|
||||||
|
|
||||||
#include "defines.h" // for Color
|
#include "defines.hpp" // for Color
|
||||||
#include "external/sprite.h" // for Sprite
|
#include "external/sprite.hpp" // for Sprite
|
||||||
class Texture;
|
class Texture;
|
||||||
|
|
||||||
class Ball {
|
class Ball {
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
#include "boid_manager.h"
|
#include "boid_manager.hpp"
|
||||||
|
|
||||||
#include <algorithm> // for std::min, std::max
|
#include <algorithm> // for std::min, std::max
|
||||||
#include <cmath> // for sqrt, atan2
|
#include <cmath> // for sqrt, atan2
|
||||||
|
|
||||||
#include "../ball.h" // for Ball
|
#include "ball.hpp" // for Ball
|
||||||
#include "../engine.h" // for Engine (si se necesita)
|
#include "engine.hpp" // for Engine (si se necesita)
|
||||||
#include "../scene/scene_manager.h" // for SceneManager
|
#include "scene/scene_manager.hpp" // for SceneManager
|
||||||
#include "../state/state_manager.h" // for StateManager
|
#include "state/state_manager.hpp" // for StateManager
|
||||||
#include "../ui/ui_manager.h" // for UIManager
|
#include "ui/ui_manager.hpp" // for UIManager
|
||||||
|
|
||||||
BoidManager::BoidManager()
|
BoidManager::BoidManager()
|
||||||
: engine_(nullptr)
|
: engine_(nullptr)
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
#include <cstddef> // for size_t
|
#include <cstddef> // for size_t
|
||||||
|
|
||||||
#include "../defines.h" // for SimulationMode, AppMode
|
#include "defines.hpp" // for SimulationMode, AppMode
|
||||||
#include "../spatial_grid.h" // for SpatialGrid
|
#include "spatial_grid.hpp" // for SpatialGrid
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
class Engine;
|
class Engine;
|
||||||
@@ -8,9 +8,9 @@
|
|||||||
constexpr char WINDOW_CAPTION[] = "ViBe3 Physics (JailDesigner 2025)";
|
constexpr char WINDOW_CAPTION[] = "ViBe3 Physics (JailDesigner 2025)";
|
||||||
|
|
||||||
// Resolución por defecto (usada si no se especifica en CLI)
|
// Resolución por defecto (usada si no se especifica en CLI)
|
||||||
constexpr int DEFAULT_SCREEN_WIDTH = 320; // Ancho lógico por defecto (si no hay -w)
|
constexpr int DEFAULT_SCREEN_WIDTH = 1280; // Ancho lógico por defecto (si no hay -w)
|
||||||
constexpr int DEFAULT_SCREEN_HEIGHT = 240; // Alto lógico por defecto (si no hay -h)
|
constexpr int DEFAULT_SCREEN_HEIGHT = 720; // Alto lógico por defecto (si no hay -h)
|
||||||
constexpr int DEFAULT_WINDOW_ZOOM = 3; // Zoom inicial de ventana (1x = sin zoom)
|
constexpr int DEFAULT_WINDOW_ZOOM = 1; // Zoom inicial de ventana (1x = sin zoom)
|
||||||
|
|
||||||
// Configuración de zoom dinámico de ventana
|
// Configuración de zoom dinámico de ventana
|
||||||
constexpr int WINDOW_ZOOM_MIN = 1; // Zoom mínimo (320x240)
|
constexpr int WINDOW_ZOOM_MIN = 1; // Zoom mínimo (320x240)
|
||||||
@@ -22,7 +22,6 @@ constexpr int WINDOW_DECORATION_HEIGHT = 30; // Altura estimada de decoraciones
|
|||||||
constexpr float GRAVITY_FORCE = 0.2f; // Fuerza de gravedad (píxeles/frame²)
|
constexpr float GRAVITY_FORCE = 0.2f; // Fuerza de gravedad (píxeles/frame²)
|
||||||
|
|
||||||
// Configuración de interfaz
|
// Configuración de interfaz
|
||||||
constexpr Uint64 TEXT_DURATION = 2000; // Duración del texto informativo (ms) - OBSOLETO, usar NOTIFICATION_DURATION
|
|
||||||
constexpr float THEME_TRANSITION_DURATION = 0.5f; // Duración de transiciones LERP entre temas (segundos)
|
constexpr float THEME_TRANSITION_DURATION = 0.5f; // Duración de transiciones LERP entre temas (segundos)
|
||||||
|
|
||||||
// Configuración de notificaciones (sistema Notifier)
|
// Configuración de notificaciones (sistema Notifier)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "engine.h"
|
#include "engine.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL_error.h> // for SDL_GetError
|
#include <SDL3/SDL_error.h> // for SDL_GetError
|
||||||
#include <SDL3/SDL_events.h> // for SDL_Event, SDL_PollEvent
|
#include <SDL3/SDL_events.h> // for SDL_Event, SDL_PollEvent
|
||||||
@@ -17,22 +17,24 @@
|
|||||||
#include <iostream> // for cout
|
#include <iostream> // for cout
|
||||||
#include <string> // for string
|
#include <string> // for string
|
||||||
|
|
||||||
|
#include "resource_manager.hpp" // for ResourceManager
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h> // for GetModuleFileName
|
#include <windows.h> // for GetModuleFileName
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "ball.h" // for Ball
|
#include "ball.hpp" // for Ball
|
||||||
#include "external/mouse.h" // for Mouse namespace
|
#include "external/mouse.hpp" // for Mouse namespace
|
||||||
#include "external/texture.h" // for Texture
|
#include "external/texture.hpp" // for Texture
|
||||||
#include "shapes/atom_shape.h" // for AtomShape
|
#include "shapes/atom_shape.hpp" // for AtomShape
|
||||||
#include "shapes/cube_shape.h" // for CubeShape
|
#include "shapes/cube_shape.hpp" // for CubeShape
|
||||||
#include "shapes/cylinder_shape.h" // for CylinderShape
|
#include "shapes/cylinder_shape.hpp" // for CylinderShape
|
||||||
#include "shapes/helix_shape.h" // for HelixShape
|
#include "shapes/helix_shape.hpp" // for HelixShape
|
||||||
#include "shapes/icosahedron_shape.h" // for IcosahedronShape
|
#include "shapes/icosahedron_shape.hpp" // for IcosahedronShape
|
||||||
#include "shapes/lissajous_shape.h" // for LissajousShape
|
#include "shapes/lissajous_shape.hpp" // for LissajousShape
|
||||||
#include "shapes/png_shape.h" // for PNGShape
|
#include "shapes/png_shape.hpp" // for PNGShape
|
||||||
#include "shapes/sphere_shape.h" // for SphereShape
|
#include "shapes/sphere_shape.hpp" // for SphereShape
|
||||||
#include "shapes/torus_shape.h" // for TorusShape
|
#include "shapes/torus_shape.hpp" // for TorusShape
|
||||||
|
|
||||||
// getExecutableDirectory() ya está definido en defines.h como inline
|
// getExecutableDirectory() ya está definido en defines.h como inline
|
||||||
|
|
||||||
@@ -164,9 +166,9 @@ bool Engine::initialize(int width, int height, int zoom, bool fullscreen, AppMod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Fallback: cargar texturas desde pack usando la lista del ResourcePack
|
// Fallback: cargar texturas desde pack usando la lista del ResourceManager
|
||||||
if (Texture::isPackLoaded()) {
|
if (ResourceManager::isPackLoaded()) {
|
||||||
auto pack_resources = Texture::getPackResourceList();
|
auto pack_resources = ResourceManager::getResourceList();
|
||||||
|
|
||||||
// Filtrar solo los recursos en balls/ con extensión .png
|
// Filtrar solo los recursos en balls/ con extensión .png
|
||||||
for (const auto& resource : pack_resources) {
|
for (const auto& resource : pack_resources) {
|
||||||
@@ -235,7 +237,9 @@ bool Engine::initialize(int width, int height, int zoom, bool fullscreen, AppMod
|
|||||||
// Inicializar UIManager (HUD, FPS, notificaciones)
|
// Inicializar UIManager (HUD, FPS, notificaciones)
|
||||||
// NOTA: Debe llamarse DESPUÉS de calcular physical_window_* y ThemeManager
|
// NOTA: Debe llamarse DESPUÉS de calcular physical_window_* y ThemeManager
|
||||||
ui_manager_ = std::make_unique<UIManager>();
|
ui_manager_ = std::make_unique<UIManager>();
|
||||||
ui_manager_->initialize(renderer_, theme_manager_.get(), physical_window_width_, physical_window_height_);
|
ui_manager_->initialize(renderer_, theme_manager_.get(),
|
||||||
|
physical_window_width_, physical_window_height_,
|
||||||
|
current_screen_width_, current_screen_height_);
|
||||||
|
|
||||||
// Inicializar ShapeManager (gestión de figuras 3D)
|
// Inicializar ShapeManager (gestión de figuras 3D)
|
||||||
shape_manager_ = std::make_unique<ShapeManager>();
|
shape_manager_ = std::make_unique<ShapeManager>();
|
||||||
@@ -1502,21 +1506,7 @@ void Engine::executeRandomizeOnDemoStart(bool is_lite) {
|
|||||||
} else {
|
} else {
|
||||||
// DEMO COMPLETO: Randomizar TODO
|
// DEMO COMPLETO: Randomizar TODO
|
||||||
|
|
||||||
// 1. Escenario (excluir índices 0, 6, 7)
|
// 1. Física o Figura (decidir PRIMERO antes de cambiar escenario)
|
||||||
int valid_scenarios[] = {1, 2, 3, 4, 5};
|
|
||||||
int new_scenario = valid_scenarios[rand() % 5];
|
|
||||||
scene_manager_->changeScenario(new_scenario, current_mode_);
|
|
||||||
|
|
||||||
// 2. Tema (elegir entre TODOS los 15 temas)
|
|
||||||
int random_theme_index = rand() % 15;
|
|
||||||
theme_manager_->switchToTheme(random_theme_index);
|
|
||||||
|
|
||||||
// 3. Sprite
|
|
||||||
if (rand() % 2 == 0) {
|
|
||||||
switchTextureInternal(false); // Suprimir notificación al activar modo DEMO
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. Física o Figura
|
|
||||||
if (rand() % 2 == 0) {
|
if (rand() % 2 == 0) {
|
||||||
// Modo física
|
// Modo física
|
||||||
if (current_mode_ == SimulationMode::SHAPE) {
|
if (current_mode_ == SimulationMode::SHAPE) {
|
||||||
@@ -1525,20 +1515,83 @@ void Engine::executeRandomizeOnDemoStart(bool is_lite) {
|
|||||||
} else {
|
} else {
|
||||||
// Modo figura: elegir figura aleatoria (excluir PNG_SHAPE - es logo especial)
|
// Modo figura: elegir figura aleatoria (excluir PNG_SHAPE - es logo especial)
|
||||||
ShapeType shapes[] = {ShapeType::SPHERE, ShapeType::LISSAJOUS, ShapeType::HELIX, ShapeType::TORUS, ShapeType::CUBE, ShapeType::CYLINDER, ShapeType::ICOSAHEDRON, ShapeType::ATOM};
|
ShapeType shapes[] = {ShapeType::SPHERE, ShapeType::LISSAJOUS, ShapeType::HELIX, ShapeType::TORUS, ShapeType::CUBE, ShapeType::CYLINDER, ShapeType::ICOSAHEDRON, ShapeType::ATOM};
|
||||||
activateShapeInternal(shapes[rand() % 8]);
|
ShapeType selected_shape = shapes[rand() % 8];
|
||||||
|
|
||||||
// 5. Profundidad (solo si estamos en figura)
|
// Configurar figura SIN generar puntos (changeScenario lo hará después)
|
||||||
|
last_shape_type_ = selected_shape;
|
||||||
|
current_shape_type_ = selected_shape;
|
||||||
|
current_mode_ = SimulationMode::SHAPE;
|
||||||
|
|
||||||
|
// Crear instancia de la figura sin generar puntos todavía
|
||||||
|
switch (selected_shape) {
|
||||||
|
case ShapeType::SPHERE:
|
||||||
|
active_shape_ = std::make_unique<SphereShape>();
|
||||||
|
break;
|
||||||
|
case ShapeType::CUBE:
|
||||||
|
active_shape_ = std::make_unique<CubeShape>();
|
||||||
|
break;
|
||||||
|
case ShapeType::HELIX:
|
||||||
|
active_shape_ = std::make_unique<HelixShape>();
|
||||||
|
break;
|
||||||
|
case ShapeType::TORUS:
|
||||||
|
active_shape_ = std::make_unique<TorusShape>();
|
||||||
|
break;
|
||||||
|
case ShapeType::LISSAJOUS:
|
||||||
|
active_shape_ = std::make_unique<LissajousShape>();
|
||||||
|
break;
|
||||||
|
case ShapeType::CYLINDER:
|
||||||
|
active_shape_ = std::make_unique<CylinderShape>();
|
||||||
|
break;
|
||||||
|
case ShapeType::ICOSAHEDRON:
|
||||||
|
active_shape_ = std::make_unique<IcosahedronShape>();
|
||||||
|
break;
|
||||||
|
case ShapeType::ATOM:
|
||||||
|
active_shape_ = std::make_unique<AtomShape>();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
active_shape_ = std::make_unique<SphereShape>();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Profundidad (solo si estamos en figura)
|
||||||
if (rand() % 2 == 0) {
|
if (rand() % 2 == 0) {
|
||||||
depth_zoom_enabled_ = !depth_zoom_enabled_;
|
depth_zoom_enabled_ = !depth_zoom_enabled_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Escala de figura (aleatoria entre 0.5x y 2.0x)
|
// Escala de figura (aleatoria entre 0.5x y 2.0x)
|
||||||
shape_scale_factor_ = 0.5f + (rand() % 1500) / 1000.0f;
|
shape_scale_factor_ = 0.5f + (rand() % 1500) / 1000.0f;
|
||||||
clampShapeScale();
|
clampShapeScale();
|
||||||
generateShape();
|
|
||||||
|
// NOTA: NO llamar a generateShape() ni activar atracción aquí
|
||||||
|
// changeScenario() creará las pelotas y luego llamará a generateShape()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. Gravedad: dirección + ON/OFF
|
// 2. Escenario (excluir índices 0, 6, 7) - AHORA con current_mode_ ya establecido correctamente
|
||||||
|
int valid_scenarios[] = {1, 2, 3, 4, 5};
|
||||||
|
int new_scenario = valid_scenarios[rand() % 5];
|
||||||
|
scene_manager_->changeScenario(new_scenario, current_mode_);
|
||||||
|
|
||||||
|
// Si estamos en modo SHAPE, generar la figura y activar atracción
|
||||||
|
if (current_mode_ == SimulationMode::SHAPE) {
|
||||||
|
generateShape();
|
||||||
|
|
||||||
|
// Activar atracción física en las bolas nuevas
|
||||||
|
auto& balls = scene_manager_->getBallsMutable();
|
||||||
|
for (auto& ball : balls) {
|
||||||
|
ball->enableShapeAttraction(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Tema (elegir entre TODOS los 15 temas)
|
||||||
|
int random_theme_index = rand() % 15;
|
||||||
|
theme_manager_->switchToTheme(random_theme_index);
|
||||||
|
|
||||||
|
// 4. Sprite
|
||||||
|
if (rand() % 2 == 0) {
|
||||||
|
switchTextureInternal(false); // Suprimir notificación al activar modo DEMO
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Gravedad: dirección + ON/OFF
|
||||||
GravityDirection new_direction = static_cast<GravityDirection>(rand() % 4);
|
GravityDirection new_direction = static_cast<GravityDirection>(rand() % 4);
|
||||||
scene_manager_->changeGravityDirection(new_direction);
|
scene_manager_->changeGravityDirection(new_direction);
|
||||||
if (rand() % 3 == 0) { // 33% probabilidad de desactivar gravedad
|
if (rand() % 3 == 0) { // 33% probabilidad de desactivar gravedad
|
||||||
|
|||||||
@@ -10,18 +10,18 @@
|
|||||||
#include <string> // for string
|
#include <string> // for string
|
||||||
#include <vector> // for vector
|
#include <vector> // for vector
|
||||||
|
|
||||||
#include "app_logo.h" // for AppLogo
|
#include "app_logo.hpp" // for AppLogo
|
||||||
#include "ball.h" // for Ball
|
#include "ball.hpp" // for Ball
|
||||||
#include "boids_mgr/boid_manager.h" // for BoidManager
|
#include "boids_mgr/boid_manager.hpp" // for BoidManager
|
||||||
#include "defines.h" // for GravityDirection, ColorTheme, ShapeType
|
#include "defines.hpp" // for GravityDirection, ColorTheme, ShapeType
|
||||||
#include "external/texture.h" // for Texture
|
#include "external/texture.hpp" // for Texture
|
||||||
#include "input/input_handler.h" // for InputHandler
|
#include "input/input_handler.hpp" // for InputHandler
|
||||||
#include "scene/scene_manager.h" // for SceneManager
|
#include "scene/scene_manager.hpp" // for SceneManager
|
||||||
#include "shapes/shape.h" // for Shape (interfaz polimórfica)
|
#include "shapes/shape.hpp" // for Shape (interfaz polimórfica)
|
||||||
#include "shapes_mgr/shape_manager.h" // for ShapeManager
|
#include "shapes_mgr/shape_manager.hpp" // for ShapeManager
|
||||||
#include "state/state_manager.h" // for StateManager
|
#include "state/state_manager.hpp" // for StateManager
|
||||||
#include "theme_manager.h" // for ThemeManager
|
#include "theme_manager.hpp" // for ThemeManager
|
||||||
#include "ui/ui_manager.h" // for UIManager
|
#include "ui/ui_manager.hpp" // for UIManager
|
||||||
|
|
||||||
class Engine {
|
class Engine {
|
||||||
public:
|
public:
|
||||||
2
source/external/mouse.cpp
vendored
2
source/external/mouse.cpp
vendored
@@ -1,4 +1,4 @@
|
|||||||
#include "mouse.h"
|
#include "mouse.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_GetTicks, Uint32, SDL_HideCursor, SDL_ShowCursor
|
#include <SDL3/SDL.h> // Para SDL_GetTicks, Uint32, SDL_HideCursor, SDL_ShowCursor
|
||||||
|
|
||||||
|
|||||||
4
source/external/sprite.cpp
vendored
4
source/external/sprite.cpp
vendored
@@ -1,6 +1,6 @@
|
|||||||
#include "sprite.h"
|
#include "sprite.hpp"
|
||||||
|
|
||||||
#include "texture.h" // for Texture
|
#include "texture.hpp" // for Texture
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Sprite::Sprite(std::shared_ptr<Texture> texture)
|
Sprite::Sprite(std::shared_ptr<Texture> texture)
|
||||||
|
|||||||
68
source/external/texture.cpp
vendored
68
source/external/texture.cpp
vendored
@@ -1,5 +1,5 @@
|
|||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include "texture.h"
|
#include "texture.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL_error.h> // Para SDL_GetError
|
#include <SDL3/SDL_error.h> // Para SDL_GetError
|
||||||
#include <SDL3/SDL_log.h> // Para SDL_Log
|
#include <SDL3/SDL_log.h> // Para SDL_Log
|
||||||
@@ -12,38 +12,7 @@
|
|||||||
#include <string> // Para operator<<, string
|
#include <string> // Para operator<<, string
|
||||||
|
|
||||||
#include "stb_image.h" // Para stbi_failure_reason, stbi_image_free
|
#include "stb_image.h" // Para stbi_failure_reason, stbi_image_free
|
||||||
#include "../resource_pack.h" // Sistema de empaquetado de recursos
|
#include "resource_manager.hpp" // Sistema de empaquetado de recursos centralizado
|
||||||
|
|
||||||
// Instancia global de ResourcePack (se inicializa al primer uso)
|
|
||||||
static ResourcePack* g_resourcePack = nullptr;
|
|
||||||
|
|
||||||
// Inicializar el sistema de recursos (llamar desde main antes de cargar texturas)
|
|
||||||
void Texture::initResourceSystem(const std::string& packFilePath) {
|
|
||||||
if (g_resourcePack == nullptr) {
|
|
||||||
g_resourcePack = new ResourcePack();
|
|
||||||
if (!g_resourcePack->loadPack(packFilePath)) {
|
|
||||||
// Si falla, borrar instancia (usará fallback a disco)
|
|
||||||
delete g_resourcePack;
|
|
||||||
g_resourcePack = nullptr;
|
|
||||||
std::cout << "resources.pack no encontrado - usando carpeta data/" << std::endl;
|
|
||||||
} else {
|
|
||||||
std::cout << "resources.pack cargado (" << g_resourcePack->getResourceCount() << " recursos)" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtener lista de recursos disponibles en el pack
|
|
||||||
std::vector<std::string> Texture::getPackResourceList() {
|
|
||||||
if (g_resourcePack != nullptr) {
|
|
||||||
return g_resourcePack->getResourceList();
|
|
||||||
}
|
|
||||||
return std::vector<std::string>(); // Vacío si no hay pack
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verificar si el pack está cargado
|
|
||||||
bool Texture::isPackLoaded() {
|
|
||||||
return g_resourcePack != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Texture::Texture(SDL_Renderer *renderer)
|
Texture::Texture(SDL_Renderer *renderer)
|
||||||
: renderer_(renderer),
|
: renderer_(renderer),
|
||||||
@@ -70,30 +39,29 @@ bool Texture::loadFromFile(const std::string &file_path) {
|
|||||||
int width, height, orig_format;
|
int width, height, orig_format;
|
||||||
unsigned char *data = nullptr;
|
unsigned char *data = nullptr;
|
||||||
|
|
||||||
// 1. Intentar cargar desde pack (si está inicializado)
|
// 1. Intentar cargar desde ResourceManager (pack o disco)
|
||||||
if (g_resourcePack != nullptr) {
|
unsigned char* resourceData = nullptr;
|
||||||
ResourcePack::ResourceData packData = g_resourcePack->loadResource(file_path);
|
size_t resourceSize = 0;
|
||||||
if (packData.data != nullptr) {
|
|
||||||
// Descodificar imagen desde memoria usando stb_image
|
|
||||||
data = stbi_load_from_memory(packData.data, static_cast<int>(packData.size),
|
|
||||||
&width, &height, &orig_format, req_format);
|
|
||||||
delete[] packData.data; // Liberar buffer temporal del pack
|
|
||||||
|
|
||||||
if (data != nullptr) {
|
if (ResourceManager::loadResource(file_path, resourceData, resourceSize)) {
|
||||||
|
// Descodificar imagen desde memoria usando stb_image
|
||||||
|
data = stbi_load_from_memory(resourceData, static_cast<int>(resourceSize),
|
||||||
|
&width, &height, &orig_format, req_format);
|
||||||
|
delete[] resourceData; // Liberar buffer temporal
|
||||||
|
|
||||||
|
if (data != nullptr) {
|
||||||
|
if (ResourceManager::isPackLoaded()) {
|
||||||
std::cout << "Imagen cargada desde pack: " << filename.c_str() << std::endl;
|
std::cout << "Imagen cargada desde pack: " << filename.c_str() << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "Imagen cargada desde disco: " << filename.c_str() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Fallback: cargar desde disco (modo desarrollo)
|
// 2. Si todo falla, error
|
||||||
if (data == nullptr) {
|
if (data == nullptr) {
|
||||||
data = stbi_load(file_path.c_str(), &width, &height, &orig_format, req_format);
|
SDL_Log("Error al cargar la imagen: %s", stbi_failure_reason());
|
||||||
if (data == nullptr) {
|
exit(1);
|
||||||
SDL_Log("Error al cargar la imagen: %s", stbi_failure_reason());
|
|
||||||
exit(1);
|
|
||||||
} else {
|
|
||||||
std::cout << "Imagen cargada desde disco: " << filename.c_str() << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int pitch;
|
int pitch;
|
||||||
|
|||||||
@@ -16,11 +16,6 @@ class Texture {
|
|||||||
int height_;
|
int height_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Sistema de recursos empaquetados (inicializar desde main)
|
|
||||||
static void initResourceSystem(const std::string& packFilePath);
|
|
||||||
static std::vector<std::string> getPackResourceList();
|
|
||||||
static bool isPackLoaded();
|
|
||||||
|
|
||||||
// Inicializa las variables
|
// Inicializa las variables
|
||||||
explicit Texture(SDL_Renderer *renderer);
|
explicit Texture(SDL_Renderer *renderer);
|
||||||
Texture(SDL_Renderer *renderer, const std::string &file_path);
|
Texture(SDL_Renderer *renderer, const std::string &file_path);
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
#include "input_handler.h"
|
#include "input_handler.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL_keycode.h> // for SDL_Keycode
|
#include <SDL3/SDL_keycode.h> // for SDL_Keycode
|
||||||
#include <string> // for std::string, std::to_string
|
#include <string> // for std::string, std::to_string
|
||||||
|
|
||||||
#include "../engine.h" // for Engine
|
#include "engine.hpp" // for Engine
|
||||||
#include "../external/mouse.h" // for Mouse namespace
|
#include "external/mouse.hpp" // for Mouse namespace
|
||||||
|
|
||||||
bool InputHandler::processEvents(Engine& engine) {
|
bool InputHandler::processEvents(Engine& engine) {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#define STB_IMAGE_RESIZE_IMPLEMENTATION
|
#define STB_IMAGE_RESIZE_IMPLEMENTATION
|
||||||
#include "logo_scaler.h"
|
#include "logo_scaler.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL_error.h> // Para SDL_GetError
|
#include <SDL3/SDL_error.h> // Para SDL_GetError
|
||||||
#include <SDL3/SDL_log.h> // Para SDL_Log
|
#include <SDL3/SDL_log.h> // Para SDL_Log
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "external/stb_image.h" // Para stbi_load, stbi_image_free
|
#include "external/stb_image.h" // Para stbi_load, stbi_image_free
|
||||||
#include "external/stb_image_resize2.h" // Para stbir_resize_uint8_srgb
|
#include "external/stb_image_resize2.h" // Para stbir_resize_uint8_srgb
|
||||||
|
#include "resource_manager.hpp" // Para cargar desde pack
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Detectar resolución nativa del monitor principal
|
// Detectar resolución nativa del monitor principal
|
||||||
@@ -51,10 +52,22 @@ bool LogoScaler::detectNativeResolution(int& native_width, int& native_height) {
|
|||||||
unsigned char* LogoScaler::loadAndScale(const std::string& path,
|
unsigned char* LogoScaler::loadAndScale(const std::string& path,
|
||||||
int target_width, int target_height,
|
int target_width, int target_height,
|
||||||
int& out_width, int& out_height) {
|
int& out_width, int& out_height) {
|
||||||
// 1. Cargar imagen original con stb_image
|
// 1. Intentar cargar imagen desde ResourceManager (pack o disco)
|
||||||
int orig_width, orig_height, orig_channels;
|
int orig_width, orig_height, orig_channels;
|
||||||
unsigned char* orig_data = stbi_load(path.c_str(), &orig_width, &orig_height, &orig_channels, STBI_rgb_alpha);
|
unsigned char* orig_data = nullptr;
|
||||||
|
|
||||||
|
// 1a. Cargar desde ResourceManager
|
||||||
|
unsigned char* resourceData = nullptr;
|
||||||
|
size_t resourceSize = 0;
|
||||||
|
|
||||||
|
if (ResourceManager::loadResource(path, resourceData, resourceSize)) {
|
||||||
|
// Descodificar imagen desde memoria usando stb_image
|
||||||
|
orig_data = stbi_load_from_memory(resourceData, static_cast<int>(resourceSize),
|
||||||
|
&orig_width, &orig_height, &orig_channels, STBI_rgb_alpha);
|
||||||
|
delete[] resourceData; // Liberar buffer temporal
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1b. Si falla todo, error
|
||||||
if (orig_data == nullptr) {
|
if (orig_data == nullptr) {
|
||||||
SDL_Log("Error al cargar imagen %s: %s", path.c_str(), stbi_failure_reason());
|
SDL_Log("Error al cargar imagen %s: %s", path.c_str(), stbi_failure_reason());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "engine.h"
|
#include "engine.hpp"
|
||||||
#include "defines.h"
|
#include "defines.hpp"
|
||||||
|
#include "resource_manager.hpp"
|
||||||
|
|
||||||
// getExecutableDirectory() ya está definido en defines.h como inline
|
// getExecutableDirectory() ya está definido en defines.h como inline
|
||||||
|
|
||||||
@@ -45,8 +46,8 @@ int main(int argc, char* argv[]) {
|
|||||||
} else if (strcmp(argv[i], "-w") == 0 || strcmp(argv[i], "--width") == 0) {
|
} else if (strcmp(argv[i], "-w") == 0 || strcmp(argv[i], "--width") == 0) {
|
||||||
if (i + 1 < argc) {
|
if (i + 1 < argc) {
|
||||||
width = atoi(argv[++i]);
|
width = atoi(argv[++i]);
|
||||||
if (width < 640) {
|
if (width < 320) {
|
||||||
std::cerr << "Error: Ancho mínimo es 640px\n";
|
std::cerr << "Error: Ancho mínimo es 320\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -56,8 +57,8 @@ int main(int argc, char* argv[]) {
|
|||||||
} else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--height") == 0) {
|
} else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--height") == 0) {
|
||||||
if (i + 1 < argc) {
|
if (i + 1 < argc) {
|
||||||
height = atoi(argv[++i]);
|
height = atoi(argv[++i]);
|
||||||
if (height < 480) {
|
if (height < 240) {
|
||||||
std::cerr << "Error: Alto mínimo es 480px\n";
|
std::cerr << "Error: Alto mínimo es 240\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -108,7 +109,7 @@ int main(int argc, char* argv[]) {
|
|||||||
// Inicializar sistema de recursos empaquetados (intentar cargar resources.pack)
|
// Inicializar sistema de recursos empaquetados (intentar cargar resources.pack)
|
||||||
std::string resources_dir = getResourcesDirectory();
|
std::string resources_dir = getResourcesDirectory();
|
||||||
std::string pack_path = resources_dir + "/resources.pack";
|
std::string pack_path = resources_dir + "/resources.pack";
|
||||||
Texture::initResourceSystem(pack_path);
|
ResourceManager::init(pack_path);
|
||||||
|
|
||||||
Engine engine;
|
Engine engine;
|
||||||
|
|
||||||
|
|||||||
91
source/resource_manager.cpp
Normal file
91
source/resource_manager.cpp
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
#include "resource_manager.hpp"
|
||||||
|
#include "resource_pack.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
// Inicializar el puntero estático
|
||||||
|
ResourcePack* ResourceManager::resourcePack_ = nullptr;
|
||||||
|
|
||||||
|
bool ResourceManager::init(const std::string& packFilePath) {
|
||||||
|
// Si ya estaba inicializado, liberar primero
|
||||||
|
if (resourcePack_ != nullptr) {
|
||||||
|
delete resourcePack_;
|
||||||
|
resourcePack_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intentar cargar el pack
|
||||||
|
resourcePack_ = new ResourcePack();
|
||||||
|
if (!resourcePack_->loadPack(packFilePath)) {
|
||||||
|
// Si falla, borrar instancia (usará fallback a disco)
|
||||||
|
delete resourcePack_;
|
||||||
|
resourcePack_ = nullptr;
|
||||||
|
std::cout << "resources.pack no encontrado - usando carpeta data/" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "resources.pack cargado (" << resourcePack_->getResourceCount() << " recursos)" << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceManager::shutdown() {
|
||||||
|
if (resourcePack_ != nullptr) {
|
||||||
|
delete resourcePack_;
|
||||||
|
resourcePack_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResourceManager::loadResource(const std::string& resourcePath, unsigned char*& data, size_t& size) {
|
||||||
|
data = nullptr;
|
||||||
|
size = 0;
|
||||||
|
|
||||||
|
// 1. Intentar cargar desde pack (si está disponible)
|
||||||
|
if (resourcePack_ != nullptr) {
|
||||||
|
ResourcePack::ResourceData packData = resourcePack_->loadResource(resourcePath);
|
||||||
|
if (packData.data != nullptr) {
|
||||||
|
data = packData.data;
|
||||||
|
size = packData.size;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Fallback: cargar desde disco
|
||||||
|
std::ifstream file(resourcePath, std::ios::binary | std::ios::ate);
|
||||||
|
if (!file) {
|
||||||
|
// Intentar con "data/" como prefijo si no se encontró
|
||||||
|
std::string dataPath = "data/" + resourcePath;
|
||||||
|
file.open(dataPath, std::ios::binary | std::ios::ate);
|
||||||
|
if (!file) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtener tamaño del archivo
|
||||||
|
size = static_cast<size_t>(file.tellg());
|
||||||
|
file.seekg(0, std::ios::beg);
|
||||||
|
|
||||||
|
// Alocar buffer y leer
|
||||||
|
data = new unsigned char[size];
|
||||||
|
file.read(reinterpret_cast<char*>(data), size);
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResourceManager::isPackLoaded() {
|
||||||
|
return resourcePack_ != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> ResourceManager::getResourceList() {
|
||||||
|
if (resourcePack_ != nullptr) {
|
||||||
|
return resourcePack_->getResourceList();
|
||||||
|
}
|
||||||
|
return std::vector<std::string>(); // Vacío si no hay pack
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ResourceManager::getResourceCount() {
|
||||||
|
if (resourcePack_ != nullptr) {
|
||||||
|
return resourcePack_->getResourceCount();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
82
source/resource_manager.hpp
Normal file
82
source/resource_manager.hpp
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class ResourcePack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ResourceManager - Gestor centralizado de recursos empaquetados
|
||||||
|
*
|
||||||
|
* Singleton que administra el sistema de recursos empaquetados (resources.pack)
|
||||||
|
* y proporciona fallback automático a disco cuando el pack no está disponible.
|
||||||
|
*
|
||||||
|
* Uso:
|
||||||
|
* // En main.cpp, antes de inicializar cualquier sistema:
|
||||||
|
* ResourceManager::init("resources.pack");
|
||||||
|
*
|
||||||
|
* // Desde cualquier clase que necesite recursos:
|
||||||
|
* unsigned char* data = nullptr;
|
||||||
|
* size_t size = 0;
|
||||||
|
* if (ResourceManager::loadResource("textures/ball.png", data, size)) {
|
||||||
|
* // Usar datos...
|
||||||
|
* delete[] data; // Liberar cuando termine
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
class ResourceManager {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Inicializa el sistema de recursos empaquetados
|
||||||
|
* Debe llamarse una única vez al inicio del programa
|
||||||
|
*
|
||||||
|
* @param packFilePath Ruta al archivo .pack (ej: "resources.pack")
|
||||||
|
* @return true si el pack se cargó correctamente, false si no existe (fallback a disco)
|
||||||
|
*/
|
||||||
|
static bool init(const std::string& packFilePath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Libera el sistema de recursos
|
||||||
|
* Opcional - se llama automáticamente al cerrar el programa
|
||||||
|
*/
|
||||||
|
static void shutdown();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Carga un recurso desde el pack (o disco si no existe pack)
|
||||||
|
*
|
||||||
|
* @param resourcePath Ruta relativa del recurso (ej: "textures/ball.png")
|
||||||
|
* @param data [out] Puntero donde se almacenará el buffer (debe liberar con delete[])
|
||||||
|
* @param size [out] Tamaño del buffer en bytes
|
||||||
|
* @return true si se cargó correctamente, false si falla
|
||||||
|
*/
|
||||||
|
static bool loadResource(const std::string& resourcePath, unsigned char*& data, size_t& size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifica si el pack está cargado
|
||||||
|
* @return true si hay un pack cargado, false si se usa disco
|
||||||
|
*/
|
||||||
|
static bool isPackLoaded();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtiene la lista de recursos disponibles en el pack
|
||||||
|
* @return Vector con las rutas de todos los recursos, vacío si no hay pack
|
||||||
|
*/
|
||||||
|
static std::vector<std::string> getResourceList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtiene el número de recursos en el pack
|
||||||
|
* @return Número de recursos, 0 si no hay pack
|
||||||
|
*/
|
||||||
|
static size_t getResourceCount();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Constructor privado (singleton)
|
||||||
|
ResourceManager() = default;
|
||||||
|
~ResourceManager() = default;
|
||||||
|
|
||||||
|
// Deshabilitar copia y asignación
|
||||||
|
ResourceManager(const ResourceManager&) = delete;
|
||||||
|
ResourceManager& operator=(const ResourceManager&) = delete;
|
||||||
|
|
||||||
|
// Instancia del pack (nullptr si no está cargado)
|
||||||
|
static ResourcePack* resourcePack_;
|
||||||
|
};
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "resource_pack.h"
|
#include "resource_pack.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef RESOURCE_PACK_H
|
#pragma once
|
||||||
#define RESOURCE_PACK_H
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@@ -64,5 +63,3 @@ private:
|
|||||||
uint32_t calculateChecksum(const unsigned char* data, size_t size);
|
uint32_t calculateChecksum(const unsigned char* data, size_t size);
|
||||||
std::string normalizePath(const std::string& path);
|
std::string normalizePath(const std::string& path);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RESOURCE_PACK_H
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
#include "scene_manager.h"
|
#include "scene_manager.hpp"
|
||||||
|
|
||||||
#include <cstdlib> // for rand
|
#include <cstdlib> // for rand
|
||||||
|
|
||||||
#include "../defines.h" // for BALL_COUNT_SCENARIOS, GRAVITY_MASS_MIN, etc
|
#include "defines.hpp" // for BALL_COUNT_SCENARIOS, GRAVITY_MASS_MIN, etc
|
||||||
#include "../external/texture.h" // for Texture
|
#include "external/texture.hpp" // for Texture
|
||||||
#include "../theme_manager.h" // for ThemeManager
|
#include "theme_manager.hpp" // for ThemeManager
|
||||||
|
|
||||||
SceneManager::SceneManager(int screen_width, int screen_height)
|
SceneManager::SceneManager(int screen_width, int screen_height)
|
||||||
: current_gravity_(GravityDirection::DOWN)
|
: current_gravity_(GravityDirection::DOWN)
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
#include <memory> // for unique_ptr, shared_ptr
|
#include <memory> // for unique_ptr, shared_ptr
|
||||||
#include <vector> // for vector
|
#include <vector> // for vector
|
||||||
|
|
||||||
#include "../ball.h" // for Ball
|
#include "ball.hpp" // for Ball
|
||||||
#include "../defines.h" // for GravityDirection
|
#include "defines.hpp" // for GravityDirection
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
class Texture;
|
class Texture;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "atom_shape.h"
|
#include "atom_shape.hpp"
|
||||||
#include "../defines.h"
|
#include "defines.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
void AtomShape::generatePoints(int num_points, float screen_width, float screen_height) {
|
void AtomShape::generatePoints(int num_points, float screen_width, float screen_height) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "shape.h"
|
#include "shape.hpp"
|
||||||
|
|
||||||
// Figura: Átomo con núcleo central y órbitas electrónicas
|
// Figura: Átomo con núcleo central y órbitas electrónicas
|
||||||
// Comportamiento: Núcleo estático + electrones orbitando en planos inclinados
|
// Comportamiento: Núcleo estático + electrones orbitando en planos inclinados
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "cube_shape.h"
|
#include "cube_shape.hpp"
|
||||||
#include "../defines.h"
|
#include "defines.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
void CubeShape::generatePoints(int num_points, float screen_width, float screen_height) {
|
void CubeShape::generatePoints(int num_points, float screen_width, float screen_height) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "shape.h"
|
#include "shape.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// Figura: Cubo 3D rotante
|
// Figura: Cubo 3D rotante
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "cylinder_shape.h"
|
#include "cylinder_shape.hpp"
|
||||||
#include "../defines.h"
|
#include "defines.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib> // Para rand()
|
#include <cstdlib> // Para rand()
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "shape.h"
|
#include "shape.hpp"
|
||||||
|
|
||||||
// Figura: Cilindro 3D rotante
|
// Figura: Cilindro 3D rotante
|
||||||
// Comportamiento: Superficie cilíndrica con rotación en eje Y + tumbling ocasional en X/Z
|
// Comportamiento: Superficie cilíndrica con rotación en eje Y + tumbling ocasional en X/Z
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "helix_shape.h"
|
#include "helix_shape.hpp"
|
||||||
#include "../defines.h"
|
#include "defines.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
void HelixShape::generatePoints(int num_points, float screen_width, float screen_height) {
|
void HelixShape::generatePoints(int num_points, float screen_width, float screen_height) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "shape.h"
|
#include "shape.hpp"
|
||||||
|
|
||||||
// Figura: Espiral helicoidal 3D con distribución uniforme
|
// Figura: Espiral helicoidal 3D con distribución uniforme
|
||||||
// Comportamiento: Rotación en eje Y + animación de fase vertical
|
// Comportamiento: Rotación en eje Y + animación de fase vertical
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "icosahedron_shape.h"
|
#include "icosahedron_shape.hpp"
|
||||||
#include "../defines.h"
|
#include "defines.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "shape.h"
|
#include "shape.hpp"
|
||||||
|
|
||||||
// Figura: Icosaedro 3D (D20, poliedro regular de 20 caras)
|
// Figura: Icosaedro 3D (D20, poliedro regular de 20 caras)
|
||||||
// Comportamiento: 12 vértices distribuidos uniformemente con rotación triple
|
// Comportamiento: 12 vértices distribuidos uniformemente con rotación triple
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "lissajous_shape.h"
|
#include "lissajous_shape.hpp"
|
||||||
#include "../defines.h"
|
#include "defines.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
void LissajousShape::generatePoints(int num_points, float screen_width, float screen_height) {
|
void LissajousShape::generatePoints(int num_points, float screen_width, float screen_height) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "shape.h"
|
#include "shape.hpp"
|
||||||
|
|
||||||
// Figura: Curva de Lissajous 3D
|
// Figura: Curva de Lissajous 3D
|
||||||
// Comportamiento: Curva paramétrica 3D con rotación global y animación de fase
|
// Comportamiento: Curva paramétrica 3D con rotación global y animación de fase
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "png_shape.h"
|
#include "png_shape.hpp"
|
||||||
#include "../defines.h"
|
#include "defines.hpp"
|
||||||
#include "../external/stb_image.h"
|
#include "external/stb_image.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "shape.h"
|
#include "shape.hpp"
|
||||||
#include "../defines.h" // Para PNG_IDLE_TIME_MIN/MAX constantes
|
#include "defines.hpp" // Para PNG_IDLE_TIME_MIN/MAX constantes
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstdlib> // Para rand()
|
#include <cstdlib> // Para rand()
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "sphere_shape.h"
|
#include "sphere_shape.hpp"
|
||||||
#include "../defines.h"
|
#include "defines.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
void SphereShape::generatePoints(int num_points, float screen_width, float screen_height) {
|
void SphereShape::generatePoints(int num_points, float screen_width, float screen_height) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "shape.h"
|
#include "shape.hpp"
|
||||||
|
|
||||||
// Figura: Esfera 3D con distribución uniforme (Fibonacci Sphere Algorithm)
|
// Figura: Esfera 3D con distribución uniforme (Fibonacci Sphere Algorithm)
|
||||||
// Comportamiento: Rotación dual en ejes X e Y
|
// Comportamiento: Rotación dual en ejes X e Y
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "torus_shape.h"
|
#include "torus_shape.hpp"
|
||||||
#include "../defines.h"
|
#include "defines.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
void TorusShape::generatePoints(int num_points, float screen_width, float screen_height) {
|
void TorusShape::generatePoints(int num_points, float screen_width, float screen_height) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "shape.h"
|
#include "shape.hpp"
|
||||||
|
|
||||||
// Figura: Torus/Toroide 3D (donut/rosquilla)
|
// Figura: Torus/Toroide 3D (donut/rosquilla)
|
||||||
// Comportamiento: Superficie toroidal con rotación triple (X, Y, Z)
|
// Comportamiento: Superficie toroidal con rotación triple (X, Y, Z)
|
||||||
@@ -1,25 +1,25 @@
|
|||||||
#include "shape_manager.h"
|
#include "shape_manager.hpp"
|
||||||
|
|
||||||
#include <algorithm> // for std::min, std::max
|
#include <algorithm> // for std::min, std::max
|
||||||
#include <cstdlib> // for rand
|
#include <cstdlib> // for rand
|
||||||
#include <string> // for std::string
|
#include <string> // for std::string
|
||||||
|
|
||||||
#include "../ball.h" // for Ball
|
#include "ball.hpp" // for Ball
|
||||||
#include "../defines.h" // for constantes
|
#include "defines.hpp" // for constantes
|
||||||
#include "../scene/scene_manager.h" // for SceneManager
|
#include "scene/scene_manager.hpp" // for SceneManager
|
||||||
#include "../state/state_manager.h" // for StateManager
|
#include "state/state_manager.hpp" // for StateManager
|
||||||
#include "../ui/ui_manager.h" // for UIManager
|
#include "ui/ui_manager.hpp" // for UIManager
|
||||||
|
|
||||||
// Includes de todas las shapes (necesario para creación polimórfica)
|
// Includes de todas las shapes (necesario para creación polimórfica)
|
||||||
#include "../shapes/atom_shape.h"
|
#include "shapes/atom_shape.hpp"
|
||||||
#include "../shapes/cube_shape.h"
|
#include "shapes/cube_shape.hpp"
|
||||||
#include "../shapes/cylinder_shape.h"
|
#include "shapes/cylinder_shape.hpp"
|
||||||
#include "../shapes/helix_shape.h"
|
#include "shapes/helix_shape.hpp"
|
||||||
#include "../shapes/icosahedron_shape.h"
|
#include "shapes/icosahedron_shape.hpp"
|
||||||
#include "../shapes/lissajous_shape.h"
|
#include "shapes/lissajous_shape.hpp"
|
||||||
#include "../shapes/png_shape.h"
|
#include "shapes/png_shape.hpp"
|
||||||
#include "../shapes/sphere_shape.h"
|
#include "shapes/sphere_shape.hpp"
|
||||||
#include "../shapes/torus_shape.h"
|
#include "shapes/torus_shape.hpp"
|
||||||
|
|
||||||
ShapeManager::ShapeManager()
|
ShapeManager::ShapeManager()
|
||||||
: engine_(nullptr)
|
: engine_(nullptr)
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
#include <memory> // for unique_ptr
|
#include <memory> // for unique_ptr
|
||||||
|
|
||||||
#include "../defines.h" // for SimulationMode, ShapeType
|
#include "defines.hpp" // for SimulationMode, ShapeType
|
||||||
#include "../shapes/shape.h" // for Shape base class
|
#include "shapes/shape.hpp" // for Shape base class
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
class Engine;
|
class Engine;
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
#include "spatial_grid.h"
|
#include "spatial_grid.hpp"
|
||||||
|
|
||||||
#include <algorithm> // for std::max, std::min
|
#include <algorithm> // for std::max, std::min
|
||||||
#include <cmath> // for std::floor, std::ceil
|
#include <cmath> // for std::floor, std::ceil
|
||||||
|
|
||||||
#include "ball.h" // for Ball
|
#include "ball.hpp" // for Ball
|
||||||
|
|
||||||
SpatialGrid::SpatialGrid(int world_width, int world_height, float cell_size)
|
SpatialGrid::SpatialGrid(int world_width, int world_height, float cell_size)
|
||||||
: world_width_(world_width)
|
: world_width_(world_width)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef SPATIAL_GRID_H
|
#pragma once
|
||||||
#define SPATIAL_GRID_H
|
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -70,5 +69,3 @@ private:
|
|||||||
// Usamos unordered_map para O(1) lookup
|
// Usamos unordered_map para O(1) lookup
|
||||||
std::unordered_map<int, std::vector<Ball*>> cells_;
|
std::unordered_map<int, std::vector<Ball*>> cells_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SPATIAL_GRID_H
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
#include "state_manager.h"
|
#include "state_manager.hpp"
|
||||||
|
|
||||||
#include <cstdlib> // for rand
|
#include <cstdlib> // for rand
|
||||||
|
|
||||||
#include "../defines.h" // for constantes DEMO/LOGO
|
#include "defines.hpp" // for constantes DEMO/LOGO
|
||||||
#include "../engine.h" // for Engine (callbacks)
|
#include "engine.hpp" // for Engine (callbacks)
|
||||||
#include "../shapes/png_shape.h" // for PNGShape flip detection
|
#include "shapes/png_shape.hpp" // for PNGShape flip detection
|
||||||
|
|
||||||
StateManager::StateManager()
|
StateManager::StateManager()
|
||||||
: engine_(nullptr)
|
: engine_(nullptr)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <SDL3/SDL_stdinc.h> // for Uint64
|
#include <SDL3/SDL_stdinc.h> // for Uint64
|
||||||
#include <cstddef> // for size_t
|
#include <cstddef> // for size_t
|
||||||
|
|
||||||
#include "../defines.h" // for AppMode, ShapeType, GravityDirection
|
#include "defines.hpp" // for AppMode, ShapeType, GravityDirection
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
class Engine;
|
class Engine;
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
#include "textrenderer.h"
|
#include "textrenderer.hpp"
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <SDL3_ttf/SDL_ttf.h>
|
#include <SDL3_ttf/SDL_ttf.h>
|
||||||
|
#include "resource_manager.hpp"
|
||||||
|
|
||||||
TextRenderer::TextRenderer() : renderer_(nullptr), font_(nullptr), font_size_(0), use_antialiasing_(true) {
|
TextRenderer::TextRenderer() : renderer_(nullptr), font_(nullptr), font_size_(0), use_antialiasing_(true), font_data_buffer_(nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextRenderer::~TextRenderer() {
|
TextRenderer::~TextRenderer() {
|
||||||
@@ -23,7 +24,34 @@ bool TextRenderer::init(SDL_Renderer* renderer, const char* font_path, int font_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cargar la fuente
|
// Intentar cargar la fuente desde ResourceManager (pack o disco)
|
||||||
|
unsigned char* fontData = nullptr;
|
||||||
|
size_t fontDataSize = 0;
|
||||||
|
|
||||||
|
if (ResourceManager::loadResource(font_path, fontData, fontDataSize)) {
|
||||||
|
// Crear SDL_IOStream desde memoria
|
||||||
|
SDL_IOStream* fontIO = SDL_IOFromConstMem(fontData, static_cast<size_t>(fontDataSize));
|
||||||
|
if (fontIO != nullptr) {
|
||||||
|
// Cargar fuente desde IOStream
|
||||||
|
font_ = TTF_OpenFontIO(fontIO, true, font_size); // true = cerrar stream automáticamente
|
||||||
|
|
||||||
|
if (font_ == nullptr) {
|
||||||
|
SDL_Log("Error al cargar fuente desde memoria '%s': %s", font_path, SDL_GetError());
|
||||||
|
delete[] fontData; // Liberar solo si falla la carga
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CRÍTICO: NO eliminar fontData aquí - SDL_ttf necesita estos datos en memoria
|
||||||
|
// mientras la fuente esté abierta. Se liberará en cleanup()
|
||||||
|
font_data_buffer_ = fontData;
|
||||||
|
SDL_Log("Fuente cargada desde ResourceManager: %s (%lu bytes)", font_path, (unsigned long)fontDataSize);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
delete[] fontData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback final: intentar cargar directamente desde disco (por si falla ResourceManager)
|
||||||
font_ = TTF_OpenFont(font_path, font_size);
|
font_ = TTF_OpenFont(font_path, font_size);
|
||||||
if (font_ == nullptr) {
|
if (font_ == nullptr) {
|
||||||
SDL_Log("Error al cargar fuente '%s': %s", font_path, SDL_GetError());
|
SDL_Log("Error al cargar fuente '%s': %s", font_path, SDL_GetError());
|
||||||
@@ -45,13 +73,43 @@ bool TextRenderer::reinitialize(int new_font_size) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cerrar fuente actual
|
// Cerrar fuente actual y liberar buffer previo
|
||||||
if (font_ != nullptr) {
|
if (font_ != nullptr) {
|
||||||
TTF_CloseFont(font_);
|
TTF_CloseFont(font_);
|
||||||
font_ = nullptr;
|
font_ = nullptr;
|
||||||
}
|
}
|
||||||
|
if (font_data_buffer_ != nullptr) {
|
||||||
|
delete[] font_data_buffer_;
|
||||||
|
font_data_buffer_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Cargar fuente con nuevo tamaño
|
// Intentar cargar la fuente desde ResourceManager con el nuevo tamaño
|
||||||
|
unsigned char* fontData = nullptr;
|
||||||
|
size_t fontDataSize = 0;
|
||||||
|
|
||||||
|
if (ResourceManager::loadResource(font_path_, fontData, fontDataSize)) {
|
||||||
|
SDL_IOStream* fontIO = SDL_IOFromConstMem(fontData, static_cast<size_t>(fontDataSize));
|
||||||
|
if (fontIO != nullptr) {
|
||||||
|
font_ = TTF_OpenFontIO(fontIO, true, new_font_size);
|
||||||
|
|
||||||
|
if (font_ == nullptr) {
|
||||||
|
SDL_Log("Error al recargar fuente '%s' con tamaño %d: %s",
|
||||||
|
font_path_.c_str(), new_font_size, SDL_GetError());
|
||||||
|
delete[] fontData; // Liberar solo si falla
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mantener buffer en memoria (NO eliminar)
|
||||||
|
font_data_buffer_ = fontData;
|
||||||
|
font_size_ = new_font_size;
|
||||||
|
SDL_Log("Fuente recargada desde ResourceManager: %s (tamaño %d)", font_path_.c_str(), new_font_size);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
delete[] fontData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: cargar directamente desde disco
|
||||||
font_ = TTF_OpenFont(font_path_.c_str(), new_font_size);
|
font_ = TTF_OpenFont(font_path_.c_str(), new_font_size);
|
||||||
if (font_ == nullptr) {
|
if (font_ == nullptr) {
|
||||||
SDL_Log("Error al recargar fuente '%s' con tamaño %d: %s",
|
SDL_Log("Error al recargar fuente '%s' con tamaño %d: %s",
|
||||||
@@ -59,9 +117,7 @@ bool TextRenderer::reinitialize(int new_font_size) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualizar tamaño almacenado
|
|
||||||
font_size_ = new_font_size;
|
font_size_ = new_font_size;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,6 +126,10 @@ void TextRenderer::cleanup() {
|
|||||||
TTF_CloseFont(font_);
|
TTF_CloseFont(font_);
|
||||||
font_ = nullptr;
|
font_ = nullptr;
|
||||||
}
|
}
|
||||||
|
if (font_data_buffer_ != nullptr) {
|
||||||
|
delete[] font_data_buffer_;
|
||||||
|
font_data_buffer_ = nullptr;
|
||||||
|
}
|
||||||
renderer_ = nullptr;
|
renderer_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,4 +50,5 @@ private:
|
|||||||
int font_size_;
|
int font_size_;
|
||||||
bool use_antialiasing_;
|
bool use_antialiasing_;
|
||||||
std::string font_path_; // Almacenar ruta para reinitialize()
|
std::string font_path_; // Almacenar ruta para reinitialize()
|
||||||
|
unsigned char* font_data_buffer_; // Buffer de datos de fuente (mantener en memoria mientras esté abierta)
|
||||||
};
|
};
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "theme_manager.h"
|
#include "theme_manager.hpp"
|
||||||
|
|
||||||
#include "themes/static_theme.h"
|
#include "themes/static_theme.hpp"
|
||||||
#include "themes/dynamic_theme.h"
|
#include "themes/dynamic_theme.hpp"
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// INICIALIZACIÓN
|
// INICIALIZACIÓN
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
#include <memory> // for unique_ptr
|
#include <memory> // for unique_ptr
|
||||||
#include <vector> // for vector
|
#include <vector> // for vector
|
||||||
|
|
||||||
#include "ball.h" // for Ball class
|
#include "ball.hpp" // for Ball class
|
||||||
#include "defines.h" // for Color, ColorTheme
|
#include "defines.hpp" // for Color, ColorTheme
|
||||||
#include "themes/theme.h" // for Theme interface
|
#include "themes/theme.hpp" // for Theme interface
|
||||||
#include "themes/theme_snapshot.h" // for ThemeSnapshot
|
#include "themes/theme_snapshot.hpp" // for ThemeSnapshot
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ThemeManager: Gestiona el sistema de temas visuales (unificado, estáticos y dinámicos)
|
* ThemeManager: Gestiona el sistema de temas visuales (unificado, estáticos y dinámicos)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "dynamic_theme.h"
|
#include "dynamic_theme.hpp"
|
||||||
#include <algorithm> // for std::min
|
#include <algorithm> // for std::min
|
||||||
|
|
||||||
DynamicTheme::DynamicTheme(const char* name_en, const char* name_es,
|
DynamicTheme::DynamicTheme(const char* name_en, const char* name_es,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "theme.h"
|
#include "theme.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// Forward declaration (estructura definida en defines.h)
|
// Forward declaration (estructura definida en defines.h)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "static_theme.h"
|
#include "static_theme.hpp"
|
||||||
|
|
||||||
StaticTheme::StaticTheme(const char* name_en, const char* name_es,
|
StaticTheme::StaticTheme(const char* name_en, const char* name_es,
|
||||||
int text_r, int text_g, int text_b,
|
int text_r, int text_g, int text_b,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "theme.h"
|
#include "theme.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "../defines.h" // for Color, ThemeKeyframe
|
#include "defines.hpp" // for Color, ThemeKeyframe
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Theme: Interfaz polimórfica para todos los temas (estáticos y dinámicos)
|
* Theme: Interfaz polimórfica para todos los temas (estáticos y dinámicos)
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "../defines.h" // for Color
|
#include "defines.hpp" // for Color
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ThemeSnapshot: "Fotografía" del estado de un tema en un momento dado
|
* ThemeSnapshot: "Fotografía" del estado de un tema en un momento dado
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
#include "help_overlay.h"
|
#include "help_overlay.hpp"
|
||||||
|
|
||||||
#include <algorithm> // for std::min
|
#include <algorithm> // for std::min
|
||||||
|
|
||||||
#include "../text/textrenderer.h"
|
#include "text/textrenderer.hpp"
|
||||||
#include "../theme_manager.h"
|
#include "theme_manager.hpp"
|
||||||
|
|
||||||
HelpOverlay::HelpOverlay()
|
HelpOverlay::HelpOverlay()
|
||||||
: renderer_(nullptr),
|
: renderer_(nullptr),
|
||||||
@@ -28,7 +28,7 @@ HelpOverlay::HelpOverlay()
|
|||||||
// COLUMNA 1: SIMULACIÓN
|
// COLUMNA 1: SIMULACIÓN
|
||||||
{"SIMULACIÓN", ""},
|
{"SIMULACIÓN", ""},
|
||||||
{"1-8", "Escenarios (10 a 50,000 pelotas)"},
|
{"1-8", "Escenarios (10 a 50,000 pelotas)"},
|
||||||
{"F", "Toggle Física ↔ Última Figura"},
|
{"F", "Toggle Física - Última Figura"},
|
||||||
{"B", "Modo Boids (enjambre)"},
|
{"B", "Modo Boids (enjambre)"},
|
||||||
{"ESPACIO", "Impulso contra gravedad"},
|
{"ESPACIO", "Impulso contra gravedad"},
|
||||||
{"G", "Toggle Gravedad ON/OFF"},
|
{"G", "Toggle Gravedad ON/OFF"},
|
||||||
@@ -151,7 +151,8 @@ void HelpOverlay::calculateTextDimensions(int& max_width, int& total_height) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int line_height = text_renderer_->getTextHeight();
|
int line_height = text_renderer_->getTextHeight();
|
||||||
int padding = 25;
|
// Padding dinámico basado en altura física: 25px para >= 600px, escalado proporcionalmente para menores
|
||||||
|
int padding = (physical_height_ >= 600) ? 25 : std::max(10, physical_height_ / 24);
|
||||||
|
|
||||||
// Calcular ancho máximo por columna
|
// Calcular ancho máximo por columna
|
||||||
int max_col1_width = 0;
|
int max_col1_width = 0;
|
||||||
@@ -234,11 +235,11 @@ void HelpOverlay::calculateBoxDimensions() {
|
|||||||
int text_width, text_height;
|
int text_width, text_height;
|
||||||
calculateTextDimensions(text_width, text_height);
|
calculateTextDimensions(text_width, text_height);
|
||||||
|
|
||||||
// Usar directamente el ancho y altura calculados según el contenido
|
// Aplicar límites máximos: 95% ancho, 90% altura
|
||||||
box_width_ = text_width;
|
int max_width = static_cast<int>(physical_width_ * 0.95f);
|
||||||
|
int max_height = static_cast<int>(physical_height_ * 0.90f);
|
||||||
|
|
||||||
// Altura: 90% de altura física o altura calculada, el que sea menor
|
box_width_ = std::min(text_width, max_width);
|
||||||
int max_height = static_cast<int>(physical_height_ * 0.9f);
|
|
||||||
box_height_ = std::min(text_height, max_height);
|
box_height_ = std::min(text_height, max_height);
|
||||||
|
|
||||||
// Centrar en pantalla
|
// Centrar en pantalla
|
||||||
@@ -333,7 +334,8 @@ void HelpOverlay::rebuildCachedTexture() {
|
|||||||
|
|
||||||
// Configuración de espaciado
|
// Configuración de espaciado
|
||||||
int line_height = text_renderer_->getTextHeight();
|
int line_height = text_renderer_->getTextHeight();
|
||||||
int padding = 25;
|
// Padding dinámico basado en altura física: 25px para >= 600px, escalado proporcionalmente para menores
|
||||||
|
int padding = (physical_height_ >= 600) ? 25 : std::max(10, physical_height_ / 24);
|
||||||
|
|
||||||
int current_x = padding; // Coordenadas relativas a la textura (0,0)
|
int current_x = padding; // Coordenadas relativas a la textura (0,0)
|
||||||
int current_y = padding;
|
int current_y = padding;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include "notifier.h"
|
#include "notifier.hpp"
|
||||||
#include "../text/textrenderer.h"
|
#include "text/textrenderer.hpp"
|
||||||
#include "../theme_manager.h"
|
#include "theme_manager.hpp"
|
||||||
#include "../defines.h"
|
#include "defines.hpp"
|
||||||
#include "../utils/easing_functions.h"
|
#include "utils/easing_functions.hpp"
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
#include "ui_manager.h"
|
#include "ui_manager.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "../ball.h" // for Ball
|
#include "ball.hpp" // for Ball
|
||||||
#include "../defines.h" // for TEXT_DURATION, NOTIFICATION_DURATION, AppMode, SimulationMode
|
#include "defines.hpp" // for TEXT_DURATION, NOTIFICATION_DURATION, AppMode, SimulationMode
|
||||||
#include "../engine.h" // for Engine (info de sistema)
|
#include "engine.hpp" // for Engine (info de sistema)
|
||||||
#include "../scene/scene_manager.h" // for SceneManager
|
#include "scene/scene_manager.hpp" // for SceneManager
|
||||||
#include "../shapes/shape.h" // for Shape
|
#include "shapes/shape.hpp" // for Shape
|
||||||
#include "../text/textrenderer.h" // for TextRenderer
|
#include "text/textrenderer.hpp" // for TextRenderer
|
||||||
#include "../theme_manager.h" // for ThemeManager
|
#include "theme_manager.hpp" // for ThemeManager
|
||||||
#include "notifier.h" // for Notifier
|
#include "notifier.hpp" // for Notifier
|
||||||
#include "help_overlay.h" // for HelpOverlay
|
#include "help_overlay.hpp" // for HelpOverlay
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// HELPER: Obtener viewport en coordenadas físicas (no lógicas)
|
// HELPER: Obtener viewport en coordenadas físicas (no lógicas)
|
||||||
@@ -39,16 +39,11 @@ static SDL_Rect getPhysicalViewport(SDL_Renderer* renderer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
UIManager::UIManager()
|
UIManager::UIManager()
|
||||||
: text_renderer_(nullptr)
|
: text_renderer_debug_(nullptr)
|
||||||
, text_renderer_debug_(nullptr)
|
|
||||||
, text_renderer_notifier_(nullptr)
|
, text_renderer_notifier_(nullptr)
|
||||||
, notifier_(nullptr)
|
, notifier_(nullptr)
|
||||||
, help_overlay_(nullptr)
|
, help_overlay_(nullptr)
|
||||||
, show_debug_(false)
|
, show_debug_(false)
|
||||||
, show_text_(true)
|
|
||||||
, text_()
|
|
||||||
, text_pos_(0)
|
|
||||||
, text_init_time_(0)
|
|
||||||
, fps_last_time_(0)
|
, fps_last_time_(0)
|
||||||
, fps_frame_count_(0)
|
, fps_frame_count_(0)
|
||||||
, fps_current_(0)
|
, fps_current_(0)
|
||||||
@@ -58,12 +53,13 @@ UIManager::UIManager()
|
|||||||
, theme_manager_(nullptr)
|
, theme_manager_(nullptr)
|
||||||
, physical_window_width_(0)
|
, physical_window_width_(0)
|
||||||
, physical_window_height_(0)
|
, physical_window_height_(0)
|
||||||
|
, logical_window_width_(0)
|
||||||
|
, logical_window_height_(0)
|
||||||
, current_font_size_(18) { // Tamaño por defecto (medium)
|
, current_font_size_(18) { // Tamaño por defecto (medium)
|
||||||
}
|
}
|
||||||
|
|
||||||
UIManager::~UIManager() {
|
UIManager::~UIManager() {
|
||||||
// Limpieza: Los objetos creados con new deben ser eliminados
|
// Limpieza: Los objetos creados con new deben ser eliminados
|
||||||
delete text_renderer_;
|
|
||||||
delete text_renderer_debug_;
|
delete text_renderer_debug_;
|
||||||
delete text_renderer_notifier_;
|
delete text_renderer_notifier_;
|
||||||
delete notifier_;
|
delete notifier_;
|
||||||
@@ -71,22 +67,23 @@ UIManager::~UIManager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UIManager::initialize(SDL_Renderer* renderer, ThemeManager* theme_manager,
|
void UIManager::initialize(SDL_Renderer* renderer, ThemeManager* theme_manager,
|
||||||
int physical_width, int physical_height) {
|
int physical_width, int physical_height,
|
||||||
|
int logical_width, int logical_height) {
|
||||||
renderer_ = renderer;
|
renderer_ = renderer;
|
||||||
theme_manager_ = theme_manager;
|
theme_manager_ = theme_manager;
|
||||||
physical_window_width_ = physical_width;
|
physical_window_width_ = physical_width;
|
||||||
physical_window_height_ = physical_height;
|
physical_window_height_ = physical_height;
|
||||||
|
logical_window_width_ = logical_width;
|
||||||
|
logical_window_height_ = logical_height;
|
||||||
|
|
||||||
// Calcular tamaño de fuente apropiado según dimensiones físicas
|
// Calcular tamaño de fuente apropiado según dimensiones LÓGICAS (sin zoom)
|
||||||
current_font_size_ = calculateFontSize(physical_width, physical_height);
|
current_font_size_ = calculateFontSize(logical_height);
|
||||||
|
|
||||||
// Crear renderers de texto
|
// Crear renderers de texto
|
||||||
text_renderer_ = new TextRenderer();
|
|
||||||
text_renderer_debug_ = new TextRenderer();
|
text_renderer_debug_ = new TextRenderer();
|
||||||
text_renderer_notifier_ = new TextRenderer();
|
text_renderer_notifier_ = new TextRenderer();
|
||||||
|
|
||||||
// Inicializar renderers con tamaño dinámico
|
// Inicializar renderers con tamaño dinámico
|
||||||
text_renderer_->init(renderer, "data/fonts/FunnelSans-Regular.ttf", current_font_size_, true);
|
|
||||||
text_renderer_debug_->init(renderer, "data/fonts/FunnelSans-Regular.ttf", current_font_size_, true);
|
text_renderer_debug_->init(renderer, "data/fonts/FunnelSans-Regular.ttf", current_font_size_, true);
|
||||||
text_renderer_notifier_->init(renderer, "data/fonts/FunnelSans-Regular.ttf", current_font_size_, true);
|
text_renderer_notifier_->init(renderer, "data/fonts/FunnelSans-Regular.ttf", current_font_size_, true);
|
||||||
|
|
||||||
@@ -115,11 +112,6 @@ void UIManager::update(Uint64 current_time, float delta_time) {
|
|||||||
fps_text_ = "fps: " + std::to_string(fps_current_);
|
fps_text_ = "fps: " + std::to_string(fps_current_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualizar texto obsoleto (DEPRECATED)
|
|
||||||
if (show_text_) {
|
|
||||||
show_text_ = !(SDL_GetTicks() - text_init_time_ > TEXT_DURATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actualizar sistema de notificaciones
|
// Actualizar sistema de notificaciones
|
||||||
notifier_->update(current_time);
|
notifier_->update(current_time);
|
||||||
}
|
}
|
||||||
@@ -138,11 +130,6 @@ void UIManager::render(SDL_Renderer* renderer,
|
|||||||
physical_window_width_ = physical_width;
|
physical_window_width_ = physical_width;
|
||||||
physical_window_height_ = physical_height;
|
physical_window_height_ = physical_height;
|
||||||
|
|
||||||
// Renderizar texto obsoleto centrado (DEPRECATED - mantener temporalmente)
|
|
||||||
if (show_text_) {
|
|
||||||
renderObsoleteText(current_screen_width);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Renderizar debug HUD si está activo
|
// Renderizar debug HUD si está activo
|
||||||
if (show_debug_) {
|
if (show_debug_) {
|
||||||
renderDebugHUD(engine, scene_manager, current_mode, current_app_mode,
|
renderDebugHUD(engine, scene_manager, current_mode, current_app_mode,
|
||||||
@@ -183,17 +170,15 @@ void UIManager::updatePhysicalWindowSize(int width, int height) {
|
|||||||
physical_window_width_ = width;
|
physical_window_width_ = width;
|
||||||
physical_window_height_ = height;
|
physical_window_height_ = height;
|
||||||
|
|
||||||
// Calcular nuevo tamaño de fuente apropiado
|
// Calcular nuevo tamaño de fuente apropiado basado en altura LÓGICA
|
||||||
int new_font_size = calculateFontSize(width, height);
|
// (las dimensiones lógicas no cambian con zoom, solo con cambios explícitos de resolución)
|
||||||
|
int new_font_size = calculateFontSize(logical_window_height_);
|
||||||
|
|
||||||
// Si el tamaño cambió, reinicializar todos los text renderers
|
// Si el tamaño cambió, reinicializar todos los text renderers
|
||||||
if (new_font_size != current_font_size_) {
|
if (new_font_size != current_font_size_) {
|
||||||
current_font_size_ = new_font_size;
|
current_font_size_ = new_font_size;
|
||||||
|
|
||||||
// Reinicializar text renderers con nuevo tamaño
|
// Reinicializar text renderers con nuevo tamaño
|
||||||
if (text_renderer_) {
|
|
||||||
text_renderer_->reinitialize(current_font_size_);
|
|
||||||
}
|
|
||||||
if (text_renderer_debug_) {
|
if (text_renderer_debug_) {
|
||||||
text_renderer_debug_->reinitialize(current_font_size_);
|
text_renderer_debug_->reinitialize(current_font_size_);
|
||||||
}
|
}
|
||||||
@@ -211,13 +196,6 @@ void UIManager::updatePhysicalWindowSize(int width, int height) {
|
|||||||
notifier_->updateWindowSize(width, height);
|
notifier_->updateWindowSize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIManager::setTextObsolete(const std::string& text, int pos, int current_screen_width) {
|
|
||||||
text_ = text;
|
|
||||||
text_pos_ = pos;
|
|
||||||
text_init_time_ = SDL_GetTicks();
|
|
||||||
show_text_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// === Métodos privados ===
|
// === Métodos privados ===
|
||||||
|
|
||||||
void UIManager::renderDebugHUD(const Engine* engine,
|
void UIManager::renderDebugHUD(const Engine* engine,
|
||||||
@@ -424,27 +402,6 @@ void UIManager::renderDebugHUD(const Engine* engine,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIManager::renderObsoleteText(int current_screen_width) {
|
|
||||||
// DEPRECATED: Sistema antiguo de texto centrado
|
|
||||||
// Mantener por compatibilidad temporal hasta migrar todo a Notifier
|
|
||||||
|
|
||||||
// Calcular escala dinámica basada en resolución física
|
|
||||||
float text_scale_x = static_cast<float>(physical_window_width_) / 426.0f;
|
|
||||||
float text_scale_y = static_cast<float>(physical_window_height_) / 240.0f;
|
|
||||||
|
|
||||||
// Obtener color del tema actual (LERP interpolado)
|
|
||||||
int margin = 8;
|
|
||||||
Color text_color = theme_manager_->getInterpolatedColor(0);
|
|
||||||
int text_color_r = text_color.r;
|
|
||||||
int text_color_g = text_color.g;
|
|
||||||
int text_color_b = text_color.b;
|
|
||||||
|
|
||||||
// Renderizar texto centrado usando coordenadas físicas
|
|
||||||
text_renderer_->printPhysical(text_pos_, margin, text_.c_str(),
|
|
||||||
text_color_r, text_color_g, text_color_b,
|
|
||||||
text_scale_x, text_scale_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string UIManager::gravityDirectionToString(int direction) const {
|
std::string UIManager::gravityDirectionToString(int direction) const {
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case 0: return "Abajo"; // DOWN
|
case 0: return "Abajo"; // DOWN
|
||||||
@@ -455,20 +412,37 @@ std::string UIManager::gravityDirectionToString(int direction) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int UIManager::calculateFontSize(int physical_width, int physical_height) const {
|
int UIManager::calculateFontSize(int logical_height) const {
|
||||||
// Calcular área física de la ventana
|
// Escalado híbrido basado en ALTURA LÓGICA (resolución interna, sin zoom)
|
||||||
int area = physical_width * physical_height;
|
// Esto asegura que el tamaño de fuente sea consistente independientemente del zoom de ventana
|
||||||
|
// - Proporcional en extremos (muy bajo/alto)
|
||||||
|
// - Escalonado en rango medio (estabilidad)
|
||||||
|
|
||||||
// Stepped scaling con 3 tamaños:
|
int font_size = 14; // Default fallback
|
||||||
// - SMALL: < 800x600 (480,000 pixels) → 14px
|
|
||||||
// - MEDIUM: 800x600 a 1920x1080 (2,073,600 pixels) → 18px
|
|
||||||
// - LARGE: > 1920x1080 → 24px
|
|
||||||
|
|
||||||
if (area < 480000) {
|
if (logical_height < 300) {
|
||||||
return 14; // Ventanas pequeñas
|
// Rango bajo: proporcional (240px→9.6, 280px→11.2)
|
||||||
} else if (area < 2073600) {
|
font_size = logical_height / 25;
|
||||||
return 18; // Ventanas medianas (default)
|
} else if (logical_height < 380) {
|
||||||
|
// Rango muy bajo (300-379px) → 10px (crítico para 640x360)
|
||||||
|
font_size = 10;
|
||||||
|
} else if (logical_height < 500) {
|
||||||
|
// Rango medio-bajo (380-499px) → 12px
|
||||||
|
font_size = 12;
|
||||||
|
} else if (logical_height < 700) {
|
||||||
|
// Rango medio (500-699px) → 14px
|
||||||
|
font_size = 14;
|
||||||
|
} else if (logical_height < 900) {
|
||||||
|
// Rango medio-alto (700-899px) → 18px
|
||||||
|
font_size = 18;
|
||||||
} else {
|
} else {
|
||||||
return 24; // Ventanas grandes
|
// Rango alto: proporcional (1080px→42, 1440px→55, 2160px→72)
|
||||||
|
font_size = logical_height / 26;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Aplicar límites: mínimo 9px, máximo 72px
|
||||||
|
if (font_size < 9) font_size = 9;
|
||||||
|
if (font_size > 72) font_size = 72;
|
||||||
|
|
||||||
|
return font_size;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,9 +46,12 @@ class UIManager {
|
|||||||
* @param theme_manager Gestor de temas (para colores)
|
* @param theme_manager Gestor de temas (para colores)
|
||||||
* @param physical_width Ancho físico de ventana (píxeles reales)
|
* @param physical_width Ancho físico de ventana (píxeles reales)
|
||||||
* @param physical_height Alto físico de ventana (píxeles reales)
|
* @param physical_height Alto físico de ventana (píxeles reales)
|
||||||
|
* @param logical_width Ancho lógico (resolución interna)
|
||||||
|
* @param logical_height Alto lógico (resolución interna)
|
||||||
*/
|
*/
|
||||||
void initialize(SDL_Renderer* renderer, ThemeManager* theme_manager,
|
void initialize(SDL_Renderer* renderer, ThemeManager* theme_manager,
|
||||||
int physical_width, int physical_height);
|
int physical_width, int physical_height,
|
||||||
|
int logical_width, int logical_height);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Actualiza UI (FPS counter, notificaciones, texto obsoleto)
|
* @brief Actualiza UI (FPS counter, notificaciones, texto obsoleto)
|
||||||
@@ -111,14 +114,6 @@ class UIManager {
|
|||||||
*/
|
*/
|
||||||
void updatePhysicalWindowSize(int width, int height);
|
void updatePhysicalWindowSize(int width, int height);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Establece texto obsoleto (DEPRECATED - usar Notifier en su lugar)
|
|
||||||
* @param text Texto a mostrar
|
|
||||||
* @param pos Posición X del texto
|
|
||||||
* @param current_screen_width Ancho de pantalla (para cálculos)
|
|
||||||
*/
|
|
||||||
void setTextObsolete(const std::string& text, int pos, int current_screen_width);
|
|
||||||
|
|
||||||
// === Getters ===
|
// === Getters ===
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -131,11 +126,6 @@ class UIManager {
|
|||||||
*/
|
*/
|
||||||
int getCurrentFPS() const { return fps_current_; }
|
int getCurrentFPS() const { return fps_current_; }
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Verifica si texto obsoleto está visible
|
|
||||||
*/
|
|
||||||
bool isTextObsoleteVisible() const { return show_text_; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief Renderiza HUD de debug (solo si show_debug_ == true)
|
* @brief Renderiza HUD de debug (solo si show_debug_ == true)
|
||||||
@@ -153,12 +143,6 @@ class UIManager {
|
|||||||
const Shape* active_shape,
|
const Shape* active_shape,
|
||||||
float shape_convergence);
|
float shape_convergence);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Renderiza texto obsoleto centrado (DEPRECATED)
|
|
||||||
* @param current_screen_width Ancho lógico de pantalla
|
|
||||||
*/
|
|
||||||
void renderObsoleteText(int current_screen_width);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Convierte dirección de gravedad a string
|
* @brief Convierte dirección de gravedad a string
|
||||||
* @param direction Dirección como int (cast de GravityDirection)
|
* @param direction Dirección como int (cast de GravityDirection)
|
||||||
@@ -167,15 +151,13 @@ class UIManager {
|
|||||||
std::string gravityDirectionToString(int direction) const;
|
std::string gravityDirectionToString(int direction) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Calcula tamaño de fuente apropiado según dimensiones físicas
|
* @brief Calcula tamaño de fuente apropiado según dimensiones lógicas
|
||||||
* @param physical_width Ancho físico de ventana
|
* @param logical_height Alto lógico (resolución interna, sin zoom)
|
||||||
* @param physical_height Alto físico de ventana
|
* @return Tamaño de fuente (9-72px)
|
||||||
* @return Tamaño de fuente (14px/18px/24px)
|
|
||||||
*/
|
*/
|
||||||
int calculateFontSize(int physical_width, int physical_height) const;
|
int calculateFontSize(int logical_height) const;
|
||||||
|
|
||||||
// === Recursos de renderizado ===
|
// === Recursos de renderizado ===
|
||||||
TextRenderer* text_renderer_; // Texto obsoleto (DEPRECATED)
|
|
||||||
TextRenderer* text_renderer_debug_; // HUD de debug
|
TextRenderer* text_renderer_debug_; // HUD de debug
|
||||||
TextRenderer* text_renderer_notifier_; // Notificaciones
|
TextRenderer* text_renderer_notifier_; // Notificaciones
|
||||||
Notifier* notifier_; // Sistema de notificaciones
|
Notifier* notifier_; // Sistema de notificaciones
|
||||||
@@ -183,12 +165,6 @@ class UIManager {
|
|||||||
|
|
||||||
// === Estado de UI ===
|
// === Estado de UI ===
|
||||||
bool show_debug_; // HUD de debug activo (tecla F12)
|
bool show_debug_; // HUD de debug activo (tecla F12)
|
||||||
bool show_text_; // Texto obsoleto visible (DEPRECATED)
|
|
||||||
|
|
||||||
// === Sistema de texto obsoleto (DEPRECATED) ===
|
|
||||||
std::string text_; // Texto a mostrar
|
|
||||||
int text_pos_; // Posición X del texto
|
|
||||||
Uint64 text_init_time_; // Tiempo de inicio de texto
|
|
||||||
|
|
||||||
// === Sistema de FPS ===
|
// === Sistema de FPS ===
|
||||||
Uint64 fps_last_time_; // Último tiempo de actualización de FPS
|
Uint64 fps_last_time_; // Último tiempo de actualización de FPS
|
||||||
@@ -202,7 +178,9 @@ class UIManager {
|
|||||||
ThemeManager* theme_manager_; // Gestor de temas (para colores)
|
ThemeManager* theme_manager_; // Gestor de temas (para colores)
|
||||||
int physical_window_width_; // Ancho físico de ventana (píxeles reales)
|
int physical_window_width_; // Ancho físico de ventana (píxeles reales)
|
||||||
int physical_window_height_; // Alto físico de ventana (píxeles reales)
|
int physical_window_height_; // Alto físico de ventana (píxeles reales)
|
||||||
|
int logical_window_width_; // Ancho lógico (resolución interna)
|
||||||
|
int logical_window_height_; // Alto lógico (resolución interna)
|
||||||
|
|
||||||
// === Sistema de escalado dinámico de texto ===
|
// === Sistema de escalado dinámico de texto ===
|
||||||
int current_font_size_; // Tamaño de fuente actual (14/18/24)
|
int current_font_size_; // Tamaño de fuente actual (9-72px)
|
||||||
};
|
};
|
||||||
187
tools/Makefile
Normal file
187
tools/Makefile
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
# ============================================================================
|
||||||
|
# ViBe3 Physics - Resource Packer Tool Makefile
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# Directorios
|
||||||
|
DIR_ROOT := $(dir $(abspath $(dir $(MAKEFILE_LIST))))
|
||||||
|
DIR_SOURCES := $(DIR_ROOT)source/
|
||||||
|
DIR_TOOLS := $(DIR_ROOT)tools/
|
||||||
|
DIR_DATA := $(DIR_ROOT)data/
|
||||||
|
|
||||||
|
# Archivos fuente
|
||||||
|
PACK_SOURCES := $(DIR_TOOLS)pack_resources.cpp $(DIR_SOURCES)resource_pack.cpp
|
||||||
|
PACK_INCLUDES := -I$(DIR_ROOT)
|
||||||
|
|
||||||
|
# Compilador y flags
|
||||||
|
CXX := g++
|
||||||
|
CXXFLAGS := -std=c++17 -Wall -Os -ffunction-sections -fdata-sections
|
||||||
|
|
||||||
|
# Variables específicas por sistema operativo
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
# Windows
|
||||||
|
PACK_TOOL := pack_resources.exe
|
||||||
|
RESOURCE_PACK := ../resources.pack
|
||||||
|
TEST_PACK := test_resources.pack
|
||||||
|
LDFLAGS := -Wl,--gc-sections -static-libstdc++ -static-libgcc
|
||||||
|
RMFILE := del /Q
|
||||||
|
MKDIR := mkdir
|
||||||
|
FixPath = $(subst /,\,$1)
|
||||||
|
else
|
||||||
|
UNAME_S := $(shell uname -s)
|
||||||
|
ifeq ($(UNAME_S),Linux)
|
||||||
|
# Linux
|
||||||
|
PACK_TOOL := pack_resources
|
||||||
|
RESOURCE_PACK := ../resources.pack
|
||||||
|
TEST_PACK := test_resources.pack
|
||||||
|
LDFLAGS := -Wl,--gc-sections
|
||||||
|
RMFILE := rm -f
|
||||||
|
MKDIR := mkdir -p
|
||||||
|
FixPath = $1
|
||||||
|
endif
|
||||||
|
ifeq ($(UNAME_S),Darwin)
|
||||||
|
# macOS
|
||||||
|
PACK_TOOL := pack_resources
|
||||||
|
RESOURCE_PACK := ../resources.pack
|
||||||
|
TEST_PACK := test_resources.pack
|
||||||
|
LDFLAGS :=
|
||||||
|
RMFILE := rm -f
|
||||||
|
MKDIR := mkdir -p
|
||||||
|
FixPath = $1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Detectar todos los archivos en data/ como dependencias
|
||||||
|
DATA_FILES := $(shell find ../data -type f 2>/dev/null)
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Targets principales
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
.PHONY: all pack_tool resource_pack test_pack clean help
|
||||||
|
|
||||||
|
# Target por defecto: compilar herramienta
|
||||||
|
all: pack_tool
|
||||||
|
|
||||||
|
# Compilar herramienta de empaquetado
|
||||||
|
pack_tool: $(PACK_TOOL)
|
||||||
|
|
||||||
|
$(PACK_TOOL): $(PACK_SOURCES)
|
||||||
|
@echo "=========================================="
|
||||||
|
@echo "Compilando herramienta de empaquetado..."
|
||||||
|
@echo "=========================================="
|
||||||
|
$(CXX) $(CXXFLAGS) $(PACK_INCLUDES) $(PACK_SOURCES) $(LDFLAGS) -o $(PACK_TOOL)
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
@echo.
|
||||||
|
else
|
||||||
|
@echo ""
|
||||||
|
endif
|
||||||
|
@echo "✓ Herramienta compilada: $(PACK_TOOL)"
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
@echo.
|
||||||
|
else
|
||||||
|
@echo ""
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Crear pack de recursos final
|
||||||
|
resource_pack: $(PACK_TOOL)
|
||||||
|
@echo "=========================================="
|
||||||
|
@echo "Generando resources.pack..."
|
||||||
|
@echo "=========================================="
|
||||||
|
@echo "Directorio de datos: ../data"
|
||||||
|
@echo "Archivo de salida: $(RESOURCE_PACK)"
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
@echo.
|
||||||
|
else
|
||||||
|
@echo ""
|
||||||
|
endif
|
||||||
|
./$(PACK_TOOL) ../data $(RESOURCE_PACK)
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
@echo.
|
||||||
|
else
|
||||||
|
@echo ""
|
||||||
|
endif
|
||||||
|
@echo "✓ Pack de recursos creado exitosamente"
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
@echo.
|
||||||
|
else
|
||||||
|
@echo ""
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Crear pack de recursos de prueba
|
||||||
|
test_pack: $(PACK_TOOL)
|
||||||
|
@echo "=========================================="
|
||||||
|
@echo "Generando pack de prueba..."
|
||||||
|
@echo "=========================================="
|
||||||
|
@echo "Directorio de datos: ../data"
|
||||||
|
@echo "Archivo de salida: $(TEST_PACK)"
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
@echo.
|
||||||
|
else
|
||||||
|
@echo ""
|
||||||
|
endif
|
||||||
|
./$(PACK_TOOL) ../data $(TEST_PACK)
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
@echo.
|
||||||
|
else
|
||||||
|
@echo ""
|
||||||
|
endif
|
||||||
|
@echo "✓ Pack de prueba creado: $(TEST_PACK)"
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
@echo.
|
||||||
|
else
|
||||||
|
@echo ""
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Limpiar archivos generados
|
||||||
|
clean:
|
||||||
|
@echo "Limpiando archivos generados..."
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
@if exist "$(PACK_TOOL)" $(RMFILE) "$(PACK_TOOL)"
|
||||||
|
@if exist "$(TEST_PACK)" $(RMFILE) "$(TEST_PACK)"
|
||||||
|
else
|
||||||
|
@$(RMFILE) $(PACK_TOOL) $(TEST_PACK)
|
||||||
|
endif
|
||||||
|
@echo "✓ Limpieza completada"
|
||||||
|
|
||||||
|
# Mostrar ayuda
|
||||||
|
help:
|
||||||
|
@echo "=========================================="
|
||||||
|
@echo "ViBe3 Physics - Resource Packer Makefile"
|
||||||
|
@echo "=========================================="
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
@echo.
|
||||||
|
else
|
||||||
|
@echo ""
|
||||||
|
endif
|
||||||
|
@echo "Comandos disponibles:"
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
@echo.
|
||||||
|
else
|
||||||
|
@echo ""
|
||||||
|
endif
|
||||||
|
@echo " make - Compilar herramienta (equivalente a 'make pack_tool')"
|
||||||
|
@echo " make pack_tool - Compilar herramienta de empaquetado"
|
||||||
|
@echo " make resource_pack - Crear ../resources.pack desde ../data"
|
||||||
|
@echo " make test_pack - Crear pack de prueba (test_resources.pack)"
|
||||||
|
@echo " make clean - Limpiar archivos generados"
|
||||||
|
@echo " make help - Mostrar esta ayuda"
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
@echo.
|
||||||
|
else
|
||||||
|
@echo ""
|
||||||
|
endif
|
||||||
|
@echo "Ejemplos de uso:"
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
@echo.
|
||||||
|
else
|
||||||
|
@echo ""
|
||||||
|
endif
|
||||||
|
@echo " cd tools"
|
||||||
|
@echo " make # Compilar herramienta"
|
||||||
|
@echo " make resource_pack # Crear pack de recursos"
|
||||||
|
@echo " ./$(PACK_TOOL) --help # Ver ayuda de la herramienta"
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
@echo.
|
||||||
|
else
|
||||||
|
@echo ""
|
||||||
|
endif
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "../source/resource_pack.h"
|
#include "../source/resource_pack.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user