From 25bbd8f7f6546f993c5ef9744ea9d22a94b58d0e Mon Sep 17 00:00:00 2001 From: nickpons666 Date: Fri, 3 Apr 2026 15:11:17 -0600 Subject: [PATCH] feat: Add Spanish translation system (LanguageManager, Espanol.json ~950 strings, UI selector) - LanguageManager.h/cpp: Dynamic language loading from JSON files - Espanol.json: ~950 translations extracted from all menu files - SohMenu.cpp/h: Widget name translation with stable index-based keys - SohMenuSettings.cpp: Dynamic language selector with persistence - Localization.h/cpp: Stub for compilation compatibility - PLAN_TRADUCCION.md: Complete implementation plan with analysis --- PLAN_TRADUCCION.md | 396 ++++++++++++ lenguajes/Espanol.json | 954 +++++++++++++++++++++++++++++ soh.desktop | 9 + soh/soh/Localization.cpp | 1 + soh/soh/Localization.h | 7 + soh/soh/SohGui/LanguageManager.cpp | 174 ++++++ soh/soh/SohGui/LanguageManager.h | 33 + soh/soh/SohGui/SohMenu.cpp | 51 +- soh/soh/SohGui/SohMenu.h | 4 + soh/soh/SohGui/SohMenuSettings.cpp | 73 ++- 10 files changed, 1697 insertions(+), 5 deletions(-) create mode 100644 PLAN_TRADUCCION.md create mode 100644 lenguajes/Espanol.json create mode 100644 soh.desktop create mode 100644 soh/soh/Localization.cpp create mode 100644 soh/soh/Localization.h create mode 100644 soh/soh/SohGui/LanguageManager.cpp create mode 100644 soh/soh/SohGui/LanguageManager.h diff --git a/PLAN_TRADUCCION.md b/PLAN_TRADUCCION.md new file mode 100644 index 000000000..3d1d20842 --- /dev/null +++ b/PLAN_TRADUCCION.md @@ -0,0 +1,396 @@ +# Plan de Implementación del Sistema de Traducción + +## Objetivo +Crear un sistema de traducción dinámico que permita cargar idiomas desde archivos JSON externos **sin modificar los textos hardcodeados existentes**. Los textos en el código permanecen en inglés como fallback por defecto. + +--- + +## 1. Funcionamiento Clave + +### 1.1 Comportamiento +- **Sin carpeta de idiomas**: El juego funciona exactamente como ahora con los textos hardcodeados en inglés +- **Con carpeta de idiomas**: Cuando el usuario selecciona un idioma, se carga el JSON y se traducen los textos disponibles +- **Fallback**: Si una traducción no existe en el JSON, se usa el texto hardcodeado (inglés) +- **Persistencia**: El idioma seleccionado se guarda en la configuración y se carga automáticamente al iniciar + +### 1.2 Carpeta de Idiomas (opcional) +``` +/lenguajes/ + ├── Espanol.json + ├── Portugues.json + └── (otros idiomas).json +``` + +**Nota**: No se requiere English.json porque el inglés ya está hardcodeado en el código. + +--- + +## 2. Archivos Creados + +| Archivo | Descripción | +|---------|-------------| +| `soh/soh/SohGui/LanguageManager.h` | Header del manager de idiomas | +| `soh/soh/SohGui/LanguageManager.cpp` | Implementación del manager | +| `lenguajes/Espanol.json` | Traducción español (~950 claves) | +| `soh/soh/Localization.h` | Stub para compatibilidad de compilación | +| `soh/soh/Localization.cpp` | Stub para compatibilidad de compilación | + +--- + +## 3. Archivos Modificados (Implementación Base) + +| Archivo | Cambios | +|---------|---------| +| `soh/soh/SohGui/SohMenuSettings.cpp` | Agregar selector de idioma dinámico + carga automática al inicio | +| `soh/soh/SohGui/SohMenu.cpp` | Aplicar traducción automática en DrawElement() con almacenamiento de nombres originales | +| `soh/soh/SohGui/SohMenu.h` | Agregar mapa de nombres originales y tooltips originales | + +--- + +## 4. Ubicación de la Carpeta de Idiomas + +### 4.1 Ubicaciones Buscadas +El sistema busca la carpeta `lenguajes` en este orden: +1. **Directorio actual** (desde donde se ejecuta el juego) +2. **Directorio de datos de la app** (~/.local/share/com.shipofharkinian.soh/) + +### 4.2 Cómo colocar los archivos +```bash +# Opción 1: Copiar junto al ejecutable (después de compilar) +cp -r lenguajes build-cmake/soh/ + +# Opción 2: En el directorio de datos de la app +# Linux: ~/.local/share/com.shipofharkinian.soh/lenguajes/ +``` + +--- + +## 5. Formato de Archivos JSON + +### 5.1 Estructura del JSON +```json +{ + "language": "Español", + "strings": { + "Settings": "Configuración", + "Enabled": "Activado", + "Disabled": "Desactivado" + } +} +``` + +### 5.2 Espanol.json (Completo) +Actualmente incluye ~950 traducciones extraídas automáticamente de todos los archivos del menú. + +--- + +## 6. Implementación del LanguageManager + +### 6.1 LanguageManager.h +```cpp +class LanguageManager { +public: + static LanguageManager& Instance(); + + void Init(); + void LoadLanguage(const std::string& languageName); + std::string GetString(const std::string& key); + std::vector GetAvailableLanguages(); + std::string GetCurrentLanguage(); + bool IsTranslationLoaded(); + +private: + std::string currentLanguage; + std::map translations; + bool translationLoaded; + + void ScanLanguageFiles(); + bool LoadJsonFile(const std::string& path); + std::string GetLanguagesDirectory(); +}; +``` + +### 6.2 Lógica de Funcionamiento +```cpp +std::string LanguageManager::GetString(const std::string& key) { + if (!translationLoaded || translations.empty()) { + return key; + } + auto it = translations.find(key); + if (it != translations.end()) { + return it->second; + } + return key; // Fallback al texto original +} +``` + +--- + +## 7. Estado Actual de la Implementación + +### ✅ Completado +- [x] LanguageManager.h/cpp - Carga de idiomas desde JSON +- [x] Selector de idioma dinámico en Settings (usa CVar integer para el índice) +- [x] Traducción automática de nombres de widgets en DrawElement() +- [x] Almacenamiento de nombres originales con claves estables (sección|sidebar|columna|índice) +- [x] Persistencia del idioma seleccionado +- [x] Espanol.json con ~950 traducciones +- [x] Compilación exitosa y funcional + +### ❌ Pendiente - Fase 1: Menú Completo (Riesgo Bajo-Medio) +- [ ] Headers del menú principal (Settings, Enhancements, Randomizer, Network, Dev Tools) +- [ ] Labels de sidebars (General, Audio, Graphics, Controls, etc.) +- [ ] Tooltips de widgets (mensajes al pasar el mouse) +- [ ] Opciones de combobox (temas, filtros de textura, etc.) +- [ ] Mensajes de estado (disabled tooltips, mensajes de error) +- [ ] Custom widgets que usan ImGui directo +- [ ] Editor de resolución (labels de presets, textos de configuración) +- [ ] Textos del sistema base de búsqueda (Search Results, Clear Search, No results found) +- [ ] Botones del header (Quit SoH, Reset, Close Menu) +- [ ] Nombres de botones N64 en UIWidgets (Modifier 1, Modifier 2) +- [ ] Textos dinámicos en PreFunc (Connecting..., Connected, etc.) + +### ❌ Pendiente - Fase 2: Randomizer (Riesgo Alto) +- [ ] Opciones del randomizer (settings.cpp - macros OPT_U8, OPT_BOOL) +- [ ] Descripciones de opciones (option_descriptions.cpp) +- [ ] Nombres de grupos de opciones (OptionGroup::SubGroup) +- [ ] Textos custom del menú randomizer (ImGui directo) +- [ ] Nombres de tricks y descripciones +- [ ] Nombres de áreas +- [ ] Textos del Plandomizer (Locations, Items, etc.) + +--- + +## 8. Análisis Completo de Textos por Categoría + +### Categoría 1: SohMenu.cpp - Mensajes de Estado +**Archivo:** `soh/soh/SohGui/SohMenu.cpp` +**Textos:** ~14 mensajes de disabledMap +**Ejemplos:** "Disabling VSync not supported", "Debug Mode is Disabled", "Frame Advance is Disabled" +**Cómo se dibujan:** Se concatenan en `Menu::MenuDrawItem()` como tooltips de widgets deshabilitados +**Tipo:** `const char*` en struct `disabledInfo` +**Riesgo:** BAJO + +### Categoría 2: SohMenuSettings.cpp - Widgets de Settings +**Archivo:** `soh/soh/SohGui/SohMenuSettings.cpp` +**Textos:** ~200 (nombres de widgets, tooltips, opciones de combobox) +**Ejemplos de combobox options:** "Small", "Normal", "Large" (ImGui Scale), "Red", "Dark Red", "Orange" (temas), "Three-Point", "Linear", "None" (filtro textura) +**Ejemplos de tooltips:** "Changes the Theme of the Menu Widgets.", "Allows controller navigation of the port menu..." +**Cómo se dibujan:** Via `AddWidget().Tooltip("...")` y `.ComboMap(mapa)` +**Tipo:** Tooltips como `std::string` en WidgetOptions, combobox como `std::map` +**Riesgo:** MEDIO + +### Categoría 3: SohMenuEnhancements.cpp - Widgets de Enhancements +**Archivo:** `soh/soh/SohGui/SohMenuEnhancements.cpp` +**Textos:** ~500+ (nombres, tooltips, opciones de combobox, disabledTooltips) +**Ejemplos de combobox options:** "Vanilla", "Faster Run", "Faster + Longer Jump" (Bunny Hood), "Plentiful", "Balanced", "Scarce", "Minimal" (Item Pool del randomizer) +**Ejemplos de tooltips:** Textos largos de varias líneas explicando cada mejora +**Cómo se dibujan:** Mismo patrón que Settings +**Riesgo:** MEDIO-ALTO (volumen grande) + +### Categoría 4: SohMenuRandomizer.cpp - Widgets de Randomizer +**Archivo:** `soh/soh/SohGui/SohMenuRandomizer.cpp` +**Textos:** ~100 + datos del motor del randomizer +**Ejemplos:** "Seed Entry", "Generate Randomizer", "Filter (inc,-exc)", "Disable All", "Enable All" +**Cómo se dibujan:** Mix de `AddWidget()` y custom widgets con ImGui directo (`ImGui::Text()`, `ImGui::Button()`, `ImGui::BeginTable()`) +**Datos del randomizer:** Nombres de ubicaciones, tricks, áreas vienen de `Rando::StaticData`, `TrickSetting`, `Option` +**Riesgo:** ALTO (datos del randomizer pueden afectar compatibilidad con seeds) + +### Categoría 5: SohMenuNetwork.cpp - Widgets de Network +**Archivo:** `soh/soh/SohGui/SohMenuNetwork.cpp` +**Textos:** ~30 +**Ejemplos:** "Host & Port", "Enable##Sail", "Connecting...##Sail", "About Crowd Control" +**Cómo se dibujan:** Mix de `AddWidget()` y textos ImGui directo +**Riesgo:** BAJO + +### Categoría 6: SohMenuDevTools.cpp - Widgets de Dev Tools +**Archivo:** `soh/soh/SohGui/SohMenuDevTools.cpp` +**Textos:** ~50 +**Ejemplos:** "Debug Mode", "Frame Advance", "Log Level", "Trace", "Debug", "Info", "Warn" +**Riesgo:** BAJO (herramientas de desarrollo, prioridad baja) + +### Categoría 7: Menu.cpp - Sistema Base del Menú +**Archivo:** `soh/soh/SohGui/Menu.cpp` +**Textos:** ~20 +**Ejemplos:** "This setting is disabled because: \n", "Search Results", "Clear Search", "No results found", "Quit SoH", "Reset", "Close Menu (Esc)" +**Cómo se dibujan:** Directamente en `MenuDrawItem()` con llamadas ImGui +**Riesgo:** MEDIO (textos del sistema core) + +### Categoría 8: UIWidgets.cpp - Widgets UI +**Archivo:** `soh/soh/SohGui/UIWidgets.cpp` +**Textos:** ~15 +**Ejemplos:** "Modifier 1", "Modifier 2", "Remove this button from the combination", "Resets this color to its default value" +**Cómo se dibujan:** En `BtnSelector()` y Color Picker +**Riesgo:** BAJO-MEDIO + +### Categoría 9: ResolutionEditor.cpp - Editor de Resolución +**Archivo:** `soh/soh/SohGui/ResolutionEditor.cpp` +**Textos:** ~40 +**Ejemplos:** "Off", "Custom", "Original (4:3)", "Widescreen (16:9)", "Pixel Perfect Mode", "Integer Scaling Settings" +**Cómo se dibujan:** Mix de `AddWidget()` y `ResolutionCustomWidget()` con ImGui directo +**Riesgo:** MEDIO + +### Categoría 10: Randomizer Settings - Opciones del Randomizer +**Archivos:** +- `soh/soh/Enhancements/randomizer/settings.cpp` +- `soh/soh/Enhancements/randomizer/option_descriptions.cpp` +**Textos:** ~1000+ +**Ejemplos:** "Item Pool", "Logic", "Closed Forest", "Kakariko Gate", "Starting Age" +**Cómo se dibujan:** Via macros `OPT_U8`, `OPT_BOOL` que crean objetos `Option`, no pasan por `AddWidget()` +**Descripciones:** Textos largos en `option_descriptions.cpp` (~836 líneas) +**Grupos:** `OptionGroup::SubGroup("Logic Options", ...)`, `OptionGroup::SubGroup("Logical Tricks", ...)` +**Riesgo:** MUY ALTO (puede romper compatibilidad con seeds, spoiler logs, herramientas externas) + +### Categoría 11: SohMenu.h - Idiomas del Juego +**Archivo:** `soh/soh/SohGui/SohMenu.h` +**Textos:** 4 ("English", "German", "French", "Japanese") +**Riesgo:** MUY BAJO (nombres propios de idiomas) + +--- + +## 9. Plan de Implementación Gradual (Opción C) + +### Fase 1: Menú Completo (sin Randomizer) +**Objetivo:** Traducir todo el menú principal ~700 textos adicionales +**Riesgo:** Medio +**Tiempo estimado:** Moderado + +#### Paso 1.1: Headers y Sidebars +- Modificar `DrawElement()` para traducir `section.label` y `sidebarOrder` +- Usar claves estables basadas en índices (igual que widgets) +- **Archivo:** `soh/soh/SohGui/SohMenu.cpp` + +#### Paso 1.2: Tooltips de Widgets +- Agregar mapa `mOriginalTooltips` en SohMenu.h +- Guardar tooltips originales con claves de índice +- Traducir en `DrawElement()` antes de dibujar +- **Archivos:** `SohMenu.h`, `SohMenu.cpp` + +#### Paso 1.3: Opciones de Combobox +- Traducir en `PreFunc` de cada widget combobox +- Usar mapas estáticos con traducción dinámica +- **Archivos:** `SohMenuSettings.cpp`, `SohMenuEnhancements.cpp`, etc. + +#### Paso 1.4: Mensajes de Estado (disabledMap) +- Traducir `disabledInfo.reason` en `MenuDrawItem()` al concatenar +- **Archivo:** `soh/soh/SohGui/Menu.cpp` + +#### Paso 1.5: Textos del Sistema Base +- Traducir textos de búsqueda, botones del header, diálogos de confirmación +- **Archivo:** `soh/soh/SohGui/Menu.cpp` + +#### Paso 1.6: Custom Widgets +- Envolver textos ImGui directo con `LanguageManager::Instance().GetString()` +- **Archivos:** `SohMenuNetwork.cpp`, `SohMenuDevTools.cpp`, `ResolutionEditor.cpp` + +#### Paso 1.7: UIWidgets +- Traducir labels de botones (Modifier 1, Modifier 2) y tooltips de Color Picker +- **Archivo:** `soh/soh/SohGui/UIWidgets.cpp` + +### Fase 2: Randomizer (requiere diseño cuidadoso) +**Objetivo:** Traducir opciones del randomizer ~1000+ textos +**Riesgo:** Alto +**Consideraciones:** +- Los nombres de opciones se usan como keys en mapas y serialización +- Puede afectar compatibilidad con seeds existentes y spoiler logs +- Los nombres de tricks son parte de la cultura del speedrunning +- Se necesita evaluar si traducir solo display names o también keys internas + +#### Paso 2.1: Opciones del Randomizer +- Integrar `LanguageManager` en el sistema de `Option` +- Traducir `GetName()` al renderizar, NO al crear la opción +- **Archivo:** `soh/soh/Enhancements/randomizer/settings.cpp` + +#### Paso 2.2: Descripciones de Opciones +- Traducir `mOptionDescriptions[]` al mostrar +- **Archivo:** `soh/soh/Enhancements/randomizer/option_descriptions.cpp` + +#### Paso 2.3: Grupos de Opciones +- Traducir nombres de `OptionGroup::SubGroup()` al renderizar +- **Archivo:** `soh/soh/Enhancements/randomizer/settings.cpp` + +#### Paso 2.4: Custom Widgets del Randomizer +- Traducir textos ImGui directo en el menú del randomizer +- **Archivo:** `soh/soh/SohGui/SohMenuRandomizer.cpp` + +#### Paso 2.5: Tricks y Áreas (opcional, bajo demanda) +- Traducir nombres de tricks y áreas +- Evaluar impacto en la comunidad de speedrunning +- **Archivos:** `soh/soh/Enhancements/randomizer/3drando/tricks.cpp`, etc. + +--- + +## 10. Notas Importantes + +- ✅ **Textos hardcodeados permanecen**: El código no se modifica, los textos en inglés quedan como están +- ✅ **Sin carpeta de idiomas funciona igual**: Si no existe la carpeta, el juego funciona exactamente como antes +- ✅ **Fallback automático**: Si falta una traducción, se muestra el texto original +- ✅ **Selector dinámico**: Los nombres de idiomas vienen de los archivos JSON, no están hardcodeados +- ✅ **Fácil agregar idiomas**: Solo hay que crear un nuevo archivo `.json` en la carpeta +- ✅ **Persistencia**: El idioma seleccionado se guarda y se carga automáticamente al iniciar +- ⚠️ **Ubicación de carpeta**: La carpeta `lenguajes` debe estar junto al ejecutable o en el directorio de datos de la app +- ⚠️ **Claves estables**: Los nombres de widgets se traducen usando claves basadas en índices para evitar corrupción al cambiar idioma + +--- + +## 11. Cómo Compilar y Ejecutar + +```bash +# 1. Compilar el proyecto +cmake -H. -Bbuild-cmake -GNinja +cmake --build build-cmake -j$(nproc) + +# 2. Copiar carpeta de idiomas junto al ejecutable +cp -r lenguajes build-cmake/soh/ + +# 3. Ejecutar desde la raíz del proyecto +./build-cmake/soh/soh.elf +``` + +--- + +## 12. Resumen de Dificultad por Categoría + +| Categoría | Textos | Dificultad | Riesgo | +|---|---|---|---| +| Headers y Sidebars | ~30 | Media | Medio | +| Tooltips del menú | ~400 | Media | Medio | +| Opciones de combobox | ~150 | Media | Medio | +| Mensajes de estado | ~30 | Baja | Bajo | +| Custom widgets | ~80 | Media | Medio | +| Editor de resolución | ~40 | Media | Medio | +| Sistema base (búsqueda, botones) | ~20 | Media | Medio | +| UIWidgets | ~15 | Baja | Bajo | +| **Opciones del Randomizer** | ~1000+ | Muy Alta | **Muy Alto** | +| Tricks y Áreas | ~100+ | Muy Alta | **Muy Alto** | + +--- + +## 13. Archivos de Referencia con Textos Hardcodeados + +### SohGui (ya analizados) +- `SohMenu_hardcoded.txt` +- `SohMenuSettings_hardcoded.txt` +- `SohMenuEnhancements_hardcoded.txt` +- `SohMenuRandomizer_hardcoded.txt` +- `SohMenuNetwork_hardcoded.txt` +- `SohMenuDevTools_hardcoded.txt` +- `SohMenuBar_hardcoded.txt` +- `ResolutionEditor_hardcoded.txt` + +--- + +## 14. Diferencias con el Plan Anterior + +| Aspecto | Plan Anterior | Plan Actual | +|---------|---------------|--------------| +| English.json | Obligatorio | No necesario (hardcodeado es fallback) | +| Reemplazo de textos | Sí, en todos los archivos | No, solo agregar función GetString | +| Archivos a modificar | 8+ archivos | 2 archivos (SohMenuSettings.cpp, SohMenu.cpp) | +| Funcionamiento sin carpeta | Requiere English.json | Funciona igual que antes | +| Stub Localization | No previsto | Necesario para compilar | +| Persistencia de idioma | No implementada | ✅ Guardado y cargado automáticamente | +| Strings en selector | Implementación con problemas | ✅ Solucionado con map estático | +| Traducción de tooltips | No previsto | ✅ Implementado con claves estables | +| Headers y Sidebars | No previsto | ⏳ Pendiente (Fase 1) | +| Randomizer | No previsto | ⏳ Pendiente (Fase 2, requiere diseño) | diff --git a/lenguajes/Espanol.json b/lenguajes/Espanol.json new file mode 100644 index 000000000..1296d1445 --- /dev/null +++ b/lenguajes/Espanol.json @@ -0,0 +1,954 @@ +{ + "language": "Español", + "strings": { + "English": "Inglés", + "German": "Alemán", + "French": "Francés", + "Japanese": "Japonés", + "Red": "Rojo", + "Dark Red": "Rojo Oscuro", + "Orange": "Naranja", + "Green": "Verde", + "Dark Green": "Verde Oscuro", + "Light Blue": "Azul Claro", + "Blue": "Azul", + "Dark Blue": "Azul Oscuro", + "Indigo": "Índigo", + "Violet": "Violeta", + "Purple": "Púrpura", + "Brown": "Marrón", + "Gray": "Gris", + "Dark Gray": "Gris Oscuro", + "Three-Point": "Tres Puntos", + "Linear": "Lineal", + "None": "Ninguno", + "Trace": "Rastro", + "Debug": "Depuración", + "Info": "Información", + "Warn": "Advertencia", + "Error": "Error", + "Critical": "Crítico", + "Off": "Apagado", + "Top Left": "Superior Izquierda", + "Top Right": "Superior Derecha", + "Bottom Left": "Inferior Izquierda", + "Bottom Right": "Inferior Derecha", + "Hidden": "Oculto", + "Normal": "Normal", + "Unbreakable": "Inquebrantable", + "Unbreakable + Always on Fire": "Inquebrantable + Siempre en Llamas", + "Navi": "Navi", + "NPCs": "NPCs", + "All": "Todos", + "Disabled": "Desactivado", + "Junk Items": "Objetos Basura", + "All Items": "Todos los Objetos", + "Both": "Ambos", + "Texture Only": "Solo Textura", + "Size Only": "Solo Tamaño", + "Ocarina of Time": "Ocarina del Tiempo", + "Any Ocarina": "Cualquier Ocarina", + "Always": "Siempre", + "Once": "Una vez", + "Never": "Nunca", + "Vanilla (1x)": "Original (1x)", + "Double (2x)": "Doble (2x)", + "Quadruple (4x)": "Cuádruple (4x)", + "Octuple (8x)": "Óctuple (8x)", + "Foolish (16x)": "Absurdo (16x)", + "Ridiculous (32x)": "Ridículo (32x)", + "Merciless (64x)": "Cruel (64x)", + "Pure Torture (128x)": "Pura Tortura (128x)", + "OHKO (256x)": "KO (256x)", + "No Damage": "Sin Daño", + "0.25 Hearts": "0.25 Corazones", + "0.5 Hearts": "0.5 Corazones", + "1 Heart": "1 Corazón", + "2 Hearts": "2 Corazones", + "4 Hearts": "4 Corazones", + "8 Hearts": "8 Corazones", + "Only in Rando": "Solo en Rando", + "Child Toggle": "Cambiar Niño", + "Both Ages": "Ambas Edades", + "Consistent Vanish": "Desvanecer Consistente", + "No Vanish": "Sin Desvanecer", + "Random": "Aleatorio", + "Random (Seeded)": "Aleatorio (Semilla)", + "Dungeons": "Mazmorras", + "Dungeons (Vanilla)": "Mazmorras (Original)", + "Dungeons (MQ)": "Mazmorras (MQ)", + "Dungeons Random": "Mazmorras Aleatorio", + "Dungeons Random (Seeded)": "Mazmorras Aleatorio (Semilla)", + "Vanilla": "Original", + "Maxed": "Maximizado", + "Default": "Por Defecto", + "Authentic": "Auténtico", + "File Select": "Selección de Archivo", + "Vanilla Plus": "Original Plus", + "Enhanced": "Mejorado", + "Randomizer": "Randomizer", + "Small": "Pequeño", + "Large": "Grande", + "X-Large": "Extra Grande", + "NTSC 1.0": "NTSC 1.0", + "NTSC 1.1": "NTSC 1.1", + "NTSC 1.2": "NTSC 1.2", + "NTSC-U GC": "NTSC-U GC", + "NTSC-J GC": "NTSC-J GC", + "NTSC-J GC (Collector's Edition)": "NTSC-J GC (Edición Coleccionista)", + "NTSC-U MQ": "NTSC-U MQ", + "NTSC-J MQ": "NTSC-J MQ", + "PAL 1.0": "PAL 1.0", + "PAL 1.1": "PAL 1.1", + "PAL GC": "PAL GC", + "PAL MQ": "PAL MQ", + "PAL GC-D": "PAL GC-D", + "PAL MQ-D": "PAL MQ-D", + "IQUE CN": "IQUE CN", + "IQUE TW": "IQUE TW", + "UNKNOWN": "DESCONOCIDO", + "Changes the Theme of the Menu Widgets.": "Cambia el tema de los widgets del menú.", + "Allows controller navigation of the port menu": "Permite navegación con controlador del menú de puertos", + "CAUTION: This will disable game inputs while the menu is visible.": "ADVERTENCIA: Esto deshabilitará las entradas del juego mientras el menú sea visible.", + "D-pad to move between items, A to select, B to move up in scope.": "D-pad para mover entre elementos, A para seleccionar, B para subir.", + "Sets the opacity of the background of the port menu.": "Establece la opacidad del fondo del menú de puertos.", + "Makes the cursor always visible, even in full screen.": "Hace el cursor siempre visible, incluso en pantalla completa.", + "Displays the Search menu as a sidebar entry in Settings instead of in the header.": "Muestra el menú de búsqueda como entrada lateral en Configuración.", + "Search input box gets autofocus when visible.": "La caja de búsqueda obtiene enfoque automático cuando es visible.", + "Allows pressing the Tab key to toggle alternate assets": "Permite presionar Tab para alternar assets alternativos", + "Opens the folder that contains the save and mods folders, etc.": "Abre la carpeta que contiene guardados y mods.", + "Configure what happens when starting or resetting the game.": "Configura qué sucede al iniciar o reiniciar el juego.", + "Default: LUS logo -> N64 logo": "Por defecto: Logo LUS -> Logo N64", + "Authentic: N64 logo only": "Auténtico: Solo logo N64", + "File Select: Skip to file select menu": "Selección de Archivo: Saltar al menú de selección", + "Enables text to speech for in game dialog": "Habilita texto a voz para diálogos del juego", + "Disables the automatic re-centering of the camera when idle.": "Deshabilita el recentrado automático de la cámara.", + "EXPERIMENTAL": "EXPERIMENTAL", + "Changes the scaling of the ImGui menu elements.": "Cambia la escala de los elementos del menú ImGui.", + "Ship Of Harkinian": "Ship Of Harkinian", + "Branch": "Rama", + "Commit": "Commit", + "Master Volume: %d %%": "Volumen Principal: %d %%", + "Main Music Volume: %d %%": "Volumen de Música Principal: %d %%", + "Sub Music Volume: %d %%": "Volumen de Música Secundaria: %d %%", + "Fanfare Volume: %d %%": "Volumen de Fanfarria: %d %%", + "Sound Effects Volume: %d %%": "Volumen de Efectos de Sonido: %d %%", + "Audio API (Needs reload)": "API de Audio (Necesita recargar)", + "Uses Matrix Interpolation to create extra frames": "Usa Interpolación de Matrices para crear cuadros extra", + "Toggles Fullscreen On/Off.": "Alternar Pantalla Completa.", + "Multiplies your output resolution by the value inputted": "Multiplica tu resolución de salida por el valor introducido", + "Activates MSAA (multi-sample anti-aliasing) from 2x up to 8x": "Activa MSAA (antialiasing multiamuestra) de 2x hasta 8x", + "Original (%d)": "Original (%d)", + "Match interpolation value to the refresh rate of your display.": "Coincidir valor de interpolación con tasa de refresco.", + "Renderer API (Needs reload)": "API del Renderizador (Necesita recargar)", + "Removes tearing, but clamps your max FPS to your displays refresh rate.": "Elimina tearing, pero limita FPS máximos.", + "Enables Windowed Fullscreen Mode.": "Habilita Modo Ventana Pantalla Completa.", + "Allows multiple windows to be opened at once.": "Permite múltiples ventanas a la vez.", + "Sets the applied Texture Filtering.": "Establece el filtro de textura aplicado.", + "Advanced Graphics Options": "Opciones Avanzadas de Gráficos", + "Controller Bindings": "Botones del Controlador", + "Enables the separate Bindings Window.": "Habilita la ventana de botones separada.", + "Input Viewer": "Visor de Entrada", + "Toggles the Input Viewer.": "Alterna el visor de entrada.", + "Input Viewer Settings": "Configuración del Visor de Entrada", + "Which corner of the screen notifications appear in.": "En qué esquina aparecen las notificaciones.", + "Duration (seconds):": "Duración (segundos):", + "How long notifications are displayed for.": "Cuánto tiempo se muestran las notificaciones.", + "Background Opacity": "Opacidad del Fondo", + "How opaque the background of notifications is.": "Qué tan opaco es el fondo de notificaciones.", + "Size:": "Tamaño:", + "How large notifications are.": "Qué tan grandes son las notificaciones.", + "Test Notification": "Probar Notificación", + "This is a test.": "Esto es una prueba.", + "Displays a test notification.": "Muestra una notificación de prueba.", + "Quality of Life": "Calidad de Vida", + "Saving": "Guardado", + "Save the game automatically on a 3 minute interval": "Guardar automáticamente cada 3 minutos", + "When loading a save, places Link at the last entrance": "Al cargar, coloca a Link en la última entrada", + "Containers Match Contents": "Contenedores equal Contenido", + "Chests of Agony": "Cofres de Agonía", + "Time of Day": "Hora del Día", + "Nighttime GS Always Spawn": "GS Nocturno Siempre Aparece", + "Pull Grave During the Day": "Tumbar de Día", + "Dampe Appears All Night": "Dampe Aparece Toda la Noche", + "Exit Market at Night": "Salir del Mercado de Noche", + "Shops and Games Always Open": "Tiendas y Juegos Siempre Abiertos", + "Pause Menu": "Menú de Pausa", + "Allow the Cursor to be on Any Slot": "Permitir Cursor en Cualquier Ranura", + "Pause Warp": "Teletransporte de Pausa", + "Controls": "Controles", + "Answer Navi Prompt with L Button": "Responder a Navi con Botón L", + "Don't Require Input for Credits Sequence": "No Requerir Input para Secuencia de Créditos", + "Include Held Inputs at the Start of Pause Buffer Input Window": "Incluir Inputs Sostenidos al Inicio de Ventana de Pausa", + "Pause Buffer Input Window: %d frames": "Ventana de Input de Pausa: %d cuadros", + "Simulated Input Lag: %d frames": "Lag de Input Simulado: %d cuadros", + "Item Count Messages": "Mensajes de Cantidad de Objetos", + "Gold Skulltula Tokens": "Tokens de Gold Skulltula", + "Pieces of Heart": "Piezas de Corazón", + "Heart Containers": "Contenedores de Corazón", + "Misc": "Varios", + "Disable Crit Wiggle": "Desactivar Crítico", + "Better Owl": "Mejor Búho", + "Quit Fishing at Door": "Salir de Pescar en Puerta", + "Instant Putaway": "Guardar Instantáneo", + "Navi Timer Resets on Scene Change": "Temporizador de Navi Resetea al Cambiar Escena", + "Link's Cow in Both Time Periods": "Vaca de Link en Ambos Períodos", + "Play Zelda's Lullaby to Open Sleeping Waterfall": "Tocar Canción de Zelda para Abrir Cascada Dormida", + "Skips & Speed-ups": "Saltos y Aceleraciones", + "Cutscenes": "Cinematicas", + "Skip Intro": "Saltar Introducción", + "Skip Entrance Cutscenes": "Saltar Cinemáticas de Entrada", + "Skip Story Cutscenes": "Saltar Cinemáticas de Historia", + "Skip Song Cutscenes": "Saltar Cinemáticas de Canciones", + "Skip Boss Introductions": "Saltar Introducciones de Jefes", + "Quick Boss Deaths": "Muertes Rápidas de Jefes", + "Skip One Point Cutscenes": "Saltar Cinemáticas de Un Punto", + "Skip Owl Interactions": "Saltar Interacciones del Búho", + "Skip Misc Interactions": "Saltar Interacciones Varias", + "Disable Title Card": "Desactivar Tarjeta de Título", + "Exclude Glitch-Aiding Cutscenes": "Excluir Cinemáticas de Glitch", + "Text": "Texto", + "Skip Pickup Messages": "Saltar Mensajes de Recolección", + "Skip Forced Dialog": "Saltar Diálogo Forzado", + "Skip Text": "Saltar Texto", + "Text Speed: %dx": "Velocidad de Texto: %dx", + "Slow Text Speed: %dx": "Velocidad de Texto Lento: %dx", + "Animations": "Animaciones", + "Faster Heavy Block Lift": "Levantar Bloque Pesado Más Rápido", + "Fast Chests": "Cofres Rápidos", + "Skip Water Take Breath Animation": "Saltar Animación de Respirar Bajo Agua", + "Vine/Ladder Climb Speed +%d": "Velocidad de Escalar Enredadera/Escalera +%d", + "Block Pushing Speed +%d": "Velocidad de Empujar Bloques +%d", + "Crawl Speed %dx": "Velocidad de Arrastre %dx", + "King Zra Speed: %.2fx": "Velocidad de Rey Zora: %.2fx", + "Skip Child Stealth": "Saltar Sigilo de Niño", + "Skip Tower Escape": "Saltar Escape de Torre", + "Skip Scarecrow's Song": "Saltar Canción del Espantapájaros", + "Faster Rupee Accumulator": "Acumulador de Rupias Más Rápido", + "No Skulltula Freeze": "Sin Congelamiento de Skulltula", + "Skip Save Confirmation": "Saltar Confirmación de Guardado", + "Link as Default File Name": "Link como Nombre de Archivo por Defecto", + "Biggoron Forge Time: %d days": "Tiempo de Forja de Biggoron: %d días", + "Mods": "Mods", + "Use Alternate Assets": "Usar Assets Alternativos", + "Disable Bomb Billboarding": "Desactivar Billboard de Bombas", + "Disable Grotto Fixed Rotation": "Desactivar Rotación Fija de Grotto", + "Ingame Text Spacing: %d": "Espaciado de Texto en Juego: %d", + "Models & Textures": "Modelos y Texturas", + "Disable LOD": "Desactivar LOD", + "Enemy Health Bars": "Barras de Salud de Enemigos", + "Enable 3D Dropped Items/Projectiles": "Habilitar Objetos 3D Lanzados", + "Animated Link in Pause Menu": "Link Animado en Menú de Pausa", + "Show Age-Dependent Equipment": "Mostrar Equipo Dependiente de Edad", + "Scale Adult Equipment as Child": "Escalar Equipo de Adulto como Niño", + "Show Gauntlets in First Person": "Mostrar Guanteletes en Primera Persona", + "Show Chains on Both Sides of Locked Doors": "Mostrar Cadenas en Ambos Lados de Puertas Cerradas", + "Color Temple of Time's Medallions": "Colorear Medallones del Templo del Tiempo", + "UI": "Interfaz", + "Minimal UI": "Interfaz Mínima", + "Disable Hot/Underwater Warning Text": "Desactivar Texto de Advertencia Calor/Submarino", + "Remember Minimap State Between Areas": "Recordar Estado del Minimapa Entre Áreas", + "Visual Stone of Agony": "Piedra Visual de Agonía", + "Disable HUD Heart Animations": "Desactivar Animaciones de Corazones HUD", + "Glitch Line-up Tick": "Ticks de Alineación de Glitch", + "Disable Black Bar Letterboxes": "Desactivar Carteleras Negras", + "Dynamic Wallet Icon": "Icono de Billetera Dinámico", + "Always Show Dungeon Entrances": "Siempre Mostrar Entradas de Mazmorras", + "More Info in File Select": "Más Info en Selección de Archivo", + "Better Ammo Rendering in Pause Menu": "Mejor Renderizado de Munición en Pausa", + "Enable Passage of Time on File Select": "Habilitar Paso del Tiempo en Selección", + "Misc.": "Varios", + "N64 Mode": "Modo N64", + "Remove Spin Attack Darkness": "Remover Oscuridad de Ataque Giratorio", + "Draw Distance": "Distancia de Dibujo", + "Increase Actor Draw Distance: %dx": "Aumentar Distancia de Dibujo de Actores: %dx", + "Kokiri Draw Distance": "Distancia de Dibujo Kokiri", + "Widescreen Actor Culling": "Culling de Actores Widescreen", + "Cull Glitch Useful Actors": "Culling de Actores Útiles para Glitch", + "Items": "Objetos", + "Equipment": "Equipo", + "Equip Items on Dpad": "Equipar Objetos en Dpad", + "Assignable Tunics and Boots": "Túnicas y Botas Asignables", + "Equipment Toggle": "Alternar Equipo", + "Allow Strength Equipment to be Toggled": "Permitir Alternar Equipo de Fuerza", + "Sword Toggle Options": "Opciones de Alternar Espada", + "Ask to Equip New Items": "Preguntar para Equipar Nuevos Objetos", + "Ocarina": "Ocarina", + "Prevent Dropped Ocarina Inputs": "Prevenir Inputs de Ocarina Suelta", + "Fast Ocarina Playback": "Reproducción Rápida de Ocarina", + "Time Travel with Song of Time": "Viajar en el Tiempo con Canción del Tiempo", + "Masks": "Máscaras", + "Bunny Hood Effect": "Efecto de Máscara de Conejo", + "Masks Equippable as Adult": "Máscaras Equipables como Adulto", + "Persistent Masks": "Máscaras Persistentes", + "Invisible Bunny Hood": "Máscara de Conejo Invisible", + "Mask Select in Inventory": "Selección de Máscara en Inventario", + "Explosives": "Explosivos", + "Deku Nuts Explode Bombs": "Nueces Deku Explotan Bombas", + "Remove Explosive Limit": "Remover Límite de Explosivos", + "Static Explosion Radius": "Radio de Explosión Estático", + "Prevent Bombchus Forcing First-Person": "Prevenir Bombchus Forzando Primera Persona", + "Better Bombchu Shopping": "Mejor Compra de Bombchus", + "Bow / Slingshot": "Arco/Honda", + "Equip Multiple Arrows at Once": "Equipar Múltiples Flechas a la Vez", + "Skip Magic Arrow Equip Animation": "Saltar Animación de Equipar Flecha Mágica", + "Blue Fire Arrows": "Flechas de Fuego Azul", + "Sunlight Arrows": "Flechas de Luz Solar", + "Bow as Child/Slingshot as Adult": "Arco como Niño/Honda como Adulto", + "Aiming Reticle for the Bow/Slingshot": "Retícula de Puntería para Arco/Honda", + "Hookshot": "Gancho", + "Targetable Hookshot Reticle": "Retícula de Gancho Dirigible", + "Boomerang": "Bumerang", + "Instant Boomerang Recall": "Retorno Instantáneo de Bumerang", + "Aim Boomerang in First-Person Mode": "Apuntar Bumerang en Modo Primera Persona", + "Aiming Reticle for Boomerang": "Retícula de Puntería para Bumerang", + "Magic Spells": "Hechizos", + "Better Farore's Wind": "Mejor Viento de Farore", + "Faster Farore's Wind": "Viento de Farore Más Rápido", + "Fixes": "Arreglos", + "Gameplay Fixes": "Arreglos de Jugabilidad", + "Fix the Gravedigging Tour Glitch": "Arreglar Glitch de Excursión de Excavación", + "Fix Raised Floor Switches": "Arreglar Interruptores de Piso Elevado", + "Popout Randomizer Settings Window": "Abrir Ventana de Configuración de Randomizer", + "Randomizer Settings": "Configuración de Randomizer", + "Enables the separate Randomizer Settings Window.": "Habilita la ventana separada de configuración de Randomizer.", + "Randomizer Enhancements": "Mejoras de Randomizer", + "Rando-Relevant Navi Hints": "Pistas de Navi Relevantes para Rando", + "Random Rupee Names": "Nombres Aleatorios de Rupias", + "Use Custom Key Models": "Usar Modelos de Llaves Personalizados", + "Map & Compass Colors Match Dungeon": "Colores de Mapa y Brújula igual a Mazmorra", + "Quest Item Fanfares": "Fanfarrias de Objetos de Misión", + "Mysterious Shuffled Items": "Objetos Mezclados Misteriosos", + "Simpler Boss Soul Models": "Modelos de Almas de Jefe Simples", + "Skip Get Item Animations": "Saltar Animaciones de Obtener Objeto", + "Item Scale: %.2f": "Escala de Objeto: %.2f", + "Popout Plandomizer Window": "Abrir Ventana de Plandomizer", + "Plandomizer Editor": "Editor de Plandomizer", + "Item Tracker": "Rastreador de Objetos", + "Toggle Item Tracker": "Alternar Rastreador de Objetos", + "Item Tracker Settings": "Configuración de Rastreador de Objetos", + "Popout Item Tracker Settings": "Abrir Configuración de Rastreador de Objetos", + "Entrance Tracker": "Rastreador de Entradas", + "Toggle Entrance Tracker": "Alternar Rastreador de Entradas", + "Entrance Tracker Settings": "Configuración de Rastreador de Entradas", + "Popout Entrance Tracker Settings": "Abrir Configuración de Rastreador de Entradas", + "Check Tracker": "Rastreador de Checks", + "Toggle Check Tracker": "Alternar Rastreador de Checks", + "Check Tracker Settings": "Configuración de Rastreador de Checks", + "Popout Check Tracker Settings": "Abrir Configuración de Rastreador de Checks", + "Popout Menu": "Abrir Menú", + "Debug Mode": "Modo Depuración", + "OoT Registry Editor": "Editor de Registro de OoT", + "Debug Save File Mode": "Modo de Archivo de Guardado de Depuración", + "OoT Skulltula Debug": "Depuración de Skulltula de OoT", + "Better Debug Warp Screen": "Mejor Pantalla de Teletransporte de Depuración", + "Debug Warp Screen Translation": "Traducción de Pantalla de Teletransporte", + "Resource logging": "Registro de Recursos", + "Frame Advance": "Avance de Cuadro", + "Advance 1": "Avanzar 1", + "Advance (Hold)": "Avanzar (Mantener)", + "Popout Stats Window": "Abrir Ventana de Estadísticas", + "Stats": "Estadísticas", + "Popout Console": "Abrir Consola", + "Console": "Consola", + "Popout Save Editor": "Abrir Editor de Guardado", + "Save Editor": "Editor de Guardado", + "Popout Hook Debugger": "Abrir Depurador de Hooks", + "Hook Debugger": "Depurador de Hooks", + "Popout Collision Viewer": "Abrir Visor de Colisiones", + "Collision Viewer": "Visor de Colisiones", + "Popout Actor Viewer": "Abrir Visor de Actores", + "Actor Viewer": "Visor de Actores", + "Popout Display List Viewer": "Abrir Visor de Lista de Display", + "Display List Viewer": "Visor de Lista de Display", + "Popout Value Viewer": "Abrir Visor de Valores", + "Value Viewer": "Visor de Valores", + "Popout Message Viewer": "Abrir Visor de Mensajes", + "Message Viewer": "Visor de Mensajes", + "Popout Gfx Debugger": "Abrir Depurador de Gráficos", + "Gfx Debugger": "Depurador de Gráficos", + "DirectX": "DirectX", + "OpenGL": "OpenGL", + "Metal": "Metal", + "Resolution Presets": "Preajustes de Resolución", + "Custom": "Personalizado", + "Original (4:3)": "Original (4:3)", + "Widescreen (16:9)": "Pantalla Amplia (16:9)", + "Nintendo 3DS (5:3)": "Nintendo 3DS (5:3)", + "16:10 (8:5)": "16:10 (8:5)", + "Ultrawide (21:9)": "Ultrawide (21:9)", + "Pixel Count Presets": "Preajustes de Cantidad de Píxeles", + "Native N64 (240p)": "Nativo N64 (240p)", + "2x (480p)": "2x (480p)", + "3x (720p)": "3x (720p)", + "4x (960p)": "4x (960p)", + "5x (1200p)": "5x (1200p)", + "6x (1440p)": "6x (1440p)", + "Full HD (1080p)": "Full HD (1080p)", + "4K (2160p)": "4K (2160p)", + "Set fixed vertical resolution": "Establecer resolución vertical fija", + "Horiz. Pixel Count": "Cantidad de Píxeles Horiz.", + "Force aspect ratio": "Forzar proporción de aspecto", + "Click to resolve": "Clic para resolver", + "Vertical Pixel Count": "Cantidad de Píxeles Vertical", + "Integer Scaling Settings": "Configuración de Escala Entera", + "Pixel Perfect Mode": "Modo Pixel Perfecto", + "Integer scale factor: {}": "Factor de escala entera: {}", + "Window exceeded.": "Ventana excedida.", + "Automatically scale image to fit viewport": "Escalar automáticamente imagen para ajustar", + "Additional Settings": "Configuración Adicional", + "If the image is stretched and you don't know why, click this.": "Si la imagen está estirada y no sabes por qué, haz clic.", + "Click to reenable aspect correction.": "Clic para rehabilitar corrección de aspecto.", + "Show a horizontal resolution field": "Mostrar campo de resolución horizontal", + "Allow integer scale factor to go +1 above maximum screen bounds.": "Permitir factor de escala entera +1 arriba del máximo.", + "A scroll bar may become visible if screen bounds are exceeded.": "Barra de desplazamiento puede aparecer.", + "Click to reset a console variable that may be causing this.": "Clic para reiniciar variable.", + "Viewport dimensions: {} x {}": "Dimensiones de viewport: {} x {}", + "Internal resolution: {} x {}": "Resolución interna: {} x {}", + "Enable advanced settings.": "Habilitar configuración avanzada.", + "Significant frame rate (FPS) drops may be occuring.": "Caídas significativas de FPS pueden estar ocurriendo.", + "N64 Mode is overriding these settings.": "Modo N64 está sobrescribiendo estas configuraciones.", + "Click to disable N64 mode": "Clic para desactivar modo N64", + "Aspect Ratio": "Proporción de Aspecto", + "Disabling VSync not supported": "Desactivar VSync no soportado", + "Windowed Fullscreen not supported": "Pantalla Completa en Ventana no soportada", + "Multi-viewports not supported": "Multi-viewports no soportado", + "Available Only on DirectX": "Solo Disponible en DirectX", + "Not Available on DirectX": "No Disponible en DirectX", + "Match Refresh Rate is Enabled": "Coincidir Tasa de Refresco está Habilitado", + "Advanced Resolution Enabled": "Resolución Avanzada Habilitada", + "Vertical Resolution Toggle Enabled": "Alternar Resolución Vertical Habilitado", + "N64 Mode Enabled": "Modo N64 Habilitado", + "Save Not Loaded": "Guardado No Cargado", + "Debug Mode is Disabled": "Modo Depuración está Desactivado", + "Frame Advance is Disabled": "Avance de Cuadro está Desactivado", + "Advanced Resolution is Disabled": "Resolución Avanzada está Desactivada", + "Vertical Resolution Toggle is Off": "Alternar Resolución Vertical está Apagado", + "A Wallmaster follows Link everywhere, don't get caught!": "¡Un Wallmaster sigue a Link a todas partes, no te dejes atrapar!", + "About": "Acerca de", + "About Crowd Control": "Acerca de Crowd Control", + "Accessibility": "Accesibilidad", + "Activates MSAA (multi-sample anti-aliasing) from 2x up to 8x, to smooth the edges of": "Activa MSAA (antialiasing multiamuestra) de 2x hasta 8x, para suavizar los bordes de", + "Additional Traps": "Trampas Adicionales", + "Adds a prompt to equip newly-obtained Swords, Shields, and Tunics.": "Agrega un aviso para equipar Espadas, Escudos y Túnicas recién obtenidas.", + "Adds back in a delay after unpausing before the game resumes playing again,": "Agrega un retraso después de despausar antes de que el juego se reanude,", + "Adjust the number of notes the Skull Kids play to start the first round.": "Ajusta el número de notas que tocan los Skull Kids para iniciar la primera ronda.", + "Adjust the number of notes you need to play to end the first round.": "Ajusta el número de notas que debes tocar para terminar la primera ronda.", + "Adjust the number of notes you need to play to end the second round.": "Ajusta el número de notas que debes tocar para terminar la segunda ronda.", + "Adjust the number of notes you need to play to end the third round.": "Ajusta el número de notas que debes tocar para terminar la tercera ronda.", + "Adjusts rate Dampe drops flames during race.": "Ajusta la velocidad a la que Dampe lanza llamas durante la carrera.", + "Adjusts the Horizontal Culling Plane to account for Widescreen Resolutions.": "Ajusta el Plano de Recorte Horizontal para tener en cuenta Resoluciones Panorámicas.", + "Adult Minimum Weight: %d lbs.": "Peso Mínimo Adulto: %d lbs.", + "Adult Starting Ammunition: %d arrows": "Munición Inicial Adulto: %d flechas", + "Advance 1 frame.": "Avanzar 1 cuadro.", + "Advance frames while the button is held.": "Avanzar cuadros mientras se mantiene el botón.", + "Aiming with a Bow or Slingshot will display a reticle as with the Hookshot": "Apuntar con Arco o Honda mostrará una retícula como con el Gancho", + "Aiming with the Boomerang will display a reticle as with the Hookshot.": "Apuntar con el Bumerán mostrará una retícula como con el Gancho.", + "All Dogs are Richard": "Todos los Perros son Richard", + "All Fish are Hyrule Loaches": "Todos los Peces son Lochas de Hyrule", + "All Major Bosses move and act twice as fast.": "Todos los Jefes Mayores se mueven y actúan el doble de rápido.", + "All Regular Enemies and Mini-Bosses move and act twice as fast.": "Todos los Enemigos Regulares y Mini-Jefes se mueven y actúan el doble de rápido.", + "All dogs can be traded in and will count as Richard.": "Todos los perros pueden ser intercambiados y contarán como Richard.", + "All fish will be caught instantly.": "Todos los peces se atrapan instantáneamente.", + "All##Skips": "Todos##Saltos", + "Allow Link to enter Jabu-Jabu without feeding him a fish.": "Permitir que Link entre a Jabu-Jabu sin alimentarlo con un pez.", + "Allow Link to put items away without having to wait around.": "Permitir que Link guarde objetos sin tener que esperar.", + "Allow background inputs": "Permitir entradas de fondo", + "Allow multi-windows": "Permitir múltiples ventanas", + "Allow unequipping Items": "Permitir Desequipar Objetos", + "Allows Bombchus to explode out of bounds. Similar to GameCube and Wii VC.": "Permite que las Bombchus exploten fuera de límites. Similar a GameCube y Wii VC.", + "Allows Child Link to use a Bow with Arrows.\n": "Permite que Link Niño use un Arco con Flechas.\n", + "Allows Link to bounce off walls when linear velocity is high enough, this is": "Permite que Link rebote en paredes cuando la velocidad lineal es suficientemente alta, esto es", + "Allows Link to freely change age by playing the Song of Time.\n": "Permite que Link cambie de edad libremente tocando la Canción del Tiempo.\n", + "Allows Link to unsheathe sword without slashing automatically.": "Permite que Link desenvaine la espada sin cortar automáticamente.", + "Allows Z-Targeting Gold Skulltulas.": "Permite Apuntar a las Gold Skulltulas.", + "Allows any item to be equipped, regardless of age.\n": "Permite equipar cualquier objeto, sin importar la edad.\n", + "Allows controller inputs to be picked up by the game even when the game window isn't": "Permite que el juego capture entradas del controlador incluso cuando la ventana del juego no está", + "Allows dogs to follow you anywhere you go, even if you leave the Market.": "Permite que los perros te sigan a donde vayas, incluso si sales del Mercado.", + "Allows equipping Shields, Tunics and Boots to C-Buttons/D-pad.": "Permite equipar Escudos, Túnicas y Botas a los Botones-C/D-pad.", + "Allows graves to be pulled when child during the day.": "Permite tumbar lápidas siendo niño durante el día.", + "Allows masks to be equipped normally from the pause menu as adult.": "Permite que las máscaras se equipen normalmente desde el menú de pausa como adulto.", + "Allows multiple windows to be opened at once. Requires a reload to take effect.": "Permite abrir múltiples ventanas a la vez. Requiere recargar para tener efecto.", + "Allows the cursor on the pause menu to be over any slot. Sometimes required in Randomizer": "Permite que el cursor del menú de pausa esté sobre cualquier ranura. A veces requerido en Randomizer", + "Allows unequipping items from C-Buttons/D-pad by hovering over an equipped": "Permite desequipar objetos de los Botones-C/d-pad pasando el cursor sobre un equipado", + "Allows you to control a Bombchu after dropping it.\n": "Permite controlar una Bombchu después de soltarla.\n", + "Allows you to have \"Link\" as a premade file name.": "Permite tener \"Link\" como nombre de archivo predeterminado.", + "Allows you to use any item at any location": "Permite usar cualquier objeto en cualquier ubicación", + "Allows you to walk through walls.": "Permite caminar a través de paredes.", + "Always Win Dampe Digging Game": "Ganar Siempre Juego de Excavación de Dampe", + "Always Win Goron Pot": "Ganar Siempre Olla Goron", + "Always get the Heart Piece/Purple Rupee from the Spinning Goron Pot.": "Obtener siempre la Pieza de Corazón/Rupia Púrpura de la Olla Giratoria Goron.", + "Always shows dungeon entrance icons on the Minimap.": "Siempre muestra iconos de entrada de mazmorras en el Minimapa.", + "Ammo": "Munición", + "Ammo Traps": "Trampas de Munición", + "Amy's block pushing puzzle instantly solved.": "Puzzle de empujar bloques de Amy resuelto instantáneamente.", + "Anti-aliasing (MSAA)": "Antialiasing (MSAA)", + "Any Ocarina + Master Sword": "Cualquier Ocarina + Espada Maestra", + "Arrow Cycle": "Ciclo de Flechas", + "Assignable Shields, Tunics and Boots": "Escudos, Túnicas y Botas Asignables", + "Audio": "Audio", + "Audio Fixes": "Arreglos de Audio", + "Autosave": "Autoguardado", + "Be sure to explore the Presets and Enhancements Menus for various Speedups and Quality of life changes!": "¡Asegúrate de explorar los menús de Preajustes y Mejoras para varias aceleraciones y cambios de calidad de vida!", + "Beta Quest": "Misión Beta", + "Beta Quest World: %d": "Mundo de Misión Beta: %d", + "Blue Fire dropped from bottle can be bottled.": "Fuego Azul derramado de botella puede ser embotellado.", + "Bomb Timer Multiplier: %.2fx": "Multiplicador de Temporizador de Bomba: %.2fx", + "Bomb Traps": "Trampas de Bomba", + "Bombchu Bowling": "Bolos de Bombchu", + "Bombchu Count: %d bombchus": "Cantidad de Bombchus: %d bombchus", + "Bombchus Out of Bounds": "Bombchus Fuera de Límites", + "Bombchus do not sell out when bought, and a 10 pack of Bombchus costs 99 rupees": "Las Bombchus no se agotan al comprarlas, y un paquete de 10 cuesta 99 rupias", + "Bombchus will sometimes drop in place of Bombs.": "Las Bombchus a veces caerán en lugar de Bombas.", + "Bonk Damage Multiplier": "Multiplicador de Daño por Golpe", + "Boot": "Inicio", + "Boot Sequence": "Secuencia de Inicio", + "Bottles": "Botellas", + "Bounce off Walls": "Rebotar en Paredes", + "Buffers your inputs to be executed a specified amount of frames later.": "Almacena tus entradas para ser ejecutadas una cantidad específica de cuadros después.", + "Bugs don't Despawn": "Los Bichos no Desaparecen", + "Burn Traps": "Trampas de Quemadura", + "Button Combination:": "Combinación de Botones:", + "Buttons that activate Speed Modifier 1.\n\n": "Botones que activan el Modificador de Velocidad 1.\n\n", + "Buttons to activate target switching.": "Botones para activar cambio de objetivo.", + "Camera Fixes": "Arreglos de Cámara", + "Cancel": "Cancelar", + "Causes your Wallet to fill and empty faster when you gain or lose money.": "Hace que tu Billetera se llene y vacíe más rápido al ganar o perder dinero.", + "Change Age": "Cambiar Edad", + "Changes Heart Piece and Heart Container functionality.\n\n": "Cambia la funcionalidad de Piezas de Corazón y Contenedores de Corazón.\n\n", + "Changes the behavior of debug file select creation (creating a save file on slot 1": "Cambia el comportamiento de creación de archivo de depuración (crear un archivo en la ranura 1", + "Changes the menu display from overlay to windowed.": "Cambia la visualización del menú de superpuesto a ventana.", + "Child Minimum Weight: %d lbs.": "Peso Mínimo Niño: %d lbs.", + "Child Starting Ammunition: %d seeds": "Munición Inicial Niño: %d semillas", + "Clear": "Limpiar", + "Clear Config": "Limpiar Configuración", + "Clear Cutscene Pointer": "Limpiar Puntero de Cinemática", + "Clear Devices": "Limpiar Dispositivos", + "Clears the cutscene pointer to a value safe for wrong warps.": "Limpia el puntero de cinemática a un valor seguro para wrong warps.", + "Climb Everything": "Escalar Todo", + "Configure what happens when starting or resetting the game.\n\n": "Configura qué sucede al iniciar o reiniciar el juego.\n\n", + "Connect to Crowd Control": "Conectar a Crowd Control", + "Connecting...": "Conectando...", + "Connecting...##Sail": "Conectando...##Sail", + "Containers of Agony": "Contenedores de Agonía", + "Convenience": "Conveniencia", + "Correctly centers the Navi text prompt on the HUD's C-Up button.": "Centra correctamente el aviso de texto de Navi en el botón C-Arriba del HUD.", + "Creates a new random seed value to be used when generating a randomizer": "Crea un nuevo valor de semilla aleatoria para usar al generar un randomizer", + "Crowd Control is a platform that allows viewers to interact": "Crowd Control es una plataforma que permite a los espectadores interactuar", + "Cuccos Needed By Anju: %d": "Cuccos Necesarios por Anju: %d", + "Cuccos Stay Put Multiplier: %dx": "Multiplicador de Cuccos Quietos: %dx", + "Current FPS": "FPS Actuales", + "Cursor Always Visible": "Cursor Siempre Visible", + "Customize Behavior##Bowling": "Personalizar Comportamiento##Bolos", + "Customize Behavior##Fishing": "Personalizar Comportamiento##Pesca", + "Customize Behavior##Frogs": "Personalizar Comportamiento##Ranas", + "Customize Behavior##LostWoods": "Personalizar Comportamiento##BosquePerdido", + "Customize Behavior##Shooting": "Personalizar Comportamiento##Tiro", + "Damage Multiplier": "Multiplicador de Daño", + "Dampe Drop Rate": "Tasa de Caída de Dampe", + "Dampe's Inferno": "Infierno de Dampe", + "Death Traps": "Trampas de Muerte", + "Debug Warp Screen": "Pantalla de Teletransporte Debug", + "Deku Sticks:": "Palos Deku:", + "Delete File on Death": "Eliminar Archivo al Morir", + "Despawn Timers": "Temporizadores de Desaparición", + "Desync Fixes": "Arreglos de Desincronización", + "Dev Tools": "Htas. Desarrollo", + "Disable 2D Pre-Rendered Scenes": "Desactivar Escenas Pre-renderizadas 2D", + "Disable Fixed Camera": "Desactivar Cámara Fija", + "Disable Haunted Wasteland Sandstorm": "Desactivar Tormenta de Arena del Páramo", + "Disable Idle Camera Re-Centering": "Desactivar Recentrado de Cámara en Reposo", + "Disable Jabu Wobble": "Desactivar Bamboleo de Jabu", + "Disable Kokiri Fade": "Desactivar Desvanecimiento Kokiri", + "Disable Link Spinning With Goron Pot": "Desactivar Giro de Link con Olla Goron", + "Disable Link's Sword Trail": "Desactivar Estela de Espada de Link", + "Disable Random Camera Wiggle at Low Health.": "Desactivar Movimiento Aleatorio de Cámara con Poca Salud.", + "Disable Screen Flash for Finishing Blow": "Desactivar Flash de Pantalla para Golpe Final", + "Disable the geometry wobble and camera distortion inside Jabu.": "Desactivar el bamboleo de geometría y distorsión de cámara dentro de Jabu.", + "Disabled: Paths vanish more the higher the resolution (Z-Fighting is based on resolution).\n": "Desactivado: Los caminos desaparecen más cuanto mayor es la resolución (Z-Fighting depende de la resolución).\n", + "Disables 2D pre-rendered backgrounds. Enable this when using a mod that": "Desactiva fondos pre-renderizados 2D. Habilita esto al usar un mod que", + "Disables Random Drops, except from the Goron Pot, Dampe, and Bosses.": "Desactiva Caídas Aleatorias, excepto de la Olla Goron, Dampe y Jefes.", + "Disables sandstorm effect in Haunted Wasteland.": "Desactiva el efecto de tormenta de arena en el Páramo Encantado.", + "Disables the Beating Animation of the Hearts on the HUD.": "Desactiva la Animación de Latido de los Corazones en el HUD.", + "Disables the sword trail effect when swinging Link's sword. Useful when": "Desactiva el efecto de estela de espada al balancear la espada de Link. Útil cuando", + "Disables the white screen flash on enemy kill.": "Desactiva el flash de pantalla blanca al matar enemigos.", + "Disables warning text when you don't have on the Goron/Zora Tunic": "Desactiva texto de advertencia cuando no tienes puesta la Túnica Goron/Zora", + "Dogs Follow You Everywhere": "Los Perros te Siguen a Todas Partes", + "Don't affect jump distance/velocity": "No afecta distancia/velocidad de salto", + "Don't increase crawl speed when exiting glitch-useful crawlspaces.": "No aumentar velocidad de arrastre al salir de espacios de arrastre útiles para glitches.", + "Don't scale image to fill window.": "No escalar imagen para llenar ventana.", + "Don't skip cutscenes that are associated with useful glitches. Currently, it is": "No saltar cinemáticas asociadas con glitches útiles. Actualmente, es", + "Drops": "Caídas", + "Drops Don't Despawn": "Las Caídas no Desaparecen", + "Drops from enemies, grass, etc. don't disappear after a set amount of time.": "Las caídas de enemigos, hierba, etc. no desaparecen después de un tiempo establecido.", + "Dying will delete your file.\n\n": "Morir eliminará tu archivo.\n\n", + "Early Eyeball Frog": "Rana Ojo Temprana", + "Easy Frame Advancing with Pause": "Avance de Cuadro Fácil con Pausa", + "Easy ISG": "ISG Fácil", + "Easy QPA": "QPA Fácil", + "Empty Bottles Faster": "Vaciar Botellas Más Rápido", + "Enable Beta Quest": "Habilitar Misión Beta", + "Enable Bombchu Drops": "Habilitar Caída de Bombchus", + "Enable Visual Guard Vision": "Habilitar Visión Visual de Guardia", + "Enable Vsync": "Habilitar Vsync", + "Enable##CrowdControl": "Habilitar##CrowdControl", + "Enable##Sail": "Habilitar##Sail", + "Enables Debug Mode, allowing you to select maps with L + R + Z, noclip": "Habilita el Modo Debug, permitiéndote seleccionar mapas con L + R + Z, noclip", + "Enables Skulltula Debug, when moving the cursor in the menu above various": "Habilita Debug de Skulltula, al mover el cursor en el menú sobre varios", + "Enables additional Trap variants.": "Habilita variantes adicionales de Trampas.", + "Enables the registry editor.": "Habilita el editor de registro.", + "Enables the separate Actor Viewer Window.": "Habilita la ventana separada de Visor de Actores.", + "Enables the separate Additional Timers Window.": "Habilita la ventana separada de Temporizadores Adicionales.", + "Enables the separate Audio Editor Window.": "Habilita la ventana separada de Editor de Audio.", + "Enables the separate Check Tracker Settings Window.": "Habilita la ventana separada de Configuración de Rastreador de Checks.", + "Enables the separate Collision Viewer Window.": "Habilita la ventana separada de Visor de Colisiones.", + "Enables the separate Console Window.": "Habilita la ventana separada de Consola.", + "Enables the separate Cosmetics Editor Window.": "Habilita la ventana separada de Editor de Cosméticos.", + "Enables the separate Display List Viewer Window.": "Habilita la ventana separada de Visor de Lista de Display.", + "Enables the separate Entrance Tracker Settings Window.": "Habilita la ventana separada de Configuración de Rastreador de Entradas.", + "Enables the separate Gameplay Stats Window.": "Habilita la ventana separada de Estadísticas de Jugabilidad.", + "Enables the separate Gfx Debugger Window.": "Habilita la ventana separada de Depurador de Gráficos.", + "Enables the separate Hook Debugger Window.": "Habilita la ventana separada de Depurador de Hooks.", + "Enables the separate Input Viewer Settings Window.": "Habilita la ventana separada de Configuración de Visor de Entradas.", + "Enables the separate Item Tracker Settings Window.": "Habilita la ventana separada de Configuración de Rastreador de Objetos.", + "Enables the separate Message Viewer Window.": "Habilita la ventana separada de Visor de Mensajes.", + "Enables the separate Mod Menu Window.": "Habilita la ventana separada de Menú de Mods.", + "Enables the separate Save Editor Window.": "Habilita la ventana separada de Editor de Guardado.", + "Enables the separate Stats Window.": "Habilita la ventana separada de Estadísticas.", + "Enables the separate Time Splits Window.": "Habilita la ventana separada de Divisiones de Tiempo.", + "Enables the separate Value Viewer Window.": "Habilita la ventana separada de Visor de Valores.", + "Enemies": "Enemigos", + "Enemies spawned by CrowdControl won't be considered for \"clear enemy": "Los enemigos generados por CrowdControl no se considerarán para \"enemigo despejado\"", + "Enemy Name Tags": "Etiquetas de Nombre de Enemigos", + "Enhancements": "Mejoras", + "Epona Boost": "Impulso de Epona", + "Every fish in the Fishing Pond will always be a Hyrule Loach.\n\n": "Todos los peces en el Estanque de Pesca siempre serán Loachas de Hyrule.\n\n", + "Exclude Glitch-Aiding Crawlspaces": "Excluir Espacios de Arrastre para Glitches", + "Excluded Locations": "Ubicaciones Excluidas", + "F5 to save, F6 to change slots, F7 to load": "F5 para guardar, F6 para cambiar ranuras, F7 para cargar", + "Fall Damage Multiplier": "Multiplicador de Daño por Caída", + "Faster + Longer Jump": "Salto Más Rápido + Largo", + "Faster Pause Menu": "Menú de Pausa Más Rápido", + "Faster Run": "Carrera Más Rápida", + "Faster Shadow Ship": "Barco de Sombra Más Rápido", + "Fireproof Deku Shield": "Escudo Deku Ignífugo", + "Fish don't Despawn": "Los Peces no Desaparecen", + "Fish never Escape": "Los Peces Nunca Escapan", + "Fish while Hovering": "Pescar mientras Flotas", + "Fishing": "Pesca", + "Fix Anubis Fireballs": "Arreglar Bolas de Fuego de Anubis", + "Fix Broken Giant's Knife Bug": "Arreglar Bug de Espada del Gigante Rota", + "Fix Bush Item Drops": "Arreglar Caídas de Objetos de Arbustos", + "Fix Camera Drift": "Arreglar Deriva de Cámara", + "Fix Camera Swing": "Arreglar Balanceo de Cámara", + "Fix Credits Timing (PAL)": "Arreglar Tiempo de Créditos (PAL)", + "Fix Dampé Going Backwards": "Arreglar Dampe Yendo Hacia Atrás", + "Fix Darunia Dancing too Fast": "Arreglar Darunia Bailando Demasiado Rápido", + "Fix Deku Nut Upgrade": "Arreglar Mejora de Nuez Deku", + "Fix Dungeon Entrances": "Arreglar Entradas de Mazmorras", + "Fix Enemies not Spawning Near Water": "Arreglar Enemigos que no Aparecen Cerca del Agua", + "Fix Falling from Vine Edges": "Arreglar Caída desde Bordes de Enredadera", + "Fix Gerudo Warrior's Clothing Colors": "Arreglar Colores de Ropa de Guerrera Gerudo", + "Fix Goron City Doors After Fire Temple": "Arreglar Puertas de Ciudad Goron Después del Templo del Fuego", + "Fix Hand Holding Hammer": "Arreglar Mano Sosteniendo Martillo", + "Fix Hanging Ledge Swing Rate": "Arreglar Velocidad de Balanceo de Borde Colgante", + "Fix Kokiri Forest Quest State": "Arreglar Estado de Misión del Bosque Kokiri", + "Fix L&R Pause Menu": "Arreglar Menú de Pausa L&R", + "Fix L&Z Page Switch in Pause Menu": "Arreglar Cambio de Página L&Z en Menú de Pausa", + "Fix Link's Eyes Open while Sleeping": "Arreglar Ojos de Link Abiertos mientras Duerme", + "Fix Megaton Hammer Crouch Stab": "Arreglar Puñalada Agachada con Martillo Megatón", + "Fix Missing Jingle after 5 Silver Rupees": "Arreglar Jingle Faltante después de 5 Rupias de Plata", + "Fix Navi Text HUD Position": "Arreglar Posición de Texto de Navi en HUD", + "Fix Out of Bounds Textures": "Arreglar Texturas Fuera de Límites", + "Fix Poacher's Saw Softlock": "Arreglar Softlock de Sierra de Cazador Furtivo", + "Fix Two-Handed Idle Animations": "Arreglar Animaciones de Inactividad a Dos Manos", + "Fix Vanishing Paths": "Arreglar Caminos que Desaparecen", + "Fix Zora Hint Dialogue": "Arreglar Diálogo de Pista Zora", + "Fixes camera slightly drifting to the left when standing still due to a": "Arregla la deriva leve de la cámara hacia la izquierda al estar quieto debido a un", + "Fixes camera swing rate when the player falls off a ledge and the camera": "Arregla la velocidad de balanceo de cámara cuando el jugador cae de un borde y la cámara", + "Fixes kokiri animation state to match their text state when getting": "Arregla el estado de animación de los kokiri para coincidir con su estado de texto al obtener", + "Fixes the Broken Giant's Knife flag not being reset when Medigoron fixes it.": "Arregla la bandera de Espada del Gigante Rota no siendo reiniciada cuando Medigoron la arregla.", + "Font Scale: %.2fx": "Escala de Fuente: %.2fx", + "Force aspect ratio:": "Forzar proporción de aspecto:", + "Forest Temple": "Templo del Bosque", + "Freeze Time": "Congelar Tiempo", + "Freeze Traps": "Trampas de Congelación", + "Freezes the time of day.": "Congela la hora del día.", + "Frogs' Ocarina Game": "Juego de Ocarina de las Ranas", + "General": "General", + "General Settings": "Configuración General", + "Generate Randomizer": "Generar Randomizer", + "Ghost Pepper": "Chile Fantasma", + "Gives you the glitched damage value of the quick put away glitch.": "Te da el valor de daño glitcheado del glitch de guardado rápido.", + "Glitch Aids": "Ayudas de Glitch", + "Glitch Restorations": "Restauraciones de Glitch", + "Graphical Fixes": "Arreglos Gráficos", + "Graphical Restorations": "Restauraciones Gráficas", + "Graphics": "Gráficos", + "Graphics Options": "Opciones de Gráficos", + "Grave Hole Jumps": "Saltos de Agujero de Tumba", + "Greatly decreases cast time of Farore's Wind magic spell.": "Disminuye enormemente el tiempo de lanzamiento del hechizo Viento de Farore.", + "Guarantee Bite": "Garantizar Mordida", + "Habanero": "Habanero", + "Health": "Salud", + "Hide Background": "Ocultar Fondo", + "Hides most of the UI when not needed.\n": "Oculta la mayor parte de la interfaz cuando no es necesaria.\n", + "Holding L makes you float into the air.": "Mantener L te hace flotar en el aire.", + "Holding down B skips text.": "Mantener presionado B salta el texto.", + "Hookshot Everything": "Gancho a Todo", + "Hookshot Reach Multiplier: %.2fx": "Multiplicador de Alcance del Gancho: %.2fx", + "Host & Port": "Anfitrión y Puerto", + "Hurt Container Mode": "Modo Contenedor Dañino", + "Hyper Bosses": "Jefes Hiper", + "Hyper Enemies": "Enemigos Hiper", + "I promise I have read the warning": "Prometo que he leído la advertencia", + "I understand, enable save states": "Entiendo, habilitar estados de guardado", + "If enabled, signs near loading zones will tell you where they lead to.": "Si está habilitado, los letreros cerca de zonas de carga te dirán a dónde llevan.", + "ImGui Menu Scaling": "Escalado de Menú ImGui", + "Infinite...": "Infinito...", + "Instant Age Change": "Cambio de Edad Instantáneo", + "Instant Fishing": "Pesca Instantánea", + "Instant Win": "Victoria Instantánea", + "Instant Win##Frogs": "Victoria Instantánea##Ranas", + "Instant Win##LostWoods": "Victoria Instantánea##BosquePerdido", + "Instantly return the Boomerang to Link by pressing its item button while": "Devuelve instantáneamente el Bumerán a Link presionando su botón de objeto mientras", + "Integer scales the image. Only available in Pixel Perfect Mode.": "Escala la imagen en números enteros. Solo disponible en Modo Pixel Perfect.", + "Internal Resolution": "Resolución Interna", + "Interval between Rupee reduction in Rupee Dash Mode.": "Intervalo entre reducción de Rupias en Modo Rupee Dash.", + "Introduces Options for unequipping Link's sword\n\n": "Introduce Opciones para desequipar la espada de Link\n\n", + "Item-related Fixes": "Arreglos Relacionados con Objetos", + "Ivan the Fairy (Coop Mode)": "Ivan el Hada (Modo Coop)", + "Jabber Nut Colors Match Kind": "Colores de Nueces Jabber Coinciden con Tipo", + "Jalapeño": "Jalapeño", + "Keese/Guay don't Target You": "Keese/Guay no te Apuntan", + "King Zora Speed: %.2fx": "Velocidad de Rey Zora: %.2fx", + "Knockback Traps": "Trampas de Retroceso", + "Language": "Idioma", + "Languages": "Idiomas", + "Leever Spawn Rate: %d seconds": "Tasa de Aparición de Leever: %d segundos", + "Link will not spin when the Goron Pot starts to spin.": "Link no girará cuando la Olla Goron comience a girar.", + "Loaches always Appear": "Las Lochas Siempre Aparecen", + "Loaches will always appear in the fishing pond instead of every four visits.": "Las lochas siempre aparecerán en el estanque de pesca en lugar de cada cuatro visitas.", + "Log Level": "Nivel de Registro", + "Logs some resources as XML when they're loaded in binary format.": "Registra algunos recursos como XML cuando se cargan en formato binario.", + "Lost Woods Ocarina Game": "Juego de Ocarina del Bosque Perdido", + "Magic": "Magia", + "Make Deku Nuts explode Bombs, similar to how they interact with Bombchus.": "Hace que las Nueces Deku exploten Bombas, similar a como interactúan con Bombchus.", + "Make crouch stabbing always do the same damage as a regular slash.": "Hace que la puñalada agachada siempre haga el mismo daño que un corte regular.", + "Makes Link always kick the chest to open it, instead of doing the longer": "Hace que Link siempre patee el cofre para abrirlo, en lugar de hacer la animación más larga", + "Makes all equipment visible, regardless of age.": "Hace que todo el equipo sea visible, sin importar la edad.", + "Makes every surface in the game climbable.": "Hace que cada superficie en el juego sea escalable.", + "Makes every surface in the game hookshotable.": "Hace que cada superficie en el juego sea alcanzable con el gancho.", + "Makes every tunic have the effects of every other tunic.": "Hace que cada túnica tenga los efectos de todas las demás túnicas.", + "Makes the L and R buttons in the pause menu the same color.": "Hace que los botones L y R en el menú de pausa sean del mismo color.", + "Manual seed entry": "Entrada manual de semilla", + "Map Select Button Combination:": "Combinación de Botones de Selección de Mapa:", + "Match Refresh Rate": "Coincidir Tasa de Refresco", + "Matches interpolation value to the refresh rate of your display.": "Coincide el valor de interpolación con la tasa de refresco de tu pantalla.", + "Matches the color of maps & compasses to the dungeon they belong to.": "Coincide el color de mapas y brújulas con la mazmorra a la que pertenecen.", + "Menu Background Opacity": "Opacidad de Fondo del Menú", + "Menu Controller Navigation": "Navegación de Controlador del Menú", + "Menu Settings": "Configuración del Menú", + "Menu Theme": "Tema del Menú", + "Mirrored World": "Mundo Espejado", + "Misc Restorations": "Restauraciones Varias", + "Miscellaneous": "Misceláneo", + "Modifies Damage taken after Bonking.": "Modifica el Daño recibido después de Golpearse.", + "Modifies damage taken after falling into a void:\n": "Modifica el daño recibido al caer en un vacío:\n", + "Modify Note Timer: %dx": "Modificar Temporizador de Notas: %dx", + "Money": "Dinero", + "Moon Jump on L": "Salto Lunar en L", + "MoreResolutionSettings": "MásConfiguracionesDeResolución", + "Multiplier:": "Multiplicador:", + "Multiplies your output resolution by the value inputted, as a more intensive but effective": "Multiplica tu resolución de salida por el valor ingresado, como una forma más intensiva pero efectiva", + "Mute Notification Sound": "Silenciar Sonido de Notificación", + "N64 Weird Frames": "Cuadros Extraños N64", + "Nayru's Love": "Amor de Nayru", + "Network": "Red", + "Nighttime Skulltulas will spawn during both day and night.": "Las Skulltulas nocturnas aparecerán tanto de día como de noche.", + "No Clip": "Sin Colisión", + "No Clip Button Combination:": "Combinación de Botones Sin Colisión:", + "No Heart Drops": "Sin Caídas de Corazones", + "No Random Drops": "Sin Caídas Aleatorias", + "No ReDead/Gibdo Freeze": "Sin Congelación de ReDead/Gibdo", + "No Rupee Randomization": "Sin Aleatorización de Rupias", + "None##Skips": "Ninguno##Saltos", + "Note Play Speed: %dx": "Velocidad de Reproducción de Notas: %dx", + "Notification on Autosave": "Notificación de Autoguardado", + "Number of Starting Notes: %d notes": "Número de Notas Iniciales: %d notas", + "OHKO": "KO", + "Ocarina of Time + Master Sword": "Ocarina del Tiempo + Espada Maestra", + "Once a hook as been set, Fish will never let go while being reeled in.": "Una vez que se ha puesto un gancho, los peces nunca soltarán mientras se recogen.", + "Only change the texture of containers if you have the Stone of Agony.": "Cambiar solo la textura de contenedores si tienes la Piedra de Agonía.", + "Open App Files Folder": "Abrir Carpeta de Archivos de la App", + "Optimized Debug Warp Screen, with the added ability to chose entrances and time of day.": "Pantalla de Teletransporte Debug optimizada, con la capacidad añadida de elegir entradas y hora del día.", + "Override the resolution scale slider and use the settings below, irrespective of window size.": "Anular el control deslizante de escala de resolución y usar las configuraciones de abajo, independientemente del tamaño de ventana.", + "Passive Infinite Sword Glitch\n": "Glitch de Espada Infinita Pasiva\n", + "Permanent Heart Loss": "Pérdida Permanente de Corazón", + "Popout Audio Editor Window": "Abrir Ventana de Editor de Audio", + "Popout Bindings Window": "Abrir Ventana de Controles", + "Popout Cosmetics Editor Window": "Abrir Ventana de Editor de Cosméticos", + "Popout Gameplay Stats Window": "Abrir Ventana de Estadísticas de Jugabilidad", + "Popout Input Viewer Settings": "Abrir Configuración de Visor de Entradas", + "Popout Mod Menu Window": "Abrir Ventana de Menú de Mods", + "Popout Time Splits Window": "Abrir Ventana de Divisiones de Tiempo", + "Position": "Posición", + "Prevent dropping inputs when playing the Ocarina too quickly.": "Prevenir pérdida de entradas al tocar la Ocarina demasiado rápido.", + "Prevent forced conversations with Navi and/or other NPCs.": "Prevenir conversaciones forzadas con Navi y/o otros NPCs.", + "Prevent notifications from playing a sound.": "Prevenir que las notificaciones reproduzcan un sonido.", + "Prevents ReDeads and Gibdos from being able to freeze you with their scream.": "Previene que ReDeads y Gibdos puedan congelarte con su grito.", + "Prevents bugs from automatically despawning after a while when dropped.": "Previene que los bichos desaparezcan automáticamente después de un tiempo al soltarlos.", + "Prevents fish from automatically despawning after a while when dropped.": "Previene que los peces desaparezcan automáticamente después de un tiempo al soltarlos.", + "Prevents immediately falling off climbable surfaces if climbing on the edges.": "Previene caer inmediatamente de superficies escalables si estás escalando en los bordes.", + "Prevents integer scaling factor from exceeding screen bounds.\n\n": "Previene que el factor de escala entero exceda los límites de la pantalla.\n\n", + "Prevents the Deku Shield from burning on contact with fire.": "Previene que el Escudo Deku se queme al contacto con fuego.", + "Prevents the Forest Stage Deku Nut upgrade from becoming unobtainable": "Previene que la mejora de Nuez Deku del Bosque se vuelva inalcanzable", + "Prevents the big Cucco from appearing in the Bombchu Bowling minigame.": "Previene que el Cucco grande aparezca en el minijuego de Bolos de Bombchu.", + "Prevents the small Cucco from appearing in the Bombchu Bowling minigame.": "Previene que el Cucco pequeño aparezca en el minijuego de Bolos de Bombchu.", + "Pulsate Boss Icon": "Icono de Jefe Pulsante", + "Quick Bongo Kill": "Muerte Rápida de Bongo", + "Quick Putaway": "Guardado Rápido", + "Randomize All Settings": "Aleatorizar Todas las Configuraciones", + "Randomizes all randomizer settings to random valid values (excludes tricks).": "Aleatoriza todas las configuraciones del randomizer a valores válidos aleatorios (excluye trucos).", + "Rebottle Blue Fire": "Reembottellar Fuego Azul", + "Red Ganon Blood": "Sangre de Ganon Roja", + "Remember Save Location": "Recordar Ubicación de Guardado", + "Remote Bombchu": "Bombchu Remota", + "Remove Big Cucco": "Eliminar Cucco Grande", + "Remove Power Crouch Stab": "Eliminar Puñalada Agachada de Poder", + "Remove Small Cucco": "Eliminar Cucco Pequeño", + "Remove the Darkness that appears when charging a Spin Attack.": "Eliminar la Oscuridad que aparece al cargar un Ataque Giratorio.", + "Removes the cap of 3 active explosives being deployed at once.": "Elimina el límite de 3 explosivos activos desplegados a la vez.", + "Removes the timer to play back the song.": "Elimina el temporizador para reproducir la canción.", + "Renders Gauntlets when using the Bow and Hookshot like in OoT3D.": "Renderiza Guanteletes al usar el Arco y Gancho como en OoT3D.", + "Renders a health bar for Enemies when Z-Targeted.": "Renderiza una barra de salud para Enemigos cuando se Apunta con Z.", + "Replace Navi's overworld quest hints with rando-related gameplay hints.": "Reemplaza las pistas de misión del mundo de Navi con pistas de jugabilidad relacionadas con rando.", + "Reset Button Combination:": "Combinación de Botones de Reinicio:", + "Resets the Navi timer on scene change. If you have already talked to her,": "Reinicia el temporizador de Navi al cambiar de escena. Si ya has hablado con ella,", + "Respawn with Full Health instead of 3 hearts.": "Reaparecer con Salud Completa en lugar de 3 corazones.", + "Restore Old Gold Skulltula Cutscene": "Restaurar Cinemática de Gold Skulltula Antigua", + "Restore the original red blood from NTSC 1.0/1.1. Disable for Green blood.": "Restaurar la sangre roja original de NTSC 1.0/1.1. Desactivar para sangre verde.", + "Restores the wider range of certain shutter doors from NTSC 1.0.\n": "Restaura el rango más amplio de ciertas puertas correderas de NTSC 1.0.\n", + "Reworked Targeting": "Apuntado Retrabajado", + "Reworks targeting functionality\n": "Retrabaja la funcionalidad de apuntado\n", + "Round One Notes: %d notes": "Notas de la Ronda Uno: %d notas", + "Round Three Notes: %d notes": "Notas de la Ronda Tres: %d notas", + "Round Two Notes: %d notes": "Notas de la Ronda Dos: %d notas", + "Rupee Dash Interval %d seconds": "Intervalo de Rupee Dash %d segundos", + "Rupee Dash Mode": "Modo Rupee Dash", + "Rupees reduce over time, Link suffers damage when the count hits 0.": "Las rupias se reducen con el tiempo, Link sufre daño cuando el conteo llega a 0.", + "Sail": "Sail", + "Sail is a networking protocol designed to facilitate remote": "Sail es un protocolo de red diseñado para facilitar remoto", + "Save States": "Estados de Guardado", + "Search In Sidebar": "Buscar en Barra Lateral", + "Search Input Autofocus": "Autoenfoque de Entrada de Búsqueda", + "Seed": "Semilla", + "Seed Entry": "Entrada de Semilla", + "Select the UI translation language...": "Seleccionar el idioma de traducción de la interfaz...", + "Serrano": "Serrano", + "Settings": "Configuración", + "Shadow Tag Mode": "Modo Sombra Pegajosa", + "Shield with Two-Handed Weapons": "Escudo con Armas a Dos Manos", + "Shock Traps": "Trampas de Choque", + "Shooting Gallery": "Galería de Tiro", + "Shops and Minigames are open both day and night. Requires a scene reload to take effect.": "Tiendas y Minijuegos están abiertos de día y de noche. Requiere recargar escena para tener efecto.", + "Show Gauntlets in First-Person": "Mostrar Guanteletes en Primera Persona", + "Show a notification when the game is autosaved.": "Mostrar una notificación cuando el juego se autoguarda.", + "Signs Hint Entrances": "Letreros Indican Entradas", + "Skip Bottle Pickup Messages": "Saltar Mensajes de Recoger Botella", + "Skip Consumable Item Pickup Messages": "Saltar Mensajes de Recoger Objetos Consumibles", + "Skip Feeding Jabu-Jabu": "Saltar Alimentar a Jabu-Jabu", + "Skip Keep Confirmation": "Saltar Confirmación de Keep", + "Skip One Point Cutscenes (Chests, Door Unlocks, etc.)": "Saltar Cinemáticas de Un Punto (Cofres, Apertura de Puertas, etc.)", + "Skip Pickup Messages for Bottle Swipes.": "Saltar Mensajes de Recoger para Botellas.", + "Skip Pickup Messages for new Consumable Items.": "Saltar Mensajes de Recoger para Objetos Consumibles nuevos.", + "Skip Playing Scarecrow's Song": "Saltar Tocar Canción del Espantapájaros", + "Skip the \"Game Saved\" confirmation screen.": "Saltar la pantalla de confirmación \"Juego Guardado\".", + "Skip the part where the Ocarina Playback is called when you play a song.": "Saltar la parte donde se llama la Reproducción de Ocarina al tocar una canción.", + "Skip the tower escape sequence between Ganondorf and Ganon.": "Saltar la secuencia de escape de la torre entre Ganondorf y Ganon.", + "Skips Link's taking breath animation after coming up from water.": "Salta la animación de Link tomando aire al salir del agua.", + "Skips the Frogs' Ocarina Game.": "Salta el Juego de Ocarina de las Ranas.", + "Skips the Lost Woods Ocarina Memory Game.": "Salta el Juego de Memoria de Ocarina del Bosque Perdido.", + "Skips the Shooting Gallery minigame.": "Salta el minijuego de la Galería de Tiro.", + "Solve Amy's Puzzle": "Resolver Puzzle de Amy", + "Spawn Bean Skulltula Faster": "Aparecer Bean Skulltula Más Rápido", + "Spawn with Full Health": "Aparecer con Salud Completa", + "Spawned Enemies Ignored Ingame": "Enemigos Generados Ignorados en el Juego", + "Speak to Navi with L but enter First-Person Camera with C-Up.": "Hablar con Navi con L pero entrar a Cámara en Primera Persona con C-Arriba.", + "Speed Modifier": "Modificador de Velocidad", + "Speed Traps": "Trampas de Velocidad", + "Speeds up animation of the pause menu, similar to Majora's Mask": "Acelera la animación del menú de pausa, similar a Majora's Mask", + "Speeds up emptying animation when dumping out the contents of a bottle.": "Acelera la animación de vaciado al verter el contenido de una botella.", + "Speeds up lifting Silver Rocks and Obelisks.": "Acelera el levantamiento de Rocas de Plata y Obeliscos.", + "Speeds up ship in Shadow Temple.": "Acelera el barco en el Templo de las Sombras.", + "Spoiler File": "Archivo de Spoiler", + "Stops masks from automatically unequipping on certain situations:\n": "Detiene que las máscaras se desequen automáticamente en ciertas situaciones:\n", + "Super Tunic": "Super Túnica", + "Switch Timer Multiplier": "Multiplicador de Temporizador de Cambio", + "Switches Link's age and reloads the area.": "Cambia la edad de Link y recarga el área.", + "Syncs the in-game time with the real world time.": "Sincroniza el tiempo del juego con el tiempo del mundo real.", + "Target Switch Button Combination:": "Combinación de Botones de Cambio de Objetivo:", + "Targetable Gold Skulltula": "Gold Skulltula Apuntable", + "Teleport Traps": "Trampas de Teletransporte", + "Text to Speech": "Texto a Voz", + "Texture Filter (Needs reload)": "Filtro de Textura (Necesita recargar)", + "The Pond Owner will not ask to confirm if you want to keep a smaller Fish.": "El Dueño del Estanque no pedirá confirmar si quieres quedarte con un Pez más pequeño.", + "The ammunition at the start of the Shooting Gallery minigame as Adult.": "La munición al inicio del minijuego de Galería de Tiro como Adulto.", + "The ammunition at the start of the Shooting Gallery minigame as Child.": "La munición al inicio del minijuego de Galería de Tiro como Niño.", + "The log level determines which messages are printed to the console.": "El nivel de registro determina qué mensajes se imprimen en la consola.", + "The number of Bombchus available at the start of the Bombchu Bowling minigame.": "El número de Bombchus disponibles al inicio del minijuego de Bolos de Bombchu.", + "The skybox in the background of the File Select screen will go through the": "El skybox en el fondo de la pantalla de Selección de Archivo pasará por el", + "The time between groups of Leevers spawning.": "El tiempo entre grupos de Leevers apareciendo.", + "These are NOT like emulator states. They do not save your game progress": "Estos NO son como estados de emulador. No guardan tu progreso del juego", + "These enhancements are only useful in the Randomizer mode but do not affect the randomizer logic.": "Estas mejoras solo son útiles en el modo Randomizer pero no afectan la lógica del randomizer.", + "This will completely erase the controls config, including registered devices.\nContinue?": "Esto borrará completamente la configuración de controles, incluyendo dispositivos registrados.\n¿Continuar?", + "Tier 1 Traps:": "Trampas de Nivel 1:", + "Tier 2 Traps:": "Trampas de Nivel 2:", + "Tier 3 Traps:": "Trampas de Nivel 3:", + "Time Sync": "Sincronización de Tiempo", + "Timeless Equipment": "Equipo Atemporal", + "Toggle Fullscreen": "Alternar Pantalla Completa", + "Toggle Input Viewer": "Alternar Visor de Entradas", + "Toggle Timers Window": "Alternar Ventana de Temporizadores", + "Toggle modifier instead of holding": "Alternar modificador en lugar de mantener", + "Toggles the Check Tracker.": "Alterna el Rastreador de Checks.", + "Toggles the Entrance Tracker.": "Alterna el Rastreador de Entradas.", + "Toggles the Item Tracker.": "Alterna el Rastreador de Objetos.", + "Translate Title Screen": "Traducir Pantalla de Título", + "Translate the Debug Warp Screen based on the game language.": "Traducir la Pantalla de Teletransporte Debug según el idioma del juego.", + "Trap Options": "Opciones de Trampas", + "Trees Drop Sticks": "Los Árboles Suelten Palos", + "Tricks/Glitches": "Trucos/Glitches", + "Turn on/off changes to the Bombchu Bowling behavior.": "Activar/desactivar cambios al comportamiento de Bolos de Bombchu.", + "Turn on/off changes to the Fishing behavior.": "Activar/desactivar cambios al comportamiento de Pesca.", + "Turn on/off changes to the Frogs' Ocarina Game behavior.": "Activar/desactivar cambios al comportamiento del Juego de Ocarina de las Ranas.", + "Turn on/off changes to the Lost Woods Ocarina Game behavior.": "Activar/desactivar cambios al comportamiento del Juego de Ocarina del Bosque Perdido.", + "Turn on/off changes to the shooting gallery behavior.": "Activar/desactivar cambios al comportamiento de la galería de tiro.", + "Turns Bunny Hood Invisible while still maintaining its effects.": "Vuelve invisible la Máscara de Conejo mientras mantiene sus efectos.", + "Turns on OoT Beta Quest. *WARNING*: This will reset your game!": "Activa la Misión Beta de OoT. *ADVERTENCIA*: ¡Esto reiniciará tu juego!", + "Turns the Static Image of Link in the Pause Menu's Equipment Subscreen": "Convierte la Imagen Estática de Link en la Subpantalla de Equipo del Menú de Pausa", + "UI Translation": "Traducción de Interfaz", + "Unlimited Playback Time##Frogs": "Tiempo de Reproducción Ilimitado##Ranas", + "Unlimited Playback Time##LostWoods": "Tiempo de Reproducción Ilimitado##BosquePerdido", + "Unrestricted Items": "Objetos Sin Restricciones", + "Unsheathe Sword Without Slashing": "Desenvainar Espada sin Cortar", + "Use Custom graphics for Dungeon Keys, Big and Small, so that they can be easily told apart.": "Usar gráficos personalizados para Llaves de Mazmorra, Grandes y Pequeñas, para que puedan distinguirse fácilmente.", + "Void Damage Multiplier": "Multiplicador de Daño de Vacío", + "Void Traps": "Trampas de Vacío", + "Warp Point": "Punto de Teletransporte", + "Warp Points": "Puntos de Teletransporte", + "Warping": "Teletransporte", + "Wearing the Bunny Hood grants a speed and jump boost like in Majora's Mask.\n": "Usar la Máscara de Conejo otorga un aumento de velocidad y salto como en Majora's Mask.\n", + "When a line is stable, guarantee bite. Otherwise use Default logic.": "Cuando una línea es estable, garantizar mordida. De lo contrario usar lógica predeterminada.", + "When obtaining Rupees, randomize what the Rupee is called in the textbox.": "Al obtener Rupias, aleatorizar cómo se llama la Rupia en el cuadro de texto.", + "Wide Door Ranges": "Rangos de Puertas Anchos", + "Windowed Fullscreen": "Pantalla Completa en Ventana", + "With Shuffle Speak, jabber nut model & color will be generic.": "Con Shuffle Speak, el modelo y color de nuez jabber será genérico.", + "https://github.com/HarbourMasters/sail": "https://github.com/HarbourMasters/sail", + "AspectRatioCustom": "ProporciónPersonalizada", + "AspectSep": "SepProporción", + "Automatically sets scale factor to fit window. Only available in Pixel Perfect Mode.": "Establece automáticamente el factor de escala para ajustar a la ventana. Solo disponible en Modo Pixel Perfect.", + "Item Pool": "Lista de Objetos", + "Logic": "Logica" + } +} diff --git a/soh.desktop b/soh.desktop new file mode 100644 index 000000000..5e517c597 --- /dev/null +++ b/soh.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Version=1.0 +Name=SOH +Exec=soh.elf +Terminal=false +Icon=sohIcon +Type=Application +Categories=Game; +X-AppImage-Integrate=false diff --git a/soh/soh/Localization.cpp b/soh/soh/Localization.cpp new file mode 100644 index 000000000..3242634e8 --- /dev/null +++ b/soh/soh/Localization.cpp @@ -0,0 +1 @@ +// Stub for compatibility - actual implementation is in LanguageManager diff --git a/soh/soh/Localization.h b/soh/soh/Localization.h new file mode 100644 index 000000000..bc4815f2c --- /dev/null +++ b/soh/soh/Localization.h @@ -0,0 +1,7 @@ +#ifndef LOCALIZATION_H +#define LOCALIZATION_H + +// Stub for compatibility - actual implementation is in LanguageManager +#define L(key) (key) + +#endif // LOCALIZATION_H \ No newline at end of file diff --git a/soh/soh/SohGui/LanguageManager.cpp b/soh/soh/SohGui/LanguageManager.cpp new file mode 100644 index 000000000..57913cdd1 --- /dev/null +++ b/soh/soh/SohGui/LanguageManager.cpp @@ -0,0 +1,174 @@ +#include "LanguageManager.h" +#include +#include +#include +#include +#include "../OTRGlobals.h" + +using json = nlohmann::json; + +namespace SohGui { + +LanguageManager& LanguageManager::Instance() { + static LanguageManager instance; + return instance; +} + +void LanguageManager::Init() { + translationLoaded = false; + currentLanguage = ""; + translations.clear(); + + // Try to load saved language by index + int32_t savedLangIdx = CVarGetInteger(CVAR_SETTING("UILanguage"), 0); + if (savedLangIdx > 0) { + auto langs = GetAvailableLanguages(); + if (savedLangIdx <= static_cast(langs.size())) { + LoadLanguage(langs[savedLangIdx - 1]); + } + } + + // Scan for available languages + ScanLanguageFiles(); +} + +void LanguageManager::LoadLanguage(const std::string& languageName) { + if (languageName == "None" || languageName.empty()) { + translationLoaded = false; + currentLanguage = ""; + translations.clear(); + CVarSetInteger(CVAR_SETTING("UILanguage"), 0); + CVarSave(); + return; + } + + std::string langFile = GetLanguagesDirectory() + "/" + languageName + ".json"; + if (LoadJsonFile(langFile)) { + currentLanguage = languageName; + translationLoaded = true; + + // Save the language selection by index + auto langs = GetAvailableLanguages(); + int32_t idx = 0; + for (size_t i = 0; i < langs.size(); i++) { + if (langs[i] == languageName) { + idx = static_cast(i + 1); + break; + } + } + CVarSetInteger(CVAR_SETTING("UILanguage"), idx); + CVarSave(); + } else { + translationLoaded = false; + currentLanguage = ""; + translations.clear(); + } +} + +std::string LanguageManager::GetString(const std::string& key) { + // If no translation loaded, return the hardcoded text (English) + if (!translationLoaded || translations.empty()) { + return key; + } + + // Look for the translation + auto it = translations.find(key); + if (it != translations.end()) { + return it->second; + } + + // If translation not found, return the hardcoded text + return key; +} + +std::vector LanguageManager::GetAvailableLanguages() { + std::vector languages; + std::string langDir = GetLanguagesDirectory(); + + try { + for (const auto& entry : std::filesystem::directory_iterator(langDir)) { + if (entry.is_regular_file() && entry.path().extension() == ".json") { + std::string filename = entry.path().stem().string(); + if (!filename.empty()) { + languages.push_back(filename); + } + } + } + } catch (const std::filesystem::filesystem_error& e) { + // Directory doesn't exist or other filesystem error + } + + return languages; +} + +std::string LanguageManager::GetCurrentLanguage() { + return currentLanguage; +} + +bool LanguageManager::IsTranslationLoaded() { + return translationLoaded; +} + +void LanguageManager::ScanLanguageFiles() { + // Just ensure the directory exists + std::string langDir = GetLanguagesDirectory(); + if (!std::filesystem::exists(langDir)) { + try { + std::filesystem::create_directories(langDir); + } catch (const std::filesystem::filesystem_error& e) { + // Failed to create directory + } + } +} + +bool LanguageManager::LoadJsonFile(const std::string& path) { + std::ifstream file(path); + if (!file.is_open()) { + return false; + } + + json j; + try { + file >> j; + } catch (const json::parse_error& e) { + return false; + } + + // Clear existing translations + translations.clear(); + + // Load language name (optional) + if (j.contains("language") && j["language"].is_string()) { + currentLanguage = j["language"].get(); + } + + // Load strings + if (j.contains("strings") && j["strings"].is_object()) { + for (auto& [key, value] : j["strings"].items()) { + if (value.is_string()) { + translations[key] = value.get(); + } + } + } + + return !translations.empty(); +} + +std::string LanguageManager::GetLanguagesDirectory() { + // Try current directory first + std::string currentDir = "./lenguajes"; + if (std::filesystem::exists(currentDir)) { + return currentDir; + } + + // Try app data directory + std::string appDataDir = Ship::Context::GetInstance()->GetAppDirectoryPath() + "/lenguajes"; + if (std::filesystem::exists(appDataDir)) { + return appDataDir; + } + + // Return current directory as default (will be created if needed) + return currentDir; +} + +} // namespace SohGui \ No newline at end of file diff --git a/soh/soh/SohGui/LanguageManager.h b/soh/soh/SohGui/LanguageManager.h new file mode 100644 index 000000000..3de9d7ee9 --- /dev/null +++ b/soh/soh/SohGui/LanguageManager.h @@ -0,0 +1,33 @@ +#ifndef LANGUAGE_MANAGER_H +#define LANGUAGE_MANAGER_H + +#include +#include +#include + +namespace SohGui { + +class LanguageManager { +public: + static LanguageManager& Instance(); + + void Init(); + void LoadLanguage(const std::string& languageName); + std::string GetString(const std::string& key); + std::vector GetAvailableLanguages(); + std::string GetCurrentLanguage(); + bool IsTranslationLoaded(); + +private: + std::string currentLanguage; + std::map translations; + bool translationLoaded; + + void ScanLanguageFiles(); + bool LoadJsonFile(const std::string& path); + std::string GetLanguagesDirectory(); +}; + +} // namespace SohGui + +#endif // LANGUAGE_MANAGER_H \ No newline at end of file diff --git a/soh/soh/SohGui/SohMenu.cpp b/soh/soh/SohGui/SohMenu.cpp index 0e8ea5cf8..57835e1f8 100644 --- a/soh/soh/SohGui/SohMenu.cpp +++ b/soh/soh/SohGui/SohMenu.cpp @@ -3,6 +3,7 @@ #include #include #include +#include "LanguageManager.h" extern "C" { extern PlayState* gPlayState; @@ -34,7 +35,9 @@ WidgetInfo& SohMenu::AddWidget(WidgetPath& pathInfo, std::string widgetName, Wid } } SidebarEntry& entry = sidebar.at(pathInfo.sidebarName); - entry.columnWidgets.at(column).push_back({ .name = widgetName, .type = widgetType }); + // Apply automatic translation to the widget name + std::string translatedName = LanguageManager::Instance().GetString(widgetName); + entry.columnWidgets.at(column).push_back({ .name = translatedName, .type = widgetType }); WidgetInfo& widget = entry.columnWidgets.at(column).back(); switch (widgetType) { case WIDGET_CHECKBOX: @@ -173,8 +176,54 @@ void SohMenu::Draw() { Ship::Menu::Draw(); } +void SohMenu::StoreOriginalWidgetNames() { + if (mOriginalNamesStored) return; + for (auto& [sectionName, section] : menuEntries) { + for (auto& [sidebarName, sidebar] : section.sidebars) { + size_t colIdx = 0; + for (auto& column : sidebar.columnWidgets) { + size_t widgetIdx = 0; + for (auto& widget : column) { + std::string key = fmt::format("{}|{}|{}|{}", sectionName, sidebarName, colIdx, widgetIdx); + mOriginalWidgetNames[key] = widget.name; + if (widget.options && !widget.options->tooltip.empty()) { + mOriginalTooltips[key] = widget.options->tooltip; + } + widgetIdx++; + } + colIdx++; + } + } + } + mOriginalNamesStored = true; +} + void SohMenu::DrawElement() { if (mMenuElementsInitialized) { + StoreOriginalWidgetNames(); + + // Translate widget names and tooltips from originals before drawing each frame + for (auto& [sectionName, section] : menuEntries) { + for (auto& [sidebarName, sidebar] : section.sidebars) { + size_t colIdx = 0; + for (auto& column : sidebar.columnWidgets) { + size_t widgetIdx = 0; + for (auto& widget : column) { + std::string key = fmt::format("{}|{}|{}|{}", sectionName, sidebarName, colIdx, widgetIdx); + auto it = mOriginalWidgetNames.find(key); + if (it != mOriginalWidgetNames.end()) { + widget.name = LanguageManager::Instance().GetString(it->second); + } + auto tipIt = mOriginalTooltips.find(key); + if (tipIt != mOriginalTooltips.end()) { + widget.options->tooltip = LanguageManager::Instance().GetString(tipIt->second); + } + widgetIdx++; + } + colIdx++; + } + } + } Ship::Menu::DrawElement(); } } diff --git a/soh/soh/SohGui/SohMenu.h b/soh/soh/SohGui/SohMenu.h index 5b0b07827..f3c7f4923 100644 --- a/soh/soh/SohGui/SohMenu.h +++ b/soh/soh/SohGui/SohMenu.h @@ -52,6 +52,10 @@ class SohMenu : public Ship::Menu { char mGitCommitHashTruncated[8]; bool mIsTaggedVersion; bool mMenuElementsInitialized = false; + std::unordered_map mOriginalWidgetNames; + std::unordered_map mOriginalTooltips; + void StoreOriginalWidgetNames(); + bool mOriginalNamesStored = false; }; } // namespace SohGui diff --git a/soh/soh/SohGui/SohMenuSettings.cpp b/soh/soh/SohGui/SohMenuSettings.cpp index b806da560..5af895712 100644 --- a/soh/soh/SohGui/SohMenuSettings.cpp +++ b/soh/soh/SohGui/SohMenuSettings.cpp @@ -7,6 +7,7 @@ #include "soh/ResourceManagerHelpers.h" #include "UIWidgets.hpp" #include +#include "LanguageManager.h" extern "C" { #include "include/z64audio.h" @@ -19,6 +20,43 @@ extern std::shared_ptr mSohMenu; extern std::shared_ptr mModalWindow; using namespace UIWidgets; +// UI Translation Selector variables +static std::map uiLanguageOptionsStr = { }; +static std::map uiLanguageOptions = { }; +static bool uiLanguagesInitialized = false; + +static void InitUILanguages() { + if (uiLanguagesInitialized) { + return; + } + + LanguageManager::Instance().Init(); + uiLanguageOptionsStr.clear(); + uiLanguageOptions.clear(); + + uiLanguageOptionsStr[0] = "None"; + uiLanguageOptions[0] = "None"; + + int32_t idx = 1; + auto availableLangs = LanguageManager::Instance().GetAvailableLanguages(); + for (const auto& lang : availableLangs) { + if (!lang.empty()) { + uiLanguageOptionsStr[idx] = lang; + uiLanguageOptions[idx] = uiLanguageOptionsStr[idx].c_str(); + idx++; + } + } + + // Load saved language automatically (only once) + int32_t savedLang = CVarGetInteger(CVAR_SETTING("UILanguage"), 0); + if (savedLang > 0 && savedLang < (int32_t)availableLangs.size() + 1) { + std::string langName = availableLangs[savedLang - 1]; + LanguageManager::Instance().LoadLanguage(langName); + } + + uiLanguagesInitialized = true; +} + static std::map imguiScaleOptions = { { 0, "Small" }, { 1, "Normal" }, @@ -228,10 +266,37 @@ void SohMenu::AddMenuSettings() { SohMenu::UpdateLanguageMap(options->comboMap); }) .Options(ComboboxOptions() - .LabelPosition(LabelPositions::Far) - .ComponentAlignment(ComponentAlignments::Right) - .ComboMap(languages) - .DefaultIndex(LANGUAGE_ENG)); + .LabelPosition(LabelPositions::Far) + .ComponentAlignment(ComponentAlignments::Right) + .ComboMap(languages) + .DefaultIndex(LANGUAGE_ENG)); + + // UI Translation Selector (Dynamic Language Selector) + AddWidget(path, "UI Translation", WIDGET_CVAR_COMBOBOX) + .CVar(CVAR_SETTING("UILanguage")) + .PreFunc([](WidgetInfo& info) { + InitUILanguages(); + if (info.options) { + auto options = std::static_pointer_cast(info.options); + options->comboMap = uiLanguageOptions; + } + }) + .Callback([](WidgetInfo& info) { + int32_t selectedIndex = CVarGetInteger(CVAR_SETTING("UILanguage"), 0); + if (selectedIndex == 0) { + LanguageManager::Instance().LoadLanguage("None"); + } else if (selectedIndex > 0) { + auto availableLanguages = LanguageManager::Instance().GetAvailableLanguages(); + if (selectedIndex <= static_cast(availableLanguages.size())) { + std::string langName = availableLanguages[selectedIndex - 1]; + LanguageManager::Instance().LoadLanguage(langName); + } + } + }) + .Options(ComboboxOptions() + .ComboMap(uiLanguageOptions) + .Tooltip("Select the UI translation language...") + .DefaultIndex(0)); AddWidget(path, "Accessibility", WIDGET_SEPARATOR_TEXT); #if defined(_WIN32) || defined(__APPLE__) || defined(ESPEAK) AddWidget(path, "Text to Speech", WIDGET_CVAR_CHECKBOX)