eliminat el checkFiles inicial que a jaildoc li molestava
This commit is contained in:
@@ -10,7 +10,10 @@
|
|||||||
"Bash(find:*)",
|
"Bash(find:*)",
|
||||||
"Bash(for file in source/game/scenes/title.cpp source/game/scenes/game.cpp source/game/entities/player.cpp source/game/options.cpp source/core/rendering/screen.cpp)",
|
"Bash(for file in source/game/scenes/title.cpp source/game/scenes/game.cpp source/game/entities/player.cpp source/game/options.cpp source/core/rendering/screen.cpp)",
|
||||||
"Bash(do echo \"=== $file ===\")",
|
"Bash(do echo \"=== $file ===\")",
|
||||||
"Bash(done)"
|
"Bash(done)",
|
||||||
|
"Bash(Xvfb:*)",
|
||||||
|
"Bash(chmod:*)",
|
||||||
|
"Bash(timeout:*)"
|
||||||
],
|
],
|
||||||
"deny": [],
|
"deny": [],
|
||||||
"ask": []
|
"ask": []
|
||||||
|
|||||||
93
CLAUDE.md
93
CLAUDE.md
@@ -55,6 +55,46 @@ cmake --build build --clean-first
|
|||||||
|
|
||||||
**Important:** The build directory is `/Users/sergio/Gitea/jaildoctors_dilemma/build` and the output executable is placed in the project root directory.
|
**Important:** The build directory is `/Users/sergio/Gitea/jaildoctors_dilemma/build` and the output executable is placed in the project root directory.
|
||||||
|
|
||||||
|
### Testing in Headless Environment (SSH/Remote Server)
|
||||||
|
|
||||||
|
**IMPORTANT:** When working on a remote server via SSH without a physical display, the game MUST be run using Xvfb (X Virtual Framebuffer) to avoid SDL3 display initialization errors.
|
||||||
|
|
||||||
|
#### Required Setup (One-time)
|
||||||
|
```bash
|
||||||
|
# Install Xvfb
|
||||||
|
sudo apt-get install xvfb
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Running the Game in Headless Mode
|
||||||
|
|
||||||
|
**Option 1: Using the wrapper script (RECOMMENDED)**
|
||||||
|
```bash
|
||||||
|
./run_headless.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option 2: Using xvfb-run directly**
|
||||||
|
```bash
|
||||||
|
xvfb-run -a ./jaildoctors_dilemma
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option 3: Custom display configuration**
|
||||||
|
```bash
|
||||||
|
xvfb-run -a -s "-screen 0 1280x720x24" ./jaildoctors_dilemma
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Why This Is Critical
|
||||||
|
|
||||||
|
- **SDL3 requires a display:** The game uses SDL3 which requires X11/Wayland display
|
||||||
|
- **No code changes needed:** Xvfb simulates a virtual display without modifying the codebase
|
||||||
|
- **Full logging:** Console output and logs work normally, essential for debugging resource loading
|
||||||
|
- **Testing resource loading:** When modifying asset loading code, running with xvfb-run allows seeing all initialization logs
|
||||||
|
|
||||||
|
**ALWAYS use xvfb-run when testing on the remote server, especially when:**
|
||||||
|
- Modifying resource loading code
|
||||||
|
- Testing asset initialization
|
||||||
|
- Debugging startup issues
|
||||||
|
- Verifying configuration changes
|
||||||
|
|
||||||
### Static Analysis Tools (Linters)
|
### Static Analysis Tools (Linters)
|
||||||
|
|
||||||
This project uses two complementary static analysis tools for code quality:
|
This project uses two complementary static analysis tools for code quality:
|
||||||
@@ -306,8 +346,8 @@ class Screen {
|
|||||||
- `Screen` - Rendering, window management, palette/shader effects
|
- `Screen` - Rendering, window management, palette/shader effects
|
||||||
- `Input` - Keyboard & gamepad input binding and checking
|
- `Input` - Keyboard & gamepad input binding and checking
|
||||||
- `Audio` - Music and sound effect playback
|
- `Audio` - Music and sound effect playback
|
||||||
- `Resource` - Asset loading, caching, streaming
|
- `Resource::Cache` - Asset loading, caching, streaming (with error handling)
|
||||||
- `Asset` - Asset path registry and verification
|
- `Resource::List` - Asset path registry from assets.yaml (O(1) lookups)
|
||||||
- `Director` - Main application controller
|
- `Director` - Main application controller
|
||||||
- `Cheevos` - Achievement state management
|
- `Cheevos` - Achievement state management
|
||||||
- `Debug` - Debug information overlay
|
- `Debug` - Debug information overlay
|
||||||
@@ -413,12 +453,14 @@ struct AnimationData {
|
|||||||
main()
|
main()
|
||||||
↓
|
↓
|
||||||
Director::Director() [Initialization]
|
Director::Director() [Initialization]
|
||||||
├─ Options::init() - Load game configuration
|
├─ Resource::List::init() - Initialize asset registry singleton
|
||||||
├─ Asset::init() - Register asset paths
|
├─ Director::setFileList() - Load assets.yaml configuration (no verification)
|
||||||
├─ Screen::init() - Create window, SDL renderer
|
├─ Options::loadFromFile() - Load game configuration
|
||||||
├─ Audio::init() - Initialize SDL audio
|
├─ Audio::init() - Initialize SDL audio
|
||||||
|
├─ Screen::init() - Create window, SDL renderer
|
||||||
├─ Input::init() - Bind keyboard/gamepad controls
|
├─ Input::init() - Bind keyboard/gamepad controls
|
||||||
├─ Resource::init() - Load all game resources
|
├─ Resource::Cache::init() - Load ALL game resources (with verification)
|
||||||
|
│ └─ Throws exception if any required asset is missing
|
||||||
└─ Cheevos::init() - Load achievement state
|
└─ Cheevos::init() - Load achievement state
|
||||||
|
|
||||||
Director::run() [Main loop]
|
Director::run() [Main loop]
|
||||||
@@ -433,11 +475,11 @@ Director::run() [Main loop]
|
|||||||
|
|
||||||
Director::~Director() [Cleanup]
|
Director::~Director() [Cleanup]
|
||||||
├─ Options::saveToFile() - Save game settings
|
├─ Options::saveToFile() - Save game settings
|
||||||
├─ Resource::destroy()
|
├─ Resource::Cache::destroy()
|
||||||
├─ Audio::destroy()
|
├─ Audio::destroy()
|
||||||
├─ Input::destroy()
|
├─ Input::destroy()
|
||||||
├─ Screen::destroy()
|
├─ Screen::destroy()
|
||||||
└─ Asset::destroy()
|
└─ Resource::List::destroy()
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.2 Game Scene Flow (Core Gameplay Loop)
|
### 4.2 Game Scene Flow (Core Gameplay Loop)
|
||||||
@@ -468,24 +510,27 @@ Game::run() {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Director::setFileList()
|
Director::setFileList()
|
||||||
├─ Asset::loadFromFile(config_path, PREFIX, system_folder_)
|
└─ Asset::loadFromFile(config_path, PREFIX, system_folder_)
|
||||||
│ ├─ Read config/assets.yaml - Parse text configuration file
|
├─ Read config/assets.yaml - Parse text configuration file
|
||||||
│ ├─ Parse each line: TYPE|PATH|OPTIONS - Extract asset information
|
├─ Parse YAML structure: assets grouped by category
|
||||||
│ ├─ Replace variables (${PREFIX}, ${SYSTEM_FOLDER})
|
├─ Replace variables (${PREFIX}, ${SYSTEM_FOLDER})
|
||||||
│ └─ Store in unordered_map (O(1) lookup) - Fast asset path retrieval
|
└─ Store in unordered_map (O(1) lookup) - Fast asset path retrieval
|
||||||
└─ Asset::check() - Verify required files exist
|
|
||||||
|
|
||||||
Game Scene initialization
|
Game Scene initialization
|
||||||
└─ Resource::init() - Loads all resources
|
└─ Resource::Cache::init() - Loads all resources
|
||||||
├─ loadSounds() - WAV files
|
├─ loadSounds() - WAV files (with error handling)
|
||||||
├─ loadMusics() - OGG files
|
├─ loadMusics() - OGG files (with error handling)
|
||||||
├─ loadSurfaces() - GIF/PNG images
|
├─ loadSurfaces() - GIF/PNG images (with error handling)
|
||||||
├─ loadAnimations() - .ani animation definitions
|
├─ loadPalettes() - PAL palette files (with error handling)
|
||||||
├─ loadTileMaps() - .room tilemap data
|
├─ loadTextFiles() - Font definition files (with error handling)
|
||||||
└─ loadRooms() - Room metadata
|
├─ loadAnimations() - YAML animation definitions (with error handling)
|
||||||
|
└─ loadRooms() - Room YAML files (with error handling)
|
||||||
|
|
||||||
|
Note: Asset verification happens during actual loading.
|
||||||
|
If a required file is missing, Cache::load() throws detailed exception.
|
||||||
|
|
||||||
During gameplay
|
During gameplay
|
||||||
└─ Resource::get*(name) - Return cached resource
|
└─ Resource::Cache::get*(name) - Return cached resource
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.4 Input Flow
|
### 4.4 Input Flow
|
||||||
@@ -653,8 +698,8 @@ Achievements trigger notifications on unlock.
|
|||||||
| `Screen` | Rendering, window, palette management | Singleton |
|
| `Screen` | Rendering, window, palette management | Singleton |
|
||||||
| `Input` | Keyboard & gamepad input | Singleton |
|
| `Input` | Keyboard & gamepad input | Singleton |
|
||||||
| `Audio` | Music and SFX playback | Singleton |
|
| `Audio` | Music and SFX playback | Singleton |
|
||||||
| `Resource` | Asset caching and loading | Singleton |
|
| `Resource::Cache` | Asset caching and loading (with detailed error messages) | Singleton |
|
||||||
| `Asset` | Asset path registry from config/assets.yaml, O(1) lookups, variable substitution | Singleton |
|
| `Resource::List` | Asset path registry from config/assets.yaml, O(1) lookups, variable substitution | Singleton |
|
||||||
| `Debug` | Debug overlay information | Singleton |
|
| `Debug` | Debug overlay information | Singleton |
|
||||||
| `globalEvents` | Global SDL event handling (quit, device reset, mouse) | Namespace |
|
| `globalEvents` | Global SDL event handling (quit, device reset, mouse) | Namespace |
|
||||||
|
|
||||||
|
|||||||
51
run_headless.sh
Executable file
51
run_headless.sh
Executable file
@@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Script para ejecutar JailDoctor's Dilemma en modo headless (sin pantalla)
|
||||||
|
# Usa Xvfb (X Virtual Framebuffer) para simular un display
|
||||||
|
|
||||||
|
# Configuración
|
||||||
|
GAME_EXECUTABLE="./jaildoctors_dilemma"
|
||||||
|
DISPLAY_SIZE="1280x720x24" # Resolución y profundidad de color
|
||||||
|
|
||||||
|
# Colores para output
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
echo -e "${GREEN}=== JailDoctor's Dilemma - Modo Headless ===${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Verificar que Xvfb está instalado
|
||||||
|
if ! command -v xvfb-run &> /dev/null; then
|
||||||
|
echo -e "${YELLOW}ERROR: Xvfb no está instalado${NC}"
|
||||||
|
echo "Instálalo con: sudo apt-get install xvfb"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verificar que el ejecutable existe
|
||||||
|
if [ ! -f "$GAME_EXECUTABLE" ]; then
|
||||||
|
echo -e "${YELLOW}ERROR: No se encuentra el ejecutable $GAME_EXECUTABLE${NC}"
|
||||||
|
echo "Compila el juego primero con: cmake --build build"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Iniciando juego con Xvfb..."
|
||||||
|
echo "Display virtual: $DISPLAY_SIZE"
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}Nota: El juego está corriendo. Presiona Ctrl+C para detenerlo.${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Ejecutar el juego con Xvfb
|
||||||
|
# Opciones:
|
||||||
|
# -a: Selecciona automáticamente un número de display disponible
|
||||||
|
# -s: Configura el servidor X (resolución y profundidad)
|
||||||
|
xvfb-run -a -s "-screen 0 ${DISPLAY_SIZE}" "$GAME_EXECUTABLE" "$@"
|
||||||
|
|
||||||
|
EXIT_CODE=$?
|
||||||
|
echo ""
|
||||||
|
if [ $EXIT_CODE -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}Juego finalizado correctamente${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}Juego finalizado con código de salida: $EXIT_CODE${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $EXIT_CODE
|
||||||
@@ -176,6 +176,15 @@ auto Cache::getRooms() -> std::vector<RoomResource>& {
|
|||||||
return rooms_;
|
return rooms_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper para lanzar errores de carga con formato consistente
|
||||||
|
[[noreturn]] void Cache::throwLoadError(const std::string& asset_type, const std::string& file_path, const std::exception& e) {
|
||||||
|
std::cerr << "\n[ ERROR ] Failed to load " << asset_type << ": " << getFileName(file_path) << '\n';
|
||||||
|
std::cerr << "[ ERROR ] Path: " << file_path << '\n';
|
||||||
|
std::cerr << "[ ERROR ] Reason: " << e.what() << '\n';
|
||||||
|
std::cerr << "[ ERROR ] Check config/assets.yaml configuration\n";
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
// Carga los sonidos
|
// Carga los sonidos
|
||||||
void Cache::loadSounds() {
|
void Cache::loadSounds() {
|
||||||
std::cout << "\n>> SOUND FILES" << '\n';
|
std::cout << "\n>> SOUND FILES" << '\n';
|
||||||
@@ -183,6 +192,7 @@ void Cache::loadSounds() {
|
|||||||
sounds_.clear();
|
sounds_.clear();
|
||||||
|
|
||||||
for (const auto& l : list) {
|
for (const auto& l : list) {
|
||||||
|
try {
|
||||||
auto name = getFileName(l);
|
auto name = getFileName(l);
|
||||||
JA_Sound_t* sound = nullptr;
|
JA_Sound_t* sound = nullptr;
|
||||||
|
|
||||||
@@ -197,9 +207,16 @@ void Cache::loadSounds() {
|
|||||||
sound = JA_LoadSound(l.c_str());
|
sound = JA_LoadSound(l.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sound == nullptr) {
|
||||||
|
throw std::runtime_error("Failed to decode audio file");
|
||||||
|
}
|
||||||
|
|
||||||
sounds_.emplace_back(SoundResource{.name = name, .sound = sound});
|
sounds_.emplace_back(SoundResource{.name = name, .sound = sound});
|
||||||
printWithDots("Sound : ", name, "[ LOADED ]");
|
printWithDots("Sound : ", name, "[ LOADED ]");
|
||||||
updateLoadingProgress();
|
updateLoadingProgress();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
throwLoadError("SOUND", l, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,6 +227,7 @@ void Cache::loadMusics() {
|
|||||||
musics_.clear();
|
musics_.clear();
|
||||||
|
|
||||||
for (const auto& l : list) {
|
for (const auto& l : list) {
|
||||||
|
try {
|
||||||
auto name = getFileName(l);
|
auto name = getFileName(l);
|
||||||
JA_Music_t* music = nullptr;
|
JA_Music_t* music = nullptr;
|
||||||
|
|
||||||
@@ -224,9 +242,16 @@ void Cache::loadMusics() {
|
|||||||
music = JA_LoadMusic(l.c_str());
|
music = JA_LoadMusic(l.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (music == nullptr) {
|
||||||
|
throw std::runtime_error("Failed to decode music file");
|
||||||
|
}
|
||||||
|
|
||||||
musics_.emplace_back(MusicResource{.name = name, .music = music});
|
musics_.emplace_back(MusicResource{.name = name, .music = music});
|
||||||
printWithDots("Music : ", name, "[ LOADED ]");
|
printWithDots("Music : ", name, "[ LOADED ]");
|
||||||
updateLoadingProgress(1);
|
updateLoadingProgress(1);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
throwLoadError("MUSIC", l, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,10 +262,14 @@ void Cache::loadSurfaces() {
|
|||||||
surfaces_.clear();
|
surfaces_.clear();
|
||||||
|
|
||||||
for (const auto& l : list) {
|
for (const auto& l : list) {
|
||||||
|
try {
|
||||||
auto name = getFileName(l);
|
auto name = getFileName(l);
|
||||||
surfaces_.emplace_back(SurfaceResource{.name = name, .surface = std::make_shared<Surface>(l)});
|
surfaces_.emplace_back(SurfaceResource{.name = name, .surface = std::make_shared<Surface>(l)});
|
||||||
surfaces_.back().surface->setTransparentColor(0);
|
surfaces_.back().surface->setTransparentColor(0);
|
||||||
updateLoadingProgress();
|
updateLoadingProgress();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
throwLoadError("BITMAP", l, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reconfigura el color transparente de algunas surfaces
|
// Reconfigura el color transparente de algunas surfaces
|
||||||
@@ -260,9 +289,13 @@ void Cache::loadPalettes() {
|
|||||||
palettes_.clear();
|
palettes_.clear();
|
||||||
|
|
||||||
for (const auto& l : list) {
|
for (const auto& l : list) {
|
||||||
|
try {
|
||||||
auto name = getFileName(l);
|
auto name = getFileName(l);
|
||||||
palettes_.emplace_back(ResourcePalette{.name = name, .palette = readPalFile(l)});
|
palettes_.emplace_back(ResourcePalette{.name = name, .palette = readPalFile(l)});
|
||||||
updateLoadingProgress();
|
updateLoadingProgress();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
throwLoadError("PALETTE", l, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,9 +306,13 @@ void Cache::loadTextFiles() {
|
|||||||
text_files_.clear();
|
text_files_.clear();
|
||||||
|
|
||||||
for (const auto& l : list) {
|
for (const auto& l : list) {
|
||||||
|
try {
|
||||||
auto name = getFileName(l);
|
auto name = getFileName(l);
|
||||||
text_files_.emplace_back(TextFileResource{.name = name, .text_file = Text::loadTextFile(l)});
|
text_files_.emplace_back(TextFileResource{.name = name, .text_file = Text::loadTextFile(l)});
|
||||||
updateLoadingProgress();
|
updateLoadingProgress();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
throwLoadError("FONT", l, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,14 +323,22 @@ void Cache::loadAnimations() {
|
|||||||
animations_.clear();
|
animations_.clear();
|
||||||
|
|
||||||
for (const auto& l : list) {
|
for (const auto& l : list) {
|
||||||
|
try {
|
||||||
auto name = getFileName(l);
|
auto name = getFileName(l);
|
||||||
|
|
||||||
// Cargar bytes del archivo YAML sin parsear (carga lazy)
|
// Cargar bytes del archivo YAML sin parsear (carga lazy)
|
||||||
auto yaml_bytes = Helper::loadFile(l);
|
auto yaml_bytes = Helper::loadFile(l);
|
||||||
|
|
||||||
|
if (yaml_bytes.empty()) {
|
||||||
|
throw std::runtime_error("File is empty or could not be loaded");
|
||||||
|
}
|
||||||
|
|
||||||
animations_.emplace_back(AnimationResource{.name = name, .yaml_data = yaml_bytes});
|
animations_.emplace_back(AnimationResource{.name = name, .yaml_data = yaml_bytes});
|
||||||
printWithDots("Animation : ", name, "[ LOADED ]");
|
printWithDots("Animation : ", name, "[ LOADED ]");
|
||||||
updateLoadingProgress();
|
updateLoadingProgress();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
throwLoadError("ANIMATION", l, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,10 +349,14 @@ void Cache::loadRooms() {
|
|||||||
rooms_.clear();
|
rooms_.clear();
|
||||||
|
|
||||||
for (const auto& l : list) {
|
for (const auto& l : list) {
|
||||||
|
try {
|
||||||
auto name = getFileName(l);
|
auto name = getFileName(l);
|
||||||
rooms_.emplace_back(RoomResource{.name = name, .room = std::make_shared<Room::Data>(Room::loadYAML(l))});
|
rooms_.emplace_back(RoomResource{.name = name, .room = std::make_shared<Room::Data>(Room::loadYAML(l))});
|
||||||
printWithDots("Room : ", name, "[ LOADED ]");
|
printWithDots("Room : ", name, "[ LOADED ]");
|
||||||
updateLoadingProgress();
|
updateLoadingProgress();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
throwLoadError("ROOM", l, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,9 @@ class Cache {
|
|||||||
static void checkEvents();
|
static void checkEvents();
|
||||||
void updateLoadingProgress(int steps = 5);
|
void updateLoadingProgress(int steps = 5);
|
||||||
|
|
||||||
|
// Helper para mensajes de error de carga
|
||||||
|
[[noreturn]] static void throwLoadError(const std::string& asset_type, const std::string& file_path, const std::exception& e);
|
||||||
|
|
||||||
// Constructor y destructor
|
// Constructor y destructor
|
||||||
Cache();
|
Cache();
|
||||||
~Cache() = default;
|
~Cache() = default;
|
||||||
|
|||||||
@@ -200,61 +200,6 @@ auto List::exists(const std::string& filename) const -> bool {
|
|||||||
return file_list_.find(filename) != file_list_.end();
|
return file_list_.find(filename) != file_list_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba que existen todos los elementos
|
|
||||||
auto List::check() const -> bool {
|
|
||||||
bool success = true;
|
|
||||||
|
|
||||||
std::cout << "\n** CHECKING FILES" << '\n';
|
|
||||||
|
|
||||||
// Agrupar por tipo para mostrar organizado
|
|
||||||
std::unordered_map<Type, std::vector<const Item*>> by_type;
|
|
||||||
|
|
||||||
for (const auto& [filename, item] : file_list_) {
|
|
||||||
if (item.required) {
|
|
||||||
by_type[item.type].push_back(&item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verificar por tipo
|
|
||||||
for (int type = 0; type < static_cast<int>(Type::SIZE); ++type) {
|
|
||||||
Type asset_type = static_cast<Type>(type);
|
|
||||||
|
|
||||||
if (by_type.find(asset_type) != by_type.end()) {
|
|
||||||
std::cout << "\n>> " << getTypeName(asset_type) << " FILES" << '\n';
|
|
||||||
|
|
||||||
bool type_success = true;
|
|
||||||
for (const auto* item : by_type[asset_type]) {
|
|
||||||
if (!checkFile(item->file)) {
|
|
||||||
success = false;
|
|
||||||
type_success = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type_success) {
|
|
||||||
std::cout << " All files are OK." << '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resultado
|
|
||||||
std::cout << (success ? "\n** CHECKING FILES COMPLETED.\n" : "\n** CHECKING FILES FAILED.\n") << '\n';
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Comprueba que existe un fichero
|
|
||||||
auto List::checkFile(const std::string& path) -> bool {
|
|
||||||
std::ifstream file(path);
|
|
||||||
bool success = file.good();
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
printWithDots("Checking file : ", getFileName(path), "[ ERROR ]");
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parsea string a Type
|
// Parsea string a Type
|
||||||
auto List::parseAssetType(const std::string& type_str) -> Type {
|
auto List::parseAssetType(const std::string& type_str) -> Type {
|
||||||
if (type_str == "DATA") {
|
if (type_str == "DATA") {
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ class List {
|
|||||||
void loadFromString(const std::string& config_content, const std::string& prefix = "", const std::string& system_folder = ""); // Para cargar desde pack (release)
|
void loadFromString(const std::string& config_content, const std::string& prefix = "", const std::string& system_folder = ""); // Para cargar desde pack (release)
|
||||||
[[nodiscard]] auto get(const std::string& filename) const -> std::string; // Obtiene la ruta completa
|
[[nodiscard]] auto get(const std::string& filename) const -> std::string; // Obtiene la ruta completa
|
||||||
[[nodiscard]] auto loadData(const std::string& filename) const -> std::vector<uint8_t>; // Carga datos del archivo
|
[[nodiscard]] auto loadData(const std::string& filename) const -> std::vector<uint8_t>; // Carga datos del archivo
|
||||||
[[nodiscard]] auto check() const -> bool;
|
|
||||||
[[nodiscard]] auto getListByType(Type type) const -> std::vector<std::string>;
|
[[nodiscard]] auto getListByType(Type type) const -> std::vector<std::string>;
|
||||||
[[nodiscard]] auto exists(const std::string& filename) const -> bool; // Verifica si un asset existe
|
[[nodiscard]] auto exists(const std::string& filename) const -> bool; // Verifica si un asset existe
|
||||||
|
|
||||||
@@ -59,7 +58,6 @@ class List {
|
|||||||
std::string executable_path_; // Ruta del ejecutable
|
std::string executable_path_; // Ruta del ejecutable
|
||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
[[nodiscard]] static auto checkFile(const std::string& path) -> bool; // Verifica si un archivo existe
|
|
||||||
[[nodiscard]] static auto getTypeName(Type type) -> std::string; // Obtiene el nombre del tipo
|
[[nodiscard]] static auto getTypeName(Type type) -> std::string; // Obtiene el nombre del tipo
|
||||||
[[nodiscard]] static auto parseAssetType(const std::string& type_str) -> Type; // Convierte string a tipo
|
[[nodiscard]] static auto parseAssetType(const std::string& type_str) -> Type; // Convierte string a tipo
|
||||||
void addToMap(const std::string& file_path, Type type, bool required, bool absolute); // Añade archivo al mapa
|
void addToMap(const std::string& file_path, Type type, bool required, bool absolute); // Añade archivo al mapa
|
||||||
|
|||||||
@@ -107,10 +107,9 @@ Director::Director(std::vector<std::string> const& args) {
|
|||||||
// 1. Initialize Asset system from filesystem
|
// 1. Initialize Asset system from filesystem
|
||||||
Resource::List::init(executable_path_);
|
Resource::List::init(executable_path_);
|
||||||
|
|
||||||
// 2. Load and verify assets from disk
|
// 2. Load asset configuration from disk
|
||||||
if (!setFileList()) {
|
// Note: Asset verification happens during Resource::Cache::load()
|
||||||
exit(EXIT_FAILURE);
|
setFileList();
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Initialize resource pack system (optional, with fallback)
|
// 3. Initialize resource pack system (optional, with fallback)
|
||||||
std::cout << "Initializing resource pack (development mode): " << pack_path << '\n';
|
std::cout << "Initializing resource pack (development mode): " << pack_path << '\n';
|
||||||
@@ -259,8 +258,8 @@ void Director::createSystemFolder(const std::string& folder) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crea el indice de ficheros
|
// Carga la configuración de assets desde assets.yaml
|
||||||
auto Director::setFileList() -> bool {
|
void Director::setFileList() {
|
||||||
// Determinar el prefijo de ruta según la plataforma
|
// Determinar el prefijo de ruta según la plataforma
|
||||||
#ifdef MACOS_BUNDLE
|
#ifdef MACOS_BUNDLE
|
||||||
const std::string PREFIX = "/../Resources";
|
const std::string PREFIX = "/../Resources";
|
||||||
@@ -272,10 +271,8 @@ auto Director::setFileList() -> bool {
|
|||||||
std::string config_path = executable_path_ + PREFIX + "/config/assets.yaml";
|
std::string config_path = executable_path_ + PREFIX + "/config/assets.yaml";
|
||||||
|
|
||||||
// Cargar todos los assets desde el archivo de configuración
|
// Cargar todos los assets desde el archivo de configuración
|
||||||
|
// La verificación de existencia de archivos se realiza durante Resource::Cache::load()
|
||||||
Resource::List::get()->loadFromFile(config_path, PREFIX, system_folder_);
|
Resource::List::get()->loadFromFile(config_path, PREFIX, system_folder_);
|
||||||
|
|
||||||
// Verificar que todos los assets requeridos existen
|
|
||||||
return Resource::List::get()->check();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ejecuta la seccion de juego con el logo
|
// Ejecuta la seccion de juego con el logo
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class Director {
|
|||||||
|
|
||||||
// --- Funciones ---
|
// --- Funciones ---
|
||||||
void createSystemFolder(const std::string& folder); // Crea la carpeta del sistema donde guardar datos
|
void createSystemFolder(const std::string& folder); // Crea la carpeta del sistema donde guardar datos
|
||||||
auto setFileList() -> bool; // Crea el indice de ficheros
|
void setFileList(); // Carga la configuración de assets desde assets.yaml
|
||||||
static void runLogo(); // Ejecuta la seccion de juego con el logo
|
static void runLogo(); // Ejecuta la seccion de juego con el logo
|
||||||
static void runLoadingScreen(); // Ejecuta la seccion de juego de la pantalla de carga
|
static void runLoadingScreen(); // Ejecuta la seccion de juego de la pantalla de carga
|
||||||
static void runTitle(); // Ejecuta la seccion de juego con el titulo y los menus
|
static void runTitle(); // Ejecuta la seccion de juego con el titulo y los menus
|
||||||
|
|||||||
Reference in New Issue
Block a user