diff --git a/.claude/settings.local.json b/.claude/settings.local.json index d637cda..9fd45b7 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -22,7 +22,8 @@ "WebFetch(domain:raw.githubusercontent.com)", "Bash(curl:*)", "WebFetch(domain:fktn-k.github.io)", - "Bash(./jaildoctors_dilemma)" + "Bash(./jaildoctors_dilemma)", + "Bash(timeout 5 ./jaildoctors_dilemma:*)" ], "deny": [], "ask": [] diff --git a/CLAUDE.md b/CLAUDE.md index daa3151..bdf0d10 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -261,7 +261,7 @@ source/ └── main.cpp # Application entry point config/ # Configuration files -└── assets.txt # Asset registry (text-based configuration) +└── assets.yaml # Asset registry (text-based configuration) data/ # Game assets ├── font/ # Bitmap fonts + descriptors @@ -469,7 +469,7 @@ Game::run() { ``` Director::setFileList() ├─ Asset::loadFromFile(config_path, PREFIX, system_folder_) - │ ├─ Read config/assets.txt - Parse text configuration file + │ ├─ Read config/assets.yaml - Parse text configuration file │ ├─ Parse each line: TYPE|PATH|OPTIONS - Extract asset information │ ├─ Replace variables (${PREFIX}, ${SYSTEM_FOLDER}) │ └─ Store in unordered_map (O(1) lookup) - Fast asset path retrieval @@ -654,7 +654,7 @@ Achievements trigger notifications on unlock. | `Input` | Keyboard & gamepad input | Singleton | | `Audio` | Music and SFX playback | Singleton | | `Resource` | Asset caching and loading | Singleton | -| `Asset` | Asset path registry from config/assets.txt, O(1) lookups, variable substitution | Singleton | +| `Asset` | Asset path registry from config/assets.yaml, O(1) lookups, variable substitution | Singleton | | `Debug` | Debug overlay information | Singleton | | `globalEvents` | Global SDL event handling (quit, device reset, mouse) | Namespace | @@ -717,16 +717,25 @@ Achievements trigger notifications on unlock. ### Adding Game Assets 1. Place file in `data/` directory -2. Add entry to `config/assets.txt`: +2. Add entry to `config/assets.yaml` under the appropriate category: + ```yaml + assets: + category_name: # e.g., player, enemies, music, etc. + - type: BITMAP + path: ${PREFIX}/data/path/file.ext ``` - TYPE|${PREFIX}/data/path/file.ext + Available types: `DATA`, `BITMAP`, `ANIMATION`, `MUSIC`, `SOUND`, `FONT`, `ROOM`, `PALETTE` +3. Optional flags can be added: + ```yaml + - type: DATA + path: ${SYSTEM_FOLDER}/file.txt + required: false # Don't fail if missing + absolute: true # Path is absolute ``` - Available types: `DATA`, `BITMAP`, `ANIMATION`, `MUSIC`, `SOUND`, `FONT`, `ROOM`, `TILEMAP`, `PALETTE` -3. Optional flags can be added: `TYPE|${PREFIX}/path/file.ext|optional,absolute` 4. Resource loads automatically during `Resource::init()` 5. Access via: `Resource::Cache::get()->getSurface("name")` -**Note:** No recompilation needed when adding/removing/modifying assets in `config/assets.txt` +**Note:** No recompilation needed when adding/removing/modifying assets in `config/assets.yaml` ### Modifying Collision Detection @@ -782,36 +791,58 @@ In debug builds (`#ifdef DEBUG`), renders: ## 11. File Format Reference -### Asset Configuration File (config/assets.txt) -Text-based asset registry with pipe-delimited format: -``` -# Format: TYPE|PATH [|OPTIONS] -# Comments start with # or ; +### Asset Configuration File (config/assets.yaml) +YAML-based asset registry with grouped structure: +```yaml +# JailDoctor's Dilemma - Asset Configuration # Variables: ${PREFIX}, ${SYSTEM_FOLDER} -# Options: optional, absolute (comma-separated) -# Example entries: -BITMAP|${PREFIX}/data/player/player.gif -ANIMATION|${PREFIX}/data/player/player.ani -MUSIC|${PREFIX}/data/music/title.ogg -DATA|${SYSTEM_FOLDER}/config.txt|optional,absolute +assets: + # FONTS + fonts: + - type: BITMAP + path: ${PREFIX}/data/font/smb2.gif + - type: FONT + path: ${PREFIX}/data/font/smb2.txt + + # PLAYER + player: + - type: BITMAP + path: ${PREFIX}/data/player/player.gif + - type: ANIMATION + path: ${PREFIX}/data/player/player.yaml + + # MUSIC + music: + - type: MUSIC + path: ${PREFIX}/data/music/title.ogg + + # SYSTEM FILES (optional, absolute paths) + system: + - type: DATA + path: ${SYSTEM_FOLDER}/config.txt + required: false + absolute: true ``` +**Asset Structure:** +- Assets are organized into categories (fonts, palettes, shaders, player, enemies, etc.) +- Each asset entry contains: + - `type` - Asset type (required) + - `path` - File path with variable substitution (required) + - `required` - Whether file must exist (optional, default: `true`) + - `absolute` - Whether path is absolute (optional, default: `false`) + **Available Asset Types:** - `DATA` - General data files (text, JSON, etc.) - `BITMAP` - Images (GIF, PNG) -- `ANIMATION` - Animation definition files (.ani) +- `ANIMATION` - Animation definition files (.yaml) - `MUSIC` - Music files (OGG) - `SOUND` - Sound effects (WAV) - `FONT` - Font definition files -- `ROOM` - Room data files (.room) -- `TILEMAP` - Tilemap files (.tmx) +- `ROOM` - Room data files (.yaml) - `PALETTE` - Color palette files (.pal) -**Options:** -- `optional` - File is not required (won't fail check if missing) -- `absolute` - Path is absolute (not relative to executable) - **Variables:** - `${PREFIX}` - Replaced with `/../Resources` on macOS bundles, empty otherwise - `${SYSTEM_FOLDER}` - Replaced with user's system config folder @@ -865,7 +896,7 @@ Binary 256-color palette format (256 × 4 bytes RGBA). - `Player::update()` - Physics and movement ### For Asset Management -- `config/assets.txt` - Asset configuration file (text-based, no recompilation needed) +- `config/assets.yaml` - Asset configuration file (text-based, no recompilation needed) - `Asset::loadFromFile()` - Loads assets from config file - `Resource::List::get()` - Retrieves asset path (O(1) lookup with unordered_map) - `Resource::load()` - Asset loading diff --git a/config/assets.txt b/config/assets.txt deleted file mode 100644 index 0b520fc..0000000 --- a/config/assets.txt +++ /dev/null @@ -1,339 +0,0 @@ -# JailDoctor's Dilemma - Asset Configuration -# Format: TYPE|PATH [|OPTIONS] -# Options: optional, absolute (comma-separated) -# Variables: ${PREFIX}, ${SYSTEM_FOLDER} - -# =================================================================== -# FONTS -# =================================================================== -BITMAP|${PREFIX}/data/font/smb2.gif -FONT|${PREFIX}/data/font/smb2.txt -BITMAP|${PREFIX}/data/font/aseprite.gif -FONT|${PREFIX}/data/font/aseprite.txt -BITMAP|${PREFIX}/data/font/gauntlet.gif -FONT|${PREFIX}/data/font/gauntlet.txt -BITMAP|${PREFIX}/data/font/subatomic.gif -FONT|${PREFIX}/data/font/subatomic.txt -BITMAP|${PREFIX}/data/font/8bithud.gif -FONT|${PREFIX}/data/font/8bithud.txt - -# =================================================================== -# PALETTES -# =================================================================== -PALETTE|${PREFIX}/data/palette/zx-spectrum.pal -PALETTE|${PREFIX}/data/palette/zx-spectrum-adjusted.pal -PALETTE|${PREFIX}/data/palette/zxarne-5-2.pal -PALETTE|${PREFIX}/data/palette/black-and-white.pal -PALETTE|${PREFIX}/data/palette/green-phosphor.pal -PALETTE|${PREFIX}/data/palette/orange-screen.pal -PALETTE|${PREFIX}/data/palette/ruzx-spectrum.pal -PALETTE|${PREFIX}/data/palette/ruzx-spectrum-revision-2.pal -PALETTE|${PREFIX}/data/palette/pico-8.pal -PALETTE|${PREFIX}/data/palette/sweetie-16.pal -PALETTE|${PREFIX}/data/palette/island-joy-16.pal -PALETTE|${PREFIX}/data/palette/lost-century.pal -PALETTE|${PREFIX}/data/palette/na16.pal -PALETTE|${PREFIX}/data/palette/steam-lords.pal - -# =================================================================== -# SHADERS -# =================================================================== -DATA|${PREFIX}/data/shaders/crtpi_vertex.glsl -DATA|${PREFIX}/data/shaders/crtpi_fragment.glsl -DATA|${PREFIX}/data/shaders/crtpi_vertex_es.glsl -DATA|${PREFIX}/data/shaders/crtpi_fragment_es.glsl - -# =================================================================== -# INPUT DATA (in root, not packed - SDL needs filesystem access) -# =================================================================== -DATA|${PREFIX}/gamecontrollerdb.txt - -# =================================================================== -# SYSTEM FILES (optional, absolute paths) -# =================================================================== -DATA|${SYSTEM_FOLDER}/config.txt|optional,absolute -DATA|${SYSTEM_FOLDER}/stats_buffer.csv|optional,absolute -DATA|${SYSTEM_FOLDER}/stats.csv|optional,absolute -DATA|${SYSTEM_FOLDER}/cheevos.bin|optional,absolute - -# =================================================================== -# ROOMS (60 rooms - formato YAML unificado con tilemap embebido) -# =================================================================== -ROOM|${PREFIX}/data/room/01.yaml -ROOM|${PREFIX}/data/room/02.yaml -ROOM|${PREFIX}/data/room/03.yaml -ROOM|${PREFIX}/data/room/04.yaml -ROOM|${PREFIX}/data/room/05.yaml -ROOM|${PREFIX}/data/room/06.yaml -ROOM|${PREFIX}/data/room/07.yaml -ROOM|${PREFIX}/data/room/08.yaml -ROOM|${PREFIX}/data/room/09.yaml -ROOM|${PREFIX}/data/room/10.yaml -ROOM|${PREFIX}/data/room/11.yaml -ROOM|${PREFIX}/data/room/12.yaml -ROOM|${PREFIX}/data/room/13.yaml -ROOM|${PREFIX}/data/room/14.yaml -ROOM|${PREFIX}/data/room/15.yaml -ROOM|${PREFIX}/data/room/16.yaml -ROOM|${PREFIX}/data/room/17.yaml -ROOM|${PREFIX}/data/room/18.yaml -ROOM|${PREFIX}/data/room/19.yaml -ROOM|${PREFIX}/data/room/20.yaml -ROOM|${PREFIX}/data/room/21.yaml -ROOM|${PREFIX}/data/room/22.yaml -ROOM|${PREFIX}/data/room/23.yaml -ROOM|${PREFIX}/data/room/24.yaml -ROOM|${PREFIX}/data/room/25.yaml -ROOM|${PREFIX}/data/room/26.yaml -ROOM|${PREFIX}/data/room/27.yaml -ROOM|${PREFIX}/data/room/28.yaml -ROOM|${PREFIX}/data/room/29.yaml -ROOM|${PREFIX}/data/room/30.yaml -ROOM|${PREFIX}/data/room/31.yaml -ROOM|${PREFIX}/data/room/32.yaml -ROOM|${PREFIX}/data/room/33.yaml -ROOM|${PREFIX}/data/room/34.yaml -ROOM|${PREFIX}/data/room/35.yaml -ROOM|${PREFIX}/data/room/36.yaml -ROOM|${PREFIX}/data/room/37.yaml -ROOM|${PREFIX}/data/room/38.yaml -ROOM|${PREFIX}/data/room/39.yaml -ROOM|${PREFIX}/data/room/40.yaml -ROOM|${PREFIX}/data/room/41.yaml -ROOM|${PREFIX}/data/room/42.yaml -ROOM|${PREFIX}/data/room/43.yaml -ROOM|${PREFIX}/data/room/44.yaml -ROOM|${PREFIX}/data/room/45.yaml -ROOM|${PREFIX}/data/room/46.yaml -ROOM|${PREFIX}/data/room/47.yaml -ROOM|${PREFIX}/data/room/48.yaml -ROOM|${PREFIX}/data/room/49.yaml -ROOM|${PREFIX}/data/room/50.yaml -ROOM|${PREFIX}/data/room/51.yaml -ROOM|${PREFIX}/data/room/52.yaml -ROOM|${PREFIX}/data/room/53.yaml -ROOM|${PREFIX}/data/room/54.yaml -ROOM|${PREFIX}/data/room/55.yaml -ROOM|${PREFIX}/data/room/56.yaml -ROOM|${PREFIX}/data/room/57.yaml -ROOM|${PREFIX}/data/room/58.yaml -ROOM|${PREFIX}/data/room/59.yaml -ROOM|${PREFIX}/data/room/60.yaml - -# =================================================================== -# TILESETS -# =================================================================== -BITMAP|${PREFIX}/data/tilesets/standard.gif - -# =================================================================== -# ENEMIES -# =================================================================== -ANIMATION|${PREFIX}/data/enemies/abad_bell.yaml -BITMAP|${PREFIX}/data/enemies/abad_bell.gif -ANIMATION|${PREFIX}/data/enemies/abad.yaml -BITMAP|${PREFIX}/data/enemies/abad.gif -ANIMATION|${PREFIX}/data/enemies/amstrad_cs.yaml -BITMAP|${PREFIX}/data/enemies/amstrad_cs.gif -ANIMATION|${PREFIX}/data/enemies/flying_arounder.yaml -BITMAP|${PREFIX}/data/enemies/flying_arounder.gif -ANIMATION|${PREFIX}/data/enemies/stopped_arounder.yaml -BITMAP|${PREFIX}/data/enemies/stopped_arounder.gif -ANIMATION|${PREFIX}/data/enemies/walking_arounder.yaml -BITMAP|${PREFIX}/data/enemies/walking_arounder.gif -ANIMATION|${PREFIX}/data/enemies/arounders_door.yaml -BITMAP|${PREFIX}/data/enemies/arounders_door.gif -ANIMATION|${PREFIX}/data/enemies/arounders_machine.yaml -BITMAP|${PREFIX}/data/enemies/arounders_machine.gif -ANIMATION|${PREFIX}/data/enemies/bat.yaml -BITMAP|${PREFIX}/data/enemies/bat.gif -ANIMATION|${PREFIX}/data/enemies/batman_bell.yaml -BITMAP|${PREFIX}/data/enemies/batman_bell.gif -ANIMATION|${PREFIX}/data/enemies/batman_fire.yaml -BITMAP|${PREFIX}/data/enemies/batman_fire.gif -ANIMATION|${PREFIX}/data/enemies/batman.yaml -BITMAP|${PREFIX}/data/enemies/batman.gif -ANIMATION|${PREFIX}/data/enemies/bell.yaml -BITMAP|${PREFIX}/data/enemies/bell.gif -ANIMATION|${PREFIX}/data/enemies/bin.yaml -BITMAP|${PREFIX}/data/enemies/bin.gif -ANIMATION|${PREFIX}/data/enemies/bird.yaml -BITMAP|${PREFIX}/data/enemies/bird.gif -ANIMATION|${PREFIX}/data/enemies/breakout.yaml -BITMAP|${PREFIX}/data/enemies/breakout.gif -ANIMATION|${PREFIX}/data/enemies/bry.yaml -BITMAP|${PREFIX}/data/enemies/bry.gif -ANIMATION|${PREFIX}/data/enemies/chip.yaml -BITMAP|${PREFIX}/data/enemies/chip.gif -ANIMATION|${PREFIX}/data/enemies/code.yaml -BITMAP|${PREFIX}/data/enemies/code.gif -ANIMATION|${PREFIX}/data/enemies/congo.yaml -BITMAP|${PREFIX}/data/enemies/congo.gif -ANIMATION|${PREFIX}/data/enemies/crosshair.yaml -BITMAP|${PREFIX}/data/enemies/crosshair.gif -ANIMATION|${PREFIX}/data/enemies/demon.yaml -BITMAP|${PREFIX}/data/enemies/demon.gif -ANIMATION|${PREFIX}/data/enemies/dimallas.yaml -BITMAP|${PREFIX}/data/enemies/dimallas.gif -ANIMATION|${PREFIX}/data/enemies/floppy.yaml -BITMAP|${PREFIX}/data/enemies/floppy.gif -ANIMATION|${PREFIX}/data/enemies/dong.yaml -BITMAP|${PREFIX}/data/enemies/dong.gif -ANIMATION|${PREFIX}/data/enemies/guitar.yaml -BITMAP|${PREFIX}/data/enemies/guitar.gif -ANIMATION|${PREFIX}/data/enemies/heavy.yaml -BITMAP|${PREFIX}/data/enemies/heavy.gif -ANIMATION|${PREFIX}/data/enemies/jailer_#1.yaml -BITMAP|${PREFIX}/data/enemies/jailer_#1.gif -ANIMATION|${PREFIX}/data/enemies/jailer_#2.yaml -BITMAP|${PREFIX}/data/enemies/jailer_#2.gif -ANIMATION|${PREFIX}/data/enemies/jailer_#3.yaml -BITMAP|${PREFIX}/data/enemies/jailer_#3.gif -ANIMATION|${PREFIX}/data/enemies/jailbattle_alien.yaml -BITMAP|${PREFIX}/data/enemies/jailbattle_alien.gif -ANIMATION|${PREFIX}/data/enemies/jailbattle_human.yaml -BITMAP|${PREFIX}/data/enemies/jailbattle_human.gif -ANIMATION|${PREFIX}/data/enemies/jeannine.yaml -BITMAP|${PREFIX}/data/enemies/jeannine.gif -ANIMATION|${PREFIX}/data/enemies/lamp.yaml -BITMAP|${PREFIX}/data/enemies/lamp.gif -ANIMATION|${PREFIX}/data/enemies/lord_abad.yaml -BITMAP|${PREFIX}/data/enemies/lord_abad.gif -ANIMATION|${PREFIX}/data/enemies/matatunos.yaml -BITMAP|${PREFIX}/data/enemies/matatunos.gif -ANIMATION|${PREFIX}/data/enemies/mummy.yaml -BITMAP|${PREFIX}/data/enemies/mummy.gif -ANIMATION|${PREFIX}/data/enemies/paco.yaml -BITMAP|${PREFIX}/data/enemies/paco.gif -ANIMATION|${PREFIX}/data/enemies/elsa.yaml -BITMAP|${PREFIX}/data/enemies/elsa.gif -ANIMATION|${PREFIX}/data/enemies/qvoid.yaml -BITMAP|${PREFIX}/data/enemies/qvoid.gif -ANIMATION|${PREFIX}/data/enemies/robot.yaml -BITMAP|${PREFIX}/data/enemies/robot.gif -ANIMATION|${PREFIX}/data/enemies/sam.yaml -BITMAP|${PREFIX}/data/enemies/sam.gif -ANIMATION|${PREFIX}/data/enemies/shock.yaml -BITMAP|${PREFIX}/data/enemies/shock.gif -ANIMATION|${PREFIX}/data/enemies/sigmasua.yaml -BITMAP|${PREFIX}/data/enemies/sigmasua.gif -ANIMATION|${PREFIX}/data/enemies/spark.yaml -BITMAP|${PREFIX}/data/enemies/spark.gif -ANIMATION|${PREFIX}/data/enemies/special/aerojailer.yaml -BITMAP|${PREFIX}/data/enemies/special/aerojailer.gif -ANIMATION|${PREFIX}/data/enemies/special/arounder.yaml -BITMAP|${PREFIX}/data/enemies/special/arounder.gif -ANIMATION|${PREFIX}/data/enemies/special/pepe_rosita_job.yaml -BITMAP|${PREFIX}/data/enemies/special/pepe_rosita_job.gif -ANIMATION|${PREFIX}/data/enemies/special/shooting_star.yaml -BITMAP|${PREFIX}/data/enemies/special/shooting_star.gif -ANIMATION|${PREFIX}/data/enemies/spider.yaml -BITMAP|${PREFIX}/data/enemies/spider.gif -ANIMATION|${PREFIX}/data/enemies/tree_thing.yaml -BITMAP|${PREFIX}/data/enemies/tree_thing.gif -ANIMATION|${PREFIX}/data/enemies/tuno.yaml -BITMAP|${PREFIX}/data/enemies/tuno.gif -ANIMATION|${PREFIX}/data/enemies/tv_panel.yaml -BITMAP|${PREFIX}/data/enemies/tv_panel.gif -ANIMATION|${PREFIX}/data/enemies/tv.yaml -BITMAP|${PREFIX}/data/enemies/tv.gif -ANIMATION|${PREFIX}/data/enemies/upv_student.yaml -BITMAP|${PREFIX}/data/enemies/upv_student.gif -ANIMATION|${PREFIX}/data/enemies/wave.yaml -BITMAP|${PREFIX}/data/enemies/wave.gif -ANIMATION|${PREFIX}/data/enemies/z80.yaml -BITMAP|${PREFIX}/data/enemies/z80.gif - -# =================================================================== -# PLAYER -# =================================================================== -BITMAP|${PREFIX}/data/player/player.gif -ANIMATION|${PREFIX}/data/player/player.yaml -BITMAP|${PREFIX}/data/player/player2.gif -ANIMATION|${PREFIX}/data/player/player2.yaml -BITMAP|${PREFIX}/data/player/player_game_over.gif -ANIMATION|${PREFIX}/data/player/player_game_over.yaml - -# =================================================================== -# ITEMS -# =================================================================== -BITMAP|${PREFIX}/data/items/items.gif - -# =================================================================== -# MUSIC -# =================================================================== -MUSIC|${PREFIX}/data/music/title.ogg -MUSIC|${PREFIX}/data/music/game.ogg -MUSIC|${PREFIX}/data/music/loading_data1.ogg -MUSIC|${PREFIX}/data/music/loading_data2.ogg -MUSIC|${PREFIX}/data/music/loading_header.ogg -MUSIC|${PREFIX}/data/music/loading_screen_color.ogg -MUSIC|${PREFIX}/data/music/loading_screen_data.ogg -MUSIC|${PREFIX}/data/music/ending1.ogg -MUSIC|${PREFIX}/data/music/ending2.ogg -MUSIC|${PREFIX}/data/music/game_over.ogg - -# =================================================================== -# SOUND EFFECTS -# =================================================================== -SOUND|${PREFIX}/data/sound/item.wav -SOUND|${PREFIX}/data/sound/death.wav -SOUND|${PREFIX}/data/sound/notify.wav - -# Jump sounds (1-24) -SOUND|${PREFIX}/data/sound/jump1.wav -SOUND|${PREFIX}/data/sound/jump2.wav -SOUND|${PREFIX}/data/sound/jump3.wav -SOUND|${PREFIX}/data/sound/jump4.wav -SOUND|${PREFIX}/data/sound/jump5.wav -SOUND|${PREFIX}/data/sound/jump6.wav -SOUND|${PREFIX}/data/sound/jump7.wav -SOUND|${PREFIX}/data/sound/jump8.wav -SOUND|${PREFIX}/data/sound/jump9.wav -SOUND|${PREFIX}/data/sound/jump10.wav -SOUND|${PREFIX}/data/sound/jump11.wav -SOUND|${PREFIX}/data/sound/jump12.wav -SOUND|${PREFIX}/data/sound/jump13.wav -SOUND|${PREFIX}/data/sound/jump14.wav -SOUND|${PREFIX}/data/sound/jump15.wav -SOUND|${PREFIX}/data/sound/jump16.wav -SOUND|${PREFIX}/data/sound/jump17.wav -SOUND|${PREFIX}/data/sound/jump18.wav -SOUND|${PREFIX}/data/sound/jump19.wav -SOUND|${PREFIX}/data/sound/jump20.wav -SOUND|${PREFIX}/data/sound/jump21.wav -SOUND|${PREFIX}/data/sound/jump22.wav -SOUND|${PREFIX}/data/sound/jump23.wav -SOUND|${PREFIX}/data/sound/jump24.wav - -# =================================================================== -# LOGO -# =================================================================== -BITMAP|${PREFIX}/data/logo/jailgames.gif -BITMAP|${PREFIX}/data/logo/since_1998.gif - -# =================================================================== -# LOADING SCREEN -# =================================================================== -BITMAP|${PREFIX}/data/loading/loading_screen_bn.gif -BITMAP|${PREFIX}/data/loading/loading_screen_color.gif -BITMAP|${PREFIX}/data/loading/program_jaildoc.gif - -# =================================================================== -# TITLE SCREEN -# =================================================================== -BITMAP|${PREFIX}/data/title/title_logo.gif - -# =================================================================== -# ENDING SCREENS -# =================================================================== -BITMAP|${PREFIX}/data/ending/ending1.gif -BITMAP|${PREFIX}/data/ending/ending2.gif -BITMAP|${PREFIX}/data/ending/ending3.gif -BITMAP|${PREFIX}/data/ending/ending4.gif -BITMAP|${PREFIX}/data/ending/ending5.gif - -# =================================================================== -# CREDITS -# =================================================================== -BITMAP|${PREFIX}/data/credits/shine.gif -ANIMATION|${PREFIX}/data/credits/shine.yaml diff --git a/config/assets.yaml b/config/assets.yaml new file mode 100644 index 0000000..4ccbf27 --- /dev/null +++ b/config/assets.yaml @@ -0,0 +1,593 @@ +# JailDoctor's Dilemma - Asset Configuration +# Migrated from assets.txt to YAML format +# Variables: ${PREFIX}, ${SYSTEM_FOLDER} + +assets: + # FONTS + fonts: + - type: BITMAP + path: ${PREFIX}/data/font/smb2.gif + - type: FONT + path: ${PREFIX}/data/font/smb2.txt + - type: BITMAP + path: ${PREFIX}/data/font/aseprite.gif + - type: FONT + path: ${PREFIX}/data/font/aseprite.txt + - type: BITMAP + path: ${PREFIX}/data/font/gauntlet.gif + - type: FONT + path: ${PREFIX}/data/font/gauntlet.txt + - type: BITMAP + path: ${PREFIX}/data/font/subatomic.gif + - type: FONT + path: ${PREFIX}/data/font/subatomic.txt + - type: BITMAP + path: ${PREFIX}/data/font/8bithud.gif + - type: FONT + path: ${PREFIX}/data/font/8bithud.txt + + # PALETTES + palettes: + - type: PALETTE + path: ${PREFIX}/data/palette/zx-spectrum.pal + - type: PALETTE + path: ${PREFIX}/data/palette/zx-spectrum-adjusted.pal + - type: PALETTE + path: ${PREFIX}/data/palette/zxarne-5-2.pal + - type: PALETTE + path: ${PREFIX}/data/palette/black-and-white.pal + - type: PALETTE + path: ${PREFIX}/data/palette/green-phosphor.pal + - type: PALETTE + path: ${PREFIX}/data/palette/orange-screen.pal + - type: PALETTE + path: ${PREFIX}/data/palette/ruzx-spectrum.pal + - type: PALETTE + path: ${PREFIX}/data/palette/ruzx-spectrum-revision-2.pal + - type: PALETTE + path: ${PREFIX}/data/palette/pico-8.pal + - type: PALETTE + path: ${PREFIX}/data/palette/sweetie-16.pal + - type: PALETTE + path: ${PREFIX}/data/palette/island-joy-16.pal + - type: PALETTE + path: ${PREFIX}/data/palette/lost-century.pal + - type: PALETTE + path: ${PREFIX}/data/palette/na16.pal + - type: PALETTE + path: ${PREFIX}/data/palette/steam-lords.pal + + # SHADERS + shaders: + - type: DATA + path: ${PREFIX}/data/shaders/crtpi_vertex.glsl + - type: DATA + path: ${PREFIX}/data/shaders/crtpi_fragment.glsl + - type: DATA + path: ${PREFIX}/data/shaders/crtpi_vertex_es.glsl + - type: DATA + path: ${PREFIX}/data/shaders/crtpi_fragment_es.glsl + + # INPUT + input: + - type: DATA + path: ${PREFIX}/gamecontrollerdb.txt + + # SYSTEM + system: + - type: DATA + path: ${SYSTEM_FOLDER}/config.txt + required: false + absolute: true + - type: DATA + path: ${SYSTEM_FOLDER}/stats_buffer.csv + required: false + absolute: true + - type: DATA + path: ${SYSTEM_FOLDER}/stats.csv + required: false + absolute: true + - type: DATA + path: ${SYSTEM_FOLDER}/cheevos.bin + required: false + absolute: true + + # ROOMS + rooms: + - type: ROOM + path: ${PREFIX}/data/room/01.yaml + - type: ROOM + path: ${PREFIX}/data/room/02.yaml + - type: ROOM + path: ${PREFIX}/data/room/03.yaml + - type: ROOM + path: ${PREFIX}/data/room/04.yaml + - type: ROOM + path: ${PREFIX}/data/room/05.yaml + - type: ROOM + path: ${PREFIX}/data/room/06.yaml + - type: ROOM + path: ${PREFIX}/data/room/07.yaml + - type: ROOM + path: ${PREFIX}/data/room/08.yaml + - type: ROOM + path: ${PREFIX}/data/room/09.yaml + - type: ROOM + path: ${PREFIX}/data/room/10.yaml + - type: ROOM + path: ${PREFIX}/data/room/11.yaml + - type: ROOM + path: ${PREFIX}/data/room/12.yaml + - type: ROOM + path: ${PREFIX}/data/room/13.yaml + - type: ROOM + path: ${PREFIX}/data/room/14.yaml + - type: ROOM + path: ${PREFIX}/data/room/15.yaml + - type: ROOM + path: ${PREFIX}/data/room/16.yaml + - type: ROOM + path: ${PREFIX}/data/room/17.yaml + - type: ROOM + path: ${PREFIX}/data/room/18.yaml + - type: ROOM + path: ${PREFIX}/data/room/19.yaml + - type: ROOM + path: ${PREFIX}/data/room/20.yaml + - type: ROOM + path: ${PREFIX}/data/room/21.yaml + - type: ROOM + path: ${PREFIX}/data/room/22.yaml + - type: ROOM + path: ${PREFIX}/data/room/23.yaml + - type: ROOM + path: ${PREFIX}/data/room/24.yaml + - type: ROOM + path: ${PREFIX}/data/room/25.yaml + - type: ROOM + path: ${PREFIX}/data/room/26.yaml + - type: ROOM + path: ${PREFIX}/data/room/27.yaml + - type: ROOM + path: ${PREFIX}/data/room/28.yaml + - type: ROOM + path: ${PREFIX}/data/room/29.yaml + - type: ROOM + path: ${PREFIX}/data/room/30.yaml + - type: ROOM + path: ${PREFIX}/data/room/31.yaml + - type: ROOM + path: ${PREFIX}/data/room/32.yaml + - type: ROOM + path: ${PREFIX}/data/room/33.yaml + - type: ROOM + path: ${PREFIX}/data/room/34.yaml + - type: ROOM + path: ${PREFIX}/data/room/35.yaml + - type: ROOM + path: ${PREFIX}/data/room/36.yaml + - type: ROOM + path: ${PREFIX}/data/room/37.yaml + - type: ROOM + path: ${PREFIX}/data/room/38.yaml + - type: ROOM + path: ${PREFIX}/data/room/39.yaml + - type: ROOM + path: ${PREFIX}/data/room/40.yaml + - type: ROOM + path: ${PREFIX}/data/room/41.yaml + - type: ROOM + path: ${PREFIX}/data/room/42.yaml + - type: ROOM + path: ${PREFIX}/data/room/43.yaml + - type: ROOM + path: ${PREFIX}/data/room/44.yaml + - type: ROOM + path: ${PREFIX}/data/room/45.yaml + - type: ROOM + path: ${PREFIX}/data/room/46.yaml + - type: ROOM + path: ${PREFIX}/data/room/47.yaml + - type: ROOM + path: ${PREFIX}/data/room/48.yaml + - type: ROOM + path: ${PREFIX}/data/room/49.yaml + - type: ROOM + path: ${PREFIX}/data/room/50.yaml + - type: ROOM + path: ${PREFIX}/data/room/51.yaml + - type: ROOM + path: ${PREFIX}/data/room/52.yaml + - type: ROOM + path: ${PREFIX}/data/room/53.yaml + - type: ROOM + path: ${PREFIX}/data/room/54.yaml + - type: ROOM + path: ${PREFIX}/data/room/55.yaml + - type: ROOM + path: ${PREFIX}/data/room/56.yaml + - type: ROOM + path: ${PREFIX}/data/room/57.yaml + - type: ROOM + path: ${PREFIX}/data/room/58.yaml + - type: ROOM + path: ${PREFIX}/data/room/59.yaml + - type: ROOM + path: ${PREFIX}/data/room/60.yaml + + # TILESETS + tilesets: + - type: BITMAP + path: ${PREFIX}/data/tilesets/standard.gif + + # ENEMIES + enemies: + - type: ANIMATION + path: ${PREFIX}/data/enemies/abad_bell.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/abad_bell.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/abad.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/abad.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/amstrad_cs.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/amstrad_cs.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/flying_arounder.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/flying_arounder.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/stopped_arounder.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/stopped_arounder.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/walking_arounder.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/walking_arounder.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/arounders_door.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/arounders_door.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/arounders_machine.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/arounders_machine.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/bat.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/bat.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/batman_bell.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/batman_bell.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/batman_fire.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/batman_fire.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/batman.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/batman.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/bell.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/bell.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/bin.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/bin.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/bird.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/bird.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/breakout.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/breakout.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/bry.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/bry.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/chip.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/chip.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/code.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/code.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/congo.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/congo.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/crosshair.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/crosshair.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/demon.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/demon.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/dimallas.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/dimallas.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/floppy.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/floppy.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/dong.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/dong.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/guitar.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/guitar.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/heavy.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/heavy.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/jailer_#1.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/jailer_#1.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/jailer_#2.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/jailer_#2.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/jailer_#3.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/jailer_#3.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/jailbattle_alien.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/jailbattle_alien.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/jailbattle_human.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/jailbattle_human.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/jeannine.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/jeannine.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/lamp.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/lamp.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/lord_abad.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/lord_abad.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/matatunos.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/matatunos.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/mummy.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/mummy.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/paco.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/paco.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/elsa.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/elsa.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/qvoid.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/qvoid.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/robot.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/robot.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/sam.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/sam.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/shock.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/shock.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/sigmasua.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/sigmasua.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/spark.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/spark.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/special/aerojailer.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/special/aerojailer.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/special/arounder.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/special/arounder.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/special/pepe_rosita_job.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/special/pepe_rosita_job.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/special/shooting_star.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/special/shooting_star.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/spider.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/spider.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/tree_thing.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/tree_thing.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/tuno.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/tuno.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/tv_panel.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/tv_panel.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/tv.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/tv.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/upv_student.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/upv_student.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/wave.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/wave.gif + - type: ANIMATION + path: ${PREFIX}/data/enemies/z80.yaml + - type: BITMAP + path: ${PREFIX}/data/enemies/z80.gif + + # PLAYER + player: + - type: BITMAP + path: ${PREFIX}/data/player/player.gif + - type: ANIMATION + path: ${PREFIX}/data/player/player.yaml + - type: BITMAP + path: ${PREFIX}/data/player/player2.gif + - type: ANIMATION + path: ${PREFIX}/data/player/player2.yaml + - type: BITMAP + path: ${PREFIX}/data/player/player_game_over.gif + - type: ANIMATION + path: ${PREFIX}/data/player/player_game_over.yaml + + # ITEMS + items: + - type: BITMAP + path: ${PREFIX}/data/items/items.gif + + # MUSIC + music: + - type: MUSIC + path: ${PREFIX}/data/music/title.ogg + - type: MUSIC + path: ${PREFIX}/data/music/game.ogg + - type: MUSIC + path: ${PREFIX}/data/music/loading_data1.ogg + - type: MUSIC + path: ${PREFIX}/data/music/loading_data2.ogg + - type: MUSIC + path: ${PREFIX}/data/music/loading_header.ogg + - type: MUSIC + path: ${PREFIX}/data/music/loading_screen_color.ogg + - type: MUSIC + path: ${PREFIX}/data/music/loading_screen_data.ogg + - type: MUSIC + path: ${PREFIX}/data/music/ending1.ogg + - type: MUSIC + path: ${PREFIX}/data/music/ending2.ogg + - type: MUSIC + path: ${PREFIX}/data/music/game_over.ogg + + # SOUNDS + sounds: + - type: SOUND + path: ${PREFIX}/data/sound/item.wav + - type: SOUND + path: ${PREFIX}/data/sound/death.wav + - type: SOUND + path: ${PREFIX}/data/sound/notify.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump1.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump2.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump3.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump4.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump5.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump6.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump7.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump8.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump9.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump10.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump11.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump12.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump13.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump14.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump15.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump16.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump17.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump18.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump19.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump20.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump21.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump22.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump23.wav + - type: SOUND + path: ${PREFIX}/data/sound/jump24.wav + + # LOGO + logo: + - type: BITMAP + path: ${PREFIX}/data/logo/jailgames.gif + - type: BITMAP + path: ${PREFIX}/data/logo/since_1998.gif + + # LOADING + loading: + - type: BITMAP + path: ${PREFIX}/data/loading/loading_screen_bn.gif + - type: BITMAP + path: ${PREFIX}/data/loading/loading_screen_color.gif + - type: BITMAP + path: ${PREFIX}/data/loading/program_jaildoc.gif + + # TITLE + title: + - type: BITMAP + path: ${PREFIX}/data/title/title_logo.gif + + # ENDING + ending: + - type: BITMAP + path: ${PREFIX}/data/ending/ending1.gif + - type: BITMAP + path: ${PREFIX}/data/ending/ending2.gif + - type: BITMAP + path: ${PREFIX}/data/ending/ending3.gif + - type: BITMAP + path: ${PREFIX}/data/ending/ending4.gif + - type: BITMAP + path: ${PREFIX}/data/ending/ending5.gif + + # CREDITS + credits: + - type: BITMAP + path: ${PREFIX}/data/credits/shine.gif + - type: ANIMATION + path: ${PREFIX}/data/credits/shine.yaml diff --git a/source/core/resources/resource_helper.cpp b/source/core/resources/resource_helper.cpp index 8608733..d9dff2e 100644 --- a/source/core/resources/resource_helper.cpp +++ b/source/core/resources/resource_helper.cpp @@ -149,7 +149,7 @@ auto shouldUseResourcePack(const std::string& filepath) -> bool { std::string path = filepath; std::ranges::replace(path, '\\', '/'); - // Don't use pack for most config files (except config/assets.txt which is loaded + // Don't use pack for most config files (except config/assets.yaml which is loaded // directly via Loader::loadAssetsConfig() in release builds) if (path.find("config/") != std::string::npos) { return false; diff --git a/source/core/resources/resource_list.cpp b/source/core/resources/resource_list.cpp index bef783f..f846c22 100644 --- a/source/core/resources/resource_list.cpp +++ b/source/core/resources/resource_list.cpp @@ -11,7 +11,8 @@ #include // Para istringstream #include // Para runtime_error -#include "utils/utils.hpp" // Para getFileName, printWithDots +#include "external/fkyaml_node.hpp" // Para parsear YAML +#include "utils/utils.hpp" // Para getFileName, printWithDots namespace Resource { @@ -71,70 +72,87 @@ void List::loadFromFile(const std::string& config_file_path, const std::string& // Carga recursos desde un string de configuración (para release con pack) void List::loadFromString(const std::string& config_content, const std::string& prefix, const std::string& system_folder) { - std::istringstream stream(config_content); - std::string line; - int line_number = 0; + try { + // Parsear YAML + auto yaml = fkyaml::node::deserialize(config_content); - while (std::getline(stream, line)) { - ++line_number; - - // Limpiar espacios en blanco al principio y final - line.erase(0, line.find_first_not_of(" \t\r")); - line.erase(line.find_last_not_of(" \t\r") + 1); - - // Ignorar líneas vacías y comentarios - if (line.empty() || line[0] == '#' || line[0] == ';') { - continue; + // Verificar estructura básica + if (!yaml.contains("assets")) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Invalid assets.yaml format - missing 'assets' key"); + return; } - // Dividir la línea por el separador '|' - std::vector parts; - std::istringstream iss(line); - std::string part; + const auto& assets = yaml["assets"]; - while (std::getline(iss, part, '|')) { - parts.push_back(part); - } + // Iterar sobre cada categoría (fonts, palettes, etc.) + for (auto it = assets.begin(); it != assets.end(); ++it) { + const std::string& category = it.key().get_value(); + const auto& category_assets = it.value(); - // Verificar que tenemos al menos tipo y ruta - if (parts.size() < 2) { - SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, - "Warning: Malformed line %d in config (insufficient fields)", - line_number); - continue; - } - - try { - const std::string& type_str = parts[0]; - std::string path = parts[1]; - - // Valores por defecto - bool required = true; - bool absolute = false; - - // Si hay opciones en el tercer campo, parsearlas - if (parts.size() >= 3) { - parseOptions(parts[2], required, absolute); + // Verificar que es un array + if (!category_assets.is_sequence()) { + SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, + "Warning: Category '%s' is not a sequence, skipping", + category.c_str()); + continue; } - // Reemplazar variables en la ruta - path = replaceVariables(path, prefix, system_folder); + // Procesar cada asset en la categoría + for (const auto& asset : category_assets) { + try { + // Verificar campos obligatorios + if (!asset.contains("type") || !asset.contains("path")) { + SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, + "Warning: Asset in category '%s' missing 'type' or 'path', skipping", + category.c_str()); + continue; + } - // Parsear el tipo de asset - Type type = parseAssetType(type_str); + // Extraer campos + std::string type_str = asset["type"].get_value(); + std::string path = asset["path"].get_value(); - // Añadir al mapa - addToMap(path, type, required, absolute); + // Valores por defecto + bool required = true; + bool absolute = false; - } catch (const std::exception& e) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Error parsing line %d in config: %s", - line_number, - e.what()); + // Campos opcionales + if (asset.contains("required")) { + required = asset["required"].get_value(); + } + if (asset.contains("absolute")) { + absolute = asset["absolute"].get_value(); + } + + // Reemplazar variables en la ruta + path = replaceVariables(path, prefix, system_folder); + + // Parsear el tipo de asset + Type type = parseAssetType(type_str); + + // Añadir al mapa + addToMap(path, type, required, absolute); + + } catch (const std::exception& e) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "Error parsing asset in category '%s': %s", + category.c_str(), + e.what()); + } + } } - } - std::cout << "Loaded " << file_list_.size() << " assets from config" << '\n'; + std::cout << "Loaded " << file_list_.size() << " assets from YAML config" << '\n'; + + } catch (const fkyaml::exception& e) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "YAML parsing error: %s", + e.what()); + } catch (const std::exception& e) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "Error loading assets: %s", + e.what()); + } } // Devuelve la ruta completa a un fichero (búsqueda O(1)) diff --git a/source/core/resources/resource_loader.cpp b/source/core/resources/resource_loader.cpp index d8ed836..080f672 100644 --- a/source/core/resources/resource_loader.cpp +++ b/source/core/resources/resource_loader.cpp @@ -167,30 +167,30 @@ auto Loader::validatePack() const -> bool { return true; } -// Load assets.txt from pack +// Load assets.yaml from pack auto Loader::loadAssetsConfig() const -> std::string { if (!initialized_ || !resource_pack_ || !resource_pack_->isLoaded()) { std::cerr << "Loader: Cannot load assets config - pack not loaded\n"; return ""; } - // Try to load config/assets.txt from pack - std::string config_path = "config/assets.txt"; + // Try to load config/assets.yaml from pack + std::string config_path = "config/assets.yaml"; if (!resource_pack_->hasResource(config_path)) { - std::cerr << "Loader: assets.txt not found in pack: " << config_path << '\n'; + std::cerr << "Loader: assets.yaml not found in pack: " << config_path << '\n'; return ""; } auto data = resource_pack_->getResource(config_path); if (data.empty()) { - std::cerr << "Loader: Failed to load assets.txt from pack\n"; + std::cerr << "Loader: Failed to load assets.yaml from pack\n"; return ""; } // Convert bytes to string std::string config_content(data.begin(), data.end()); - std::cout << "Loader: Loaded assets.txt from pack (" << data.size() + std::cout << "Loader: Loaded assets.yaml from pack (" << data.size() << " bytes)\n"; return config_content; diff --git a/source/core/resources/resource_loader.hpp b/source/core/resources/resource_loader.hpp index b61c4e4..924bc45 100644 --- a/source/core/resources/resource_loader.hpp +++ b/source/core/resources/resource_loader.hpp @@ -36,7 +36,7 @@ class Loader { // Validate pack integrity (checksum) [[nodiscard]] auto validatePack() const -> bool; - // Load assets.txt from pack (for release builds) + // Load assets.yaml from pack (for release builds) [[nodiscard]] auto loadAssetsConfig() const -> std::string; // Cleanup diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index 30aba0e..c43db76 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -19,21 +19,21 @@ #include "core/resources/resource_list.hpp" // Para Asset, AssetType #include "core/resources/resource_loader.hpp" // Para ResourceLoader #ifdef _DEBUG -#include "core/system/debug.hpp" // Para Debug +#include "core/system/debug.hpp" // Para Debug #endif -#include "game/gameplay/cheevos.hpp" // Para Cheevos -#include "game/options.hpp" // Para Options, options, OptionsVideo -#include "game/scene_manager.hpp" // Para SceneManager -#include "game/scenes/credits.hpp" // Para Credits -#include "game/scenes/ending.hpp" // Para Ending -#include "game/scenes/ending2.hpp" // Para Ending2 -#include "game/scenes/game.hpp" // Para Game, GameMode -#include "game/scenes/game_over.hpp" // Para GameOver -#include "game/scenes/loading_screen.hpp" // Para LoadingScreen -#include "game/scenes/logo.hpp" // Para Logo -#include "game/scenes/title.hpp" // Para Title -#include "game/ui/notifier.hpp" // Para Notifier -#include "utils/defines.hpp" // Para WINDOW_CAPTION +#include "game/gameplay/cheevos.hpp" // Para Cheevos +#include "game/options.hpp" // Para Options, options, OptionsVideo +#include "game/scene_manager.hpp" // Para SceneManager +#include "game/scenes/credits.hpp" // Para Credits +#include "game/scenes/ending.hpp" // Para Ending +#include "game/scenes/ending2.hpp" // Para Ending2 +#include "game/scenes/game.hpp" // Para Game, GameMode +#include "game/scenes/game_over.hpp" // Para GameOver +#include "game/scenes/loading_screen.hpp" // Para LoadingScreen +#include "game/scenes/logo.hpp" // Para Logo +#include "game/scenes/title.hpp" // Para Title +#include "game/ui/notifier.hpp" // Para Notifier +#include "utils/defines.hpp" // Para WINDOW_CAPTION #ifndef _WIN32 #include @@ -83,18 +83,18 @@ Director::Director(std::vector const& args) { exit(EXIT_FAILURE); } - // 3. Load assets.txt from pack + // 3. Load assets.yaml from pack std::cout << "Loading assets configuration from pack..." << '\n'; std::string assets_config = Resource::Loader::get().loadAssetsConfig(); if (assets_config.empty()) { - std::cerr << "ERROR: Failed to load assets.txt from pack\n"; + std::cerr << "ERROR: Failed to load assets.yaml from pack\n"; exit(EXIT_FAILURE); } // 4. Initialize Asset system with config from pack // NOTE: In release, don't use executable_path or PREFIX - paths in pack are relative // Pass empty string to avoid issues when running from different directories - Resource::List::init(""); // Empty executable_path in release + Resource::List::init(""); // Empty executable_path in release Resource::List::get()->loadFromString(assets_config, "", system_folder_); // Empty PREFIX for pack std::cout << "Asset system initialized from pack\n"; @@ -267,7 +267,7 @@ auto Director::setFileList() -> bool { #endif // Construir ruta al archivo de configuración de assets - std::string config_path = executable_path_ + PREFIX + "/config/assets.txt"; + std::string config_path = executable_path_ + PREFIX + "/config/assets.yaml"; // Cargar todos los assets desde el archivo de configuración Resource::List::get()->loadFromFile(config_path, PREFIX, system_folder_); diff --git a/tools/pack_resources/pack_resources.cpp b/tools/pack_resources/pack_resources.cpp index b97aacb..8ad6fd9 100644 --- a/tools/pack_resources/pack_resources.cpp +++ b/tools/pack_resources/pack_resources.cpp @@ -35,10 +35,10 @@ auto handleDefaultPack() -> int { return 1; } - // Add config/assets.txt to pack (required for release builds) + // Add config/assets.yaml to pack (required for release builds) std::cout << "\nAdding config files...\n"; - if (!pack.addFile("config/assets.txt", "config/assets.txt")) { - std::cerr << "Warning: Failed to add config/assets.txt (optional)\n"; + if (!pack.addFile("config/assets.yaml", "config/assets.yaml")) { + std::cerr << "Warning: Failed to add config/assets.yaml (optional)\n"; } if (!pack.savePack(output_file)) { @@ -86,10 +86,10 @@ auto handlePackDirectory(const std::string& input_dir, const std::string& output return 1; } - // Add config/assets.txt to pack (required for release builds) + // Add config/assets.yaml to pack (required for release builds) std::cout << "\nAdding config files...\n"; - if (!pack.addFile("config/assets.txt", "config/assets.txt")) { - std::cerr << "Warning: Failed to add config/assets.txt (optional)\n"; + if (!pack.addFile("config/assets.yaml", "config/assets.yaml")) { + std::cerr << "Warning: Failed to add config/assets.yaml (optional)\n"; } if (!pack.savePack(output_file)) {