afegida persistencia i fuck yamal

This commit is contained in:
2026-04-04 13:00:02 +02:00
parent 08ba88ec05
commit 6a09d7219d
9 changed files with 15021 additions and 98 deletions

View File

@@ -35,6 +35,14 @@ All engine modules are flat C-style APIs (no classes), prefixed by subsystem:
- **JF** (`source/core/jfile`) — File I/O: supports loading from filesystem folder or a packed resource file (`.jrf`). Currently uses folder mode (`data/`)
- **shader** (`source/core/jshader`) — OpenGL post-processing shader (CRT effect) applied to the back buffer
### Configuration System (`source/game/`)
Follows the pattern from `jaildoctors_dilemma`:
- **defines.hpp** <20><> Game-wide constants (window title, version, screen dimensions)
- **defaults.hpp** — Default values for all persistent options (audio, game)
- **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/`)
- **ModuleSequence** — Non-gameplay screens: intro, menu, slides, banners, credits, death screen. State machine entry point (state=1)
@@ -51,6 +59,7 @@ All engine modules are flat C-style APIs (no classes), prefixed by subsystem:
- `gif.h` — Header-only GIF decoder
- `stb_vorbis.h` — stb single-header OGG decoder
- `fkyaml_node.hpp` — Header-only YAML parser (fkYAML v0.4.2)
### Main Loop (`source/main.cpp`)

View File

@@ -21,6 +21,7 @@ set(APP_SOURCES
source/core/jshader.cpp
# Game
source/game/options.cpp
source/game/bola.cpp
source/game/engendro.cpp
source/game/info.cpp

View File

@@ -139,7 +139,8 @@ char *file_getfilebuffer(const char *resourcename, int& filesize, const bool zer
return buffer;
}
// Crea la carpeta del sistema donde guardar datos
// Crea la carpeta del sistema donde guardar datos.
// Acepta rutas con subdirectorios (ej: "jailgames/aee") y crea toda la jerarquía.
void file_setconfigfolder(const char *foldername)
{
#ifdef _WIN32
@@ -151,28 +152,15 @@ void file_setconfigfolder(const char *foldername)
#elif __linux__
struct passwd *pw = getpwuid(getuid());
const char *homedir = pw->pw_dir;
config_folder = std::string(homedir) + "/." + foldername;
config_folder = std::string(homedir) + "/.config/" + foldername;
#endif
struct stat st = {0};
if (stat(config_folder.c_str(), &st) == -1)
{
#ifdef _WIN32
int ret = mkdir(config_folder.c_str());
#else
int ret = mkdir(config_folder.c_str(), S_IRWXU);
#endif
if (ret == -1)
{
printf("ERROR CREATING CONFIG FOLDER.");
exit(EXIT_FAILURE);
}
}
std::filesystem::create_directories(config_folder);
}
const char *file_getconfigfolder() {
std::string folder = config_folder + "/";
static std::string folder;
folder = config_folder + "/";
return folder.c_str();
}

14726
source/external/fkyaml_node.hpp vendored Normal file

File diff suppressed because it is too large Load Diff

15
source/game/defaults.hpp Normal file
View File

@@ -0,0 +1,15 @@
#pragma once
namespace Defaults::Audio {
constexpr float VOLUME = 1.0F;
constexpr bool MUSIC_ENABLED = true;
constexpr float MUSIC_VOLUME = 0.8F;
constexpr bool SOUND_ENABLED = true;
constexpr float SOUND_VOLUME = 1.0F;
} // namespace Defaults::Audio
namespace Defaults::Game {
constexpr int HABITACIO_INICIAL = 1;
constexpr int PIRAMIDE_INICIAL = 255;
constexpr int VIDES = 5;
} // namespace Defaults::Game

14
source/game/defines.hpp Normal file
View File

@@ -0,0 +1,14 @@
#pragma once
// Textos
namespace Texts {
constexpr const char* WINDOW_TITLE = "Aventures En Egipte";
constexpr const char* VERSION = "1.00";
} // namespace Texts
// Resolución del juego
namespace Screen {
constexpr int WIDTH = 320;
constexpr int HEIGHT = 200;
constexpr int BUFFER_SIZE = WIDTH * HEIGHT; // 64000
} // namespace Screen

146
source/game/options.cpp Normal file
View File

@@ -0,0 +1,146 @@
#include "game/options.hpp"
#include <fstream>
#include <iostream>
#include <string>
#include "external/fkyaml_node.hpp"
#include "game/defaults.hpp"
#include "game/defines.hpp"
namespace Options {
// Estableix la ruta del fitxer de configuració
void setConfigFile(const std::string& path) {
config_file_path = path;
}
// --- Funcions helper de càrrega ---
static void loadAudioConfigFromYaml(const fkyaml::node& yaml) {
if (!yaml.contains("audio")) return;
const auto& node = yaml["audio"];
if (node.contains("volume"))
audio.volume = node["volume"].get_value<float>();
if (node.contains("music")) {
const auto& music = node["music"];
if (music.contains("enabled"))
audio.music_enabled = music["enabled"].get_value<bool>();
if (music.contains("volume"))
audio.music_volume = music["volume"].get_value<float>();
}
if (node.contains("sound")) {
const auto& sound = node["sound"];
if (sound.contains("enabled"))
audio.sound_enabled = sound["enabled"].get_value<bool>();
if (sound.contains("volume"))
audio.sound_volume = sound["volume"].get_value<float>();
}
}
static void loadGameConfigFromYaml(const fkyaml::node& yaml) {
if (!yaml.contains("game")) return;
const auto& node = yaml["game"];
if (node.contains("habitacio_inicial"))
game.habitacio_inicial = node["habitacio_inicial"].get_value<int>();
if (node.contains("piramide_inicial"))
game.piramide_inicial = node["piramide_inicial"].get_value<int>();
if (node.contains("vides"))
game.vides = node["vides"].get_value<int>();
}
// Carrega les opcions des del fitxer configurat
auto loadFromFile() -> bool {
const std::string CONFIG_VERSION = Texts::VERSION;
version = "";
std::ifstream file(config_file_path);
if (!file.good()) {
std::cout << "Config file not found, creating default: " << config_file_path << '\n';
saveToFile();
return true;
}
std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
file.close();
try {
std::cout << "Reading config file: " << config_file_path << '\n';
auto yaml = fkyaml::node::deserialize(content);
if (yaml.contains("version")) {
version = yaml["version"].get_value<std::string>();
}
if (CONFIG_VERSION != version) {
std::cout << "Config version mismatch (expected: " << CONFIG_VERSION
<< ", got: " << version << "), creating new config\n";
saveToFile();
return true;
}
loadAudioConfigFromYaml(yaml);
loadGameConfigFromYaml(yaml);
std::cout << "Config file loaded successfully\n\n";
return true;
} catch (const fkyaml::exception& e) {
std::cerr << "Error parsing YAML config: " << e.what() << '\n';
std::cerr << "Creating new config with defaults\n";
saveToFile();
return true;
}
}
// Guarda les opcions al fitxer configurat
auto saveToFile() -> bool {
std::ofstream file(config_file_path);
if (!file.is_open()) {
std::cerr << "Error: Unable to open file " << config_file_path << " for writing\n";
return false;
}
std::cout << "Writing config file: " << config_file_path << '\n';
file << "# Aventures En Egipte - Configuration File\n";
file << "# \n";
file << "# This file is automatically generated and managed by the game.\n";
file << "# Manual edits are preserved if valid.\n";
file << "\n";
// VERSION
file << "version: \"" << Texts::VERSION << "\"\n";
file << "\n";
// AUDIO
file << "# AUDIO\n";
file << "audio:\n";
file << " volume: " << audio.volume << "\n";
file << " music:\n";
file << " enabled: " << (audio.music_enabled ? "true" : "false") << "\n";
file << " volume: " << audio.music_volume << "\n";
file << " sound:\n";
file << " enabled: " << (audio.sound_enabled ? "true" : "false") << "\n";
file << " volume: " << audio.sound_volume << "\n";
file << "\n";
// GAME
file << "# GAME\n";
file << "game:\n";
file << " habitacio_inicial: " << game.habitacio_inicial << "\n";
file << " piramide_inicial: " << game.piramide_inicial << "\n";
file << " vides: " << game.vides << "\n";
file.close();
std::cout << "Config file saved successfully\n\n";
return true;
}
} // namespace Options

37
source/game/options.hpp Normal file
View File

@@ -0,0 +1,37 @@
#pragma once
#include <string>
#include "game/defaults.hpp"
#include "game/defines.hpp"
namespace Options {
// Opcions d'àudio
struct Audio {
bool music_enabled{Defaults::Audio::MUSIC_ENABLED};
float music_volume{Defaults::Audio::MUSIC_VOLUME};
bool sound_enabled{Defaults::Audio::SOUND_ENABLED};
float sound_volume{Defaults::Audio::SOUND_VOLUME};
float volume{Defaults::Audio::VOLUME};
};
// Opcions de joc
struct Game {
int habitacio_inicial{Defaults::Game::HABITACIO_INICIAL};
int piramide_inicial{Defaults::Game::PIRAMIDE_INICIAL};
int vides{Defaults::Game::VIDES};
};
// --- Variables globals ---
inline std::string version{};
inline Audio audio{};
inline Game game{};
inline std::string config_file_path{};
// --- API ---
void setConfigFile(const std::string& path);
auto loadFromFile() -> bool;
auto saveToFile() -> bool;
} // namespace Options

View File

@@ -2,46 +2,32 @@
#include "core/jdraw8.hpp"
#include "core/jail_audio.hpp"
#include "core/jfile.hpp"
#include "game/defines.hpp"
#include "game/info.hpp"
#include "game/modulegame.hpp"
#include "game/modulesequence.hpp"
#include "game/options.hpp"
#include <ctime>
#include <string>
/*
#ifndef WIN32
#include <libgen.h>
#endif
*/
int main( int argc, char* args[] ) {
//file_setresourcefilename("data.jrf");
/*#ifdef WIN32
JF_SetResourceFile("data.jrf");
#else
char res_file[255] = "";
strcpy(res_file, dirname(args[0]));
#ifdef __APPLE__
strcat(res_file, "/../Resources/data.jrf");
#else
strcat(res_file, "/data.jrf");
#endif
printf("ARXIU DE RECURSOS: %s\n", res_file);
JF_SetResourceFile(res_file);
#endif
*/
srand( unsigned(time(NULL)) );
// Crea la carpeta de configuració i carrega les opcions
file_setconfigfolder("jailgames/aee");
Options::setConfigFile(std::string(file_getconfigfolder()) + "config.yaml");
Options::loadFromFile();
JG_Init();
JD8_Init("Aventures En Egipte");
JD8_Init(Texts::WINDOW_TITLE);
JA_Init(48000, SDL_AUDIO_S16, 2);
info::num_habitacio = 1;
info::num_piramide = 255;
info::num_habitacio = Options::game.habitacio_inicial;
info::num_piramide = Options::game.piramide_inicial;
info::diners = 0;
info::diamants = 0;
info::vida = 5;
info::vida = Options::game.vides;
info::momies = 0;
info::nou_personatge = false;
info::pepe_activat = false;
@@ -71,10 +57,11 @@ int main( int argc, char* args[] ) {
}
}
Options::saveToFile();
JA_Quit();
JD8_Quit();
JG_Finalize();
return 0;
}