Files
orni-attack/source/core/system/director.cpp
T
2025-12-03 09:42:45 +01:00

192 lines
5.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "director.hpp"
#include <SDL3/SDL.h>
#include <sys/stat.h>
#include <cerrno>
#include <cstdlib>
#include <iostream>
#include "../../game/escenes/escena_joc.hpp"
#include "../../game/escenes/escena_logo.hpp"
#include "../../game/escenes/escena_titol.hpp"
#include "../../game/options.hpp"
#include "../audio/audio.hpp"
#include "../defaults.hpp"
#include "../rendering/sdl_manager.hpp"
#include "gestor_escenes.hpp"
#include "project.h"
#ifndef _WIN32
#include <pwd.h>
#include <unistd.h>
#endif
// Constructor
Director::Director(std::vector<std::string> const& args) {
std::cout << "Orni Attack - Inici\n";
// Inicialitzar opcions amb valors per defecte
Options::init();
// Comprovar arguments del programa
executable_path_ = checkProgramArguments(args);
// Crear carpetes del sistema
createSystemFolder("jailgames");
createSystemFolder(std::string("jailgames/") + Project::NAME);
// Establir ruta del fitxer de configuració
Options::setConfigFile(system_folder_ + "/config.yaml");
// Carregar o crear configuració
Options::loadFromFile();
if (Options::console) {
std::cout << "Configuració carregada\n";
std::cout << " Finestra: " << Options::window.width << "×"
<< Options::window.height << '\n';
std::cout << " Física: rotation=" << Options::physics.rotation_speed
<< " rad/s\n";
}
std::cout << '\n';
}
Director::~Director() {
// Guardar opcions
Options::saveToFile();
// Cleanup audio
Audio::destroy();
// Cleanup SDL
SDL_Quit();
std::cout << "\nAdéu!\n";
}
// Comprovar arguments del programa
auto Director::checkProgramArguments(std::vector<std::string> const& args)
-> std::string {
for (std::size_t i = 1; i < args.size(); ++i) {
const std::string& argument = args[i];
if (argument == "--console") {
Options::console = true;
std::cout << "Mode consola activat\n";
} else if (argument == "--reset-config") {
Options::init();
Options::saveToFile();
std::cout << "Configuració restablida als valors per defecte\n";
}
}
return args[0]; // Retornar ruta de l'executable
}
// Crear carpeta del sistema (específic per plataforma)
void Director::createSystemFolder(const std::string& folder) {
#ifdef _WIN32
system_folder_ = std::string(getenv("APPDATA")) + "/" + folder;
#elif __APPLE__
struct passwd* pw = getpwuid(getuid());
const char* homedir = pw->pw_dir;
system_folder_ =
std::string(homedir) + "/Library/Application Support/" + folder;
#elif __linux__
struct passwd* pw = getpwuid(getuid());
const char* homedir = pw->pw_dir;
system_folder_ = std::string(homedir) + "/.config/" + folder;
// CRÍTIC: Crear ~/.config si no existeix
{
std::string config_base_folder = std::string(homedir) + "/.config";
int ret = mkdir(config_base_folder.c_str(), S_IRWXU);
if (ret == -1 && errno != EEXIST) {
printf("ERROR: No es pot crear la carpeta ~/.config\n");
exit(EXIT_FAILURE);
}
}
#endif
// Comprovar si la carpeta existeix
struct stat st = {.st_dev = 0};
if (stat(system_folder_.c_str(), &st) == -1) {
errno = 0;
#ifdef _WIN32
int ret = mkdir(system_folder_.c_str());
#else
int ret = mkdir(system_folder_.c_str(), S_IRWXU);
#endif
if (ret == -1) {
switch (errno) {
case EACCES:
printf("ERROR: Permisos denegats creant %s\n", system_folder_.c_str());
exit(EXIT_FAILURE);
case EEXIST:
// La carpeta ja existeix (race condition), continuar
break;
case ENAMETOOLONG:
printf("ERROR: Ruta massa llarga: %s\n", system_folder_.c_str());
exit(EXIT_FAILURE);
default:
perror("mkdir");
exit(EXIT_FAILURE);
}
}
}
if (Options::console) {
std::cout << "Carpeta del sistema: " << system_folder_ << '\n';
}
}
// Bucle principal del joc
auto Director::run() -> int {
// Calculate initial size from saved zoom_factor
int initial_width = static_cast<int>(std::round(
Defaults::Window::WIDTH * Options::window.zoom_factor));
int initial_height = static_cast<int>(std::round(
Defaults::Window::HEIGHT * Options::window.zoom_factor));
// Crear gestor SDL amb configuració de Options
SDLManager sdl(initial_width, initial_height, Options::window.fullscreen);
// Inicialitzar sistema d'audio
Audio::init();
// Bucle principal de gestió d'escenes
while (GestorEscenes::actual != GestorEscenes::Escena::EIXIR) {
switch (GestorEscenes::actual) {
case GestorEscenes::Escena::LOGO: {
EscenaLogo logo(sdl);
logo.executar();
break;
}
case GestorEscenes::Escena::TITOL: {
EscenaTitol titol(sdl);
titol.executar();
break;
}
case GestorEscenes::Escena::JOC: {
EscenaJoc joc(sdl);
joc.executar();
break;
}
default:
break;
}
}
return 0;
}