forked from jaildesigner-jailgames/jaildoctors_dilemma
redistribuida la carpeta source
This commit is contained in:
179
source/core/resources/asset.cpp
Normal file
179
source/core/resources/asset.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
#include "core/resources/asset.hpp"
|
||||
#include <algorithm> // Para find_if, max
|
||||
#include <fstream> // Para basic_ostream, operator<<, basic_ifstream, endl
|
||||
#include <iostream> // Para cout
|
||||
#include <string> // Para allocator, char_traits, string, operator+, oper...
|
||||
#include "utils/utils.hpp" // Para getFileName, printWithDots
|
||||
|
||||
// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
|
||||
Asset *Asset::asset_ = nullptr;
|
||||
|
||||
// [SINGLETON] Crearemos el objeto asset con esta función estática
|
||||
void Asset::init(const std::string &executable_path)
|
||||
{
|
||||
Asset::asset_ = new Asset(executable_path);
|
||||
}
|
||||
|
||||
// [SINGLETON] Destruiremos el objeto asset con esta función estática
|
||||
void Asset::destroy()
|
||||
{
|
||||
delete Asset::asset_;
|
||||
}
|
||||
|
||||
// [SINGLETON] Con este método obtenemos el objeto asset y podemos trabajar con él
|
||||
Asset *Asset::get()
|
||||
{
|
||||
return Asset::asset_;
|
||||
}
|
||||
|
||||
// Añade un elemento a la lista
|
||||
void Asset::add(const std::string &file, AssetType type, bool required, bool absolute)
|
||||
{
|
||||
file_list_.emplace_back(absolute ? file : executable_path_ + file, type, required);
|
||||
longest_name_ = std::max(longest_name_, static_cast<int>(file_list_.back().file.size()));
|
||||
}
|
||||
|
||||
// Devuelve la ruta completa a un fichero a partir de una cadena
|
||||
std::string Asset::get(const std::string &text) const
|
||||
{
|
||||
auto it = std::find_if(file_list_.begin(), file_list_.end(),
|
||||
[&text](const auto &f)
|
||||
{
|
||||
return getFileName(f.file) == text;
|
||||
});
|
||||
|
||||
if (it != file_list_.end())
|
||||
{
|
||||
return it->file;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Warning: file " << text << " not found" << std::endl;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// Comprueba que existen todos los elementos
|
||||
bool Asset::check() const
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
std::cout << "\n** CHECKING FILES" << std::endl;
|
||||
|
||||
// std::cout << "Executable path is: " << executable_path_ << std::endl;
|
||||
// std::cout << "Sample filepath: " << file_list_.back().file << std::endl;
|
||||
|
||||
// Comprueba la lista de ficheros clasificandolos por tipo
|
||||
for (int type = 0; type < static_cast<int>(AssetType::MAX_ASSET_TYPE); ++type)
|
||||
{
|
||||
// Comprueba si hay ficheros de ese tipo
|
||||
bool any = false;
|
||||
|
||||
for (const auto &f : file_list_)
|
||||
{
|
||||
if (f.required && f.type == static_cast<AssetType>(type))
|
||||
{
|
||||
any = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Si hay ficheros de ese tipo, comprueba si existen
|
||||
if (any)
|
||||
{
|
||||
std::cout << "\n>> " << getTypeName(static_cast<AssetType>(type)).c_str() << " FILES" << std::endl;
|
||||
|
||||
for (const auto &f : file_list_)
|
||||
{
|
||||
if (f.required && f.type == static_cast<AssetType>(type))
|
||||
{
|
||||
success &= checkFile(f.file);
|
||||
}
|
||||
}
|
||||
if (success)
|
||||
std::cout << " All files are OK." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Resultado
|
||||
std::cout << (success ? "\n** CHECKING FILES COMPLETED.\n" : "\n** CHECKING FILES FAILED.\n") << std::endl;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
// Comprueba que existe un fichero
|
||||
bool Asset::checkFile(const std::string &path) const
|
||||
{
|
||||
std::ifstream file(path);
|
||||
bool success = file.good();
|
||||
file.close();
|
||||
|
||||
if (!success)
|
||||
{
|
||||
printWithDots("Checking file : ", getFileName(path), "[ ERROR ]");
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
// Devuelve el nombre del tipo de recurso
|
||||
std::string Asset::getTypeName(AssetType type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case AssetType::DATA:
|
||||
return "DATA";
|
||||
break;
|
||||
|
||||
case AssetType::BITMAP:
|
||||
return "BITMAP";
|
||||
break;
|
||||
|
||||
case AssetType::ANIMATION:
|
||||
return "ANIMATION";
|
||||
break;
|
||||
|
||||
case AssetType::MUSIC:
|
||||
return "MUSIC";
|
||||
break;
|
||||
|
||||
case AssetType::SOUND:
|
||||
return "SOUND";
|
||||
break;
|
||||
|
||||
case AssetType::FONT:
|
||||
return "FONT";
|
||||
break;
|
||||
|
||||
case AssetType::ROOM:
|
||||
return "ROOM";
|
||||
break;
|
||||
|
||||
case AssetType::TILEMAP:
|
||||
return "TILEMAP";
|
||||
break;
|
||||
|
||||
case AssetType::PALETTE:
|
||||
return "PALETTE";
|
||||
break;
|
||||
|
||||
default:
|
||||
return "ERROR";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Devuelve la lista de recursos de un tipo
|
||||
std::vector<std::string> Asset::getListByType(AssetType type) const
|
||||
{
|
||||
std::vector<std::string> list;
|
||||
|
||||
for (auto f : file_list_)
|
||||
{
|
||||
if (f.type == type)
|
||||
{
|
||||
list.push_back(f.file);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
79
source/core/resources/asset.hpp
Normal file
79
source/core/resources/asset.hpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#pragma once
|
||||
|
||||
#include <string> // para string, basic_string
|
||||
#include <vector> // para vector
|
||||
#include "utils/utils.hpp"
|
||||
|
||||
enum class AssetType : int
|
||||
{
|
||||
DATA,
|
||||
BITMAP,
|
||||
ANIMATION,
|
||||
MUSIC,
|
||||
SOUND,
|
||||
FONT,
|
||||
ROOM,
|
||||
TILEMAP,
|
||||
PALETTE,
|
||||
MAX_ASSET_TYPE
|
||||
};
|
||||
|
||||
// Clase Asset
|
||||
class Asset
|
||||
{
|
||||
private:
|
||||
// [SINGLETON] Objeto asset privado para Don Melitón
|
||||
static Asset *asset_;
|
||||
|
||||
// Estructura para definir un item
|
||||
struct AssetItem
|
||||
{
|
||||
std::string file; // Ruta del fichero desde la raíz del directorio
|
||||
AssetType type; // Indica el tipo de recurso
|
||||
bool required; // Indica si es un fichero que debe de existir
|
||||
|
||||
// Constructor
|
||||
AssetItem(const std::string &filePath, AssetType assetType, bool isRequired)
|
||||
: file(filePath), type(assetType), required(isRequired) {}
|
||||
};
|
||||
|
||||
// Variables
|
||||
int longest_name_ = 0; // Contiene la longitud del nombre de fichero mas largo
|
||||
std::vector<AssetItem> file_list_; // Listado con todas las rutas a los ficheros
|
||||
std::string executable_path_; // Ruta al ejecutable
|
||||
|
||||
// Comprueba que existe un fichero
|
||||
bool checkFile(const std::string &path) const;
|
||||
|
||||
// Devuelve el nombre del tipo de recurso
|
||||
std::string getTypeName(AssetType type) const;
|
||||
|
||||
// Constructor
|
||||
explicit Asset(const std::string &executable_path)
|
||||
: executable_path_(getPath(executable_path)) {}
|
||||
|
||||
// Destructor
|
||||
~Asset() = default;
|
||||
|
||||
public:
|
||||
// [SINGLETON] Crearemos el objeto con esta función estática
|
||||
static void init(const std::string &executable_path);
|
||||
|
||||
// [SINGLETON] Destruiremos el objeto con esta función estática
|
||||
static void destroy();
|
||||
|
||||
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
|
||||
static Asset *get();
|
||||
|
||||
// Añade un elemento a la lista
|
||||
void add(const std::string &file, AssetType type, bool required = true, bool absolute = false);
|
||||
|
||||
// Devuelve la ruta completa a un fichero a partir de una cadena
|
||||
std::string get(const std::string &text) const;
|
||||
|
||||
// Comprueba que existen todos los elementos
|
||||
bool check() const;
|
||||
|
||||
// Devuelve la lista de recursos de un tipo
|
||||
std::vector<std::string> getListByType(AssetType type) const;
|
||||
};
|
||||
418
source/core/resources/resource.cpp
Normal file
418
source/core/resources/resource.cpp
Normal file
@@ -0,0 +1,418 @@
|
||||
#include "core/resources/resource.hpp"
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <stdlib.h> // Para exit, size_t
|
||||
|
||||
#include <algorithm> // Para find_if
|
||||
#include <iostream> // Para basic_ostream, operator<<, endl, cout
|
||||
#include <stdexcept> // Para runtime_error
|
||||
|
||||
#include "core/resources/asset.hpp" // Para AssetType, Asset
|
||||
#include "external/jail_audio.h" // Para JA_DeleteMusic, JA_DeleteSound, JA_Loa...
|
||||
#include "game/gameplay/options.hpp" // Para Options, OptionsGame, options
|
||||
#include "game/gameplay/room.hpp" // Para RoomData, loadRoomFile, loadRoomTileFile
|
||||
#include "core/rendering/screen.hpp" // Para Screen
|
||||
#include "core/rendering/text.hpp" // Para Text, loadTextFile
|
||||
#include "utils/utils.hpp" // Para getFileName, printWithDots, PaletteColor
|
||||
struct JA_Music_t; // lines 17-17
|
||||
struct JA_Sound_t; // lines 18-18
|
||||
|
||||
// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
|
||||
Resource* Resource::resource_ = nullptr;
|
||||
|
||||
// [SINGLETON] Crearemos el objeto screen con esta función estática
|
||||
void Resource::init() { Resource::resource_ = new Resource(); }
|
||||
|
||||
// [SINGLETON] Destruiremos el objeto screen con esta función estática
|
||||
void Resource::destroy() { delete Resource::resource_; }
|
||||
|
||||
// [SINGLETON] Con este método obtenemos el objeto screen y podemos trabajar con él
|
||||
Resource* Resource::get() { return Resource::resource_; }
|
||||
|
||||
// Constructor
|
||||
Resource::Resource() { load(); }
|
||||
|
||||
// Vacia todos los vectores de recursos
|
||||
void Resource::clear() {
|
||||
clearSounds();
|
||||
clearMusics();
|
||||
surfaces_.clear();
|
||||
palettes_.clear();
|
||||
text_files_.clear();
|
||||
texts_.clear();
|
||||
animations_.clear();
|
||||
}
|
||||
|
||||
// Carga todos los recursos
|
||||
void Resource::load() {
|
||||
calculateTotal();
|
||||
Screen::get()->setBorderColor(static_cast<Uint8>(PaletteColor::BLACK));
|
||||
std::cout << "** LOADING RESOURCES" << std::endl;
|
||||
loadSounds();
|
||||
loadMusics();
|
||||
loadSurfaces();
|
||||
loadPalettes();
|
||||
loadTextFiles();
|
||||
loadAnimations();
|
||||
loadTileMaps();
|
||||
loadRooms();
|
||||
createText();
|
||||
std::cout << "\n** RESOURCES LOADED" << std::endl;
|
||||
}
|
||||
|
||||
// Recarga todos los recursos
|
||||
void Resource::reload() {
|
||||
clear();
|
||||
load();
|
||||
}
|
||||
|
||||
// Obtiene el sonido a partir de un nombre
|
||||
JA_Sound_t* Resource::getSound(const std::string& name) {
|
||||
auto it = std::find_if(sounds_.begin(), sounds_.end(), [&name](const auto& s) { return s.name == name; });
|
||||
|
||||
if (it != sounds_.end()) {
|
||||
return it->sound;
|
||||
}
|
||||
|
||||
std::cerr << "Error: Sonido no encontrado " << name << std::endl;
|
||||
throw std::runtime_error("Sonido no encontrado: " + name);
|
||||
}
|
||||
|
||||
// Obtiene la música a partir de un nombre
|
||||
JA_Music_t* Resource::getMusic(const std::string& name) {
|
||||
auto it = std::find_if(musics_.begin(), musics_.end(), [&name](const auto& m) { return m.name == name; });
|
||||
|
||||
if (it != musics_.end()) {
|
||||
return it->music;
|
||||
}
|
||||
|
||||
std::cerr << "Error: Música no encontrada " << name << std::endl;
|
||||
throw std::runtime_error("Música no encontrada: " + name);
|
||||
}
|
||||
|
||||
// Obtiene la surface a partir de un nombre
|
||||
std::shared_ptr<Surface> Resource::getSurface(const std::string& name) {
|
||||
auto it = std::find_if(surfaces_.begin(), surfaces_.end(), [&name](const auto& t) { return t.name == name; });
|
||||
|
||||
if (it != surfaces_.end()) {
|
||||
return it->surface;
|
||||
}
|
||||
|
||||
std::cerr << "Error: Imagen no encontrada " << name << std::endl;
|
||||
throw std::runtime_error("Imagen no encontrada: " + name);
|
||||
}
|
||||
|
||||
// Obtiene la paleta a partir de un nombre
|
||||
Palette Resource::getPalette(const std::string& name) {
|
||||
auto it = std::find_if(palettes_.begin(), palettes_.end(), [&name](const auto& t) { return t.name == name; });
|
||||
|
||||
if (it != palettes_.end()) {
|
||||
return it->palette;
|
||||
}
|
||||
|
||||
std::cerr << "Error: Paleta no encontrada " << name << std::endl;
|
||||
throw std::runtime_error("Paleta no encontrada: " + name);
|
||||
}
|
||||
|
||||
// Obtiene el fichero de texto a partir de un nombre
|
||||
std::shared_ptr<TextFile> Resource::getTextFile(const std::string& name) {
|
||||
auto it = std::find_if(text_files_.begin(), text_files_.end(), [&name](const auto& t) { return t.name == name; });
|
||||
|
||||
if (it != text_files_.end()) {
|
||||
return it->text_file;
|
||||
}
|
||||
|
||||
std::cerr << "Error: TextFile no encontrado " << name << std::endl;
|
||||
throw std::runtime_error("TextFile no encontrado: " + name);
|
||||
}
|
||||
|
||||
// Obtiene el objeto de texto a partir de un nombre
|
||||
std::shared_ptr<Text> Resource::getText(const std::string& name) {
|
||||
auto it = std::find_if(texts_.begin(), texts_.end(), [&name](const auto& t) { return t.name == name; });
|
||||
|
||||
if (it != texts_.end()) {
|
||||
return it->text;
|
||||
}
|
||||
|
||||
std::cerr << "Error: Text no encontrado " << name << std::endl;
|
||||
throw std::runtime_error("Texto no encontrado: " + name);
|
||||
}
|
||||
|
||||
// Obtiene la animación a partir de un nombre
|
||||
Animations& Resource::getAnimations(const std::string& name) {
|
||||
auto it = std::find_if(animations_.begin(), animations_.end(), [&name](const auto& a) { return a.name == name; });
|
||||
|
||||
if (it != animations_.end()) {
|
||||
return it->animation;
|
||||
}
|
||||
|
||||
std::cerr << "Error: Animación no encontrada " << name << std::endl;
|
||||
throw std::runtime_error("Animación no encontrada: " + name);
|
||||
}
|
||||
|
||||
// Obtiene el mapa de tiles a partir de un nombre
|
||||
std::vector<int>& Resource::getTileMap(const std::string& name) {
|
||||
auto it = std::find_if(tile_maps_.begin(), tile_maps_.end(), [&name](const auto& t) { return t.name == name; });
|
||||
|
||||
if (it != tile_maps_.end()) {
|
||||
return it->tileMap;
|
||||
}
|
||||
|
||||
std::cerr << "Error: Mapa de tiles no encontrado " << name << std::endl;
|
||||
throw std::runtime_error("Mapa de tiles no encontrado: " + name);
|
||||
}
|
||||
|
||||
// Obtiene la habitación a partir de un nombre
|
||||
std::shared_ptr<RoomData> Resource::getRoom(const std::string& name) {
|
||||
auto it = std::find_if(rooms_.begin(), rooms_.end(), [&name](const auto& r) { return r.name == name; });
|
||||
|
||||
if (it != rooms_.end()) {
|
||||
return it->room;
|
||||
}
|
||||
|
||||
std::cerr << "Error: Habitación no encontrada " << name << std::endl;
|
||||
throw std::runtime_error("Habitación no encontrada: " + name);
|
||||
}
|
||||
|
||||
// Obtiene todas las habitaciones
|
||||
std::vector<ResourceRoom>& Resource::getRooms() {
|
||||
return rooms_;
|
||||
}
|
||||
|
||||
// Carga los sonidos
|
||||
void Resource::loadSounds() {
|
||||
std::cout << "\n>> SOUND FILES" << std::endl;
|
||||
auto list = Asset::get()->getListByType(AssetType::SOUND);
|
||||
sounds_.clear();
|
||||
|
||||
for (const auto& l : list) {
|
||||
auto name = getFileName(l);
|
||||
sounds_.emplace_back(ResourceSound(name, JA_LoadSound(l.c_str())));
|
||||
printWithDots("Sound : ", name, "[ LOADED ]");
|
||||
updateLoadingProgress();
|
||||
}
|
||||
}
|
||||
|
||||
// Carga las musicas
|
||||
void Resource::loadMusics() {
|
||||
std::cout << "\n>> MUSIC FILES" << std::endl;
|
||||
auto list = Asset::get()->getListByType(AssetType::MUSIC);
|
||||
musics_.clear();
|
||||
|
||||
for (const auto& l : list) {
|
||||
auto name = getFileName(l);
|
||||
musics_.emplace_back(ResourceMusic(name, JA_LoadMusic(l.c_str())));
|
||||
printWithDots("Music : ", name, "[ LOADED ]");
|
||||
updateLoadingProgress(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Carga las texturas
|
||||
void Resource::loadSurfaces() {
|
||||
std::cout << "\n>> SURFACES" << std::endl;
|
||||
auto list = Asset::get()->getListByType(AssetType::BITMAP);
|
||||
surfaces_.clear();
|
||||
|
||||
for (const auto& l : list) {
|
||||
auto name = getFileName(l);
|
||||
surfaces_.emplace_back(ResourceSurface(name, std::make_shared<Surface>(l)));
|
||||
surfaces_.back().surface->setTransparentColor(0);
|
||||
updateLoadingProgress();
|
||||
}
|
||||
|
||||
// Reconfigura el color transparente de algunas surfaces
|
||||
getSurface("loading_screen_color.gif")->setTransparentColor();
|
||||
getSurface("ending1.gif")->setTransparentColor();
|
||||
getSurface("ending2.gif")->setTransparentColor();
|
||||
getSurface("ending3.gif")->setTransparentColor();
|
||||
getSurface("ending4.gif")->setTransparentColor();
|
||||
getSurface("ending5.gif")->setTransparentColor();
|
||||
getSurface("standard.gif")->setTransparentColor(16);
|
||||
}
|
||||
|
||||
// Carga las paletas
|
||||
void Resource::loadPalettes() {
|
||||
std::cout << "\n>> PALETTES" << std::endl;
|
||||
auto list = Asset::get()->getListByType(AssetType::PALETTE);
|
||||
palettes_.clear();
|
||||
|
||||
for (const auto& l : list) {
|
||||
auto name = getFileName(l);
|
||||
palettes_.emplace_back(ResourcePalette(name, readPalFile(l)));
|
||||
updateLoadingProgress();
|
||||
}
|
||||
}
|
||||
|
||||
// Carga los ficheros de texto
|
||||
void Resource::loadTextFiles() {
|
||||
std::cout << "\n>> TEXT FILES" << std::endl;
|
||||
auto list = Asset::get()->getListByType(AssetType::FONT);
|
||||
text_files_.clear();
|
||||
|
||||
for (const auto& l : list) {
|
||||
auto name = getFileName(l);
|
||||
text_files_.emplace_back(ResourceTextFile(name, loadTextFile(l)));
|
||||
updateLoadingProgress();
|
||||
}
|
||||
}
|
||||
|
||||
// Carga las animaciones
|
||||
void Resource::loadAnimations() {
|
||||
std::cout << "\n>> ANIMATIONS" << std::endl;
|
||||
auto list = Asset::get()->getListByType(AssetType::ANIMATION);
|
||||
animations_.clear();
|
||||
|
||||
for (const auto& l : list) {
|
||||
auto name = getFileName(l);
|
||||
animations_.emplace_back(ResourceAnimation(name, loadAnimationsFromFile(l)));
|
||||
updateLoadingProgress();
|
||||
}
|
||||
}
|
||||
|
||||
// Carga los mapas de tiles
|
||||
void Resource::loadTileMaps() {
|
||||
std::cout << "\n>> TILE MAPS" << std::endl;
|
||||
auto list = Asset::get()->getListByType(AssetType::TILEMAP);
|
||||
tile_maps_.clear();
|
||||
|
||||
for (const auto& l : list) {
|
||||
auto name = getFileName(l);
|
||||
tile_maps_.emplace_back(ResourceTileMap(name, loadRoomTileFile(l)));
|
||||
printWithDots("TileMap : ", name, "[ LOADED ]");
|
||||
updateLoadingProgress();
|
||||
}
|
||||
}
|
||||
|
||||
// Carga las habitaciones
|
||||
void Resource::loadRooms() {
|
||||
std::cout << "\n>> ROOMS" << std::endl;
|
||||
auto list = Asset::get()->getListByType(AssetType::ROOM);
|
||||
rooms_.clear();
|
||||
|
||||
for (const auto& l : list) {
|
||||
auto name = getFileName(l);
|
||||
rooms_.emplace_back(ResourceRoom(name, std::make_shared<RoomData>(loadRoomFile(l))));
|
||||
printWithDots("Room : ", name, "[ LOADED ]");
|
||||
updateLoadingProgress();
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::createText() {
|
||||
struct ResourceInfo {
|
||||
std::string key; // Identificador del recurso
|
||||
std::string textureFile; // Nombre del archivo de textura
|
||||
std::string textFile; // Nombre del archivo de texto
|
||||
|
||||
// Constructor para facilitar la creación de objetos ResourceInfo
|
||||
ResourceInfo(const std::string& k, const std::string& tFile, const std::string& txtFile)
|
||||
: key(k),
|
||||
textureFile(tFile),
|
||||
textFile(txtFile) {}
|
||||
};
|
||||
|
||||
std::cout << "\n>> CREATING TEXT_OBJECTS" << std::endl;
|
||||
|
||||
std::vector<ResourceInfo> resources = {
|
||||
{"debug", "debug.gif", "debug.txt"},
|
||||
{"gauntlet", "gauntlet.gif", "gauntlet.txt"},
|
||||
{"smb2", "smb2.gif", "smb2.txt"},
|
||||
{"subatomic", "subatomic.gif", "subatomic.txt"},
|
||||
{"8bithud", "8bithud.gif", "8bithud.txt"}};
|
||||
|
||||
for (const auto& resource : resources) {
|
||||
texts_.emplace_back(ResourceText(resource.key, std::make_shared<Text>(getSurface(resource.textureFile), getTextFile(resource.textFile))));
|
||||
printWithDots("Text : ", resource.key, "[ DONE ]");
|
||||
}
|
||||
}
|
||||
|
||||
// Vacía el vector de sonidos
|
||||
void Resource::clearSounds() {
|
||||
// Itera sobre el vector y libera los recursos asociados a cada JA_Sound_t
|
||||
for (auto& sound : sounds_) {
|
||||
if (sound.sound) {
|
||||
JA_DeleteSound(sound.sound);
|
||||
sound.sound = nullptr;
|
||||
}
|
||||
}
|
||||
sounds_.clear(); // Limpia el vector después de liberar todos los recursos
|
||||
}
|
||||
|
||||
// Vacía el vector de musicas
|
||||
void Resource::clearMusics() {
|
||||
// Itera sobre el vector y libera los recursos asociados a cada JA_Music_t
|
||||
for (auto& music : musics_) {
|
||||
if (music.music) {
|
||||
JA_DeleteMusic(music.music);
|
||||
music.music = nullptr;
|
||||
}
|
||||
}
|
||||
musics_.clear(); // Limpia el vector después de liberar todos los recursos
|
||||
}
|
||||
|
||||
// Calcula el numero de recursos para cargar
|
||||
void Resource::calculateTotal() {
|
||||
std::vector<AssetType> assetTypes = {
|
||||
AssetType::SOUND,
|
||||
AssetType::MUSIC,
|
||||
AssetType::BITMAP,
|
||||
AssetType::PALETTE,
|
||||
AssetType::FONT,
|
||||
AssetType::ANIMATION,
|
||||
AssetType::TILEMAP,
|
||||
AssetType::ROOM};
|
||||
|
||||
size_t total = 0;
|
||||
for (const auto& assetType : assetTypes) {
|
||||
auto list = Asset::get()->getListByType(assetType);
|
||||
total += list.size();
|
||||
}
|
||||
|
||||
count_ = ResourceCount(total, 0);
|
||||
}
|
||||
|
||||
// Muestra el progreso de carga
|
||||
void Resource::renderProgress() {
|
||||
constexpr float X_PADDING = 10;
|
||||
constexpr float Y_PADDING = 10;
|
||||
constexpr float BAR_HEIGHT = 10;
|
||||
const float bar_position = options.game.height - BAR_HEIGHT - Y_PADDING;
|
||||
Screen::get()->start();
|
||||
Screen::get()->clearSurface(static_cast<Uint8>(PaletteColor::BLACK));
|
||||
|
||||
auto surface = Screen::get()->getRendererSurface();
|
||||
const float WIRED_BAR_WIDTH = options.game.width - (X_PADDING * 2);
|
||||
SDL_FRect rect_wired = {X_PADDING, bar_position, WIRED_BAR_WIDTH, X_PADDING};
|
||||
surface->drawRectBorder(&rect_wired, static_cast<Uint8>(PaletteColor::WHITE));
|
||||
|
||||
const float FULL_BAR_WIDTH = WIRED_BAR_WIDTH * count_.getPercentage();
|
||||
SDL_FRect rect_full = {X_PADDING, bar_position, FULL_BAR_WIDTH, X_PADDING};
|
||||
surface->fillRect(&rect_full, static_cast<Uint8>(PaletteColor::WHITE));
|
||||
|
||||
Screen::get()->render();
|
||||
}
|
||||
|
||||
// Comprueba los eventos de la pantalla de carga
|
||||
void Resource::checkEvents() {
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_EVENT_QUIT:
|
||||
exit(0);
|
||||
break;
|
||||
case SDL_EVENT_KEY_DOWN:
|
||||
if (event.key.key == SDLK_ESCAPE) {
|
||||
exit(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza el progreso de carga
|
||||
void Resource::updateLoadingProgress(int steps) {
|
||||
count_.add(1);
|
||||
if (count_.loaded % steps == 0 || count_.loaded == count_.total) {
|
||||
renderProgress();
|
||||
}
|
||||
checkEvents();
|
||||
}
|
||||
257
source/core/resources/resource.hpp
Normal file
257
source/core/resources/resource.hpp
Normal file
@@ -0,0 +1,257 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory> // Para shared_ptr
|
||||
#include <string> // Para string
|
||||
#include <vector> // Para vector
|
||||
|
||||
#include "game/gameplay/room.hpp" // Para room_t
|
||||
#include "core/rendering/surface_animated_sprite.hpp" // Para AnimationsFileBuffer
|
||||
#include "core/rendering/surface.hpp" // Para Surface
|
||||
#include "core/rendering/text.hpp" // Para Text, TextFile
|
||||
struct JA_Music_t; // lines 11-11
|
||||
struct JA_Sound_t; // lines 12-12
|
||||
|
||||
// Estructura para almacenar ficheros de sonido y su nombre
|
||||
struct ResourceSound {
|
||||
std::string name; // Nombre del sonido
|
||||
JA_Sound_t* sound; // Objeto con el sonido
|
||||
|
||||
// Constructor
|
||||
ResourceSound(const std::string& name, JA_Sound_t* sound)
|
||||
: name(name),
|
||||
sound(sound) {}
|
||||
};
|
||||
|
||||
// Estructura para almacenar ficheros musicales y su nombre
|
||||
struct ResourceMusic {
|
||||
std::string name; // Nombre de la musica
|
||||
JA_Music_t* music; // Objeto con la música
|
||||
|
||||
// Constructor
|
||||
ResourceMusic(const std::string& name, JA_Music_t* music)
|
||||
: name(name),
|
||||
music(music) {}
|
||||
};
|
||||
|
||||
// Estructura para almacenar objetos Surface y su nombre
|
||||
struct ResourceSurface {
|
||||
std::string name; // Nombre de la surface
|
||||
std::shared_ptr<Surface> surface; // Objeto con la surface
|
||||
|
||||
// Constructor
|
||||
ResourceSurface(const std::string& name, std::shared_ptr<Surface> surface)
|
||||
: name(name),
|
||||
surface(surface) {}
|
||||
};
|
||||
|
||||
// Estructura para almacenar objetos Palette y su nombre
|
||||
struct ResourcePalette {
|
||||
std::string name; // Nombre de la surface
|
||||
Palette palette; // Paleta
|
||||
|
||||
// Constructor
|
||||
ResourcePalette(const std::string& name, Palette palette)
|
||||
: name(name),
|
||||
palette(palette) {}
|
||||
};
|
||||
|
||||
// Estructura para almacenar ficheros TextFile y su nombre
|
||||
struct ResourceTextFile {
|
||||
std::string name; // Nombre del fichero
|
||||
std::shared_ptr<TextFile> text_file; // Objeto con los descriptores de la fuente de texto
|
||||
|
||||
// Constructor
|
||||
ResourceTextFile(const std::string& name, std::shared_ptr<TextFile> text_file)
|
||||
: name(name),
|
||||
text_file(text_file) {}
|
||||
};
|
||||
|
||||
// Estructura para almacenar objetos Text y su nombre
|
||||
struct ResourceText {
|
||||
std::string name; // Nombre del objeto
|
||||
std::shared_ptr<Text> text; // Objeto
|
||||
|
||||
// Constructor
|
||||
ResourceText(const std::string& name, std::shared_ptr<Text> text)
|
||||
: name(name),
|
||||
text(text) {}
|
||||
};
|
||||
|
||||
// Estructura para almacenar ficheros animaciones y su nombre
|
||||
struct ResourceAnimation {
|
||||
std::string name; // Nombre del fichero
|
||||
Animations animation; // Objeto con las animaciones
|
||||
|
||||
// Constructor
|
||||
ResourceAnimation(const std::string& name, const Animations& animation)
|
||||
: name(name),
|
||||
animation(animation) {}
|
||||
};
|
||||
|
||||
// Estructura para almacenar ficheros con el mapa de tiles de una habitación y su nombre
|
||||
struct ResourceTileMap {
|
||||
std::string name; // Nombre del mapa de tiles
|
||||
std::vector<int> tileMap; // Vector con los indices del mapa de tiles
|
||||
|
||||
// Constructor
|
||||
ResourceTileMap(const std::string& name, const std::vector<int>& tileMap)
|
||||
: name(name),
|
||||
tileMap(tileMap) {}
|
||||
};
|
||||
|
||||
// Estructura para almacenar habitaciones y su nombre
|
||||
struct ResourceRoom {
|
||||
std::string name; // Nombre de la habitación
|
||||
std::shared_ptr<RoomData> room; // Habitación
|
||||
|
||||
// Constructor
|
||||
ResourceRoom(const std::string& name, std::shared_ptr<RoomData> room)
|
||||
: name(name),
|
||||
room(room) {}
|
||||
};
|
||||
|
||||
// Estructura para llevar la cuenta de los recursos cargados
|
||||
struct ResourceCount {
|
||||
int total; // Número total de recursos
|
||||
int loaded; // Número de recursos cargados
|
||||
|
||||
// Constructor
|
||||
ResourceCount()
|
||||
: total(0),
|
||||
loaded(0) {}
|
||||
|
||||
// Constructor
|
||||
ResourceCount(int total, int loaded)
|
||||
: total(total),
|
||||
loaded(loaded) {}
|
||||
|
||||
// Añade una cantidad a los recursos cargados
|
||||
void add(int amount) {
|
||||
loaded += amount;
|
||||
}
|
||||
|
||||
// Obtiene el porcentaje de recursos cargados
|
||||
float getPercentage() {
|
||||
return static_cast<float>(loaded) / static_cast<float>(total);
|
||||
}
|
||||
};
|
||||
|
||||
class Resource {
|
||||
private:
|
||||
// [SINGLETON] Objeto resource privado para Don Melitón
|
||||
static Resource* resource_;
|
||||
|
||||
std::vector<ResourceSound> sounds_; // Vector con los sonidos
|
||||
std::vector<ResourceMusic> musics_; // Vector con las musicas
|
||||
std::vector<ResourceSurface> surfaces_; // Vector con las surfaces
|
||||
std::vector<ResourcePalette> palettes_; // Vector con las paletas
|
||||
std::vector<ResourceTextFile> text_files_; // Vector con los ficheros de texto
|
||||
std::vector<ResourceText> texts_; // Vector con los objetos de texto
|
||||
std::vector<ResourceAnimation> animations_; // Vector con las animaciones
|
||||
std::vector<ResourceTileMap> tile_maps_; // Vector con los mapas de tiles
|
||||
std::vector<ResourceRoom> rooms_; // Vector con las habitaciones
|
||||
|
||||
ResourceCount count_; // Contador de recursos
|
||||
|
||||
// Carga los sonidos
|
||||
void loadSounds();
|
||||
|
||||
// Carga las musicas
|
||||
void loadMusics();
|
||||
|
||||
// Carga las surfaces
|
||||
void loadSurfaces();
|
||||
|
||||
// Carga las paletas
|
||||
void loadPalettes();
|
||||
|
||||
// Carga los ficheros de texto
|
||||
void loadTextFiles();
|
||||
|
||||
// Carga las animaciones
|
||||
void loadAnimations();
|
||||
|
||||
// Carga los mapas de tiles
|
||||
void loadTileMaps();
|
||||
|
||||
// Carga las habitaciones
|
||||
void loadRooms();
|
||||
|
||||
// Crea los objetos de texto
|
||||
void createText();
|
||||
|
||||
// Vacia todos los vectores de recursos
|
||||
void clear();
|
||||
|
||||
// Carga todos los recursos
|
||||
void load();
|
||||
|
||||
// Vacía el vector de sonidos
|
||||
void clearSounds();
|
||||
|
||||
// Vacía el vector de musicas
|
||||
void clearMusics();
|
||||
|
||||
// Calcula el numero de recursos para cargar
|
||||
void calculateTotal();
|
||||
|
||||
// Muestra el progreso de carga
|
||||
void renderProgress();
|
||||
|
||||
// Comprueba los eventos
|
||||
void checkEvents();
|
||||
|
||||
// Actualiza el progreso de carga
|
||||
void updateLoadingProgress(int steps = 5);
|
||||
|
||||
// [SINGLETON] Ahora el constructor y el destructor son privados, para no poder crear objetos resource desde fuera
|
||||
|
||||
// Constructor
|
||||
Resource();
|
||||
|
||||
// Destructor
|
||||
~Resource() = default;
|
||||
|
||||
public:
|
||||
// [SINGLETON] Crearemos el objeto resource con esta función estática
|
||||
static void init();
|
||||
|
||||
// [SINGLETON] Destruiremos el objeto resource con esta función estática
|
||||
static void destroy();
|
||||
|
||||
// [SINGLETON] Con este método obtenemos el objeto resource y podemos trabajar con él
|
||||
static Resource* get();
|
||||
|
||||
// Obtiene el sonido a partir de un nombre
|
||||
JA_Sound_t* getSound(const std::string& name);
|
||||
|
||||
// Obtiene la música a partir de un nombre
|
||||
JA_Music_t* getMusic(const std::string& name);
|
||||
|
||||
// Obtiene la surface a partir de un nombre
|
||||
std::shared_ptr<Surface> getSurface(const std::string& name);
|
||||
|
||||
// Obtiene la paleta a partir de un nombre
|
||||
Palette getPalette(const std::string& name);
|
||||
|
||||
// Obtiene el fichero de texto a partir de un nombre
|
||||
std::shared_ptr<TextFile> getTextFile(const std::string& name);
|
||||
|
||||
// Obtiene el objeto de texto a partir de un nombre
|
||||
std::shared_ptr<Text> getText(const std::string& name);
|
||||
|
||||
// Obtiene la animación a partir de un nombre
|
||||
Animations& getAnimations(const std::string& name);
|
||||
|
||||
// Obtiene el mapa de tiles a partir de un nombre
|
||||
std::vector<int>& getTileMap(const std::string& name);
|
||||
|
||||
// Obtiene la habitación a partir de un nombre
|
||||
std::shared_ptr<RoomData> getRoom(const std::string& name);
|
||||
|
||||
// Obtiene todas las habitaciones
|
||||
std::vector<ResourceRoom>& getRooms();
|
||||
|
||||
// Recarga todos los recursos
|
||||
void reload();
|
||||
};
|
||||
Reference in New Issue
Block a user