afegit fixer de locales (textos centralitzats)
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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 ? "<PREM TECLA>" : (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);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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
|
||||
|
||||
Reference in New Issue
Block a user