creat project.h
This commit is contained in:
212
CLAUDE.md
212
CLAUDE.md
@@ -4,11 +4,11 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||
|
||||
## Project Overview
|
||||
|
||||
This is an **Asteroids-style game** originally written in **Turbo Pascal 7 for DOS** (1999), now being **migrated to modern C++20 with SDL3**. The game features a spaceship that must avoid and destroy enemies (pentagonal "ORNIs"). This is a **phased migration** preserving the original game feel.
|
||||
This is **Orni Attack**, an **Asteroids-style game** originally written in **Turbo Pascal 7 for DOS** (1999), now being **migrated to modern C++20 with SDL3**. The game features a spaceship that must avoid and destroy enemies (pentagonal "ORNIs"). This is a **phased migration** preserving the original game feel.
|
||||
|
||||
**Language**: All code, comments, and variable names are in **Catalan/Valencian** (preserved from original).
|
||||
|
||||
**Current Status**: **BETA 2.2** - Phases 0-9 completed (playable with ship, enemies, and bullets).
|
||||
**Current Status**: **BETA 3.0** - Modernized architecture with dynamic windows, modular code organization, viewport scaling, and auto-generated project metadata.
|
||||
|
||||
## Build System
|
||||
|
||||
@@ -21,7 +21,7 @@ Based on `/home/sergio/gitea/pollo` project structure.
|
||||
make clean && make
|
||||
|
||||
# Run
|
||||
./asteroids
|
||||
./orni
|
||||
|
||||
# Individual targets
|
||||
make linux # Linux build
|
||||
@@ -31,22 +31,68 @@ make windows # Windows build (MinGW)
|
||||
|
||||
### Build Files
|
||||
|
||||
- **CMakeLists.txt** - CMake configuration (C++20, SDL3)
|
||||
- **CMakeLists.txt** - CMake configuration (C++20, SDL3, project metadata)
|
||||
- **Makefile** - Cross-platform wrapper, extracts project info from CMakeLists.txt
|
||||
- **source/project.h.in** - Template for auto-generated project.h
|
||||
- **build/project.h** - Auto-generated (by CMake) with project constants
|
||||
- **release/** - Platform-specific resources (icons, .rc, .plist)
|
||||
|
||||
### Project Metadata System
|
||||
|
||||
**Auto-generation with CMake**:
|
||||
|
||||
CMake generates `build/project.h` from `source/project.h.in` template on every compilation:
|
||||
|
||||
```cpp
|
||||
// build/project.h (generated automatically)
|
||||
namespace Project {
|
||||
constexpr const char* NAME = "orni"; // From project(orni ...)
|
||||
constexpr const char* LONG_NAME = "Orni Attack"; // From PROJECT_LONG_NAME
|
||||
constexpr const char* VERSION = "0.1.0"; // From VERSION
|
||||
constexpr const char* COPYRIGHT = "© 1999..."; // From PROJECT_COPYRIGHT
|
||||
constexpr const char* GIT_HASH = "abc1234"; // From git rev-parse
|
||||
}
|
||||
```
|
||||
|
||||
**Window title format** (dynamic, in sdl_manager.cpp):
|
||||
```cpp
|
||||
std::format("{} v{} ({})",
|
||||
Project::LONG_NAME, // "Orni Attack"
|
||||
Project::VERSION, // "0.1.0"
|
||||
Project::COPYRIGHT) // "© 1999 Visente i Sergi, 2025 Port"
|
||||
```
|
||||
|
||||
Result: `Orni Attack v0.1.0 (© 1999 Visente i Sergi, 2025 Port)`
|
||||
|
||||
**Single source of truth**: All project info in CMakeLists.txt, no hardcoded strings.
|
||||
|
||||
## Architecture
|
||||
|
||||
### File Structure
|
||||
### File Structure (BETA 3.0)
|
||||
|
||||
```
|
||||
source/
|
||||
├── main.cpp # Entry point, game loop, delta_time calculation
|
||||
├── sdl_manager.hpp/cpp # SDL3 initialization, window, renderer
|
||||
├── joc_asteroides.hpp # Game structures, constants
|
||||
└── joc_asteroides.cpp # Game logic, physics, rendering
|
||||
├── core/ - Reusable engine layer
|
||||
│ ├── defaults.hpp - Configuration constants (SINGLE SOURCE OF TRUTH)
|
||||
│ ├── types.hpp - Data structures (IPunt, Punt, Triangle, Poligon)
|
||||
│ └── rendering/
|
||||
│ ├── sdl_manager.hpp/cpp - SDL3 window management + viewport scaling
|
||||
│ └── primitives.hpp/cpp - Pure geometric functions
|
||||
├── game/ - Asteroids-specific game logic
|
||||
│ ├── constants.hpp - Legacy constant aliases
|
||||
│ └── joc_asteroides.hpp/cpp - Game loop, physics, rendering
|
||||
├── utils/ - Shared utilities (empty for now)
|
||||
├── main.cpp - Entry point, F1/F2/F3 window controls
|
||||
└── legacy/
|
||||
└── asteroids.cpp - Original Pascal code (reference only)
|
||||
```
|
||||
|
||||
**Key architectural decisions:**
|
||||
- **core/** contains reusable, game-agnostic code
|
||||
- **game/** contains Asteroids-specific logic
|
||||
- All constants centralized in `core/defaults.hpp`
|
||||
- Backward compatibility via `game/constants.hpp` aliases
|
||||
|
||||
### Core Data Structures
|
||||
|
||||
The game uses **polar coordinates** for all geometric objects (preserved from Pascal original):
|
||||
@@ -571,6 +617,153 @@ if (time_accumulator >= 1.0f) {
|
||||
- Cross-platform testing
|
||||
- Final physics tuning
|
||||
|
||||
## IMPORTANT: Modernization Architecture (BETA 3.0)
|
||||
|
||||
Starting from BETA 3.0, the project has evolved into a professional modular architecture:
|
||||
|
||||
### Structural Changes
|
||||
|
||||
**Before (BETA 2.2):**
|
||||
```
|
||||
source/
|
||||
├── main.cpp
|
||||
├── sdl_manager.hpp/cpp
|
||||
├── joc_asteroides.hpp/cpp
|
||||
└── asteroids.cpp (Pascal)
|
||||
```
|
||||
|
||||
**Now (BETA 3.0):**
|
||||
```
|
||||
source/
|
||||
├── core/ - Reusable engine
|
||||
│ ├── defaults.hpp - SINGLE SOURCE OF TRUTH for constants
|
||||
│ ├── types.hpp - Data structures
|
||||
│ └── rendering/
|
||||
│ ├── sdl_manager - Dynamic windows + viewport
|
||||
│ └── primitives - Pure geometric functions
|
||||
├── game/ - Asteroids-specific logic
|
||||
│ ├── constants.hpp - Aliases for backward compatibility
|
||||
│ └── joc_asteroides - Game loop
|
||||
├── utils/ - Shared utilities
|
||||
├── main.cpp - Entry point
|
||||
└── legacy/
|
||||
└── asteroids.cpp - Original Pascal code (reference)
|
||||
```
|
||||
|
||||
### Dynamic Window System
|
||||
|
||||
**Controls:**
|
||||
- **F1**: Decrease window (-100px width/height)
|
||||
- **F2**: Increase window (+100px width/height)
|
||||
- **F3**: Toggle fullscreen
|
||||
- **ESC**: Exit (unchanged)
|
||||
|
||||
**Behavior:**
|
||||
- Window starts at 640x480 centered on screen
|
||||
- Each resize keeps window centered on itself
|
||||
- Minimum size: 320x240
|
||||
- Maximum size: Calculated from display resolution (limit -100px)
|
||||
|
||||
**Viewport Scaling (SDL3):**
|
||||
- Game ALWAYS renders in logical coordinates 640x480
|
||||
- SDL3 automatically scales to any physical window size
|
||||
- Aspect ratio preserved (4:3 with letterboxing)
|
||||
- Vectors look SHARPER in larger windows (higher resolution)
|
||||
- Game physics UNCHANGED (still px/s relative to 640x480 logical)
|
||||
|
||||
**Implementation:**
|
||||
```cpp
|
||||
SDL_SetRenderLogicalPresentation(
|
||||
renderer_,
|
||||
640, 480, // Fixed logical size
|
||||
SDL_LOGICAL_PRESENTATION_LETTERBOX // Maintain aspect ratio
|
||||
);
|
||||
```
|
||||
|
||||
### Configuration System
|
||||
|
||||
**core/defaults.hpp** - Only place to change constants:
|
||||
|
||||
```cpp
|
||||
namespace Defaults {
|
||||
namespace Window {
|
||||
constexpr int WIDTH = 640;
|
||||
constexpr int HEIGHT = 480;
|
||||
constexpr int SIZE_INCREMENT = 100; // F1/F2
|
||||
}
|
||||
|
||||
namespace Game {
|
||||
constexpr int WIDTH = 640; // Logical
|
||||
constexpr int HEIGHT = 480;
|
||||
constexpr int MARGIN_LEFT = 20; // MARGE_ESQ
|
||||
constexpr int MARGIN_RIGHT = 620; // MARGE_DRET
|
||||
// ...
|
||||
}
|
||||
|
||||
namespace Physics {
|
||||
constexpr float ROTATION_SPEED = 2.5f;
|
||||
constexpr float ACCELERATION = 100.0f;
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**game/constants.hpp** - Backward compatibility:
|
||||
```cpp
|
||||
using Defaults::Game::MARGIN_LEFT; // For legacy code using MARGE_ESQ
|
||||
// ...
|
||||
```
|
||||
|
||||
### Important Reminders
|
||||
|
||||
**1. Logical vs Physical Coordinates**
|
||||
- ALL game code uses logical coordinates (640x480)
|
||||
- NO need to adjust physics or collision calculations
|
||||
- SDL3 handles conversion automatically
|
||||
|
||||
**2. Rendering**
|
||||
- `linea()`, `rota_tri()`, `rota_pol()` still use direct coords
|
||||
- NO manual transformation, SDL does it internally
|
||||
|
||||
**3. Configuration**
|
||||
- NEVER use magic numbers in new code
|
||||
- Always reference `Defaults::*`
|
||||
- For game values, create aliases in `game/constants.hpp` if needed
|
||||
|
||||
**4. Future OpenGL**
|
||||
- Current system allows migrating to OpenGL without changing game code
|
||||
- Would only require changing SDLManager and rendering function implementations
|
||||
- Postponed until needing >50 enemies or complex effects
|
||||
|
||||
### Compilation
|
||||
|
||||
**No changes:**
|
||||
```bash
|
||||
make clean && make
|
||||
./asteroids
|
||||
```
|
||||
|
||||
**Files modified by CMake:**
|
||||
- Updated to include subdirectories core/, game/
|
||||
- Include path: `${CMAKE_SOURCE_DIR}/source` (for relative includes)
|
||||
|
||||
### Migration for Future Sessions
|
||||
|
||||
If you find code using magic numbers:
|
||||
1. Add constant in `core/defaults.hpp` in the appropriate namespace
|
||||
2. If it's a frequently used game value, create alias in `game/constants.hpp`
|
||||
3. Replace the number with the constant
|
||||
4. Compile and verify
|
||||
|
||||
Example:
|
||||
```cpp
|
||||
// Before (bad):
|
||||
if (enemy.centre.x < 20 || enemy.centre.x > 620) { ... }
|
||||
|
||||
// After (good):
|
||||
if (enemy.centre.x < MARGIN_LEFT || enemy.centre.x > MARGIN_RIGHT) { ... }
|
||||
```
|
||||
|
||||
## Tips for Future Claude Code Sessions
|
||||
|
||||
- **Always read this file first** before making changes
|
||||
@@ -582,3 +775,4 @@ if (time_accumulator >= 1.0f) {
|
||||
- **Angle convention**: angle=0 points UP (not right), hence `angle - PI/2` in calculations
|
||||
- **One bullet at a time**: Original game limitation, preserve it
|
||||
- **Simple code style**: Avoid over-engineering, keep "small DOS program" feel
|
||||
- **Use defaults.hpp**: Never hardcode constants, always use Defaults namespace
|
||||
|
||||
Reference in New Issue
Block a user