Compare commits
8 Commits
2e1a82ff40
...
b1f9e57f36
| Author | SHA1 | Date | |
|---|---|---|---|
| b1f9e57f36 | |||
| f7875baa2d | |||
| c6e37af7d1 | |||
| 5e57034a38 | |||
| 2a8fbbb095 | |||
| 53e93ef697 | |||
| e7aa2463b4 | |||
| 27f8b0ae36 |
1
.claude/scheduled_tasks.lock
Normal file
1
.claude/scheduled_tasks.lock
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"sessionId":"7b0c9c32-3dd4-48a3-ba06-c2303dc08243","pid":123890,"acquiredAt":1776510185734}
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
@@ -24,19 +24,16 @@
|
|||||||
#include "game/options.hpp" // Para Options::audio
|
#include "game/options.hpp" // Para Options::audio
|
||||||
|
|
||||||
// Singleton
|
// Singleton
|
||||||
Audio* Audio::instance = nullptr;
|
std::unique_ptr<Audio> Audio::instance;
|
||||||
|
|
||||||
// Inicializa la instancia única del singleton
|
// Inicializa la instancia única del singleton
|
||||||
void Audio::init() { Audio::instance = new Audio(); }
|
void Audio::init() { Audio::instance = std::unique_ptr<Audio>(new Audio()); }
|
||||||
|
|
||||||
// Libera la instancia
|
// Libera la instancia
|
||||||
void Audio::destroy() {
|
void Audio::destroy() { Audio::instance.reset(); }
|
||||||
delete Audio::instance;
|
|
||||||
Audio::instance = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtiene la instancia
|
// Obtiene la instancia
|
||||||
auto Audio::get() -> Audio* { return Audio::instance; }
|
auto Audio::get() -> Audio* { return Audio::instance.get(); }
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Audio::Audio() { initSDLAudio(); }
|
Audio::Audio() { initSDLAudio(); }
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint> // Para int8_t, uint8_t
|
#include <cstdint> // Para int8_t, uint8_t
|
||||||
|
#include <memory> // Para std::unique_ptr
|
||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
#include <utility> // Para move
|
#include <utility> // Para move
|
||||||
|
|
||||||
@@ -35,6 +36,7 @@ class Audio {
|
|||||||
static void init(); // Inicializa el objeto Audio
|
static void init(); // Inicializa el objeto Audio
|
||||||
static void destroy(); // Libera el objeto Audio
|
static void destroy(); // Libera el objeto Audio
|
||||||
static auto get() -> Audio*; // Obtiene el puntero al objeto Audio
|
static auto get() -> Audio*; // Obtiene el puntero al objeto Audio
|
||||||
|
~Audio(); // Destructor (públic per a std::unique_ptr)
|
||||||
Audio(const Audio&) = delete; // Evitar copia
|
Audio(const Audio&) = delete; // Evitar copia
|
||||||
auto operator=(const Audio&) -> Audio& = delete; // Evitar asignación
|
auto operator=(const Audio&) -> Audio& = delete; // Evitar asignación
|
||||||
|
|
||||||
@@ -101,11 +103,10 @@ class Audio {
|
|||||||
|
|
||||||
// --- Métodos ---
|
// --- Métodos ---
|
||||||
Audio(); // Constructor privado
|
Audio(); // Constructor privado
|
||||||
~Audio(); // Destructor privado
|
|
||||||
void initSDLAudio(); // Inicializa SDL Audio
|
void initSDLAudio(); // Inicializa SDL Audio
|
||||||
|
|
||||||
// --- Variables miembro ---
|
// --- Variables miembro ---
|
||||||
static Audio* instance; // Instancia única de Audio
|
static std::unique_ptr<Audio> instance; // Instancia única de Audio
|
||||||
|
|
||||||
Music music_; // Estado de la música
|
Music music_; // Estado de la música
|
||||||
bool enabled_{true}; // Estado general del audio
|
bool enabled_{true}; // Estado general del audio
|
||||||
|
|||||||
@@ -265,13 +265,13 @@ inline JA_Music_t* JA_LoadMusic(const Uint8* buffer, Uint32 length) {
|
|||||||
auto* music = new JA_Music_t();
|
auto* music = new JA_Music_t();
|
||||||
music->ogg_data.assign(buffer, buffer + length);
|
music->ogg_data.assign(buffer, buffer + length);
|
||||||
|
|
||||||
int error = 0;
|
int vorbis_error = 0;
|
||||||
music->vorbis = stb_vorbis_open_memory(music->ogg_data.data(),
|
music->vorbis = stb_vorbis_open_memory(music->ogg_data.data(),
|
||||||
static_cast<int>(length),
|
static_cast<int>(length),
|
||||||
&error,
|
&vorbis_error,
|
||||||
nullptr);
|
nullptr);
|
||||||
if (!music->vorbis) {
|
if (!music->vorbis) {
|
||||||
std::cout << "JA_LoadMusic: stb_vorbis_open_memory failed (error " << error << ")" << '\n';
|
std::cout << "JA_LoadMusic: stb_vorbis_open_memory failed (error " << vorbis_error << ")" << '\n';
|
||||||
delete music;
|
delete music;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,20 +19,23 @@
|
|||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JD8_Surface screen = NULL;
|
JD8_Surface screen = nullptr;
|
||||||
JD8_Palette main_palette = NULL;
|
JD8_Palette main_palette = nullptr;
|
||||||
Uint32* pixel_data = NULL;
|
Uint32* pixel_data = nullptr;
|
||||||
|
|
||||||
void JD8_Init() {
|
void JD8_Init() {
|
||||||
screen = (JD8_Surface)calloc(1, 64000);
|
screen = new Uint8[64000]{};
|
||||||
main_palette = (JD8_Palette)calloc(1, 768);
|
main_palette = new Color[256]{};
|
||||||
pixel_data = (Uint32*)calloc(1, 320 * 200 * 4);
|
pixel_data = new Uint32[320 * 200]{};
|
||||||
}
|
}
|
||||||
|
|
||||||
void JD8_Quit() {
|
void JD8_Quit() {
|
||||||
if (screen != NULL) free(screen);
|
delete[] screen;
|
||||||
if (main_palette != NULL) free(main_palette);
|
delete[] main_palette;
|
||||||
if (pixel_data != NULL) free(pixel_data);
|
delete[] pixel_data;
|
||||||
|
screen = nullptr;
|
||||||
|
main_palette = nullptr;
|
||||||
|
pixel_data = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JD8_ClearScreen(Uint8 color) {
|
void JD8_ClearScreen(Uint8 color) {
|
||||||
@@ -40,9 +43,7 @@ void JD8_ClearScreen(Uint8 color) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JD8_Surface JD8_NewSurface() {
|
JD8_Surface JD8_NewSurface() {
|
||||||
JD8_Surface surface = (JD8_Surface)malloc(64000);
|
return new Uint8[64000]{};
|
||||||
memset(surface, 0, 64000);
|
|
||||||
return surface;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper intern: deriva el basename d'una ruta per a buscar al Cache.
|
// Helper intern: deriva el basename d'una ruta per a buscar al Cache.
|
||||||
@@ -71,7 +72,7 @@ JD8_Surface JD8_LoadSurface(const char* file) {
|
|||||||
auto buffer = ResourceHelper::loadFile(file);
|
auto buffer = ResourceHelper::loadFile(file);
|
||||||
unsigned short w, h;
|
unsigned short w, h;
|
||||||
Uint8* pixels = LoadGif(buffer.data(), &w, &h);
|
Uint8* pixels = LoadGif(buffer.data(), &w, &h);
|
||||||
if (pixels == NULL) {
|
if (pixels == nullptr) {
|
||||||
printf("Unable to load bitmap: %s\n", SDL_GetError());
|
printf("Unable to load bitmap: %s\n", SDL_GetError());
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -82,27 +83,31 @@ JD8_Surface JD8_LoadSurface(const char* file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JD8_Palette JD8_LoadPalette(const char* file) {
|
JD8_Palette JD8_LoadPalette(const char* file) {
|
||||||
|
// Sempre retorna un buffer de 256 colors reservat amb `new Color[256]`
|
||||||
|
// — el caller és responsable d'alliberar-lo amb `delete[]` (o lliurar-ne
|
||||||
|
// l'ownership a `JD8_SetScreenPalette`).
|
||||||
|
JD8_Palette palette = new Color[256];
|
||||||
|
|
||||||
if (Resource::Cache::get() != nullptr) {
|
if (Resource::Cache::get() != nullptr) {
|
||||||
try {
|
try {
|
||||||
const auto& cached = Resource::Cache::get()->getPaletteBytes(jd8_basename(file));
|
const auto& cached = Resource::Cache::get()->getPaletteBytes(jd8_basename(file));
|
||||||
// Reservem un buffer 768 bytes (256 * RGB) que el caller ha
|
|
||||||
// d'alliberar amb free() — mateixa convenció que el LoadPalette
|
|
||||||
// original (retornava un malloc).
|
|
||||||
JD8_Palette palette = (JD8_Palette)malloc(768);
|
|
||||||
memcpy(palette, cached.data(), 768);
|
memcpy(palette, cached.data(), 768);
|
||||||
return palette;
|
return palette;
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
// No està al cache.
|
// No està al cache — fallback a lectura + LoadPalette.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto buffer = ResourceHelper::loadFile(file);
|
auto buffer = ResourceHelper::loadFile(file);
|
||||||
return (JD8_Palette)LoadPalette(buffer.data());
|
Uint8* raw = LoadPalette(buffer.data()); // external malloc
|
||||||
|
memcpy(palette, raw, 768);
|
||||||
|
free(raw);
|
||||||
|
return palette;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JD8_SetScreenPalette(JD8_Palette palette) {
|
void JD8_SetScreenPalette(JD8_Palette palette) {
|
||||||
if (main_palette == palette) return;
|
if (main_palette == palette) return;
|
||||||
if (main_palette != NULL) free(main_palette);
|
delete[] main_palette;
|
||||||
main_palette = palette;
|
main_palette = palette;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,7 +223,7 @@ Uint32* JD8_GetFramebuffer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void JD8_FreeSurface(JD8_Surface surface) {
|
void JD8_FreeSurface(JD8_Surface surface) {
|
||||||
free(surface);
|
delete[] surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint8 JD8_GetPixel(JD8_Surface surface, int x, int y) {
|
Uint8 JD8_GetPixel(JD8_Surface surface, int x, int y) {
|
||||||
@@ -240,26 +245,26 @@ void JD8_SetPaletteColor(Uint8 index, Uint8 r, Uint8 g, Uint8 b) {
|
|||||||
// el caller decideix quan fer Flip.
|
// el caller decideix quan fer Flip.
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
enum FadeType {
|
enum class FadeType {
|
||||||
FADE_NONE = 0,
|
None = 0,
|
||||||
FADE_OUT,
|
Out,
|
||||||
FADE_TO_PAL,
|
ToPal,
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr int FADE_STEPS = 32;
|
constexpr int FADE_STEPS = 32;
|
||||||
|
|
||||||
FadeType fade_type = FADE_NONE;
|
FadeType fade_type = FadeType::None;
|
||||||
Color fade_target[256];
|
Color fade_target[256];
|
||||||
int fade_step = 0;
|
int fade_step = 0;
|
||||||
|
|
||||||
void apply_fade_step() {
|
void apply_fade_step() {
|
||||||
if (fade_type == FADE_OUT) {
|
if (fade_type == FadeType::Out) {
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
main_palette[i].r = main_palette[i].r >= 8 ? main_palette[i].r - 8 : 0;
|
main_palette[i].r = main_palette[i].r >= 8 ? main_palette[i].r - 8 : 0;
|
||||||
main_palette[i].g = main_palette[i].g >= 8 ? main_palette[i].g - 8 : 0;
|
main_palette[i].g = main_palette[i].g >= 8 ? main_palette[i].g - 8 : 0;
|
||||||
main_palette[i].b = main_palette[i].b >= 8 ? main_palette[i].b - 8 : 0;
|
main_palette[i].b = main_palette[i].b >= 8 ? main_palette[i].b - 8 : 0;
|
||||||
}
|
}
|
||||||
} else if (fade_type == FADE_TO_PAL) {
|
} else if (fade_type == FadeType::ToPal) {
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
main_palette[i].r = main_palette[i].r <= int(fade_target[i].r) - 8
|
main_palette[i].r = main_palette[i].r <= int(fade_target[i].r) - 8
|
||||||
? main_palette[i].r + 8
|
? main_palette[i].r + 8
|
||||||
@@ -277,28 +282,28 @@ namespace {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void JD8_FadeStartOut() {
|
void JD8_FadeStartOut() {
|
||||||
fade_type = FADE_OUT;
|
fade_type = FadeType::Out;
|
||||||
fade_step = 0;
|
fade_step = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JD8_FadeStartToPal(JD8_Palette pal) {
|
void JD8_FadeStartToPal(JD8_Palette pal) {
|
||||||
fade_type = FADE_TO_PAL;
|
fade_type = FadeType::ToPal;
|
||||||
memcpy(fade_target, pal, sizeof(Color) * 256);
|
memcpy(fade_target, pal, sizeof(Color) * 256);
|
||||||
fade_step = 0;
|
fade_step = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JD8_FadeIsActive() {
|
bool JD8_FadeIsActive() {
|
||||||
return fade_type != FADE_NONE;
|
return fade_type != FadeType::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JD8_FadeTickStep() {
|
bool JD8_FadeTickStep() {
|
||||||
if (fade_type == FADE_NONE) return true;
|
if (fade_type == FadeType::None) return true;
|
||||||
|
|
||||||
apply_fade_step();
|
apply_fade_step();
|
||||||
fade_step++;
|
fade_step++;
|
||||||
|
|
||||||
if (fade_step >= FADE_STEPS) {
|
if (fade_step >= FADE_STEPS) {
|
||||||
fade_type = FADE_NONE;
|
fade_type = FadeType::None;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ struct Color {
|
|||||||
Uint8 b;
|
Uint8 b;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Uint8* JD8_Surface;
|
using JD8_Surface = Uint8*;
|
||||||
typedef Color* JD8_Palette;
|
using JD8_Palette = Color*;
|
||||||
|
|
||||||
void JD8_Init();
|
void JD8_Init();
|
||||||
|
|
||||||
|
|||||||
@@ -82,9 +82,7 @@ void file_setconfigfolder(const char* foldername) {
|
|||||||
config_folder = std::string(homedir) + "/.config/" + foldername;
|
config_folder = std::string(homedir) + "/.config/" + foldername;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!config_folder.empty()) {
|
std::filesystem::create_directories(config_folder);
|
||||||
std::filesystem::create_directories(config_folder);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* file_getconfigfolder() {
|
const char* file_getconfigfolder() {
|
||||||
|
|||||||
@@ -55,19 +55,18 @@ namespace {
|
|||||||
} // namespace
|
} // namespace
|
||||||
#endif // __EMSCRIPTEN__
|
#endif // __EMSCRIPTEN__
|
||||||
|
|
||||||
Screen* Screen::instance_ = nullptr;
|
std::unique_ptr<Screen> Screen::instance_;
|
||||||
|
|
||||||
void Screen::init() {
|
void Screen::init() {
|
||||||
instance_ = new Screen();
|
instance_ = std::unique_ptr<Screen>(new Screen());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::destroy() {
|
void Screen::destroy() {
|
||||||
delete instance_;
|
instance_.reset();
|
||||||
instance_ = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Screen::get() -> Screen* {
|
auto Screen::get() -> Screen* {
|
||||||
return instance_;
|
return instance_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Screen::Screen() {
|
Screen::Screen() {
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ class Screen {
|
|||||||
static void destroy();
|
static void destroy();
|
||||||
static auto get() -> Screen*;
|
static auto get() -> Screen*;
|
||||||
|
|
||||||
|
~Screen(); // públic per a std::unique_ptr
|
||||||
|
|
||||||
// Presentació — rep el buffer ARGB de 320x200 de JD8
|
// Presentació — rep el buffer ARGB de 320x200 de JD8
|
||||||
void present(Uint32* pixel_data);
|
void present(Uint32* pixel_data);
|
||||||
|
|
||||||
@@ -62,7 +64,6 @@ class Screen {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Screen();
|
Screen();
|
||||||
~Screen();
|
|
||||||
|
|
||||||
void adjustWindowSize();
|
void adjustWindowSize();
|
||||||
void calculateMaxZoom();
|
void calculateMaxZoom();
|
||||||
@@ -70,7 +71,7 @@ class Screen {
|
|||||||
void applyFallbackPresentation(); // Logical presentation + scale mode per al path SDL_Renderer
|
void applyFallbackPresentation(); // Logical presentation + scale mode per al path SDL_Renderer
|
||||||
void ensureFallbackInternalTexture(); // Recrea internal_texture_sdl_ si cal (fallback path)
|
void ensureFallbackInternalTexture(); // Recrea internal_texture_sdl_ si cal (fallback path)
|
||||||
|
|
||||||
static Screen* instance_;
|
static std::unique_ptr<Screen> instance_;
|
||||||
|
|
||||||
SDL_Window* window_{nullptr};
|
SDL_Window* window_{nullptr};
|
||||||
SDL_Renderer* renderer_{nullptr};
|
SDL_Renderer* renderer_{nullptr};
|
||||||
|
|||||||
@@ -19,10 +19,6 @@ Text::Text(const char* fnt_file, const char* gif_file) {
|
|||||||
loadFont(fnt_file);
|
loadFont(fnt_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
Text::~Text() {
|
|
||||||
if (bitmap_) free(bitmap_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- UTF-8 ---
|
// --- UTF-8 ---
|
||||||
|
|
||||||
auto Text::nextCodepoint(const char*& ptr) -> uint32_t {
|
auto Text::nextCodepoint(const char*& ptr) -> uint32_t {
|
||||||
@@ -80,27 +76,27 @@ void Text::loadFont(const char* fnt_file) {
|
|||||||
// Elimina comentaris inline
|
// Elimina comentaris inline
|
||||||
auto comment_pos = line.find('#');
|
auto comment_pos = line.find('#');
|
||||||
if (comment_pos != std::string::npos) {
|
if (comment_pos != std::string::npos) {
|
||||||
line = line.substr(0, comment_pos);
|
line.resize(comment_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parseja directives
|
// Parseja directives
|
||||||
if (line.find("box_width") == 0) {
|
if (line.starts_with("box_width")) {
|
||||||
sscanf(line.c_str(), "box_width %d", &box_width_);
|
sscanf(line.c_str(), "box_width %d", &box_width_);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (line.find("box_height") == 0) {
|
if (line.starts_with("box_height")) {
|
||||||
sscanf(line.c_str(), "box_height %d", &box_height_);
|
sscanf(line.c_str(), "box_height %d", &box_height_);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (line.find("columns") == 0) {
|
if (line.starts_with("columns")) {
|
||||||
sscanf(line.c_str(), "columns %d", &columns_);
|
sscanf(line.c_str(), "columns %d", &columns_);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (line.find("cell_spacing") == 0) {
|
if (line.starts_with("cell_spacing")) {
|
||||||
sscanf(line.c_str(), "cell_spacing %d", &cell_spacing_);
|
sscanf(line.c_str(), "cell_spacing %d", &cell_spacing_);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (line.find("row_spacing") == 0) {
|
if (line.starts_with("row_spacing")) {
|
||||||
sscanf(line.c_str(), "row_spacing %d", &row_spacing_);
|
sscanf(line.c_str(), "row_spacing %d", &row_spacing_);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -146,7 +142,8 @@ void Text::loadBitmap(const char* gif_file) {
|
|||||||
|
|
||||||
bitmap_width_ = w;
|
bitmap_width_ = w;
|
||||||
bitmap_height_ = h;
|
bitmap_height_ = h;
|
||||||
bitmap_ = pixels;
|
bitmap_.assign(pixels, pixels + (static_cast<size_t>(w) * h));
|
||||||
|
free(pixels); // LoadGif usa malloc internament
|
||||||
|
|
||||||
std::cout << "Text: bitmap loaded " << w << "x" << h << '\n';
|
std::cout << "Text: bitmap loaded " << w << "x" << h << '\n';
|
||||||
}
|
}
|
||||||
@@ -154,7 +151,7 @@ void Text::loadBitmap(const char* gif_file) {
|
|||||||
// --- Renderitzat ---
|
// --- Renderitzat ---
|
||||||
|
|
||||||
void Text::draw(Uint32* pixel_data, int x, int y, const char* text, Uint32 color) const {
|
void Text::draw(Uint32* pixel_data, int x, int y, const char* text, Uint32 color) const {
|
||||||
if (!bitmap_ || !pixel_data) return;
|
if (bitmap_.empty() || !pixel_data) return;
|
||||||
|
|
||||||
const char* ptr = text;
|
const char* ptr = text;
|
||||||
int cursor_x = x;
|
int cursor_x = x;
|
||||||
@@ -207,7 +204,7 @@ void Text::drawCentered(Uint32* pixel_data, int y, const char* text, Uint32 colo
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Text::drawClipped(Uint32* pixel_data, int x, int y, const char* text, Uint32 color, int clip_x_min, int clip_x_max, int clip_y_min, int clip_y_max) const {
|
void Text::drawClipped(Uint32* pixel_data, int x, int y, const char* text, Uint32 color, int clip_x_min, int clip_x_max, int clip_y_min, int clip_y_max) const {
|
||||||
if (!bitmap_ || !pixel_data) return;
|
if (bitmap_.empty() || !pixel_data) return;
|
||||||
|
|
||||||
// Descart ràpid si el glifo sencer cau fora verticalment
|
// Descart ràpid si el glifo sencer cau fora verticalment
|
||||||
if (y + box_height_ <= clip_y_min || y >= clip_y_max) return;
|
if (y + box_height_ <= clip_y_min || y >= clip_y_max) return;
|
||||||
@@ -262,7 +259,7 @@ void Text::drawClipped(Uint32* pixel_data, int x, int y, const char* text, Uint3
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Text::drawMono(Uint32* pixel_data, int x, int y, const char* text, Uint32 color, int cell_w) const {
|
void Text::drawMono(Uint32* pixel_data, int x, int y, const char* text, Uint32 color, int cell_w) const {
|
||||||
if (!bitmap_ || !pixel_data) return;
|
if (bitmap_.empty() || !pixel_data) return;
|
||||||
|
|
||||||
const char* ptr = text;
|
const char* ptr = text;
|
||||||
int cursor_x = x;
|
int cursor_x = x;
|
||||||
@@ -308,7 +305,7 @@ void Text::drawMono(Uint32* pixel_data, int x, int y, const char* text, Uint32 c
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Text::drawMonoDigits(Uint32* pixel_data, int x, int y, const char* text, Uint32 color, int digit_cell_w) const {
|
void Text::drawMonoDigits(Uint32* pixel_data, int x, int y, const char* text, Uint32 color, int digit_cell_w) const {
|
||||||
if (!bitmap_ || !pixel_data) return;
|
if (bitmap_.empty() || !pixel_data) return;
|
||||||
|
|
||||||
const char* ptr = text;
|
const char* ptr = text;
|
||||||
int cursor_x = x;
|
int cursor_x = x;
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class Text {
|
class Text {
|
||||||
public:
|
public:
|
||||||
Text(const char* fnt_file, const char* gif_file);
|
Text(const char* fnt_file, const char* gif_file);
|
||||||
~Text();
|
|
||||||
|
|
||||||
// Pinta texto sobre un buffer ARGB de 320x200
|
// Pinta texto sobre un buffer ARGB de 320x200
|
||||||
void draw(Uint32* pixel_data, int x, int y, const char* text, Uint32 color) const;
|
void draw(Uint32* pixel_data, int x, int y, const char* text, Uint32 color) const;
|
||||||
@@ -46,7 +46,7 @@ class Text {
|
|||||||
int cell_spacing_{0};
|
int cell_spacing_{0};
|
||||||
int row_spacing_{0};
|
int row_spacing_{0};
|
||||||
|
|
||||||
Uint8* bitmap_{nullptr}; // píxels 8-bit del GIF de la font
|
std::vector<Uint8> bitmap_; // píxels 8-bit del GIF de la font
|
||||||
int bitmap_width_{0};
|
int bitmap_width_{0};
|
||||||
int bitmap_height_{0};
|
int bitmap_height_{0};
|
||||||
|
|
||||||
|
|||||||
@@ -20,14 +20,11 @@ extern unsigned char* LoadPalette(unsigned char* data);
|
|||||||
|
|
||||||
namespace Resource {
|
namespace Resource {
|
||||||
|
|
||||||
Cache* Cache::instance = nullptr;
|
std::unique_ptr<Cache> Cache::instance;
|
||||||
|
|
||||||
void Cache::init() { instance = new Cache(); }
|
void Cache::init() { instance = std::unique_ptr<Cache>(new Cache()); }
|
||||||
void Cache::destroy() {
|
void Cache::destroy() { instance.reset(); }
|
||||||
delete instance;
|
auto Cache::get() -> Cache* { return instance.get(); }
|
||||||
instance = nullptr;
|
|
||||||
}
|
|
||||||
auto Cache::get() -> Cache* { return instance; }
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
auto basename(const std::string& path) -> std::string {
|
auto basename(const std::string& path) -> std::string {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -20,6 +21,7 @@ namespace Resource {
|
|||||||
static void destroy();
|
static void destroy();
|
||||||
static auto get() -> Cache*;
|
static auto get() -> Cache*;
|
||||||
|
|
||||||
|
~Cache() = default;
|
||||||
Cache(const Cache&) = delete;
|
Cache(const Cache&) = delete;
|
||||||
auto operator=(const Cache&) -> Cache& = delete;
|
auto operator=(const Cache&) -> Cache& = delete;
|
||||||
|
|
||||||
@@ -39,7 +41,6 @@ namespace Resource {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Cache() = default;
|
Cache() = default;
|
||||||
~Cache() = default;
|
|
||||||
|
|
||||||
enum class LoadStage {
|
enum class LoadStage {
|
||||||
MUSICS,
|
MUSICS,
|
||||||
@@ -66,7 +67,7 @@ namespace Resource {
|
|||||||
int loaded_count_{0};
|
int loaded_count_{0};
|
||||||
std::string current_loading_name_;
|
std::string current_loading_name_;
|
||||||
|
|
||||||
static Cache* instance;
|
static std::unique_ptr<Cache> instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Resource
|
} // namespace Resource
|
||||||
|
|||||||
@@ -9,19 +9,16 @@
|
|||||||
|
|
||||||
namespace Resource {
|
namespace Resource {
|
||||||
|
|
||||||
List* List::instance = nullptr;
|
std::unique_ptr<List> List::instance;
|
||||||
|
|
||||||
void List::init(const std::string& yaml_path) {
|
void List::init(const std::string& yaml_path) {
|
||||||
instance = new List();
|
instance = std::unique_ptr<List>(new List());
|
||||||
instance->loadFromYaml(yaml_path);
|
instance->loadFromYaml(yaml_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void List::destroy() {
|
void List::destroy() { instance.reset(); }
|
||||||
delete instance;
|
|
||||||
instance = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto List::get() -> List* { return instance; }
|
auto List::get() -> List* { return instance.get(); }
|
||||||
|
|
||||||
void List::loadFromYaml(const std::string& yaml_path) {
|
void List::loadFromYaml(const std::string& yaml_path) {
|
||||||
auto bytes = ResourceHelper::loadFile(yaml_path);
|
auto bytes = ResourceHelper::loadFile(yaml_path);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -25,6 +26,7 @@ namespace Resource {
|
|||||||
static void destroy();
|
static void destroy();
|
||||||
static auto get() -> List*;
|
static auto get() -> List*;
|
||||||
|
|
||||||
|
~List() = default;
|
||||||
List(const List&) = delete;
|
List(const List&) = delete;
|
||||||
auto operator=(const List&) -> List& = delete;
|
auto operator=(const List&) -> List& = delete;
|
||||||
|
|
||||||
@@ -44,7 +46,6 @@ namespace Resource {
|
|||||||
};
|
};
|
||||||
|
|
||||||
List() = default;
|
List() = default;
|
||||||
~List() = default;
|
|
||||||
|
|
||||||
void loadFromYaml(const std::string& yaml_path);
|
void loadFromYaml(const std::string& yaml_path);
|
||||||
void loadFromString(const std::string& yaml_content);
|
void loadFromString(const std::string& yaml_content);
|
||||||
@@ -55,7 +56,7 @@ namespace Resource {
|
|||||||
|
|
||||||
std::unordered_map<std::string, Item> file_list_;
|
std::unordered_map<std::string, Item> file_list_;
|
||||||
|
|
||||||
static List* instance;
|
static std::unique_ptr<List> instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Resource
|
} // namespace Resource
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
// Cheats del joc original — declarats a jinput.cpp
|
// Cheats del joc original — declarats a jinput.cpp
|
||||||
extern void JI_moveCheats(Uint8 new_key);
|
extern void JI_moveCheats(Uint8 new_key);
|
||||||
|
|
||||||
Director* Director::instance_ = nullptr;
|
std::unique_ptr<Director> Director::instance_;
|
||||||
|
|
||||||
Director::~Director() = default;
|
Director::~Director() = default;
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ std::unique_ptr<scenes::Scene> Director::createNextScene() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Director::init() {
|
void Director::init() {
|
||||||
instance_ = new Director();
|
instance_ = std::unique_ptr<Director>(new Director());
|
||||||
Gamepad::init();
|
Gamepad::init();
|
||||||
|
|
||||||
// Registre d'escenes. Cada entrada = un state_key (`num_piramide`)
|
// Registre d'escenes. Cada entrada = un state_key (`num_piramide`)
|
||||||
@@ -116,12 +116,11 @@ void Director::init() {
|
|||||||
|
|
||||||
void Director::destroy() {
|
void Director::destroy() {
|
||||||
Gamepad::destroy();
|
Gamepad::destroy();
|
||||||
delete instance_;
|
instance_.reset();
|
||||||
instance_ = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Director::get() -> Director* {
|
auto Director::get() -> Director* {
|
||||||
return instance_;
|
return instance_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Director::togglePause() {
|
void Director::togglePause() {
|
||||||
|
|||||||
@@ -52,11 +52,13 @@ class Director {
|
|||||||
void togglePause();
|
void togglePause();
|
||||||
auto isPaused() const -> bool { return paused_; }
|
auto isPaused() const -> bool { return paused_; }
|
||||||
|
|
||||||
private:
|
public:
|
||||||
Director() = default;
|
|
||||||
~Director();
|
~Director();
|
||||||
|
|
||||||
static Director* instance_;
|
private:
|
||||||
|
Director() = default;
|
||||||
|
|
||||||
|
static std::unique_ptr<Director> instance_;
|
||||||
|
|
||||||
void pollAllEvents(); // drenatge amb SDL_PollEvent, només per al bucle natiu
|
void pollAllEvents(); // drenatge amb SDL_PollEvent, només per al bucle natiu
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
class Bola : public Sprite {
|
class Bola : public Sprite {
|
||||||
public:
|
public:
|
||||||
Bola(JD8_Surface gfx, Prota* sam);
|
explicit Bola(JD8_Surface gfx, Prota* sam);
|
||||||
|
|
||||||
void draw();
|
void draw() override;
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -29,10 +29,6 @@ Engendro::Engendro(JD8_Surface gfx, Uint16 x, Uint16 y)
|
|||||||
this->cycles_per_frame = 30;
|
this->cycles_per_frame = 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engendro::draw() {
|
|
||||||
Sprite::draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Engendro::update() {
|
bool Engendro::update() {
|
||||||
bool mort = false;
|
bool mort = false;
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,8 @@
|
|||||||
|
|
||||||
class Engendro : public Sprite {
|
class Engendro : public Sprite {
|
||||||
public:
|
public:
|
||||||
Engendro(JD8_Surface gfx, Uint16 x, Uint16 y);
|
explicit Engendro(JD8_Surface gfx, Uint16 x, Uint16 y);
|
||||||
|
|
||||||
void draw();
|
|
||||||
bool update();
|
bool update();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -27,9 +27,14 @@ struct Vertex {
|
|||||||
|
|
||||||
class Mapa {
|
class Mapa {
|
||||||
public:
|
public:
|
||||||
Mapa(JD8_Surface gfx, Prota* sam);
|
explicit Mapa(JD8_Surface gfx, Prota* sam);
|
||||||
~Mapa(void);
|
~Mapa(void);
|
||||||
|
|
||||||
|
Mapa(const Mapa&) = delete;
|
||||||
|
Mapa& operator=(const Mapa&) = delete;
|
||||||
|
Mapa(Mapa&&) = delete;
|
||||||
|
Mapa& operator=(Mapa&&) = delete;
|
||||||
|
|
||||||
void draw();
|
void draw();
|
||||||
void update();
|
void update();
|
||||||
bool novaMomia();
|
bool novaMomia();
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
class Marcador {
|
class Marcador {
|
||||||
public:
|
public:
|
||||||
Marcador(JD8_Surface gfx, Prota* sam);
|
explicit Marcador(JD8_Surface gfx, Prota* sam);
|
||||||
~Marcador(void);
|
~Marcador(void);
|
||||||
|
|
||||||
void draw();
|
void draw();
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "game/modulegame.hpp"
|
#include "game/modulegame.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "core/audio/audio.hpp"
|
#include "core/audio/audio.hpp"
|
||||||
#include "core/jail/jdraw8.hpp"
|
#include "core/jail/jdraw8.hpp"
|
||||||
#include "core/jail/jgame.hpp"
|
#include "core/jail/jgame.hpp"
|
||||||
@@ -9,29 +11,17 @@ ModuleGame::ModuleGame() {
|
|||||||
this->gfx = JD8_LoadSurface(info::ctx.pepe_activat ? "gfx/frames2.gif" : "gfx/frames.gif");
|
this->gfx = JD8_LoadSurface(info::ctx.pepe_activat ? "gfx/frames2.gif" : "gfx/frames.gif");
|
||||||
JG_SetUpdateTicks(10);
|
JG_SetUpdateTicks(10);
|
||||||
|
|
||||||
this->sam = new Prota(this->gfx);
|
this->sam = std::make_unique<Prota>(this->gfx);
|
||||||
this->mapa = new Mapa(this->gfx, this->sam);
|
this->mapa = std::make_unique<Mapa>(this->gfx, this->sam.get());
|
||||||
this->marcador = new Marcador(this->gfx, this->sam);
|
this->marcador = std::make_unique<Marcador>(this->gfx, this->sam.get());
|
||||||
if (info::ctx.num_piramide == 2) {
|
if (info::ctx.num_piramide == 2) {
|
||||||
this->bola = new Bola(this->gfx, this->sam);
|
this->bola = std::make_unique<Bola>(this->gfx, this->sam.get());
|
||||||
} else {
|
|
||||||
this->bola = nullptr;
|
|
||||||
}
|
}
|
||||||
this->momies = nullptr;
|
|
||||||
|
|
||||||
this->iniciarMomies();
|
this->iniciarMomies();
|
||||||
}
|
}
|
||||||
|
|
||||||
ModuleGame::~ModuleGame() {
|
ModuleGame::~ModuleGame() {
|
||||||
if (this->bola != nullptr) delete this->bola;
|
|
||||||
if (this->momies != nullptr) {
|
|
||||||
this->momies->clear();
|
|
||||||
delete this->momies;
|
|
||||||
}
|
|
||||||
delete this->marcador;
|
|
||||||
delete this->mapa;
|
|
||||||
delete this->sam;
|
|
||||||
|
|
||||||
JD8_FreeSurface(this->gfx);
|
JD8_FreeSurface(this->gfx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,8 +112,8 @@ void ModuleGame::Draw() {
|
|||||||
this->mapa->draw();
|
this->mapa->draw();
|
||||||
this->marcador->draw();
|
this->marcador->draw();
|
||||||
this->sam->draw();
|
this->sam->draw();
|
||||||
if (this->momies != nullptr) this->momies->draw();
|
for (auto& m : this->momies) m->draw();
|
||||||
if (this->bola != nullptr) this->bola->draw();
|
if (this->bola) this->bola->draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModuleGame::Update() {
|
void ModuleGame::Update() {
|
||||||
@@ -131,32 +121,19 @@ void ModuleGame::Update() {
|
|||||||
JI_Update();
|
JI_Update();
|
||||||
|
|
||||||
this->final_ = this->sam->update();
|
this->final_ = this->sam->update();
|
||||||
if (this->momies != nullptr && this->momies->update()) {
|
const auto erased = std::erase_if(this->momies, [](auto& m) { return m->update(); });
|
||||||
Momia* seguent = this->momies->next;
|
info::ctx.momies -= static_cast<int>(erased);
|
||||||
delete this->momies;
|
if (this->bola) this->bola->update();
|
||||||
this->momies = seguent;
|
|
||||||
info::ctx.momies--;
|
|
||||||
}
|
|
||||||
if (this->bola != nullptr) this->bola->update();
|
|
||||||
this->mapa->update();
|
this->mapa->update();
|
||||||
if (this->mapa->novaMomia()) {
|
if (this->mapa->novaMomia()) {
|
||||||
if (this->momies != nullptr) {
|
this->momies.emplace_back(std::make_unique<Momia>(this->gfx, true, 0, 0, this->sam.get()));
|
||||||
this->momies->insertar(new Momia(this->gfx, true, 0, 0, this->sam));
|
info::ctx.momies++;
|
||||||
info::ctx.momies++;
|
|
||||||
} else {
|
|
||||||
this->momies = new Momia(this->gfx, true, 0, 0, this->sam);
|
|
||||||
info::ctx.momies++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JI_CheatActivated("reviu")) info::ctx.vida = 5;
|
if (JI_CheatActivated("reviu")) info::ctx.vida = 5;
|
||||||
if (JI_CheatActivated("alone")) {
|
if (JI_CheatActivated("alone")) {
|
||||||
if (this->momies != nullptr) {
|
this->momies.clear();
|
||||||
this->momies->clear();
|
info::ctx.momies = 0;
|
||||||
delete this->momies;
|
|
||||||
this->momies = nullptr;
|
|
||||||
info::ctx.momies = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (JI_CheatActivated("obert")) {
|
if (JI_CheatActivated("obert")) {
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
@@ -186,11 +163,7 @@ void ModuleGame::iniciarMomies() {
|
|||||||
int y = 170;
|
int y = 170;
|
||||||
bool dimonis = info::ctx.num_piramide == 6;
|
bool dimonis = info::ctx.num_piramide == 6;
|
||||||
for (int i = 0; i < info::ctx.momies; i++) {
|
for (int i = 0; i < info::ctx.momies; i++) {
|
||||||
if (this->momies == nullptr) {
|
this->momies.emplace_back(std::make_unique<Momia>(this->gfx, dimonis, x, y, this->sam.get()));
|
||||||
this->momies = new Momia(this->gfx, dimonis, x, y, this->sam);
|
|
||||||
} else {
|
|
||||||
this->momies->insertar(new Momia(this->gfx, dimonis, x, y, this->sam));
|
|
||||||
}
|
|
||||||
x += 65;
|
x += 65;
|
||||||
if (x == 345) {
|
if (x == 345) {
|
||||||
x = 20;
|
x = 20;
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "game/bola.hpp"
|
#include "game/bola.hpp"
|
||||||
#include "game/info.hpp"
|
#include "game/info.hpp"
|
||||||
#include "game/mapa.hpp"
|
#include "game/mapa.hpp"
|
||||||
@@ -28,6 +31,11 @@ class ModuleGame : public scenes::Scene {
|
|||||||
ModuleGame();
|
ModuleGame();
|
||||||
~ModuleGame() override;
|
~ModuleGame() override;
|
||||||
|
|
||||||
|
ModuleGame(const ModuleGame&) = delete;
|
||||||
|
ModuleGame& operator=(const ModuleGame&) = delete;
|
||||||
|
ModuleGame(ModuleGame&&) = delete;
|
||||||
|
ModuleGame& operator=(ModuleGame&&) = delete;
|
||||||
|
|
||||||
void onEnter() override;
|
void onEnter() override;
|
||||||
void tick(int delta_ms) override;
|
void tick(int delta_ms) override;
|
||||||
bool done() const override { return phase_ == Phase::Done; }
|
bool done() const override { return phase_ == Phase::Done; }
|
||||||
@@ -52,9 +60,9 @@ class ModuleGame : public scenes::Scene {
|
|||||||
Uint8 final_{0};
|
Uint8 final_{0};
|
||||||
JD8_Surface gfx{nullptr};
|
JD8_Surface gfx{nullptr};
|
||||||
|
|
||||||
Mapa* mapa{nullptr};
|
std::unique_ptr<Mapa> mapa;
|
||||||
Prota* sam{nullptr};
|
std::unique_ptr<Prota> sam;
|
||||||
Marcador* marcador{nullptr};
|
std::unique_ptr<Marcador> marcador;
|
||||||
Momia* momies{nullptr};
|
std::vector<std::unique_ptr<Momia>> momies;
|
||||||
Bola* bola{nullptr};
|
std::unique_ptr<Bola> bola;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,15 +10,15 @@ Momia::Momia(JD8_Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam)
|
|||||||
this->sam = sam;
|
this->sam = sam;
|
||||||
|
|
||||||
entitat.frames.reserve(20);
|
entitat.frames.reserve(20);
|
||||||
for (int y = 0; y < 4; y++) {
|
for (int row = 0; row < 4; row++) {
|
||||||
for (int x = 0; x < 5; x++) {
|
for (int col = 0; col < 5; col++) {
|
||||||
Frame f;
|
Frame f;
|
||||||
f.w = 15;
|
f.w = 15;
|
||||||
f.h = 15;
|
f.h = 15;
|
||||||
if (info::ctx.num_piramide == 4) f.h -= 5;
|
if (info::ctx.num_piramide == 4) f.h -= 5;
|
||||||
f.x = (x * 15) + 75;
|
f.x = (col * 15) + 75;
|
||||||
if (this->dimoni) f.x += 75;
|
if (this->dimoni) f.x += 75;
|
||||||
f.y = 20 + (y * 15);
|
f.y = 20 + (row * 15);
|
||||||
entitat.frames.push_back(f);
|
entitat.frames.push_back(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,7 +40,6 @@ Momia::Momia(JD8_Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam)
|
|||||||
this->cur_frame = 0;
|
this->cur_frame = 0;
|
||||||
this->o = rand() % 4;
|
this->o = rand() % 4;
|
||||||
this->cycles_per_frame = 4;
|
this->cycles_per_frame = 4;
|
||||||
this->next = NULL;
|
|
||||||
|
|
||||||
if (this->dimoni) {
|
if (this->dimoni) {
|
||||||
if (x == 0) {
|
if (x == 0) {
|
||||||
@@ -57,22 +56,15 @@ Momia::Momia(JD8_Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam)
|
|||||||
} else {
|
} else {
|
||||||
this->y = y;
|
this->y = y;
|
||||||
}
|
}
|
||||||
this->engendro = new Engendro(gfx, this->x, this->y);
|
this->engendro = std::make_unique<Engendro>(gfx, this->x, this->y);
|
||||||
} else {
|
} else {
|
||||||
this->engendro = NULL;
|
|
||||||
this->x = x;
|
this->x = x;
|
||||||
this->y = y;
|
this->y = y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Momia::clear() {
|
|
||||||
if (this->next != NULL) this->next->clear();
|
|
||||||
if (this->engendro != NULL) delete this->engendro;
|
|
||||||
delete this->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Momia::draw() {
|
void Momia::draw() {
|
||||||
if (this->engendro != NULL) {
|
if (this->engendro) {
|
||||||
this->engendro->draw();
|
this->engendro->draw();
|
||||||
} else {
|
} else {
|
||||||
Sprite::draw();
|
Sprite::draw();
|
||||||
@@ -85,95 +77,77 @@ void Momia::draw() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this->next != NULL) this->next->draw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Momia::update() {
|
bool Momia::update() {
|
||||||
bool morta = false;
|
bool morta = false;
|
||||||
|
|
||||||
if (this->engendro != NULL) {
|
if (this->engendro) {
|
||||||
if (this->engendro->update()) {
|
if (this->engendro->update()) {
|
||||||
delete this->engendro;
|
this->engendro.reset();
|
||||||
this->engendro = NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this->sam->o < 4 && (this->dimoni || info::ctx.num_piramide == 5 || JG_GetCycleCounter() % 2 == 0)) {
|
|
||||||
if ((this->x - 20) % 65 == 0 && (this->y - 30) % 35 == 0) {
|
|
||||||
if (this->dimoni) {
|
|
||||||
if (rand() % 2 == 0) {
|
|
||||||
if (this->x > this->sam->x) {
|
|
||||||
this->o = 3;
|
|
||||||
} else if (this->x < this->sam->x) {
|
|
||||||
this->o = 2;
|
|
||||||
} else if (this->y < this->sam->y) {
|
|
||||||
this->o = 0;
|
|
||||||
} else if (this->y > this->sam->y) {
|
|
||||||
this->o = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this->y < this->sam->y) {
|
|
||||||
this->o = 0;
|
|
||||||
} else if (this->y > this->sam->y) {
|
|
||||||
this->o = 1;
|
|
||||||
} else if (this->x > this->sam->x) {
|
|
||||||
this->o = 3;
|
|
||||||
} else if (this->x < this->sam->x) {
|
|
||||||
this->o = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this->o = rand() % 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (this->o) {
|
|
||||||
case 0:
|
|
||||||
if (y < 170) this->y++;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (y > 30) this->y--;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (x < 280) this->x++;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
if (x > 20) this->x--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JG_GetCycleCounter() % this->cycles_per_frame == 0) {
|
|
||||||
this->cur_frame++;
|
|
||||||
if (this->cur_frame == entitat.animacions[this->o].frames.size()) this->cur_frame = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->x > (this->sam->x - 7) && this->x < (this->sam->x + 7) && this->y > (this->sam->y - 7) && this->y < (this->sam->y + 7)) {
|
|
||||||
morta = true;
|
|
||||||
if (this->sam->pergami) {
|
|
||||||
this->sam->pergami = false;
|
|
||||||
} else {
|
|
||||||
info::ctx.vida--;
|
|
||||||
if (info::ctx.vida == 0) this->sam->o = 5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return morta;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->next != NULL) {
|
if (this->sam->o < 4 && (this->dimoni || info::ctx.num_piramide == 5 || JG_GetCycleCounter() % 2 == 0)) {
|
||||||
if (this->next->update()) {
|
if ((this->x - 20) % 65 == 0 && (this->y - 30) % 35 == 0) {
|
||||||
Momia* seguent = this->next->next;
|
if (this->dimoni) {
|
||||||
delete this->next;
|
if (rand() % 2 == 0) {
|
||||||
this->next = seguent;
|
if (this->x > this->sam->x) {
|
||||||
info::ctx.momies--;
|
this->o = 3;
|
||||||
|
} else if (this->x < this->sam->x) {
|
||||||
|
this->o = 2;
|
||||||
|
} else if (this->y < this->sam->y) {
|
||||||
|
this->o = 0;
|
||||||
|
} else if (this->y > this->sam->y) {
|
||||||
|
this->o = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this->y < this->sam->y) {
|
||||||
|
this->o = 0;
|
||||||
|
} else if (this->y > this->sam->y) {
|
||||||
|
this->o = 1;
|
||||||
|
} else if (this->x > this->sam->x) {
|
||||||
|
this->o = 3;
|
||||||
|
} else if (this->x < this->sam->x) {
|
||||||
|
this->o = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this->o = rand() % 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (this->o) {
|
||||||
|
case 0:
|
||||||
|
if (y < 170) this->y++;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (y > 30) this->y--;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (x < 280) this->x++;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (x > 20) this->x--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (JG_GetCycleCounter() % this->cycles_per_frame == 0) {
|
||||||
|
this->cur_frame++;
|
||||||
|
if (this->cur_frame == entitat.animacions[this->o].frames.size()) this->cur_frame = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->x > (this->sam->x - 7) && this->x < (this->sam->x + 7) && this->y > (this->sam->y - 7) && this->y < (this->sam->y + 7)) {
|
||||||
|
morta = true;
|
||||||
|
if (this->sam->pergami) {
|
||||||
|
this->sam->pergami = false;
|
||||||
|
} else {
|
||||||
|
info::ctx.vida--;
|
||||||
|
if (info::ctx.vida == 0) this->sam->o = 5;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return morta;
|
return morta;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Momia::insertar(Momia* momia) {
|
|
||||||
if (this->next != NULL) {
|
|
||||||
this->next->insertar(momia);
|
|
||||||
} else {
|
|
||||||
this->next = momia;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "game/engendro.hpp"
|
#include "game/engendro.hpp"
|
||||||
#include "game/info.hpp"
|
#include "game/info.hpp"
|
||||||
#include "game/prota.hpp"
|
#include "game/prota.hpp"
|
||||||
@@ -7,17 +9,14 @@
|
|||||||
|
|
||||||
class Momia : public Sprite {
|
class Momia : public Sprite {
|
||||||
public:
|
public:
|
||||||
Momia(JD8_Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam);
|
explicit Momia(JD8_Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam);
|
||||||
|
|
||||||
void clear();
|
void draw() override;
|
||||||
void draw();
|
|
||||||
bool update();
|
bool update();
|
||||||
void insertar(Momia* momia);
|
|
||||||
|
|
||||||
bool dimoni;
|
bool dimoni;
|
||||||
Momia* next;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Prota* sam;
|
Prota* sam;
|
||||||
Engendro* engendro;
|
std::unique_ptr<Engendro> engendro;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
class Prota : public Sprite {
|
class Prota : public Sprite {
|
||||||
public:
|
public:
|
||||||
Prota(JD8_Surface gfx);
|
explicit Prota(JD8_Surface gfx);
|
||||||
|
|
||||||
void draw();
|
void draw() override;
|
||||||
Uint8 update();
|
Uint8 update();
|
||||||
|
|
||||||
Uint8 frame_pejades;
|
Uint8 frame_pejades;
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ struct Entitat {
|
|||||||
|
|
||||||
class Sprite {
|
class Sprite {
|
||||||
public:
|
public:
|
||||||
Sprite(JD8_Surface gfx);
|
explicit Sprite(JD8_Surface gfx);
|
||||||
virtual ~Sprite() = default;
|
virtual ~Sprite() = default;
|
||||||
|
|
||||||
void draw();
|
virtual void draw();
|
||||||
|
|
||||||
Entitat entitat;
|
Entitat entitat;
|
||||||
Uint8 cur_frame = 0;
|
Uint8 cur_frame = 0;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ namespace scenes {
|
|||||||
// PaletteFade copia internament amb memcpy; alliberem la paleta temporal.
|
// PaletteFade copia internament amb memcpy; alliberem la paleta temporal.
|
||||||
JD8_Palette pal = JD8_LoadPalette("gfx/ffase.gif");
|
JD8_Palette pal = JD8_LoadPalette("gfx/ffase.gif");
|
||||||
fade_.startFadeTo(pal);
|
fade_.startFadeTo(pal);
|
||||||
std::free(pal);
|
delete[] pal;
|
||||||
|
|
||||||
phase_ = Phase::FadingIn;
|
phase_ = Phase::FadingIn;
|
||||||
remaining_ms_ = 5000;
|
remaining_ms_ = 5000;
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ namespace scenes {
|
|||||||
void onEnter() override;
|
void onEnter() override;
|
||||||
void tick(int delta_ms) override;
|
void tick(int delta_ms) override;
|
||||||
bool done() const override { return done_; }
|
bool done() const override { return done_; }
|
||||||
int nextState() const override { return 1; } // 1 → SceneRegistry::tryCreate(num_piramide=255 → intro)
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void render() const;
|
void render() const;
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ namespace scenes {
|
|||||||
void onEnter() override;
|
void onEnter() override;
|
||||||
void tick(int delta_ms) override;
|
void tick(int delta_ms) override;
|
||||||
bool done() const override { return phase_ == Phase::Done; }
|
bool done() const override { return phase_ == Phase::Done; }
|
||||||
int nextState() const override { return 1; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class Phase { Rolling,
|
enum class Phase { Rolling,
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ namespace scenes {
|
|||||||
void onEnter() override;
|
void onEnter() override;
|
||||||
void tick(int delta_ms) override;
|
void tick(int delta_ms) override;
|
||||||
bool done() const override { return phase_ == Phase::Done; }
|
bool done() const override { return phase_ == Phase::Done; }
|
||||||
int nextState() const override { return 1; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class Phase {
|
enum class Phase {
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ namespace scenes {
|
|||||||
void onEnter() override;
|
void onEnter() override;
|
||||||
void tick(int delta_ms) override;
|
void tick(int delta_ms) override;
|
||||||
bool done() const override { return phase_ == Phase::Done; }
|
bool done() const override { return phase_ == Phase::Done; }
|
||||||
int nextState() const override { return 1; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class Phase {
|
enum class Phase {
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ namespace scenes {
|
|||||||
void onEnter() override;
|
void onEnter() override;
|
||||||
void tick(int delta_ms) override;
|
void tick(int delta_ms) override;
|
||||||
bool done() const override { return done_; }
|
bool done() const override { return done_; }
|
||||||
int nextState() const override { return 1; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SurfaceHandle gfx_;
|
SurfaceHandle gfx_;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace scenes {
|
|||||||
|
|
||||||
JD8_Palette pal = JD8_LoadPalette("gfx/menu2.gif");
|
JD8_Palette pal = JD8_LoadPalette("gfx/menu2.gif");
|
||||||
fade_.startFadeTo(pal);
|
fade_.startFadeTo(pal);
|
||||||
std::free(pal);
|
delete[] pal;
|
||||||
|
|
||||||
phase_ = Phase::FadingIn;
|
phase_ = Phase::FadingIn;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ namespace scenes {
|
|||||||
void onEnter() override;
|
void onEnter() override;
|
||||||
void tick(int delta_ms) override;
|
void tick(int delta_ms) override;
|
||||||
bool done() const override { return phase_ == Phase::Done; }
|
bool done() const override { return phase_ == Phase::Done; }
|
||||||
int nextState() const override { return 1; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class Phase { FadingIn,
|
enum class Phase { FadingIn,
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace scenes {
|
|||||||
// la paleta temporal immediatament.
|
// la paleta temporal immediatament.
|
||||||
JD8_Palette pal = JD8_LoadPalette("gfx/gameover.gif");
|
JD8_Palette pal = JD8_LoadPalette("gfx/gameover.gif");
|
||||||
fade_.startFadeTo(pal);
|
fade_.startFadeTo(pal);
|
||||||
std::free(pal);
|
delete[] pal;
|
||||||
|
|
||||||
phase_ = Phase::FadingIn;
|
phase_ = Phase::FadingIn;
|
||||||
remaining_ms_ = 10000;
|
remaining_ms_ = 10000;
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ namespace scenes {
|
|||||||
void onEnter() override;
|
void onEnter() override;
|
||||||
void tick(int delta_ms) override;
|
void tick(int delta_ms) override;
|
||||||
bool done() const override { return phase_ == Phase::Done; }
|
bool done() const override { return phase_ == Phase::Done; }
|
||||||
int nextState() const override { return 1; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class Phase { FadingIn,
|
enum class Phase { FadingIn,
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ namespace {
|
|||||||
namespace scenes {
|
namespace scenes {
|
||||||
|
|
||||||
SecretaScene::~SecretaScene() {
|
SecretaScene::~SecretaScene() {
|
||||||
if (pal_aux_) std::free(pal_aux_);
|
delete[] pal_aux_;
|
||||||
// pal_active_ NO s'allibera: propietat de main_palette via SetScreenPalette.
|
// pal_active_ NO s'allibera: propietat de main_palette via SetScreenPalette.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ namespace scenes {
|
|||||||
|
|
||||||
gfx_ = SurfaceHandle("gfx/tomba1.gif");
|
gfx_ = SurfaceHandle("gfx/tomba1.gif");
|
||||||
pal_aux_ = JD8_LoadPalette("gfx/tomba1.gif");
|
pal_aux_ = JD8_LoadPalette("gfx/tomba1.gif");
|
||||||
pal_active_ = static_cast<JD8_Palette>(std::malloc(768));
|
pal_active_ = new Color[256];
|
||||||
std::memcpy(pal_active_, pal_aux_, 768);
|
std::memcpy(pal_active_, pal_aux_, 768);
|
||||||
|
|
||||||
phase_ = Phase::InitialFadeOut;
|
phase_ = Phase::InitialFadeOut;
|
||||||
@@ -62,7 +62,7 @@ namespace scenes {
|
|||||||
JD8_ClearScreen(255);
|
JD8_ClearScreen(255);
|
||||||
gfx_.reset("gfx/tomba2.gif");
|
gfx_.reset("gfx/tomba2.gif");
|
||||||
|
|
||||||
std::free(pal_aux_);
|
delete[] pal_aux_;
|
||||||
pal_aux_ = JD8_LoadPalette("gfx/tomba2.gif");
|
pal_aux_ = JD8_LoadPalette("gfx/tomba2.gif");
|
||||||
// pal_active_ continua sent el mateix buffer: només actualitzem
|
// pal_active_ continua sent el mateix buffer: només actualitzem
|
||||||
// el seu contingut. main_palette ja apunta ací.
|
// el seu contingut. main_palette ja apunta ací.
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace {
|
|||||||
namespace scenes {
|
namespace scenes {
|
||||||
|
|
||||||
SlidesScene::~SlidesScene() {
|
SlidesScene::~SlidesScene() {
|
||||||
if (pal_aux_) std::free(pal_aux_);
|
delete[] pal_aux_;
|
||||||
// pal_active_ NO s'allibera: propietat de main_palette via SetScreenPalette.
|
// pal_active_ NO s'allibera: propietat de main_palette via SetScreenPalette.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ namespace scenes {
|
|||||||
// main_palette després del SetScreenPalette — modificar-la modifica
|
// main_palette després del SetScreenPalette — modificar-la modifica
|
||||||
// main_palette directament. `pal_aux_` es manté intacte per a poder
|
// main_palette directament. `pal_aux_` es manté intacte per a poder
|
||||||
// restaurar després de cada fade-out intermedi.
|
// restaurar després de cada fade-out intermedi.
|
||||||
pal_active_ = static_cast<JD8_Palette>(std::malloc(768));
|
pal_active_ = new Color[256];
|
||||||
std::memcpy(pal_active_, pal_aux_, 768);
|
std::memcpy(pal_active_, pal_aux_, 768);
|
||||||
JD8_SetScreenPalette(pal_active_);
|
JD8_SetScreenPalette(pal_active_);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user