merge: neteja cppcheck JDD
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <iostream> // Para basic_ostream, operator<<, cout, cerr
|
#include <iostream> // Para basic_ostream, operator<<, cout, cerr
|
||||||
#include <memory> // Para shared_ptr, __shared_ptr_access, allocator, operator==, make_shared
|
#include <memory> // Para shared_ptr, __shared_ptr_access, allocator, operator==, make_shared
|
||||||
|
#include <algorithm> // Para ranges::any_of
|
||||||
#include <ranges> // Para __find_if_fn, find_if
|
#include <ranges> // Para __find_if_fn, find_if
|
||||||
#include <unordered_map> // Para unordered_map, _Node_iterator, operator==, _Node_iterator_base, _Node_const_iterator
|
#include <unordered_map> // Para unordered_map, _Node_iterator, operator==, _Node_iterator_base, _Node_const_iterator
|
||||||
#include <utility> // Para pair, move
|
#include <utility> // Para pair, move
|
||||||
@@ -182,14 +183,10 @@ auto Input::checkAnyInput(bool check_keyboard, const std::shared_ptr<Gamepad>& g
|
|||||||
// Obtenemos el número total de acciones posibles para iterar sobre ellas.
|
// Obtenemos el número total de acciones posibles para iterar sobre ellas.
|
||||||
|
|
||||||
// --- Comprobación del Teclado ---
|
// --- Comprobación del Teclado ---
|
||||||
if (check_keyboard) {
|
// Llegim l'estat pre-calculat per Input::update() (sense tornar a cridar SDL_GetKeyboardState).
|
||||||
for (const auto& pair : keyboard_.bindings) {
|
if (check_keyboard && std::ranges::any_of(keyboard_.bindings,
|
||||||
// Simplemente leemos el estado pre-calculado por Input::update().
|
[](const auto& pair) { return pair.second.just_pressed; })) {
|
||||||
// Ya no se llama a SDL_GetKeyboardState ni se modifica el estado '.active'.
|
return true;
|
||||||
if (pair.second.just_pressed) {
|
|
||||||
return true; // Se encontró una acción recién pulsada.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si gamepad es nullptr pero hay mandos conectados, usar el primero
|
// Si gamepad es nullptr pero hay mandos conectados, usar el primero
|
||||||
@@ -199,15 +196,10 @@ auto Input::checkAnyInput(bool check_keyboard, const std::shared_ptr<Gamepad>& g
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- Comprobación del Mando ---
|
// --- Comprobación del Mando ---
|
||||||
// Comprobamos si hay mandos y si el índice solicitado es válido.
|
// Iterem sobre totes les accions del mandos pre-calculades per Input::update().
|
||||||
if (active_gamepad != nullptr) {
|
if (active_gamepad != nullptr && std::ranges::any_of(active_gamepad->bindings,
|
||||||
// Iteramos sobre todas las acciones, no sobre el número de mandos.
|
[](const auto& pair) { return pair.second.just_pressed; })) {
|
||||||
for (const auto& pair : active_gamepad->bindings) {
|
return true;
|
||||||
// Leemos el estado pre-calculado para el mando y la acción específicos.
|
|
||||||
if (pair.second.just_pressed) {
|
|
||||||
return true; // Se encontró una acción recién pulsada en el mando.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si llegamos hasta aquí, no se detectó ninguna nueva pulsación.
|
// Si llegamos hasta aquí, no se detectó ninguna nueva pulsación.
|
||||||
@@ -216,22 +208,14 @@ auto Input::checkAnyInput(bool check_keyboard, const std::shared_ptr<Gamepad>& g
|
|||||||
|
|
||||||
// Comprueba si hay algún botón pulsado
|
// Comprueba si hay algún botón pulsado
|
||||||
auto Input::checkAnyButton(bool repeat) -> bool { // NOLINT(readability-convert-member-functions-to-static)
|
auto Input::checkAnyButton(bool repeat) -> bool { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
// Solo comprueba los botones definidos previamente
|
return std::ranges::any_of(BUTTON_INPUTS, [&](auto bi) {
|
||||||
for (auto bi : BUTTON_INPUTS) {
|
|
||||||
// Comprueba el teclado
|
|
||||||
if (checkAction(bi, repeat, CHECK_KEYBOARD)) {
|
if (checkAction(bi, repeat, CHECK_KEYBOARD)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return std::ranges::any_of(gamepads_, [&](const auto& gamepad) {
|
||||||
// Comprueba los mandos
|
return checkAction(bi, repeat, DO_NOT_CHECK_KEYBOARD, gamepad);
|
||||||
for (const auto& gamepad : gamepads_) {
|
});
|
||||||
if (checkAction(bi, repeat, DO_NOT_CHECK_KEYBOARD, gamepad)) {
|
});
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba si hay algun mando conectado
|
// Comprueba si hay algun mando conectado
|
||||||
@@ -245,9 +229,9 @@ auto Input::getControllerName(const std::shared_ptr<Gamepad>& gamepad) -> std::s
|
|||||||
// Obtiene la lista de nombres de mandos
|
// Obtiene la lista de nombres de mandos
|
||||||
auto Input::getControllerNames() const -> std::vector<std::string> {
|
auto Input::getControllerNames() const -> std::vector<std::string> {
|
||||||
std::vector<std::string> names;
|
std::vector<std::string> names;
|
||||||
for (const auto& gamepad : gamepads_) {
|
names.reserve(gamepads_.size());
|
||||||
names.push_back(gamepad->name);
|
std::ranges::transform(gamepads_, std::back_inserter(names),
|
||||||
}
|
[](const auto& gamepad) { return gamepad->name; });
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,21 +240,15 @@ auto Input::getNumGamepads() const -> int { return gamepads_.size(); }
|
|||||||
|
|
||||||
// Obtiene el gamepad a partir de un event.id
|
// Obtiene el gamepad a partir de un event.id
|
||||||
auto Input::getGamepad(SDL_JoystickID id) const -> std::shared_ptr<Input::Gamepad> { // NOLINT(readability-convert-member-functions-to-static)
|
auto Input::getGamepad(SDL_JoystickID id) const -> std::shared_ptr<Input::Gamepad> { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
for (const auto& gamepad : gamepads_) {
|
auto it = std::ranges::find_if(gamepads_,
|
||||||
if (gamepad->instance_id == id) {
|
[id](const auto& gamepad) { return gamepad->instance_id == id; });
|
||||||
return gamepad;
|
return (it != gamepads_.end()) ? *it : nullptr;
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Input::getGamepadByName(const std::string& name) const -> std::shared_ptr<Input::Gamepad> { // NOLINT(readability-convert-member-functions-to-static)
|
auto Input::getGamepadByName(const std::string& name) const -> std::shared_ptr<Input::Gamepad> { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
for (const auto& gamepad : gamepads_) {
|
auto it = std::ranges::find_if(gamepads_,
|
||||||
if (gamepad && gamepad->name == name) {
|
[&name](const auto& gamepad) { return gamepad && gamepad->name == name; });
|
||||||
return gamepad;
|
return (it != gamepads_.end()) ? *it : nullptr;
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene el SDL_GamepadButton asignado a un action
|
// Obtiene el SDL_GamepadButton asignado a un action
|
||||||
@@ -511,19 +489,14 @@ auto Input::findAvailableGamepadByName(const std::string& gamepad_name) -> std::
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Buscar por nombre
|
// Buscar por nombre
|
||||||
for (const auto& gamepad : gamepads_) {
|
auto by_name = std::ranges::find_if(gamepads_,
|
||||||
if (gamepad && gamepad->name == gamepad_name) {
|
[&gamepad_name](const auto& gamepad) { return gamepad && gamepad->name == gamepad_name; });
|
||||||
return gamepad;
|
if (by_name != gamepads_.end()) {
|
||||||
}
|
return *by_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si no se encuentra por nombre, devolver el primer gamepad válido
|
// Si no se encuentra por nombre, devolver el primer gamepad válido
|
||||||
for (const auto& gamepad : gamepads_) {
|
auto first_valid = std::ranges::find_if(gamepads_,
|
||||||
if (gamepad) {
|
[](const auto& gamepad) { return static_cast<bool>(gamepad); });
|
||||||
return gamepad;
|
return (first_valid != gamepads_.end()) ? *first_valid : nullptr;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Si llegamos aquí, no hay gamepads válidos
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
@@ -120,9 +120,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Si quedan colores sin asignar, añadirlos al final
|
// Si quedan colores sin asignar, añadirlos al final
|
||||||
for (const auto& c : available) {
|
std::ranges::copy(available, std::back_inserter(result));
|
||||||
result.push_back(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
Palette out{};
|
Palette out{};
|
||||||
out.fill(0);
|
out.fill(0);
|
||||||
|
|||||||
@@ -415,7 +415,7 @@ static auto computeFadeDensity(int screen_y, int fade_h, int canvas_height) -> f
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Render amb dissolució als cantons superior/inferior (hash 2D, sense parpelleig)
|
// Render amb dissolució als cantons superior/inferior (hash 2D, sense parpelleig)
|
||||||
void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, SDL_FRect* src_rect) const {
|
void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, const SDL_FRect* src_rect) const {
|
||||||
const int SX = (src_rect != nullptr) ? static_cast<int>(src_rect->x) : 0;
|
const int SX = (src_rect != nullptr) ? static_cast<int>(src_rect->x) : 0;
|
||||||
const int SY = (src_rect != nullptr) ? static_cast<int>(src_rect->y) : 0;
|
const int SY = (src_rect != nullptr) ? static_cast<int>(src_rect->y) : 0;
|
||||||
const int SW = (src_rect != nullptr) ? static_cast<int>(src_rect->w) : surface_data_->width;
|
const int SW = (src_rect != nullptr) ? static_cast<int>(src_rect->w) : surface_data_->width;
|
||||||
@@ -452,7 +452,7 @@ void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Idem però reemplaçant un color índex
|
// Idem però reemplaçant un color índex
|
||||||
void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, Uint8 source_color, Uint8 target_color, SDL_FRect* src_rect) const {
|
void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, Uint8 source_color, Uint8 target_color, const SDL_FRect* src_rect) const {
|
||||||
const int SX = (src_rect != nullptr) ? static_cast<int>(src_rect->x) : 0;
|
const int SX = (src_rect != nullptr) ? static_cast<int>(src_rect->x) : 0;
|
||||||
const int SY = (src_rect != nullptr) ? static_cast<int>(src_rect->y) : 0;
|
const int SY = (src_rect != nullptr) ? static_cast<int>(src_rect->y) : 0;
|
||||||
const int SW = (src_rect != nullptr) ? static_cast<int>(src_rect->w) : surface_data_->width;
|
const int SW = (src_rect != nullptr) ? static_cast<int>(src_rect->w) : surface_data_->width;
|
||||||
|
|||||||
@@ -87,10 +87,10 @@ class Surface {
|
|||||||
void renderWithColorReplace(int x, int y, Uint8 source_color = 0, Uint8 target_color = 0, SDL_FRect* src_rect = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE) const;
|
void renderWithColorReplace(int x, int y, Uint8 source_color = 0, Uint8 target_color = 0, SDL_FRect* src_rect = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE) const;
|
||||||
|
|
||||||
// Render amb dissolució als cantons superior/inferior (hash 2D, sense parpelleig)
|
// Render amb dissolució als cantons superior/inferior (hash 2D, sense parpelleig)
|
||||||
void renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, SDL_FRect* src_rect = nullptr) const;
|
void renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, const SDL_FRect* src_rect = nullptr) const;
|
||||||
|
|
||||||
// Idem però reemplaçant un color índex (per a sprites sobre fons del mateix color)
|
// Idem però reemplaçant un color índex (per a sprites sobre fons del mateix color)
|
||||||
void renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, Uint8 source_color, Uint8 target_color, SDL_FRect* src_rect = nullptr) const;
|
void renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, Uint8 source_color, Uint8 target_color, const SDL_FRect* src_rect = nullptr) const;
|
||||||
|
|
||||||
// Establece un color en la paleta
|
// Establece un color en la paleta
|
||||||
void setColor(int index, Uint32 color);
|
void setColor(int index, Uint32 color);
|
||||||
|
|||||||
@@ -362,13 +362,13 @@ namespace Resource {
|
|||||||
return rooms_;
|
return rooms_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper para lanzar errores de carga con formato consistente
|
// Helper para registrar errores de carga con formato consistente.
|
||||||
[[noreturn]] void Cache::throwLoadError(const std::string& asset_type, const std::string& file_path, const std::exception& e) { // NOLINT(readability-convert-member-functions-to-static)
|
// El rethrow es responsabilitat del catch que crida la funció.
|
||||||
|
void Cache::logLoadError(const std::string& asset_type, const std::string& file_path, const std::exception& e) { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
std::cerr << "\n[ ERROR ] Failed to load " << asset_type << ": " << getFileName(file_path) << '\n';
|
std::cerr << "\n[ ERROR ] Failed to load " << asset_type << ": " << getFileName(file_path) << '\n';
|
||||||
std::cerr << "[ ERROR ] Path: " << file_path << '\n';
|
std::cerr << "[ ERROR ] Path: " << file_path << '\n';
|
||||||
std::cerr << "[ ERROR ] Reason: " << e.what() << '\n';
|
std::cerr << "[ ERROR ] Reason: " << e.what() << '\n';
|
||||||
std::cerr << "[ ERROR ] Check config/assets.yaml configuration\n";
|
std::cerr << "[ ERROR ] Check config/assets.yaml configuration\n";
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lista fija de text objects. Compartida entre createText() y createOneText(i).
|
// Lista fija de text objects. Compartida entre createText() y createOneText(i).
|
||||||
@@ -415,7 +415,8 @@ namespace Resource {
|
|||||||
printWithDots("Sound : ", name, "[ LOADED ]");
|
printWithDots("Sound : ", name, "[ LOADED ]");
|
||||||
updateLoadingProgress();
|
updateLoadingProgress();
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
throwLoadError("SOUND", l, e);
|
logLoadError("SOUND", l, e);
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,7 +443,8 @@ namespace Resource {
|
|||||||
printWithDots("Music : ", name, "[ LOADED ]");
|
printWithDots("Music : ", name, "[ LOADED ]");
|
||||||
updateLoadingProgress();
|
updateLoadingProgress();
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
throwLoadError("MUSIC", l, e);
|
logLoadError("MUSIC", l, e);
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,7 +458,8 @@ namespace Resource {
|
|||||||
surfaces_.back().surface->setTransparentColor(0);
|
surfaces_.back().surface->setTransparentColor(0);
|
||||||
updateLoadingProgress();
|
updateLoadingProgress();
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
throwLoadError("BITMAP", l, e);
|
logLoadError("BITMAP", l, e);
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,7 +483,8 @@ namespace Resource {
|
|||||||
palettes_.emplace_back(ResourcePalette{.name = name, .palette = readPalFile(l)});
|
palettes_.emplace_back(ResourcePalette{.name = name, .palette = readPalFile(l)});
|
||||||
updateLoadingProgress();
|
updateLoadingProgress();
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
throwLoadError("PALETTE", l, e);
|
logLoadError("PALETTE", l, e);
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,7 +497,8 @@ namespace Resource {
|
|||||||
text_files_.emplace_back(TextFileResource{.name = name, .text_file = Text::loadTextFile(l)});
|
text_files_.emplace_back(TextFileResource{.name = name, .text_file = Text::loadTextFile(l)});
|
||||||
updateLoadingProgress();
|
updateLoadingProgress();
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
throwLoadError("FONT", l, e);
|
logLoadError("FONT", l, e);
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -513,7 +518,8 @@ namespace Resource {
|
|||||||
printWithDots("Animation : ", name, "[ LOADED ]");
|
printWithDots("Animation : ", name, "[ LOADED ]");
|
||||||
updateLoadingProgress();
|
updateLoadingProgress();
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
throwLoadError("ANIMATION", l, e);
|
logLoadError("ANIMATION", l, e);
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,7 +533,8 @@ namespace Resource {
|
|||||||
printWithDots("Room : ", name, "[ LOADED ]");
|
printWithDots("Room : ", name, "[ LOADED ]");
|
||||||
updateLoadingProgress();
|
updateLoadingProgress();
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
throwLoadError("ROOM", l, e);
|
logLoadError("ROOM", l, e);
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ namespace Resource {
|
|||||||
void setCurrentLoading(const std::string& name); // Desa el nom del recurs en curs
|
void setCurrentLoading(const std::string& name); // Desa el nom del recurs en curs
|
||||||
|
|
||||||
// Helper para mensajes de error de carga
|
// Helper para mensajes de error de carga
|
||||||
[[noreturn]] static void throwLoadError(const std::string& asset_type, const std::string& file_path, const std::exception& e);
|
static void logLoadError(const std::string& asset_type, const std::string& file_path, const std::exception& e);
|
||||||
|
|
||||||
// Constructor y destructor
|
// Constructor y destructor
|
||||||
Cache();
|
Cache();
|
||||||
|
|||||||
@@ -75,11 +75,11 @@ namespace Resource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Buscar la última entrada con el mismo prefijo de ruta e insertar después
|
// Buscar la última entrada con el mismo prefijo de ruta e insertar después
|
||||||
std::string entry = " - " + var_path + "\n";
|
|
||||||
auto last_pos = content.rfind(var_path.substr(0, var_path.rfind('/')));
|
auto last_pos = content.rfind(var_path.substr(0, var_path.rfind('/')));
|
||||||
if (last_pos != std::string::npos) {
|
if (last_pos != std::string::npos) {
|
||||||
auto end_of_line = content.find('\n', last_pos);
|
auto end_of_line = content.find('\n', last_pos);
|
||||||
if (end_of_line != std::string::npos) {
|
if (end_of_line != std::string::npos) {
|
||||||
|
std::string entry = " - " + var_path + "\n";
|
||||||
content.insert(end_of_line + 1, entry);
|
content.insert(end_of_line + 1, entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <SDL3/SDL_filesystem.h>
|
#include <SDL3/SDL_filesystem.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <numeric>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -14,11 +15,10 @@ namespace Resource {
|
|||||||
|
|
||||||
// Calculate CRC32 checksum for data verification
|
// Calculate CRC32 checksum for data verification
|
||||||
auto Pack::calculateChecksum(const std::vector<uint8_t>& data) -> uint32_t { // NOLINT(readability-convert-member-functions-to-static)
|
auto Pack::calculateChecksum(const std::vector<uint8_t>& data) -> uint32_t { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
uint32_t checksum = 0x12345678;
|
return std::accumulate(data.begin(), data.end(), uint32_t{0x12345678},
|
||||||
for (unsigned char byte : data) {
|
[](uint32_t acc, unsigned char byte) -> uint32_t {
|
||||||
checksum = ((checksum << 5) + checksum) + byte;
|
return ((acc << 5) + acc) + byte;
|
||||||
}
|
});
|
||||||
return checksum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// XOR encryption (symmetric - same function for encrypt/decrypt)
|
// XOR encryption (symmetric - same function for encrypt/decrypt)
|
||||||
|
|||||||
@@ -45,21 +45,24 @@
|
|||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Constructor
|
namespace {
|
||||||
Director::Director() {
|
auto getExecutablePath() -> std::string {
|
||||||
std::cout << "Game start" << '\n';
|
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
// En Emscripten els assets estan al root del filesystem virtual (/data, /config)
|
// En Emscripten els assets estan al root del filesystem virtual (/data, /config)
|
||||||
executable_path_ = "";
|
return "";
|
||||||
#else
|
#else
|
||||||
// Obtiene la ruta del ejecutable
|
std::string base = SDL_GetBasePath();
|
||||||
std::string base = SDL_GetBasePath();
|
if (!base.empty() && base.back() == '/') {
|
||||||
if (!base.empty() && base.back() == '/') {
|
base.pop_back();
|
||||||
base.pop_back();
|
}
|
||||||
}
|
return base;
|
||||||
executable_path_ = base;
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
Director::Director() : executable_path_(getExecutablePath()) {
|
||||||
|
std::cout << "Game start" << '\n';
|
||||||
|
|
||||||
// Crea la carpeta del sistema donde guardar datos
|
// Crea la carpeta del sistema donde guardar datos
|
||||||
createSystemFolder("jailgames");
|
createSystemFolder("jailgames");
|
||||||
|
|||||||
@@ -15,13 +15,10 @@
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
EditorStatusBar::EditorStatusBar(std::string room_number, std::string room_name)
|
EditorStatusBar::EditorStatusBar(std::string room_number, std::string room_name)
|
||||||
: room_number_(std::move(room_number)),
|
: surface_(std::make_shared<Surface>(Options::game.width, 6.0F * Tile::SIZE)),
|
||||||
|
surface_dest_{.x = 0, .y = Options::game.height - (6.0F * Tile::SIZE), .w = Options::game.width, .h = 6.0F * Tile::SIZE},
|
||||||
|
room_number_(std::move(room_number)),
|
||||||
room_name_(std::move(room_name)) {
|
room_name_(std::move(room_name)) {
|
||||||
const float SURFACE_WIDTH = Options::game.width;
|
|
||||||
constexpr float SURFACE_HEIGHT = 6.0F * Tile::SIZE; // 48 pixels, igual que el scoreboard
|
|
||||||
|
|
||||||
surface_ = std::make_shared<Surface>(SURFACE_WIDTH, SURFACE_HEIGHT);
|
|
||||||
surface_dest_ = {.x = 0, .y = Options::game.height - SURFACE_HEIGHT, .w = SURFACE_WIDTH, .h = SURFACE_HEIGHT};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pinta la barra de estado en pantalla
|
// Pinta la barra de estado en pantalla
|
||||||
|
|||||||
@@ -876,7 +876,7 @@ void MapEditor::updateStatusBarInfo() { // NOLINT(readability-function-cognitiv
|
|||||||
const auto& e = room_data_.enemies[selected_enemy_];
|
const auto& e = room_data_.enemies[selected_enemy_];
|
||||||
std::string anim = e.animation_path;
|
std::string anim = e.animation_path;
|
||||||
auto dot = anim.rfind('.');
|
auto dot = anim.rfind('.');
|
||||||
if (dot != std::string::npos) { anim = anim.substr(0, dot); }
|
if (dot != std::string::npos) { anim.resize(dot); }
|
||||||
|
|
||||||
line2 = "enemy " + std::to_string(selected_enemy_) + ": " + anim + " " + e.color;
|
line2 = "enemy " + std::to_string(selected_enemy_) + ": " + anim + " " + e.color;
|
||||||
line3 = "vx:" + std::to_string(static_cast<int>(e.vx)) +
|
line3 = "vx:" + std::to_string(static_cast<int>(e.vx)) +
|
||||||
@@ -1278,7 +1278,7 @@ auto MapEditor::createNewRoom(const std::string& direction) -> std::string { //
|
|||||||
|
|
||||||
// Comprobar que no hay ya una room en esa dirección
|
// Comprobar que no hay ya una room en esa dirección
|
||||||
if (!direction.empty()) {
|
if (!direction.empty()) {
|
||||||
std::string* existing = nullptr;
|
const std::string* existing = nullptr;
|
||||||
if (direction == "UP") {
|
if (direction == "UP") {
|
||||||
existing = &room_data_.upper_room;
|
existing = &room_data_.upper_room;
|
||||||
} else if (direction == "DOWN") {
|
} else if (direction == "DOWN") {
|
||||||
@@ -1294,7 +1294,7 @@ auto MapEditor::createNewRoom(const std::string& direction) -> std::string { //
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Encontrar el primer número libre (reutiliza huecos)
|
// Encontrar el primer número libre (reutiliza huecos)
|
||||||
auto& rooms = Resource::Cache::get()->getRooms();
|
const auto& rooms = Resource::Cache::get()->getRooms();
|
||||||
std::set<int> used;
|
std::set<int> used;
|
||||||
for (const auto& r : rooms) {
|
for (const auto& r : rooms) {
|
||||||
try {
|
try {
|
||||||
@@ -1425,11 +1425,11 @@ auto MapEditor::deleteRoom() -> std::string { // NOLINT(readability-function-co
|
|||||||
|
|
||||||
if (target == "0") {
|
if (target == "0") {
|
||||||
// Buscar la primera room que no sea esta
|
// Buscar la primera room que no sea esta
|
||||||
for (const auto& r : Resource::Cache::get()->getRooms()) {
|
const auto& rooms = Resource::Cache::get()->getRooms();
|
||||||
if (r.name != deleted_name) {
|
auto it = std::ranges::find_if(rooms,
|
||||||
target = r.name;
|
[&deleted_name](const auto& r) { return r.name != deleted_name; });
|
||||||
break;
|
if (it != rooms.end()) {
|
||||||
}
|
target = it->name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (target == "0") { return "Cannot delete: no other room to navigate to"; }
|
if (target == "0") { return "Cannot delete: no other room to navigate to"; }
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ void MiniMap::buildTileColorTable(const std::string& tileset_name) {
|
|||||||
|
|
||||||
// Posiciona las rooms en un grid usando BFS desde las conexiones
|
// Posiciona las rooms en un grid usando BFS desde las conexiones
|
||||||
void MiniMap::layoutRooms() {
|
void MiniMap::layoutRooms() {
|
||||||
auto& rooms = Resource::Cache::get()->getRooms();
|
const auto& rooms = Resource::Cache::get()->getRooms();
|
||||||
if (rooms.empty()) { return; }
|
if (rooms.empty()) { return; }
|
||||||
|
|
||||||
// Mapa de nombre → Room::Data
|
// Mapa de nombre → Room::Data
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ Cheevos::~Cheevos() {
|
|||||||
// Inicializa los logros
|
// Inicializa los logros
|
||||||
void Cheevos::init() { // NOLINT(readability-convert-member-functions-to-static)
|
void Cheevos::init() { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
cheevos_list_.clear();
|
cheevos_list_.clear();
|
||||||
auto* loc = Locale::get();
|
const auto* loc = Locale::get();
|
||||||
cheevos_list_.emplace_back(Achievement{.id = 1, .caption = loc->get("achievements.c1"), .description = loc->get("achievements.d1"), .icon = 2});
|
cheevos_list_.emplace_back(Achievement{.id = 1, .caption = loc->get("achievements.c1"), .description = loc->get("achievements.d1"), .icon = 2});
|
||||||
cheevos_list_.emplace_back(Achievement{.id = 2, .caption = loc->get("achievements.c2"), .description = loc->get("achievements.d2"), .icon = 2});
|
cheevos_list_.emplace_back(Achievement{.id = 2, .caption = loc->get("achievements.c2"), .description = loc->get("achievements.d2"), .icon = 2});
|
||||||
cheevos_list_.emplace_back(Achievement{.id = 3, .caption = loc->get("achievements.c3"), .description = loc->get("achievements.d3"), .icon = 2});
|
cheevos_list_.emplace_back(Achievement{.id = 3, .caption = loc->get("achievements.c3"), .description = loc->get("achievements.d3"), .icon = 2});
|
||||||
|
|||||||
@@ -108,32 +108,23 @@ auto CollisionMap::getSlopeHeight(SDL_FPoint p, Tile slope) -> int {
|
|||||||
|
|
||||||
// Comprueba las colisiones con paredes derechas
|
// Comprueba las colisiones con paredes derechas
|
||||||
auto CollisionMap::checkRightSurfaces(const SDL_FRect& rect) -> int { // NOLINT(readability-convert-member-functions-to-static)
|
auto CollisionMap::checkRightSurfaces(const SDL_FRect& rect) -> int { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
for (const auto& s : right_walls_) {
|
auto it = std::ranges::find_if(right_walls_,
|
||||||
if (checkCollision(s, rect)) {
|
[&rect](const auto& s) { return checkCollision(s, rect); });
|
||||||
return s.x;
|
return (it != right_walls_.end()) ? it->x : Collision::NONE;
|
||||||
}
|
|
||||||
}
|
|
||||||
return Collision::NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones con paredes izquierdas
|
// Comprueba las colisiones con paredes izquierdas
|
||||||
auto CollisionMap::checkLeftSurfaces(const SDL_FRect& rect) -> int { // NOLINT(readability-convert-member-functions-to-static)
|
auto CollisionMap::checkLeftSurfaces(const SDL_FRect& rect) -> int { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
for (const auto& s : left_walls_) {
|
auto it = std::ranges::find_if(left_walls_,
|
||||||
if (checkCollision(s, rect)) {
|
[&rect](const auto& s) { return checkCollision(s, rect); });
|
||||||
return s.x;
|
return (it != left_walls_.end()) ? it->x : Collision::NONE;
|
||||||
}
|
|
||||||
}
|
|
||||||
return Collision::NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones con techos
|
// Comprueba las colisiones con techos
|
||||||
auto CollisionMap::checkTopSurfaces(const SDL_FRect& rect) -> int { // NOLINT(readability-convert-member-functions-to-static)
|
auto CollisionMap::checkTopSurfaces(const SDL_FRect& rect) -> int { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
for (const auto& s : top_floors_) {
|
auto it = std::ranges::find_if(top_floors_,
|
||||||
if (checkCollision(s, rect)) {
|
[&rect](const auto& s) { return checkCollision(s, rect); });
|
||||||
return s.y;
|
return (it != top_floors_.end()) ? it->y : Collision::NONE;
|
||||||
}
|
|
||||||
}
|
|
||||||
return Collision::NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones punto con techos
|
// Comprueba las colisiones punto con techos
|
||||||
@@ -145,22 +136,16 @@ auto CollisionMap::checkTopSurfaces(const SDL_FPoint& p) -> bool {
|
|||||||
|
|
||||||
// Comprueba las colisiones con suelos
|
// Comprueba las colisiones con suelos
|
||||||
auto CollisionMap::checkBottomSurfaces(const SDL_FRect& rect) -> int { // NOLINT(readability-convert-member-functions-to-static)
|
auto CollisionMap::checkBottomSurfaces(const SDL_FRect& rect) -> int { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
for (const auto& s : bottom_floors_) {
|
auto it = std::ranges::find_if(bottom_floors_,
|
||||||
if (checkCollision(s, rect)) {
|
[&rect](const auto& s) { return checkCollision(s, rect); });
|
||||||
return s.y;
|
return (it != bottom_floors_.end()) ? it->y : Collision::NONE;
|
||||||
}
|
|
||||||
}
|
|
||||||
return Collision::NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones con conveyor belts
|
// Comprueba las colisiones con conveyor belts
|
||||||
auto CollisionMap::checkAutoSurfaces(const SDL_FRect& rect) -> int { // NOLINT(readability-convert-member-functions-to-static)
|
auto CollisionMap::checkAutoSurfaces(const SDL_FRect& rect) -> int { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
for (const auto& s : conveyor_belt_floors_) {
|
auto it = std::ranges::find_if(conveyor_belt_floors_,
|
||||||
if (checkCollision(s, rect)) {
|
[&rect](const auto& s) { return checkCollision(s, rect); });
|
||||||
return s.y;
|
return (it != conveyor_belt_floors_.end()) ? it->y : Collision::NONE;
|
||||||
}
|
|
||||||
}
|
|
||||||
return Collision::NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones punto con conveyor belts
|
// Comprueba las colisiones punto con conveyor belts
|
||||||
@@ -208,18 +193,16 @@ auto CollisionMap::checkRightSlopes(const SDL_FPoint& p) -> bool {
|
|||||||
|
|
||||||
// Obtiene puntero a slope en un punto (prioriza left_slopes_ sobre right_slopes_)
|
// Obtiene puntero a slope en un punto (prioriza left_slopes_ sobre right_slopes_)
|
||||||
auto CollisionMap::getSlopeAtPoint(const SDL_FPoint& p) const -> const LineDiagonal* { // NOLINT(readability-convert-member-functions-to-static)
|
auto CollisionMap::getSlopeAtPoint(const SDL_FPoint& p) const -> const LineDiagonal* { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
// Primero busca en rampas izquierdas
|
auto pred = [&p](const auto& slope) { return static_cast<bool>(checkCollision(p, slope)); };
|
||||||
for (const auto& slope : left_slopes_) {
|
|
||||||
if (checkCollision(p, slope)) {
|
auto left_it = std::ranges::find_if(left_slopes_, pred);
|
||||||
return &slope;
|
if (left_it != left_slopes_.end()) {
|
||||||
}
|
return &(*left_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Luego busca en rampas derechas
|
auto right_it = std::ranges::find_if(right_slopes_, pred);
|
||||||
for (const auto& slope : right_slopes_) {
|
if (right_it != right_slopes_.end()) {
|
||||||
if (checkCollision(p, slope)) {
|
return &(*right_it);
|
||||||
return &slope;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// No hay colisión con ninguna slope
|
// No hay colisión con ninguna slope
|
||||||
|
|||||||
@@ -44,9 +44,7 @@ auto RoomLoader::flattenTilemap(const std::vector<std::vector<int>>& tilemap_2d)
|
|||||||
tilemap_flat.reserve(512); // 16 rows × 32 cols
|
tilemap_flat.reserve(512); // 16 rows × 32 cols
|
||||||
|
|
||||||
for (const auto& row : tilemap_2d) {
|
for (const auto& row : tilemap_2d) {
|
||||||
for (int tile : row) {
|
std::ranges::copy(row, std::back_inserter(tilemap_flat));
|
||||||
tilemap_flat.push_back(tile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tilemap_flat;
|
return tilemap_flat;
|
||||||
@@ -135,12 +133,9 @@ void RoomLoader::parseTilemap(const fkyaml::node& yaml, Room::Data& room, const
|
|||||||
for (const auto& row_node : tilemap_node) {
|
for (const auto& row_node : tilemap_node) {
|
||||||
std::vector<int> row;
|
std::vector<int> row;
|
||||||
row.reserve(32);
|
row.reserve(32);
|
||||||
|
std::ranges::transform(row_node, std::back_inserter(row),
|
||||||
for (const auto& tile_node : row_node) {
|
[](const auto& tile_node) { return tile_node.template get_value<int>(); });
|
||||||
row.push_back(tile_node.get_value<int>());
|
tilemap_2d.push_back(std::move(row));
|
||||||
}
|
|
||||||
|
|
||||||
tilemap_2d.push_back(row);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to 1D flat array
|
// Convert to 1D flat array
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ Scoreboard::Scoreboard(std::shared_ptr<Data> data)
|
|||||||
|
|
||||||
// Inicializa el vector de colores
|
// Inicializa el vector de colores
|
||||||
const std::vector<std::string> COLORS = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"};
|
const std::vector<std::string> COLORS = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"};
|
||||||
for (const auto& color : COLORS) {
|
color_.reserve(COLORS.size());
|
||||||
color_.push_back(stringToColor(color));
|
std::ranges::transform(COLORS, std::back_inserter(color_),
|
||||||
}
|
[](const auto& color) { return stringToColor(color); });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pinta el objeto en pantalla
|
// Pinta el objeto en pantalla
|
||||||
|
|||||||
@@ -15,9 +15,8 @@ TilemapRenderer::TilemapRenderer(std::vector<int> tile_map, int tile_set_width,
|
|||||||
tile_set_width_(tile_set_width),
|
tile_set_width_(tile_set_width),
|
||||||
tileset_surface_(std::move(tileset_surface)),
|
tileset_surface_(std::move(tileset_surface)),
|
||||||
bg_color_(std::move(bg_color)),
|
bg_color_(std::move(bg_color)),
|
||||||
conveyor_belt_direction_(conveyor_belt_direction) {
|
conveyor_belt_direction_(conveyor_belt_direction),
|
||||||
// Crear la surface del mapa
|
map_surface_(std::make_shared<Surface>(PlayArea::WIDTH, PlayArea::HEIGHT)) {
|
||||||
map_surface_ = std::make_shared<Surface>(PlayArea::WIDTH, PlayArea::HEIGHT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inicializa el renderizador
|
// Inicializa el renderizador
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ void Credits::handleInput() {
|
|||||||
|
|
||||||
// Inicializa los textos
|
// Inicializa los textos
|
||||||
void Credits::iniTexts() { // NOLINT(readability-convert-member-functions-to-static)
|
void Credits::iniTexts() { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
auto* loc = Locale::get();
|
const auto* loc = Locale::get();
|
||||||
|
|
||||||
texts_.clear();
|
texts_.clear();
|
||||||
texts_.push_back({.label = "", .color = static_cast<Uint8>(PaletteColor::WHITE)});
|
texts_.push_back({.label = "", .color = static_cast<Uint8>(PaletteColor::WHITE)});
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ void Ending::updateState(float delta_time) {
|
|||||||
void Ending::iniTexts() { // NOLINT(readability-convert-member-functions-to-static)
|
void Ending::iniTexts() { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
// Vector con los textos (traducidos según el idioma activo)
|
// Vector con los textos (traducidos según el idioma activo)
|
||||||
std::vector<TextAndPosition> texts;
|
std::vector<TextAndPosition> texts;
|
||||||
auto* loc = Locale::get();
|
const auto* loc = Locale::get();
|
||||||
|
|
||||||
// Escena #0
|
// Escena #0
|
||||||
texts.push_back({.caption = loc->get("ending.t0"), .pos = 32});
|
texts.push_back({.caption = loc->get("ending.t0"), .pos = 32});
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ Ending2::Ending2()
|
|||||||
|
|
||||||
// Inicializa el vector de colores
|
// Inicializa el vector de colores
|
||||||
const std::vector<std::string> COLORS = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
|
const std::vector<std::string> COLORS = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
|
||||||
for (const auto& color : COLORS) {
|
colors_.reserve(COLORS.size());
|
||||||
colors_.push_back(stringToColor(color));
|
std::ranges::transform(COLORS, std::back_inserter(colors_),
|
||||||
}
|
[](const auto& color) { return stringToColor(color); });
|
||||||
|
|
||||||
Screen::get()->setBorderColor(static_cast<Uint8>(PaletteColor::BLACK)); // Cambia el color del borde
|
Screen::get()->setBorderColor(static_cast<Uint8>(PaletteColor::BLACK)); // Cambia el color del borde
|
||||||
iniSpriteList(); // Inicializa la lista de sprites
|
iniSpriteList(); // Inicializa la lista de sprites
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <cmath> // Para std::sqrt, std::min
|
#include <cmath> // Para std::sqrt, std::min
|
||||||
|
#include <numeric> // Para std::accumulate
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
@@ -865,14 +866,9 @@ auto Game::checkEndGame() -> bool {
|
|||||||
|
|
||||||
// Obtiene la cantidad total de items que hay en el mapeado del juego
|
// Obtiene la cantidad total de items que hay en el mapeado del juego
|
||||||
auto Game::getTotalItems() -> int {
|
auto Game::getTotalItems() -> int {
|
||||||
int items = 0;
|
const auto& rooms = Resource::Cache::get()->getRooms();
|
||||||
auto rooms = Resource::Cache::get()->getRooms();
|
return static_cast<int>(std::accumulate(rooms.begin(), rooms.end(), size_t{0},
|
||||||
|
[](size_t acc, const auto& room) { return acc + room.room->items.size(); }));
|
||||||
for (const auto& room : rooms) {
|
|
||||||
items += room.room->items.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
return items;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pone el juego en pausa
|
// Pone el juego en pausa
|
||||||
|
|||||||
@@ -38,9 +38,9 @@ GameOver::GameOver()
|
|||||||
|
|
||||||
// Inicializa el vector de colores (de brillante a oscuro para fade)
|
// Inicializa el vector de colores (de brillante a oscuro para fade)
|
||||||
const std::vector<std::string> COLORS = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
|
const std::vector<std::string> COLORS = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
|
||||||
for (const auto& color : COLORS) {
|
colors_.reserve(COLORS.size());
|
||||||
colors_.push_back(stringToColor(color));
|
std::ranges::transform(COLORS, std::back_inserter(colors_),
|
||||||
}
|
[](const auto& color) { return stringToColor(color); });
|
||||||
color_ = colors_.back(); // Empieza en black
|
color_ = colors_.back(); // Empieza en black
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ void GameOver::render() {
|
|||||||
auto text = Resource::Cache::get()->getText("smb2");
|
auto text = Resource::Cache::get()->getText("smb2");
|
||||||
|
|
||||||
// Escribe el texto de GAME OVER
|
// Escribe el texto de GAME OVER
|
||||||
auto* loc = Locale::get();
|
const auto* loc = Locale::get();
|
||||||
text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GameCanvas::CENTER_X, TEXT_Y, loc->get("game_over.title"), 1, color_); // NOLINT(readability-static-accessed-through-instance)
|
text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GameCanvas::CENTER_X, TEXT_Y, loc->get("game_over.title"), 1, color_); // NOLINT(readability-static-accessed-through-instance)
|
||||||
|
|
||||||
// Dibuja los sprites (ya posicionados en el constructor, solo ajustamos Y)
|
// Dibuja los sprites (ya posicionados en el constructor, solo ajustamos Y)
|
||||||
|
|||||||
@@ -259,9 +259,8 @@ void Logo::initColors() { // NOLINT(readability-convert-member-functions-to-sta
|
|||||||
static_cast<Uint8>(PaletteColor::CYAN),
|
static_cast<Uint8>(PaletteColor::CYAN),
|
||||||
static_cast<Uint8>(PaletteColor::YELLOW),
|
static_cast<Uint8>(PaletteColor::YELLOW),
|
||||||
static_cast<Uint8>(PaletteColor::BRIGHT_WHITE)};
|
static_cast<Uint8>(PaletteColor::BRIGHT_WHITE)};
|
||||||
for (const auto& color : COLORS) {
|
color_.reserve(COLORS.size());
|
||||||
color_.push_back(color);
|
std::ranges::copy(COLORS, std::back_inserter(color_));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crea los sprites de cada linea
|
// Crea los sprites de cada linea
|
||||||
|
|||||||
@@ -544,7 +544,7 @@ void Title::renderMainMenu() {
|
|||||||
const int TOTAL_HEIGHT = 3 * SPACING; // 3 espacios entre 4 items
|
const int TOTAL_HEIGHT = 3 * SPACING; // 3 espacios entre 4 items
|
||||||
const int START_Y = MENU_CENTER_Y - (TOTAL_HEIGHT / 2);
|
const int START_Y = MENU_CENTER_Y - (TOTAL_HEIGHT / 2);
|
||||||
|
|
||||||
auto* loc = Locale::get();
|
const auto* loc = Locale::get();
|
||||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y, loc->get("title.menu.play"), 1, COLOR);
|
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y, loc->get("title.menu.play"), 1, COLOR);
|
||||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y + SPACING, loc->get("title.menu.keyboard"), 1, COLOR);
|
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y + SPACING, loc->get("title.menu.keyboard"), 1, COLOR);
|
||||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y + (2 * SPACING), loc->get("title.menu.joystick"), 1, COLOR);
|
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y + (2 * SPACING), loc->get("title.menu.joystick"), 1, COLOR);
|
||||||
@@ -652,19 +652,6 @@ auto Title::isKeyDuplicate(SDL_Scancode scancode, int current_step) -> bool { /
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Retorna el nombre de la accion para el paso actual
|
// Retorna el nombre de la accion para el paso actual
|
||||||
auto Title::getActionName(int step) -> std::string { // NOLINT(readability-convert-member-functions-to-static)
|
|
||||||
switch (step) {
|
|
||||||
case 0:
|
|
||||||
return "LEFT";
|
|
||||||
case 1:
|
|
||||||
return "RIGHT";
|
|
||||||
case 2:
|
|
||||||
return "JUMP";
|
|
||||||
default:
|
|
||||||
return "UNKNOWN";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aplica y guarda las teclas redefinidas
|
// Aplica y guarda las teclas redefinidas
|
||||||
void Title::applyKeyboardRemap() { // NOLINT(readability-convert-member-functions-to-static)
|
void Title::applyKeyboardRemap() { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
// Guardar las nuevas teclas en Options::controls
|
// Guardar las nuevas teclas en Options::controls
|
||||||
@@ -696,7 +683,7 @@ void Title::renderKeyboardRemap() const {
|
|||||||
const int START_Y = MENU_CENTER_Y - (2 * TEXT_SIZE); // Centrado aproximado
|
const int START_Y = MENU_CENTER_Y - (2 * TEXT_SIZE); // Centrado aproximado
|
||||||
|
|
||||||
// Mensaje principal: "PRESS KEY FOR [ACTION]" o "KEYS DEFINED" si completado
|
// Mensaje principal: "PRESS KEY FOR [ACTION]" o "KEYS DEFINED" si completado
|
||||||
auto* loc = Locale::get();
|
const auto* loc = Locale::get();
|
||||||
if (remap_step_ >= 3) {
|
if (remap_step_ >= 3) {
|
||||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y, loc->get("title.keys.defined"), 1, COLOR);
|
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y, loc->get("title.keys.defined"), 1, COLOR);
|
||||||
} else {
|
} else {
|
||||||
@@ -744,7 +731,7 @@ void Title::renderJoystickRemap() const {
|
|||||||
const int START_Y = MENU_CENTER_Y - (2 * TEXT_SIZE); // Centrado aproximado
|
const int START_Y = MENU_CENTER_Y - (2 * TEXT_SIZE); // Centrado aproximado
|
||||||
|
|
||||||
// Mensaje principal: "PRESS BUTTON FOR [ACTION]" o "BUTTONS DEFINED" si completado
|
// Mensaje principal: "PRESS BUTTON FOR [ACTION]" o "BUTTONS DEFINED" si completado
|
||||||
auto* loc = Locale::get();
|
const auto* loc = Locale::get();
|
||||||
if (remap_step_ >= 3) {
|
if (remap_step_ >= 3) {
|
||||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y, loc->get("title.buttons.defined"), 1, COLOR);
|
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y, loc->get("title.buttons.defined"), 1, COLOR);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -88,7 +88,6 @@ class Title : public Scene {
|
|||||||
auto isButtonDuplicate(int button, int current_step) -> bool; // Valida si un boton esta duplicado
|
auto isButtonDuplicate(int button, int current_step) -> bool; // Valida si un boton esta duplicado
|
||||||
void applyKeyboardRemap(); // Aplica y guarda las teclas redefinidas
|
void applyKeyboardRemap(); // Aplica y guarda las teclas redefinidas
|
||||||
void applyJoystickRemap(); // Aplica y guarda los botones del gamepad redefinidos
|
void applyJoystickRemap(); // Aplica y guarda los botones del gamepad redefinidos
|
||||||
static auto getActionName(int step) -> std::string; // Retorna el nombre de la accion (LEFT/RIGHT/JUMP)
|
|
||||||
static auto getButtonName(int button) -> std::string; // Retorna el nombre amigable del boton del gamepad
|
static auto getButtonName(int button) -> std::string; // Retorna el nombre amigable del boton del gamepad
|
||||||
void createCheevosTexture(); // Crea y rellena la surface para mostrar los logros
|
void createCheevosTexture(); // Crea y rellena la surface para mostrar los logros
|
||||||
void resetCheevosScroll(); // Resetea el scroll de la lista de logros
|
void resetCheevosScroll(); // Resetea el scroll de la lista de logros
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <algorithm> // Para ranges::transform
|
#include <algorithm> // Para ranges::transform
|
||||||
|
#include <numeric> // Para std::accumulate
|
||||||
#include <cctype> // Para toupper
|
#include <cctype> // Para toupper
|
||||||
#include <sstream> // Para std::istringstream
|
#include <sstream> // Para std::istringstream
|
||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
@@ -181,8 +182,8 @@ void Console::update(float delta_time) { // NOLINT(readability-function-cogniti
|
|||||||
|
|
||||||
// Efecto typewriter: revelar letras una a una (solo cuando ACTIVE)
|
// Efecto typewriter: revelar letras una a una (solo cuando ACTIVE)
|
||||||
if (status_ == Status::ACTIVE) {
|
if (status_ == Status::ACTIVE) {
|
||||||
int total_chars = 0;
|
const int total_chars = std::accumulate(msg_lines_.begin(), msg_lines_.end(), 0,
|
||||||
for (const auto& line : msg_lines_) { total_chars += static_cast<int>(line.size()); }
|
[](int acc, const auto& line) { return acc + static_cast<int>(line.size()); });
|
||||||
if (typewriter_chars_ < total_chars) {
|
if (typewriter_chars_ < total_chars) {
|
||||||
typewriter_timer_ += delta_time;
|
typewriter_timer_ += delta_time;
|
||||||
while (typewriter_timer_ >= TYPEWRITER_CHAR_DELAY && typewriter_chars_ < total_chars) {
|
while (typewriter_timer_ >= TYPEWRITER_CHAR_DELAY && typewriter_chars_ < total_chars) {
|
||||||
@@ -337,11 +338,9 @@ void Console::handleEvent(const SDL_Event& event) { // NOLINT(readability-funct
|
|||||||
const size_t SPACE_POS = upper.rfind(' ');
|
const size_t SPACE_POS = upper.rfind(' ');
|
||||||
if (SPACE_POS == std::string::npos) {
|
if (SPACE_POS == std::string::npos) {
|
||||||
// Modo comando: ciclar keywords visibles que empiecen por el prefijo
|
// Modo comando: ciclar keywords visibles que empiecen por el prefijo
|
||||||
for (const auto& kw : registry_.getVisibleKeywords()) {
|
const auto KEYWORDS = registry_.getVisibleKeywords();
|
||||||
if (upper.empty() || kw.starts_with(upper)) {
|
std::ranges::copy_if(KEYWORDS, std::back_inserter(tab_matches_),
|
||||||
tab_matches_.emplace_back(kw);
|
[&upper](const auto& kw) { return upper.empty() || kw.starts_with(upper); });
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
const std::string BASE_CMD = upper.substr(0, SPACE_POS);
|
const std::string BASE_CMD = upper.substr(0, SPACE_POS);
|
||||||
const std::string SUB_PREFIX = upper.substr(SPACE_POS + 1);
|
const std::string SUB_PREFIX = upper.substr(SPACE_POS + 1);
|
||||||
@@ -357,7 +356,8 @@ void Console::handleEvent(const SDL_Event& event) { // NOLINT(readability-funct
|
|||||||
if (tab_matches_.empty()) { break; }
|
if (tab_matches_.empty()) { break; }
|
||||||
tab_index_ = (tab_index_ + 1) % static_cast<int>(tab_matches_.size());
|
tab_index_ = (tab_index_ + 1) % static_cast<int>(tab_matches_.size());
|
||||||
std::string result = tab_matches_[static_cast<size_t>(tab_index_)];
|
std::string result = tab_matches_[static_cast<size_t>(tab_index_)];
|
||||||
for (char& c : result) { c = static_cast<char>(std::tolower(static_cast<unsigned char>(c))); }
|
std::ranges::transform(result, result.begin(),
|
||||||
|
[](char c) { return static_cast<char>(std::tolower(static_cast<unsigned char>(c))); });
|
||||||
input_line_ = result;
|
input_line_ = result;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -403,9 +403,8 @@ void Console::processCommand() {
|
|||||||
|
|
||||||
// Typewriter: instantáneo si el comando lo requiere, letra a letra si no
|
// Typewriter: instantáneo si el comando lo requiere, letra a letra si no
|
||||||
if (instant) {
|
if (instant) {
|
||||||
int total = 0;
|
typewriter_chars_ = std::accumulate(msg_lines_.begin(), msg_lines_.end(), 0,
|
||||||
for (const auto& l : msg_lines_) { total += static_cast<int>(l.size()); }
|
[](int acc, const auto& l) { return acc + static_cast<int>(l.size()); });
|
||||||
typewriter_chars_ = total;
|
|
||||||
} else {
|
} else {
|
||||||
typewriter_chars_ = 0;
|
typewriter_chars_ = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
// Toggle genérico para comandos booleanos ON/OFF (reemplaza macro BOOL_TOGGLE_CMD)
|
// Toggle genérico para comandos booleanos ON/OFF (reemplaza macro BOOL_TOGGLE_CMD)
|
||||||
static auto boolToggle(
|
static auto boolToggle(
|
||||||
const std::string& label,
|
const std::string& label,
|
||||||
bool& option,
|
const bool& option,
|
||||||
const std::function<void()>& toggle_fn,
|
const std::function<void()>& toggle_fn,
|
||||||
const std::vector<std::string>& args) -> std::string {
|
const std::vector<std::string>& args) -> std::string {
|
||||||
if (args.empty()) {
|
if (args.empty()) {
|
||||||
@@ -836,13 +836,12 @@ static auto cmdCheat(const std::vector<std::string>& args) -> std::string { //
|
|||||||
if (args.size() < 2 || args[1] != "LIVES") { return "usage: cheat infinite lives [on|off]"; }
|
if (args.size() < 2 || args[1] != "LIVES") { return "usage: cheat infinite lives [on|off]"; }
|
||||||
auto& cheat = Options::cheats.infinite_lives;
|
auto& cheat = Options::cheats.infinite_lives;
|
||||||
using State = Options::Cheat::State;
|
using State = Options::Cheat::State;
|
||||||
const std::vector<std::string> REST(args.begin() + 2, args.end());
|
if (args.size() == 2) {
|
||||||
if (REST.empty()) {
|
|
||||||
cheat = (cheat == State::ENABLED) ? State::DISABLED : State::ENABLED;
|
cheat = (cheat == State::ENABLED) ? State::DISABLED : State::ENABLED;
|
||||||
} else if (REST[0] == "ON") {
|
} else if (args[2] == "ON") {
|
||||||
if (cheat == State::ENABLED) { return "Infinite lives already ON"; }
|
if (cheat == State::ENABLED) { return "Infinite lives already ON"; }
|
||||||
cheat = State::ENABLED;
|
cheat = State::ENABLED;
|
||||||
} else if (REST[0] == "OFF") {
|
} else if (args[2] == "OFF") {
|
||||||
if (cheat == State::DISABLED) { return "Infinite lives already OFF"; }
|
if (cheat == State::DISABLED) { return "Infinite lives already OFF"; }
|
||||||
cheat = State::DISABLED;
|
cheat = State::DISABLED;
|
||||||
} else {
|
} else {
|
||||||
@@ -1013,9 +1012,9 @@ void CommandRegistry::registerHandlers() { // NOLINT(readability-function-cogni
|
|||||||
dynamic_providers_["PALETTE"] = []() -> std::vector<std::string> {
|
dynamic_providers_["PALETTE"] = []() -> std::vector<std::string> {
|
||||||
std::vector<std::string> result = {"NEXT", "PREV", "SORT", "DEFAULT"};
|
std::vector<std::string> result = {"NEXT", "PREV", "SORT", "DEFAULT"};
|
||||||
if (Screen::get() != nullptr) {
|
if (Screen::get() != nullptr) {
|
||||||
for (const auto& name : Screen::get()->getPaletteNames()) {
|
const auto NAMES = Screen::get()->getPaletteNames();
|
||||||
result.push_back(toUpper(name));
|
std::ranges::transform(NAMES, std::back_inserter(result),
|
||||||
}
|
[](const auto& name) { return toUpper(name); });
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
@@ -1024,10 +1023,11 @@ void CommandRegistry::registerHandlers() { // NOLINT(readability-function-cogni
|
|||||||
dynamic_providers_["SHADER PRESET"] = []() -> std::vector<std::string> {
|
dynamic_providers_["SHADER PRESET"] = []() -> std::vector<std::string> {
|
||||||
std::vector<std::string> result = {"NEXT", "PREV"};
|
std::vector<std::string> result = {"NEXT", "PREV"};
|
||||||
const bool IS_CRTPI = Options::video.shader.current_shader == Rendering::ShaderType::CRTPI;
|
const bool IS_CRTPI = Options::video.shader.current_shader == Rendering::ShaderType::CRTPI;
|
||||||
|
auto upper_name = [](const auto& p) { return toUpper(p.name); };
|
||||||
if (IS_CRTPI) {
|
if (IS_CRTPI) {
|
||||||
for (const auto& p : Options::crtpi_presets) { result.push_back(toUpper(p.name)); }
|
std::ranges::transform(Options::crtpi_presets, std::back_inserter(result), upper_name);
|
||||||
} else {
|
} else {
|
||||||
for (const auto& p : Options::postfx_presets) { result.push_back(toUpper(p.name)); }
|
std::ranges::transform(Options::postfx_presets, std::back_inserter(result), upper_name);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
@@ -1068,7 +1068,7 @@ void CommandRegistry::registerHandlers() { // NOLINT(readability-function-cogni
|
|||||||
if (path.find("enemies") == std::string::npos) { continue; }
|
if (path.find("enemies") == std::string::npos) { continue; }
|
||||||
std::string name = getFileName(path);
|
std::string name = getFileName(path);
|
||||||
auto dot = name.rfind('.');
|
auto dot = name.rfind('.');
|
||||||
if (dot != std::string::npos) { name = name.substr(0, dot); }
|
if (dot != std::string::npos) { name.resize(dot); }
|
||||||
result.push_back(toUpper(name));
|
result.push_back(toUpper(name));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -1082,7 +1082,7 @@ void CommandRegistry::registerHandlers() { // NOLINT(readability-function-cogni
|
|||||||
if (path.find("tilesets") == std::string::npos) { continue; }
|
if (path.find("tilesets") == std::string::npos) { continue; }
|
||||||
std::string name = getFileName(path);
|
std::string name = getFileName(path);
|
||||||
auto dot = name.rfind('.');
|
auto dot = name.rfind('.');
|
||||||
if (dot != std::string::npos) { name = name.substr(0, dot); }
|
if (dot != std::string::npos) { name.resize(dot); }
|
||||||
result.push_back(toUpper(name));
|
result.push_back(toUpper(name));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -1120,7 +1120,8 @@ void CommandRegistry::load(const std::string& yaml_path) { // NOLINT(readabilit
|
|||||||
if (cat_node.contains("scope")) {
|
if (cat_node.contains("scope")) {
|
||||||
const auto& scope_node = cat_node["scope"];
|
const auto& scope_node = cat_node["scope"];
|
||||||
if (scope_node.is_sequence()) {
|
if (scope_node.is_sequence()) {
|
||||||
for (const auto& s : scope_node) { cat_scopes.push_back(s.get_value<std::string>()); }
|
std::ranges::transform(scope_node, std::back_inserter(cat_scopes),
|
||||||
|
[](const auto& s) { return s.template get_value<std::string>(); });
|
||||||
} else {
|
} else {
|
||||||
cat_scopes.push_back(scope_node.get_value<std::string>());
|
cat_scopes.push_back(scope_node.get_value<std::string>());
|
||||||
}
|
}
|
||||||
@@ -1161,9 +1162,8 @@ void CommandRegistry::load(const std::string& yaml_path) { // NOLINT(readabilit
|
|||||||
for (auto it = completions_node.begin(); it != completions_node.end(); ++it) {
|
for (auto it = completions_node.begin(); it != completions_node.end(); ++it) {
|
||||||
auto path = it.key().get_value<std::string>();
|
auto path = it.key().get_value<std::string>();
|
||||||
std::vector<std::string> opts;
|
std::vector<std::string> opts;
|
||||||
for (const auto& opt : *it) {
|
std::ranges::transform(*it, std::back_inserter(opts),
|
||||||
opts.push_back(opt.get_value<std::string>());
|
[](const auto& opt) { return opt.template get_value<std::string>(); });
|
||||||
}
|
|
||||||
def.completions[path] = std::move(opts);
|
def.completions[path] = std::move(opts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1182,9 +1182,8 @@ void CommandRegistry::load(const std::string& yaml_path) { // NOLINT(readabilit
|
|||||||
for (auto it = extras_completions.begin(); it != extras_completions.end(); ++it) {
|
for (auto it = extras_completions.begin(); it != extras_completions.end(); ++it) {
|
||||||
auto path = it.key().get_value<std::string>();
|
auto path = it.key().get_value<std::string>();
|
||||||
std::vector<std::string> opts;
|
std::vector<std::string> opts;
|
||||||
for (const auto& opt : *it) {
|
std::ranges::transform(*it, std::back_inserter(opts),
|
||||||
opts.push_back(opt.get_value<std::string>());
|
[](const auto& opt) { return opt.template get_value<std::string>(); });
|
||||||
}
|
|
||||||
def.completions[path] = std::move(opts);
|
def.completions[path] = std::move(opts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1237,10 +1236,9 @@ void CommandRegistry::load(const std::string& yaml_path) { // NOLINT(readabilit
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto CommandRegistry::findCommand(const std::string& keyword) const -> const CommandDef* {
|
auto CommandRegistry::findCommand(const std::string& keyword) const -> const CommandDef* {
|
||||||
for (const auto& cmd : commands_) {
|
auto it = std::ranges::find_if(commands_,
|
||||||
if (cmd.keyword == keyword) { return &cmd; }
|
[&keyword](const auto& cmd) { return cmd.keyword == keyword; });
|
||||||
}
|
return (it != commands_.end()) ? &(*it) : nullptr;
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CommandRegistry::execute(const std::string& keyword, const std::vector<std::string>& args) const -> std::string {
|
auto CommandRegistry::execute(const std::string& keyword, const std::vector<std::string>& args) const -> std::string {
|
||||||
@@ -1331,7 +1329,7 @@ auto CommandRegistry::getCompletions(const std::string& path) const -> std::vect
|
|||||||
if (!active_scope_.empty()) {
|
if (!active_scope_.empty()) {
|
||||||
std::string root = path;
|
std::string root = path;
|
||||||
auto space = root.find(' ');
|
auto space = root.find(' ');
|
||||||
if (space != std::string::npos) { root = root.substr(0, space); }
|
if (space != std::string::npos) { root.resize(space); }
|
||||||
const auto* cmd = findCommand(root);
|
const auto* cmd = findCommand(root);
|
||||||
if (cmd != nullptr && !isCommandVisible(*cmd)) { return {}; }
|
if (cmd != nullptr && !isCommandVisible(*cmd)) { return {}; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -306,8 +306,7 @@ auto Notifier::getVisibleHeight() const -> int {
|
|||||||
auto Notifier::getCodes() -> std::vector<std::string> {
|
auto Notifier::getCodes() -> std::vector<std::string> {
|
||||||
std::vector<std::string> codes;
|
std::vector<std::string> codes;
|
||||||
codes.reserve(notifications_.size());
|
codes.reserve(notifications_.size());
|
||||||
for (const auto& notification : notifications_) {
|
std::ranges::transform(notifications_, std::back_inserter(codes),
|
||||||
codes.emplace_back(notification.code);
|
[](const auto& notification) { return notification.code; });
|
||||||
}
|
|
||||||
return codes;
|
return codes;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user