eliminades referencies antigues
This commit is contained in:
930
CLAUDE.md
930
CLAUDE.md
@@ -23,90 +23,15 @@ Se han renombrado las referencias de `JailDoctor's Dilemma` → `Projecte 2026`
|
||||
- El publisher `jailgames` (carpeta de config de sistema: `~/.config/jailgames/projecte_2026`).
|
||||
- Los archivos `release/windows/jdd.rc` y `jdd.res` (solo bundlean el icono).
|
||||
|
||||
## Log de cambios realizados (sesiones de trabajo)
|
||||
## Pendiente
|
||||
|
||||
### Eliminaciones
|
||||
- **Clase `Stats` (persistencia CSV de muertes/visitas)** eliminada por completo: archivos `source/game/gameplay/stats.hpp/cpp`, entrada en CMakeLists, referencias en `Game` scene (`stats_`, `initStats()`, `addVisit/addDeath`), ficheros `stats.csv`/`stats_buffer.csv` en `config/assets.yaml`, patrón `*stats.txt` en `.gitignore`, campo `worst_nightmare` en `Options::Stats` + `Defaults::Stats::WORST_NIGHTMARE`, display de "worst nightmare" en `game_over.cpp`/`.hpp`, traducciones en locales, menciones en docs.
|
||||
- **Mantenido:** `Options::stats.items` y `Options::stats.rooms` — son contadores de runtime del marcador/game_over, no tienen persistencia CSV. Coincidencia de nombre con la clase Stats eliminada.
|
||||
|
||||
### Música
|
||||
- Eliminadas las 10 pistas originales (14 MB) de `data/music/`.
|
||||
- Copiadas 2 pistas de `../pollo/data/music/`: `574070_KUVO_Farewell_to_school.ogg` y `574071_EA_DTV.ogg` (7 MB total).
|
||||
- `config/assets.yaml` reducido a esas 2 entradas.
|
||||
- Las 10 llamadas `playMusic()` existentes (title/game/loading_*/ending*/game_over) remapeadas alternadamente a una de las 2 pistas. Mapeo concreto en esta misma documentación si hace falta consultarlo (ver git log del cambio).
|
||||
|
||||
### Paleta
|
||||
- Eliminadas las 23 paletas ZX Spectrum/otras de `data/palette/`.
|
||||
- Traída `cpc.pal` de `../pollo/data/palettes/` (JASC-PAL, 28 entradas: CLEAR+27 colores CPC).
|
||||
- `config/assets.yaml`: solo `cpc.pal`.
|
||||
- `Defaults::Video::PALETTE_NAME = "cpc"`.
|
||||
- Traída la clase `Color` de pollo a `source/utils/color.hpp` + `color.cpp` (enum `Color::Cpc` con 28 valores 0-27 + `Color::fromString()`).
|
||||
- Struct RGB `Color` en `utils.hpp` **renombrada a `Rgb`** para evitar conflicto con la nueva clase. Propagado a `utils.cpp` (`colorAreEqual`), `screen.hpp`/`.cpp` (`clearRenderer`).
|
||||
- Añadido `source/utils/color.cpp` a `CMakeLists.txt`.
|
||||
- **Pendiente de revisar:** enum `PaletteColor` en `utils.hpp` sigue con los 16 índices antiguos (ZX Spectrum). Los índices 0-4 coinciden con CPC, pero 5+ mapean a colores diferentes (ej. `PaletteColor::BRIGHT_RED=5` ahora renderiza MAGENTA en CPC). `stringToColor()` también sin actualizar. `SPECTRUM_REFERENCE` en `palette_manager.cpp` sigue siendo la referencia ZX Spectrum de 16 colores. Falta decidir cómo migrar estos tres puntos cuando se vea el resultado visual.
|
||||
- **`next()`/`previous()` en PaletteManager**: con una sola paleta hacen wrap al mismo índice (no crashean). El concepto de ciclar paletas queda desactivado de facto; posible futura reutilización para ciclar modos de ordenación.
|
||||
|
||||
### Otros
|
||||
- Añadidos `desktop.ini` y `Thumbs.db` al `.gitignore`.
|
||||
|
||||
### Transiciones de pantalla (sesión abril 2026)
|
||||
- **Cambio de pantalla por punto central:** `Player::handleBorders()` usa el centro del rectángulo del jugador para detectar cambio de pantalla (antes usaba bordes).
|
||||
- **Conservación de momento:** `Player::switchBorders()` conserva velocidad y estado al cambiar de pantalla (antes forzaba ON_GROUND y reseteaba vy_).
|
||||
- **Transición animada con scroll:** Al cambiar de habitación, ambas rooms se desplazan con easing `cubicInOut` durante 0.5s.
|
||||
- Render offset global añadido a `Screen` (`setRenderOffset`) aplicado en los 6 métodos de `Surface::render()`.
|
||||
- Enemigos de ambas habitaciones se actualizan durante la transición.
|
||||
- El jugador puede moverse durante la transición.
|
||||
- Estado en `Game`: `transitioning_`, `transition_timer_`, `transition_old_room_`, `transition_direction_`.
|
||||
- Ficheros: `screen.hpp/cpp`, `surface.cpp`, `game.hpp/cpp`.
|
||||
|
||||
### Impulso de salto
|
||||
- `JUMP_VELOCITY` incrementado 5%: de -170.0 a -178.5.
|
||||
|
||||
### Collision tilemap (sesión abril 2026)
|
||||
- **Formato YAML nuevo:** `tilemap:` tiene dos sub-mapas: `draw:` (tilemap de dibujo, el original) y `collision:` (mapa de colisiones). `RoomLoader::parseTilemap()` lee ambos con fallback al formato antiguo.
|
||||
- **`Room::Data::collision_tile_map`** — vector<int> con tipos: 0=vacío, 1=muro, 2=plataforma, 3=slope_l, 4=slope_r, 5=kill, 6=conveyor.
|
||||
- **CollisionMap migrado:** `getTile()` lee directamente del `collision_tile_map` (antes deducía el tipo por rangos de índice del tileset de dibujo). Constructor ya no necesita `tile_set_width`.
|
||||
- **Editor de colisiones:** Tecla 7 o `EDIT DRAW`/`EDIT COLLISION` alterna entre editar el tilemap de dibujo y el de colisiones. En modo collision se superpone el `collision.gif` (7 tiles) sobre el mapa de dibujo. Right-click abre el tile picker del tileset correspondiente. `RoomSaver` guarda ambos sub-mapas.
|
||||
- **`collision.gif`** registrado en `assets.yaml` (7 tiles: vacío, muro, plataforma, slope_l, slope_r, kill, conveyor).
|
||||
|
||||
### Nuevo motor de colisiones tile-based (sesión abril 2026)
|
||||
- **Clase `TileCollider`** (`source/game/gameplay/tile_collider.hpp/cpp`): queries directas contra el grid de tiles sin listas de superficies intermedias. API: `checkWallLeft/Right`, `checkCeiling`, `checkFloor` (con FloorHit struct), `hasGroundBelow`, `checkSlopeBelow` (con SlopeInfo struct), `getSlopeY`.
|
||||
- Integrado en `CollisionMap` (miembro + getter) y expuesto via `Room::getTileCollider()`.
|
||||
- **Player reescrito** con pipeline de 6 fases claras:
|
||||
1. `handleInput()` — leer input
|
||||
2. `updateVelocity()` + `applyGravity()` — calcular velocidades
|
||||
3. `handleJumpAndDrop()` — salto + drop-through (plataformas y slopes con DOWN)
|
||||
4. `moveHorizontal()` + `moveVertical()` — movimiento con colisión tile-based
|
||||
5. `checkFalling()` — detectar caída
|
||||
6. `syncSpriteAndCollider()` + `animate()` + `handleBorders()`
|
||||
- **~20 métodos eliminados** del Player antiguo. Slopes gestionadas por tile (slope_tile_x/y/type) en vez de puntero a LineDiagonal.
|
||||
- **Sistema antiguo de superficies preservado** en CollisionMap (no eliminado), simplemente ya no usado por Player.
|
||||
- **Slopes — escalera diagonal de tiles:**
|
||||
- Las slopes de 45° se pintan como escalera en el collision tilemap: cada tile una fila arriba/abajo y una columna al lado.
|
||||
- `checkSlopeBelow`: escanea la fila de los pies Y la de arriba (la slope entry siempre está una fila arriba del suelo).
|
||||
- `followSlope`: busca el siguiente tile de slope en la fila actual Y la de abajo (para descenso en escalera).
|
||||
- `exitSlope`: comprueba suelo en `foot_y` y `foot_y+1` (boundary de fila al salir por abajo) y snapea al borde del tile.
|
||||
- **Drop-through — sin flags, puramente posicional:**
|
||||
- Al pulsar DOWN sobre slope/plataforma: `y_ += 1` y ON_AIR. No hay flags `dropping_through_`.
|
||||
- `checkFloor` para PASSABLE: solo aterriza si `foot_y_current <= tile_top` (pies estaban por encima).
|
||||
- `checkFloor` para slopes: solo aterriza si `foot_y_current <= slope_y` (pies por encima de la superficie).
|
||||
- `isInsideAnySlope()`: si algún pie está por debajo de la superficie de cualquier slope que solape, bloquea TODOS los aterrizajes en slopes. Esto asegura que al hacer drop o saltar desde abajo, el jugador atraviesa toda la escalera de slopes sin quedarse pegado.
|
||||
- **Kill tiles (tipo 5):** implementados en `TileCollider::touchesKillTile()`. Comprueba si el rectángulo del jugador solapa algún tile KILL. Se llama en `Player::update()` después del movimiento.
|
||||
- **Motor antiguo eliminado:**
|
||||
- `CollisionMap` reducido a wrapper mínimo: solo contiene `collision_tile_map_`, `conveyor_belt_direction_` y `TileCollider`.
|
||||
- Eliminados de `CollisionMap`: enum `Tile` antiguo, `getTile()`, `getSlopeHeight()`, todas las listas de superficies (`bottom_floors_`, `top_floors_`, etc.), todos los `check*Surfaces()`, `initializeSurfaces()`, `collect*Tiles()`, `buildHorizontalLines()`, `set*Surfaces()`.
|
||||
- Eliminados de `Room`: enum `Tile`, `getTile()`, `getSlopeHeight()`, `getTileSize()`, todos los `check*()` delegados, `getSlopeAtPoint()`.
|
||||
- Eliminados de `utils.hpp/cpp`: structs `LineHorizontal`, `LineVertical`, `LineDiagonal`, `Line` y todos los `checkCollision` / `normalizeLine` que los usaban.
|
||||
- `TilemapRenderer`: eliminado `renderDebugCollisionSurfaces()` (pintaba líneas de superficies). Modo debug (tecla 0) ahora renderiza el collision tilemap usando `collision.gif`.
|
||||
- `TilemapRenderer::setAnimatedTiles()` ahora lee del `collision_tile_map` (valor 6 = conveyor) en vez de `CollisionMap::getTile()`.
|
||||
- **Pendiente:** tile 6 (conveyor) no soportado aún en el nuevo motor de Player.
|
||||
|
||||
### Otros
|
||||
- Añadidos `desktop.ini` y `Thumbs.db` al `.gitignore`.
|
||||
- **PaletteColor enum** en `utils.hpp` sigue con los 16 índices antiguos (ZX Spectrum). Los índices 0-4 coinciden con CPC, pero 5+ mapean a colores diferentes (ej. `PaletteColor::BRIGHT_RED=5` ahora renderiza MAGENTA en CPC). `stringToColor()` y `SPECTRUM_REFERENCE` en `palette_manager.cpp` tampoco están actualizados. Falta decidir cómo migrar cuando se vea el resultado visual.
|
||||
- **Tile 6 (conveyor)** no soportado aún en el nuevo motor de Player.
|
||||
- **`next()`/`previous()` en PaletteManager** desactivados de facto (solo 1 paleta). Posible futura reutilización para ciclar modos de ordenación.
|
||||
|
||||
---
|
||||
|
||||
## Overview (legacy)
|
||||
## Overview
|
||||
|
||||
**Projecte 2026** is a retro-style 2D puzzle platformer game built in C++20 using SDL3 for graphics and audio. The game features 60+ rooms, collectible items, enemies, and an achievement system. It targets multiple platforms (Windows, macOS, Linux) with a focus on retro aesthetics and precise collision detection.
|
||||
|
||||
@@ -190,11 +115,13 @@ xvfb-run -a -s "-screen 0 1280x720x24" ./projecte_2026
|
||||
- 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:
|
||||
|
||||
#### clang-tidy (Modernization & Best Practices)
|
||||
### clang-tidy (Modernization & Best Practices)
|
||||
|
||||
**Purpose:** Detects style issues, modernization opportunities, and potential bugs. Best for refactoring and applying C++20 best practices.
|
||||
|
||||
@@ -214,18 +141,11 @@ tools/linter/run_clang-tidy.sh --fix source/game/entities/player.cpp
|
||||
tools/linter/run_clang-tidy.sh
|
||||
```
|
||||
|
||||
**Common clang-tidy Checks:**
|
||||
- `modernize-*`: C++ modernization (use auto, range-for, etc.)
|
||||
- `readability-*`: Code readability improvements
|
||||
- `performance-*`: Performance optimizations
|
||||
- `bugprone-*`: Potential bug detection
|
||||
|
||||
**Known False Positives:**
|
||||
- `defaults.hpp`: May report errors in constant definitions
|
||||
- `readability-magic-numbers`: Acceptable for game constants (block sizes, speeds, etc.)
|
||||
- `cppcoreguidelines-avoid-magic-numbers`: Same as above, acceptable in game code
|
||||
- `readability-magic-numbers` / `cppcoreguidelines-avoid-magic-numbers`: Acceptable for game constants (block sizes, speeds, etc.)
|
||||
|
||||
#### cppcheck (Bug Detection & Memory Safety)
|
||||
### cppcheck (Bug Detection & Memory Safety)
|
||||
|
||||
**Purpose:** Detects bugs, memory leaks, undefined behavior, and style issues. Complementary to clang-tidy.
|
||||
|
||||
@@ -245,19 +165,12 @@ tools/linter/run_cppcheck.sh -w
|
||||
|
||||
**Output:** Results are saved in `tools/linter/cppcheck-result-*.txt`
|
||||
|
||||
**Common cppcheck Checks:**
|
||||
- Memory leaks and resource management
|
||||
- Null pointer dereferences
|
||||
- Buffer overflows and array bounds
|
||||
- Uninitialized variables
|
||||
- Dead code and unused functions
|
||||
|
||||
**Known False Positives:**
|
||||
- `unusedFunction`: May report false positives for callback functions or public API methods
|
||||
- `passedByValue`: Acceptable for small types like SDL_FRect in game code
|
||||
- `constParameter`: Not always applicable for API consistency
|
||||
|
||||
#### When to Use Each Tool
|
||||
### When to Use Each Tool
|
||||
|
||||
| Scenario | Tool | Reason |
|
||||
|----------|------|--------|
|
||||
@@ -267,16 +180,7 @@ tools/linter/run_cppcheck.sh -w
|
||||
| **Hunting memory leaks** | cppcheck | Specialized detection |
|
||||
| **Code modernization** | clang-tidy --fix | Automatic C++20 upgrades |
|
||||
|
||||
#### Best Practices
|
||||
|
||||
1. **Run linters after compilation succeeds** - Fix compile errors first
|
||||
2. **Analyze specific files** - Faster feedback, avoids unrelated errors
|
||||
3. **Review before applying --fix** - Understand changes before accepting
|
||||
4. **Context matters** - Game code may legitimately have "magic numbers" for gameplay constants
|
||||
5. **Use both tools** - They catch different issues and complement each other
|
||||
6. **Check suppressions file** - `tools/linter/cppcheck_suppressions` excludes external/ and system headers
|
||||
|
||||
#### Integration with Development Workflow
|
||||
### Integration with Development Workflow
|
||||
|
||||
When refactoring code (especially with `/refactor-class` command):
|
||||
1. Make structural changes
|
||||
@@ -291,813 +195,7 @@ When refactoring code (especially with `/refactor-class` command):
|
||||
|
||||
---
|
||||
|
||||
## 1. High-Level Architecture Overview
|
||||
|
||||
The architecture follows a **layered, modular design** with clear separation of concerns:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Application Layer │
|
||||
│ (Director, Scene Manager) │
|
||||
└─────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────┐
|
||||
│ Game Logic Layer │
|
||||
│ (Game Scene, Entities, Gameplay) │
|
||||
└─────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────┐
|
||||
│ Core Systems Layer │
|
||||
│ (Rendering, Audio, Input, Resources)│
|
||||
└─────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────┐
|
||||
│ SDL3 & External Libraries │
|
||||
│ (jail_audio, stb_image, stb_vorbis) │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Key Design Principles
|
||||
|
||||
- **Singleton Pattern:** Core systems (Director, Screen, Audio, Input, Resource, Asset) use singleton pattern for global access
|
||||
- **Scene-Based Architecture:** Game flow managed through discrete scenes (Logo, Title, Loading, Game, Ending, etc.)
|
||||
- **Component-Based Entities:** Player, enemies, and items are discrete entities with render/update patterns
|
||||
- **Resource Management:** All assets (textures, sounds, animations, tilemaps) cached through Resource singleton
|
||||
- **Delta Time:** Frame-rate independent physics using DeltaTimer class
|
||||
|
||||
---
|
||||
|
||||
## 2. Directory Structure
|
||||
|
||||
```
|
||||
source/
|
||||
├── core/ # Core engine systems
|
||||
│ ├── audio/ # Audio management
|
||||
│ │ ├── audio.hpp/cpp # Audio singleton (music, sounds, volumes)
|
||||
│ │ └── jail_audio.hpp # Custom jail_audio library wrapper
|
||||
│ ├── input/ # Input handling
|
||||
│ │ ├── input.hpp/cpp # Input manager (keyboard, gamepad)
|
||||
│ │ ├── input_types.hpp # Input type definitions
|
||||
│ │ ├── global_inputs.hpp # Global input state
|
||||
│ │ └── mouse.hpp # Mouse input
|
||||
│ ├── locale/ # Localization
|
||||
│ │ └── locale.hpp # Locale/language support
|
||||
│ ├── rendering/ # Graphics rendering
|
||||
│ │ ├── screen.hpp/cpp # Screen/window singleton, SDL renderer
|
||||
│ │ ├── surface.hpp/cpp # 8-bit indexed color surface abstraction
|
||||
│ │ ├── sprite/ # Sprite rendering classes
|
||||
│ │ │ ├── sprite.hpp # Static sprite rendering
|
||||
│ │ │ ├── animated_sprite.hpp # Animated sprite with frame data
|
||||
│ │ │ ├── moving_sprite.hpp # Moving sprite with velocity
|
||||
│ │ │ └── dissolve_sprite.hpp # Dissolve transition sprite
|
||||
│ │ ├── text.hpp/cpp # Text rendering system
|
||||
│ │ ├── gif.hpp/cpp # GIF image loader
|
||||
│ │ ├── pixel_reveal.hpp # Pixel reveal effect
|
||||
│ │ ├── render_info.hpp # Render information data
|
||||
│ │ ├── palette_manager.hpp # Palette management
|
||||
│ │ ├── sdl3gpu/ # SDL3 GPU shader backend
|
||||
│ │ │ ├── sdl3gpu_shader.hpp/cpp # CRT/post-processing shader effects
|
||||
│ │ │ └── *_spv.h # Pre-compiled SPIR-V shader headers
|
||||
│ │ └── shader_backend.hpp # Abstract shader interface
|
||||
│ ├── resources/ # Asset & Resource management
|
||||
│ │ ├── resource_list.hpp # Asset path registry (O(1) lookups)
|
||||
│ │ ├── resource_cache.hpp # Resource caching singleton
|
||||
│ │ ├── resource_loader.hpp # Asset loading logic
|
||||
│ │ ├── resource_pack.hpp # Resource pack handling
|
||||
│ │ ├── resource_helper.hpp # Resource utility functions
|
||||
│ │ └── resource_types.hpp # Resource type definitions
|
||||
│ └── system/ # System management
|
||||
│ ├── director.hpp/cpp # Main application controller
|
||||
│ ├── debug.hpp/cpp # Debug info overlay
|
||||
│ └── global_events.hpp/cpp # Global event broadcasting
|
||||
├── game/ # Game-specific logic
|
||||
│ ├── entities/ # Game objects
|
||||
│ │ ├── player.hpp/cpp # Player entity with physics
|
||||
│ │ ├── enemy.hpp/cpp # Enemy entities
|
||||
│ │ └── item.hpp/cpp # Collectible items
|
||||
│ ├── gameplay/ # Core gameplay systems
|
||||
│ │ ├── room.hpp/cpp # Room/level logic, collision
|
||||
│ │ ├── room_loader.hpp/cpp # Room loading from YAML files
|
||||
│ │ ├── room_tracker.hpp/cpp # Tracks visited rooms
|
||||
│ │ ├── collision_map.hpp/cpp # Collision map data
|
||||
│ │ ├── tilemap_renderer.hpp/cpp # Tilemap rendering
|
||||
│ │ ├── enemy_manager.hpp/cpp # Enemy lifecycle management
|
||||
│ │ ├── item_manager.hpp/cpp # Item lifecycle management
|
||||
│ │ ├── scoreboard.hpp/cpp # Score display & data
|
||||
│ │ ├── item_tracker.hpp/cpp # Tracks collected items
|
||||
│ │ └── cheevos.hpp/cpp # Achievement system
|
||||
│ ├── scenes/ # Game scenes (flow states)
|
||||
│ │ ├── logo.hpp/cpp # JailGames logo screen
|
||||
│ │ ├── loading_screen.hpp/cpp # Resource loading progress
|
||||
│ │ ├── title.hpp/cpp # Title screen & menus
|
||||
│ │ ├── game.hpp/cpp # Main gameplay loop
|
||||
│ │ ├── game_over.hpp/cpp # Game over screen
|
||||
│ │ ├── ending.hpp/cpp # Ending sequence 1
|
||||
│ │ ├── ending2.hpp/cpp # Ending sequence 2
|
||||
│ │ └── credits.hpp/cpp # Credits screen
|
||||
│ ├── ui/ # User interface
|
||||
│ │ ├── notifier.hpp/cpp # Achievement/notification display
|
||||
│ │ ├── console.hpp/cpp # In-game debug console
|
||||
│ │ └── console_commands.hpp/cpp # Console command definitions
|
||||
│ ├── options.hpp/cpp # Game configuration/options
|
||||
│ ├── game_control.hpp # Game control logic
|
||||
│ ├── scene_manager.hpp # Scene flow state machine
|
||||
│ └── defaults.hpp # Game defaults constants
|
||||
├── external/ # Third-party libraries
|
||||
│ ├── fkyaml_node.hpp # YAML parsing library
|
||||
│ ├── stb_image.h # Image loading library
|
||||
│ └── stb_vorbis.h # OGG Vorbis audio decoding
|
||||
├── utils/ # Utility code
|
||||
│ ├── delta_timer.hpp/cpp # Frame-rate independent timing
|
||||
│ ├── easing_functions.hpp # Easing/interpolation functions
|
||||
│ ├── defines.hpp # Game constants (resolutions, block sizes)
|
||||
│ └── utils.hpp/cpp # Helper functions (colors, math)
|
||||
└── main.cpp # Application entry point
|
||||
|
||||
config/ # Configuration files
|
||||
└── assets.yaml # Asset registry (text-based configuration)
|
||||
|
||||
data/ # Game assets
|
||||
├── font/ # Bitmap fonts + descriptors
|
||||
├── palette/ # Color palettes (.pal files)
|
||||
├── shaders/ # GLSL vertex/fragment shaders
|
||||
├── room/ # Tilemaps & room definitions (01.tmx-60.tmx)
|
||||
├── tilesets/ # Tileset graphics
|
||||
├── enemies/ # Enemy sprites & animations
|
||||
├── player/ # Player sprites & animations
|
||||
├── items/ # Item sprite sheets
|
||||
├── music/ # Background music (OGG)
|
||||
├── sound/ # Sound effects (WAV)
|
||||
├── logo/ # Logo images
|
||||
├── loading/ # Loading screen graphics
|
||||
├── title/ # Title screen graphics
|
||||
├── ending/ # Ending sequence images
|
||||
└── credits/ # Credits screen assets
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Key Architectural Patterns
|
||||
|
||||
### 3.1 Singleton Pattern (Core Systems)
|
||||
|
||||
Most core systems use thread-safe singleton pattern:
|
||||
|
||||
```cpp
|
||||
class Screen {
|
||||
private:
|
||||
static Screen* screen_; // Singleton instance
|
||||
Screen(); // Private constructor
|
||||
~Screen();
|
||||
public:
|
||||
static void init(); // Creates singleton
|
||||
static void destroy(); // Destroys singleton
|
||||
static Screen* get(); // Accesses singleton
|
||||
};
|
||||
```
|
||||
|
||||
**Singleton Systems:**
|
||||
- `Screen` - Rendering, window management, palette/shader effects
|
||||
- `Input` - Keyboard & gamepad input binding and checking
|
||||
- `Audio` - Music and sound effect playback
|
||||
- `Resource::Cache` - Asset loading, caching, streaming (with error handling)
|
||||
- `Resource::List` - Asset path registry from assets.yaml (O(1) lookups)
|
||||
- `Director` - Main application controller
|
||||
- `Cheevos` - Achievement state management
|
||||
- `Debug` - Debug information overlay
|
||||
|
||||
### 3.2 Scene-Based State Machine
|
||||
|
||||
The game uses a scene manager to control application flow:
|
||||
|
||||
```cpp
|
||||
// namespace SceneManager
|
||||
enum class Scene {
|
||||
LOGO, LOADING_SCREEN, TITLE, CREDITS, GAME, DEMO,
|
||||
GAME_OVER, ENDING, ENDING2, RESTART_CURRENT, QUIT
|
||||
};
|
||||
|
||||
inline Scene current = Scene::LOGO; // Global scene state
|
||||
inline Options options = ...; // Transition options
|
||||
```
|
||||
|
||||
**Scene Hierarchy:**
|
||||
- Each scene runs its own update/render loop
|
||||
- `Director` switches between scenes based on `SceneManager::current`
|
||||
- Scenes can request transitions via `SceneManager::current` assignment
|
||||
|
||||
### 3.3 Entity-Component Pattern (Simplified)
|
||||
|
||||
Entities (Player, Enemies, Items) have:
|
||||
- **Update** - Logic, physics, animation
|
||||
- **Render** - Draw to screen surface
|
||||
- **Collision** - Hit detection (player collides with room, enemies, items)
|
||||
|
||||
### 3.4 Surface-Based Rendering Pipeline
|
||||
|
||||
The rendering system uses a **8-bit indexed color** pipeline:
|
||||
|
||||
```
|
||||
SurfaceData (pixel buffer)
|
||||
↓
|
||||
Surface (palette + rendering operations)
|
||||
↓
|
||||
SDL_Texture (GPU texture)
|
||||
↓
|
||||
SDL_Renderer (to SDL_Window)
|
||||
↓
|
||||
Display
|
||||
```
|
||||
|
||||
**Key Components:**
|
||||
- `Surface` - 8-bit indexed pixel buffer with palette support
|
||||
- `Sprite` - Renders a fixed region of a surface
|
||||
- `AnimatedSprite` - Frame-based animation on top of sprite
|
||||
- `MovingSprite` - Adds velocity/position to animated sprite
|
||||
- `DissolveSprite` - Dissolve transition effect sprite
|
||||
- Supports color replacement, palette swapping, and shader effects (CRT)
|
||||
|
||||
### 3.5 Tile-Based Collision System
|
||||
|
||||
Rooms use a sophisticated collision detection system:
|
||||
|
||||
```cpp
|
||||
class Room {
|
||||
std::vector<LineHorizontal> bottom_floors_; // Ground surfaces
|
||||
std::vector<LineHorizontal> top_floors_; // Ceiling surfaces
|
||||
std::vector<LineVertical> left_walls_; // Left walls
|
||||
std::vector<LineVertical> right_walls_; // Right walls
|
||||
std::vector<LineDiagonal> left_slopes_; // Ramps going left
|
||||
std::vector<LineDiagonal> right_slopes_; // Ramps going right
|
||||
std::vector<LineHorizontal> conveyor_belt_floors_; // Moving platforms
|
||||
};
|
||||
```
|
||||
|
||||
**Collision Detection:**
|
||||
- Player has collision points and "feet" points for fine-grained detection
|
||||
- Room provides `check*Surfaces()` methods for collision resolution
|
||||
- Supports ramps, slopes, conveyor belts, and auto-surfaces
|
||||
- Enemies have axis-aligned bounding boxes
|
||||
|
||||
### 3.6 Sprite Animation System
|
||||
|
||||
Animation is data-driven:
|
||||
|
||||
```cpp
|
||||
struct AnimationData {
|
||||
std::string name;
|
||||
std::vector<SDL_FRect> frames; // Frame rectangles
|
||||
int speed; // Milliseconds per frame
|
||||
int loop; // Frame to return to (-1 = no loop)
|
||||
bool completed;
|
||||
int current_frame;
|
||||
int counter;
|
||||
};
|
||||
|
||||
// Loaded from .yaml animation definition files
|
||||
// Rendered with AnimatedSprite
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. System Interactions & Data Flow
|
||||
|
||||
### 4.1 Application Lifecycle
|
||||
|
||||
```
|
||||
main()
|
||||
↓
|
||||
Director::Director() [Initialization]
|
||||
├─ Resource::List::init() - Initialize asset registry singleton
|
||||
├─ Director::setFileList() - Load assets.yaml via Resource::List (no verification)
|
||||
├─ Options::loadFromFile() - Load game configuration
|
||||
├─ Audio::init() - Initialize SDL audio
|
||||
├─ Screen::init() - Create window, SDL renderer
|
||||
├─ Input::init() - Bind keyboard/gamepad controls
|
||||
├─ Resource::Cache::init() - Load ALL game resources (with verification)
|
||||
│ └─ Throws exception if any required asset is missing
|
||||
└─ Cheevos::init() - Load achievement state
|
||||
|
||||
Director::run() [Main loop]
|
||||
├─ while (SceneManager::current != QUIT)
|
||||
│ ├─ Logo::run()
|
||||
│ ├─ LoadingScreen::run()
|
||||
│ ├─ Title::run()
|
||||
│ ├─ Game::run()
|
||||
│ ├─ Ending::run()
|
||||
│ └─ ...
|
||||
└─ return 0
|
||||
|
||||
Director::~Director() [Cleanup]
|
||||
├─ Options::saveToFile() - Save game settings
|
||||
├─ Resource::Cache::destroy()
|
||||
├─ Audio::destroy()
|
||||
├─ Input::destroy()
|
||||
├─ Screen::destroy()
|
||||
└─ Resource::List::destroy()
|
||||
```
|
||||
|
||||
### 4.2 Game Scene Flow (Core Gameplay Loop)
|
||||
|
||||
```cpp
|
||||
Game::run() {
|
||||
while (game is running) {
|
||||
// Update
|
||||
Input::checkInput() - Get player commands
|
||||
Player::update() - Physics, animation, collision
|
||||
Room::update() - Enemy AI, animated tiles
|
||||
checkCollisions() - Player vs enemies, items, room
|
||||
checkGameOver() - Win/lose conditions
|
||||
|
||||
// Render
|
||||
Screen::start() - Prepare for drawing
|
||||
Room::renderMap() - Draw tilemap
|
||||
Room::renderEnemies() - Draw enemy sprites
|
||||
Room::renderItems() - Draw item sprites
|
||||
Player::render() - Draw player sprite
|
||||
renderScoreboard() - Draw HUD
|
||||
Screen::render() - Flush to GPU
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 Resource Loading & Caching
|
||||
|
||||
```
|
||||
Director::setFileList()
|
||||
└─ Resource::List::loadFromFile(config_path, PREFIX, system_folder_)
|
||||
├─ Read config/assets.yaml - Parse text configuration file
|
||||
├─ Parse YAML structure: assets grouped by category
|
||||
├─ Replace variables (${PREFIX}, ${SYSTEM_FOLDER})
|
||||
└─ Store in unordered_map (O(1) lookup) - Fast asset path retrieval
|
||||
|
||||
Game Scene initialization
|
||||
└─ Resource::Cache::init() - Loads all resources
|
||||
├─ loadSounds() - WAV files (with error handling)
|
||||
├─ loadMusics() - OGG files (with error handling)
|
||||
├─ loadSurfaces() - GIF/PNG images (with error handling)
|
||||
├─ loadPalettes() - PAL palette files (with error handling)
|
||||
├─ loadTextFiles() - Font definition files (with error handling)
|
||||
├─ 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
|
||||
└─ Resource::Cache::get*(name) - Return cached resource
|
||||
```
|
||||
|
||||
### 4.4 Input Flow
|
||||
|
||||
```
|
||||
SDL_Event (from OS)
|
||||
↓
|
||||
Input::checkInput(action)
|
||||
├─ Check keyboard bindings - SDL_Scancode → InputAction
|
||||
├─ Check gamepad bindings - SDL_GamepadButton → InputAction
|
||||
└─ Return true if action active
|
||||
|
||||
Game logic uses checked inputs
|
||||
└─ Player responds to actions
|
||||
```
|
||||
|
||||
### 4.5 Audio Control Flow
|
||||
|
||||
```
|
||||
Game code
|
||||
├─ Audio::playMusic(name, loop)
|
||||
├─ Audio::playSound(name, group)
|
||||
└─ Audio::stopMusic()
|
||||
↓
|
||||
Audio [wrapper/manager]
|
||||
├─ Resource::getMusic(name)
|
||||
├─ Resource::getSound(name)
|
||||
└─ jail_audio C library
|
||||
└─ SDL3 Audio device
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Important Design Patterns & Conventions
|
||||
|
||||
### 5.1 Naming Conventions
|
||||
|
||||
**Classes:**
|
||||
- `PascalCase` for classes: `Player`, `Room`, `Screen`, `Director`
|
||||
- Suffix `Sprite` for sprite classes: `Sprite`, `AnimatedSprite`, `MovingSprite`
|
||||
|
||||
**Methods:**
|
||||
- `get*()` for getters: `getWidth()`, `getRect()`
|
||||
- `set*()` for setters: `setColor()`, `setPos()`
|
||||
- `check*()` for boolean checks: `checkInput()`, `checkCollision()`
|
||||
- `update()` for game logic updates
|
||||
- `render()` for drawing
|
||||
|
||||
**Variables:**
|
||||
- `snake_case` for member variables with `_` suffix: `x_`, `y_`, `sprite_`
|
||||
- `UPPER_CASE` for constants: `BLOCK`, `MAX_VY`, `WIDTH`
|
||||
- Private members: `private_member_`
|
||||
|
||||
**Structs for Data:**
|
||||
- `XxxData` suffix: `PlayerData`, `RoomData`, `AnimationData`
|
||||
- Used as initialization structures passed to constructors
|
||||
|
||||
### 5.2 Memory Management
|
||||
|
||||
- **Smart Pointers:** Uses `std::shared_ptr` for shared ownership (Surfaces, Sprites, Rooms)
|
||||
- **Unique Pointers:** Uses `std::unique_ptr` for sole ownership (Director, local objects)
|
||||
- **Raw Pointers:** Minimal use, mainly for singleton access or SDL objects
|
||||
- **Static Allocation:** Singletons use static pointer pattern for RAII
|
||||
|
||||
### 5.3 Frame-Independent Physics
|
||||
|
||||
Uses `DeltaTimer` for delta time calculation:
|
||||
|
||||
```cpp
|
||||
// In game loop
|
||||
float delta = deltaTimer.tick(); // Get seconds since last frame
|
||||
|
||||
// Apply to physics
|
||||
player.vy_ += gravity * delta;
|
||||
player.y_ += player.vy_ * delta;
|
||||
```
|
||||
|
||||
Provides **time scaling** for slow-motion effects.
|
||||
|
||||
### 5.4 Palette System
|
||||
|
||||
- 8-bit indexed color (256 colors per palette)
|
||||
- Multiple palettes can be loaded and swapped via `PaletteManager`
|
||||
- `Screen::setPaletteByName()` changes the active palette
|
||||
- Supports palette sort modes (by luminosity, similarity to Spectrum palette, etc.)
|
||||
- Supports color replacement per-render: `renderWithColorReplace()`
|
||||
- CRT shader effects can modify colors in real-time
|
||||
|
||||
### 5.5 Configuration System
|
||||
|
||||
Game settings stored in configuration file:
|
||||
|
||||
```cpp
|
||||
namespace Options {
|
||||
inline Video video{}; // Screen resolution, fullscreen, etc.
|
||||
inline Audio audio{}; // Music/sound volumes
|
||||
inline Notification notifications{};
|
||||
inline Cheat cheats{}; // Cheat codes
|
||||
inline ControlScheme keys{}; // Control mapping
|
||||
}
|
||||
|
||||
Options::loadFromFile(path); // Load from config.yaml
|
||||
Options::saveToFile(path); // Save on exit
|
||||
```
|
||||
|
||||
### 5.6 Achievement System
|
||||
|
||||
```cpp
|
||||
struct Achievement {
|
||||
int id;
|
||||
std::string caption;
|
||||
std::string description;
|
||||
int icon;
|
||||
bool completed;
|
||||
bool obtainable;
|
||||
};
|
||||
|
||||
Cheevos::unlock(id); // Unlock achievement
|
||||
Cheevos::setUnobtainable(id); // Lock achievement
|
||||
Cheevos::saveToFile(); // Persist state
|
||||
```
|
||||
|
||||
Achievements trigger notifications on unlock.
|
||||
|
||||
---
|
||||
|
||||
## 6. Technology Stack
|
||||
|
||||
### Core Technologies
|
||||
|
||||
| Component | Technology | Version | Role |
|
||||
|-----------|-----------|---------|------|
|
||||
| **Graphics** | SDL3 | Latest | Window, rendering, input |
|
||||
| **GPU Rendering** | SDL3 GPU | Latest | Shader effects (CRT, post-processing via SPIR-V) |
|
||||
| **Audio** | SDL3 Audio | Latest | Audio device, mixing |
|
||||
| **Audio Decoding** | jail_audio (custom) | 1.x | OGG/WAV playback |
|
||||
| **Image Loading** | stb_image | v2.x | PNG/GIF image loading |
|
||||
| **Audio Decoding** | stb_vorbis | v1.x | OGG Vorbis support |
|
||||
| **Language** | C++ | C++20 | Standard library features |
|
||||
| **Build System** | CMake | 3.10+ | Cross-platform building |
|
||||
|
||||
### C++ Features Used
|
||||
|
||||
- **Smart Pointers:** `std::shared_ptr`, `std::unique_ptr`
|
||||
- **Standard Containers:** `std::vector`, `std::array`
|
||||
- **Modern Features:** `std::move`, lambda functions, constexpr
|
||||
- **Namespaces:** Extensive use for organization
|
||||
- **Inline Variables:** C++17 `inline` for global game state
|
||||
|
||||
### Platform Support
|
||||
|
||||
- **Windows:** MinGW/MSVC with SDL3
|
||||
- **macOS:** Apple Clang, arm64 architecture, OpenGL
|
||||
- **Linux:** GCC with SDL3 and OpenGL
|
||||
|
||||
---
|
||||
|
||||
## 7. Key Classes & Their Responsibilities
|
||||
|
||||
### Core System Classes
|
||||
|
||||
| Class | Purpose | Pattern |
|
||||
|-------|---------|---------|
|
||||
| `Director` | Main application controller, scene manager | Singleton |
|
||||
| `Screen` | Rendering, window, palette management | Singleton |
|
||||
| `Input` | Keyboard & gamepad input | Singleton |
|
||||
| `Audio` | Music and SFX playback | Singleton |
|
||||
| `Resource::Cache` | Asset caching and loading (with detailed error messages) | Singleton |
|
||||
| `Resource::List` | Asset path registry from config/assets.yaml, O(1) lookups, variable substitution | Singleton |
|
||||
| `PaletteManager` | Palette loading, switching, and sorting | Managed by Screen |
|
||||
| `Debug` | Debug overlay information | Singleton |
|
||||
| `globalEvents` | Global SDL event handling (quit, device reset, mouse) | Namespace |
|
||||
|
||||
### Game Logic Classes
|
||||
|
||||
| Class | Purpose |
|
||||
|-------|---------|
|
||||
| `Game` | Main gameplay scene, orchestrates update/render |
|
||||
| `Player` | Player entity with physics and animation |
|
||||
| `Room` | Level data, collision detection |
|
||||
| `RoomLoader` | Room loading from YAML files |
|
||||
| `TilemapRenderer` | Tilemap rendering |
|
||||
| `CollisionMap` | Collision map data |
|
||||
| `EnemyManager` | Enemy lifecycle management |
|
||||
| `ItemManager` | Item lifecycle management |
|
||||
| `Enemy` | Enemy entity behavior and rendering |
|
||||
| `Item` | Collectible items |
|
||||
| `Scoreboard` | HUD display data |
|
||||
| `Cheevos` | Achievement unlock and state |
|
||||
| `ItemTracker` | Tracks collected items |
|
||||
| `RoomTracker` | Tracks visited rooms |
|
||||
|
||||
### Rendering Classes
|
||||
|
||||
| Class | Purpose |
|
||||
|-------|---------|
|
||||
| `Surface` | 8-bit indexed color pixel buffer with palette |
|
||||
| `Sprite` | Renders a sprite region |
|
||||
| `AnimatedSprite` | Frame-based animation rendering |
|
||||
| `MovingSprite` | Sprite with velocity/position |
|
||||
| `DissolveSprite` | Dissolve transition sprite |
|
||||
| `Text` | Text rendering system |
|
||||
| `Sdl3gpuShader` | SDL3 GPU shader compilation and effects |
|
||||
| `PaletteManager` | Palette loading and management |
|
||||
|
||||
### Utility Classes
|
||||
|
||||
| Class/Header | Purpose |
|
||||
|-------|---------|
|
||||
| `DeltaTimer` | Frame-rate independent timing |
|
||||
| `easing_functions.hpp` | Easing/interpolation functions for animations |
|
||||
|
||||
---
|
||||
|
||||
## 8. Common Development Workflows
|
||||
|
||||
### Adding a New Input Action
|
||||
|
||||
1. Add to `InputAction` enum in `core/input/input.hpp`
|
||||
2. Bind in `Director::initInput()`:
|
||||
```cpp
|
||||
Input::get()->bindKey(InputAction::NEW_ACTION, SDL_SCANCODE_X);
|
||||
```
|
||||
3. Check in game code:
|
||||
```cpp
|
||||
if (Input::get()->checkInput(InputAction::NEW_ACTION)) {
|
||||
// Handle action
|
||||
}
|
||||
```
|
||||
|
||||
### Adding a New Scene
|
||||
|
||||
1. Create class inheriting appropriate base (usually standalone `run()` method)
|
||||
2. Add to `SceneManager::Scene` enum
|
||||
3. Implement in `Director::run()` switch statement
|
||||
4. Set `SceneManager::current` to transition
|
||||
|
||||
### Adding Game Assets
|
||||
|
||||
1. Place file in `data/` directory
|
||||
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
|
||||
```
|
||||
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
|
||||
```
|
||||
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.yaml`
|
||||
|
||||
### Modifying Collision Detection
|
||||
|
||||
1. Update `Room::setBottomSurfaces()`, `setLeftSlopes()`, etc.
|
||||
2. Modify Player collision point generation in `Player::updateColliderPoints()`
|
||||
3. Adjust tile classification in `TileType` enum
|
||||
4. Test with debug visualization (F12 key)
|
||||
|
||||
---
|
||||
|
||||
## 9. Debug Features
|
||||
|
||||
### Available at Runtime
|
||||
|
||||
- **F12** - Toggle debug info overlay (FPS, player position, collision points)
|
||||
- **F1/F2** - Decrease/increase window zoom
|
||||
- **F3** - Toggle fullscreen mode
|
||||
- **F4** - Toggle shader effects
|
||||
- **F5/F6** - Next/previous palette
|
||||
- **F7** - Toggle integer scaling
|
||||
- **M** - Toggle music
|
||||
- **B** - Toggle border display
|
||||
- **P** - Pause game
|
||||
|
||||
### Debug Mode Compilation
|
||||
|
||||
In debug builds (`#ifdef DEBUG`), renders:
|
||||
- Player collision boxes
|
||||
- Collision point visualization
|
||||
- Debug information overlay
|
||||
- Special debug event handling
|
||||
|
||||
---
|
||||
|
||||
## 10. Performance Considerations
|
||||
|
||||
### Optimization Points
|
||||
|
||||
1. **Rendering:** Uses indexed color (8-bit) to reduce memory bandwidth
|
||||
2. **Surfaces:** Shared smart pointers reduce copying
|
||||
3. **Collision:** Pre-computed tile surface lists avoid per-frame searches
|
||||
4. **Animation:** Frame-based animation reduces computation vs. bone systems
|
||||
5. **Audio:** Cached music and sound effects, no runtime decoding
|
||||
6. **Delta Time:** Frame-rate independent logic for smooth gameplay
|
||||
|
||||
### Known Limitations
|
||||
|
||||
- Single-threaded architecture (SDL3 requires single-thread rendering)
|
||||
- Surfaces stored entirely in CPU memory (not GPU-side textures)
|
||||
- Palette system requires full surface redraw when changing colors
|
||||
|
||||
---
|
||||
|
||||
## 11. File Format Reference
|
||||
|
||||
### Asset Configuration File (config/assets.yaml)
|
||||
YAML-based asset registry with grouped structure:
|
||||
```yaml
|
||||
# Projecte 2026 - Asset Configuration
|
||||
# Variables: ${PREFIX}, ${SYSTEM_FOLDER}
|
||||
|
||||
assets:
|
||||
# FONTS
|
||||
fonts:
|
||||
- type: BITMAP
|
||||
path: ${PREFIX}/data/font/smb2.gif
|
||||
- type: FONT
|
||||
path: ${PREFIX}/data/font/smb2.fnt
|
||||
|
||||
# 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.yaml
|
||||
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 (.yaml)
|
||||
- `MUSIC` - Music files (OGG)
|
||||
- `SOUND` - Sound effects (WAV)
|
||||
- `FONT` - Font definition files
|
||||
- `ROOM` - Room data files (.yaml)
|
||||
- `PALETTE` - Color palette files (.pal)
|
||||
|
||||
**Variables:**
|
||||
- `${PREFIX}` - Replaced with `/../Resources` on macOS bundles, empty otherwise
|
||||
- `${SYSTEM_FOLDER}` - Replaced with user's system config folder
|
||||
|
||||
### Animation Files (.yaml)
|
||||
YAML-based animation definitions with frame data:
|
||||
```yaml
|
||||
animations:
|
||||
- name: default
|
||||
frameWidth: 16
|
||||
frameHeight: 16
|
||||
speed: 100
|
||||
loop: 0
|
||||
frames: [...]
|
||||
```
|
||||
|
||||
### Room Data Files (.yaml)
|
||||
YAML-based room definitions:
|
||||
```yaml
|
||||
room:
|
||||
name_en: Starting Room
|
||||
bgColor: 0x000000
|
||||
connections: [...]
|
||||
tilemap: [...]
|
||||
```
|
||||
|
||||
### Tilemap Files (.tmx)
|
||||
Tiled map format with tileset and collision data.
|
||||
|
||||
### Palette Files (.pal)
|
||||
Binary 256-color palette format (256 × 4 bytes RGBA).
|
||||
|
||||
---
|
||||
|
||||
## 12. Quick Reference: Main Entry Points
|
||||
|
||||
### For Graphics Issues
|
||||
- `Screen::render()` - Main rendering method
|
||||
- `Screen::setPaletteByName()` - Palette switching
|
||||
- `PaletteManager` - Palette loading and sorting
|
||||
- `Surface` class - Pixel buffer operations
|
||||
|
||||
### For Input Issues
|
||||
- `Input::checkInput()` - Input state checking
|
||||
- `Director::initInput()` - Binding configuration
|
||||
|
||||
### For Audio Issues
|
||||
- `Audio::playMusic()` - Music playback
|
||||
- `Audio::playSound()` - SFX playback
|
||||
- `jail_audio` library - Low-level audio operations
|
||||
|
||||
### For Game Logic
|
||||
- `Game::run()` - Main game loop
|
||||
- `Room` class - Collision and level logic
|
||||
- `Player::update()` - Physics and movement
|
||||
|
||||
### For Asset Management
|
||||
- `config/assets.yaml` - Asset configuration file (text-based, no recompilation needed)
|
||||
- `Resource::List::loadFromFile()` - Loads asset registry from config file
|
||||
- `Resource::List::get()` - Retrieves asset path (O(1) lookup with unordered_map)
|
||||
- `Resource::Cache` - Asset loading and caching
|
||||
- `Director::setFileList()` - Calls `Resource::List::loadFromFile()` with PREFIX and system_folder
|
||||
|
||||
---
|
||||
|
||||
## 13. Future Enhancement Points
|
||||
|
||||
### Identified Areas for Expansion
|
||||
|
||||
1. **More Scenes:** Additional game modes
|
||||
3. **Custom Rooms:** Level editor integration
|
||||
4. **Audio Streaming:** Background music without loading entire file
|
||||
5. **Particle System:** Visual effects for pickups/collisions
|
||||
6. **Controller Feedback:** Haptic feedback for game events
|
||||
7. **Accessibility:** Font scaling, color-blind modes, key remapping UI
|
||||
|
||||
---
|
||||
|
||||
## Development Notes
|
||||
|
||||
- **Language:** All code comments and some variable names are in Spanish (maintaining original author style)
|
||||
- **Compilation:** Use CMake - automatically handles platform differences
|
||||
- **Performance Profiling:** Use debug overlay (F12) for basic metrics; consider external profilers for deeper analysis
|
||||
- **Common Warnings:** The codebase has been cleaned of the `struct`/`class` forward declaration inconsistency warnings that previously appeared
|
||||
|
||||
### Important Code Consistency Rules
|
||||
## Important Code Consistency Rules
|
||||
|
||||
1. **Forward Declarations:** Always use `class` for forward declarations of classes defined with `class` (not `struct`). The `Surface` class is defined as `class Surface` in `surface.hpp:57`, so all forward declarations must use `class Surface;`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user