diff --git a/CMakeLists.txt b/CMakeLists.txt index 975433c..5ac9f63 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,9 @@ set(APP_SOURCES source/core/jail/jgame.cpp source/core/jail/jinput.cpp + # Core - Locale (nova capa) + source/core/locale/locale.cpp + # Core - Capa de presentación (nueva) source/core/rendering/menu.cpp source/core/rendering/overlay.cpp diff --git a/data/locale/ca.yaml b/data/locale/ca.yaml new file mode 100644 index 0000000..60bb41f --- /dev/null +++ b/data/locale/ca.yaml @@ -0,0 +1,68 @@ +# Aventures En Egipte — Textos en Valencià (idioma per defecte) +# Edita aquest fitxer per canviar els textos del joc. +# Les claus es referencien des del codi amb notació punt: "menu.titles.root" + +menu: + titles: + root: "OPCIONS" + video: "VIDEO" + audio: "AUDIO" + controls: "CONTROLS" + + items: + video: "VIDEO" + audio: "AUDIO" + controls: "CONTROLS" + zoom: "ZOOM" + screen: "PANTALLA" + shader: "SHADER" + aspect_4_3: "ASPECTE 4:3" + supersampling: "SUPERSAMPLING" + shader_type: "TIPUS SHADER" + preset: "PRESET" + stretch_filter: "FILTRE 4:3" + render_info: "RENDER INFO" + uptime: "TEMPS DE JOC" + master_enable: "AUDIO" + master_volume: "MASTER" + music: "MUSICA" + music_volume: "VOL MUSICA" + sounds: "SONS" + sounds_volume: "VOL SONS" + move_up: "MOU AMUNT" + move_down: "MOU AVALL" + move_left: "MOU ESQUERRA" + move_right: "MOU DRETA" + menu_key: "TECLA MENU" + + values: + "yes": "SI" + "no": "NO" + "on": "ON" + "off": "OFF" + fullscreen: "COMPLETA" + windowed: "FINESTRA" + linear: "LINEAR" + nearest: "NEAREST" + top: "TOP" + bottom: "BOTTOM" + press_key: "" + empty: "(BUIT)" + unknown: "---" + +notifications: + exit_double_esc: "TORNA A PULSAR ESC PER EIXIR" + zoom_fmt: "ZOOM %dX" + fullscreen: "PANTALLA COMPLETA" + windowed: "FINESTRA" + shader_on: "SHADER ON" + shader_off: "SHADER OFF" + aspect_43: "4:3 CRT" + aspect_square: "PIXELS QUADRATS" + ss_on: "SUPERSAMPLING ON" + ss_off: "SUPERSAMPLING OFF" + preset_fmt: "PRESET: %s" + filter_linear: "FILTRE: LINEAR" + filter_nearest: "FILTRE: NEAREST" + pause: "PAUSA" + resume: "REPRES" diff --git a/source/core/input/global_inputs.cpp b/source/core/input/global_inputs.cpp index c347b9b..ca556dc 100644 --- a/source/core/input/global_inputs.cpp +++ b/source/core/input/global_inputs.cpp @@ -4,6 +4,7 @@ #include #include "core/jail/jinput.hpp" +#include "core/locale/locale.hpp" #include "core/rendering/overlay.hpp" #include "core/rendering/screen.hpp" #include "game/options.hpp" @@ -29,7 +30,7 @@ namespace GlobalInputs { if (dec_zoom && !dec_zoom_prev) { Screen::get()->decZoom(); char msg[32]; - snprintf(msg, sizeof(msg), "ZOOM %dx", Screen::get()->getZoom()); + snprintf(msg, sizeof(msg), Locale::get("notifications.zoom_fmt"), Screen::get()->getZoom()); Overlay::showNotification(msg); } if (dec_zoom) consumed = true; @@ -40,7 +41,7 @@ namespace GlobalInputs { if (inc_zoom && !inc_zoom_prev) { Screen::get()->incZoom(); char msg[32]; - snprintf(msg, sizeof(msg), "ZOOM %dx", Screen::get()->getZoom()); + snprintf(msg, sizeof(msg), Locale::get("notifications.zoom_fmt"), Screen::get()->getZoom()); Overlay::showNotification(msg); } if (inc_zoom) consumed = true; @@ -50,7 +51,7 @@ namespace GlobalInputs { bool fullscreen = JI_KeyPressed(Options::keys_gui.fullscreen); if (fullscreen && !fullscreen_prev) { Screen::get()->toggleFullscreen(); - Overlay::showNotification(Screen::get()->isFullscreen() ? "PANTALLA COMPLETA" : "FINESTRA"); + Overlay::showNotification(Screen::get()->isFullscreen() ? Locale::get("notifications.fullscreen") : Locale::get("notifications.windowed")); } if (fullscreen) consumed = true; fullscreen_prev = fullscreen; @@ -59,7 +60,7 @@ namespace GlobalInputs { bool shader = JI_KeyPressed(Options::keys_gui.toggle_shader); if (shader && !shader_prev) { Screen::get()->toggleShaders(); - Overlay::showNotification(Options::video.shader_enabled ? "SHADER ON" : "SHADER OFF"); + Overlay::showNotification(Options::video.shader_enabled ? Locale::get("notifications.shader_on") : Locale::get("notifications.shader_off")); } if (shader) consumed = true; shader_prev = shader; @@ -68,7 +69,7 @@ namespace GlobalInputs { bool aspect = JI_KeyPressed(Options::keys_gui.toggle_aspect_ratio); if (aspect && !aspect_prev) { Screen::get()->toggleAspectRatio(); - Overlay::showNotification(Options::video.aspect_ratio_4_3 ? "4:3 CRT" : "PIXELS QUADRATS"); + Overlay::showNotification(Options::video.aspect_ratio_4_3 ? Locale::get("notifications.aspect_43") : Locale::get("notifications.aspect_square")); } if (aspect) consumed = true; aspect_prev = aspect; @@ -77,7 +78,7 @@ namespace GlobalInputs { bool ss = JI_KeyPressed(Options::keys_gui.toggle_supersampling); if (ss && !ss_prev) { Screen::get()->toggleSupersampling(); - Overlay::showNotification(Options::video.supersampling ? "SUPERSAMPLING ON" : "SUPERSAMPLING OFF"); + Overlay::showNotification(Options::video.supersampling ? Locale::get("notifications.ss_on") : Locale::get("notifications.ss_off")); } if (ss) consumed = true; ss_prev = ss; @@ -98,7 +99,7 @@ namespace GlobalInputs { if (next_preset && !next_preset_prev) { Screen::get()->nextPreset(); char msg[64]; - snprintf(msg, sizeof(msg), "PRESET: %s", Screen::get()->getCurrentPresetName()); + snprintf(msg, sizeof(msg), Locale::get("notifications.preset_fmt"), Screen::get()->getCurrentPresetName()); Overlay::showNotification(msg); } if (next_preset) consumed = true; @@ -108,7 +109,7 @@ namespace GlobalInputs { bool stretch_filter = JI_KeyPressed(Options::keys_gui.toggle_stretch_filter); if (stretch_filter && !stretch_filter_prev) { Screen::get()->toggleStretchFilter(); - Overlay::showNotification(Options::video.stretch_filter_linear ? "FILTRE: LINEAR" : "FILTRE: NEAREST"); + Overlay::showNotification(Options::video.stretch_filter_linear ? Locale::get("notifications.filter_linear") : Locale::get("notifications.filter_nearest")); } if (stretch_filter) consumed = true; stretch_filter_prev = stretch_filter; diff --git a/source/core/locale/locale.cpp b/source/core/locale/locale.cpp new file mode 100644 index 0000000..d908721 --- /dev/null +++ b/source/core/locale/locale.cpp @@ -0,0 +1,57 @@ +#include "core/locale/locale.hpp" + +#include +#include +#include + +#include "core/jail/jfile.hpp" +#include "external/fkyaml_node.hpp" + +namespace Locale { + + static std::unordered_map strings_; + + // Aplana un node YAML en claus amb notació punt + static void traverse(const fkyaml::node& node, const std::string& prefix) { + if (node.is_mapping()) { + for (auto it = node.begin(); it != node.end(); ++it) { + std::string key = it.key().get_value(); + std::string full = prefix.empty() ? key : prefix + "." + key; + traverse(it.value(), full); + } + } else if (node.is_scalar()) { + try { + strings_[prefix] = node.get_value(); + } catch (...) {} + } + } + + bool load(const char* filename) { + int size = 0; + char* buffer = file_getfilebuffer(filename, size, true); + if (!buffer || size <= 0) { + std::cerr << "Locale: unable to load " << filename << '\n'; + return false; + } + std::string content(buffer, size); + free(buffer); + + try { + auto yaml = fkyaml::node::deserialize(content); + strings_.clear(); + traverse(yaml, ""); + std::cout << "Locale loaded: " << strings_.size() << " string(s) from " << filename << '\n'; + return true; + } catch (const fkyaml::exception& e) { + std::cerr << "Locale: error parsing " << filename << ": " << e.what() << '\n'; + return false; + } + } + + auto get(const char* key) -> const char* { + auto it = strings_.find(key); + if (it != strings_.end()) return it->second.c_str(); + return key; // fallback: retorna la clau mateixa + } + +} // namespace Locale diff --git a/source/core/locale/locale.hpp b/source/core/locale/locale.hpp new file mode 100644 index 0000000..cbe8da6 --- /dev/null +++ b/source/core/locale/locale.hpp @@ -0,0 +1,12 @@ +#pragma once + +// Locale: carrega cadenes de text des d'un fitxer YAML i les exposa per clau. +// Les claus són nested amb notació punt ("menu.items.zoom"). +// Si una clau no existeix, Locale::get torna la clau mateixa (útil per debug). +namespace Locale { + bool load(const char* filename); + + // Retorna la cadena associada a la clau. El punter és estable durant tota la + // sessió (no canvia), per tant es pot guardar en const char*. + auto get(const char* key) -> const char*; +} // namespace Locale diff --git a/source/core/rendering/menu.cpp b/source/core/rendering/menu.cpp index 041c378..445401d 100644 --- a/source/core/rendering/menu.cpp +++ b/source/core/rendering/menu.cpp @@ -6,6 +6,7 @@ #include #include +#include "core/locale/locale.hpp" #include "core/rendering/overlay.hpp" #include "core/rendering/screen.hpp" #include "core/rendering/text.hpp" @@ -92,8 +93,8 @@ namespace Menu { // --- Helpers --- - static std::string yesNo(bool b) { return b ? "SI" : "NO"; } - static std::string onOff(bool b) { return b ? "ON" : "OFF"; } + static std::string yesNo(bool b) { return b ? Locale::get("menu.values.yes") : Locale::get("menu.values.no"); } + static std::string onOff(bool b) { return b ? Locale::get("menu.values.on") : Locale::get("menu.values.off"); } // --- Builders de pàgines --- @@ -102,50 +103,65 @@ namespace Menu { static Page buildControls(); static Page buildRoot() { - Page p{"OPCIONS", {}, 0}; - p.items.push_back({"VIDEO", ItemKind::Submenu, nullptr, nullptr, [] { pushPage(buildVideo()); }, nullptr}); - p.items.push_back({"AUDIO", ItemKind::Submenu, nullptr, nullptr, [] { pushPage(buildAudio()); }, nullptr}); - p.items.push_back({"CONTROLS", ItemKind::Submenu, nullptr, nullptr, [] { pushPage(buildControls()); }, nullptr}); + Page p{Locale::get("menu.titles.root"), {}, 0}; + p.items.push_back({Locale::get("menu.items.video"), ItemKind::Submenu, nullptr, nullptr, [] { pushPage(buildVideo()); }, nullptr}); + p.items.push_back({Locale::get("menu.items.audio"), ItemKind::Submenu, nullptr, nullptr, [] { pushPage(buildAudio()); }, nullptr}); + p.items.push_back({Locale::get("menu.items.controls"), ItemKind::Submenu, nullptr, nullptr, [] { pushPage(buildControls()); }, nullptr}); return p; } static Page buildVideo() { - Page p{"VIDEO", {}, 0}; + Page p{Locale::get("menu.titles.video"), {}, 0}; - p.items.push_back({"ZOOM", ItemKind::IntRange, [] { + p.items.push_back({Locale::get("menu.items.zoom"), ItemKind::IntRange, [] { char buf[16]; std::snprintf(buf, sizeof(buf), "%dX", Screen::get()->getZoom()); return std::string(buf); }, [](int dir) { if (dir < 0) Screen::get()->decZoom(); else if (dir > 0) Screen::get()->incZoom(); }, nullptr}); - p.items.push_back({"PANTALLA", ItemKind::Toggle, [] { return std::string(Screen::get()->isFullscreen() ? "COMPLETA" : "FINESTRA"); }, [](int) { Screen::get()->toggleFullscreen(); }, nullptr}); + p.items.push_back({Locale::get("menu.items.screen"), ItemKind::Toggle, + [] { return std::string(Screen::get()->isFullscreen() ? Locale::get("menu.values.fullscreen") : Locale::get("menu.values.windowed")); }, + [](int) { Screen::get()->toggleFullscreen(); }, nullptr}); - p.items.push_back({"SHADER", ItemKind::Toggle, [] { return onOff(Options::video.shader_enabled); }, [](int) { Screen::get()->toggleShaders(); }, nullptr}); + p.items.push_back({Locale::get("menu.items.shader"), ItemKind::Toggle, + [] { return onOff(Options::video.shader_enabled); }, + [](int) { Screen::get()->toggleShaders(); }, nullptr}); - p.items.push_back({"ASPECTE 4:3", ItemKind::Toggle, [] { return yesNo(Options::video.aspect_ratio_4_3); }, [](int) { Screen::get()->toggleAspectRatio(); }, nullptr}); + p.items.push_back({Locale::get("menu.items.aspect_4_3"), ItemKind::Toggle, + [] { return yesNo(Options::video.aspect_ratio_4_3); }, + [](int) { Screen::get()->toggleAspectRatio(); }, nullptr}); - p.items.push_back({"SUPERSAMPLING", ItemKind::Toggle, [] { return onOff(Options::video.supersampling); }, [](int) { Screen::get()->toggleSupersampling(); }, nullptr}); + p.items.push_back({Locale::get("menu.items.supersampling"), ItemKind::Toggle, + [] { return onOff(Options::video.supersampling); }, + [](int) { Screen::get()->toggleSupersampling(); }, nullptr}); - p.items.push_back({"TIPUS SHADER", ItemKind::Cycle, [] { return std::string(Screen::get()->getActiveShaderName()); }, [](int dir) { + p.items.push_back({Locale::get("menu.items.shader_type"), ItemKind::Cycle, + [] { return std::string(Screen::get()->getActiveShaderName()); }, [](int dir) { if (dir < 0) Screen::get()->prevShaderType(); else Screen::get()->nextShaderType(); }, nullptr}); - p.items.push_back({"PRESET", ItemKind::Cycle, [] { return std::string(Screen::get()->getCurrentPresetName()); }, [](int dir) { + p.items.push_back({Locale::get("menu.items.preset"), ItemKind::Cycle, + [] { return std::string(Screen::get()->getCurrentPresetName()); }, [](int dir) { if (dir < 0) Screen::get()->prevPreset(); else Screen::get()->nextPreset(); }, nullptr}); - p.items.push_back({"FILTRE 4:3", ItemKind::Toggle, [] { return std::string(Options::video.stretch_filter_linear ? "LINEAR" : "NEAREST"); }, [](int) { Screen::get()->toggleStretchFilter(); }, nullptr}); + p.items.push_back({Locale::get("menu.items.stretch_filter"), ItemKind::Toggle, + [] { return std::string(Options::video.stretch_filter_linear ? Locale::get("menu.values.linear") : Locale::get("menu.values.nearest")); }, + [](int) { Screen::get()->toggleStretchFilter(); }, nullptr}); - p.items.push_back({"RENDER INFO", ItemKind::Cycle, [] { + p.items.push_back({Locale::get("menu.items.render_info"), ItemKind::Cycle, [] { switch (Options::render_info.position) { - case Options::RenderInfoPosition::OFF: return std::string("OFF"); - case Options::RenderInfoPosition::TOP: return std::string("TOP"); - case Options::RenderInfoPosition::BOTTOM: return std::string("BOTTOM"); + case Options::RenderInfoPosition::OFF: return std::string(Locale::get("menu.values.off")); + case Options::RenderInfoPosition::TOP: return std::string(Locale::get("menu.values.top")); + case Options::RenderInfoPosition::BOTTOM: return std::string(Locale::get("menu.values.bottom")); } - return std::string("OFF"); }, [](int dir) { Overlay::cycleRenderInfo(dir); }, nullptr}); + return std::string(Locale::get("menu.values.off")); }, + [](int dir) { Overlay::cycleRenderInfo(dir); }, nullptr}); - p.items.push_back({"HORA", ItemKind::Toggle, [] { return onOff(Options::render_info.show_time); }, [](int) { Options::render_info.show_time = !Options::render_info.show_time; }, nullptr}); + p.items.push_back({Locale::get("menu.items.uptime"), ItemKind::Toggle, + [] { return onOff(Options::render_info.show_time); }, + [](int) { Options::render_info.show_time = !Options::render_info.show_time; }, nullptr}); return p; } @@ -169,35 +185,47 @@ namespace Menu { } static Page buildControls() { - Page p{"CONTROLS", {}, 0}; - p.items.push_back({"MOU AMUNT", ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_game.up}); - p.items.push_back({"MOU AVALL", ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_game.down}); - p.items.push_back({"MOU ESQUERRA", ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_game.left}); - p.items.push_back({"MOU DRETA", ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_game.right}); - p.items.push_back({"TECLA MENU", ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_gui.menu_toggle}); + Page p{Locale::get("menu.titles.controls"), {}, 0}; + p.items.push_back({Locale::get("menu.items.move_up"), ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_game.up}); + p.items.push_back({Locale::get("menu.items.move_down"), ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_game.down}); + p.items.push_back({Locale::get("menu.items.move_left"), ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_game.left}); + p.items.push_back({Locale::get("menu.items.move_right"), ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_game.right}); + p.items.push_back({Locale::get("menu.items.menu_key"), ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_gui.menu_toggle}); return p; } static Page buildAudio() { - Page p{"AUDIO", {}, 0}; + Page p{Locale::get("menu.titles.audio"), {}, 0}; - p.items.push_back({"AUDIO", ItemKind::Toggle, [] { return onOff(Options::audio.enabled); }, [](int) { + p.items.push_back({Locale::get("menu.items.master_enable"), ItemKind::Toggle, + [] { return onOff(Options::audio.enabled); }, [](int) { Options::audio.enabled = !Options::audio.enabled; - Options::applyAudio(); }, nullptr}); + Options::applyAudio(); }, + nullptr}); - p.items.push_back({"MASTER", ItemKind::IntRange, [] { return volPct(Options::audio.volume); }, [](int dir) { stepVolume(Options::audio.volume, dir); }, nullptr}); + p.items.push_back({Locale::get("menu.items.master_volume"), ItemKind::IntRange, + [] { return volPct(Options::audio.volume); }, + [](int dir) { stepVolume(Options::audio.volume, dir); }, nullptr}); - p.items.push_back({"MUSICA", ItemKind::Toggle, [] { return onOff(Options::audio.music_enabled); }, [](int) { + p.items.push_back({Locale::get("menu.items.music"), ItemKind::Toggle, + [] { return onOff(Options::audio.music_enabled); }, [](int) { Options::audio.music_enabled = !Options::audio.music_enabled; - Options::applyAudio(); }, nullptr}); + Options::applyAudio(); }, + nullptr}); - p.items.push_back({"VOL MUSICA", ItemKind::IntRange, [] { return volPct(Options::audio.music_volume); }, [](int dir) { stepVolume(Options::audio.music_volume, dir); }, nullptr}); + p.items.push_back({Locale::get("menu.items.music_volume"), ItemKind::IntRange, + [] { return volPct(Options::audio.music_volume); }, + [](int dir) { stepVolume(Options::audio.music_volume, dir); }, nullptr}); - p.items.push_back({"SONS", ItemKind::Toggle, [] { return onOff(Options::audio.sound_enabled); }, [](int) { + p.items.push_back({Locale::get("menu.items.sounds"), ItemKind::Toggle, + [] { return onOff(Options::audio.sound_enabled); }, [](int) { Options::audio.sound_enabled = !Options::audio.sound_enabled; - Options::applyAudio(); }, nullptr}); + Options::applyAudio(); }, + nullptr}); - p.items.push_back({"VOL SONS", ItemKind::IntRange, [] { return volPct(Options::audio.sound_volume); }, [](int dir) { stepVolume(Options::audio.sound_volume, dir); }, nullptr}); + p.items.push_back({Locale::get("menu.items.sounds_volume"), ItemKind::IntRange, + [] { return volPct(Options::audio.sound_volume); }, + [](int dir) { stepVolume(Options::audio.sound_volume, dir); }, nullptr}); return p; } @@ -381,7 +409,7 @@ namespace Menu { // Items o placeholder buit int items_y = title_line_y + 4; if (page.items.empty()) { - const char* empty_text = "(BUIT)"; + const char* empty_text = Locale::get("menu.values.empty"); int ew = font_->width(empty_text); font_->drawClipped(pixel_data, box_x + (BOX_W - ew) / 2 + x_offset, items_y + 2, empty_text, EMPTY_COLOR, clip_x_min, clip_x_max, clip_y_min, clip_y_max); return; @@ -406,8 +434,8 @@ namespace Menu { font_->drawClipped(pixel_data, box_x + BOX_W - ITEM_PAD_X - aw + x_offset, y, arrow, ac, clip_x_min, clip_x_max, clip_y_min, clip_y_max); } else if (item.kind == ItemKind::KeyBind) { bool this_capturing = (capturing_ == item.scancode); - const char* text = this_capturing ? "" : (item.scancode ? SDL_GetScancodeName(*item.scancode) : ""); - if (!text || !*text) text = "---"; + const char* text = this_capturing ? Locale::get("menu.values.press_key") : (item.scancode ? SDL_GetScancodeName(*item.scancode) : ""); + if (!text || !*text) text = Locale::get("menu.values.unknown"); int tw = font_->width(text); Uint32 tc = this_capturing ? 0xFF00FFFF : (selected ? CURSOR_COLOR : VALUE_COLOR); font_->drawClipped(pixel_data, box_x + BOX_W - ITEM_PAD_X - tw + x_offset, y, text, tc, clip_x_min, clip_x_max, clip_y_min, clip_y_max); diff --git a/source/core/rendering/overlay.cpp b/source/core/rendering/overlay.cpp index 36ff3bb..48da119 100644 --- a/source/core/rendering/overlay.cpp +++ b/source/core/rendering/overlay.cpp @@ -5,6 +5,7 @@ #include #include +#include "core/locale/locale.hpp" #include "core/rendering/menu.hpp" #include "core/rendering/text.hpp" #include "core/system/director.hpp" @@ -229,7 +230,7 @@ namespace Overlay { // Indicador de pausa persistent (cantó superior dret) if (Director::get() && Director::get()->isPaused()) { - const char* pause_text = "PAUSA"; + const char* pause_text = Locale::get("notifications.pause"); int w = font_->width(pause_text); int x = SCREEN_W - w - 4; int y = 4; @@ -287,7 +288,7 @@ namespace Overlay { if (!esc_waiting_) { // Primera pulsació: mostra avís i consumeix esc_waiting_ = true; - showNotification("TORNA A PULSAR ESC PER EIXIR", 2.0F); + showNotification(Locale::get("notifications.exit_double_esc"), 2.0F); return true; // Consumit } // Segona pulsació: deixa passar diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index 2394fc0..8e28efb 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -7,6 +7,7 @@ #include "core/input/global_inputs.hpp" #include "core/input/key_remap.hpp" #include "core/input/mouse.hpp" +#include "core/locale/locale.hpp" #include "core/jail/jail_audio.hpp" #include "core/jail/jgame.hpp" #include "core/jail/jinput.hpp" @@ -146,7 +147,7 @@ void Director::handleEvents() { if (event.type == SDL_EVENT_KEY_DOWN && !event.key.repeat && event.key.scancode == Options::keys_gui.pause_toggle) { togglePause(); - Overlay::showNotification(paused_ ? "PAUSA" : "REPRES"); + Overlay::showNotification(paused_ ? Locale::get("notifications.pause") : Locale::get("notifications.resume")); menu_keys_held_[event.key.scancode] = true; continue; } diff --git a/source/main.cpp b/source/main.cpp index 8d459d7..59d45bf 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -5,6 +5,7 @@ #include "core/jail/jdraw8.hpp" #include "core/jail/jfile.hpp" #include "core/jail/jgame.hpp" +#include "core/locale/locale.hpp" #include "core/rendering/menu.hpp" #include "core/rendering/overlay.hpp" #include "core/rendering/screen.hpp" @@ -19,6 +20,9 @@ int main(int /*argc*/, char* /*args*/[]) { Options::setConfigFile(std::string(file_getconfigfolder()) + "config.yaml"); Options::loadFromFile(); + // Carrega textos (idioma per defecte: valencià) + Locale::load("locale/ca.yaml"); + // Carrega presets de shaders Options::setPostFXFile(std::string(file_getconfigfolder()) + "postfx.yaml"); Options::loadPostFXFromFile();