treballant en el overlay, el text i les notificacions
This commit is contained in:
69
CLAUDE.md
69
CLAUDE.md
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|||||||
|
|
||||||
## Project Overview
|
## Project Overview
|
||||||
|
|
||||||
**Aventures En Egipte (AEE)** — a retro-style 2D game written in C++ using SDL3. The game uses a software-rendered 8-bit paletted graphics engine (320x200, 256 colors) with an OpenGL CRT shader pass, custom audio (JailAudio replacing SDL_Mixer), and GIF-based assets. The codebase and commit messages are in Valencian/Catalan.
|
**Aventures En Egipte (AEE)** — a retro-style 2D game written in C++ using SDL3. The game uses a software-rendered 8-bit paletted graphics engine (320x200, 256 colors), custom audio (JailAudio), and GIF-based assets. The codebase and commit messages are in Valencian/Catalan.
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
@@ -18,38 +18,61 @@ cmake -B build -G "MinGW Makefiles"
|
|||||||
cmake --build build
|
cmake --build build
|
||||||
```
|
```
|
||||||
|
|
||||||
Dependencies: SDL3, OpenGL. Uses CMake (minimum 3.10) with C++20.
|
Dependencies: SDL3. Uses CMake (minimum 3.10) with C++20.
|
||||||
|
|
||||||
The executable is output to the project root. The `data/` folder contains runtime assets (GIF images, OGG music, GLSL shader) and must be in the working directory at runtime.
|
The executable is output to the project root. The `data/` folder must be in the working directory at runtime.
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
### Custom "Jail" Engine Libraries (prefix: J)
|
### Boundary: Original vs New Code
|
||||||
|
|
||||||
All engine modules are flat C-style APIs (no classes), prefixed by subsystem:
|
The codebase has a clear separation between the original game and the new modernization layer:
|
||||||
|
|
||||||
- **JG** (`source/core/jgame`) — Game loop timing: init/finalize, fixed-timestep update via `JG_ShouldUpdate()`
|
| Path | Owner | Rule |
|
||||||
- **JD8** (`source/core/jdraw8`) — 8-bit paletted software renderer. 320x200 screen buffer (`JD8_Surface` = `Uint8*`), palette-indexed blitting with color-key transparency, fade effects. `JD8_Flip()` converts the indexed buffer to ARGB, uploads to SDL texture, and renders through the CRT shader
|
|------|-------|------|
|
||||||
- **JA** (`source/core/jail_audio`) — Custom audio mixing using SDL3 audio streams directly (OGG via stb_vorbis, WAV). Manages music and sound channels independently
|
| `source/core/jail/` | Original engine | **Do not modify** gameplay behavior |
|
||||||
- **JI** (`source/core/jinput`) — Input: keyboard state polling, key debouncing, cheat code detection
|
| `source/game/*.cpp/hpp` (except options/defines/defaults) | Original game | **Do not modify** |
|
||||||
- **JF** (`source/core/jfile`) — File I/O: supports loading from filesystem folder or a packed resource file (`.jrf`). Currently uses folder mode (`data/`)
|
| `source/core/rendering/` | New presentation layer | Free to modify |
|
||||||
- **shader** (`source/core/jshader`) — OpenGL post-processing shader (CRT effect) applied to the back buffer
|
| `source/core/input/` | New input layer | Free to modify |
|
||||||
|
| `source/game/options.hpp/cpp` | New config system | Free to modify |
|
||||||
|
| `source/game/defines.hpp` | New constants | Free to modify |
|
||||||
|
| `source/game/defaults.hpp` | New defaults | Free to modify |
|
||||||
|
| `data/*.gif, *.ogg` | Original assets | **Do not modify** |
|
||||||
|
| `data/fonts/, data/ui/` | New assets | Free to modify |
|
||||||
|
|
||||||
|
### Original "Jail" Engine (`source/core/jail/`)
|
||||||
|
|
||||||
|
Flat C-style APIs (no classes), prefixed by subsystem. **Do not touch gameplay logic.**
|
||||||
|
|
||||||
|
- **JG** (`jgame`) — Game loop timing: init/finalize, fixed-timestep update via `JG_ShouldUpdate()`
|
||||||
|
- **JD8** (`jdraw8`) — 8-bit paletted software renderer. 320x200 screen buffer (`JD8_Surface` = `Uint8*`), palette-indexed blitting with color-key transparency, fade effects. `JD8_Flip()` converts palette→ARGB and delegates to `Screen::present()`
|
||||||
|
- **JA** (`jail_audio`) — Custom audio mixing using SDL3 audio streams (OGG via stb_vorbis, WAV)
|
||||||
|
- **JI** (`jinput`) — Input: keyboard state polling, key debouncing, cheat code detection. Calls `GlobalInputs::handle()` at end of each update
|
||||||
|
- **JF** (`jfile`) — File I/O: filesystem folder mode (`data/`) or packed resource file (`.jrf`)
|
||||||
|
|
||||||
|
### Presentation Layer (`source/core/rendering/`)
|
||||||
|
|
||||||
|
- **Screen** — Singleton managing SDL_Window, SDL_Renderer, SDL_Texture. Receives ARGB pixel buffer from JD8 and presents it. Handles fullscreen toggle, zoom. Prepared for future SDL3GPU backend
|
||||||
|
|
||||||
|
### Input Layer (`source/core/input/`)
|
||||||
|
|
||||||
|
- **GlobalInputs** — Maps configurable function keys to window management actions (F1 zoom-, F2 zoom+, F3 fullscreen). Reads key bindings from `Options::keys_gui`
|
||||||
|
|
||||||
### Configuration System (`source/game/`)
|
### Configuration System (`source/game/`)
|
||||||
|
|
||||||
Follows the pattern from `jaildoctors_dilemma`:
|
Follows the pattern from `jaildoctors_dilemma`:
|
||||||
|
|
||||||
- **defines.hpp** <EFBFBD><EFBFBD> Game-wide constants (window title, version, screen dimensions)
|
- **defines.hpp** — Game-wide constants (window title, version, screen dimensions)
|
||||||
- **defaults.hpp** — Default values for all persistent options (audio, game)
|
- **defaults.hpp** — Default values for all persistent options, including key bindings (`Defaults::KeysGUI`, `Defaults::KeysGame`)
|
||||||
- **options.hpp/cpp** — `Options` namespace with structs, inline globals, and YAML load/save API. Config persists to `~/.config/jailgames/aee/config.yaml` (Linux), `%APPDATA%/jailgames/aee/` (Windows)
|
- **options.hpp/cpp** — `Options` namespace with structs, inline globals, and YAML load/save API. Config persists to `~/.config/jailgames/aee/config.yaml` (Linux), `%APPDATA%/jailgames/aee/` (Windows)
|
||||||
|
|
||||||
### Game Modules (`source/game/`)
|
### Game Modules (`source/game/`) — Original, Do Not Touch
|
||||||
|
|
||||||
- **ModuleSequence** — Non-gameplay screens: intro, menu, slides, banners, credits, death screen. State machine entry point (state=1)
|
- **ModuleSequence** — Non-gameplay screens: intro, menu, slides, banners, credits, death screen (state=1)
|
||||||
- **ModuleGame** — Core gameplay loop. Owns and orchestrates all game objects. State=0
|
- **ModuleGame** — Core gameplay loop, orchestrates all game objects (state=0)
|
||||||
- **Sprite** — Base class for animated entities (frame/animation data via `Entitat`)
|
- **Sprite** — Base class for animated entities (frame/animation data via `Entitat`)
|
||||||
- **Prota** — Player character ("Sam"), extends Sprite
|
- **Prota** — Player character ("Sam"), extends Sprite
|
||||||
- **Mapa** — Level map with tomb grid (16 tombs), items (treasure, keys, pharaoh, mummy, scroll, diamond), door logic
|
- **Mapa** — Level map with tomb grid (16 tombs), items, door logic
|
||||||
- **Momia** — Enemy: mummies
|
- **Momia** — Enemy: mummies
|
||||||
- **Bola** — Enemy: projectile ball
|
- **Bola** — Enemy: projectile ball
|
||||||
- **Marcador** — HUD/scoreboard
|
- **Marcador** — HUD/scoreboard
|
||||||
@@ -61,19 +84,21 @@ Follows the pattern from `jaildoctors_dilemma`:
|
|||||||
- `stb_vorbis.h` — stb single-header OGG decoder
|
- `stb_vorbis.h` — stb single-header OGG decoder
|
||||||
- `fkyaml_node.hpp` — Header-only YAML parser (fkYAML v0.4.2)
|
- `fkyaml_node.hpp` — Header-only YAML parser (fkYAML v0.4.2)
|
||||||
|
|
||||||
|
### Data Assets (`data/`)
|
||||||
|
|
||||||
|
- `*.gif`, `*.ogg`, `crtpi.glsl` — Original game assets (**do not modify**)
|
||||||
|
- `fonts/` — New font assets for overlay/UI
|
||||||
|
- `ui/` — New UI graphics for overlay
|
||||||
|
|
||||||
### Main Loop (`source/main.cpp`)
|
### Main Loop (`source/main.cpp`)
|
||||||
|
|
||||||
A state machine alternates between `ModuleSequence` (state 1) and `ModuleGame` (state 0). Each module's `Go()` returns the next state (-1 to quit). Modules are allocated/freed each transition.
|
A state machine alternates between `ModuleSequence` (state 1) and `ModuleGame` (state 0). Each module's `Go()` returns the next state (-1 to quit). Modules are allocated/freed each transition.
|
||||||
|
|
||||||
### Golden Rule: Do Not Touch Gameplay
|
|
||||||
|
|
||||||
The original game logic (gameplay, entities, map, scoring, collisions, animations) must remain untouched. All modernization work targets the presentation layer and infrastructure only: window management, configuration/persistence, rendering pipeline (overlay/UI), and build system. Any new feature (save states, options menu, etc.) must be implemented as an overlay on top of the existing game, never by modifying the original gameplay code.
|
|
||||||
|
|
||||||
### Key Conventions
|
### Key Conventions
|
||||||
|
|
||||||
- All surfaces are 320x200 = 64000 bytes. Pixel coordinates assume this fixed resolution
|
- All surfaces are 320x200 = 64000 bytes. Pixel coordinates assume this fixed resolution
|
||||||
- Graphics loaded from GIF files, palettes extracted from GIF headers
|
- Graphics loaded from GIF files, palettes extracted from GIF headers
|
||||||
- Music files are numbered OGG files (`00000001.ogg` etc.)
|
- Music files are numbered OGG files (`00000001.ogg` etc.)
|
||||||
- `trick.ini` presence enables the secret character
|
- `trick.ini` presence enables the secret character
|
||||||
- Includes use absolute paths from `source/` (e.g., `#include "core/jgame.hpp"`, `#include "game/info.hpp"`)
|
- Includes use absolute paths from `source/` (e.g., `#include "core/jail/jgame.hpp"`, `#include "game/info.hpp"`)
|
||||||
- Headers use `.hpp` extension; external third-party headers in `source/external/` keep `.h`
|
- Headers use `.hpp` extension; external third-party headers in `source/external/` keep `.h`
|
||||||
|
|||||||
@@ -12,14 +12,20 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|||||||
|
|
||||||
# --- LISTA EXPLÍCITA DE FUENTES ---
|
# --- LISTA EXPLÍCITA DE FUENTES ---
|
||||||
set(APP_SOURCES
|
set(APP_SOURCES
|
||||||
# Core - Motor "Jail"
|
# Core - Motor original "Jail" (no tocar gameplay)
|
||||||
source/core/global_inputs.cpp
|
source/core/jail/jail_audio.cpp
|
||||||
source/core/jail_audio.cpp
|
source/core/jail/jdraw8.cpp
|
||||||
source/core/jdraw8.cpp
|
source/core/jail/jfile.cpp
|
||||||
source/core/jfile.cpp
|
source/core/jail/jgame.cpp
|
||||||
source/core/jgame.cpp
|
source/core/jail/jinput.cpp
|
||||||
source/core/jinput.cpp
|
|
||||||
source/core/screen.cpp
|
# Core - Capa de presentación (nueva)
|
||||||
|
source/core/rendering/overlay.cpp
|
||||||
|
source/core/rendering/screen.cpp
|
||||||
|
source/core/rendering/text.cpp
|
||||||
|
|
||||||
|
# Core - Input global (nueva)
|
||||||
|
source/core/input/global_inputs.cpp
|
||||||
|
|
||||||
# Game
|
# Game
|
||||||
source/game/options.cpp
|
source/game/options.cpp
|
||||||
|
|||||||
0
data/fonts/.gitkeep
Normal file
0
data/fonts/.gitkeep
Normal file
132
data/fonts/8bithud.fnt
Normal file
132
data/fonts/8bithud.fnt
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
# Font: 8bithud — generado desde 8-bit-hud.ttf size 5
|
||||||
|
# Generado con tools/font_gen/font_gen.py
|
||||||
|
|
||||||
|
box_width 8
|
||||||
|
box_height 8
|
||||||
|
columns 15
|
||||||
|
|
||||||
|
# codepoint_decimal ancho_visual
|
||||||
|
32 3 # U+0020
|
||||||
|
33 2 # !
|
||||||
|
34 5 # "
|
||||||
|
35 6 # #
|
||||||
|
36 6 # $
|
||||||
|
37 6 # %
|
||||||
|
38 6 # &
|
||||||
|
39 2 # '
|
||||||
|
40 3 # (
|
||||||
|
41 3 # )
|
||||||
|
42 4 # *
|
||||||
|
43 3 # +
|
||||||
|
44 2 # ,
|
||||||
|
45 3 # -
|
||||||
|
46 2 # .
|
||||||
|
47 4 # /
|
||||||
|
48 6 # 0
|
||||||
|
49 3 # 1
|
||||||
|
50 6 # 2
|
||||||
|
51 6 # 3
|
||||||
|
52 6 # 4
|
||||||
|
53 6 # 5
|
||||||
|
54 6 # 6
|
||||||
|
55 6 # 7
|
||||||
|
56 6 # 8
|
||||||
|
57 6 # 9
|
||||||
|
58 2 # :
|
||||||
|
59 2 # ;
|
||||||
|
60 4 # <
|
||||||
|
61 3 # =
|
||||||
|
62 4 # >
|
||||||
|
63 6 # ?
|
||||||
|
64 8 # @
|
||||||
|
65 6 # A
|
||||||
|
66 6 # B
|
||||||
|
67 6 # C
|
||||||
|
68 6 # D
|
||||||
|
69 6 # E
|
||||||
|
70 6 # F
|
||||||
|
71 6 # G
|
||||||
|
72 6 # H
|
||||||
|
73 6 # I
|
||||||
|
74 6 # J
|
||||||
|
75 6 # K
|
||||||
|
76 6 # L
|
||||||
|
77 6 # M
|
||||||
|
78 6 # N
|
||||||
|
79 6 # O
|
||||||
|
80 6 # P
|
||||||
|
81 6 # Q
|
||||||
|
82 6 # R
|
||||||
|
83 6 # S
|
||||||
|
84 6 # T
|
||||||
|
85 6 # U
|
||||||
|
86 5 # V
|
||||||
|
87 6 # W
|
||||||
|
88 6 # X
|
||||||
|
89 6 # Y
|
||||||
|
90 6 # Z
|
||||||
|
91 3 # [
|
||||||
|
92 4 # \
|
||||||
|
93 3 # ]
|
||||||
|
94 4 # ^
|
||||||
|
95 6 # _
|
||||||
|
96 2 # `
|
||||||
|
97 5 # a
|
||||||
|
98 5 # b
|
||||||
|
99 5 # c
|
||||||
|
100 5 # d
|
||||||
|
101 5 # e
|
||||||
|
102 5 # f
|
||||||
|
103 5 # g
|
||||||
|
104 5 # h
|
||||||
|
105 4 # i
|
||||||
|
106 5 # j
|
||||||
|
107 5 # k
|
||||||
|
108 5 # l
|
||||||
|
109 6 # m
|
||||||
|
110 5 # n
|
||||||
|
111 5 # o
|
||||||
|
112 5 # p
|
||||||
|
113 5 # q
|
||||||
|
114 5 # r
|
||||||
|
115 5 # s
|
||||||
|
116 4 # t
|
||||||
|
117 5 # u
|
||||||
|
118 5 # v
|
||||||
|
119 6 # w
|
||||||
|
120 4 # x
|
||||||
|
121 4 # y
|
||||||
|
122 5 # z
|
||||||
|
123 4 # {
|
||||||
|
124 1 # |
|
||||||
|
125 4 # }
|
||||||
|
126 4 # ~
|
||||||
|
192 6 # À
|
||||||
|
193 6 # Á
|
||||||
|
200 6 # È
|
||||||
|
201 6 # É
|
||||||
|
204 6 # Ì
|
||||||
|
205 6 # Í
|
||||||
|
210 6 # Ò
|
||||||
|
211 6 # Ó
|
||||||
|
219 6 # Ù
|
||||||
|
218 6 # Ú
|
||||||
|
209 6 # Ñ
|
||||||
|
199 6 # Ç
|
||||||
|
224 5 # à
|
||||||
|
225 5 # á
|
||||||
|
232 5 # è
|
||||||
|
233 5 # é
|
||||||
|
236 4 # ì
|
||||||
|
237 4 # í
|
||||||
|
242 5 # ò
|
||||||
|
243 5 # ó
|
||||||
|
249 5 # ù
|
||||||
|
250 5 # ú
|
||||||
|
241 5 # ñ
|
||||||
|
231 5 # ç
|
||||||
|
161 2 # ¡
|
||||||
|
191 6 # ¿
|
||||||
|
171 4 # «
|
||||||
|
187 4 # »
|
||||||
|
183 2 # ·
|
||||||
BIN
data/fonts/8bithud.gif
Normal file
BIN
data/fonts/8bithud.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 837 B |
0
data/ui/.gitkeep
Normal file
0
data/ui/.gitkeep
Normal file
@@ -1,37 +0,0 @@
|
|||||||
#include "core/global_inputs.hpp"
|
|
||||||
|
|
||||||
#include <SDL3/SDL.h>
|
|
||||||
|
|
||||||
#include "core/jinput.hpp"
|
|
||||||
#include "core/screen.hpp"
|
|
||||||
|
|
||||||
namespace GlobalInputs {
|
|
||||||
|
|
||||||
static bool f1_was_pressed = false;
|
|
||||||
static bool f2_was_pressed = false;
|
|
||||||
static bool f3_was_pressed = false;
|
|
||||||
|
|
||||||
void handle() {
|
|
||||||
// F1 — decrement zoom
|
|
||||||
bool f1 = JI_KeyPressed(SDL_SCANCODE_F1);
|
|
||||||
if (f1 && !f1_was_pressed) {
|
|
||||||
Screen::get()->decZoom();
|
|
||||||
}
|
|
||||||
f1_was_pressed = f1;
|
|
||||||
|
|
||||||
// F2 — increment zoom
|
|
||||||
bool f2 = JI_KeyPressed(SDL_SCANCODE_F2);
|
|
||||||
if (f2 && !f2_was_pressed) {
|
|
||||||
Screen::get()->incZoom();
|
|
||||||
}
|
|
||||||
f2_was_pressed = f2;
|
|
||||||
|
|
||||||
// F3 — toggle fullscreen
|
|
||||||
bool f3 = JI_KeyPressed(SDL_SCANCODE_F3);
|
|
||||||
if (f3 && !f3_was_pressed) {
|
|
||||||
Screen::get()->toggleFullscreen();
|
|
||||||
}
|
|
||||||
f3_was_pressed = f3;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace GlobalInputs
|
|
||||||
47
source/core/input/global_inputs.cpp
Normal file
47
source/core/input/global_inputs.cpp
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include "core/input/global_inputs.hpp"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "core/jail/jinput.hpp"
|
||||||
|
#include "core/rendering/overlay.hpp"
|
||||||
|
#include "core/rendering/screen.hpp"
|
||||||
|
#include "game/options.hpp"
|
||||||
|
|
||||||
|
namespace GlobalInputs {
|
||||||
|
|
||||||
|
static bool dec_zoom_was_pressed = false;
|
||||||
|
static bool inc_zoom_was_pressed = false;
|
||||||
|
static bool fullscreen_was_pressed = false;
|
||||||
|
|
||||||
|
void handle() {
|
||||||
|
// Decrement zoom
|
||||||
|
bool dec_zoom = JI_KeyPressed(Options::keys_gui.dec_zoom);
|
||||||
|
if (dec_zoom && !dec_zoom_was_pressed) {
|
||||||
|
Screen::get()->decZoom();
|
||||||
|
char msg[32];
|
||||||
|
snprintf(msg, sizeof(msg), "ZOOM %dx", Screen::get()->getZoom());
|
||||||
|
Overlay::showNotification(msg);
|
||||||
|
}
|
||||||
|
dec_zoom_was_pressed = dec_zoom;
|
||||||
|
|
||||||
|
// Increment zoom
|
||||||
|
bool inc_zoom = JI_KeyPressed(Options::keys_gui.inc_zoom);
|
||||||
|
if (inc_zoom && !inc_zoom_was_pressed) {
|
||||||
|
Screen::get()->incZoom();
|
||||||
|
char msg[32];
|
||||||
|
snprintf(msg, sizeof(msg), "ZOOM %dx", Screen::get()->getZoom());
|
||||||
|
Overlay::showNotification(msg);
|
||||||
|
}
|
||||||
|
inc_zoom_was_pressed = inc_zoom;
|
||||||
|
|
||||||
|
// Toggle fullscreen
|
||||||
|
bool fullscreen = JI_KeyPressed(Options::keys_gui.fullscreen);
|
||||||
|
if (fullscreen && !fullscreen_was_pressed) {
|
||||||
|
Screen::get()->toggleFullscreen();
|
||||||
|
Overlay::showNotification(Screen::get()->isFullscreen() ? "FULLSCREEN" : "WINDOWED");
|
||||||
|
}
|
||||||
|
fullscreen_was_pressed = fullscreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace GlobalInputs
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef JA_USESDLMIXER
|
#ifndef JA_USESDLMIXER
|
||||||
#include "core/jail_audio.hpp"
|
#include "core/jail/jail_audio.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
#include "core/jdraw8.hpp"
|
#include "core/jail/jdraw8.hpp"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include "core/jfile.hpp"
|
#include "core/jail/jfile.hpp"
|
||||||
#include "core/screen.hpp"
|
#include "core/rendering/screen.hpp"
|
||||||
#include "external/gif.h"
|
#include "external/gif.h"
|
||||||
|
|
||||||
JD8_Surface screen = NULL;
|
JD8_Surface screen = NULL;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "core/jfile.hpp"
|
#include "core/jail/jfile.hpp"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "core/jgame.hpp"
|
#include "core/jail/jgame.hpp"
|
||||||
|
|
||||||
bool eixir = false;
|
bool eixir = false;
|
||||||
Uint32 updateTicks = 0;
|
Uint32 updateTicks = 0;
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
#include "core/jinput.hpp"
|
#include "core/jail/jinput.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "core/global_inputs.hpp"
|
#include "core/input/global_inputs.hpp"
|
||||||
#include "core/jgame.hpp"
|
#include "core/jail/jgame.hpp"
|
||||||
|
|
||||||
const bool* keystates; // = SDL_GetKeyboardState( NULL );
|
const bool* keystates; // = SDL_GetKeyboardState( NULL );
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
119
source/core/rendering/overlay.cpp
Normal file
119
source/core/rendering/overlay.cpp
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
#include "core/rendering/overlay.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "core/rendering/text.hpp"
|
||||||
|
|
||||||
|
namespace Overlay {
|
||||||
|
|
||||||
|
static std::unique_ptr<Text> font_;
|
||||||
|
|
||||||
|
// --- Notificacions amb animació ---
|
||||||
|
|
||||||
|
enum class Status { RISING, STAY, VANISHING, FINISHED };
|
||||||
|
|
||||||
|
struct Notification {
|
||||||
|
std::string message;
|
||||||
|
Status status{Status::RISING};
|
||||||
|
float y_offset{0.0F}; // 0 = fora de pantalla, 1 = posició final
|
||||||
|
float timer{0.0F};
|
||||||
|
float duration{2.0F};
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::vector<Notification> notifications_;
|
||||||
|
static Uint32 last_ticks_ = 0;
|
||||||
|
|
||||||
|
static constexpr float SLIDE_SPEED = 4.0F; // velocitat d'animació (unitats/segon)
|
||||||
|
static constexpr int BAR_HEIGHT = 12; // alçada de la barra
|
||||||
|
static constexpr int TEXT_Y_OFFSET = 2; // offset del text dins la barra
|
||||||
|
static constexpr Uint32 BG_COLOR = 0xFF1A1A2E; // fons blau fosc
|
||||||
|
static constexpr Uint32 TEXT_COLOR = 0xFF00FFFF; // cyan
|
||||||
|
static constexpr int SCREEN_W = 320;
|
||||||
|
static constexpr int SCREEN_H = 200;
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
font_ = std::make_unique<Text>("fonts/8bithud.fnt", "fonts/8bithud.gif");
|
||||||
|
last_ticks_ = SDL_GetTicks();
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy() {
|
||||||
|
font_.reset();
|
||||||
|
notifications_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drawBar(Uint32* pixel_data, int y, int h, Uint32 color) {
|
||||||
|
for (int row = y; row < y + h; row++) {
|
||||||
|
if (row < 0 || row >= SCREEN_H) continue;
|
||||||
|
for (int col = 0; col < SCREEN_W; col++) {
|
||||||
|
pixel_data[col + row * SCREEN_W] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void render(Uint32* pixel_data) {
|
||||||
|
if (!font_ || !pixel_data) return;
|
||||||
|
|
||||||
|
// Calcula delta time
|
||||||
|
Uint32 now = SDL_GetTicks();
|
||||||
|
float dt = static_cast<float>(now - last_ticks_) / 1000.0F;
|
||||||
|
last_ticks_ = now;
|
||||||
|
|
||||||
|
// Actualitza i pinta cada notificació
|
||||||
|
for (auto& notif : notifications_) {
|
||||||
|
switch (notif.status) {
|
||||||
|
case Status::RISING:
|
||||||
|
notif.y_offset += SLIDE_SPEED * dt;
|
||||||
|
if (notif.y_offset >= 1.0F) {
|
||||||
|
notif.y_offset = 1.0F;
|
||||||
|
notif.status = Status::STAY;
|
||||||
|
notif.timer = 0.0F;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Status::STAY:
|
||||||
|
notif.timer += dt;
|
||||||
|
if (notif.timer >= notif.duration) {
|
||||||
|
notif.status = Status::VANISHING;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Status::VANISHING:
|
||||||
|
notif.y_offset -= SLIDE_SPEED * dt;
|
||||||
|
if (notif.y_offset <= 0.0F) {
|
||||||
|
notif.status = Status::FINISHED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Status::FINISHED:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notif.status == Status::FINISHED) continue;
|
||||||
|
|
||||||
|
// Posició: puja des de sota la pantalla
|
||||||
|
int bar_y = SCREEN_H - static_cast<int>(notif.y_offset * BAR_HEIGHT);
|
||||||
|
|
||||||
|
// Pinta fons
|
||||||
|
drawBar(pixel_data, bar_y, BAR_HEIGHT, BG_COLOR);
|
||||||
|
|
||||||
|
// Pinta text centrat
|
||||||
|
font_->drawCentered(pixel_data, bar_y + TEXT_Y_OFFSET, notif.message.c_str(), TEXT_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Elimina les acabades
|
||||||
|
notifications_.erase(
|
||||||
|
std::remove_if(notifications_.begin(), notifications_.end(),
|
||||||
|
[](const Notification& n) { return n.status == Status::FINISHED; }),
|
||||||
|
notifications_.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void showNotification(const char* text, float duration_seconds) {
|
||||||
|
// Si ja hi ha una notificació, la reemplaça (no apilem)
|
||||||
|
notifications_.clear();
|
||||||
|
notifications_.push_back({text, Status::RISING, 0.0F, 0.0F, duration_seconds});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Overlay
|
||||||
14
source/core/rendering/overlay.hpp
Normal file
14
source/core/rendering/overlay.hpp
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
namespace Overlay {
|
||||||
|
void init();
|
||||||
|
void destroy();
|
||||||
|
|
||||||
|
// Pinta l'overlay sobre el buffer ARGB — cridar abans de presentar
|
||||||
|
void render(Uint32* pixel_data);
|
||||||
|
|
||||||
|
// Mostra una notificació amb animació slide-in/stay/slide-out
|
||||||
|
void showNotification(const char* text, float duration_seconds = 2.0F);
|
||||||
|
} // namespace Overlay
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
#include "core/screen.hpp"
|
#include "core/rendering/screen.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "core/rendering/overlay.hpp"
|
||||||
#include "game/defines.hpp"
|
#include "game/defines.hpp"
|
||||||
#include "game/options.hpp"
|
#include "game/options.hpp"
|
||||||
|
|
||||||
@@ -53,7 +54,8 @@ Screen::~Screen() {
|
|||||||
if (window_) SDL_DestroyWindow(window_);
|
if (window_) SDL_DestroyWindow(window_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::present(const Uint32* pixel_data) {
|
void Screen::present(Uint32* pixel_data) {
|
||||||
|
Overlay::render(pixel_data);
|
||||||
SDL_UpdateTexture(texture_, nullptr, pixel_data, GAME_WIDTH * sizeof(Uint32));
|
SDL_UpdateTexture(texture_, nullptr, pixel_data, GAME_WIDTH * sizeof(Uint32));
|
||||||
SDL_RenderClear(renderer_);
|
SDL_RenderClear(renderer_);
|
||||||
SDL_RenderTexture(renderer_, texture_, nullptr, nullptr);
|
SDL_RenderTexture(renderer_, texture_, nullptr, nullptr);
|
||||||
@@ -11,7 +11,7 @@ class Screen {
|
|||||||
static auto get() -> Screen*;
|
static auto get() -> Screen*;
|
||||||
|
|
||||||
// Presentació — rep el buffer ARGB de 320x200 de JD8
|
// Presentació — rep el buffer ARGB de 320x200 de JD8
|
||||||
void present(const Uint32* pixel_data);
|
void present(Uint32* pixel_data);
|
||||||
|
|
||||||
// Gestió de finestra
|
// Gestió de finestra
|
||||||
void toggleFullscreen();
|
void toggleFullscreen();
|
||||||
239
source/core/rendering/text.cpp
Normal file
239
source/core/rendering/text.cpp
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
#include "core/rendering/text.hpp"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "core/jail/jfile.hpp"
|
||||||
|
|
||||||
|
// Forward declarations de gif.h (inclòs des de jdraw8.cpp, no es pot incloure dos vegades)
|
||||||
|
struct rgb;
|
||||||
|
extern unsigned char* LoadGif(unsigned char* data, unsigned short* w, unsigned short* h);
|
||||||
|
|
||||||
|
Text::Text(const char* fnt_file, const char* gif_file) {
|
||||||
|
loadBitmap(gif_file);
|
||||||
|
loadFont(fnt_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
Text::~Text() {
|
||||||
|
if (bitmap_) free(bitmap_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- UTF-8 ---
|
||||||
|
|
||||||
|
auto Text::nextCodepoint(const char*& ptr) -> uint32_t {
|
||||||
|
auto byte = static_cast<uint8_t>(*ptr);
|
||||||
|
if (byte == 0) return 0;
|
||||||
|
|
||||||
|
uint32_t cp = 0;
|
||||||
|
int extra = 0;
|
||||||
|
|
||||||
|
if (byte < 0x80) {
|
||||||
|
cp = byte;
|
||||||
|
} else if ((byte & 0xE0) == 0xC0) {
|
||||||
|
cp = byte & 0x1F;
|
||||||
|
extra = 1;
|
||||||
|
} else if ((byte & 0xF0) == 0xE0) {
|
||||||
|
cp = byte & 0x0F;
|
||||||
|
extra = 2;
|
||||||
|
} else if ((byte & 0xF8) == 0xF0) {
|
||||||
|
cp = byte & 0x07;
|
||||||
|
extra = 3;
|
||||||
|
} else {
|
||||||
|
ptr++;
|
||||||
|
return 0xFFFD;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr++;
|
||||||
|
for (int i = 0; i < extra; i++) {
|
||||||
|
auto cont = static_cast<uint8_t>(*ptr);
|
||||||
|
if ((cont & 0xC0) != 0x80) return 0xFFFD;
|
||||||
|
cp = (cp << 6) | (cont & 0x3F);
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Càrrega de font ---
|
||||||
|
|
||||||
|
void Text::loadFont(const char* fnt_file) {
|
||||||
|
int filesize = 0;
|
||||||
|
char* buffer = file_getfilebuffer(fnt_file, filesize, true);
|
||||||
|
if (!buffer) {
|
||||||
|
std::cerr << "Text: unable to load font file: " << fnt_file << '\n';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istringstream stream(std::string(buffer, filesize));
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
int glyph_index = 0;
|
||||||
|
|
||||||
|
while (std::getline(stream, line)) {
|
||||||
|
// Ignora comentaris i línies buides
|
||||||
|
if (line.empty() || line[0] == '#') continue;
|
||||||
|
|
||||||
|
// Elimina comentaris inline
|
||||||
|
auto comment_pos = line.find('#');
|
||||||
|
if (comment_pos != std::string::npos) {
|
||||||
|
line = line.substr(0, comment_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parseja directives
|
||||||
|
if (line.find("box_width") == 0) {
|
||||||
|
sscanf(line.c_str(), "box_width %d", &box_width_);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line.find("box_height") == 0) {
|
||||||
|
sscanf(line.c_str(), "box_height %d", &box_height_);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line.find("columns") == 0) {
|
||||||
|
sscanf(line.c_str(), "columns %d", &columns_);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line.find("cell_spacing") == 0) {
|
||||||
|
sscanf(line.c_str(), "cell_spacing %d", &cell_spacing_);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line.find("row_spacing") == 0) {
|
||||||
|
sscanf(line.c_str(), "row_spacing %d", &row_spacing_);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Línies de glifos: "codepoint width"
|
||||||
|
uint32_t codepoint = 0;
|
||||||
|
int visual_width = 0;
|
||||||
|
if (sscanf(line.c_str(), "%u %d", &codepoint, &visual_width) == 2) {
|
||||||
|
int col = glyph_index % columns_;
|
||||||
|
int row = glyph_index / columns_;
|
||||||
|
|
||||||
|
GlyphInfo glyph{};
|
||||||
|
glyph.x = col * (box_width_ + cell_spacing_) + cell_spacing_;
|
||||||
|
glyph.y = row * (box_height_ + (row_spacing_ > 0 ? row_spacing_ : cell_spacing_)) + cell_spacing_;
|
||||||
|
glyph.w = visual_width;
|
||||||
|
|
||||||
|
glyphs_[codepoint] = glyph;
|
||||||
|
glyph_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Text: loaded font with " << glyphs_.size() << " glyphs (" << box_width_ << "x" << box_height_ << ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text::loadBitmap(const char* gif_file) {
|
||||||
|
int filesize = 0;
|
||||||
|
char* buffer = file_getfilebuffer(gif_file, filesize);
|
||||||
|
if (!buffer) {
|
||||||
|
std::cerr << "Text: unable to load bitmap: " << gif_file << '\n';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extrau dimensions del header GIF (bytes 6-7 = width, 8-9 = height, little-endian)
|
||||||
|
auto* raw = reinterpret_cast<unsigned char*>(buffer);
|
||||||
|
int w = raw[6] | (raw[7] << 8);
|
||||||
|
int h = raw[8] | (raw[9] << 8);
|
||||||
|
|
||||||
|
unsigned short gw = 0, gh = 0;
|
||||||
|
Uint8* pixels = LoadGif(raw, &gw, &gh);
|
||||||
|
if (!pixels) {
|
||||||
|
std::cerr << "Text: unable to decode GIF: " << gif_file << '\n';
|
||||||
|
free(buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap_width_ = w;
|
||||||
|
bitmap_height_ = h;
|
||||||
|
bitmap_ = pixels;
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
std::cout << "Text: bitmap loaded " << w << "x" << h << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Renderitzat ---
|
||||||
|
|
||||||
|
void Text::draw(Uint32* pixel_data, int x, int y, const char* text, Uint32 color) const {
|
||||||
|
if (!bitmap_ || !pixel_data) return;
|
||||||
|
|
||||||
|
const char* ptr = text;
|
||||||
|
int cursor_x = x;
|
||||||
|
|
||||||
|
while (*ptr) {
|
||||||
|
uint32_t cp = nextCodepoint(ptr);
|
||||||
|
if (cp == 0) break;
|
||||||
|
|
||||||
|
auto it = glyphs_.find(cp);
|
||||||
|
if (it == glyphs_.end()) {
|
||||||
|
it = glyphs_.find('?');
|
||||||
|
if (it == glyphs_.end()) {
|
||||||
|
cursor_x += box_width_;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& glyph = it->second;
|
||||||
|
|
||||||
|
// Pinta glifo pixel a pixel
|
||||||
|
for (int gy = 0; gy < box_height_; gy++) {
|
||||||
|
int dst_y = y + gy;
|
||||||
|
if (dst_y < 0 || dst_y >= SCREEN_HEIGHT) continue;
|
||||||
|
|
||||||
|
for (int gx = 0; gx < glyph.w; gx++) {
|
||||||
|
int dst_x = cursor_x + gx;
|
||||||
|
if (dst_x < 0 || dst_x >= SCREEN_WIDTH) continue;
|
||||||
|
|
||||||
|
int src_x = glyph.x + gx;
|
||||||
|
int src_y = glyph.y + gy;
|
||||||
|
|
||||||
|
if (src_x >= bitmap_width_ || src_y >= bitmap_height_) continue;
|
||||||
|
|
||||||
|
Uint8 pixel = bitmap_[src_x + src_y * bitmap_width_];
|
||||||
|
// Píxel no transparent (índex 0 és fons típicament)
|
||||||
|
if (pixel != 0) {
|
||||||
|
pixel_data[dst_x + dst_y * SCREEN_WIDTH] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor_x += glyph.w + 1; // +1 kerning
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text::drawCentered(Uint32* pixel_data, int y, const char* text, Uint32 color) const {
|
||||||
|
int w = width(text);
|
||||||
|
int x = (SCREEN_WIDTH - w) / 2;
|
||||||
|
draw(pixel_data, x, y, text, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Text::width(const char* text) const -> int {
|
||||||
|
const char* ptr = text;
|
||||||
|
int w = 0;
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
while (*ptr) {
|
||||||
|
uint32_t cp = nextCodepoint(ptr);
|
||||||
|
if (cp == 0) break;
|
||||||
|
|
||||||
|
auto it = glyphs_.find(cp);
|
||||||
|
if (it == glyphs_.end()) {
|
||||||
|
it = glyphs_.find('?');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!first) w += 1; // kerning
|
||||||
|
first = false;
|
||||||
|
|
||||||
|
if (it != glyphs_.end()) {
|
||||||
|
w += it->second.w;
|
||||||
|
} else {
|
||||||
|
w += box_width_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return w;
|
||||||
|
}
|
||||||
47
source/core/rendering/text.hpp
Normal file
47
source/core/rendering/text.hpp
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
class Text {
|
||||||
|
public:
|
||||||
|
Text(const char* fnt_file, const char* gif_file);
|
||||||
|
~Text();
|
||||||
|
|
||||||
|
// Pinta texto sobre un buffer ARGB de 320x200
|
||||||
|
void draw(Uint32* pixel_data, int x, int y, const char* text, Uint32 color) const;
|
||||||
|
void drawCentered(Uint32* pixel_data, int y, const char* text, Uint32 color) const;
|
||||||
|
|
||||||
|
// Calcula ancho en píxeles d'un text
|
||||||
|
[[nodiscard]] auto width(const char* text) const -> int;
|
||||||
|
[[nodiscard]] auto charHeight() const -> int { return box_height_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct GlyphInfo {
|
||||||
|
int x, y; // posició en el bitmap
|
||||||
|
int w; // ample visual
|
||||||
|
};
|
||||||
|
|
||||||
|
int box_width_{0};
|
||||||
|
int box_height_{0};
|
||||||
|
int columns_{0};
|
||||||
|
int cell_spacing_{0};
|
||||||
|
int row_spacing_{0};
|
||||||
|
|
||||||
|
Uint8* bitmap_{nullptr}; // píxels 8-bit del GIF de la font
|
||||||
|
int bitmap_width_{0};
|
||||||
|
int bitmap_height_{0};
|
||||||
|
|
||||||
|
std::unordered_map<uint32_t, GlyphInfo> glyphs_;
|
||||||
|
|
||||||
|
static auto nextCodepoint(const char*& ptr) -> uint32_t;
|
||||||
|
|
||||||
|
void loadFont(const char* fnt_file);
|
||||||
|
void loadBitmap(const char* gif_file);
|
||||||
|
|
||||||
|
static constexpr int SCREEN_WIDTH = 320;
|
||||||
|
static constexpr int SCREEN_HEIGHT = 200;
|
||||||
|
};
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "core/jgame.hpp"
|
#include "core/jail/jgame.hpp"
|
||||||
|
|
||||||
Bola::Bola(JD8_Surface gfx, Prota* sam)
|
Bola::Bola(JD8_Surface gfx, Prota* sam)
|
||||||
: Sprite(gfx) {
|
: Sprite(gfx) {
|
||||||
|
|||||||
@@ -1,5 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
// Tecles GUI (capa de presentació — finestra, zoom, etc.)
|
||||||
|
namespace Defaults::KeysGUI {
|
||||||
|
constexpr SDL_Scancode DEC_ZOOM = SDL_SCANCODE_F1;
|
||||||
|
constexpr SDL_Scancode INC_ZOOM = SDL_SCANCODE_F2;
|
||||||
|
constexpr SDL_Scancode FULLSCREEN = SDL_SCANCODE_F3;
|
||||||
|
} // namespace Defaults::KeysGUI
|
||||||
|
|
||||||
|
// Tecles de joc (moviment del personatge, accions)
|
||||||
|
namespace Defaults::KeysGame {
|
||||||
|
constexpr SDL_Scancode UP = SDL_SCANCODE_UP;
|
||||||
|
constexpr SDL_Scancode DOWN = SDL_SCANCODE_DOWN;
|
||||||
|
constexpr SDL_Scancode LEFT = SDL_SCANCODE_LEFT;
|
||||||
|
constexpr SDL_Scancode RIGHT = SDL_SCANCODE_RIGHT;
|
||||||
|
constexpr SDL_Scancode EXIT = SDL_SCANCODE_ESCAPE;
|
||||||
|
} // namespace Defaults::KeysGame
|
||||||
|
|
||||||
namespace Defaults::Audio {
|
namespace Defaults::Audio {
|
||||||
constexpr float VOLUME = 1.0F;
|
constexpr float VOLUME = 1.0F;
|
||||||
constexpr bool MUSIC_ENABLED = true;
|
constexpr bool MUSIC_ENABLED = true;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "core/jgame.hpp"
|
#include "core/jail/jgame.hpp"
|
||||||
|
|
||||||
Engendro::Engendro(JD8_Surface gfx, Uint16 x, Uint16 y)
|
Engendro::Engendro(JD8_Surface gfx, Uint16 x, Uint16 y)
|
||||||
: Sprite(gfx) {
|
: Sprite(gfx) {
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "core/jgame.hpp"
|
#include "core/jail/jgame.hpp"
|
||||||
#include "core/jinput.hpp"
|
#include "core/jail/jinput.hpp"
|
||||||
|
|
||||||
Mapa::Mapa(JD8_Surface gfx, Prota* sam) {
|
Mapa::Mapa(JD8_Surface gfx, Prota* sam) {
|
||||||
this->gfx = gfx;
|
this->gfx = gfx;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/jdraw8.hpp"
|
#include "core/jail/jdraw8.hpp"
|
||||||
#include "game/info.hpp"
|
#include "game/info.hpp"
|
||||||
#include "game/prota.hpp"
|
#include "game/prota.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/jdraw8.hpp"
|
#include "core/jail/jdraw8.hpp"
|
||||||
#include "game/info.hpp"
|
#include "game/info.hpp"
|
||||||
#include "game/prota.hpp"
|
#include "game/prota.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
#include "game/modulegame.hpp"
|
#include "game/modulegame.hpp"
|
||||||
|
|
||||||
#include "core/jail_audio.hpp"
|
#include "core/jail/jail_audio.hpp"
|
||||||
#include "core/jdraw8.hpp"
|
#include "core/jail/jdraw8.hpp"
|
||||||
#include "core/jfile.hpp"
|
#include "core/jail/jfile.hpp"
|
||||||
#include "core/jgame.hpp"
|
#include "core/jail/jgame.hpp"
|
||||||
#include "core/jinput.hpp"
|
#include "core/jail/jinput.hpp"
|
||||||
|
|
||||||
ModuleGame::ModuleGame() {
|
ModuleGame::ModuleGame() {
|
||||||
this->gfx = JD8_LoadSurface(info::pepe_activat ? "frames2.gif" : "frames.gif");
|
this->gfx = JD8_LoadSurface(info::pepe_activat ? "frames2.gif" : "frames.gif");
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "core/jail_audio.hpp"
|
#include "core/jail/jail_audio.hpp"
|
||||||
#include "core/jdraw8.hpp"
|
#include "core/jail/jdraw8.hpp"
|
||||||
#include "core/jfile.hpp"
|
#include "core/jail/jfile.hpp"
|
||||||
#include "core/jgame.hpp"
|
#include "core/jail/jgame.hpp"
|
||||||
#include "core/jinput.hpp"
|
#include "core/jail/jinput.hpp"
|
||||||
|
|
||||||
ModuleSequence::ModuleSequence() {
|
ModuleSequence::ModuleSequence() {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "core/jgame.hpp"
|
#include "core/jail/jgame.hpp"
|
||||||
|
|
||||||
Momia::Momia(JD8_Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam)
|
Momia::Momia(JD8_Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam)
|
||||||
: Sprite(gfx) {
|
: Sprite(gfx) {
|
||||||
|
|||||||
@@ -7,6 +7,22 @@
|
|||||||
|
|
||||||
namespace Options {
|
namespace Options {
|
||||||
|
|
||||||
|
// Tecles GUI (finestra, zoom)
|
||||||
|
struct KeysGUI {
|
||||||
|
SDL_Scancode dec_zoom{Defaults::KeysGUI::DEC_ZOOM};
|
||||||
|
SDL_Scancode inc_zoom{Defaults::KeysGUI::INC_ZOOM};
|
||||||
|
SDL_Scancode fullscreen{Defaults::KeysGUI::FULLSCREEN};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Tecles de joc (moviment, accions)
|
||||||
|
struct KeysGame {
|
||||||
|
SDL_Scancode up{Defaults::KeysGame::UP};
|
||||||
|
SDL_Scancode down{Defaults::KeysGame::DOWN};
|
||||||
|
SDL_Scancode left{Defaults::KeysGame::LEFT};
|
||||||
|
SDL_Scancode right{Defaults::KeysGame::RIGHT};
|
||||||
|
SDL_Scancode exit{Defaults::KeysGame::EXIT};
|
||||||
|
};
|
||||||
|
|
||||||
// Opcions d'àudio
|
// Opcions d'àudio
|
||||||
struct Audio {
|
struct Audio {
|
||||||
bool music_enabled{Defaults::Audio::MUSIC_ENABLED};
|
bool music_enabled{Defaults::Audio::MUSIC_ENABLED};
|
||||||
@@ -31,6 +47,8 @@ namespace Options {
|
|||||||
|
|
||||||
// --- Variables globals ---
|
// --- Variables globals ---
|
||||||
inline std::string version{};
|
inline std::string version{};
|
||||||
|
inline KeysGUI keys_gui{};
|
||||||
|
inline KeysGame keys_game{};
|
||||||
inline Audio audio{};
|
inline Audio audio{};
|
||||||
inline Window window{};
|
inline Window window{};
|
||||||
inline Game game{};
|
inline Game game{};
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "core/jgame.hpp"
|
#include "core/jail/jgame.hpp"
|
||||||
#include "core/jinput.hpp"
|
#include "core/jail/jinput.hpp"
|
||||||
|
|
||||||
Prota::Prota(JD8_Surface gfx)
|
Prota::Prota(JD8_Surface gfx)
|
||||||
: Sprite(gfx) {
|
: Sprite(gfx) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/jdraw8.hpp"
|
#include "core/jail/jdraw8.hpp"
|
||||||
|
|
||||||
struct Frame {
|
struct Frame {
|
||||||
Uint16 x;
|
Uint16 x;
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "core/global_inputs.hpp"
|
#include "core/input/global_inputs.hpp"
|
||||||
#include "core/jail_audio.hpp"
|
#include "core/jail/jail_audio.hpp"
|
||||||
#include "core/jdraw8.hpp"
|
#include "core/jail/jdraw8.hpp"
|
||||||
#include "core/jfile.hpp"
|
#include "core/jail/jfile.hpp"
|
||||||
#include "core/jgame.hpp"
|
#include "core/jail/jgame.hpp"
|
||||||
#include "core/screen.hpp"
|
#include "core/rendering/overlay.hpp"
|
||||||
|
#include "core/rendering/screen.hpp"
|
||||||
#include "game/defines.hpp"
|
#include "game/defines.hpp"
|
||||||
#include "game/info.hpp"
|
#include "game/info.hpp"
|
||||||
#include "game/modulegame.hpp"
|
#include "game/modulegame.hpp"
|
||||||
@@ -25,6 +26,7 @@ int main(int argc, char* args[]) {
|
|||||||
Screen::init();
|
Screen::init();
|
||||||
JD8_Init();
|
JD8_Init();
|
||||||
JA_Init(48000, SDL_AUDIO_S16, 2);
|
JA_Init(48000, SDL_AUDIO_S16, 2);
|
||||||
|
Overlay::init();
|
||||||
|
|
||||||
info::num_habitacio = Options::game.habitacio_inicial;
|
info::num_habitacio = Options::game.habitacio_inicial;
|
||||||
info::num_piramide = Options::game.piramide_inicial;
|
info::num_piramide = Options::game.piramide_inicial;
|
||||||
@@ -62,6 +64,7 @@ int main(int argc, char* args[]) {
|
|||||||
|
|
||||||
Options::saveToFile();
|
Options::saveToFile();
|
||||||
|
|
||||||
|
Overlay::destroy();
|
||||||
JA_Quit();
|
JA_Quit();
|
||||||
JD8_Quit();
|
JD8_Quit();
|
||||||
Screen::destroy();
|
Screen::destroy();
|
||||||
|
|||||||
Reference in New Issue
Block a user