Compare commits
127 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 70d6cbfaf8 | |||
| 95dd6b4f70 | |||
| 633936c6e8 | |||
| 95b82e5f62 | |||
| ead3265bfc | |||
| 8bf9da5fb6 | |||
| cd836862c0 | |||
| acdad8295a | |||
| f14a1075ab | |||
| 31c84f9676 | |||
| 9e8c5e13df | |||
| de8c714132 | |||
| da65777a5b | |||
| 70b76edcbf | |||
| 6af2d72ea8 | |||
| 5f47c88770 | |||
| 3179a08dac | |||
| b1dca32a5b | |||
| aacb14149f | |||
| cdb9bde6aa | |||
| 5d8811026d | |||
| 231dcd4b3b | |||
| 17101a3da1 | |||
| 87370dd11d | |||
| fc17131455 | |||
| 0c87612a17 | |||
| 96506988b6 | |||
| c7b07e9351 | |||
| 6d2a116d15 | |||
| d1acc59319 | |||
| 0388adfed8 | |||
| 342177a751 | |||
| fdea094e26 | |||
| 2eadd7d8df | |||
| 51330db998 | |||
| df4965a84b | |||
| 8f49e442de | |||
| 9676e5bc2f | |||
| 545d471654 | |||
| 9db902c024 | |||
| 7fe2523221 | |||
| d5ff840445 | |||
| fb5fee02e9 | |||
| 9a4b3b04a5 | |||
| e811cf0a1d | |||
| e4a08d2ec7 | |||
| 7c102e42cc | |||
| 78c5333144 | |||
| c3415fd106 | |||
| 428fe664bd | |||
| 0f8de0d8b5 | |||
| 2ee2d5c45d | |||
| b8cde79107 | |||
| 0667e2105b | |||
| f438e8946b | |||
| 68c97610fb | |||
| 7746b679b4 | |||
| 73008992e0 | |||
| d4acb38c05 | |||
| 7aae9fb5e6 | |||
| a63066bd68 | |||
| 0de6117ca0 | |||
| a43967c279 | |||
| 15ecc10d8b | |||
| 0a5996f220 | |||
| 64ee2d1e45 | |||
| 40dcbabfe8 | |||
| a14f6fcf6f | |||
| 7b3f82aa34 | |||
| 3a36bf6530 | |||
| 195d812d2a | |||
| fdb85ac393 | |||
| d4e3995d71 | |||
| b885aa8c9e | |||
| 9cf0891a04 | |||
| 09ac952404 | |||
| 529bfb5e3a | |||
| ce88596d35 | |||
| 6c3e231d51 | |||
| ae5c511988 | |||
| 9eaf3bc134 | |||
| ff309168ef | |||
| c5c312fc51 | |||
| 34d34a5d91 | |||
| d339fb13b0 | |||
| d0e06e30c9 | |||
| 982db7f75b | |||
| 68e03ac1b0 | |||
| 537150365b | |||
| 12e27a1062 | |||
| 72efa0dc46 | |||
| f2bfc970bc | |||
| 60c926a9c9 | |||
| 10debde847 | |||
| 5cc163dd14 | |||
| 241732752a | |||
| 5a8747cc4b | |||
| 70a50f5117 | |||
| d41b0cb31c | |||
| 33038e8509 | |||
| 57481a1e97 | |||
| 05f91b2a94 | |||
| c4033e3663 | |||
| b940d627d6 | |||
| b320030547 | |||
| d7e0178602 | |||
| c9e75ad5c8 | |||
| 8f1d1df5d6 | |||
| db3a0d7263 | |||
| 636b91ae6f | |||
| 4b820ad6b7 | |||
| a4db80e116 | |||
| 2ebb285a27 | |||
| d05f18ce2d | |||
| 0d74a8a29f | |||
| cdf0b0a694 | |||
| 82f0992116 | |||
| b1ba5e67dc | |||
| 193dac708f | |||
| cd96be80f9 | |||
| aca2be98af | |||
| 360ebfd2e6 | |||
| 5c371e7517 | |||
| 31cded15cc | |||
| 3562b139c3 | |||
| c2040d3ded | |||
| b34f4dda42 |
21
.clang-format
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
BasedOnStyle: Google
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentAccessModifiers: true
|
||||||
|
ColumnLimit: 0 # Sin límite de longitud de línea
|
||||||
|
BreakBeforeBraces: Attach # Llaves en la misma línea
|
||||||
|
AllowShortIfStatementsOnASingleLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: true
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AlignOperands: DontAlign
|
||||||
|
AlignAfterOpenBracket: DontAlign
|
||||||
|
BinPackArguments: false
|
||||||
|
BinPackParameters: false
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
AllowAllConstructorInitializersOnNextLine: false
|
||||||
|
PackConstructorInitializers: Never
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
83
.clang-tidy
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
Checks:
|
||||||
|
- readability-*
|
||||||
|
- modernize-*
|
||||||
|
- performance-*
|
||||||
|
- bugprone-unchecked-optional-access
|
||||||
|
- bugprone-sizeof-expression
|
||||||
|
- bugprone-suspicious-missing-comma
|
||||||
|
- bugprone-suspicious-index
|
||||||
|
- bugprone-undefined-memory-manipulation
|
||||||
|
- bugprone-use-after-move
|
||||||
|
- bugprone-out-of-bound-access
|
||||||
|
- -readability-identifier-length
|
||||||
|
- -readability-magic-numbers
|
||||||
|
- -bugprone-narrowing-conversions
|
||||||
|
- -performance-enum-size
|
||||||
|
- -performance-inefficient-string-concatenation
|
||||||
|
- -bugprone-integer-division
|
||||||
|
- -bugprone-easily-swappable-parameters
|
||||||
|
|
||||||
|
WarningsAsErrors: '*'
|
||||||
|
# Solo incluir archivos de tu código fuente
|
||||||
|
HeaderFilterRegex: '^source/(sections|ui)/.*'
|
||||||
|
FormatStyle: file
|
||||||
|
|
||||||
|
CheckOptions:
|
||||||
|
# Variables locales en snake_case
|
||||||
|
- { key: readability-identifier-naming.VariableCase, value: lower_case }
|
||||||
|
|
||||||
|
# Miembros privados en snake_case con sufijo _
|
||||||
|
- { key: readability-identifier-naming.PrivateMemberCase, value: lower_case }
|
||||||
|
- { key: readability-identifier-naming.PrivateMemberSuffix, value: _ }
|
||||||
|
|
||||||
|
# Miembros protegidos en snake_case con sufijo _
|
||||||
|
- { key: readability-identifier-naming.ProtectedMemberCase, value: lower_case }
|
||||||
|
- { key: readability-identifier-naming.ProtectedMemberSuffix, value: _ }
|
||||||
|
|
||||||
|
# Miembros públicos en snake_case (sin sufijo)
|
||||||
|
- { key: readability-identifier-naming.PublicMemberCase, value: lower_case }
|
||||||
|
|
||||||
|
# Namespaces en CamelCase
|
||||||
|
- { key: readability-identifier-naming.NamespaceCase, value: CamelCase }
|
||||||
|
|
||||||
|
# Variables estáticas privadas como miembros privados
|
||||||
|
- { key: readability-identifier-naming.StaticVariableCase, value: lower_case }
|
||||||
|
- { key: readability-identifier-naming.StaticVariableSuffix, value: _ }
|
||||||
|
|
||||||
|
# Constantes estáticas sin sufijo
|
||||||
|
- { key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# Constantes globales en UPPER_CASE
|
||||||
|
- { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# Variables constexpr globales en UPPER_CASE
|
||||||
|
- { key: readability-identifier-naming.ConstexprVariableCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# Constantes locales en UPPER_CASE
|
||||||
|
- { key: readability-identifier-naming.LocalConstantCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# Constexpr miembros en UPPER_CASE (sin sufijo)
|
||||||
|
- { key: readability-identifier-naming.ConstexprMemberCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# Constexpr miembros privados/protegidos con sufijo _
|
||||||
|
- { key: readability-identifier-naming.ConstexprMethodCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# Clases, structs y enums en CamelCase
|
||||||
|
- { key: readability-identifier-naming.ClassCase, value: CamelCase }
|
||||||
|
- { key: readability-identifier-naming.StructCase, value: CamelCase }
|
||||||
|
- { key: readability-identifier-naming.EnumCase, value: CamelCase }
|
||||||
|
|
||||||
|
# Valores de enums en UPPER_CASE
|
||||||
|
- { key: readability-identifier-naming.EnumConstantCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# Métodos en camelBack (sin sufijos)
|
||||||
|
- { key: readability-identifier-naming.MethodCase, value: camelBack }
|
||||||
|
- { key: readability-identifier-naming.PrivateMethodCase, value: camelBack }
|
||||||
|
- { key: readability-identifier-naming.ProtectedMethodCase, value: camelBack }
|
||||||
|
- { key: readability-identifier-naming.PublicMethodCase, value: camelBack }
|
||||||
|
|
||||||
|
# Funciones en camelBack
|
||||||
|
- { key: readability-identifier-naming.FunctionCase, value: camelBack }
|
||||||
|
|
||||||
|
# Parámetros en lower_case
|
||||||
|
- { key: readability-identifier-naming.ParameterCase, value: lower_case }
|
||||||
4
.gitignore
vendored
@@ -1,4 +1,4 @@
|
|||||||
.vscode
|
.vscode/
|
||||||
*data/config/config.txt
|
*data/config/config.txt
|
||||||
*stats.txt
|
*stats.txt
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
@@ -11,8 +11,8 @@ thumbs.db
|
|||||||
*.zip
|
*.zip
|
||||||
*.app
|
*.app
|
||||||
*_debug*
|
*_debug*
|
||||||
sync_jail_engine.sh
|
|
||||||
jaildoctors_dilemma*
|
jaildoctors_dilemma*
|
||||||
todo
|
todo
|
||||||
build/
|
build/
|
||||||
linux_utils/
|
linux_utils/
|
||||||
|
.claude/
|
||||||
788
CLAUDE.md
Normal file
@@ -0,0 +1,788 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# JailDoctor's Dilemma - Codebase Architecture Guide
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
**JailDoctor's Dilemma** 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.
|
||||||
|
|
||||||
|
**Language:** C++20
|
||||||
|
**Graphics:** SDL3, OpenGL
|
||||||
|
**Audio:** SDL3 + custom jail_audio library
|
||||||
|
**Build:** CMake 3.10+
|
||||||
|
**Game Canvas:** 256x192 pixels (retro resolution)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Build Commands
|
||||||
|
|
||||||
|
### Initial Setup & Build
|
||||||
|
```bash
|
||||||
|
# From project root
|
||||||
|
mkdir -p build
|
||||||
|
cd build
|
||||||
|
cmake ..
|
||||||
|
cmake --build .
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rebuild After Changes
|
||||||
|
```bash
|
||||||
|
# From build directory
|
||||||
|
cmake --build .
|
||||||
|
|
||||||
|
# Or from project root
|
||||||
|
cmake --build build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Clean Build
|
||||||
|
```bash
|
||||||
|
# From build directory
|
||||||
|
cmake --build . --clean-first
|
||||||
|
|
||||||
|
# Or from project root
|
||||||
|
cmake --build build --clean-first
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run the Game
|
||||||
|
```bash
|
||||||
|
# Executable is placed in project root
|
||||||
|
./jaildoctors_dilemma
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important:** The build directory is `/Users/sergio/Gitea/jaildoctors_dilemma/build` and the output executable is placed in the project root directory.
|
||||||
|
|
||||||
|
### Linter (clang-tidy)
|
||||||
|
|
||||||
|
**IMPORTANT:** Always run the linter on specific files, NOT on the entire project, to avoid long execution times and errors in unrelated files.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Analyze a specific file (RECOMMENDED)
|
||||||
|
tools/linter/run_clang-tidy.sh source/game/entities/player.cpp
|
||||||
|
|
||||||
|
# Analyze multiple specific files
|
||||||
|
tools/linter/run_clang-tidy.sh source/game/entities/player.cpp source/game/entities/enemy.cpp
|
||||||
|
|
||||||
|
# Apply fixes automatically to a specific file
|
||||||
|
tools/linter/run_clang-tidy.sh --fix source/game/entities/player.cpp
|
||||||
|
|
||||||
|
# Analyze entire project (SLOW, may have errors in defaults.hpp)
|
||||||
|
tools/linter/run_clang-tidy.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** Running the linter on the entire project can produce errors in files like `defaults.hpp` that are unrelated to your changes. Always target specific files you're working on.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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)
|
||||||
|
│ ├── input/ # Input handling
|
||||||
|
│ │ ├── input.hpp/cpp # Input manager (keyboard, gamepad)
|
||||||
|
│ │ ├── global_inputs.hpp # Global input state
|
||||||
|
│ │ └── mouse.hpp # Mouse input
|
||||||
|
│ ├── rendering/ # Graphics rendering
|
||||||
|
│ │ ├── screen.hpp/cpp # Screen/window singleton, SDL renderer
|
||||||
|
│ │ ├── surface.hpp/cpp # 8-bit indexed color surface abstraction
|
||||||
|
│ │ ├── surface_sprite.hpp # Static sprite rendering
|
||||||
|
│ │ ├── surface_animated_sprite.hpp # Animated sprite with frame data
|
||||||
|
│ │ ├── surface_moving_sprite.hpp # Moving sprite with velocity
|
||||||
|
│ │ ├── texture.hpp/cpp # SDL texture wrapper
|
||||||
|
│ │ ├── text.hpp/cpp # Text rendering system
|
||||||
|
│ │ ├── gif.hpp/cpp # GIF image loader
|
||||||
|
│ │ ├── opengl/ # OpenGL shader backend
|
||||||
|
│ │ │ └── opengl_shader.hpp/cpp # CRT shader effects
|
||||||
|
│ │ └── shader_backend.hpp # Abstract shader interface
|
||||||
|
│ ├── resources/ # Asset & Resource management
|
||||||
|
│ │ ├── asset.hpp/cpp # Asset registry (file path mapping)
|
||||||
|
│ │ └── resource.hpp/cpp # Resource singleton (loads/caches assets)
|
||||||
|
│ └── 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, tilemap, collision
|
||||||
|
│ │ ├── room_tracker.hpp/cpp # Tracks visited rooms
|
||||||
|
│ │ ├── scoreboard.hpp/cpp # Score display & data
|
||||||
|
│ │ ├── item_tracker.hpp/cpp # Tracks collected items
|
||||||
|
│ │ ├── stats.hpp/cpp # Game statistics
|
||||||
|
│ │ └── 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
|
||||||
|
│ ├── options.hpp/cpp # Game configuration/options
|
||||||
|
│ ├── scene_manager.hpp # Scene flow state machine
|
||||||
|
│ ├── defaults.hpp # Game defaults constants
|
||||||
|
│ └── gameplay.hpp # Gameplay constants
|
||||||
|
├── external/ # Third-party libraries
|
||||||
|
│ ├── jail_audio.hpp/cpp # Custom audio library
|
||||||
|
│ ├── jail_audio.h # C interface for jail_audio
|
||||||
|
│ ├── stb_image.h # Image loading library
|
||||||
|
│ └── stb_vorbis.h # OGG Vorbis audio decoding
|
||||||
|
├── utils/ # Utility code
|
||||||
|
│ ├── delta_timer.hpp/cpp # Frame-rate independent timing
|
||||||
|
│ ├── defines.hpp # Game constants (resolutions, block sizes)
|
||||||
|
│ └── utils.hpp/cpp # Helper functions (colors, math)
|
||||||
|
└── main.cpp # Application entry point
|
||||||
|
|
||||||
|
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` - Asset loading, caching, streaming
|
||||||
|
- `Asset` - Asset path registry and verification
|
||||||
|
- `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, 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
|
||||||
|
- `SurfaceSprite` - Renders a fixed region of a surface
|
||||||
|
- `SurfaceAnimatedSprite` - Frame-based animation on top of sprite
|
||||||
|
- `SurfaceMovingSprite` - Adds velocity/position to animated 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 .ani files (list of animation names)
|
||||||
|
// Rendered with SurfaceAnimatedSprite
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. System Interactions & Data Flow
|
||||||
|
|
||||||
|
### 4.1 Application Lifecycle
|
||||||
|
|
||||||
|
```
|
||||||
|
main()
|
||||||
|
↓
|
||||||
|
Director::Director() [Initialization]
|
||||||
|
├─ Options::init() - Load game configuration
|
||||||
|
├─ Asset::init() - Register asset paths
|
||||||
|
├─ Screen::init() - Create window, SDL renderer
|
||||||
|
├─ Audio::init() - Initialize SDL audio
|
||||||
|
├─ Input::init() - Bind keyboard/gamepad controls
|
||||||
|
├─ Resource::init() - Load all game resources
|
||||||
|
└─ 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::destroy()
|
||||||
|
├─ Audio::destroy()
|
||||||
|
├─ Input::destroy()
|
||||||
|
├─ Screen::destroy()
|
||||||
|
└─ Asset::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()
|
||||||
|
├─ Asset::add(file, type) - Register all assets
|
||||||
|
└─ Asset::check() - Verify files exist
|
||||||
|
|
||||||
|
Game Scene initialization
|
||||||
|
└─ Resource::init() - Loads all resources
|
||||||
|
├─ loadSounds() - WAV files
|
||||||
|
├─ loadMusics() - OGG files
|
||||||
|
├─ loadSurfaces() - GIF/PNG images
|
||||||
|
├─ loadAnimations() - .ani animation definitions
|
||||||
|
├─ loadTileMaps() - .room tilemap data
|
||||||
|
└─ loadRooms() - Room metadata
|
||||||
|
|
||||||
|
During gameplay
|
||||||
|
└─ Resource::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: `SurfaceSprite`, `SurfaceAnimatedSprite`
|
||||||
|
|
||||||
|
**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
|
||||||
|
- `Surface::setPalette()` changes rendering colors
|
||||||
|
- 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
|
||||||
|
inline Stats stats{}; // Game statistics
|
||||||
|
}
|
||||||
|
|
||||||
|
Options::loadFromFile(path); // Load from config.txt
|
||||||
|
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** | OpenGL | 3.2+ | Shader effects (CRT) |
|
||||||
|
| **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` | Asset caching and loading | Singleton |
|
||||||
|
| `Asset` | Asset path registry | Singleton |
|
||||||
|
| `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, tilemap rendering |
|
||||||
|
| `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 |
|
||||||
|
| `SurfaceSprite` | Renders a sprite region |
|
||||||
|
| `SurfaceAnimatedSprite` | Frame-based animation rendering |
|
||||||
|
| `SurfaceMovingSprite` | Sprite with velocity/position |
|
||||||
|
| `Text` | Text rendering system |
|
||||||
|
| `OpenGLShader` | Shader compilation and effects |
|
||||||
|
|
||||||
|
### Utility Classes
|
||||||
|
|
||||||
|
| Class | Purpose |
|
||||||
|
|-------|---------|
|
||||||
|
| `DeltaTimer` | Frame-rate independent timing |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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. Register in `Director::setFileList()`:
|
||||||
|
```cpp
|
||||||
|
Asset::get()->add("/data/path/file.ext", AssetType::TYPE);
|
||||||
|
```
|
||||||
|
3. Resource loads automatically during `Resource::init()`
|
||||||
|
4. Access via: `Resource::get()->getSurface("name")`
|
||||||
|
|
||||||
|
### 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
|
||||||
|
|
||||||
|
### Animation Files (.ani)
|
||||||
|
List of animation names, one per line:
|
||||||
|
```
|
||||||
|
default
|
||||||
|
jump
|
||||||
|
run
|
||||||
|
fall
|
||||||
|
```
|
||||||
|
|
||||||
|
### Room Data Files (.room)
|
||||||
|
Key-value pairs defining room properties:
|
||||||
|
```
|
||||||
|
number=01
|
||||||
|
name=Starting Room
|
||||||
|
bg_color=0x000000
|
||||||
|
border_color=0xFF00FF
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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::setPalete()` - Palette application
|
||||||
|
- `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
|
||||||
|
- `Asset::add()` - Asset registration
|
||||||
|
- `Resource::load()` - Asset loading
|
||||||
|
- `Director::setFileList()` - Complete asset registry
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 13. Future Enhancement Points
|
||||||
|
|
||||||
|
### Identified Areas for Expansion
|
||||||
|
|
||||||
|
1. **Network Play:** Stats upload to online service
|
||||||
|
2. **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
|
||||||
|
|
||||||
|
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;`
|
||||||
|
|
||||||
|
2. **Singleton Pattern:** When creating new singletons, follow the existing pattern:
|
||||||
|
- Private static instance pointer
|
||||||
|
- Private constructor/destructor
|
||||||
|
- Public `init()`, `destroy()`, and `get()` methods
|
||||||
|
|
||||||
|
3. **Delta Time:** Always use `DeltaTimer` for frame-rate independent physics calculations
|
||||||
|
|
||||||
|
4. **Memory Management:** Prefer `std::shared_ptr` for shared resources (Surfaces, Sprites) and `std::unique_ptr` for sole ownership
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Last Updated:** November 2022 (per README)
|
||||||
|
**Original Author:** JailDesigner
|
||||||
|
**Repository:** Gitea (internal)
|
||||||
171
CMakeLists.txt
@@ -3,83 +3,160 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
project(jaildoctors_dilemma VERSION 1.00)
|
project(jaildoctors_dilemma VERSION 1.00)
|
||||||
|
|
||||||
# Configuración de compilador para MinGW en Windows, si es necesario
|
|
||||||
if(WIN32 AND NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
|
||||||
set(CMAKE_CXX_COMPILER "g++")
|
|
||||||
set(CMAKE_C_COMPILER "gcc")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Establecer estándar de C++
|
# Establecer estándar de C++
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||||
|
|
||||||
# Configuración global de flags de compilación
|
# Exportar comandos de compilación para herramientas de análisis
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Os -ffunction-sections -fdata-sections")
|
|
||||||
|
|
||||||
# Define el directorio de los archivos fuente
|
# Establece la política CMP0072 para indicar cómo se debe seleccionar la implementación de OpenGL.
|
||||||
set(DIR_SOURCES "${CMAKE_SOURCE_DIR}/source")
|
# En este caso, se elige la opción "GLVND", que utiliza bibliotecas modernas y modulares (libOpenGL, libGLX),
|
||||||
|
# en lugar de la biblioteca OpenGL clásica (libGL). Esto mejora la compatibilidad con drivers recientes
|
||||||
|
# y evita ambigüedades cuando se encuentran múltiples implementaciones de OpenGL en el sistema.
|
||||||
|
cmake_policy(SET CMP0072 NEW)
|
||||||
|
set(OpenGL_GL_PREFERENCE GLVND)
|
||||||
|
|
||||||
# Cargar todos los archivos fuente en DIR_SOURCES
|
# --- GENERACIÓN DE VERSIÓN AUTOMÁTICA ---
|
||||||
file(GLOB SOURCES "${DIR_SOURCES}/*.cpp")
|
find_package(Git QUIET)
|
||||||
|
if(GIT_FOUND)
|
||||||
# Verificar si se encontraron archivos fuente
|
execute_process(
|
||||||
if(NOT SOURCES)
|
COMMAND ${GIT_EXECUTABLE} rev-parse --short=7 HEAD
|
||||||
message(FATAL_ERROR "No se encontraron archivos fuente en ${DIR_SOURCES}. Verifica que el directorio existe y contiene archivos .cpp.")
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
endif()
|
OUTPUT_VARIABLE GIT_HASH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
# Configuración de SDL2
|
ERROR_QUIET
|
||||||
find_package(SDL2 REQUIRED)
|
)
|
||||||
if(SDL2_FOUND)
|
|
||||||
message(STATUS "SDL2 encontrado: ${SDL2_INCLUDE_DIRS}")
|
|
||||||
include_directories(${SDL2_INCLUDE_DIRS})
|
|
||||||
link_directories(${SDL2_LIBDIR})
|
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "SDL2 no encontrado")
|
set(GIT_HASH "unknown")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Incluye rutas de SDL2 obtenidas con pkg-config
|
# Configurar archivo de versión
|
||||||
include_directories(/usr/local/include /usr/local/include/SDL2)
|
configure_file(${CMAKE_SOURCE_DIR}/source/version.h.in ${CMAKE_BINARY_DIR}/version.h @ONLY)
|
||||||
link_directories(/usr/local/lib)
|
|
||||||
|
|
||||||
# Definir las bibliotecas comunes
|
# --- 1. LISTA EXPLÍCITA DE FUENTES ---
|
||||||
set(LIBS SDL2)
|
set(APP_SOURCES
|
||||||
|
# Core - Audio
|
||||||
|
source/core/audio/audio.cpp
|
||||||
|
|
||||||
# Configuración común de salida de ejecutables en el directorio raíz
|
# Core - Input
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})
|
source/core/input/global_inputs.cpp
|
||||||
|
source/core/input/input.cpp
|
||||||
|
source/core/input/mouse.cpp
|
||||||
|
|
||||||
# Añadir ejecutable principal
|
# Core - Rendering
|
||||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
source/core/rendering/gif.cpp
|
||||||
|
source/core/rendering/screen.cpp
|
||||||
|
source/core/rendering/surface.cpp
|
||||||
|
source/core/rendering/surface_animated_sprite.cpp
|
||||||
|
source/core/rendering/surface_moving_sprite.cpp
|
||||||
|
source/core/rendering/surface_sprite.cpp
|
||||||
|
source/core/rendering/text.cpp
|
||||||
|
source/core/rendering/texture.cpp
|
||||||
|
|
||||||
# Añadir definiciones de compilación dependiendo del tipo de build
|
# Core - Resources
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<CONFIG:DEBUG>:DEBUG VERBOSE>)
|
source/core/resources/asset.cpp
|
||||||
|
source/core/resources/resource.cpp
|
||||||
|
|
||||||
# Enlazar bibliotecas
|
# Core - System
|
||||||
target_link_libraries(${PROJECT_NAME} ${LIBS})
|
source/core/system/debug.cpp
|
||||||
|
source/core/system/director.cpp
|
||||||
|
source/core/system/global_events.cpp
|
||||||
|
|
||||||
|
# Game - Entities
|
||||||
|
source/game/entities/enemy.cpp
|
||||||
|
source/game/entities/item.cpp
|
||||||
|
source/game/entities/player.cpp
|
||||||
|
|
||||||
|
# Game - Configuration
|
||||||
|
source/game/options.cpp
|
||||||
|
|
||||||
|
# Game - Gameplay
|
||||||
|
source/game/gameplay/cheevos.cpp
|
||||||
|
source/game/gameplay/item_tracker.cpp
|
||||||
|
source/game/gameplay/room.cpp
|
||||||
|
source/game/gameplay/room_tracker.cpp
|
||||||
|
source/game/gameplay/scoreboard.cpp
|
||||||
|
source/game/gameplay/stats.cpp
|
||||||
|
|
||||||
|
# Game - Scenes
|
||||||
|
source/game/scenes/credits.cpp
|
||||||
|
source/game/scenes/ending.cpp
|
||||||
|
source/game/scenes/ending2.cpp
|
||||||
|
source/game/scenes/game.cpp
|
||||||
|
source/game/scenes/game_over.cpp
|
||||||
|
source/game/scenes/loading_screen.cpp
|
||||||
|
source/game/scenes/logo.cpp
|
||||||
|
source/game/scenes/title.cpp
|
||||||
|
|
||||||
|
# Game - UI
|
||||||
|
source/game/ui/notifier.cpp
|
||||||
|
|
||||||
|
# Utils
|
||||||
|
source/utils/delta_timer.cpp
|
||||||
|
source/utils/utils.cpp
|
||||||
|
|
||||||
|
# Main
|
||||||
|
source/main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# Fuentes de librerías de terceros
|
||||||
|
set(EXTERNAL_SOURCES
|
||||||
|
source/external/jail_audio.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# Fuentes del sistema de renderizado
|
||||||
|
set(RENDERING_SOURCES
|
||||||
|
source/core/rendering/opengl/opengl_shader.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# Configuración de SDL3
|
||||||
|
find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3)
|
||||||
|
message(STATUS "SDL3 encontrado: ${SDL3_INCLUDE_DIRS}")
|
||||||
|
|
||||||
|
# --- 2. AÑADIR EJECUTABLE ---
|
||||||
|
add_executable(${PROJECT_NAME} ${APP_SOURCES} ${EXTERNAL_SOURCES} ${RENDERING_SOURCES})
|
||||||
|
|
||||||
|
# --- 3. DIRECTORIOS DE INCLUSIÓN ---
|
||||||
|
target_include_directories(${PROJECT_NAME} PUBLIC
|
||||||
|
"${CMAKE_SOURCE_DIR}/source"
|
||||||
|
"${CMAKE_BINARY_DIR}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Enlazar la librería SDL3
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE SDL3::SDL3)
|
||||||
|
|
||||||
|
|
||||||
|
# --- 4. CONFIGURACIÓN PLATAFORMAS Y COMPILADOR ---
|
||||||
|
# Configuración de flags de compilación
|
||||||
|
target_compile_options(${PROJECT_NAME} PRIVATE -Wall)
|
||||||
|
target_compile_options(${PROJECT_NAME} PRIVATE $<$<CONFIG:RELEASE>:-Os -ffunction-sections -fdata-sections>)
|
||||||
|
|
||||||
|
# Definir _DEBUG en modo Debug
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<CONFIG:DEBUG>:_DEBUG>)
|
||||||
|
|
||||||
# Configuración específica para cada plataforma
|
# Configuración específica para cada plataforma
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE WINDOWS_BUILD)
|
target_compile_definitions(${PROJECT_NAME} PRIVATE WINDOWS_BUILD)
|
||||||
target_link_libraries(${PROJECT_NAME} mingw32 opengl32 gdi32 winmm imm32 ole32 version)
|
target_link_libraries(${PROJECT_NAME} PRIVATE ws2_32 mingw32 opengl32)
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
set(LIBS ${LIBS} "-framework OpenGL")
|
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE MACOS_BUILD)
|
target_compile_definitions(${PROJECT_NAME} PRIVATE MACOS_BUILD)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated")
|
target_compile_options(${PROJECT_NAME} PRIVATE -Wno-deprecated)
|
||||||
# Configurar compilación para Apple Silicon
|
|
||||||
set(CMAKE_OSX_ARCHITECTURES "arm64")
|
set(CMAKE_OSX_ARCHITECTURES "arm64")
|
||||||
elseif(UNIX AND NOT APPLE)
|
elseif(UNIX AND NOT APPLE)
|
||||||
set(LIBS ${LIBS} GL)
|
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE LINUX_BUILD)
|
target_compile_definitions(${PROJECT_NAME} PRIVATE LINUX_BUILD)
|
||||||
target_link_libraries(${PROJECT_NAME} ${LIBS})
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Añadir OpenGL a las bibliotecas enlazadas
|
# Configuración común para OpenGL
|
||||||
if(NOT WIN32)
|
if(NOT WIN32)
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
if(OPENGL_FOUND)
|
if(OPENGL_FOUND)
|
||||||
message(STATUS "OpenGL encontrado: ${OPENGL_LIBRARIES}")
|
message(STATUS "OpenGL encontrado: ${OPENGL_LIBRARIES}")
|
||||||
target_link_libraries(${PROJECT_NAME} ${OPENGL_LIBRARIES})
|
target_link_libraries(${PROJECT_NAME} PRIVATE ${OPENGL_LIBRARIES})
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "OpenGL no encontrado")
|
message(FATAL_ERROR "OpenGL no encontrado")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Especificar la ubicación del ejecutable
|
||||||
|
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||||
4
Makefile
@@ -2,7 +2,7 @@ executable = jaildoctors_dilemma
|
|||||||
source = source/*.cpp
|
source = source/*.cpp
|
||||||
appName = JailDoctor's Dilemma
|
appName = JailDoctor's Dilemma
|
||||||
releaseFolder = jdd_release
|
releaseFolder = jdd_release
|
||||||
version = v1.09
|
version = v1.10
|
||||||
|
|
||||||
# Release names
|
# Release names
|
||||||
windowsRelease = $(executable)-$(version)-win32-x64.zip
|
windowsRelease = $(executable)-$(version)-win32-x64.zip
|
||||||
@@ -90,7 +90,7 @@ macos_release:
|
|||||||
ln -s /Applications "$(releaseFolder)"/Applications
|
ln -s /Applications "$(releaseFolder)"/Applications
|
||||||
|
|
||||||
# Build INTEL
|
# Build INTEL
|
||||||
clang++ $(source) -D MACOS_BUNDLE -std=$(cpp_standard) -Wall -Os -framework SDL2 -F ./Frameworks -framework OpenGL -Wno-deprecated -ffunction-sections -fdata-sections -o "$(releaseFolder)/$(appName).app/Contents/MacOS/$(executable)" -rpath @executable_path/../Frameworks/ -target x86_64-apple-macos10.12
|
clang++ $(source) -D MACOS_BUNDLE -std=$(cpp_standard) -Wall -Os -framework SDL2 -F ./Frameworks -framework OpenGL -Wno-deprecated -ffunction-sections -fdata-sections -o "$(releaseFolder)/$(appName).app/Contents/MacOS/$(executable)" -rpath @executable_path/../Frameworks/ -target x86_64-apple-macos10.15
|
||||||
|
|
||||||
# Build INTEL DMG
|
# Build INTEL DMG
|
||||||
hdiutil create tmp.dmg -ov -volname "$(appName)" -fs HFS+ -srcfolder "$(releaseFolder)"
|
hdiutil create tmp.dmg -ov -volname "$(appName)" -fs HFS+ -srcfolder "$(releaseFolder)"
|
||||||
|
|||||||
14
README.md
@@ -1,8 +1,8 @@
|
|||||||
# JailDoctor's Dilemma
|
# JailDoctor's Dilemma
|
||||||
|
|
||||||
JailDoc és un Jailer. Als Jailers els agrada començar projectes. A ningú li agrada acabar-los. Els Jailers viuen a la Jail. A la Jail s'hi va a començar projectes. A la Jail s'hi va a ensenyar els projectes. A la Jail s'hi va a aprendre com començar nous projectes. A la Jail s'hi va a ajudar els companys a començar nous projectes.
|
<img src="https://php.sustancia.synology.me/images/jdd/jaildoctors_dilemma_cover_web.png" width="300" align="left" style="margin-right: 20px; margin-bottom: 10px;" alt="JailDoctor's Dilemma Cover">
|
||||||
|
|
||||||

|
JailDoc és un Jailer. Als Jailers els agrada començar projectes. A ningú li agrada acabar-los. Els Jailers viuen a la Jail. A la Jail s'hi va a començar projectes. A la Jail s'hi va a ensenyar els projectes. A la Jail s'hi va a aprendre com començar nous projectes. A la Jail s'hi va a ajudar els companys a començar nous projectes.
|
||||||
|
|
||||||
JailDoc és un Jailer destacat entre els Jailers. Té més projectes començats que ningú i és qui més ajuda als altres a iniciar els seus.
|
JailDoc és un Jailer destacat entre els Jailers. Té més projectes començats que ningú i és qui més ajuda als altres a iniciar els seus.
|
||||||
|
|
||||||
@@ -10,6 +10,8 @@ Però un dia, va passar una cosa inesperada. Algú va acabar un projecte. Algú
|
|||||||
|
|
||||||
Això va fer que JailDoc prenguera una decisió: acabaria i lliuraria un dels seus projectes. Però, quin? *JailBattle*? *Sigmasuá*? *Calculín Doom*? Quin dilema! Finalment, es va arromangar i va decidir acabar i lliurar **tots** els seus projectes inacabats. Ho aconseguirà?
|
Això va fer que JailDoc prenguera una decisió: acabaria i lliuraria un dels seus projectes. Però, quin? *JailBattle*? *Sigmasuá*? *Calculín Doom*? Quin dilema! Finalment, es va arromangar i va decidir acabar i lliurar **tots** els seus projectes inacabats. Ho aconseguirà?
|
||||||
|
|
||||||
|
<br clear="left">
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Jugabilitat
|
## Jugabilitat
|
||||||
@@ -36,9 +38,11 @@ El joc permet tant l'ús del teclat com d'un comandament. Les tecles per a jugar
|
|||||||
- **Tecla F1**: Disminueix la mida de la finestra.
|
- **Tecla F1**: Disminueix la mida de la finestra.
|
||||||
- **Tecla F2**: Augmenta la mida de la finestra.
|
- **Tecla F2**: Augmenta la mida de la finestra.
|
||||||
- **Tecla F3**: Alterna entre el mode de pantalla completa i el mode finestra.
|
- **Tecla F3**: Alterna entre el mode de pantalla completa i el mode finestra.
|
||||||
- **Tecla F4**: Activa o desactiva els shaders
|
- **Tecla F4**: Activa o desactiva els shaders.
|
||||||
- **Tecla F5**: Canvia la paleta de colors del joc.
|
- **Tecla F5**: Estableix la següent paleta de colors.
|
||||||
- **Tecla B**: Activa o desactiva el marge de colors en mode finestra.
|
- **Tecla F6**: Estableix la paleta de colors prèvia.
|
||||||
|
- **Tecla F7**: Activa o desactiva el escalat exacte.
|
||||||
|
- **Tecla B**: Activa o desactiva el marge de colors.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=shine.gif
|
||||||
frame_width=8
|
frame_width=8
|
||||||
frame_height=8
|
frame_height=8
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=6
|
speed=0.1000
|
||||||
loop=-1
|
loop=-1
|
||||||
frames=0,1,2,3,4,5,6,7
|
frames=0,1,2,3,4,5,6,7
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/credits/shine.gif
Normal file
|
After Width: | Height: | Size: 107 B |
|
Before Width: | Height: | Size: 148 B |
BIN
data/ending/ending1.gif
Normal file
|
After Width: | Height: | Size: 1014 B |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
BIN
data/ending/ending2.gif
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 4.3 KiB |
BIN
data/ending/ending3.gif
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
BIN
data/ending/ending4.gif
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
BIN
data/ending/ending5.gif
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=abad.gif
|
||||||
frame_width=8
|
frame_width=8
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=0.1333
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2
|
frames=0,1,2
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/abad.gif
Normal file
|
After Width: | Height: | Size: 130 B |
|
Before Width: | Height: | Size: 267 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=abad_bell.gif
|
||||||
frame_width=16
|
frame_width=16
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=4
|
speed=0.0667
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3,4,5,6,7,8,9
|
frames=0,1,2,3,4,5,6,7,8,9
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/abad_bell.gif
Normal file
|
After Width: | Height: | Size: 384 B |
|
Before Width: | Height: | Size: 555 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=amstrad_cs.gif
|
||||||
frame_width=8
|
frame_width=8
|
||||||
frame_height=8
|
frame_height=8
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=4
|
speed=0.0667
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
|
frames=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|||||||
BIN
data/enemies/amstrad_cs.gif
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=arounders_door.gif
|
||||||
frame_width=16
|
frame_width=16
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=0.1333
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3,3,3,3,3,3,3,3,3,3,3,3,2,1,0,0,0
|
frames=0,1,2,3,3,3,3,3,3,3,3,3,3,3,3,2,1,0,0,0
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/arounders_door.gif
Normal file
|
After Width: | Height: | Size: 198 B |
|
Before Width: | Height: | Size: 250 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=arounders_machine.gif
|
||||||
frame_width=16
|
frame_width=16
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=4
|
speed=0.0667
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3
|
frames=0,1,2,3
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/arounders_machine.gif
Normal file
|
After Width: | Height: | Size: 195 B |
|
Before Width: | Height: | Size: 234 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=bat.gif
|
||||||
frame_width=9
|
frame_width=9
|
||||||
frame_height=7
|
frame_height=7
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=3
|
speed=0.0500
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1
|
frames=0,1
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/bat.gif
Normal file
|
After Width: | Height: | Size: 86 B |
|
Before Width: | Height: | Size: 134 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=batman.gif
|
||||||
frame_width=8
|
frame_width=8
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=0.1333
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3
|
frames=0,1,2,3
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/batman.gif
Normal file
|
After Width: | Height: | Size: 146 B |
|
Before Width: | Height: | Size: 241 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=batman_bell.gif
|
||||||
frame_width=16
|
frame_width=16
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=6
|
speed=0.1000
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3,4,5
|
frames=0,1,2,3,4,5
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/batman_bell.gif
Normal file
|
After Width: | Height: | Size: 267 B |
|
Before Width: | Height: | Size: 415 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=batman_fire.gif
|
||||||
frame_width=16
|
frame_width=16
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=4
|
speed=0.0667
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3
|
frames=0,1,2,3
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/batman_fire.gif
Normal file
|
After Width: | Height: | Size: 213 B |
|
Before Width: | Height: | Size: 343 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=bell.gif
|
||||||
frame_width=16
|
frame_width=16
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=6
|
speed=0.1000
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3,4,5,6,7,8,9,10,11
|
frames=0,1,2,3,4,5,6,7,8,9,10,11
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/bell.gif
Normal file
|
After Width: | Height: | Size: 412 B |
|
Before Width: | Height: | Size: 509 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=bin.gif
|
||||||
frame_width=16
|
frame_width=16
|
||||||
frame_height=8
|
frame_height=8
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=10
|
speed=0.1667
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3,4
|
frames=0,1,2,3,4
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/bin.gif
Normal file
|
After Width: | Height: | Size: 146 B |
|
Before Width: | Height: | Size: 174 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=bird.gif
|
||||||
frame_width=16
|
frame_width=16
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=0.1333
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3
|
frames=0,1,2,3
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/bird.gif
Normal file
|
After Width: | Height: | Size: 195 B |
|
Before Width: | Height: | Size: 306 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=breakout.gif
|
||||||
frame_width=24
|
frame_width=24
|
||||||
frame_height=32
|
frame_height=32
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=6
|
speed=0.1000
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3,4,5,6,7,6,5,4,3,2,1
|
frames=0,1,2,3,4,5,6,7,6,5,4,3,2,1
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/breakout.gif
Normal file
|
After Width: | Height: | Size: 195 B |
|
Before Width: | Height: | Size: 180 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=bry.gif
|
||||||
frame_width=10
|
frame_width=10
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=6
|
speed=0.1000
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5
|
frames=0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/bry.gif
Normal file
|
After Width: | Height: | Size: 208 B |
|
Before Width: | Height: | Size: 253 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=chip.gif
|
||||||
frame_width=8
|
frame_width=8
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=0.1333
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3
|
frames=0,1,2,3
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/chip.gif
Normal file
|
After Width: | Height: | Size: 146 B |
|
Before Width: | Height: | Size: 208 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=code.gif
|
||||||
frame_width=16
|
frame_width=16
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=6
|
speed=0.1000
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3
|
frames=0,1,2,3
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/code.gif
Normal file
|
After Width: | Height: | Size: 198 B |
|
Before Width: | Height: | Size: 319 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=congo.gif
|
||||||
frame_width=8
|
frame_width=8
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=6
|
speed=0.1000
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3
|
frames=0,1,2,3
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/congo.gif
Normal file
|
After Width: | Height: | Size: 145 B |
|
Before Width: | Height: | Size: 231 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=crosshair.gif
|
||||||
frame_width=16
|
frame_width=16
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=6
|
speed=0.1000
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3
|
frames=0,1,2,3
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/crosshair.gif
Normal file
|
After Width: | Height: | Size: 213 B |
|
Before Width: | Height: | Size: 288 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=demon.gif
|
||||||
frame_width=16
|
frame_width=16
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=0.1333
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3
|
frames=0,1,2,3
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/demon.gif
Normal file
|
After Width: | Height: | Size: 213 B |
|
Before Width: | Height: | Size: 329 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=dimallas.gif
|
||||||
frame_width=16
|
frame_width=16
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=0.1333
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3
|
frames=0,1,2,3
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/dimallas.gif
Normal file
|
After Width: | Height: | Size: 212 B |
|
Before Width: | Height: | Size: 298 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=dong.gif
|
||||||
frame_width=22
|
frame_width=22
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=6
|
speed=0.1000
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3,4,5
|
frames=0,1,2,3,4,5
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/dong.gif
Normal file
|
After Width: | Height: | Size: 355 B |
|
Before Width: | Height: | Size: 630 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=elsa.gif
|
||||||
frame_width=16
|
frame_width=16
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=6
|
speed=0.1000
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3,4,5
|
frames=0,1,2,3,4,5
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/elsa.gif
Normal file
|
After Width: | Height: | Size: 236 B |
|
Before Width: | Height: | Size: 310 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=floppy.gif
|
||||||
frame_width=16
|
frame_width=16
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=0.1333
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3
|
frames=0,1,2,3
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/floppy.gif
Normal file
|
After Width: | Height: | Size: 210 B |
|
Before Width: | Height: | Size: 271 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=flying_arounder.gif
|
||||||
frame_width=7
|
frame_width=7
|
||||||
frame_height=7
|
frame_height=7
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=10
|
speed=0.1667
|
||||||
loop=0
|
loop=0
|
||||||
frames=0
|
frames=0
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/flying_arounder.gif
Normal file
|
After Width: | Height: | Size: 73 B |
|
Before Width: | Height: | Size: 122 B |
@@ -1,9 +1,10 @@
|
|||||||
|
tileSetFile=guitar.gif
|
||||||
frame_width=16
|
frame_width=16
|
||||||
frame_height=16
|
frame_height=16
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=0.1333
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3
|
frames=0,1,2,3
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/enemies/guitar.gif
Normal file
|
After Width: | Height: | Size: 220 B |
|
Before Width: | Height: | Size: 306 B |