diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d7e6b92fc..c69132fd5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,7 +35,7 @@ jobs: rm $ZIPNAME echo "OUTNAME=${ZIPNAME%.zip}" >> $GITHUB_ENV - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: name: ${{ env.OUTNAME }} path: release/* diff --git a/.gitignore b/.gitignore index 2f203cf95..ae5aeca70 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,5 @@ desktop.ini # User additions /zzz_backup +/arm9/source/language.inl +*.trf diff --git a/Makefile b/Makefile index cfbec5c0f..da57d2e1e 100644 --- a/Makefile +++ b/Makefile @@ -16,18 +16,28 @@ export RELDIR := release export COMMON_DIR := ../common # Definitions for initial RAM disk -VRAM_OUT := $(OUTDIR)/vram0.tar +VRAM_TAR := $(OUTDIR)/vram0.tar VRAM_DATA := data -VRAM_FLAGS := --make-new --path-limit 99 --size-limit 262144 +VRAM_FLAGS := --make-new --path-limit 99 ifeq ($(NTRBOOT),1) VRAM_SCRIPTS := resources/gm9/scripts endif +# Definitions for translation files +JSON_FOLDER := resources/languages +TRF_FOLDER := resources/gm9/languages + +SOURCE_JSON := $(JSON_FOLDER)/source.json +LANGUAGE_INL := arm9/source/language.inl + +JSON_FILES := $(filter-out $(SOURCE_JSON),$(wildcard $(JSON_FOLDER)/*.json)) +TRF_FILES := $(subst $(JSON_FOLDER),$(TRF_FOLDER),$(JSON_FILES:.json=.trf)) + ifeq ($(OS),Windows_NT) ifeq ($(TERM),cygwin) PY3 := py -3 # Windows / CMD/PowerShell else - PY3 := python3 # Windows / MSYS2 + PY3 := py # Windows / MSYS2 endif else PY3 := python3 # Unix-like @@ -40,18 +50,18 @@ export ASFLAGS := -g -x assembler-with-cpp $(INCLUDE) export CFLAGS := -DDBUILTS="\"$(DBUILTS)\"" -DDBUILTL="\"$(DBUILTL)\"" -DVERSION="\"$(VERSION)\"" -DFLAVOR="\"$(FLAVOR)\"" \ -g -Os -Wall -Wextra -Wcast-align -Wformat=2 -Wno-main \ -fomit-frame-pointer -ffast-math -std=gnu11 -MMD -MP \ - -Wno-unused-function -Wno-format-truncation $(INCLUDE) -ffunction-sections -fdata-sections + -Wno-unused-function -Wno-format-truncation -Wno-format-nonliteral $(INCLUDE) -ffunction-sections -fdata-sections export LDFLAGS := -Tlink.ld -nostartfiles -Wl,--gc-sections,-z,max-page-size=4096 ELF := arm9/arm9.elf arm11/arm11.elf -.PHONY: all firm vram0 elf release clean +.PHONY: all firm $(VRAM_TAR) elf release clean all: firm clean: @set -e; for elf in $(ELF); do \ $(MAKE) --no-print-directory -C $$(dirname $$elf) clean; \ done - @rm -rf $(OUTDIR) $(RELDIR) $(FIRM) $(FIRMD) $(VRAM_OUT) + @rm -rf $(OUTDIR) $(RELDIR) $(FIRM) $(FIRMD) $(VRAM_TAR) $(LANGUAGE_INL) $(TRF_FILES) unmarked_readme: .FORCE @$(PY3) utils/unmark.py -f README.md data/README_internal.md @@ -80,24 +90,34 @@ release: clean unmarked_readme @-7za a $(RELDIR)/$(FLAVOR)-$(VERSION)-$(DBUILTS).zip ./$(RELDIR)/* -vram0: - @mkdir -p "$(OUTDIR)" - @echo "Creating $(VRAM_OUT)" - @$(PY3) utils/add2tar.py $(VRAM_FLAGS) $(VRAM_OUT) $(shell ls -d $(SPLASH) $(OVERRIDE_FONT) $(VRAM_DATA)/* $(VRAM_SCRIPTS)) +$(VRAM_TAR): $(SPLASH) $(OVERRIDE_FONT) $(VRAM_DATA) $(VRAM_SCRIPTS) + @mkdir -p "$(@D)" + @echo "Creating $@" + @$(PY3) utils/add2tar.py $(VRAM_FLAGS) $(VRAM_TAR) $(shell find $^ -type f) + +$(LANGUAGE_INL): $(SOURCE_JSON) + @echo "Creating $@" + @$(PY3) utils/transcp.py $< $@ + +$(TRF_FOLDER)/%.trf: $(JSON_FOLDER)/%.json + @$(PY3) utils/transriff.py $< $@ %.elf: .FORCE @echo "Building $@" @$(MAKE) --no-print-directory -C $(@D) -firm: $(ELF) vram0 - @test `wc -c <$(VRAM_OUT)` -le 262144 +arm9/arm9.elf: $(VRAM_TAR) $(LANGUAGE_INL) + +firm: $(ELF) $(TRF_FILES) @mkdir -p $(call dirname,"$(FIRM)") $(call dirname,"$(FIRMD)") @echo "[FLAVOR] $(FLAVOR)" @echo "[VERSION] $(VERSION)" @echo "[BUILD] $(DBUILTL)" @echo "[FIRM] $(FIRM)" - @$(PY3) -m firmtool build $(FIRM) $(FTFLAGS) -g -A 0x80C0000 -D $(ELF) $(VRAM_OUT) -C NDMA XDMA memcpy + @$(PY3) -m firmtool build $(FIRM) $(FTFLAGS) -g -D $(ELF) -C NDMA XDMA @echo "[FIRM] $(FIRMD)" - @$(PY3) -m firmtool build $(FIRMD) $(FTDFLAGS) -g -A 0x80C0000 -D $(ELF) $(VRAM_OUT) -C NDMA XDMA memcpy + @$(PY3) -m firmtool build $(FIRMD) $(FTDFLAGS) -g -D $(ELF) -C NDMA XDMA + +vram0: $(VRAM_TAR) .FORCE # legacy target name .FORCE: diff --git a/README.md b/README.md index a54835dcb..ea9462e7f 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Build `GodMode9.firm` via `make firm`. This requires [firmtool](https://github.c You may run `make release` to get a nice, release-ready package of all required files. To build __SafeMode9__ (a bricksafe variant of GodMode9, with limited write permissions) instead of GodMode9, compile with `make FLAVOR=SafeMode9`. To switch screens, compile with `make SWITCH_SCREENS=1`. For additional customization, you may choose the internal font by replacing `font_default.frf` inside the `data` directory. You may also hardcode the brightness via `make FIXED_BRIGHTNESS=x`, whereas `x` is a value between 0...15. -Further customization is possible by hardcoding `aeskeydb.bin` (just put the file into the `data` folder when compiling). All files put into the `data` folder will turn up in the `V:` drive, but keep in mind there's a hard 3MB limit for all files inside, including overhead. A standalone script runner is compiled by providing `autorun.gm9` (again, in the `data` folder) and building with `make SCRIPT_RUNNER=1`. There's more possibility for customization, read the Makefiles to learn more. +Further customization is possible by hardcoding `aeskeydb.bin` (just put the file into the `data` folder when compiling). All files put into the `data` folder will turn up in the `V:` drive, but keep in mind there's a hard 223.5KiB limit for all files inside, including overhead. A standalone script runner is compiled by providing `autorun.gm9` (again, in the `data` folder) and building with `make SCRIPT_RUNNER=1`. There's more possibility for customization, read the Makefiles to learn more. To build a .firm signed with SPI boot keys (for ntrboot and the like), run `make NTRBOOT=1`. You may need to rename the output files if the ntrboot installer you use uses hardcoded filenames. Some features such as boot9 / boot11 access are not currently available from the ntrboot environment. @@ -65,6 +65,10 @@ For certain functionality, GodMode9 may need 'support files'. Support files shou * __`seeddb.bin`__: This file is optional and required to decrypt and mount seed-encrypted NCCHs and CIAs (if the seed in question is not installed to your NAND). Note that your seeddb.bin must also contain the seed for the specific game you need to decrypt. * __`encTitleKeys.bin`__ / __`decTitleKeys.bin`__: These files are optional and provide titlekeys, which are required to decrypt and install contents downloaded from CDN (for DSi and 3DS content). +### Fonts and translations +GodMode9 also supports custom fonts and translations as support files. These both use custom formats, fonts use FRF (Font RIFF) files which can be created using the `fontriff.py` Python script in the 'utils' folder. Translations use TRF (Translation RIFF) files from the `transriff.py` script. Examples of the inputs to these scripts can be found in the 'fonts' and 'languages' folders of the 'resources' folder respectively. + +TRF files can be placed in `0:/gm9/languages` to show in the language menu accessible from the HOME menu and shown on first load. Official translations are provided from the community via the [GodMode9 Crowdin](https://crowdin.com/project/GodMode9). Languages can use a special font by having an FRF with the same name, for example `en.trf` and `en.frf`. ## Drives in GodMode9 GodMode9 provides access to system data via drives, a listing of what each drive contains and additional info follows below. Some of these drives are removable (such as drive `7:`), some will only turn up if they are available (drive `8:` and everything associated with EmuNAND, f.e.). Information on the 3DS console file system is also found on [3Dbrew.org](https://3dbrew.org/wiki/Flash_Filesystem). @@ -88,7 +92,7 @@ GodMode9 provides access to system data via drives, a listing of what each drive * __`K: AESKEYDB IMAGE`__: An `aeskeydb.bin` image can be mounted and accessed via this drive. The drive shows all keys inside the aeskeydb.bin. This is read-only. * __`T: TICKET.DB IMAGE / BDRI IMAGE`__: Ticket database files can be mounted and accessed via this drive. This provides easy and quick access to all tickets inside the `ticket.db`. This drive also provides access to other BDRI images, such as the Title database (`title.db`). * __`M: MEMORY VIRTUAL`__: This provides access to various memory regions. This is protected by a special write permission, and caution is advised when doing modifications inside this drive. This drive also gives access to `boot9.bin`, `boot11.bin` (boot9strap only) and `otp.mem` (sighaxed systems only). -* __`V: VRAM VIRTUAL`__: This drive resides in the first VRAM bank and contains files essential to GodMode9. The font (in FRF format), the splash logo (in PNG format) and the readme file are found there, as well as any file that is provided inside the `data` folder at build time. This is read-only. +* __`V: VRAM VIRTUAL`__: This drive resides in part of ARM9 internal memory and contains files essential to GodMode9. The font (in FRF format), the splash logo (in PNG format) and the readme file are found there, as well as any file that is provided inside the `data` folder at build time. This is read-only. * __`Y: TITLE MANAGER`__: The title manager is accessed via the HOME menu and provides easy access to all installed titles. * __`Z: LAST SEARCH`__: After a search operation, search results are found inside this drive. The drive can be accessed at a later point to return to the former search results. @@ -182,6 +186,7 @@ This tool would not have been possible without the help of numerous people. Than * **ihaveamac** for first developing the simple CIA generation method and for being of great help in porting it * **wwylele** and **aspargas2** for documenting and implementing the DISA, DIFF, and BDRI formats * **dratini0** for savefile management, based on [TWLSaveTool](https://github.com/TuxSH/TWLSaveTool/) +* **Pk11** for unicode and translation support * **b1l1s** for helping me figure out A9LH compatibility * **Gelex** and **AuroraWright** for helping me figure out various things * **stuckpixel** for the new 6x10 font and help on various things diff --git a/arm11/Makefile b/arm11/Makefile index 3528587f3..b52d531e9 100644 --- a/arm11/Makefile +++ b/arm11/Makefile @@ -1,6 +1,6 @@ PROCESSOR := ARM11 -TARGET := $(shell basename $(CURDIR)) +TARGET := $(shell basename "$(CURDIR)") SOURCE := source BUILD := build @@ -11,7 +11,7 @@ INCLUDE := $(foreach dir,$(INCDIRS),-I"$(shell pwd)/$(dir)") ASFLAGS += $(SUBARCH) $(INCLUDE) CFLAGS += $(SUBARCH) $(INCLUDE) -flto -LDFLAGS += $(SUBARCH) -Wl,-Map,$(TARGET).map -flto +LDFLAGS += $(SUBARCH) -Wl,--use-blx,-Map,$(TARGET).map -flto include ../Makefile.common include ../Makefile.build diff --git a/arm11/link.ld b/arm11/link.ld index 36642423a..51122881f 100644 --- a/arm11/link.ld +++ b/arm11/link.ld @@ -16,7 +16,7 @@ SECTIONS __text_va = ABSOLUTE(.); *(.text*) . = ALIGN(4K); - __text_len = . - __text_va; + __text_va_end = .; } >AXIWRAM .data : ALIGN(4K) @@ -25,7 +25,7 @@ SECTIONS __data_va = ABSOLUTE(.); *(.data*) . = ALIGN(4K); - __data_len = . - __data_va; + __data_va_end = .; } >AXIWRAM .rodata : ALIGN(4K) @@ -34,7 +34,7 @@ SECTIONS __rodata_va = ABSOLUTE(.); *(.rodata*) . = ALIGN(4K); - __rodata_len = . - __rodata_va; + __rodata_va_end = .; } >AXIWRAM .shared (NOLOAD) : ALIGN(4K) @@ -43,7 +43,7 @@ SECTIONS __shared_va = ABSOLUTE(.); *(.shared*) . = ALIGN(4K); - __shared_len = . - __shared_va; + __shared_va_end = .; } >AXIWRAM .bss (NOLOAD) : ALIGN(4K) @@ -52,6 +52,6 @@ SECTIONS __bss_va = ABSOLUTE(.); *(.bss*) . = ALIGN(4K); - __bss_len = . - __bss_va; + __bss_va_end = .; } >AXIWRAM } diff --git a/arm11/source/boot.s b/arm11/source/boot.s index 9e7deef36..5b2167b65 100644 --- a/arm11/source/boot.s +++ b/arm11/source/boot.s @@ -76,10 +76,12 @@ __boot: b 1b corezero_start: - @ assume __bss_len is 128 byte aligned + @ assumes the .bss section size is 128 byte aligned (or zero) ldr r0, =__bss_pa - ldr r1, =__bss_len - add r1, r0, r1 + ldr r1, =__bss_va_end @ calculate the length of .bss using the VA start and end + ldr r2, =__bss_va + sub r1, r1, r2 + add r1, r0, r1 @ fixup to be PA start and end mov r2, #0 mov r3, #0 mov r4, #0 diff --git a/arm11/source/hw/mcu.c b/arm11/source/hw/mcu.c index 33d144662..69ab77733 100755 --- a/arm11/source/hw/mcu.c +++ b/arm11/source/hw/mcu.c @@ -22,6 +22,8 @@ #include +#include "common.h" + #include "arm/timer.h" #include "hw/gpio.h" @@ -116,16 +118,13 @@ u32 mcuGetSpecialHID(void) void mcuSetStatusLED(u32 period_ms, u32 color) { - u32 r, g, b; + u32 r, g, b, delay; mcuStatusLED ledState; - // handle proper non-zero periods - // so small the hardware can't handle it - if (period_ms != 0 && period_ms < 63) - period_ms = 63; + delay = clamp((period_ms * 0x200) / 1000, 1, 0xFF); - ledState.delay = (period_ms * 0x10) / 1000; - ledState.smoothing = 0x40; + ledState.delay = delay; + ledState.smoothing = delay; ledState.loop_delay = 0x10; ledState.unk = 0; diff --git a/arm11/source/system/sections.h b/arm11/source/system/sections.h index 008f93a6a..21e5f1294 100755 --- a/arm11/source/system/sections.h +++ b/arm11/source/system/sections.h @@ -20,7 +20,7 @@ #include -#define DEF_SECT_(n) extern u32 __##n##_pa, __##n##_va, __##n##_len; +#define DEF_SECT_(n) extern u32 __##n##_pa, __##n##_va, __##n##_va_end; DEF_SECT_(text) DEF_SECT_(data) DEF_SECT_(rodata) @@ -30,6 +30,6 @@ DEF_SECT_(shared) #define SECTION_VA(n) ((u32)&__##n##_va) #define SECTION_PA(n) ((u32)&__##n##_pa) -#define SECTION_LEN(n) ((u32)&__##n##_len) +#define SECTION_LEN(n) (((u32)(&__##n##_va_end) - (u32)(&__##n##_va))) #define SECTION_TRI(n) SECTION_VA(n), SECTION_PA(n), SECTION_LEN(n) diff --git a/arm9/Makefile b/arm9/Makefile index 0a5e2c5b5..0c5b8520f 100644 --- a/arm9/Makefile +++ b/arm9/Makefile @@ -1,6 +1,6 @@ PROCESSOR := ARM9 -TARGET := $(shell basename $(CURDIR)) +TARGET := $(shell basename "$(CURDIR)") SOURCE := source BUILD := build @@ -11,7 +11,7 @@ INCLUDE := $(foreach dir,$(INCDIRS),-I"$(shell pwd)/$(dir)") ASFLAGS += $(SUBARCH) $(INCLUDE) CFLAGS += $(SUBARCH) $(INCLUDE) -fno-builtin-memcpy -flto -LDFLAGS += $(SUBARCH) -Wl,-Map,$(TARGET).map -flto +LDFLAGS += $(SUBARCH) -Wl,--use-blx,-Map,$(TARGET).map -flto include ../Makefile.common include ../Makefile.build diff --git a/arm9/link.ld b/arm9/link.ld index e9f0a08dd..5ff9a6359 100644 --- a/arm9/link.ld +++ b/arm9/link.ld @@ -4,8 +4,8 @@ ENTRY(_start) MEMORY { - AHBWRAM (RWX) : ORIGIN = 0x08006000, LENGTH = 512K VECTORS (RX) : ORIGIN = 0x08000000, LENGTH = 64 + AHBWRAM (RWX) : ORIGIN = 0x08000040, LENGTH = 512K - 64 } SECTIONS diff --git a/arm9/source/common/screenshot.c b/arm9/source/common/screenshot.c index 285a63382..2deb65926 100644 --- a/arm9/source/common/screenshot.c +++ b/arm9/source/common/screenshot.c @@ -27,7 +27,7 @@ void CreateScreenshot(void) { fvx_rmkdir(OUTPUT_PATH); get_dstime(&dstime); - snprintf(filename, 64, OUTPUT_PATH "/snap_%02X%02X%02X%02X%02X%02X.png", + snprintf(filename, sizeof(filename), OUTPUT_PATH "/snap_%02X%02X%02X%02X%02X%02X.png", dstime.bcd_Y, dstime.bcd_M, dstime.bcd_D, dstime.bcd_h, dstime.bcd_m, dstime.bcd_s); filename[63] = '\0'; diff --git a/arm9/source/common/swkbd.c b/arm9/source/common/swkbd.c index 978e896b6..f410812d5 100644 --- a/arm9/source/common/swkbd.c +++ b/arm9/source/common/swkbd.c @@ -1,5 +1,6 @@ #include +#include "language.h" #include "swkbd.h" #include "timer.h" #include "hid.h" @@ -80,7 +81,7 @@ static void DrawKey(const TouchBox* key, const bool pressed, const u32 uppercase if (key->id == KEY_TXTBOX) return; char keystr[16]; - if (key->id >= 0x80) snprintf(keystr, 16, "%s", keystrs[key->id - 0x80]); + if (key->id >= 0x80) snprintf(keystr, sizeof(keystr), "%s", keystrs[key->id - 0x80]); else { keystr[0] = (uppercase) ? to_uppercase(key->id) : key->id; keystr[1] = 0; @@ -146,8 +147,8 @@ static void DrawTextBox(const TouchBox* txtbox, const char* inputstr, const u32 // draw input string DrawStringF(BOT_SCREEN, x, y, COLOR_STD_FONT, COLOR_STD_BG, "%c%-*.*s%c", (*scroll) ? '<' : '|', - input_shown_size, - input_shown_size, + (int) input_shown_size, + (int) input_shown_size, (*scroll > inputstr_size) ? "" : inputstr + *scroll, (inputstr_size - (s32) *scroll > input_shown_size) ? '>' : '|' ); @@ -159,11 +160,11 @@ static void DrawTextBox(const TouchBox* txtbox, const char* inputstr, const u32 } DrawStringF(BOT_SCREEN, x-(FONT_WIDTH_EXT/2), y+10, COLOR_STD_FONT, COLOR_STD_BG, "%-*.*s^%-*.*s", - 1 + cpos, - 1 + cpos, + (int) (1 + cpos), + (int) (1 + cpos), "", - input_shown_length - cpos, - input_shown_length - cpos, + (int) (input_shown_length - cpos), + (int) (input_shown_length - cpos), "" ); } @@ -253,9 +254,9 @@ bool ShowKeyboard(char* inputstr, const u32 max_size, const char *format, ...) { TouchBox* textbox = swkbd_alphabet; // always use this textbox static bool show_instr = true; - static const char* instr = "Keyboard Controls:\n \n←/→ - Move cursor\nR - Caps / Capslock\nX - Delete char\nY - Insert char\nA - Submit\nB - Cancel\n \nSELECT switches to\nclassic prompt"; + const char* instr = STR_KEYBOARD_CONTROLS_DETAILS; if (show_instr) { - ShowPrompt(false, instr); + ShowPrompt(false, "%s", instr); show_instr = false; } @@ -268,7 +269,7 @@ bool ShowKeyboard(char* inputstr, const u32 max_size, const char *format, ...) { char str[512]; // arbitrary limit, should be more than enough va_list va; va_start(va, format); - vsnprintf(str, 512, format, va); + vsnprintf(str, sizeof(str), format, va); va_end(va); u32 str_width = GetDrawStringWidth(str); if (str_width < (24 * FONT_WIDTH_EXT)) str_width = 24 * FONT_WIDTH_EXT; @@ -332,7 +333,7 @@ bool ShowKeyboard(char* inputstr, const u32 max_size, const char *format, ...) { swkbd = swkbd_numpad; } else if (key == KEY_SWITCH) { ClearScreen(BOT_SCREEN, COLOR_STD_BG); - return ShowStringPrompt(inputstr, max_size, str); + return ShowStringPrompt(inputstr, max_size, "%s", str); } else if (key == KEY_UNICODE) { if (cursor > 3 && cursor <= inputstr_size) { u16 codepoint = 0; diff --git a/arm9/source/common/swkbd.h b/arm9/source/common/swkbd.h index b81ec0dee..86f93d440 100644 --- a/arm9/source/common/swkbd.h +++ b/arm9/source/common/swkbd.h @@ -86,4 +86,4 @@ enum { #define ShowKeyboardOrPrompt (TouchIsCalibrated() ? ShowKeyboard : ShowStringPrompt) -bool ShowKeyboard(char* inputstr, u32 max_size, const char *format, ...); +bool PRINTF_ARGS(3) ShowKeyboard(char* inputstr, u32 max_size, const char *format, ...); diff --git a/arm9/source/common/touchcal.c b/arm9/source/common/touchcal.c index f1e16c54c..76412dc75 100644 --- a/arm9/source/common/touchcal.c +++ b/arm9/source/common/touchcal.c @@ -2,6 +2,7 @@ #include "ui.h" #include "hid.h" #include "crc16.h" +#include "language.h" #include "spiflash.h" #include "support.h" @@ -46,8 +47,8 @@ bool ShowTouchCalibrationDialog(void) // clear screen, draw instructions ClearScreen(BOT_SCREEN, COLOR_STD_BG); - DrawStringCenter(BOT_SCREEN, COLOR_STD_FONT, COLOR_STD_BG, - "Touch the red crosshairs to\ncalibrate your touchscreen.\n \nUse the stylus for best\nresults!"); + DrawStringCenter(BOT_SCREEN, COLOR_STD_FONT, COLOR_STD_BG, "%s", + STR_TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS); // set calibration defaults SetCalibrationDefaults(); diff --git a/arm9/source/common/ui.c b/arm9/source/common/ui.c index d8fb7cb54..e2de1ebad 100644 --- a/arm9/source/common/ui.c +++ b/arm9/source/common/ui.c @@ -15,12 +15,24 @@ #include "power.h" #include "hid.h" #include "fixp.h" +#include "language.h" #define STRBUF_SIZE 512 // maximum size of the string buffer #define FONT_MAX_WIDTH 8 #define FONT_MAX_HEIGHT 10 #define PROGRESS_REFRESH_RATE 30 // the progress bar is only allowed to draw to screen every X milliseconds +typedef struct { + char chunk_id[4]; // NOT null terminated + u32 size; +} RiffChunkHeader; + +typedef struct { + u8 width; + u8 height; + u16 count; +} FontMeta; + static u32 font_width = 0; static u32 font_height = 0; static u32 font_count = 0; @@ -129,8 +141,8 @@ u32 GetCharacter(const char** str) return c; } -u8* GetFontFromPbm(const void* pbm, const u32 pbm_size, u32* w, u32* h) { - char* hdr = (char*) pbm; +const u8* GetFontFromPbm(const void* pbm, const u32 pbm_size, u32* w, u32* h) { + const char* hdr = (const char*) pbm; u32 hdr_max_size = min(512, pbm_size); u32 pbm_w = 0; u32 pbm_h = 0; @@ -191,40 +203,43 @@ u8* GetFontFromPbm(const void* pbm, const u32 pbm_size, u32* w, u32* h) { return (u8*) pbm + p; } -u8* GetFontFromRiff(const void* riff, const u32 riff_size, u32* w, u32* h, u16* count) { - u8 *ptr = (u8*) riff; - u8 riff_w = 0; - u8 riff_h = 0; - u16 riff_count = 0; +const u8* GetFontFromRiff(const void* riff, const u32 riff_size, u32* w, u32* h, u16* count) { + const void* ptr = riff; + const RiffChunkHeader* riff_header; + const RiffChunkHeader* chunk_header; - // check header magic, then skip over - if (memcmp(ptr, "RIFF", 4) != 0) return NULL; + // check header magic and load size + if (!ptr) return NULL; + riff_header = ptr; + if (memcmp(riff_header->chunk_id, "RIFF", 4) != 0) return NULL; // ensure enough space is allocated - u32 data_size; - memcpy(&data_size, ptr + 4, sizeof(u32)); - if (data_size > riff_size) return NULL; + if (riff_header->size > riff_size) return NULL; - ptr += 8; + ptr += sizeof(RiffChunkHeader); - // check for and load META section - if (memcmp(ptr, "META", 4) == 0) { - riff_w = ptr[8]; - riff_h = ptr[9]; - memcpy(&riff_count, ptr + 10, sizeof(u16)); + while ((u32)(ptr - riff) < riff_header->size + sizeof(RiffChunkHeader)) { + chunk_header = ptr; - u32 section_size; - memcpy(§ion_size, ptr + 4, sizeof(u32)); - ptr += 8 + section_size; + // check for and load META section + if (memcmp(chunk_header->chunk_id, "META", 4) == 0) { - if (riff_w > FONT_MAX_WIDTH || riff_h > FONT_MAX_HEIGHT) return NULL; - } else return NULL; + if (chunk_header->size != 4) return NULL; - // all good - if (w) *w = riff_w; - if (h) *h = riff_h; - if (count) *count = riff_count; - return ptr; + const FontMeta *meta = ptr + sizeof(RiffChunkHeader); + if (meta->width > FONT_MAX_WIDTH || meta->height > FONT_MAX_HEIGHT) return NULL; + + // all good + if (w) *w = meta->width; + if (h) *h = meta->height; + if (count) *count = meta->count; + return ptr; + } + + ptr += sizeof(RiffChunkHeader) + chunk_header->size; + } + + return NULL; } // sets the font from a given RIFF or PBM @@ -232,7 +247,7 @@ u8* GetFontFromRiff(const void* riff, const u32 riff_size, u32* w, u32* h, u16* bool SetFont(const void* font, u32 font_size) { u32 w, h; u16 count; - u8* ptr = NULL; + const u8* ptr = NULL; if (!font) { u64 font_size64 = 0; @@ -248,33 +263,31 @@ bool SetFont(const void* font, u32 font_size) { font_height = h; font_count = count; - // character data - if (memcmp(ptr, "CDAT", 4) == 0) { - u32 section_size; - memcpy(§ion_size, ptr + 4, sizeof(u32)); + const RiffChunkHeader* riff_header; + const RiffChunkHeader* chunk_header; - if (font_bin) free(font_bin); - font_bin = malloc(font_height * font_count); - if (!font_bin) return NULL; - - memcpy(font_bin, ptr + 8, font_height * font_count); + // load total size + riff_header = font; - ptr += 8 + section_size; - } else return NULL; + while (((u32)ptr - (u32)font) < riff_header->size + sizeof(RiffChunkHeader)) { + chunk_header = (const void *)ptr; - // character map - if (memcmp(ptr, "CMAP", 4) == 0) { - u32 section_size; - memcpy(§ion_size, ptr + 4, sizeof(u32)); + if (memcmp(chunk_header->chunk_id, "CDAT", 4) == 0) { // character data + if (font_bin) free(font_bin); + font_bin = malloc(font_height * font_count); + if (!font_bin) return NULL; - if (font_map) free(font_map); - font_map = malloc(sizeof(u16) * font_count); - if (!font_map) return NULL; + memcpy(font_bin, ptr + sizeof(RiffChunkHeader), font_height * font_count); + } else if (memcmp(chunk_header->chunk_id, "CMAP", 4) == 0) { // character map + if (font_map) free(font_map); + font_map = malloc(sizeof(u16) * font_count); + if (!font_map) return NULL; - memcpy(font_map, ptr + 8, sizeof(u16) * font_count); + memcpy(font_map, ptr + sizeof(RiffChunkHeader), sizeof(u16) * font_count); + } - ptr += 8 + section_size; - } else return NULL; + ptr += sizeof(RiffChunkHeader) + chunk_header->size; + } } else if ((ptr = GetFontFromPbm(font, font_size, &w, &h))) { font_count = 0x100; @@ -576,18 +589,13 @@ void ResizeString(char* dest, const char* orig, int nlength, int tpos, bool alig if (nlength < olength) { TruncateString(dest, orig, nlength, tpos); - } else if (!align_right) { - int nsize = 0; - for (int i = 0; i < nlength || (orig[nsize] & 0xC0) == 0x80; nsize++) { - if ((orig[nsize] & 0xC0) != 0x80) i++; - } - snprintf(dest, UTF_BUFFER_BYTESIZE(nlength), "%-*.*s", nsize, nsize, orig); } else { int nsize = 0; - for (int i = 0; i < nlength || (orig[nsize] & 0xC0) == 0x80; nsize++) { - if ((orig[nsize] & 0xC0) != 0x80) i++; + int osize = strnlen(orig, 256); + for (int i = 0; i < nlength || (nsize <= osize && (orig[nsize] & 0xC0) == 0x80); nsize++) { + if (nsize > osize || (orig[nsize] & 0xC0) != 0x80) i++; } - snprintf(dest, UTF_BUFFER_BYTESIZE(nlength), "%*.*s", nsize, nsize, orig); + snprintf(dest, UTF_BUFFER_BYTESIZE(nlength), align_right ? "%*.*s" : "%-*.*s", nsize, nsize, orig); } } @@ -625,20 +633,20 @@ void FormatNumber(char* str, u64 number) { // str should be 32 byte in size for (; number / (mag1000 * 1000) > 0; mag1000 *= 1000); for (; mag1000 > 0; mag1000 /= 1000) { u32 pos = strnlen(str, 31); - snprintf(str + pos, 31 - pos, "%0*llu%c", (pos) ? 3 : 1, (number / mag1000) % 1000, (mag1000 > 1) ? ',' : '\0'); + snprintf(str + pos, 31 - pos, "%0*llu%s", (pos) ? 3 : 1, (number / mag1000) % 1000, (mag1000 > 1) ? STR_THOUSAND_SEPARATOR : ""); } } void FormatBytes(char* str, u64 bytes) { // str should be 32 byte in size, just to be safe - const char* units[] = {" Byte", " kB", " MB", " GB"}; + const char* units[] = {STR_BYTE, STR_KB, STR_MB, STR_GB}; - if (bytes == (u64) -1) snprintf(str, 32, "INVALID"); + if (bytes == (u64) -1) snprintf(str, 32, "%s", STR_INVALID); else if (bytes < 1024) snprintf(str, 32, "%llu%s", bytes, units[0]); else { u32 scale = 1; u64 bytes100 = (bytes * 100) >> 10; for(; (bytes100 >= 1024*100) && (scale < 3); scale++, bytes100 >>= 10); - snprintf(str, 32, "%llu.%llu%s", bytes100 / 100, (bytes100 % 100) / 10, units[scale]); + snprintf(str, 32, "%llu%s%llu%s", bytes100 / 100, STR_DECIMAL_SEPARATOR, (bytes100 % 100) / 10, units[scale]); } } @@ -705,7 +713,7 @@ void ShowIconString(u16* icon, int w, int h, const char *format, ...) vsnprintf(str, STRBUF_SIZE, format, va); va_end(va); - ShowIconStringF(MAIN_SCREEN, icon, w, h, str); + ShowIconStringF(MAIN_SCREEN, icon, w, h, "%s", str); } bool ShowPrompt(bool ask, const char *format, ...) @@ -720,7 +728,7 @@ bool ShowPrompt(bool ask, const char *format, ...) ClearScreenF(true, false, COLOR_STD_BG); DrawStringCenter(MAIN_SCREEN, COLOR_STD_FONT, COLOR_STD_BG, "%s\n \n%s", str, - (ask) ? "( yes, no)" : "( to continue)"); + (ask) ? STR_A_YES_B_NO : STR_A_TO_CONTINUE); while (true) { u32 pad_state = InputWait(0); @@ -775,7 +783,7 @@ bool ShowUnlockSequence(u32 seqlvl, const char *format, ...) { ClearScreenF(true, false, color_bg); DrawStringF(MAIN_SCREEN, x, y, color_font, color_bg, "%s", str); #ifndef TIMER_UNLOCK - DrawStringF(MAIN_SCREEN, x, y + str_height - 28, color_font, color_bg, "To proceed, enter this:"); + DrawStringF(MAIN_SCREEN, x, y + str_height - 28, color_font, color_bg, "%s", STR_TO_PROCEED_ENTER_THIS); // generate sequence const char *dpad_symbols[] = { "→", "←", "↑", "↓" }; // R L U D @@ -812,7 +820,7 @@ bool ShowUnlockSequence(u32 seqlvl, const char *format, ...) { lvl = 0; } #else - DrawStringF(MAIN_SCREEN, x, y + str_height - 28, color_font, color_bg, "To proceed, hold :"); + DrawStringF(MAIN_SCREEN, x, y + str_height - 28, color_font, color_bg, STR_TO_PROCEED_HOLD_X); while (!CheckButton(BUTTON_B)) { for (u32 n = 0; n < seqlen; n++) { @@ -839,10 +847,11 @@ bool ShowUnlockSequence(u32 seqlvl, const char *format, ...) { } #endif -u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...) { +u32 ShowSelectPrompt(int n, const char** options, const char *format, ...) { u32 str_width, str_height; u32 x, y, yopt; - u32 sel = 0; + int sel = 0, scroll = 0; + int n_show = min(n, 10); char str[STRBUF_SIZE]; va_list va; @@ -854,30 +863,64 @@ u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...) { // else if (n == 1) return ShowPrompt(true, "%s\n%s?", str, options[0]) ? 1 : 0; str_width = GetDrawStringWidth(str); - str_height = GetDrawStringHeight(str) + (n * (line_height + 2)) + (3 * line_height); + str_height = GetDrawStringHeight(str) + (n_show * (line_height + 2)) + (3 * line_height); if (str_width < 24 * font_width) str_width = 24 * font_width; - for (u32 i = 0; i < n; i++) if (str_width < GetDrawStringWidth(options[i])) - str_width = GetDrawStringWidth(options[i]); + for (int i = 0; i < n; i++) if (str_width < GetDrawStringWidth(options[i]) + (3 * font_width)) + str_width = GetDrawStringWidth(options[i]) + (3 * font_width); x = (str_width >= SCREEN_WIDTH_MAIN) ? 0 : (SCREEN_WIDTH_MAIN - str_width) / 2; y = (str_height >= SCREEN_HEIGHT) ? 0 : (SCREEN_HEIGHT - str_height) / 2; yopt = y + GetDrawStringHeight(str) + 8; ClearScreenF(true, false, COLOR_STD_BG); DrawStringF(MAIN_SCREEN, x, y, COLOR_STD_FONT, COLOR_STD_BG, "%s", str); - DrawStringF(MAIN_SCREEN, x, yopt + (n*(line_height+2)) + line_height, COLOR_STD_FONT, COLOR_STD_BG, "( select, cancel)"); + DrawStringF(MAIN_SCREEN, x, yopt + (n_show*(line_height+2)) + line_height, COLOR_STD_FONT, COLOR_STD_BG, "%s", STR_A_SELECT_B_CANCEL); while (true) { - for (u32 i = 0; i < n; i++) { - DrawStringF(MAIN_SCREEN, x, yopt + ((line_height+2)*i), (sel == i) ? COLOR_STD_FONT : COLOR_LIGHTGREY, COLOR_STD_BG, "%2.2s %s", + for (int i = scroll; i < scroll+n_show; i++) { + DrawStringF(MAIN_SCREEN, x, yopt + ((line_height+2)*(i-scroll)), (sel == i) ? COLOR_STD_FONT : COLOR_LIGHTGREY, COLOR_STD_BG, "%2.2s %s", (sel == i) ? "->" : "", options[i]); } + + // show [n more] + if (n - n_show - scroll > 0) { + char more_str[UTF_BUFFER_BYTESIZE(str_width / font_width)], temp_str[UTF_BUFFER_BYTESIZE(64)]; + snprintf(temp_str, sizeof(temp_str), STR_N_MORE, (n - (n_show-1) - scroll)); + ResizeString(more_str, temp_str, str_width / font_width, 8, false); + DrawString(MAIN_SCREEN, more_str, x, yopt + (line_height+2)*(n_show-1), COLOR_LIGHTGREY, COLOR_STD_BG); + } + // show scroll bar + u32 bar_x = x + str_width + 2; + const u32 flist_height = (n_show * (line_height + 2)); + const u32 bar_width = 2; + if (n > n_show) { // draw position bar at the right + const u32 bar_height_min = 32; + u32 bar_height = (n_show * flist_height) / n; + if (bar_height < bar_height_min) bar_height = bar_height_min; + const u32 bar_y = ((u64) scroll * (flist_height - bar_height)) / (n - n_show) + yopt; + + DrawRectangle(MAIN_SCREEN, bar_x, bar_y, bar_width, bar_height, COLOR_SIDE_BAR); + } + u32 pad_state = InputWait(0); if (pad_state & BUTTON_DOWN) sel = (sel+1) % n; else if (pad_state & BUTTON_UP) sel = (sel+n-1) % n; + else if (pad_state & BUTTON_RIGHT) sel += n_show; + else if (pad_state & BUTTON_LEFT) sel -= n_show; else if (pad_state & BUTTON_A) break; else if (pad_state & BUTTON_B) { sel = n; break; } + if (sel < 0) sel = 0; + else if (sel >= n) sel = n-1; + + int prev_scroll = scroll; + if (sel < scroll) scroll = sel; + else if (sel == n-1 && sel >= (scroll + n_show - 1)) scroll = sel - n_show + 1; + else if (sel >= (scroll + (n_show-1) - 1)) scroll = sel - (n_show-1) + 1; + + if (scroll != prev_scroll) { + DrawRectangle(MAIN_SCREEN, x + font_width * 3, yopt, str_width + 4, (n_show * (line_height + 2)), COLOR_STD_BG); + } } ClearScreenF(true, false, COLOR_STD_BG); @@ -885,12 +928,12 @@ u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...) { return (sel >= n) ? 0 : sel + 1; } -u32 ShowFileScrollPrompt(u32 n, const DirEntry** options, bool hide_ext, const char *format, ...) { +u32 ShowFileScrollPrompt(int n, const DirEntry** options, bool hide_ext, const char *format, ...) { u32 str_height, fname_len; u32 x, y, yopt; const u32 item_width = SCREEN_WIDTH(MAIN_SCREEN) - 40; int sel = 0, scroll = 0; - u32 n_show = min(n, 10); + int n_show = min(n, 10); char str[STRBUF_SIZE]; va_list va; @@ -909,9 +952,9 @@ u32 ShowFileScrollPrompt(u32 n, const DirEntry** options, bool hide_ext, const c ClearScreenF(true, false, COLOR_STD_BG); DrawStringF(MAIN_SCREEN, x, y, COLOR_STD_FONT, COLOR_STD_BG, "%s", str); - DrawStringF(MAIN_SCREEN, x, yopt + (n_show*(line_height+2)) + line_height, COLOR_STD_FONT, COLOR_STD_BG, "( select, cancel)"); + DrawStringF(MAIN_SCREEN, x, yopt + (n_show*(line_height+2)) + line_height, COLOR_STD_FONT, COLOR_STD_BG, "%s", STR_A_SELECT_B_CANCEL); while (true) { - for (u32 i = scroll; i < scroll+n_show; i++) { + for (int i = scroll; i < scroll+n_show; i++) { char bytestr[16]; FormatBytes(bytestr, options[i]->size); @@ -925,18 +968,19 @@ u32 ShowFileScrollPrompt(u32 n, const DirEntry** options, bool hide_ext, const c ResizeString(content_str, temp_str, fname_len, 8, false); DrawStringF(MAIN_SCREEN, x, yopt + ((line_height+2)*(i-scroll)), - (sel == (int)i) ? COLOR_STD_FONT : COLOR_ENTRY(options[i]), COLOR_STD_BG, "%2.2s %s", - (sel == (int)i) ? "->" : "", content_str); + (sel == i) ? COLOR_STD_FONT : COLOR_ENTRY(options[i]), COLOR_STD_BG, "%2.2s %s", + (sel == i) ? "->" : "", content_str); DrawStringF(MAIN_SCREEN, x + item_width - font_width * 11, yopt + ((line_height+2)*(i-scroll)), - (sel == (int)i) ? COLOR_STD_FONT : COLOR_ENTRY(options[i]), COLOR_STD_BG, "%10.10s", - (options[i]->type == T_DIR) ? "(dir)" : (options[i]->type == T_DOTDOT) ? "(..)" : bytestr); + (sel == i) ? COLOR_STD_FONT : COLOR_ENTRY(options[i]), COLOR_STD_BG, "%10.10s", + (options[i]->type == T_DIR) ? STR_DIR : (options[i]->type == T_DOTDOT) ? "(..)" : bytestr); } // show [n more] - if (n - n_show - scroll) { - char more_str[64 + 1]; - snprintf(more_str, 64, " [%d more]", (int)(n - (n_show-1) - scroll)); - DrawStringF(MAIN_SCREEN, x, yopt + (line_height+2)*(n_show-1), COLOR_LIGHTGREY, COLOR_STD_BG, "%-*s", item_width / font_width, more_str); + if (n - n_show - scroll > 0) { + char more_str[UTF_BUFFER_BYTESIZE(item_width / font_width)], temp_str[UTF_BUFFER_BYTESIZE(64)]; + snprintf(temp_str, sizeof(temp_str), STR_N_MORE, (n - (n_show-1) - scroll)); + ResizeString(more_str, temp_str, item_width / font_width, 8, false); + DrawString(MAIN_SCREEN, more_str, x, yopt + (line_height+2)*(n_show-1), COLOR_LIGHTGREY, COLOR_STD_BG); } // show scroll bar u32 bar_x = x + item_width + 2; @@ -954,8 +998,8 @@ u32 ShowFileScrollPrompt(u32 n, const DirEntry** options, bool hide_ext, const c } else DrawRectangle(MAIN_SCREEN, bar_x, yopt, bar_width, flist_height, COLOR_STD_BG); u32 pad_state = InputWait(0); - if (pad_state & BUTTON_DOWN) sel++; - else if (pad_state & BUTTON_UP) sel--; + if (pad_state & BUTTON_DOWN) sel = (sel+1) % n; + else if (pad_state & BUTTON_UP) sel = (sel+n-1) % n; else if (pad_state & BUTTON_RIGHT) sel += n_show; else if (pad_state & BUTTON_LEFT) sel -= n_show; else if (pad_state & BUTTON_A) break; @@ -964,15 +1008,15 @@ u32 ShowFileScrollPrompt(u32 n, const DirEntry** options, bool hide_ext, const c break; } if (sel < 0) sel = 0; - else if (sel >= (int)n) sel = n-1; + else if (sel >= n) sel = n-1; if (sel < scroll) scroll = sel; - else if (sel == (int) n-1 && sel >= (int)(scroll + n_show - 1)) scroll = sel - n_show + 1; - else if (sel >= (int)(scroll + (n_show-1) - 1)) scroll = sel - (n_show-1) + 1; + else if (sel == n-1 && sel >= (scroll + n_show - 1)) scroll = sel - n_show + 1; + else if (sel >= (scroll + (n_show-1) - 1)) scroll = sel - (n_show-1) + 1; } ClearScreenF(true, false, COLOR_STD_BG); - return (sel >= (int)n) ? 0 : sel + 1; + return (sel >= n) ? 0 : sel + 1; } u32 ShowHotkeyPrompt(u32 n, const char** options, const u32* keys, const char *format, ...) { @@ -989,7 +1033,7 @@ u32 ShowHotkeyPrompt(u32 n, const char** options, const u32* keys, const char *f ButtonToString(keys[i], buttonstr); ptr += snprintf(ptr, STRBUF_SIZE - (ptr-str), "\n<%s> %s", buttonstr, options[i]); } - ptr += snprintf(ptr, STRBUF_SIZE - (ptr-str), "\n \n<%s> %s", "B", "cancel"); + ptr += snprintf(ptr, STRBUF_SIZE - (ptr-str), "\n \n<%s> %s", "B", STR_CANCEL); ClearScreenF(true, false, COLOR_STD_BG); DrawStringCenter(MAIN_SCREEN, COLOR_STD_FONT, COLOR_STD_BG, "%s", str); @@ -1038,7 +1082,7 @@ bool ShowInputPrompt(char* inputstr, u32 max_size, u32 resize, const char* alpha ClearScreenF(true, false, COLOR_STD_BG); DrawStringF(MAIN_SCREEN, x, y, COLOR_STD_FONT, COLOR_STD_BG, "%s", str); DrawStringF(MAIN_SCREEN, x + 8, y + str_height - 40, COLOR_STD_FONT, COLOR_STD_BG, - "R - (↑↓) fast scroll\nL - clear data%s", resize ? "\nX - remove char\nY - insert char" : ""); + "%s\n%s", STR_R_FAST_SCROLL_L_CLEAR_DATA, resize ? STR_X_REMOVE_CHAR_Y_INSERT_CHAR : ""); // wait for all keys released while (HID_ReadState() & BUTTON_ANY); @@ -1076,15 +1120,15 @@ bool ShowInputPrompt(char* inputstr, u32 max_size, u32 resize, const char* alpha DrawStringF(MAIN_SCREEN, x, y + str_height - 76, COLOR_STD_FONT, COLOR_STD_BG, "%c%-*.*s%c\n%-*.*s^%-*.*s", (scroll) ? '<' : '|', - input_shown_size, - input_shown_size, + (int) input_shown_size, + (int) input_shown_size, (scroll > inputstr_size) ? "" : inputstr + scroll, (inputstr_size - (s32) scroll > input_shown_size) ? '>' : '|', - 1 + cpos, - 1 + cpos, + (int) 1 + cpos, + (int) 1 + cpos, "", - input_shown_length - cpos, - input_shown_length - cpos, + (int) input_shown_length - cpos, + (int) input_shown_length - cpos, "" ); @@ -1221,7 +1265,7 @@ u64 ShowHexPrompt(u64 start_val, u32 n_digits, const char *format, ...) { va_list va; if (n_digits > 16) n_digits = 16; - snprintf(inputstr, 16 + 1, "%0*llX", (int) n_digits, start_val); + snprintf(inputstr, sizeof(inputstr), "%0*llX", (int) n_digits, start_val); va_start(va, format); if (ShowInputPrompt(inputstr, n_digits + 1, 0, alphabet, format, va)) { @@ -1238,7 +1282,7 @@ u64 ShowNumberPrompt(u64 start_val, const char *format, ...) { u64 ret = 0; va_list va; - snprintf(inputstr, 20 + 1, "%llu", start_val); + snprintf(inputstr, sizeof(inputstr), "%llu", start_val); va_start(va, format); if (ShowInputPrompt(inputstr, 20 + 1, 1, alphabet, format, va)) { @@ -1358,7 +1402,7 @@ bool ShowProgress(u64 current, u64 total, const char* opstr) const u32 text_pos_y = bar_pos_y + bar_height + 2; u32 prog_width = ((total > 0) && (current <= total)) ? (current * (bar_width-4)) / total : 0; u32 prog_percent = ((total > 0) && (current <= total)) ? (current * 100) / total : 0; - char tempstr[64]; + char tempstr[UTF_BUFFER_BYTESIZE(64)]; char progstr[UTF_BUFFER_BYTESIZE(64)]; static u64 last_msec_elapsed = 0; @@ -1383,16 +1427,16 @@ bool ShowProgress(u64 current, u64 total, const char* opstr) DrawRectangle(MAIN_SCREEN, bar_pos_x + 2 + prog_width, bar_pos_y + 2, (bar_width-4) - prog_width, bar_height - 4, COLOR_STD_BG); TruncateString(progstr, opstr, min(63, (bar_width / FONT_WIDTH_EXT) - 7), 8); - snprintf(tempstr, 64, "%s (%lu%%)", progstr, prog_percent); + snprintf(tempstr, sizeof(tempstr), "%s (%lu%%)", progstr, prog_percent); ResizeString(progstr, tempstr, bar_width / FONT_WIDTH_EXT, 8, false); DrawString(MAIN_SCREEN, progstr, bar_pos_x, text_pos_y, COLOR_STD_FONT, COLOR_STD_BG); if (sec_elapsed >= 1) { - snprintf(tempstr, 16, "ETA %02llum%02llus", sec_remain / 60, sec_remain % 60); + snprintf(tempstr, sizeof(tempstr), STR_ETA_N_MIN_N_SEC, sec_remain / 60, sec_remain % 60); ResizeString(progstr, tempstr, 16, 8, true); DrawString(MAIN_SCREEN, progstr, bar_pos_x + bar_width - 1 - (FONT_WIDTH_EXT * 16), bar_pos_y - line_height - 1, COLOR_STD_FONT, COLOR_STD_BG); } - DrawString(MAIN_SCREEN, "(hold B to cancel)", bar_pos_x + 2, text_pos_y + 14, COLOR_STD_FONT, COLOR_STD_BG); + DrawString(MAIN_SCREEN, STR_HOLD_B_TO_CANCEL, bar_pos_x + 2, text_pos_y + 14, COLOR_STD_FONT, COLOR_STD_BG); last_prog_width = prog_width; @@ -1405,13 +1449,7 @@ int ShowBrightnessConfig(int set_brightness) u32 btn_input, bar_count; int bar_x_pos, bar_y_pos, bar_width, bar_height; - const char *brightness_str = - "[←] Decrease brightness\n" - "[→] Increase brightness\n" - " \n" - "[X] Use volume slider control\n" - "[A] Set current brightness\n" - "[B] Cancel"; + const char *brightness_str = STR_BRIGHTNESS_CONTROLS; static const u16 brightness_slider_colmasks[] = { COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_WHITE }; @@ -1432,7 +1470,7 @@ int ShowBrightnessConfig(int set_brightness) // draw initial UI stuff DrawStringF(MAIN_SCREEN, (SCREEN_WIDTH_MAIN - GetDrawStringWidth(brightness_str)) / 2, - (SCREEN_HEIGHT / 4) * 2, COLOR_STD_FONT, COLOR_STD_BG, brightness_str); + (SCREEN_HEIGHT / 4) * 2, COLOR_STD_FONT, COLOR_STD_BG, "%s", brightness_str); // draw all color gradient bars for (int x = 0; x < bar_width; x++) { diff --git a/arm9/source/common/ui.h b/arm9/source/common/ui.h index 071ff9980..4f51c0bb4 100644 --- a/arm9/source/common/ui.h +++ b/arm9/source/common/ui.h @@ -24,6 +24,8 @@ #define UTF_MAX_BYTES_PER_RUNE 4 #define UTF_BUFFER_BYTESIZE(rune_count) (((rune_count) + 1) * UTF_MAX_BYTES_PER_RUNE) +#define PRINTF_ARGS(n) __attribute__ ((format (printf, (n), (n) + 1))) + #define TOP_SCREEN ((u16*)VRAM_TOP_LA) #define BOT_SCREEN ((u16*)VRAM_BOT_A) @@ -43,13 +45,13 @@ #ifndef AUTO_UNLOCK -bool ShowUnlockSequence(u32 seqlvl, const char *format, ...); +bool PRINTF_ARGS(2) ShowUnlockSequence(u32 seqlvl, const char *format, ...); #else #define ShowUnlockSequence ShowPrompt #endif -u8* GetFontFromPbm(const void* pbm, const u32 riff_size, u32* w, u32* h); -u8* GetFontFromRiff(const void* riff, const u32 riff_size, u32* w, u32* h, u16* count); +const u8* GetFontFromPbm(const void* pbm, const u32 riff_size, u32* w, u32* h); +const u8* GetFontFromRiff(const void* riff, const u32 riff_size, u32* w, u32* h, u16* count); bool SetFont(const void* font, const u32 font_size); u16 GetColor(const u16 *screen, int x, int y); @@ -63,8 +65,8 @@ void DrawQrCode(u16 *screen, const u8* qrcode); void DrawCharacter(u16 *screen, u32 character, int x, int y, u32 color, u32 bgcolor); void DrawString(u16 *screen, const char *str, int x, int y, u32 color, u32 bgcolor); -void DrawStringF(u16 *screen, int x, int y, u32 color, u32 bgcolor, const char *format, ...); -void DrawStringCenter(u16 *screen, u32 color, u32 bgcolor, const char *format, ...); +void PRINTF_ARGS(6) DrawStringF(u16 *screen, int x, int y, u32 color, u32 bgcolor, const char *format, ...); +void PRINTF_ARGS(4) DrawStringCenter(u16 *screen, u32 color, u32 bgcolor, const char *format, ...); u32 GetCharSize(const char* str); u32 GetPrevCharSize(const char* str); @@ -81,19 +83,19 @@ void TruncateString(char* dest, const char* orig, int nlength, int tpos); void FormatNumber(char* str, u64 number); void FormatBytes(char* str, u64 bytes); -void ShowString(const char *format, ...); -void ShowStringF(u16* screen, const char *format, ...); -void ShowIconString(u16* icon, int w, int h, const char *format, ...); -void ShowIconStringF(u16* screen, u16* icon, int w, int h, const char *format, ...); -bool ShowPrompt(bool ask, const char *format, ...); -u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...); -u32 ShowFileScrollPrompt(u32 n, const DirEntry** entries, bool hide_ext, const char *format, ...); -u32 ShowHotkeyPrompt(u32 n, const char** options, const u32* keys, const char *format, ...); -bool ShowStringPrompt(char* inputstr, u32 max_size, const char *format, ...); -u64 ShowHexPrompt(u64 start_val, u32 n_digits, const char *format, ...); -u64 ShowNumberPrompt(u64 start_val, const char *format, ...); -bool ShowDataPrompt(u8* data, u32* size, const char *format, ...); -bool ShowRtcSetterPrompt(void* time, const char *format, ...); +void PRINTF_ARGS(1) ShowString(const char *format, ...); +void PRINTF_ARGS(2) ShowStringF(u16* screen, const char *format, ...); +void PRINTF_ARGS(4) ShowIconString(u16* icon, int w, int h, const char *format, ...); +void PRINTF_ARGS(5) ShowIconStringF(u16* screen, u16* icon, int w, int h, const char *format, ...); +bool PRINTF_ARGS(2) ShowPrompt(bool ask, const char *format, ...); +u32 PRINTF_ARGS(3) ShowSelectPrompt(int n, const char** options, const char *format, ...); +u32 PRINTF_ARGS(4) ShowFileScrollPrompt(int n, const DirEntry** entries, bool hide_ext, const char *format, ...); +u32 PRINTF_ARGS(4) ShowHotkeyPrompt(u32 n, const char** options, const u32* keys, const char *format, ...); +bool PRINTF_ARGS(3) ShowStringPrompt(char* inputstr, u32 max_size, const char *format, ...); +u64 PRINTF_ARGS(3) ShowHexPrompt(u64 start_val, u32 n_digits, const char *format, ...); +u64 PRINTF_ARGS(2) ShowNumberPrompt(u64 start_val, const char *format, ...); +bool PRINTF_ARGS(3) ShowDataPrompt(u8* data, u32* size, const char *format, ...); +bool PRINTF_ARGS(2) ShowRtcSetterPrompt(void* time, const char *format, ...); bool ShowProgress(u64 current, u64 total, const char* opstr); int ShowBrightnessConfig(int set_brightness); diff --git a/arm9/source/crypto/keydb.c b/arm9/source/crypto/keydb.c index 3b41d6866..88487d647 100644 --- a/arm9/source/crypto/keydb.c +++ b/arm9/source/crypto/keydb.c @@ -40,10 +40,13 @@ u32 GetUnitKeysType(void) } void CryptAesKeyInfo(AesKeyInfo* info) { - static u8 zeroes[16] = { 0 }; + static const u8 zeros[16] = { 0 }; + static const u8 keyY_dev[16] = { + 0xA2, 0x32, 0x4A, 0x7E, 0x7C, 0xE6, 0x1A, 0x9A, 0x45, 0x4A, 0x52, 0x19, 0xB3, 0x5B, 0xE9, 0x3B }; + const u8* aeskeyY = GetUnitKeysType() == KEYS_DEVKIT ? &keyY_dev[0] : &zeros[0]; u8 ctr[16] = { 0 }; memcpy(ctr, (void*) info, 12); // CTR -> slot + type + id + zeroes - setup_aeskeyY(0x2C, zeroes); + setup_aeskeyY(0x2C, aeskeyY); use_aeskey(0x2C); set_ctr(ctr); aes_decrypt(info->key, info->key, 1, AES_CNT_CTRNAND_MODE); @@ -152,7 +155,7 @@ u32 LoadKeyFromFile(void* key, u32 keyslot, char type, char* id) // load legacy slot0x??Key?.bin file instead if (!found && (type != 'I')) { char fname[64]; - snprintf(fname, 64, "slot0x%02lXKey%s%s.bin", keyslot, + snprintf(fname, sizeof(fname), "slot0x%02lXKey%s%s.bin", keyslot, (type == 'X') ? "X" : (type == 'Y') ? "Y" : (type == 'I') ? "IV" : "", (id) ? id : ""); found = (LoadSupportFile(fname, key, 16) == 16); } diff --git a/arm9/source/filesys/filetype.c b/arm9/source/filesys/filetype.c index baa090e9b..cc3caa610 100644 --- a/arm9/source/filesys/filetype.c +++ b/arm9/source/filesys/filetype.c @@ -129,6 +129,8 @@ u64 IdentifyFileType(const char* path) { return FONT_PBM; } else if (GetFontFromRiff(data, fsize, NULL, NULL, NULL)) { return FONT_RIFF; + } else if (GetLanguage(data, fsize, NULL, NULL, NULL)) { + return TRANSLATION; } else if ((fsize > sizeof(AgbHeader)) && (ValidateAgbHeader((AgbHeader*) data) == 0)) { return GAME_GBA; @@ -161,7 +163,7 @@ u64 IdentifyFileType(const char* path) { return BIN_CIFNSH; } else if (ValidateText((char*) data, (fsize > 0x200) ? 0x200 : fsize)) { u64 type = 0; - if ((fsize < SCRIPT_MAX_SIZE) && (strncasecmp(ext, SCRIPT_EXT, strnlen(SCRIPT_EXT, 16) + 1) == 0)) + if ((fsize < SCRIPT_MAX_SIZE) && (strcasecmp(ext, SCRIPT_EXT) == 0)) type |= TXT_SCRIPT; // should be a script (which is also generic text) if (fsize < STD_BUFFER_SIZE) type |= TXT_GENERIC; return type; diff --git a/arm9/source/filesys/filetype.h b/arm9/source/filesys/filetype.h index de963af8a..b750e1e59 100644 --- a/arm9/source/filesys/filetype.h +++ b/arm9/source/filesys/filetype.h @@ -39,6 +39,7 @@ #define FONT_RIFF (1ULL<<34) #define NOIMG_NAND (1ULL<<35) #define HDR_NAND (1ULL<<36) +#define TRANSLATION (1ULL<<37) #define TYPE_BASE 0xFFFFFFFFFFULL // 40 bit reserved for base types // #define FLAG_FIRM (1ULL<<58) // <--- for CXIs containing FIRMs @@ -77,8 +78,9 @@ #define FTYPE_KEYINSTALL(tp) (tp&(BIN_KEYDB)) #define FTYPE_SCRIPT(tp) (tp&(TXT_SCRIPT)) #define FTYPE_FONT(tp) (tp&(FONT_PBM|FONT_RIFF)) +#define FTYPE_TRANSLATION(tp) (tp&(TRANSLATION)) #define FTYPE_GFX(tp) (tp&(GFX_PNG)) -#define FTYPE_SETABLE(tp) (tp&(FONT_PBM|FONT_RIFF)) +#define FTYPE_SETABLE(tp) (tp&(FONT_PBM|FONT_RIFF|TRANSLATION)) #define FTYPE_BOOTABLE(tp) (tp&(SYS_FIRM)) #define FTYPE_INSTALLABLE(tp) (tp&(SYS_FIRM)) #define FTYPE_AGBSAVE(tp) (tp&(SYS_AGBSAVE)) diff --git a/arm9/source/filesys/fsdrive.c b/arm9/source/filesys/fsdrive.c index e680942ec..ce3e21b1a 100644 --- a/arm9/source/filesys/fsdrive.c +++ b/arm9/source/filesys/fsdrive.c @@ -1,6 +1,7 @@ #include "fsdrive.h" #include "fsgame.h" #include "fsinit.h" +#include "language.h" #include "virtual.h" #include "vcart.h" #include "sddata.h" @@ -84,13 +85,13 @@ bool GetFATVolumeLabel(const char* drv, char* label) { } bool GetRootDirContentsWorker(DirStruct* contents) { - static const char* drvname[] = { FS_DRVNAME }; + const char* drvname[] = { FS_DRVNAME }; static const char* drvnum[] = { FS_DRVNUM }; u32 n_entries = 0; char sdlabel[DRV_LABEL_LEN]; if (!GetFATVolumeLabel("0:", sdlabel) || !(*sdlabel)) - strcpy(sdlabel, "NOLABEL"); + strcpy(sdlabel, STR_LAB_NOLABEL); char carttype[16]; GetVCartTypeString(carttype); @@ -101,15 +102,15 @@ bool GetRootDirContentsWorker(DirStruct* contents) { if (!DriveType(drvnum[i])) continue; // drive not available entry->p_name = 4; entry->name = entry->path + entry->p_name; - memset(entry->path, 0x00, 64); + memset(entry->path, 0x00, 256); snprintf(entry->path, 4, "%s", drvnum[i]); if ((*(drvnum[i]) >= '7') && (*(drvnum[i]) <= '9') && !(GetMountState() & IMG_NAND)) // Drive 7...9 handling - snprintf(entry->name, 32, "[%s] %s", drvnum[i], - (*(drvnum[i]) == '7') ? "FAT IMAGE" : - (*(drvnum[i]) == '8') ? "BONUS DRIVE" : - (*(drvnum[i]) == '9') ? "RAMDRIVE" : "UNK"); + snprintf(entry->name, 252, "[%s] %s", drvnum[i], + (*(drvnum[i]) == '7') ? STR_LAB_FAT_IMAGE : + (*(drvnum[i]) == '8') ? STR_LAB_BONUS_DRIVE : + (*(drvnum[i]) == '9') ? STR_LAB_RAMDRIVE : "UNK"); else if (*(drvnum[i]) == 'G') // Game drive special handling - snprintf(entry->name, 32, "[%s] %s %s", drvnum[i], + snprintf(entry->name, 252, "[%s] %s %s", drvnum[i], (GetMountState() & GAME_CIA ) ? "CIA" : (GetMountState() & GAME_NCSD ) ? "NCSD" : (GetMountState() & GAME_NCCH ) ? "NCCH" : @@ -119,10 +120,10 @@ bool GetRootDirContentsWorker(DirStruct* contents) { (GetMountState() & SYS_FIRM ) ? "FIRM" : (GetMountState() & GAME_TAD ) ? "DSIWARE" : "UNK", drvname[i]); else if (*(drvnum[i]) == 'C') // Game cart handling - snprintf(entry->name, 32, "[%s] %s (%s)", drvnum[i], drvname[i], carttype); + snprintf(entry->name, 252, "[%s] %s (%s)", drvnum[i], drvname[i], carttype); else if (*(drvnum[i]) == '0') // SD card handling - snprintf(entry->name, 32, "[%s] %s (%s)", drvnum[i], drvname[i], sdlabel); - else snprintf(entry->name, 32, "[%s] %s", drvnum[i], drvname[i]); + snprintf(entry->name, 252, "[%s] %s (%s)", drvnum[i], drvname[i], sdlabel); + else snprintf(entry->name, 252, "[%s] %s", drvnum[i], drvname[i]); entry->size = GetTotalSpace(entry->path); entry->type = T_ROOT; entry->marked = 0; @@ -211,7 +212,7 @@ void SearchDirContents(DirStruct* contents, const char* path, const char* patter void GetDirContents(DirStruct* contents, const char* path) { if (*search_path && (DriveType(path) & DRV_SEARCH)) { - ShowString("Searching, please wait..."); + ShowString("%s", STR_SEARCHING_PLEASE_WAIT); SearchDirContents(contents, search_path, search_pattern, true); ClearScreenF(true, false, COLOR_STD_BG); } else if (title_manager_mode && (DriveType(path) & DRV_TITLEMAN)) { @@ -231,7 +232,7 @@ uint64_t GetFreeSpace(const char* path) FATFS* fsobj = GetMountedFSObject(path); if ((pdrv < 0) || !fsobj) return 0; - snprintf(fsname, 3, "%i:", pdrv); + snprintf(fsname, sizeof(fsname), "%i:", pdrv); if (f_getfree(fsname, &free_clusters, &fsptr) != FR_OK) return 0; diff --git a/arm9/source/filesys/fsdrive.h b/arm9/source/filesys/fsdrive.h index e9f4b4013..e41c461a2 100644 --- a/arm9/source/filesys/fsdrive.h +++ b/arm9/source/filesys/fsdrive.h @@ -32,16 +32,16 @@ #define DRV_LABEL_LEN (36) #define FS_DRVNAME \ - "SDCARD", \ - "SYSNAND CTRNAND", "SYSNAND TWLN", "SYSNAND TWLP", "SYSNAND SD", "SYSNAND VIRTUAL", \ - "EMUNAND CTRNAND", "EMUNAND TWLN", "EMUNAND TWLP", "EMUNAND SD", "EMUNAND VIRTUAL", \ - "IMGNAND CTRNAND", "IMGNAND TWLN", "IMGNAND TWLP", "IMGNAND VIRTUAL", \ - "GAMECART", \ - "GAME IMAGE", "AESKEYDB IMAGE", "BDRI IMAGE", "DISA/DIFF IMAGE", \ - "MEMORY VIRTUAL", \ - "VRAM VIRTUAL", \ - "TITLE MANAGER", \ - "LAST SEARCH" \ + STR_LAB_SDCARD, \ + STR_LAB_SYSNAND_CTRNAND, STR_LAB_SYSNAND_TWLN, STR_LAB_SYSNAND_TWLP, STR_LAB_SYSNAND_SD, STR_LAB_SYSNAND_VIRTUAL, \ + STR_LAB_EMUNAND_CTRNAND, STR_LAB_EMUNAND_TWLN, STR_LAB_EMUNAND_TWLP, STR_LAB_EMUNAND_SD, STR_LAB_EMUNAND_VIRTUAL, \ + STR_LAB_IMGNAND_CTRNAND, STR_LAB_IMGNAND_TWLN, STR_LAB_IMGNAND_TWLP, STR_LAB_IMGNAND_VIRTUAL, \ + STR_LAB_GAMECART, \ + STR_LAB_GAME_IMAGE, STR_LAB_AESKEYDB_IMAGE, STR_LAB_BDRI_IMAGE, STR_LAB_DISA_DIFF_IMAGE, \ + STR_LAB_MEMORY_VIRTUAL, \ + STR_LAB_VRAM_VIRTUAL, \ + STR_LAB_TITLE_MANAGER, \ + STR_LAB_LAST_SEARCH #define FS_DRVNUM \ "0:", "1:", "2:", "3:", "A:", "S:", "4:", "5:", "6:", "B:", "E:", "7:", "8:", "9:", \ diff --git a/arm9/source/filesys/fsgame.c b/arm9/source/filesys/fsgame.c index 8a0f49ff3..600eddd1f 100644 --- a/arm9/source/filesys/fsgame.c +++ b/arm9/source/filesys/fsgame.c @@ -1,6 +1,7 @@ #include "fsgame.h" #include "fsperm.h" #include "gameutil.h" +#include "language.h" #include "tie.h" #include "ui.h" #include "vff.h" @@ -39,7 +40,7 @@ bool GoodRenamer(DirEntry* entry, bool ask) { TruncateString(oldname_tr, entry->name, 32, 8); strncpy(newname_ww, goodname, 256); WordWrapString(newname_ww, 32); - if (!ShowPrompt(true, "%s\nRename to good name?\n \n%s", oldname_tr, newname_ww)) + if (!ShowPrompt(true, "%s\n%s\n \n%s", oldname_tr, STR_RENAME_TO_GOOD_NAME, newname_ww)) return true; // call it a success because user choice } diff --git a/arm9/source/filesys/fsinit.c b/arm9/source/filesys/fsinit.c index c80d34e26..f0183dcaf 100644 --- a/arm9/source/filesys/fsinit.c +++ b/arm9/source/filesys/fsinit.c @@ -21,7 +21,7 @@ bool InitExtFS() { for (u32 i = 1; i < NORM_FS; i++) { char fsname[8]; - snprintf(fsname, 7, "%lu:", i); + snprintf(fsname, sizeof(fsname), "%lu:", i); if (fs_mounted[i]) continue; fs_mounted[i] = (f_mount(fs + i, fsname, 1) == FR_OK); if ((!fs_mounted[i] || !ramdrv_ready) && (i == NORM_FS - 1) && !(GetMountState() & IMG_NAND)) { @@ -44,7 +44,7 @@ bool InitImgFS(const char* path) { u32 drv_i = NORM_FS - IMGN_FS; char fsname[8]; for (; drv_i < NORM_FS; drv_i++) { - snprintf(fsname, 7, "%lu:", drv_i); + snprintf(fsname, sizeof(fsname), "%lu:", drv_i); if (!(DriveType(fsname)&DRV_IMAGE)) break; } // deinit virtual filesystem @@ -58,7 +58,7 @@ bool InitImgFS(const char* path) { else if ((type&IMG_FAT) && (drv_i < NORM_FS - IMGN_FS + 1)) drv_i = NORM_FS - IMGN_FS + 1; // reinit image filesystem for (u32 i = NORM_FS - IMGN_FS; i < drv_i; i++) { - snprintf(fsname, 7, "%lu:", i); + snprintf(fsname, sizeof(fsname), "%lu:", i); fs_mounted[i] = (f_mount(fs + i, fsname, 1) == FR_OK); } return GetMountState(); @@ -71,7 +71,7 @@ void DeinitExtFS() { for (u32 i = NORM_FS - 1; i > 0; i--) { if (fs_mounted[i]) { char fsname[8]; - snprintf(fsname, 7, "%lu:", i); + snprintf(fsname, sizeof(fsname), "%lu:", i); f_mount(NULL, fsname, 1); fs_mounted[i] = false; } @@ -91,7 +91,7 @@ void DismountDriveType(u32 type) { // careful with this - no safety checks } for (u32 i = 0; i < NORM_FS; i++) { char fsname[8]; - snprintf(fsname, 7, "%lu:", i); + snprintf(fsname, sizeof(fsname), "%lu:", i); if (!fs_mounted[i] || !(type & DriveType(fsname))) continue; f_mount(NULL, fsname, 1); diff --git a/arm9/source/filesys/fsperm.c b/arm9/source/filesys/fsperm.c index fb545b7df..ae4eb6060 100644 --- a/arm9/source/filesys/fsperm.c +++ b/arm9/source/filesys/fsperm.c @@ -4,6 +4,7 @@ #include "image.h" #include "unittype.h" #include "essentials.h" +#include "language.h" #include "ui.h" #include "sdmmc.h" @@ -20,7 +21,7 @@ static u32 write_permissions = PERM_BASE; bool CheckWritePermissions(const char* path) { - char area_name[16]; + char area_name[UTF_BUFFER_BYTESIZE(16)]; int drvtype = DriveType(path); u32 perm; @@ -40,7 +41,7 @@ bool CheckWritePermissions(const char* path) { // SD card write protection check if ((drvtype & (DRV_SDCARD | DRV_EMUNAND | DRV_ALIAS)) && SD_WRITE_PROTECTED) { - ShowPrompt(false, "SD card is write protected!\nCan't continue."); + ShowPrompt(false, "%s", STR_SD_WRITE_PROTECTED_CANT_CONTINUE); return false; } @@ -63,7 +64,7 @@ bool CheckWritePermissions(const char* path) { if ((drvtype & DRV_CTRNAND) || (lvl == 2)) lvl = 3; } perm = perms[lvl]; - snprintf(area_name, 16, "SysNAND (lvl%lu)", lvl); + snprintf(area_name, sizeof(area_name), STR_SYSNAND_LVL_N, lvl); } else if (drvtype & DRV_EMUNAND) { static const u32 perms[] = { PERM_EMU_LVL0, PERM_EMU_LVL1 }; u32 lvl = (drvtype & (DRV_ALIAS|DRV_CTRNAND)) ? 1 : 0; @@ -73,34 +74,34 @@ bool CheckWritePermissions(const char* path) { if (strncasecmp(path_f, path_lvl1[i], 256) == 0) lvl = 1; } perm = perms[lvl]; - snprintf(area_name, 16, "EmuNAND (lvl%lu)", lvl); + snprintf(area_name, sizeof(area_name), STR_EMUNAND_LVL_N, lvl); } else if (drvtype & DRV_GAME) { perm = PERM_GAME; - snprintf(area_name, 16, "game images"); + snprintf(area_name, sizeof(area_name), "%s", STR_GAME_IMAGES); } else if (drvtype & DRV_CART) { perm = PERM_CART; - snprintf(area_name, 16, "gamecart saves"); + snprintf(area_name, sizeof(area_name), "%s", STR_GAMECART_SAVES); } else if (drvtype & DRV_VRAM) { perm = PERM_VRAM; - snprintf(area_name, 16, "vram0"); + snprintf(area_name, sizeof(area_name), "vram0"); } else if (drvtype & DRV_XORPAD) { perm = PERM_XORPAD; - snprintf(area_name, 16, "XORpads"); + snprintf(area_name, sizeof(area_name), "XORpads"); } else if (drvtype & DRV_IMAGE) { perm = PERM_IMAGE; - snprintf(area_name, 16, "images"); + snprintf(area_name, sizeof(area_name), "%s", STR_IMAGES); } else if (drvtype & DRV_MEMORY) { perm = PERM_MEMORY; - snprintf(area_name, 16, "memory areas"); + snprintf(area_name, sizeof(area_name), "%s", STR_MEMORY_AREAS); } else if (strncasecmp(path_f, "0:/Nintendo 3DS", 15) == 0) { // this check could be better perm = PERM_SDDATA; - snprintf(area_name, 16, "SD system data"); + snprintf(area_name, sizeof(area_name), "%s", STR_SD_SYSTEM_DATA); } else if (drvtype & DRV_SDCARD) { perm = PERM_SDCARD; - snprintf(area_name, 16, "SD card"); + snprintf(area_name, sizeof(area_name), "%s", STR_SD_CARD); } else if (drvtype & DRV_RAMDRIVE) { perm = PERM_RAMDRIVE; - snprintf(area_name, 16, "RAM drive"); + snprintf(area_name, sizeof(area_name), "%s", STR_RAM_DRIVE); } else { return false; } @@ -112,14 +113,14 @@ bool CheckWritePermissions(const char* path) { // offer unlock if possible if (!(perm & (PERM_VRAM|PERM_GAME|PERM_XORPAD))) { // ask the user - if (!ShowPrompt(true, "Writing to %s is locked!\nUnlock it now?", area_name)) + if (!ShowPrompt(true, STR_WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW, area_name)) return false; return SetWritePermissions(perm, true); } // unlock not possible - ShowPrompt(false, "Unlock write permission for\n%s is not allowed.", area_name); + ShowPrompt(false, STR_UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED, area_name); return false; } @@ -144,65 +145,65 @@ bool SetWritePermissions(u32 perm, bool add_perm) { switch (perm) { case PERM_BASE: - if (!ShowUnlockSequence(1, "You want to enable base\nwriting permissions.")) + if (!ShowUnlockSequence(1, "%s", STR_ENABLE_BASE_WRITE)) return false; break; case PERM_SDCARD: - if (!ShowUnlockSequence(1, "You want to enable SD card\nwriting permissions.")) + if (!ShowUnlockSequence(1, "%s", STR_ENABLE_SD_WRITE)) return false; break; case PERM_IMAGE: - if (!ShowUnlockSequence(1, "You want to enable image\nwriting permissions.")) + if (!ShowUnlockSequence(1, "%s", STR_ENABLE_IMAGE_WRITE)) return false; break; case PERM_RAMDRIVE: - if (!ShowUnlockSequence(1, "You want to enable RAM drive\nwriting permissions.")) + if (!ShowUnlockSequence(1, "%s", STR_ENABLE_RAM_DRIVE_WRITE)) return false; break; case PERM_EMU_LVL0: - if (!ShowUnlockSequence(1, "You want to enable EmuNAND\nlvl0 writing permissions.")) + if (!ShowUnlockSequence(1, "%s", STR_ENABLE_EMUNAND_0_WRITE)) return false; break; case PERM_SYS_LVL0: - if (!ShowUnlockSequence(1, "You want to enable SysNAND\nlvl0 writing permissions.")) + if (!ShowUnlockSequence(1, "%s", STR_ENABLE_SYSNAND_0_WRITE)) return false; break; case PERM_EMU_LVL1: - if (!ShowUnlockSequence(2, "You want to enable EmuNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nrecoverable system data,\nuser data & savegames.")) + if (!ShowUnlockSequence(2, "%s", STR_ENABLE_EMUNAND_1_WRITE)) return false; break; case PERM_SYS_LVL1: - if (!ShowUnlockSequence(2, "You want to enable SysNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nsystem data, installations,\nuser data & savegames.")) + if (!ShowUnlockSequence(2, "%s", STR_ENABLE_SYSNAND_1_WRITE)) return false; break; case PERM_CART: - if (!ShowUnlockSequence(2, "You want to enable gamecart\nsave writing permissions.")) + if (!ShowUnlockSequence(2, "%s", STR_ENABLE_GAMECART_SAVE_WRITE)) return false; break; #ifndef SAFEMODE case PERM_SYS_LVL2: - if (!ShowUnlockSequence(3, "!Better be careful!\n \nYou want to enable SysNAND\nlvl2 writing permissions.\n \nThis enables you to modify\nirrecoverable system data!")) + if (!ShowUnlockSequence(3, "%s", STR_ENABLE_SYSNAND_2_WRITE)) return false; break; case PERM_MEMORY: - if (!ShowUnlockSequence(4, "!Better be careful!\n \nYou want to enable memory\nwriting permissions.\n \nWriting to certain areas may\nlead to unexpected results.")) + if (!ShowUnlockSequence(4, "%s", STR_ENABLE_MEMORY_WRITE)) return false; break; case PERM_SDDATA: - if (!ShowUnlockSequence(5, "!THIS IS NOT RECOMMENDED!\n \nYou want to enable SD data\nwriting permissions.\n \nEverything here is encrypted.\nIt is recommended to use the\nA:/B: drives for modification\nof installations, user data &\nsavegames instead.")) + if (!ShowUnlockSequence(5, "%s", STR_ENABLE_SD_DATA_WRITE)) return false; break; case PERM_SYS_LVL3: - if (!ShowUnlockSequence(6, "!THIS IS YOUR ONLY WARNING!\n \nYou want to enable SysNAND\nlvl3 writing permissions.\n \nThis enables you to OVERWRITE\nyour bootloader installation,\nessential system files and/or\nBRICK your console!")) + if (!ShowUnlockSequence(6, "%s", STR_ENABLE_SYSNAND_3_WRITE)) return false; break; default: - ShowPrompt(false, "Unlock write permission is not allowed."); + ShowPrompt(false, "%s", STR_UNLOCK_WRITE_NOT_ALLOWED); return false; break; #else default: - ShowPrompt(false, "Can't unlock write permission.\nTry GodMode9 instead!"); + ShowPrompt(false, "%s", STR_CANT_UNLOCK_WRITE_TRY_GODMODE9); return false; break; #endif diff --git a/arm9/source/filesys/fsutil.c b/arm9/source/filesys/fsutil.c index f785bfe73..6b9cfd0cc 100644 --- a/arm9/source/filesys/fsutil.c +++ b/arm9/source/filesys/fsutil.c @@ -11,9 +11,10 @@ #include "ff.h" #include "ui.h" #include "swkbd.h" +#include "language.h" -#define SKIP_CUR (1UL<<10) -#define OVERWRITE_CUR (1UL<<11) +#define SKIP_CUR (1UL<<11) +#define OVERWRITE_CUR (1UL<<12) #define _MAX_FS_OPT 8 // max file selector options @@ -46,13 +47,13 @@ bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label) { // FAT size check if (fat_size < 0x80000) { // minimum free space: 256MB - ShowPrompt(false, "Error: SD card is too small"); + ShowPrompt(false, "%s", STR_ERROR_SD_TOO_SMALL); return false; } // Write protection check if (SD_WRITE_PROTECTED) { - ShowPrompt(false, "SD card is write protected!\nCan't continue."); + ShowPrompt(false, "%s", STR_SD_WRITE_PROTECTED_CANT_CONTINUE); return false; } @@ -67,15 +68,15 @@ bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label) { // one last warning.... // 0:/Nintendo 3DS/ write permission is ignored here, this warning is enough - if (!ShowUnlockSequence(5, "!WARNING!\n \nProceeding will format this SD.\nThis will irreversibly delete\nALL data on it.")) + if (!ShowUnlockSequence(5, "%s", STR_WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA)) return false; - ShowString("Formatting SD, please wait..."); + ShowString("%s", STR_FORMATTING_SD_PLEASE_WAIT); // write the MBR to disk // !this assumes a fully deinitialized file system! if ((sdmmc_sdcard_init() != 0) || (sdmmc_sdcard_writesectors(0, 1, mbr) != 0) || (emu_size && ((sdmmc_nand_readsectors(0, 1, ncsd) != 0) || (sdmmc_sdcard_writesectors(1, 1, ncsd) != 0)))) { - ShowPrompt(false, "Error: SD card i/o failure"); + ShowPrompt(false, "%s", STR_ERROR_SD_CARD_IO_FAILURE); return false; } @@ -104,9 +105,9 @@ bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label) { } bool SetupBonusDrive(void) { - if (!ShowUnlockSequence(3, "Format the bonus drive?\nThis will irreversibly delete\nALL data on it.")) + if (!ShowUnlockSequence(3, "%s", STR_FORMAT_BONUS_DRIVE_DELETE_ALL_DATA)) return false; - ShowString("Formatting drive, please wait..."); + ShowString("%s", STR_FORMATTING_DRIVE_PLEASE_WAIT); if (GetMountState() & IMG_NAND) InitImgFS(NULL); u8* buffer = (u8*) malloc(STD_BUFFER_SIZE); @@ -130,7 +131,7 @@ bool FileUnlock(const char* path) { char pathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(pathstr, path, 32, 8); if (GetMountState() && (res == FR_LOCKED) && - (ShowPrompt(true, "%s\nFile is currently mounted.\nUnmount to unlock?", pathstr))) { + (ShowPrompt(true, "%s\n%s", pathstr, STR_FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK))) { InitImgFS(NULL); if (fx_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK) return false; @@ -250,7 +251,7 @@ bool FileInjectFile(const char* dest, const char* orig, u64 off_dest, u64 off_or if (!CheckWritePermissions(dest)) return false; if (strncasecmp(dest, orig, 256) == 0) { - ShowPrompt(false, "Error: Can't inject file into itself"); + ShowPrompt(false, "%s", STR_ERROR_CANT_INJECT_FILE_INTO_ITSELF); return false; } @@ -269,12 +270,12 @@ bool FileInjectFile(const char* dest, const char* orig, u64 off_dest, u64 off_or // check file limits if (!allow_expand && (off_dest + size > fvx_size(&dfile))) { - ShowPrompt(false, "Operation would write beyond end of file"); + ShowPrompt(false, "%s", STR_OPERATION_WOULD_WRITE_BEYOND_EOF); fvx_close(&dfile); fvx_close(&ofile); return false; } else if (off_orig + size > fvx_size(&ofile)) { - ShowPrompt(false, "Not enough data in file"); + ShowPrompt(false, "%s", STR_NOT_ENOUGH_DATA_IN_FILE); fvx_close(&dfile); fvx_close(&ofile); return false; @@ -295,8 +296,8 @@ bool FileInjectFile(const char* dest, const char* orig, u64 off_dest, u64 off_or ret = false; if (ret && !ShowProgress(pos + bytes_read, size, orig)) { if (flags && (*flags & NO_CANCEL)) { - ShowPrompt(false, "Cancel is not allowed here"); - } else ret = !ShowPrompt(true, "B button detected. Cancel?"); + ShowPrompt(false, "%s", STR_CANCEL_IS_NOT_ALLOWED_HERE); + } else ret = !ShowPrompt(true, "%s", STR_B_DETECTED_CANCEL); ShowProgress(0, 0, orig); ShowProgress(pos + bytes_read, size, orig); } @@ -325,7 +326,7 @@ bool FileSetByte(const char* dest, u64 offset, u64 size, u8 fillbyte, u32* flags // check file limits if (!allow_expand && (offset + size > fvx_size(&dfile))) { - ShowPrompt(false, "Operation would write beyond end of file"); + ShowPrompt(false, "%s", STR_OPERATION_WOULD_WRITE_BEYOND_EOF); fvx_close(&dfile); return false; } @@ -345,8 +346,8 @@ bool FileSetByte(const char* dest, u64 offset, u64 size, u8 fillbyte, u32* flags ret = false; if (ret && !ShowProgress(pos + bytes_written, size, dest)) { if (flags && (*flags & NO_CANCEL)) { - ShowPrompt(false, "Cancel is not allowed here"); - } else ret = !ShowPrompt(true, "B button detected. Cancel?"); + ShowPrompt(false, "%s", STR_CANCEL_IS_NOT_ALLOWED_HERE); + } else ret = !ShowPrompt(true, "%s", STR_B_DETECTED_CANCEL); ShowProgress(0, 0, dest); ShowProgress(pos + bytes_written, size, dest); } @@ -362,8 +363,8 @@ bool FileSetByte(const char* dest, u64 offset, u64 size, u8 fillbyte, u32* flags bool FileCreateDummy(const char* cpath, const char* filename, u64 size) { char npath[256]; // 256 is the maximum length of a full path if (!CheckWritePermissions(cpath)) return false; - if (filename) snprintf(npath, 255, "%s/%s", cpath, filename); - else snprintf(npath, 255, "%s", cpath); + if (filename) snprintf(npath, sizeof(npath), "%s/%s", cpath, filename); + else snprintf(npath, sizeof(npath), "%s", cpath); // create dummy file (fail if already existing) // then, expand the file size via cluster preallocation @@ -380,7 +381,7 @@ bool FileCreateDummy(const char* cpath, const char* filename, u64 size) { bool DirCreate(const char* cpath, const char* dirname) { char npath[256]; // 256 is the maximum length of a full path if (!CheckWritePermissions(cpath)) return false; - snprintf(npath, 255, "%s/%s", cpath, dirname); + snprintf(npath, sizeof(npath), "%s/%s", cpath, dirname); if (fa_mkdir(npath) != FR_OK) return false; return (fa_stat(npath, NULL) == FR_OK); } @@ -466,7 +467,7 @@ bool PathMoveCopyRec(char* dest, char* orig, u32* flags, bool move, u8* buffer, // the copy process takes place here if (!ShowProgress(0, 0, orig) && !(flags && (*flags & NO_CANCEL))) { - if (ShowPrompt(true, "%s\nB button detected. Cancel?", deststr)) return false; + if (ShowPrompt(true, "%s\n%s", deststr, STR_B_DETECTED_CANCEL)) return false; ShowProgress(0, 0, orig); } if (move && fvx_stat(dest, NULL) != FR_OK) { // moving if dest not existing @@ -476,14 +477,14 @@ bool PathMoveCopyRec(char* dest, char* orig, u32* flags, bool move, u8* buffer, char* fname = orig + strnlen(orig, 256); if (append) { - if (!silent) ShowPrompt(false, "%s\nError: Cannot append a folder", deststr); + if (!silent) ShowPrompt(false, "%s\n%s", deststr, STR_ERROR_CANNOT_APPEND_FOLDER); return false; } // create the destination folder if it does not already exist if (fvx_opendir(&pdir, dest) != FR_OK) { if (fvx_mkdir(dest) != FR_OK) { - if (!silent) ShowPrompt(false, "%s\nError: Overwriting file with dir", deststr); + if (!silent) ShowPrompt(false, "%s\n%s", deststr, STR_ERROR_OVERWRITING_FILE_WITH_DIR); return false; } } else fvx_closedir(&pdir); @@ -516,7 +517,7 @@ bool PathMoveCopyRec(char* dest, char* orig, u32* flags, bool move, u8* buffer, } else if (move) { // moving if destination exists if (fvx_stat(dest, &fno) != FR_OK) return false; if (fno.fattrib & AM_DIR) { - if (!silent) ShowPrompt(false, "%s\nError: Overwriting dir with file", deststr); + if (!silent) ShowPrompt(false, "%s\n%s", deststr, STR_ERROR_OVERWRITING_DIR_WITH_FILE); return false; } if (fvx_unlink(dest) != FR_OK) return false; @@ -535,7 +536,7 @@ bool PathMoveCopyRec(char* dest, char* orig, u32* flags, bool move, u8* buffer, if ((!append || (fvx_open(&dfile, dest, FA_WRITE | FA_OPEN_EXISTING) != FR_OK)) && (fvx_open(&dfile, dest, FA_WRITE | FA_CREATE_ALWAYS) != FR_OK)) { - if (!silent) ShowPrompt(false, "%s\nError: Cannot open destination file", deststr); + if (!silent) ShowPrompt(false, "%s\n%s", deststr, STR_ERROR_CANNOT_OPEN_DESTINATION_FILE); fvx_close(&ofile); return false; } @@ -544,7 +545,7 @@ bool PathMoveCopyRec(char* dest, char* orig, u32* flags, bool move, u8* buffer, osize = fvx_size(&ofile); dsize = append ? fvx_size(&dfile) : 0; // always 0 if not appending to file if ((fvx_lseek(&dfile, (osize + dsize)) != FR_OK) || (fvx_sync(&dfile) != FR_OK) || (fvx_tell(&dfile) != (osize + dsize))) { // check space via cluster preallocation - if (!silent) ShowPrompt(false, "%s\nError: Not enough space available", deststr); + if (!silent) ShowPrompt(false, "%s\n%s", deststr, STR_ERROR_NOT_ENOUGH_SPACE_AVAILABLE); ret = false; } @@ -566,8 +567,8 @@ bool PathMoveCopyRec(char* dest, char* orig, u32* flags, bool move, u8* buffer, u64 total = osize; if (ret && !ShowProgress(current, total, orig)) { if (flags && (*flags & NO_CANCEL)) { - ShowPrompt(false, "%s\nCancel is not allowed here", deststr); - } else ret = !ShowPrompt(true, "%s\nB button detected. Cancel?", deststr); + ShowPrompt(false, "%s\n%s", deststr, STR_CANCEL_IS_NOT_ALLOWED_HERE); + } else ret = !ShowPrompt(true, "%s\n%s", deststr, STR_B_DETECTED_CANCEL); ShowProgress(0, 0, orig); ShowProgress(current, total, orig); } @@ -614,14 +615,14 @@ bool PathMoveCopy(const char* dest, const char* orig, u32* flags, bool move) { // moving only for regular FAT drives (= not alias drives) if (move && !(ddrvtype & odrvtype & DRV_STDFAT)) { - ShowPrompt(false, "Error: Only FAT files can be moved"); + ShowPrompt(false, "%s", STR_ERROR_ONLY_FAT_FILES_CAN_BE_MOVED); return false; } // is destination part of origin? u32 olen = strnlen(lorig, 255); if ((strncasecmp(ldest, lorig, olen) == 0) && (ldest[olen] == '/')) { - ShowPrompt(false, "%s\nError: Destination is part of origin", deststr); + ShowPrompt(false, "%s\n%s", deststr, STR_ERROR_DESTINATION_IS_PART_OF_ORIGIN); return false; } @@ -633,7 +634,7 @@ bool PathMoveCopy(const char* dest, const char* orig, u32* flags, bool move) { // check & fix destination == origin while (strncasecmp(ldest, lorig, 255) == 0) { - if (!ShowKeyboardOrPrompt(dname, 255 - (dname - ldest), "%s\nDestination equals origin\nChoose another name?", deststr)) + if (!ShowKeyboardOrPrompt(dname, 255 - (dname - ldest), "%s\n%s", deststr, STR_ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME)) return false; } @@ -644,12 +645,11 @@ bool PathMoveCopy(const char* dest, const char* orig, u32* flags, bool move) { return true; } const char* optionstr[5] = - {"Choose new name", "Overwrite file(s)", "Skip file(s)", "Overwrite all", "Skip all"}; - u32 user_select = ShowSelectPrompt((*flags & ASK_ALL) ? 5 : 3, optionstr, - "Destination already exists:\n%s", deststr); + {STR_CHOOSE_NEW_NAME, STR_OVERWRITE_FILES, STR_SKIP_FILES, STR_OVERWRITE_ALL, STR_SKIP_ALL}; + u32 user_select = ShowSelectPrompt((*flags & ASK_ALL) ? 5 : 3, optionstr, STR_DESTINATION_ALREADY_EXISTS, deststr); if (user_select == 1) { do { - if (!ShowKeyboardOrPrompt(dname, 255 - (dname - ldest), "Choose new destination name")) + if (!ShowKeyboardOrPrompt(dname, 255 - (dname - ldest), "%s", STR_CHOOSE_NEW_DESTINATION_NAME)) return false; } while (fa_stat(ldest, NULL) == FR_OK); } else if (user_select == 2) { @@ -673,7 +673,7 @@ bool PathMoveCopy(const char* dest, const char* orig, u32* flags, bool move) { // setup buffer u8* buffer = (u8*) malloc(STD_BUFFER_SIZE); if (!buffer) { - ShowPrompt(false, "Out of memory."); + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); return false; } @@ -699,20 +699,20 @@ bool PathMoveCopy(const char* dest, const char* orig, u32* flags, bool move) { // prevent illegal operations if (force_unmount && (odrvtype & ddrvtype & (DRV_SYSNAND|DRV_EMUNAND|DRV_IMAGE))) { - ShowPrompt(false, "Copy operation is not allowed"); + ShowPrompt(false, "%s", STR_COPY_OPERATION_IS_NOT_ALLOWED); return false; } // check destination == origin if (strncasecmp(ldest, lorig, 255) == 0) { - ShowPrompt(false, "%s\nDestination equals origin", deststr); + ShowPrompt(false, "%s\n%s", deststr, STR_DESTINATION_EQUALS_ORIGIN); return false; } // setup buffer u8* buffer = (u8*) malloc(STD_BUFFER_SIZE); if (!buffer) { - ShowPrompt(false, "Out of memory."); + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); return false; } @@ -731,7 +731,7 @@ bool PathCopy(const char* destdir, const char* orig, u32* flags) { char dest[256]; // maximum path name length in FAT char* oname = strrchr(orig, '/'); if (oname == NULL) return false; // not a proper origin path - snprintf(dest, 255, "%s/%s", destdir, (++oname)); + snprintf(dest, sizeof(dest), "%s/%s", destdir, (++oname)); // virtual destination special handling if (GetVirtualSource(destdir) & ~VRT_BDRI) { @@ -745,9 +745,9 @@ bool PathCopy(const char* destdir, const char* orig, u32* flags) { if (!ReadVirtualDir(&dvfile, &vdir)) return false; if (dvfile.size == osize) break; // file found } - if (!ShowPrompt(true, "Entry not found: %s\nInject into %s instead?", dest, dvfile.name)) + if (!ShowPrompt(true, STR_ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD, dest, dvfile.name)) return false; - snprintf(dest, 255, "%s/%s", destdir, dvfile.name); + snprintf(dest, sizeof(dest), "%s/%s", destdir, dvfile.name); } else if (osize < dvfile.size) { // if origin is smaller than destination... char deststr[UTF_BUFFER_BYTESIZE(36)]; char origstr[UTF_BUFFER_BYTESIZE(36)]; @@ -758,7 +758,7 @@ bool PathCopy(const char* destdir, const char* orig, u32* flags) { FormatBytes(osizestr, osize); FormatBytes(dsizestr, dvfile.size); if (dvfile.size > osize) { - if (!ShowPrompt(true, "File smaller than available space:\n%s (%s)\n%s (%s)\nContinue?", origstr, osizestr, deststr, dsizestr)) + if (!ShowPrompt(true, STR_FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE, origstr, osizestr, deststr, dsizestr)) return false; } } @@ -772,7 +772,7 @@ bool PathMove(const char* destdir, const char* orig, u32* flags) { char dest[256]; // maximum path name length in FAT char* oname = strrchr(orig, '/'); if (oname == NULL) return false; // not a proper origin path - snprintf(dest, 255, "%s/%s", destdir, (++oname)); + snprintf(dest, sizeof(dest), "%s/%s", destdir, (++oname)); return PathMoveCopy(dest, orig, flags, true); } @@ -832,13 +832,13 @@ bool FileSelectorWorker(char* result, const char* text, const char* path, const (entry->type == T_DOTDOT) || (strncmp(entry->name, "._", 2) == 0)) continue; if (!new_style && n_opt == _MAX_FS_OPT) { - snprintf(opt_names[n_opt++], 32, "[more...]"); + snprintf(opt_names[n_opt++], 32, "%s", STR_BRACKET_MORE); break; } if (!new_style) { char temp_str[256]; - snprintf(temp_str, 256, "%s", entry->name); + snprintf(temp_str, sizeof(temp_str), "%s", entry->name); if (hide_ext && (entry->type == T_FILE)) { char* dot = strrchr(temp_str, '.'); if (dot) *dot = '\0'; @@ -849,7 +849,7 @@ bool FileSelectorWorker(char* result, const char* text, const char* path, const n_found++; } if ((pos >= contents->n_entries) && (n_opt < n_found) && !new_style) - snprintf(opt_names[n_opt++], 32, "[more...]"); + snprintf(opt_names[n_opt++], 32, "%s", STR_BRACKET_MORE); if (!n_opt) break; const char* optionstr[_MAX_FS_OPT+1] = { NULL }; @@ -874,7 +874,7 @@ bool FileSelectorWorker(char* result, const char* text, const char* path, const if (!n_found) { // not a single matching entry found char pathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(pathstr, path_local, 32, 8); - ShowPrompt(false, "%s\nNo usable entries found.", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_NO_USABLE_ENTRIES_FOUND); return false; } } diff --git a/arm9/source/filesys/sddata.c b/arm9/source/filesys/sddata.c index 1148cf234..cec19cf43 100644 --- a/arm9/source/filesys/sddata.c +++ b/arm9/source/filesys/sddata.c @@ -276,7 +276,7 @@ bool SetupNandSdDrive(const char* path, const char* sd_path, const char* movable // build the alias path (id0) u32 sha256sum[8]; sha_quick(sha256sum, sd_keyy[num], 0x10, SHA256_MODE); - snprintf(alias, 127, "%s/Nintendo 3DS/%08lX%08lX%08lX%08lX", + snprintf(alias, sizeof(alias), "%s/Nintendo 3DS/%08lX%08lX%08lX%08lX", sd_path, sha256sum[0], sha256sum[1], sha256sum[2], sha256sum[3]); // find the alias path (id1) diff --git a/arm9/source/filesys/support.c b/arm9/source/filesys/support.c index 0f261d471..474237bbd 100644 --- a/arm9/source/filesys/support.c +++ b/arm9/source/filesys/support.c @@ -17,7 +17,7 @@ bool CheckSupportFile(const char* fname) const char* base_paths[] = { SUPPORT_FILE_PATHS }; for (u32 i = 0; i < countof(base_paths); i++) { char path[256]; - snprintf(path, 256, "%s/%s", base_paths[i], fname); + snprintf(path, sizeof(path), "%s/%s", base_paths[i], fname); if (fvx_stat(path, NULL) == FR_OK) return true; } @@ -40,7 +40,7 @@ size_t LoadSupportFile(const char* fname, void* buffer, size_t max_len) for (u32 i = 0; i < countof(base_paths); i++) { UINT len32; char path[256]; - snprintf(path, 256, "%s/%s", base_paths[i], fname); + snprintf(path, sizeof(path), "%s/%s", base_paths[i], fname); if (fvx_qread(path, buffer, 0, max_len, &len32) == FR_OK) return len32; } @@ -68,7 +68,7 @@ bool SaveSupportFile(const char* fname, void* buffer, size_t len) // write support file if (idx >= 0) { char path[256]; - snprintf(path, 256, "%s/%s", base_paths[idx], fname); + snprintf(path, sizeof(path), "%s/%s", base_paths[idx], fname); fvx_unlink(path); if (fvx_qwrite(path, buffer, 0, len, NULL) == FR_OK) return true; diff --git a/arm9/source/filesys/support.h b/arm9/source/filesys/support.h index 1146157b6..b750323dd 100644 --- a/arm9/source/filesys/support.h +++ b/arm9/source/filesys/support.h @@ -3,6 +3,7 @@ #include "common.h" // scripts / payloads dir names +#define LANGUAGES_DIR "languages" #define SCRIPTS_DIR "scripts" #define PAYLOADS_DIR "payloads" @@ -11,5 +12,6 @@ size_t LoadSupportFile(const char* fname, void* buffer, size_t max_len); bool SaveSupportFile(const char* fname, void* buffer, size_t len); bool SetAsSupportFile(const char* fname, const char* source); +bool GetSupportDir(char* path, const char* dname); bool CheckSupportDir(const char* fpath); bool FileSelectorSupport(char* result, const char* text, const char* dname, const char* pattern); diff --git a/arm9/source/game/bps.c b/arm9/source/game/bps.c index 4adf8eddf..3ad98530d 100644 --- a/arm9/source/game/bps.c +++ b/arm9/source/game/bps.c @@ -18,6 +18,7 @@ #include +#include "language.h" #include "common.h" #include "timer.h" #include "crc32.h" @@ -143,18 +144,18 @@ static bool BEAT_UpdateProgress(const BEAT_Context *ctx) static const char *BEAT_ErrString(int error) { // Get an error description string switch(error) { - case BEAT_OK: return "No error"; - case BEAT_EOAL: return "End of action list"; - case BEAT_ABORTED: return "Aborted by user"; - case BEAT_IO_ERROR: return "Failed to read/write file"; - case BEAT_OVERFLOW: return "Attempted to write beyond end of file"; - case BEAT_BADPATCH: return "Invalid patch file"; - case BEAT_BADINPUT: return "Invalid input file"; - case BEAT_BADOUTPUT: return "Output file checksum mismatch"; - case BEAT_BADCHKSUM: return "File checksum failed"; - case BEAT_PATCH_EXPECT: return "Expected more patch data"; - case BEAT_OUT_OF_MEMORY: return "Out of memory"; - default: return "Unknown error"; + case BEAT_OK: return STR_BEAT_NO_ERROR; + case BEAT_EOAL: return STR_BEAT_END_OF_ACTION_LIST; + case BEAT_ABORTED: return STR_BEAT_ABORTED_BY_USER; + case BEAT_IO_ERROR: return STR_BEAT_FAILED_TO_READ_WRITE_FILE; + case BEAT_OVERFLOW: return STR_BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF; + case BEAT_BADPATCH: return STR_BEAT_INVALID_PATCH_FILE; + case BEAT_BADINPUT: return STR_BEAT_INVALID_INPUT_FILE; + case BEAT_BADOUTPUT: return STR_BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH; + case BEAT_BADCHKSUM: return STR_BEAT_FILE_CHECKSUM_FAILED; + case BEAT_PATCH_EXPECT: return STR_BEAT_EXPECTED_MORE_PATCH_DATA; + case BEAT_OUT_OF_MEMORY: return STR_BEAT_OUT_OF_MEMORY; + default: return STR_BEAT_UNKNOWN_ERROR; } } @@ -221,7 +222,7 @@ static s32 BEAT_DecodeSigned(u32 val) // Extract the signed number static int BEAT_RunActions(BEAT_Context *ctx, const BEAT_Action *acts) { // Parses an action list and runs commands specified in `acts` u32 vli, len; - int cmd, res; + int cmd, res = BEAT_OK; while((res == BEAT_OK) && (ctx->foff[BEAT_PF] < (BEAT_RANGE(ctx, BEAT_PF) - ctx->eoal_offset))) { @@ -660,19 +661,18 @@ static int BEAT_Run(const char *p, const char *s, const char *d, bool bpm) progress_timer = timer_start(); res = (bpm ? BPM_InitCTX : BPS_InitCTX)(&ctx, p, s, d); if (res != BEAT_OK) { - ShowPrompt(false, "Failed to initialize %s file:\n%s", - bpm ? "BPM" : "BPS", BEAT_ErrString(res)); + ShowPrompt(false, bpm ? STR_FAILED_TO_INITIALIZE_BPM_FILE : STR_FAILED_TO_INITIALIZE_BPS_FILE, BEAT_ErrString(res)); } else { res = (bpm ? BPM_RunActions : BPS_RunActions)(&ctx); switch(res) { case BEAT_OK: - ShowPrompt(false, "Patch successfully applied"); + ShowPrompt(false, "%s", STR_PATCH_SUCCESSFULLY_APPLIED); break; case BEAT_ABORTED: - ShowPrompt(false, "Patching aborted by user"); + ShowPrompt(false, "%s", STR_PATCHING_ABORTED_BY_USER); break; default: - ShowPrompt(false, "Failed to run patch:\n%s", BEAT_ErrString(res)); + ShowPrompt(false, STR_FAILED_TO_RUN_PATCH, BEAT_ErrString(res)); break; } } diff --git a/arm9/source/game/codelzss.c b/arm9/source/game/codelzss.c index d740547fa..a75ca9571 100644 --- a/arm9/source/game/codelzss.c +++ b/arm9/source/game/codelzss.c @@ -1,4 +1,5 @@ #include "codelzss.h" +#include "language.h" #include "ui.h" #define CODE_COMP_SIZE(f) ((f)->off_size_comp & 0xFFFFFF) @@ -45,10 +46,10 @@ u32 DecompressCodeLzss(u8* code, u32* code_size, u32 max_size) { // main decompression loop while ((ptr_in > comp_start) && (ptr_out > comp_start)) { - if (!ShowProgress(data_end - ptr_out, data_end - data_start, "Decompressing .code...")) { - if (ShowPrompt(true, "Decompressing .code...\nB button detected. Cancel?")) return 1; - ShowProgress(0, data_end - data_start, "Decompressing .code..."); - ShowProgress(data_end - ptr_out, data_end - data_start, "Decompressing .code..."); + if (!ShowProgress(data_end - ptr_out, data_end - data_start, STR_DECOMPRESSING_DOT_CODE)) { + if (ShowPrompt(true, "%s", STR_DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL)) return 1; + ShowProgress(0, data_end - data_start, STR_DECOMPRESSING_DOT_CODE); + ShowProgress(data_end - ptr_out, data_end - data_start, STR_DECOMPRESSING_DOT_CODE); } // sanity check @@ -242,13 +243,13 @@ bool CompressCodeLzss(const u8* a_pUncompressed, u32 a_uUncompressedSize, u8* a_ u8* pDest = a_pCompressed + a_uUncompressedSize; while (pSrc - a_pUncompressed > 0 && pDest - a_pCompressed > 0) { - if (!ShowProgress((u32)(a_pUncompressed + a_uUncompressedSize - pSrc), a_uUncompressedSize, "Compressing .code...")) { - if (ShowPrompt(true, "Compressing .code...\nB button detected. Cancel?")) { + if (!ShowProgress((u32)(a_pUncompressed + a_uUncompressedSize - pSrc), a_uUncompressedSize, STR_COMPRESSING_DOT_CODE)) { + if (ShowPrompt(true, "%s", STR_COMPRESSING_DOT_CODE_B_DETECTED_CANCEL)) { bResult = false; break; } - ShowProgress(0, a_uUncompressedSize, "Compressing .code..."); - ShowProgress((u32)(a_pUncompressed + a_uUncompressedSize - pSrc), a_uUncompressedSize, "Compressing .code..."); + ShowProgress(0, a_uUncompressedSize, STR_COMPRESSING_DOT_CODE); + ShowProgress((u32)(a_pUncompressed + a_uUncompressedSize - pSrc), a_uUncompressedSize, STR_COMPRESSING_DOT_CODE); } u8* pFlag = --pDest; diff --git a/arm9/source/game/firm.c b/arm9/source/game/firm.c index f9f750992..c30468124 100644 --- a/arm9/source/game/firm.c +++ b/arm9/source/game/firm.c @@ -12,18 +12,19 @@ // valid addresses for FIRM section loading // pairs of start / end address, provided by Wolfvak #define FIRM_VALID_ADDRESS \ - 0x08000040, 0x08100000, \ 0x18000000, 0x18600000, \ 0x1FF00000, 0x1FFFFC00 // valid addresses (installable) for FIRM section loading #define FIRM_VALID_ADDRESS_INSTALL \ FIRM_VALID_ADDRESS, \ + 0x08000040, 0x080F7FFF, \ 0x10000000, 0x10200000 // valid addresses (bootable) for FIRM section loading #define FIRM_VALID_ADDRESS_BOOT \ FIRM_VALID_ADDRESS, \ + 0x08000040, 0x08100000, \ 0x20000000, 0x27FFFA00 static const u32 whitelist_boot[] = { FIRM_VALID_ADDRESS_BOOT }; diff --git a/arm9/source/game/gba.c b/arm9/source/game/gba.c index 65a8fb0c0..26eb98c2c 100644 --- a/arm9/source/game/gba.c +++ b/arm9/source/game/gba.c @@ -87,3 +87,17 @@ u32 ValidateAgbHeader(AgbHeader* agb) { return 0; } */ + +// see: http://problemkaputt.de/gbatek.htm#gbacartridgeheader +const char* AgbDestStr(const char* code) { + switch(code[3]) { + case 'J': return STR_REGION_JAPAN; + case 'E': return STR_REGION_AMERICAS; + case 'P': return STR_REGION_EUROPE; + case 'D': return STR_REGION_GERMANY; + case 'F': return STR_REGION_FRANCE; + case 'I': return STR_REGION_ITALY; + case 'S': return STR_REGION_SPAIN; + default: return STR_REGION_UNKNOWN; + } +} diff --git a/arm9/source/game/gba.h b/arm9/source/game/gba.h index 967b24720..7b3613389 100644 --- a/arm9/source/game/gba.h +++ b/arm9/source/game/gba.h @@ -1,6 +1,7 @@ #pragma once #include "common.h" +#include "language.h" #define GBAVC_MAGIC '.', 'C', 'A', 'A' #define AGBSAVE_MAGIC '.', 'S', 'A', 'V' @@ -28,16 +29,6 @@ ((size) == GBASAVE_FLASH_64K) || \ ((size) == GBASAVE_FLASH_128K)) -// see: http://problemkaputt.de/gbatek.htm#gbacartridgeheader -#define AGB_DESTSTR(code) \ - (((code)[3] == 'J') ? "Japan" : \ - ((code)[3] == 'E') ? "USA/English" : \ - ((code)[3] == 'P') ? "Europe/Elsewhere" : \ - ((code)[3] == 'D') ? "German" : \ - ((code)[3] == 'F') ? "French" : \ - ((code)[3] == 'I') ? "Italian" : \ - ((code)[3] == 'S') ? "Spanish" : "Unknown") - // see: http://3dbrew.org/wiki/3DS_Virtual_Console#Footer // still a lot of unknowns in here, also redundant stuff left out @@ -89,5 +80,8 @@ typedef struct { } __attribute__((packed, aligned(16))) AgbHeader; + u32 ValidateAgbSaveHeader(AgbSaveHeader* header); u32 ValidateAgbHeader(AgbHeader* agb); + +const char* AgbDestStr(const char* code); diff --git a/arm9/source/game/ips.c b/arm9/source/game/ips.c index 76cef60b7..a8f66f6c1 100644 --- a/arm9/source/game/ips.c +++ b/arm9/source/game/ips.c @@ -5,6 +5,7 @@ #include "ips.h" #include "common.h" #include "fsperm.h" +#include "language.h" #include "ui.h" #include "vff.h" @@ -30,21 +31,21 @@ char errName[256]; int displayError(int errcode) { switch(errcode) { case IPS_NOTTHIS: - ShowPrompt(false, "%s\nThe patch is most likely not intended for this file.", errName); break; + ShowPrompt(false, "%s\n%s", errName, STR_PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE); break; case IPS_THISOUT: - ShowPrompt(false, "%s\nYou most likely applied the patch on the output file.", errName); break; + ShowPrompt(false, "%s\n%s", errName, STR_YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT); break; case IPS_SCRAMBLED: - ShowPrompt(false, "%s\nThe patch is technically valid,\nbut seems scrambled or malformed.", errName); break; + ShowPrompt(false, "%s\n%s", errName, STR_PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED); break; case IPS_INVALID: - ShowPrompt(false, "%s\nThe patch is invalid.", errName); break; + ShowPrompt(false, "%s\n%s", errName, STR_PATCH_IS_INVALID); break; case IPS_16MB: - ShowPrompt(false, "%s\nOne or both files is bigger than 16MB.\nThe IPS format doesn't support that.", errName); break; + ShowPrompt(false, "%s\n%s", errName, STR_FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT); break; case IPS_INVALID_FILE_PATH: - ShowPrompt(false, "%s\nThe requested file path was invalid.", errName); break; + ShowPrompt(false, "%s\n%s", errName, STR_REQUESTED_FILE_PATH_WAS_INVALID); break; case IPS_CANCELED: - ShowPrompt(false, "%s\nPatching canceled.", errName); break; + ShowPrompt(false, "%s\n%s", errName, STR_PATCHING_CANCELED); break; case IPS_MEMORY: - ShowPrompt(false, "%s\nNot enough memory.", errName); break; + ShowPrompt(false, "%s\n%s", errName, STR_NOT_ENOUGH_MEMORY); break; } fvx_close(&patchFile); fvx_close(&inFile); @@ -112,7 +113,7 @@ UINT read24() { int ApplyIPSPatch(const char* patchName, const char* inName, const char* outName) { int error = IPS_INVALID; UINT outlen_min, outlen_max, outlen_min_mem; - snprintf(errName, 256, "%s", patchName); + snprintf(errName, sizeof(errName), "%s", patchName); if (fvx_open(&patchFile, patchName, FA_READ) != FR_OK) return displayError(IPS_INVALID_FILE_PATH); patchSize = fvx_size(&patchFile); @@ -140,7 +141,7 @@ int ApplyIPSPatch(const char* patchName, const char* inName, const char* outName while (offset != 0x454F46) // 454F46=EOF { if (!ShowProgress(patchOffset, patchSize, patchName)) { - if (ShowPrompt(true, "%s\nB button detected. Cancel?", patchName)) return displayError(IPS_CANCELED); + if (ShowPrompt(true, "%s\n%s", patchName, STR_B_DETECTED_CANCEL)) return displayError(IPS_CANCELED); ShowProgress(0, patchSize, patchName); ShowProgress(patchOffset, patchSize, patchName); } @@ -211,7 +212,7 @@ int ApplyIPSPatch(const char* patchName, const char* inName, const char* outName while (offset != 0x454F46) { if (!ShowProgress(offset, outSize, outName)) { - if (ShowPrompt(true, "%s\nB button detected. Cancel?", outName)) return displayError(IPS_CANCELED); + if (ShowPrompt(true, "%s\n%s", outName, STR_B_DETECTED_CANCEL)) return displayError(IPS_CANCELED); ShowProgress(0, outSize, outName); ShowProgress(offset, outSize, outName); } diff --git a/arm9/source/game/nds.c b/arm9/source/game/nds.c index 964842c45..75f181e3c 100644 --- a/arm9/source/game/nds.c +++ b/arm9/source/game/nds.c @@ -55,21 +55,25 @@ u32 BuildTwlSaveHeader(void* sav, u32 size) { u16 n_sct = 1; u16 sct_track = 1; u16 sct_heads = 1; - while (true) { - if (sct_heads < sct_track) { - u16 n_sct_next = sct_track * (sct_heads+1) * (sct_heads+1); - if (n_sct_next < n_sct_max) { - sct_heads++; + u16 n_sct_next = 0; + while (n_sct_next <= n_sct_max) { + n_sct_next = sct_track * (sct_heads + 1) * (sct_heads + 1); + if (n_sct_next <= n_sct_max) { + sct_heads++; + n_sct = n_sct_next; + + sct_track++; + n_sct_next = sct_track * sct_heads * sct_heads; + if (n_sct_next <= n_sct_max) { n_sct = n_sct_next; - } else break; - } else { - u16 n_sct_next = (sct_track+1) * sct_heads * sct_heads; - if (n_sct_next < n_sct_max) { - sct_track++; - n_sct = n_sct_next; - } else break; + } } } + n_sct_next = (sct_track + 1) * sct_heads * sct_heads; + if (n_sct_next <= n_sct_max) { + sct_track++; + n_sct = n_sct_next; + } // sectors per cluster (should be identical to Nintendo) u8 clr_size = (n_sct > 8 * 1024) ? 8 : (n_sct > 1024) ? 4 : 1; diff --git a/arm9/source/game/region.c b/arm9/source/game/region.c index a224d53a4..eb1a18441 100644 --- a/arm9/source/game/region.c +++ b/arm9/source/game/region.c @@ -1,4 +1,5 @@ #include "common.h" +#include "language.h" #include "region.h" // Names of system regions, short form. @@ -12,13 +13,16 @@ const char* const g_regionNamesShort[SMDH_NUM_REGIONS] = { "TWN", }; -// Names of system regions, long form. -const char* const g_regionNamesLong[SMDH_NUM_REGIONS] = { - "Japan", - "Americas", - "Europe", - "Australia", - "China", - "Korea", - "Taiwan", +// Names of system regions, long form and translatable. +const char* regionNameLong(int region) { + switch(region) { + case REGION_JPN: return STR_REGION_JAPAN; + case REGION_USA: return STR_REGION_AMERICAS; + case REGION_EUR: return STR_REGION_EUROPE; + case REGION_AUS: return STR_REGION_AUSTRALIA; + case REGION_CHN: return STR_REGION_CHINA; + case REGION_KOR: return STR_REGION_KOREA; + case REGION_TWN: return STR_REGION_TAIWAN; + default: return STR_REGION_UNKNOWN; + } }; diff --git a/arm9/source/game/region.h b/arm9/source/game/region.h index 20c2cb8d1..b3f8830a7 100644 --- a/arm9/source/game/region.h +++ b/arm9/source/game/region.h @@ -27,5 +27,5 @@ // Names of system regions, short form. extern const char* const g_regionNamesShort[SMDH_NUM_REGIONS]; -// Names of system regions, long form. -extern const char* const g_regionNamesLong[SMDH_NUM_REGIONS]; +// Names of system regions, long form and translatable. +const char* regionNameLong(int region); diff --git a/arm9/source/game/ticket.c b/arm9/source/game/ticket.c index 24005cd48..d5cdb13ad 100644 --- a/arm9/source/game/ticket.c +++ b/arm9/source/game/ticket.c @@ -120,7 +120,7 @@ u32 BuildVariableFakeTicket(Ticket** ticket, u32* ticket_size, const u8* title_i } u32 BuildFakeTicket(Ticket* ticket, const u8* title_id) { - Ticket* tik; + Ticket* tik = NULL; u32 ticket_size = sizeof(TicketCommon); u32 res = BuildVariableFakeTicket(&tik, &ticket_size, title_id, TICKET_MAX_CONTENTS); if (res != 0) return res; diff --git a/arm9/source/gamecart/command_ctr.c b/arm9/source/gamecart/command_ctr.c index 49c882984..3e2f8e2d7 100644 --- a/arm9/source/gamecart/command_ctr.c +++ b/arm9/source/gamecart/command_ctr.c @@ -27,7 +27,7 @@ void CTR_CmdReadData(u32 sector, u32 length, u32 blocks, void* buffer) (u32)((sector << 9) & 0xFFFFFFFF), 0x00000000, 0x00000000 }; - CTR_SendCommand(read_cmd, length, blocks, 0x704822C, buffer); + CTR_SendCommand(read_cmd, length, blocks, 0x104822C, buffer); // Clock divider 5 (13.4 MHz). Same as Process9. } void CTR_CmdReadHeader(void* buffer) diff --git a/arm9/source/gamecart/gamecart.c b/arm9/source/gamecart/gamecart.c index 7bd2d5006..0ca8077ac 100644 --- a/arm9/source/gamecart/gamecart.c +++ b/arm9/source/gamecart/gamecart.c @@ -64,6 +64,11 @@ u32 GetCartName(char* name, CartData* cdata) { u32 GetCartInfoString(char* info, size_t info_size, CartData* cdata) { size_t info_index = 0; + u8 padding; + + // read the last byte of the cart storage, but ignore the result + ReadCartBytes(&padding, cdata->cart_size - 1, 1, cdata, false); + if (cdata->cart_type & CART_CTR) { CartDataCtr* cdata_i = (CartDataCtr*)cdata; NcsdHeader* ncsd = &(cdata_i->ncsd); @@ -107,8 +112,10 @@ u32 GetCartInfoString(char* info, size_t info_size, CartData* cdata) { "Save chip ID : \n"); info_index += snprintf(info + info_index, info_size - info_index, + "Padding Byte : %02X\n" "Timestamp : 20%02X-%02X-%02X %02X:%02X:%02X\n" "GM9 Version : %s\n", + padding, init_time.bcd_Y, init_time.bcd_M, init_time.bcd_D, init_time.bcd_h, init_time.bcd_m, init_time.bcd_s, VERSION); @@ -247,7 +254,7 @@ u32 InitCartRead(CartData* cdata) { if (nds_header->device_capacity >= 15) return 1; // too big, not valid if (cdata->cart_size == 0) cdata->cart_size = (128 * 1024) << nds_header->device_capacity; - cdata->data_size = nds_header->ntr_rom_size + 0x88; + cdata->data_size = nds_header->ntr_rom_size; cdata->arm9i_rom_offset = 0; // TWL header @@ -266,6 +273,15 @@ u32 InitCartRead(CartData* cdata) { NTR_CmdReadHeader(cdata->storage); if (!NTR_Secure_Init(cdata->storage, NULL, Cart_GetID(), 1)) return 1; } + } else { + // Check if immediately after the reported cart size + // is the magic number string 'ac' (auth code). + // If found, add 0x88 bytes for the download play RSA key. + u16 rsaMagic; + ReadCartBytes(&rsaMagic, cdata->data_size, 2, cdata, false); + if(rsaMagic == 0x6361) { + cdata->data_size += 0x88; + } } // store encrypted secure area diff --git a/arm9/source/godmode.c b/arm9/source/godmode.c index 256d4d10c..855e98c43 100644 --- a/arm9/source/godmode.c +++ b/arm9/source/godmode.c @@ -25,6 +25,7 @@ #include "vram0.h" #include "i2c.h" #include "pxi.h" +#include "language.h" #ifndef N_PANES #define N_PANES 3 @@ -58,19 +59,18 @@ u32 BootFirmHandler(const char* bootpath, bool verbose, bool delete) { size_t firm_size = FileGetSize(bootpath); if (!firm_size) return 1; if (firm_size > FIRM_MAX_SIZE) { - if (verbose) ShowPrompt(false, "%s\nFIRM too big, can't boot", pathstr); // unlikely + if (verbose) ShowPrompt(false, "%s\n%s", pathstr, STR_FIRM_TOO_BIG); // unlikely return 1; } - if (verbose && !ShowPrompt(true, "%s (%dkB)\nWarning: Do not boot FIRMs\nfrom untrusted sources.\n \nBoot FIRM?", - pathstr, firm_size / 1024)) + if (verbose && !ShowPrompt(true, STR_PATH_DO_NOT_BOOT_UNTRUSTED, pathstr, firm_size / 1024)) return 1; void* firm = (void*) malloc(FIRM_MAX_SIZE); if (!firm) return 1; if ((FileGetData(bootpath, firm, firm_size, 0) != firm_size) || !IsBootableFirm(firm, firm_size)) { - if (verbose) ShowPrompt(false, "%s\nNot a bootable FIRM.", pathstr); + if (verbose) ShowPrompt(false, "%s\n%s", pathstr, STR_NOT_BOOTABLE_FIRM); free(firm); return 1; } @@ -81,7 +81,7 @@ u32 BootFirmHandler(const char* bootpath, bool verbose, bool delete) { FirmA9LHeader* a9l = (FirmA9LHeader*)(void*) ((u8*) firm + arm9s->offset); if (verbose && (ValidateFirmA9LHeader(a9l) == 0) && - ShowPrompt(true, "%s\nFIRM is encrypted.\n \nDecrypt before boot?", pathstr) && + ShowPrompt(true, "%s\n%s", pathstr, STR_FIRM_ENCRYPTED) && (DecryptFirmFull(firm, firm_size) != 0)) { free(firm); return 1; @@ -90,8 +90,10 @@ u32 BootFirmHandler(const char* bootpath, bool verbose, bool delete) { // unsupported location handling char fixpath[256] = { 0 }; if (verbose && (*bootpath != '0') && (*bootpath != '1')) { - const char* optionstr[2] = { "Make a copy at " OUTPUT_PATH "/temp.firm", "Try to boot anyways" }; - u32 user_select = ShowSelectPrompt(2, optionstr, "%s\nWarning: Trying to boot from an\nunsupported location.", pathstr); + char str[UTF_BUFFER_BYTESIZE(256)]; + snprintf(str, sizeof(str), STR_MAKE_COPY_AT_OUT_TEMP_FIRM, OUTPUT_PATH); + const char* optionstr[2] = { str, STR_TRY_BOOT_ANYWAYS }; + u32 user_select = ShowSelectPrompt(2, optionstr, "%s\n%s", pathstr, STR_WARNING_BOOT_UNSUPPORTED_LOCATION); if (user_select == 1) { FileSetData(OUTPUT_PATH "/temp.firm", firm, firm_size, 0, true); bootpath = OUTPUT_PATH "/temp.firm"; @@ -100,7 +102,7 @@ u32 BootFirmHandler(const char* bootpath, bool verbose, bool delete) { // fix the boot path ("sdmc"/"nand" for Luma et al, hacky af) if ((*bootpath == '0') || (*bootpath == '1')) - snprintf(fixpath, 256, "%s%s", (*bootpath == '0') ? "sdmc" : "nand", bootpath + 1); + snprintf(fixpath, sizeof(fixpath), "%s%s", (*bootpath == '0') ? "sdmc" : "nand", bootpath + 1); else strncpy(fixpath, bootpath, 256); fixpath[255] = '\0'; @@ -144,14 +146,14 @@ u32 SplashInit(const char* modestr) { } if (modestr) DrawStringF(TOP_SCREEN, SCREEN_WIDTH_TOP - 10 - GetDrawStringWidth(modestr), - SCREEN_HEIGHT - 10 - GetDrawStringHeight(modestr), COLOR_STD_FONT, COLOR_TRANSPARENT, modestr); + SCREEN_HEIGHT - 10 - GetDrawStringHeight(modestr), COLOR_STD_FONT, COLOR_TRANSPARENT, "%s", modestr); DrawStringF(BOT_SCREEN, pos_xb, pos_yb, COLOR_STD_FONT, COLOR_STD_BG, "%s\n%*.*s\n%s\n \n \n%s\n%s\n \n%s\n%s", - namestr, strnlen(namestr, 64), strnlen(namestr, 64), + namestr, strlen(namestr), strlen(namestr), "--------------------------------", "https://github.com/d0k3/GodMode9", "Releases:", "https://github.com/d0k3/GodMode9/releases/", // this won't fit with a 8px width font "Hourlies:", "https://d0k3.secretalgorithm.com/"); - DrawStringF(BOT_SCREEN, pos_xu, pos_yu, COLOR_STD_FONT, COLOR_STD_BG, loadstr); + DrawStringF(BOT_SCREEN, pos_xu, pos_yu, COLOR_STD_FONT, COLOR_STD_BG, "%s", loadstr); DrawStringF(BOT_SCREEN, pos_xb, pos_yu, COLOR_STD_FONT, COLOR_STD_BG, "built: " DBUILTL); return 0; @@ -162,14 +164,14 @@ static DirStruct* current_dir = NULL; static DirStruct* clipboard = NULL; static PaneData* panedata = NULL; -void GetTimeString(char* timestr, bool forced_update, bool full_year) { +void GetTimeString(char* timestr, bool forced_update, bool full_year) { // timestr should be 32 bytes static DsTime dstime; static u64 timer = (u64) -1; // this ensures we don't check the time too often if (forced_update || (timer == (u64) -1) || (timer_sec(timer) > 30)) { get_dstime(&dstime); timer = timer_start(); } - if (timestr) snprintf(timestr, 31, "%s%02lX-%02lX-%02lX %02lX:%02lX", full_year ? "20" : "", + if (timestr) snprintf(timestr, UTF_BUFFER_BYTESIZE(32), STR_DATE_TIME_FORMAT, full_year ? "20" : "", (u32) dstime.bcd_Y, (u32) dstime.bcd_M, (u32) dstime.bcd_D, (u32) dstime.bcd_h, (u32) dstime.bcd_m); } @@ -237,7 +239,7 @@ void DrawTopBar(const char* curr_path) { // top bar - current path DrawRectangle(TOP_SCREEN, 0, 0, SCREEN_WIDTH_TOP, 12, COLOR_TOP_BAR); if (*curr_path) TruncateString(tempstr, curr_path, min(63, len_path / FONT_WIDTH_EXT), 8); - else snprintf(tempstr, 16, "[root]"); + else snprintf(tempstr, sizeof(tempstr), "%s", STR_ROOT); DrawStringF(TOP_SCREEN, bartxt_x, bartxt_start, COLOR_STD_BG, COLOR_TOP_BAR, "%s", tempstr); bool show_time = true; @@ -246,10 +248,12 @@ void DrawTopBar(const char* curr_path) { const u32 bartxt_rx = SCREEN_WIDTH_TOP - (19*FONT_WIDTH_EXT) - bartxt_x; char bytestr0[32]; char bytestr1[32]; - DrawStringF(TOP_SCREEN, bartxt_rx, bartxt_start, COLOR_STD_BG, COLOR_TOP_BAR, "%19.19s", "LOADING..."); + char tempstr[UTF_BUFFER_BYTESIZE(19)]; + ResizeString(tempstr, STR_LOADING, 19, 19, true); + DrawString(TOP_SCREEN, tempstr, bartxt_rx, bartxt_start, COLOR_STD_BG, COLOR_TOP_BAR); FormatBytes(bytestr0, GetFreeSpace(curr_path)); FormatBytes(bytestr1, GetTotalSpace(curr_path)); - snprintf(tempstr, 64, "%s/%s", bytestr0, bytestr1); + snprintf(tempstr, sizeof(tempstr), "%s/%s", bytestr0, bytestr1); DrawStringF(TOP_SCREEN, bartxt_rx, bartxt_start, COLOR_STD_BG, COLOR_TOP_BAR, "%19.19s", tempstr); show_time = false; } @@ -264,15 +268,16 @@ void DrawTopBar(const char* curr_path) { #endif if (show_time) { // clock & battery + char timestr[UTF_BUFFER_BYTESIZE(32)]; + GetTimeString(timestr, false, false); + const u32 battery_width = 16; const u32 battery_height = 9; const u32 battery_x = SCREEN_WIDTH_TOP - battery_width - bartxt_x; const u32 battery_y = (12 - battery_height) / 2; - const u32 clock_x = battery_x - (15*FONT_WIDTH_EXT); + const u32 clock_x = battery_x - (GetDrawStringWidth(timestr) + FONT_WIDTH_EXT); - char timestr[32]; - GetTimeString(timestr, false, false); - DrawStringF(TOP_SCREEN, clock_x, bartxt_start, COLOR_STD_BG, COLOR_TOP_BAR, "%14.14s", timestr); + DrawStringF(TOP_SCREEN, clock_x, bartxt_start, COLOR_STD_BG, COLOR_TOP_BAR, "%s", timestr); DrawBatteryBitmap(TOP_SCREEN, battery_x, battery_y, battery_width, battery_height); } } @@ -300,8 +305,8 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, u32 curr_pan } // left top - current file info - if (curr_pane) snprintf(tempstr, 63, "PANE #%lu", curr_pane); - else snprintf(tempstr, 63, "CURRENT"); + if (curr_pane) snprintf(tempstr, sizeof(tempstr), STR_PANE_N, curr_pane); + else snprintf(tempstr, sizeof(tempstr), "%s", STR_CURRENT); DrawStringF(MAIN_SCREEN, 2, info_start, COLOR_STD_FONT, COLOR_STD_BG, "[%s]", tempstr); // file / entry name ResizeString(tempstr, curr_entry->name, str_len_info, 8, false); @@ -309,28 +314,27 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, u32 curr_pan DrawStringF(MAIN_SCREEN, 4, info_start + 12, color_current, COLOR_STD_BG, "%s", tempstr); // size (in Byte) or type desc if (curr_entry->type == T_DIR) { - ResizeString(tempstr, "(dir)", str_len_info, 8, false); + ResizeString(tempstr, STR_DIR, str_len_info, 8, false); } else if (curr_entry->type == T_DOTDOT) { - snprintf(tempstr, 21, "%20s", ""); + snprintf(tempstr, sizeof(tempstr), "%20s", ""); } else if (curr_entry->type == T_ROOT) { int drvtype = DriveType(curr_entry->path); - char drvstr[32]; - snprintf(drvstr, 31, "(%s%s)", - ((drvtype & DRV_SDCARD) ? "SD" : (drvtype & DRV_RAMDRIVE) ? "RAMdrive" : (drvtype & DRV_GAME) ? "Game" : - (drvtype & DRV_SYSNAND) ? "SysNAND" : (drvtype & DRV_EMUNAND) ? "EmuNAND" : (drvtype & DRV_IMAGE) ? "Image" : - (drvtype & DRV_XORPAD) ? "XORpad" : (drvtype & DRV_MEMORY) ? "Memory" : (drvtype & DRV_ALIAS) ? "Alias" : - (drvtype & DRV_CART) ? "Gamecart" : (drvtype & DRV_VRAM) ? "VRAM" : (drvtype & DRV_SEARCH) ? "Search" : - (drvtype & DRV_TITLEMAN) ? "TitleManager" : ""), - ((drvtype & DRV_FAT) ? " FAT" : (drvtype & DRV_VIRTUAL) ? " Virtual" : "")); + const char* drvstr = + (drvtype & DRV_SDCARD) ? STR_SD_FAT : (drvtype & DRV_RAMDRIVE) ? STR_RAMDRIVE_FAT : (drvtype & DRV_GAME) ? STR_GAME_VIRTUAL : + (drvtype & (DRV_SYSNAND | DRV_FAT)) ? STR_SYSNAND_FAT : (drvtype & (DRV_SYSNAND | DRV_VIRTUAL)) ? STR_SYSNAND_VIRTUAL : + (drvtype & (DRV_EMUNAND | DRV_FAT)) ? STR_EMUNAND_FAT : (drvtype & (DRV_EMUNAND | DRV_VIRTUAL)) ? STR_EMUNAND_VIRTUAL : + (drvtype & DRV_IMAGE) ? STR_IMAGE_FAT : (drvtype & DRV_XORPAD) ? STR_XORPAD_VIRTUAL : (drvtype & DRV_MEMORY) ? STR_MEMORY_VIRTUAL : + (drvtype & DRV_ALIAS) ? STR_ALIAS_FAT : (drvtype & DRV_CART) ? STR_GAMECART_VIRTUAL : (drvtype & DRV_VRAM) ? STR_VRAM_VIRTUAL : + (drvtype & DRV_SEARCH) ? STR_SEARCH : (drvtype & DRV_TITLEMAN) ? STR_TITLEMANAGER_VIRTUAL : ""; ResizeString(tempstr, drvstr, str_len_info, 8, false); } else { - char numstr[32]; - char bytestr[32]; + char numstr[UTF_BUFFER_BYTESIZE(32)]; + char bytestr[UTF_BUFFER_BYTESIZE(32)]; FormatNumber(numstr, curr_entry->size); - snprintf(bytestr, 31, "%s Byte", numstr); + snprintf(bytestr, sizeof(bytestr), STR_N_BYTE, numstr); ResizeString(tempstr, bytestr, str_len_info, 8, false); } - DrawStringF(MAIN_SCREEN, 4, info_start + 12 + 10, color_current, COLOR_STD_BG, tempstr); + DrawStringF(MAIN_SCREEN, 4, info_start + 12 + 10, color_current, COLOR_STD_BG, "%s", tempstr); // path of file (if in search results) if ((DriveType(curr_path) & DRV_SEARCH) && strrchr(curr_entry->path, '/')) { char dirstr[256]; @@ -345,32 +349,31 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, u32 curr_pan // right top - clipboard DrawStringF(MAIN_SCREEN, SCREEN_WIDTH_MAIN - len_info, info_start, COLOR_STD_FONT, COLOR_STD_BG, "%*s", - len_info / FONT_WIDTH_EXT, (clipboard->n_entries) ? "[CLIPBOARD]" : ""); + (int) (len_info / FONT_WIDTH_EXT), (clipboard->n_entries) ? STR_CLIPBOARD : ""); for (u32 c = 0; c < n_cb_show; c++) { u32 color_cb = COLOR_ENTRY(&(clipboard->entry[c])); ResizeString(tempstr, (clipboard->n_entries > c) ? clipboard->entry[c].name : "", str_len_info, 8, true); DrawStringF(MAIN_SCREEN, SCREEN_WIDTH_MAIN - len_info - 4, info_start + 12 + (c*10), color_cb, COLOR_STD_BG, "%s", tempstr); } *tempstr = '\0'; - if (clipboard->n_entries > n_cb_show) snprintf(tempstr, 60, "+ %lu more", clipboard->n_entries - n_cb_show); + if (clipboard->n_entries > n_cb_show) snprintf(tempstr, sizeof(tempstr), STR_PLUS_N_MORE, clipboard->n_entries - n_cb_show); DrawStringF(MAIN_SCREEN, SCREEN_WIDTH_MAIN - len_info - 4, info_start + 12 + (n_cb_show*10), COLOR_DARKGREY, COLOR_STD_BG, - "%*s", len_info / FONT_WIDTH_EXT, tempstr); + "%*s", (int) (len_info / FONT_WIDTH_EXT), tempstr); // bottom: instruction block - char instr[512]; - snprintf(instr, 512, "%s\n%s%s%s%s%s%s%s%s", + char instr[UTF_BUFFER_BYTESIZE(512)]; + snprintf(instr, sizeof(instr), "%s\n%s%s%s%s%s%s%s%s", FLAVOR " " VERSION, // generic start part - (*curr_path) ? ((clipboard->n_entries == 0) ? "L - MARK files (use with ↑↓→←)\nX - DELETE / [+R] RENAME file(s)\nY - COPY files / [+R] CREATE entry\n" : - "L - MARK files (use with ↑↓→←)\nX - DELETE / [+R] RENAME file(s)\nY - PASTE files / [+R] CREATE entry\n") : - ((GetWritePermissions() > PERM_BASE) ? "R+Y - Relock write permissions\n" : ""), - (*curr_path) ? "" : (GetMountState()) ? "R+X - Unmount image\n" : "", - (*curr_path) ? "" : (CheckSDMountState()) ? "R+B - Unmount SD card\n" : "R+B - Remount SD card\n", - (*curr_path) ? "R+A - Directory options\n" : "R+A - Drive options\n", - "R+L - Make a Screenshot\n", - "R+←→ - Switch to prev/next pane\n", - (clipboard->n_entries) ? "SELECT - Clear Clipboard\n" : "SELECT - Restore Clipboard\n", // only if clipboard is full - "START - Reboot / [+R] Poweroff\nHOME button for HOME menu"); // generic end part - DrawStringF(MAIN_SCREEN, instr_x, SCREEN_HEIGHT - 4 - GetDrawStringHeight(instr), COLOR_STD_FONT, COLOR_STD_BG, instr); + (*curr_path) ? ((clipboard->n_entries == 0) ? STR_MARK_DELETE_COPY : STR_MARK_DELETE_PASTE) : + ((GetWritePermissions() > PERM_BASE) ? STR_RELOCK_WRITE_PERMISSION : ""), + (*curr_path) ? "" : (GetMountState()) ? STR_UNMOUNT_IMAGE : "", + (*curr_path) ? "" : (CheckSDMountState()) ? STR_UNMOUNT_SD : STR_REMOUNT_SD, + (*curr_path) ? STR_DIRECTORY_OPTIONS : STR_DRIVE_OPTIONS, + STR_MAKE_SCREENSHOT, + STR_PREV_NEXT_PANE, + (clipboard->n_entries) ? STR_CLEAR_CLIPBOARD : STR_RESTORE_CLIPBOARD, // only if clipboard is full + STR_REBOOT_POWEROFF_HOME); // generic end part + DrawStringF(MAIN_SCREEN, instr_x, SCREEN_HEIGHT - 4 - GetDrawStringHeight(instr), COLOR_STD_FONT, COLOR_STD_BG, "%s", instr); } void DrawDirContents(DirStruct* contents, u32 cursor, u32* scroll) { @@ -393,14 +396,14 @@ void DrawDirContents(DirStruct* contents, u32 cursor, u32* scroll) { if (offset_i < contents->n_entries) { DirEntry* curr_entry = &(contents->entry[offset_i]); char namestr[UTF_BUFFER_BYTESIZE(str_width - 10)]; - char bytestr[10 + 1]; + char rawbytestr[32], bytestr[UTF_BUFFER_BYTESIZE(10)]; color_font = (cursor != offset_i) ? COLOR_ENTRY(curr_entry) : COLOR_STD_FONT; - FormatBytes(bytestr, curr_entry->size); + FormatBytes(rawbytestr, curr_entry->size); + ResizeString(bytestr, (curr_entry->type == T_DIR) ? STR_DIR : (curr_entry->type == T_DOTDOT) ? "(..)" : rawbytestr, 10, 10, true); ResizeString(namestr, curr_entry->name, str_width - 10, str_width - 20, false); - snprintf(tempstr, str_width * 4 + 1, "%s%10.10s", namestr, - (curr_entry->type == T_DIR) ? "(dir)" : (curr_entry->type == T_DOTDOT) ? "(..)" : bytestr); - } else snprintf(tempstr, str_width + 1, "%-*.*s", str_width, str_width, ""); - DrawStringF(ALT_SCREEN, pos_x, pos_y, color_font, COLOR_STD_BG, "%s", tempstr); + snprintf(tempstr, sizeof(tempstr), "%s%s", namestr, bytestr); + } else snprintf(tempstr, sizeof(tempstr), "%-*.*s", str_width, str_width, ""); + DrawString(ALT_SCREEN, tempstr, pos_x, pos_y, color_font, COLOR_STD_BG); pos_y += stp_y; } @@ -420,9 +423,9 @@ void DrawDirContents(DirStruct* contents, u32 cursor, u32* scroll) { u32 SdFormatMenu(const char* slabel) { static const u32 cluster_size_table[5] = { 0x0, 0x0, 0x4000, 0x8000, 0x10000 }; - static const char* option_emunand_size[7] = { "No EmuNAND", "RedNAND size (min)", "GW EmuNAND size (full)", - "MultiNAND size (2x)", "MultiNAND size (3x)", "MultiNAND size (4x)", "User input..." }; - static const char* option_cluster_size[4] = { "Auto", "16KB Clusters", "32KB Clusters", "64KB Clusters" }; + const char* option_emunand_size[7] = { STR_NO_EMUNAND, STR_REDNAND_SIZE_MIN, STR_GW_EMUNAND_SIZE_FULL, + STR_MULTINAND_SIZE_2X, STR_MULTINAND_SIZE_3X, STR_MULTINAND_SIZE_4X, STR_USER_INPUT }; + const char* option_cluster_size[4] = { STR_AUTO, STR_16KB_CLUSTERS, STR_32KB_CLUSTERS, STR_64KB_CLUSTERS }; u32 sysnand_min_size_sectors = GetNandMinSizeSectors(NAND_SYSNAND); u64 sysnand_min_size_mb = ((sysnand_min_size_sectors * 0x200) + 0xFFFFF) / 0x100000; u64 sysnand_multi_size_mb = (align(sysnand_min_size_sectors + 1, 0x2000) * 0x200) / 0x100000; @@ -431,55 +434,61 @@ u32 SdFormatMenu(const char* slabel) { u32 cluster_size = 0; u64 sdcard_size_mb = 0; u64 emunand_size_mb = (u64) -1; - u32 user_select; + u32 user_select = 0; // check actual SD card size sdcard_size_mb = GetSDCardSize() / 0x100000; if (!sdcard_size_mb) { - ShowPrompt(false, "Error: SD card not detected."); + ShowPrompt(false, "%s", STR_SD_NOT_DETECTED); return 1; } - user_select = ShowSelectPrompt(7, option_emunand_size, "Format SD card (%lluMB)?\nChoose EmuNAND size:", sdcard_size_mb); + user_select = ShowSelectPrompt(7, option_emunand_size, STR_FORMAT_SD_CHOOSE_EMUNAND, sdcard_size_mb); if (user_select && (user_select < 4)) { emunand_size_mb = (user_select == 2) ? sysnand_min_size_mb : (user_select == 3) ? sysnand_size_mb : 0; } else if ((user_select >= 4) && (user_select <= 6)) { u32 n = (user_select - 2); emunand_size_mb = n * sysnand_multi_size_mb; } else if (user_select == 7) do { - emunand_size_mb = ShowNumberPrompt(sysnand_min_size_mb, "SD card size is %lluMB.\nEnter EmuNAND size (MB) below:", sdcard_size_mb); + emunand_size_mb = ShowNumberPrompt(sysnand_min_size_mb, STR_SD_SIZE_IS_ENTER_EMUNAND_SIZE, sdcard_size_mb); if (emunand_size_mb == (u64) -1) break; } while (emunand_size_mb > sdcard_size_mb); if (emunand_size_mb == (u64) -1) return 1; - user_select = ShowSelectPrompt(4, option_cluster_size, "Format SD card (%lluMB)?\nChoose cluster size:", sdcard_size_mb); + user_select = ShowSelectPrompt(4, option_cluster_size, STR_FORMAT_SD_CHOOSE_CLUSTER, sdcard_size_mb); if (!user_select) return 1; else cluster_size = cluster_size_table[user_select]; - snprintf(label, DRV_LABEL_LEN + 4, "0:%s", (slabel && *slabel) ? slabel : "GM9SD"); - if (!ShowKeyboardOrPrompt(label + 2, 11 + 1, "Format SD card (%lluMB)?\nEnter label:", sdcard_size_mb)) + snprintf(label, sizeof(label), "0:%s", (slabel && *slabel) ? slabel : "GM9SD"); + if (!ShowKeyboardOrPrompt(label + 2, 11 + 1, STR_FORMAT_SD_ENTER_LABEL, sdcard_size_mb)) return 1; if (!FormatSDCard(emunand_size_mb, cluster_size, label)) { - ShowPrompt(false, "Format SD: failed!"); + ShowPrompt(false, "%s", STR_FORMAT_SD_FAILED); return 1; } if (emunand_size_mb >= sysnand_min_size_mb) { u32 emunand_offset = 1; u32 n_emunands = 1; - if (emunand_size_mb >= 2 * sysnand_size_mb) { - static const char* option_emunand_type[4] = { "RedNAND type (multi)", "RedNAND type (single)", "GW EmuNAND type", "Don't set up" }; - user_select = ShowSelectPrompt(4, option_emunand_type, "Choose EmuNAND type to set up:"); - if (user_select > 3) return 0; - emunand_offset = (user_select == 3) ? 0 : 1; + if (emunand_size_mb >= 2 * sysnand_multi_size_mb) { /* space can fit single/multi RedNAND or GW type */ + const char* option_emunand_type[4] = { STR_REDNAND_TYPE_MULTI, STR_REDNAND_TYPE_SINGLE, STR_DONT_SET_UP, 0 }; + u32 n_opt = 3; + if (emunand_size_mb >= sysnand_size_mb) { + option_emunand_type[2] = STR_GW_EMUNAND_TYPE; + option_emunand_type[3] = STR_DONT_SET_UP; + n_opt++; + } + user_select = ShowSelectPrompt(n_opt, option_emunand_type, "%s", STR_CHOOSE_EMUNAND_TYPE); + if (user_select == n_opt) return 0; + emunand_offset = (n_opt == 4 && user_select == 3) ? 0 : 1; if (user_select == 1) n_emunands = 4; - } else if (emunand_size_mb >= sysnand_size_mb) { - static const char* option_emunand_type[3] = { "RedNAND type", "GW EmuNAND type", "Don't set up" }; - user_select = ShowSelectPrompt(3, option_emunand_type, "Choose EmuNAND type to set up:"); + } else if (emunand_size_mb >= sysnand_size_mb) { /* space can fit single RedNAND or GW type, but not multi RedNAND */ + const char* option_emunand_type[3] = { STR_REDNAND_TYPE, STR_GW_EMUNAND_TYPE, STR_DONT_SET_UP }; + user_select = ShowSelectPrompt(3, option_emunand_type, "%s", STR_CHOOSE_EMUNAND_TYPE); if (user_select > 2) return 0; emunand_offset = (user_select == 2) ? 0 : 1; // 0 -> GW EmuNAND - } else user_select = ShowPrompt(true, "Clone SysNAND to RedNAND?") ? 1 : 0; + } else user_select = ShowPrompt(true, "%s", STR_CLONE_SYSNAND_TO_REDNAND) ? 1 : 0; /* space can only fit a single RedNAND */ if (!user_select) return 0; u8 ncsd[0x200]; @@ -491,7 +500,7 @@ u32 SdFormatMenu(const char* slabel) { if ((ReadNandSectors(ncsd, 0, 1, 0xFF, NAND_SYSNAND) != 0) || (WriteNandSectors(ncsd, 0, 1, 0xFF, NAND_EMUNAND) != 0) || (!PathCopy("E:", "S:/nand_minsize.bin", &flags))) { - ShowPrompt(false, "Cloning SysNAND to EmuNAND: failed!"); + ShowPrompt(false, "%s", STR_CLONING_SYSNAND_TO_EMUNAND_FAILED); break; } } @@ -524,7 +533,7 @@ u32 FileGraphicsViewer(const char* path) { if ((ret == 0) && w && h && (w <= SCREEN_WIDTH(ALT_SCREEN)) && (h <= SCREEN_HEIGHT)) { ClearScreenF(true, true, COLOR_STD_BG); DrawBitmap(ALT_SCREEN, -1, -1, w, h, bitmap); - ShowString("Press to continue"); + ShowString("%s", STR_PRESS_A_TO_CONTINUE); while(!(InputWait(0) & (BUTTON_A | BUTTON_B))); ClearScreenF(true, true, COLOR_STD_BG); } else ret = 1; @@ -571,13 +580,13 @@ u32 FileHexViewer(const char* path) { } static bool show_instr = true; - static const char* instr = "Hexeditor Controls:\n ↑↓→←(+R) - Scroll\nR+Y - Switch view\nX - Search / goto...\nA - Enter edit mode\nA+↑↓→← - Edit value\nB - Exit\n"; + const char* instr = STR_HEXEDITOR_CONTROLS; if (show_instr) { // show one time instructions - ShowPrompt(false, instr); + ShowPrompt(false, "%s", instr); show_instr = false; } - if (MAIN_SCREEN != TOP_SCREEN) ShowString(instr); + if (MAIN_SCREEN != TOP_SCREEN) ShowString("%s", instr); memcpy(bottom_cpy, BOT_SCREEN, SCREEN_SIZE_BOT); data = buffer; @@ -708,7 +717,7 @@ u32 FileHexViewer(const char* path) { // draw offset / ASCII representation if (x_off >= 0) DrawStringF(screen, x_off - x0, y, cutoff ? COLOR_HVOFFS : COLOR_HVOFFSI, - COLOR_STD_BG, "%08X", (unsigned int) offset + curr_pos); + COLOR_STD_BG, "%08X", (unsigned int) (offset + curr_pos)); if (x_ascii >= 0) { for (u32 i = 0; i < cols; i++) DrawCharacter(screen, ascii[i], x_ascii - x0 + (FONT_WIDTH_EXT * i), y, COLOR_HVASCII, COLOR_STD_BG); @@ -744,37 +753,35 @@ u32 FileHexViewer(const char* path) { else if (found_size && (pad_state & BUTTON_R1) && (pad_state & BUTTON_X)) { found_offset = FileFindData(path, found_data, found_size, found_offset + 1); if (found_offset == (u32) -1) { - ShowPrompt(false, "Not found!"); + ShowPrompt(false, "%s", STR_NOT_FOUND); found_size = 0; } else offset = found_offset; if (MAIN_SCREEN == TOP_SCREEN) ClearScreen(TOP_SCREEN, COLOR_STD_BG); else if (dual_screen) ClearScreen(BOT_SCREEN, COLOR_STD_BG); else memcpy(BOT_SCREEN, bottom_cpy, SCREEN_SIZE_BOT); } else if (pad_state & BUTTON_X) { - static const char* optionstr[3] = { "Go to offset", "Search for string", "Search for data" }; - u32 user_select = ShowSelectPrompt(3, optionstr, "Current offset: %08X\nSelect action:", - (unsigned int) offset); + const char* optionstr[3] = { STR_GO_TO_OFFSET, STR_SEARCH_FOR_STRING, STR_SEARCH_FOR_DATA }; + u32 user_select = ShowSelectPrompt(3, optionstr, STR_CURRENT_OFFSET_SELECT_ACTION, offset); if (user_select == 1) { // -> goto offset - u64 new_offset = ShowHexPrompt(offset, 8, "Current offset: %08X\nEnter new offset below.", - (unsigned int) offset); + u64 new_offset = ShowHexPrompt(offset, 8, STR_CURRENT_OFFSET_ENTER_NEW, offset); if (new_offset != (u64) -1) offset = new_offset; } else if (user_select == 2) { if (!found_size) *found_data = 0; - if (ShowKeyboardOrPrompt((char*) found_data, 64 + 1, "Enter search string below.\n(R+X to repeat search)")) { + if (ShowKeyboardOrPrompt((char*) found_data, 64 + 1, "%s", STR_ENTER_SEARCH_REPEAT_SEARCH)) { found_size = strnlen((char*) found_data, 64); found_offset = FileFindData(path, found_data, found_size, offset); if (found_offset == (u32) -1) { - ShowPrompt(false, "Not found!"); + ShowPrompt(false, "%s", STR_NOT_FOUND); found_size = 0; } else offset = found_offset; } } else if (user_select == 3) { u32 size = found_size; - if (ShowDataPrompt(found_data, &size, "Enter search data below.\n(R+X to repeat search)")) { + if (ShowDataPrompt(found_data, &size, "%s", STR_ENTER_SEARCH_REPEAT_SEARCH)) { found_size = size; found_offset = FileFindData(path, found_data, size, offset); if (found_offset == (u32) -1) { - ShowPrompt(false, "Not found!"); + ShowPrompt(false, "%s", STR_NOT_FOUND); found_size = 0; } else offset = found_offset; } @@ -799,9 +806,9 @@ u32 FileHexViewer(const char* path) { // check for user edits u32 diffs = 0; for (u32 i = 0; i < edit_bsize; i++) if (buffer[i] != buffer_cpy[i]) diffs++; - if (diffs && ShowPrompt(true, "You made edits in %i place(s).\nWrite changes to file?", diffs)) + if (diffs && ShowPrompt(true, STR_MADE_EDITS_SAVE_CHANGES, diffs)) if (!FileSetData(path, buffer, min(edit_bsize, (fsize - edit_start)), edit_start, false)) - ShowPrompt(false, "Failed writing to file!"); + ShowPrompt(false, "%s", STR_FAILED_WRITING_TO_FILE); data = buffer; last_offset = (u32) -1; // force reload from file } else if (pad_state & BUTTON_A) { @@ -851,38 +858,36 @@ u32 ShaCalculator(const char* path, bool sha1) { u8 hash[32]; TruncateString(pathstr, path, 32, 8); if (!FileGetSha(path, hash, 0, 0, sha1)) { - ShowPrompt(false, "Calculating SHA-%s: failed!", sha1 ? "1" : "256"); + ShowPrompt(false, STR_CALCULATING_SHA_FAILED, sha1 ? "1" : "256"); return 1; } else { - static char pathstr_prev[32 + 1] = { 0 }; + static char pathstr_prev[UTF_BUFFER_BYTESIZE(32)] = { 0 }; static u8 hash_prev[32] = { 0 }; char sha_path[256]; u8 sha_file[32]; - snprintf(sha_path, 256, "%s.sha%c", path, sha1 ? '1' : '\0'); + snprintf(sha_path, sizeof(sha_path), "%s.sha%c", path, sha1 ? '1' : '\0'); bool have_sha = (FileGetData(sha_path, sha_file, hashlen, 0) == hashlen); bool match_sha = have_sha && (memcmp(hash, sha_file, hashlen) == 0); bool match_prev = (memcmp(hash, hash_prev, hashlen) == 0); bool write_sha = (!have_sha || !match_sha) && (drvtype & DRV_SDCARD); // writing only on SD char hash_str[32+1+32+1]; if (sha1) - snprintf(hash_str, 20+1+20+1, "%016llX%04X\n%016llX%04X", getbe64(hash + 0), getbe16(hash + 8), + snprintf(hash_str, sizeof(hash_str), "%016llX%04X\n%016llX%04X", getbe64(hash + 0), getbe16(hash + 8), getbe64(hash + 10), getbe16(hash + 18)); else - snprintf(hash_str, 32+1+32+1, "%016llX%016llX\n%016llX%016llX", getbe64(hash + 0), getbe64(hash + 8), + snprintf(hash_str, sizeof(hash_str), "%016llX%016llX\n%016llX%016llX", getbe64(hash + 0), getbe64(hash + 8), getbe64(hash + 16), getbe64(hash + 24)); - if (ShowPrompt(write_sha, "%s\n%s%s%s%s%s%c \nWrite .SHA%s file?", + if (ShowPrompt(write_sha, "%s\n%s%s%s%s%s", pathstr, hash_str, - (have_sha) ? "\nSHA verification: " : "", - (have_sha) ? ((match_sha) ? "passed!" : "failed!") : "", - (match_prev) ? "\n \nIdentical with previous file:\n" : "", + (have_sha) ? ((match_sha) ? STR_SHA_VERIFICATION_PASSED : STR_SHA_VERIFICATION_FAILED) : "", + (match_prev) ? STR_IDENTICAL_WITH_PREVIOUS : "", (match_prev) ? pathstr_prev : "", - (write_sha) ? '\n' : '\0', - (sha1) ? "1" : "") && write_sha) { + (sha1) ? STR_WRITE_SHA1_FILE : STR_WRITE_SHA_FILE) && write_sha) { FileSetData(sha_path, hash, hashlen, 0, true); } - strncpy(pathstr_prev, pathstr, 32 + 1); + strncpy(pathstr_prev, pathstr, UTF_BUFFER_BYTESIZE(32)); memcpy(hash_prev, hash, hashlen); } @@ -895,26 +900,26 @@ u32 CmacCalculator(const char* path) { if (IdentifyFileType(path) != GAME_CMD) { u8 cmac[16] __attribute__((aligned(4))); if (CalculateFileCmac(path, cmac) != 0) { - ShowPrompt(false, "Calculating CMAC: failed!"); + ShowPrompt(false, "%s", STR_CALCULATING_CMAC_FAILED); return 1; } else { u8 cmac_file[16]; bool identical = ((ReadFileCmac(path, cmac_file) == 0) && (memcmp(cmac, cmac_file, 16) == 0)); - if (ShowPrompt(!identical, "%s\n%016llX%016llX\n%s%s%s", + if (ShowPrompt(!identical, "%s\n%016llX%016llX\n%s%s", pathstr, getbe64(cmac + 0), getbe64(cmac + 8), - "CMAC verification: ", (identical) ? "passed!" : "failed!", - (!identical) ? "\n \nFix CMAC in file?" : "") && + (identical) ? STR_CMAC_VERIFICATION_PASSED : STR_CMAC_VERIFICATION_FAILED, + (!identical) ? STR_FIX_CMAC_IN_FILE : "") && !identical && (WriteFileCmac(path, cmac, true) != 0)) { - ShowPrompt(false, "Fixing CMAC: failed!"); + ShowPrompt(false, "%s", STR_FIXING_CMAC_FAILED); } } } else { // special handling for CMD files bool correct = (CheckCmdCmac(path) == 0); - if (ShowPrompt(!correct, "%s\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n%s%s%s", - pathstr, "CMAC verification: ", (correct) ? "passed!" : "failed!", - (!correct) ? "\n \nFix CMAC in file?" : "") && + if (ShowPrompt(!correct, "%s\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n%s%s", + pathstr, (correct) ? STR_CMAC_VERIFICATION_PASSED : STR_CMAC_VERIFICATION_FAILED, + (!correct) ? STR_FIX_CMAC_IN_FILE : "") && !correct && (FixCmdCmac(path, true) != 0)) { - ShowPrompt(false, "Fixing CMAC: failed!"); + ShowPrompt(false, "%s", STR_FIXING_CMAC_FAILED); } } @@ -931,7 +936,7 @@ u32 StandardCopy(u32* cursor, u32* scroll) { } u32 flags = BUILD_PATH; - if ((n_marked > 1) && ShowPrompt(true, "Copy all %lu selected items?", n_marked)) { + if ((n_marked > 1) && ShowPrompt(true, STR_COPY_ALL_SELECTED_ITEMS, n_marked)) { u32 n_success = 0; for (u32 i = 0; i < current_dir->n_entries; i++) { const char* path = current_dir->entry[i].path; @@ -943,18 +948,18 @@ u32 StandardCopy(u32* cursor, u32* scroll) { else { // on failure: show error, break char currstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(currstr, path, 32, 12); - ShowPrompt(false, "%s\nFailed copying item", currstr); + ShowPrompt(false, "%s\n%s", currstr, STR_FAILED_COPYING_ITEM); break; } current_dir->entry[i].marked = false; } - if (n_success) ShowPrompt(false, "%lu items copied to %s", n_success, OUTPUT_PATH); + if (n_success) ShowPrompt(false, STR_ITEMS_COPIED_TO_OUT, n_success, OUTPUT_PATH); } else { char pathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(pathstr, curr_entry->path, 32, 8); if (!PathCopy(OUTPUT_PATH, curr_entry->path, &flags)) - ShowPrompt(false, "%s\nFailed copying item", pathstr); - else ShowPrompt(false, "%s\nCopied to %s", pathstr, OUTPUT_PATH); + ShowPrompt(false, "%s\n%s", pathstr, STR_FAILED_COPYING_ITEM); + else ShowPrompt(false, STR_PATH_COPIED_TO_OUT, pathstr, OUTPUT_PATH); } return 0; @@ -968,7 +973,7 @@ u32 CartRawDump(void) { u64 dsize = 0; if (!cdata ||(InitCartRead(cdata) != 0) || (GetCartName(cname, cdata) != 0)) { - ShowPrompt(false, "Cart init failed!"); + ShowPrompt(false, "%s", STR_CART_INIT_FAILED); free(cdata); return 1; } @@ -976,7 +981,7 @@ u32 CartRawDump(void) { // input dump size dsize = cdata->cart_size; FormatBytes(bytestr, dsize); - dsize = ShowHexPrompt(dsize, 8, "Cart: %s\nDetected size: %s\n \nInput dump size below.", cname, bytestr); + dsize = ShowHexPrompt(dsize, 8, STR_CART_DETECTED_SIZE_INPUT_BELOW, cname, bytestr); if (!dsize || (dsize == (u64) -1)) { free(cdata); return 1; @@ -985,10 +990,10 @@ u32 CartRawDump(void) { // for NDS carts: ask for secure area encryption if (cdata->cart_type & CART_NTR) SetSecureAreaEncryption( - !ShowPrompt(true, "Cart: %s\nNDS cart detected\nDecrypt the secure area?", cname)); + !ShowPrompt(true, STR_NDS_CART_DECRYPT_SECURE_AREA, cname)); // destination path - snprintf(dest, 256, "%s/%s_%08llX.%s", + snprintf(dest, sizeof(dest), "%s/%s_%08llX.%s", OUTPUT_PATH, cname, dsize, (cdata->cart_type & CART_CTR) ? "3ds" : "nds"); // buffer allocation @@ -1013,8 +1018,8 @@ u32 CartRawDump(void) { } } - if (ret) ShowPrompt(false, "%s\nFailed dumping cart", cname); - else ShowPrompt(false, "%s\nDumped to %s", cname, OUTPUT_PATH); + if (ret) ShowPrompt(false, STR_FAILED_DUMPING_CART, cname); + else ShowPrompt(false, STR_PATH_DUMPED_TO_OUT, cname, OUTPUT_PATH); free(buf); free(cdata); @@ -1024,7 +1029,7 @@ u32 CartRawDump(void) { u32 DirFileAttrMenu(const char* path, const char *name) { bool drv = (path[2] == '\0'); bool vrt = (!drv); // will be checked below - char namestr[128], datestr[32], attrstr[128], sizestr[192]; + char namestr[UTF_BUFFER_BYTESIZE(128)], datestr[UTF_BUFFER_BYTESIZE(32)], attrstr[UTF_BUFFER_BYTESIZE(128)], sizestr[UTF_BUFFER_BYTESIZE(192)]; FILINFO fno; u8 new_attrib; @@ -1036,8 +1041,8 @@ u32 DirFileAttrMenu(const char* path, const char *name) { if (fvx_stat(path, &fno) != FR_OK) return 1; vrt = (fno.fattrib & AM_VRT); new_attrib = fno.fattrib; - snprintf(datestr, 32, "%s: %04d-%02d-%02d %02d:%02d:%02d\n", - (fno.fattrib & AM_DIR) ? "created" : "modified", + snprintf(datestr, sizeof(datestr), "%s: %04d-%02d-%02d %02d:%02d:%02d\n", + (fno.fattrib & AM_DIR) ? STR_CREATED : STR_MODIFIED, 1980 + ((fno.fdate >> 9) & 0x7F), (fno.fdate >> 5) & 0xF, fno.fdate & 0x1F, (fno.ftime >> 11) & 0x1F, (fno.ftime >> 5) & 0x3F, (fno.ftime & 0x1F) << 1); } else { @@ -1054,7 +1059,7 @@ u32 DirFileAttrMenu(const char* path, const char *name) { u32 tfiles = 0; // this may take a while... - ShowString("Analyzing %s, please wait...", drv ? "drive" : "dir"); + ShowString("%s", drv ? STR_ANALYZING_DRIVE : STR_ANALYZING_DIR); if (!DirInfo(path, &tsize, &tdirs, &tfiles)) return 1; FormatBytes(bytestr, tsize); @@ -1064,32 +1069,27 @@ u32 DirFileAttrMenu(const char* path, const char *name) { FormatBytes(freestr, GetFreeSpace(path)); FormatBytes(drvsstr, GetTotalSpace(path)); FormatBytes(usedstr, GetTotalSpace(path) - GetFreeSpace(path)); - snprintf(sizestr, 192, "%lu files & %lu subdirs\n%s total size\n \nspace free: %s\nspace used: %s\nspace total: %s", + snprintf(sizestr, sizeof(sizestr), STR_N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL, tfiles, tdirs, bytestr, freestr, usedstr, drvsstr); } else { // dir specific - snprintf(sizestr, 192, "%lu files & %lu subdirs\n%s total size", - tfiles, tdirs, bytestr); + snprintf(sizestr, sizeof(sizestr), STR_N_FILES_N_SUBDIRS_TOTAL_SIZE, tfiles, tdirs, bytestr); } } else { // for files char bytestr[32]; FormatBytes(bytestr, fno.fsize); - snprintf(sizestr, 64, "filesize: %s", bytestr); + snprintf(sizestr, sizeof(sizestr), STR_FILESIZE_X, bytestr); } while(true) { if (!drv) { - snprintf(attrstr, 128, - " \n" - "[%c] %sread-only [%c] %shidden\n" - "[%c] %ssystem [%c] %sarchive\n" - "[%c] %svirtual\n" - "%s", + snprintf(attrstr, sizeof(attrstr), + STR_READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL, (new_attrib & AM_RDO) ? 'X' : ' ', vrt ? "" : "↑", (new_attrib & AM_HID) ? 'X' : ' ', vrt ? "" : "↓", (new_attrib & AM_SYS) ? 'X' : ' ', vrt ? "" : "→", (new_attrib & AM_ARC) ? 'X' : ' ', vrt ? "" : "←", vrt ? 'X' : ' ', vrt ? "" : " ", - vrt ? "" : " \n(↑↓→← to change attributes)\n" + vrt ? "" : STR_UDRL_CHANGE_ATTRIBUTES ); } @@ -1100,7 +1100,7 @@ u32 DirFileAttrMenu(const char* path, const char *name) { "%s \n" // attr (not for drives) "%s\n", // options namestr, datestr, sizestr, attrstr, - (drv || vrt || (new_attrib == fno.fattrib)) ? "( to continue)" : "( to apply, to cancel)" + (drv || vrt || (new_attrib == fno.fattrib)) ? STR_A_TO_CONTINUE : STR_A_APPLY_B_CANCEL ); while(true) { @@ -1111,7 +1111,7 @@ u32 DirFileAttrMenu(const char* path, const char *name) { const u8 mask = (AM_RDO | AM_HID | AM_SYS | AM_ARC); bool apply = (new_attrib != fno.fattrib) && (pad_state & BUTTON_A); if (apply && !PathAttr(path, new_attrib & mask, mask)) { - ShowPrompt(false, "%s\nFailed to set attributes!", namestr); + ShowPrompt(false, "%s\n%s", namestr, STR_FAILED_TO_SET_ATTRIBUTES); } } ClearScreenF(true, false, COLOR_STD_BG); @@ -1191,6 +1191,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan bool keyinstallable = (FTYPE_KEYINSTALL(filetype)) && !((drvtype & DRV_VIRTUAL) && (drvtype & DRV_SYSNAND)); bool scriptable = (FTYPE_SCRIPT(filetype)); bool fontable = (FTYPE_FONT(filetype)); + bool translationable = (FTYPE_TRANSLATION(filetype)); bool viewable = (FTYPE_GFX(filetype)); bool setable = (FTYPE_SETABLE(filetype)); bool bootable = (FTYPE_BOOTABLE(filetype)); @@ -1211,14 +1212,14 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan mountable || verificable || decryptable || encryptable || cia_buildable || cia_buildable_legit || cxi_dumpable || tik_buildable || key_buildable || titleinfo || renamable || trimable || transferable || hsinjectable || restorable || xorpadable || ebackupable || ncsdfixable || extrcodeable || keyinitable || - keyinstallable || bootable || scriptable || fontable || viewable || installable || agbexportable || - agbimportable || cia_installable || tik_installable || tik_dumpable || cif_installable; + keyinstallable || bootable || scriptable || fontable || translationable || viewable || installable || + agbexportable || agbimportable || cia_installable || tik_installable || tik_dumpable || cif_installable; char pathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(pathstr, file_path, 32, 8); char tidstr[32] = { 0 }; - if (tid) snprintf(tidstr, 32, "\ntid: <%016llX>", tid); + if (tid) snprintf(tidstr, sizeof(tidstr), "\ntid: <%016llX>", tid); u32 n_marked = 0; if ((&(current_dir->entry[*cursor]))->marked) { @@ -1249,54 +1250,71 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan titleman = 2; n_opt = 2; } + + // format strings that need it + char buildkeydb_str[256], buildtikdbenc_str[256], buildtikdbdec_str[256], + copyto_str[256], decryptto_str[256], encryptto_str[256], extractexefs_str[256], + initkeydb_str[256], installkeydb_str[256]; + snprintf(buildkeydb_str, sizeof(buildkeydb_str), STR_BUILD_X, KEYDB_NAME); + snprintf(buildtikdbenc_str, sizeof(buildtikdbenc_str), STR_BUILD_X, TIKDB_NAME_ENC); + snprintf(buildtikdbdec_str, sizeof(buildtikdbdec_str), STR_BUILD_X, TIKDB_NAME_DEC); + snprintf(copyto_str, sizeof(copyto_str), STR_COPY_TO_OUT, OUTPUT_PATH); + snprintf(decryptto_str, sizeof(decryptto_str), STR_DECRYPT_FILE_OUT, OUTPUT_PATH); + snprintf(encryptto_str, sizeof(encryptto_str), STR_ENCRYPT_FILE_OUT, OUTPUT_PATH); + snprintf(extractexefs_str, sizeof(extractexefs_str), STR_EXTRACT_X, EXEFS_CODE_NAME); + snprintf(initkeydb_str, sizeof(initkeydb_str), STR_INIT_X, KEYDB_NAME); + snprintf(installkeydb_str, sizeof(installkeydb_str), STR_INSTALL_X, KEYDB_NAME); + if (special > 0) optionstr[special-1] = - (filetype & IMG_NAND ) ? "NAND image options..." : - (filetype & IMG_FAT ) ? (transferable) ? "CTRNAND options..." : "Mount as FAT image" : - (filetype & GAME_CIA ) ? "CIA image options..." : - (filetype & GAME_NCSD ) ? "NCSD image options..." : - (filetype & GAME_NCCH ) ? "NCCH image options..." : - (filetype & GAME_EXEFS) ? "Mount as EXEFS image" : - (filetype & GAME_ROMFS) ? "Mount as ROMFS image" : - (filetype & GAME_TMD ) ? "TMD file options..." : - (filetype & GAME_CDNTMD)? "TMD/CDN options..." : - (filetype & GAME_TWLTMD)? "TMD/TWL options..." : - (filetype & GAME_TIE ) ? "Manage Title..." : - (filetype & GAME_BOSS ) ? "BOSS file options..." : - (filetype & GAME_NUSCDN)? "Decrypt NUS/CDN file" : - (filetype & GAME_SMDH) ? "Show SMDH title info" : - (filetype & GAME_NDS) ? "NDS image options..." : - (filetype & GAME_GBA) ? "GBA image options..." : - (filetype & GAME_TICKET)? "Ticket options..." : - (filetype & GAME_TAD) ? "TAD image options..." : - (filetype & GAME_3DSX) ? "Show 3DSX title info" : - (filetype & SYS_FIRM ) ? "FIRM image options..." : - (filetype & SYS_AGBSAVE)? (agbimportable) ? "AGBSAVE options..." : "Dump GBA VC save" : - (filetype & SYS_TICKDB) ? "Ticket.db options..." : - (filetype & SYS_DIFF) ? "Mount as DIFF image" : - (filetype & SYS_DISA) ? "Mount as DISA image" : - (filetype & BIN_CIFNSH) ? "Install cifinish.bin" : - (filetype & BIN_TIKDB) ? "Titlekey options..." : - (filetype & BIN_KEYDB) ? "AESkeydb options..." : - (filetype & BIN_LEGKEY) ? "Build " KEYDB_NAME : - (filetype & BIN_NCCHNFO)? "NCCHinfo options..." : - (filetype & TXT_SCRIPT) ? "Execute GM9 script" : - (FTYPE_FONT(filetype)) ? "Font options..." : - (filetype & GFX_PNG) ? "View PNG file" : - (filetype & HDR_NAND) ? "Rebuild NCSD header" : - (filetype & NOIMG_NAND) ? "Rebuild NCSD header" : "???"; - optionstr[hexviewer-1] = "Show in Hexeditor"; - optionstr[calcsha256-1] = "Calculate SHA-256"; - optionstr[calcsha1-1] = "Calculate SHA-1"; - optionstr[fileinfo-1] = "Show file info"; - if (textviewer > 0) optionstr[textviewer-1] = "Show in Textviewer"; - if (calccmac > 0) optionstr[calccmac-1] = "Calculate CMAC"; - if (copystd > 0) optionstr[copystd-1] = "Copy to " OUTPUT_PATH; - if (inject > 0) optionstr[inject-1] = "Inject data @offset"; - if (searchdrv > 0) optionstr[searchdrv-1] = "Open containing folder"; - if (titleman > 0) optionstr[titleman-1] = "Open title folder"; - - int user_select = ShowSelectPrompt(n_opt, optionstr, (n_marked > 1) ? - "%s%0.0s\n(%lu files selected)" : "%s%s", pathstr, tidstr, n_marked); + (filetype & IMG_NAND) ? STR_NAND_IMAGE_OPTIONS : + (filetype & IMG_FAT) ? (transferable) ? STR_CTRNAND_OPTIONS : STR_MOUNT_FAT_IMAGE : + (filetype & GAME_CIA) ? STR_CIA_IMAGE_OPTIONS : + (filetype & GAME_NCSD) ? STR_NCSD_IMAGE_OPTIONS : + (filetype & GAME_NCCH) ? STR_NCCH_IMAGE_OPTIONS : + (filetype & GAME_EXEFS) ? STR_MOUNT_AS_EXEFS_IMAGE : + (filetype & GAME_ROMFS) ? STR_MOUNT_AS_ROMFS_IMAGE : + (filetype & GAME_TMD) ? STR_TMD_FILE_OPTIONS : + (filetype & GAME_CDNTMD)? STR_TMD_CDN_OPTIONS : + (filetype & GAME_TWLTMD)? STR_TMD_TWL_OPTIONS : + (filetype & GAME_TIE) ? STR_MANAGE_TITLE : + (filetype & GAME_BOSS) ? STR_BOSS_FILE_OPTIONS : + (filetype & GAME_NUSCDN)? STR_DECRYPT_NUS_CDN_FILE : + (filetype & GAME_SMDH) ? STR_SHOW_SMDH_TITLE_INFO : + (filetype & GAME_NDS) ? STR_NDS_IMAGE_OPTIONS : + (filetype & GAME_GBA) ? STR_GBA_IMAGE_OPTIONS : + (filetype & GAME_TICKET)? STR_TICKET_OPTIONS : + (filetype & GAME_TAD) ? STR_TAD_IMAGE_OPTIONS : + (filetype & GAME_3DSX) ? STR_SHOW_3DSX_TITLE_INFO : + (filetype & SYS_FIRM) ? STR_FIRM_IMAGE_OPTIONS : + (filetype & SYS_AGBSAVE)? (agbimportable) ? STR_AGBSAVE_OPTIONS : STR_DUMP_GBA_VC_SAVE : + (filetype & SYS_TICKDB) ? STR_TICKET_DB_OPTIONS : + (filetype & SYS_DIFF) ? STR_MOUNT_AS_DIFF_IMAGE : + (filetype & SYS_DISA) ? STR_MOUNT_AS_DISA_IAMGE : + (filetype & BIN_CIFNSH) ? STR_INSTALL_CIFINISH_BIN : + (filetype & BIN_TIKDB) ? STR_TITLEKEY_OPTIONS : + (filetype & BIN_KEYDB) ? STR_AESKEYDB_OPTIONS : + (filetype & BIN_LEGKEY) ? buildkeydb_str : + (filetype & BIN_NCCHNFO)? STR_NCCHINFO_OPTIONS : + (filetype & TXT_SCRIPT) ? STR_EXECUTE_GM9_SCRIPT : + (FTYPE_FONT(filetype)) ? STR_FONT_OPTIONS : + (filetype & TRANSLATION)? STR_LANGUAGE_OPTIONS : + (filetype & GFX_PNG) ? STR_VIEW_PNG_FILE : + (filetype & HDR_NAND) ? STR_REBUILD_NCSD_HEADER : + (filetype & NOIMG_NAND) ? STR_REBUILD_NCSD_HEADER : "???"; + optionstr[hexviewer-1] = STR_SHOW_IN_HEXEDITOR; + optionstr[calcsha256-1] = STR_CALCULATE_SHA256; + optionstr[calcsha1-1] = STR_CALCULATE_SHA1; + optionstr[fileinfo-1] = STR_SHOW_FILE_INFO; + if (textviewer > 0) optionstr[textviewer-1] = STR_SHOW_IN_TEXTVIEWER; + if (calccmac > 0) optionstr[calccmac-1] = STR_CALCULATE_CMAC; + if (copystd > 0) optionstr[copystd-1] = copyto_str; + if (inject > 0) optionstr[inject-1] = STR_INJECT_DATA_AT_OFFSET; + if (searchdrv > 0) optionstr[searchdrv-1] = STR_OPEN_CONTAINING_FOLDER; + if (titleman > 0) optionstr[titleman-1] = STR_OPEN_TITLE_FOLDER; + + int user_select = (int) ((n_marked > 1) ? + ShowSelectPrompt(n_opt, optionstr, STR_PATH_N_FILES_SELECTED, pathstr, n_marked) : + ShowSelectPrompt(n_opt, optionstr, "%s%s", pathstr, tidstr)); if (user_select == hexviewer) { // -> show in hex viewer FileHexViewer(file_path); GetDirContents(current_dir, current_path); @@ -1317,10 +1335,10 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan return 0; } else if (user_select == calccmac) { // -> calculate CMAC - optionstr[0] = "Check current CMAC only"; - optionstr[1] = "Verify CMAC for all"; - optionstr[2] = "Fix CMAC for all"; - user_select = (n_marked > 1) ? ShowSelectPrompt(3, optionstr, "%s\n(%lu files selected)", pathstr, n_marked) : 1; + optionstr[0] = STR_CHECK_CURRENT_CMAC_ONLY; + optionstr[1] = STR_VERIFY_CMAC_FOR_ALL; + optionstr[2] = STR_FIX_CMAC_FOR_ALL; + user_select = (n_marked > 1) ? ShowSelectPrompt(3, optionstr, STR_PATH_N_FILES_SELECTED, pathstr, n_marked) : 1; if (user_select == 1) { CmacCalculator(file_path); return 0; @@ -1347,14 +1365,14 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan current_dir->entry[i].marked = false; } if (n_fixed) { - if (n_nocmac) ShowPrompt(false, "%lu/%lu/%lu files ok/fixed/total\n%lu/%lu have no CMAC", + if (n_nocmac) ShowPrompt(false, STR_N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC, n_success, n_fixed, n_marked, n_nocmac, n_marked); - else ShowPrompt(false, "%lu/%lu files verified ok\n%lu/%lu files fixed", + else ShowPrompt(false, STR_N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED, n_success, n_marked, n_fixed, n_marked); } else { - if (n_nocmac) ShowPrompt(false, "%lu/%lu files verified ok\n%lu/%lu have no CMAC", + if (n_nocmac) ShowPrompt(false, STR_N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC, n_success, n_marked, n_nocmac, n_marked); - else ShowPrompt(false, "%lu/%lu files verified ok", n_success, n_marked); + else ShowPrompt(false, STR_N_OF_N_FILES_VERIFIED, n_success, n_marked); } return 0; } @@ -1371,10 +1389,10 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan else if (user_select == inject) { // -> inject data from clipboard char origstr[UTF_BUFFER_BYTESIZE(18)]; TruncateString(origstr, clipboard->entry[0].name, 18, 10); - u64 offset = ShowHexPrompt(0, 8, "Inject data from %s?\nSpecify offset below.", origstr); + u64 offset = ShowHexPrompt(0, 8, STR_INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW, origstr); if (offset != (u64) -1) { if (!FileInjectFile(file_path, clipboard->entry[0].path, (u32) offset, 0, 0, NULL)) - ShowPrompt(false, "Failed injecting %s", origstr); + ShowPrompt(false, STR_FAILED_INJECTING_PATH, origstr); clipboard->n_entries = 0; } return 0; @@ -1442,50 +1460,53 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan int boot = (bootable) ? ++n_opt : -1; int script = (scriptable) ? ++n_opt : -1; int font = (fontable) ? ++n_opt : -1; + int translation = (translationable) ? ++n_opt : -1; int view = (viewable) ? ++n_opt : -1; int agbexport = (agbexportable) ? ++n_opt : -1; int agbimport = (agbimportable) ? ++n_opt : -1; int setup = (setable) ? ++n_opt : -1; - if (mount > 0) optionstr[mount-1] = (filetype & GAME_TMD) ? "Mount CXI/NDS to drive" : "Mount image to drive"; - if (restore > 0) optionstr[restore-1] = "Restore SysNAND (safe)"; - if (ebackup > 0) optionstr[ebackup-1] = "Update embedded backup"; - if (ncsdfix > 0) optionstr[ncsdfix-1] = "Rebuild NCSD header"; - if (show_info > 0) optionstr[show_info-1] = "Show title info"; - if (decrypt > 0) optionstr[decrypt-1] = (cryptable_inplace) ? "Decrypt file (...)" : "Decrypt file (" OUTPUT_PATH ")"; - if (encrypt > 0) optionstr[encrypt-1] = (cryptable_inplace) ? "Encrypt file (...)" : "Encrypt file (" OUTPUT_PATH ")"; - if (cia_build > 0) optionstr[cia_build-1] = (cia_build_legit < 0) ? "Build CIA from file" : "Build CIA (standard)"; - if (cia_build_legit > 0) optionstr[cia_build_legit-1] = "Build CIA (legit)"; - if (cxi_dump > 0) optionstr[cxi_dump-1] = "Dump CXI/NDS file"; - if (cia_install > 0) optionstr[cia_install-1] = "Install game image"; - if (tik_install > 0) optionstr[tik_install-1] = "Install ticket"; - if (tik_dump > 0) optionstr[tik_dump-1] = "Dump ticket file"; - if (cif_install > 0) optionstr[cif_install-1] = "Install cifinish.bin"; - if (uninstall > 0) optionstr[uninstall-1] = "Uninstall title"; - if (tik_build_enc > 0) optionstr[tik_build_enc-1] = "Build " TIKDB_NAME_ENC; - if (tik_build_dec > 0) optionstr[tik_build_dec-1] = "Build " TIKDB_NAME_DEC; - if (key_build > 0) optionstr[key_build-1] = "Build " KEYDB_NAME; - if (verify > 0) optionstr[verify-1] = "Verify file"; - if (ctrtransfer > 0) optionstr[ctrtransfer-1] = "Transfer image to CTRNAND"; - if (hsinject > 0) optionstr[hsinject-1] = "Inject to H&S"; - if (trim > 0) optionstr[trim-1] = "Trim file"; - if (rename > 0) optionstr[rename-1] = "Rename file"; - if (xorpad > 0) optionstr[xorpad-1] = "Build XORpads (SD output)"; - if (xorpad_inplace > 0) optionstr[xorpad_inplace-1] = "Build XORpads (inplace)"; - if (extrcode > 0) optionstr[extrcode-1] = "Extract " EXEFS_CODE_NAME; - if (keyinit > 0) optionstr[keyinit-1] = "Init " KEYDB_NAME; - if (keyinstall > 0) optionstr[keyinstall-1] = "Install " KEYDB_NAME; - if (install > 0) optionstr[install-1] = "Install FIRM"; - if (boot > 0) optionstr[boot-1] = "Boot FIRM"; - if (script > 0) optionstr[script-1] = "Execute GM9 script"; - if (view > 0) optionstr[view-1] = "View PNG file"; - if (font > 0) optionstr[font-1] = "Set as active font"; - if (agbexport > 0) optionstr[agbexport-1] = "Dump GBA VC save"; - if (agbimport > 0) optionstr[agbimport-1] = "Inject GBA VC save"; - if (setup > 0) optionstr[setup-1] = "Set as default"; + if (mount > 0) optionstr[mount-1] = (filetype & GAME_TMD) ? STR_MOUNT_CXI_NDS_TO_DRIVE : STR_MOUNT_IMAGE_TO_DRIVE; + if (restore > 0) optionstr[restore-1] = STR_RESTORE_SYSNAND_SAFE; + if (ebackup > 0) optionstr[ebackup-1] = STR_UPDATE_EMBEDDED_BACKUP; + if (ncsdfix > 0) optionstr[ncsdfix-1] = STR_REBUILD_NCSD_HEADER; + if (show_info > 0) optionstr[show_info-1] = STR_SHOW_TITLE_INFO; + if (decrypt > 0) optionstr[decrypt-1] = (cryptable_inplace) ? STR_DECRYPT_FILE : decryptto_str; + if (encrypt > 0) optionstr[encrypt-1] = (cryptable_inplace) ? STR_ENCRYPT_FILE : encryptto_str; + if (cia_build > 0) optionstr[cia_build-1] = (cia_build_legit < 0) ? STR_BUILD_CIA_FROM_FILE : STR_BUILD_CIA_STANDARD; + if (cia_build_legit > 0) optionstr[cia_build_legit-1] = STR_BUILD_CIA_LEGIT; + if (cxi_dump > 0) optionstr[cxi_dump-1] = STR_DUMP_CXI_NDS_FILE; + if (cia_install > 0) optionstr[cia_install-1] = STR_INSTALL_GAME_IMAGE; + if (tik_install > 0) optionstr[tik_install-1] = STR_INSTALL_TICKET; + if (tik_dump > 0) optionstr[tik_dump-1] = STR_DUMP_TICKET_FILE; + if (cif_install > 0) optionstr[cif_install-1] = STR_INSTALL_CIFINISH_BIN; + if (uninstall > 0) optionstr[uninstall-1] = STR_UNINSTALL_TITLE; + if (tik_build_enc > 0) optionstr[tik_build_enc-1] = buildtikdbenc_str; + if (tik_build_dec > 0) optionstr[tik_build_dec-1] = buildtikdbdec_str; + if (key_build > 0) optionstr[key_build-1] = buildkeydb_str; + if (verify > 0) optionstr[verify-1] = STR_VERIFY_FILE; + if (ctrtransfer > 0) optionstr[ctrtransfer-1] = STR_TRANSFER_IMAGE_TO_CTRNAND; + if (hsinject > 0) optionstr[hsinject-1] = STR_INJECT_TO_H_AND_S; + if (trim > 0) optionstr[trim-1] = STR_TRIM_FILE; + if (rename > 0) optionstr[rename-1] = STR_RENAME_FILE; + if (xorpad > 0) optionstr[xorpad-1] = STR_BUILD_XORPADS_SD; + if (xorpad_inplace > 0) optionstr[xorpad_inplace-1] = STR_BUILD_XORPADS_INPLACE; + if (extrcode > 0) optionstr[extrcode-1] = extractexefs_str; + if (keyinit > 0) optionstr[keyinit-1] = initkeydb_str; + if (keyinstall > 0) optionstr[keyinstall-1] = installkeydb_str; + if (install > 0) optionstr[install-1] = STR_INSTALL_FIRM; + if (boot > 0) optionstr[boot-1] = STR_BOOT_FIRM; + if (script > 0) optionstr[script-1] = STR_EXECUTE_GM9_SCRIPT; + if (view > 0) optionstr[view-1] = STR_VIEW_PNG_FILE; + if (font > 0) optionstr[font-1] = STR_SET_AS_ACTIVE_FONT; + if (translation > 0) optionstr[translation-1] = STR_SET_AS_ACTIVE_LANGUAGE; + if (agbexport > 0) optionstr[agbexport-1] = STR_DUMP_BA_VC_SAVE; + if (agbimport > 0) optionstr[agbimport-1] = STR_INJECT_GBA_VC_SAVE; + if (setup > 0) optionstr[setup-1] = STR_SET_AS_DEFAULT; // auto select when there is only one option - user_select = (n_opt <= 1) ? n_opt : (int) ShowSelectPrompt(n_opt, optionstr, (n_marked > 1) ? - "%s%0.0s\n(%lu files selected)" : "%s%s", pathstr, tidstr, n_marked); + user_select = (n_opt <= 1) ? n_opt : (int) ((n_marked > 1) ? + ShowSelectPrompt(n_opt, optionstr, STR_PATH_N_FILES_SELECTED, pathstr, n_marked) : + ShowSelectPrompt(n_opt, optionstr, "%s%s", pathstr, tidstr)); if (user_select == mount) { // -> mount file as image const char* mnt_drv_paths[] = { "7:", "G:", "K:", "T:", "I:", "D:" }; // maybe move that to fsdrive.h if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & DRV_IMAGE)) @@ -1500,10 +1521,10 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan } if (!drv_path) { - ShowPrompt(false, "Mounting image: failed"); + ShowPrompt(false, "%s", STR_MOUNTING_IMAGE_FAILED); InitImgFS(NULL); } else { // open in next pane? - if (ShowPrompt(true, "%s\nMounted as drive %s\nEnter path now?", pathstr, drv_path)) { + if (ShowPrompt(true, STR_PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW, pathstr, drv_path)) { if (N_PANES) { memcpy((*pane)->path, current_path, 256); // store current pane state (*pane)->cursor = *cursor; @@ -1521,18 +1542,21 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan } else if (user_select == decrypt) { // -> decrypt game file if (cryptable_inplace) { - optionstr[0] = "Decrypt to " OUTPUT_PATH; - optionstr[1] = "Decrypt inplace"; - user_select = (int) ShowSelectPrompt(2, optionstr, (n_marked > 1) ? - "%s%0.0s\n(%lu files selected)" : "%s%s", pathstr, tidstr, n_marked); + char decryptToOut[UTF_BUFFER_BYTESIZE(64)]; + snprintf(decryptToOut, sizeof(decryptToOut), STR_DECRYPT_TO_OUT, OUTPUT_PATH); + optionstr[0] = decryptToOut; + optionstr[1] = STR_DECRYPT_INPLACE; + user_select = (int) ((n_marked > 1) ? + ShowSelectPrompt(2, optionstr, STR_PATH_N_FILES_SELECTED, pathstr, n_marked) : + ShowSelectPrompt(2, optionstr, "%s%s", pathstr, tidstr)); } else user_select = 1; bool inplace = (user_select == 2); if (!user_select) { // do nothing when no choice is made - } else if ((n_marked > 1) && ShowPrompt(true, "Try to decrypt all %lu selected files?", n_marked)) { + } else if ((n_marked > 1) && ShowPrompt(true, STR_TRY_TO_DECRYPT_ALL_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; u32 n_unencrypted = 0; u32 n_other = 0; - ShowString("Trying to decrypt %lu files...", n_marked); + ShowString(STR_TRYING_TO_DECRYPT_N_FILES, n_marked); for (u32 i = 0; i < current_dir->n_entries; i++) { const char* path = current_dir->entry[i].path; if (!current_dir->entry[i].marked) @@ -1551,41 +1575,44 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan else { // on failure: show error, continue char lpathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(lpathstr, path, 32, 8); - if (ShowPrompt(true, "%s\nDecryption failed\n \nContinue?", lpathstr)) continue; + if (ShowPrompt(true, "%s\n%s", lpathstr, STR_DECRYPTION_FAILED_CONTINUE)) continue; else break; } current_dir->entry[i].marked = false; } if (n_other || n_unencrypted) { - ShowPrompt(false, "%lu/%lu files decrypted ok\n%lu/%lu not encrypted\n%lu/%lu not of same type", + ShowPrompt(false, STR_N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE, n_success, n_marked, n_unencrypted, n_marked, n_other, n_marked); - } else ShowPrompt(false, "%lu/%lu files decrypted ok", n_success, n_marked); - if (!inplace && n_success) ShowPrompt(false, "%lu files written to %s", n_success, OUTPUT_PATH); + } else ShowPrompt(false, STR_N_OF_N_FILES_DECRYPTED, n_success, n_marked); + if (!inplace && n_success) ShowPrompt(false, STR_N_FILES_WRITTEN_TO_OUT, n_success, OUTPUT_PATH); } else { if (!(filetype & BIN_KEYDB) && (CheckEncryptedGameFile(file_path) != 0)) { - ShowPrompt(false, "%s\nFile is not encrypted", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_FILE_NOT_ENCRYPTED); } else { u32 ret = (filetype & BIN_KEYDB) ? CryptAesKeyDb(file_path, inplace, false) : CryptGameFile(file_path, inplace, false); - if (inplace || (ret != 0)) ShowPrompt(false, "%s\nDecryption %s", pathstr, (ret == 0) ? "success" : "failed"); - else ShowPrompt(false, "%s\nDecrypted to %s", pathstr, OUTPUT_PATH); + if (inplace || (ret != 0)) ShowPrompt(false, "%s\n%s", pathstr, (ret == 0) ? STR_DECRYPTION_SUCCESS : STR_DECRYPTION_FAILED); + else ShowPrompt(false, STR_PATH_DECRYPTED_TO_OUT, pathstr, OUTPUT_PATH); } } return 0; } else if (user_select == encrypt) { // -> encrypt game file if (cryptable_inplace) { - optionstr[0] = "Encrypt to " OUTPUT_PATH; - optionstr[1] = "Encrypt inplace"; - user_select = (int) ShowSelectPrompt(2, optionstr, (n_marked > 1) ? - "%s%0.0s\n(%lu files selected)" : "%s%s", pathstr, tidstr, n_marked); + char encryptToOut[UTF_BUFFER_BYTESIZE(64)]; + snprintf(encryptToOut, sizeof(encryptToOut), STR_ENCRYPT_TO_OUT, OUTPUT_PATH); + optionstr[0] = encryptToOut; + optionstr[1] = STR_ENCRYPT_INPLACE; + user_select = (int) ((n_marked > 1) ? + ShowSelectPrompt(2, optionstr, STR_PATH_N_FILES_SELECTED, pathstr, n_marked) : + ShowSelectPrompt(2, optionstr, "%s%s", pathstr, tidstr)); } else user_select = 1; bool inplace = (user_select == 2); if (!user_select) { // do nothing when no choice is made - } else if ((n_marked > 1) && ShowPrompt(true, "Try to encrypt all %lu selected files?", n_marked)) { + } else if ((n_marked > 1) && ShowPrompt(true, STR_TRY_TO_ENCRYPT_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; u32 n_other = 0; - ShowString("Trying to encrypt %lu files...", n_marked); + ShowString(STR_TRYING_TO_ENCRYPT_N_FILES, n_marked); for (u32 i = 0; i < current_dir->n_entries; i++) { const char* path = current_dir->entry[i].path; if (!current_dir->entry[i].marked) @@ -1600,28 +1627,28 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan else { // on failure: show error, continue char lpathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(lpathstr, path, 32, 8); - if (ShowPrompt(true, "%s\nEncryption failed\n \nContinue?", lpathstr)) continue; + if (ShowPrompt(true, "%s\n%s", lpathstr, STR_ENCRYPTION_FAILED_CONTINUE)) continue; else break; } current_dir->entry[i].marked = false; } if (n_other) { - ShowPrompt(false, "%lu/%lu files encrypted ok\n%lu/%lu not of same type", + ShowPrompt(false, STR_N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE, n_success, n_marked, n_other, n_marked); - } else ShowPrompt(false, "%lu/%lu files encrypted ok", n_success, n_marked); - if (!inplace && n_success) ShowPrompt(false, "%lu files written to %s", n_success, OUTPUT_PATH); + } else ShowPrompt(false, STR_N_OF_N_FILES_ENCRYPTED, n_success, n_marked); + if (!inplace && n_success) ShowPrompt(false, STR_N_FILES_WRITTEN_TO_OUT, n_success, OUTPUT_PATH); } else { u32 ret = (filetype & BIN_KEYDB) ? CryptAesKeyDb(file_path, inplace, true) : CryptGameFile(file_path, inplace, true); - if (inplace || (ret != 0)) ShowPrompt(false, "%s\nEncryption %s", pathstr, (ret == 0) ? "success" : "failed"); - else ShowPrompt(false, "%s\nEncrypted to %s", pathstr, OUTPUT_PATH); + if (inplace || (ret != 0)) ShowPrompt(false, "%s\n%s", pathstr, (ret == 0) ? STR_ENCRYPTION_SUCCESS : STR_ENCRYPTION_FAILED); + else ShowPrompt(false, STR_PATH_ENCRYPTED_TO_OUT, pathstr, OUTPUT_PATH); } return 0; } else if ((user_select == cia_build) || (user_select == cia_build_legit) || (user_select == cxi_dump)) { // -> build CIA / dump CXI char* type = (user_select == cxi_dump) ? "CXI" : "CIA"; bool force_legit = (user_select == cia_build_legit); - if ((n_marked > 1) && ShowPrompt(true, "Try to process all %lu selected files?", n_marked)) { + if ((n_marked > 1) && ShowPrompt(true, STR_TRY_TO_PROCESS_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; u32 n_other = 0; for (u32 i = 0; i < current_dir->n_entries; i++) { @@ -1638,31 +1665,30 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan else { // on failure: show error, continue char lpathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(lpathstr, path, 32, 8); - if (ShowPrompt(true, "%s\nBuild %s failed\n \nContinue?", lpathstr, type)) continue; + if (ShowPrompt(true, STR_PATH_BUILD_TYPE_FAILED_CONTINUE, lpathstr, type)) continue; else break; } current_dir->entry[i].marked = false; } - if (n_other) ShowPrompt(false, "%lu/%lu %ss built ok\n%lu/%lu not of same type", + if (n_other) ShowPrompt(false, STR_N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE, n_success, n_marked, type, n_other, n_marked); - else ShowPrompt(false, "%lu/%lu %ss built ok", n_success, n_marked, type); - if (n_success) ShowPrompt(false, "%lu files written to %s", n_success, OUTPUT_PATH); + else ShowPrompt(false, STR_N_OF_N_TYPES_BUILT, n_success, n_marked, type); + if (n_success) ShowPrompt(false, STR_N_FILES_WRITTEN_TO_OUT, n_success, OUTPUT_PATH); if (n_success && in_output_path) GetDirContents(current_dir, current_path); if (n_success != (n_marked - n_other)) { - ShowPrompt(false, "%lu file(s) failed conversion.\nVerification is recommended.", + ShowPrompt(false, STR_N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED, n_marked - (n_success + n_other)); } } else { if (((user_select != cxi_dump) && (BuildCiaFromGameFile(file_path, force_legit) == 0)) || ((user_select == cxi_dump) && (DumpCxiSrlFromGameFile(file_path) == 0))) { - ShowPrompt(false, "%s\n%s built to %s", pathstr, type, OUTPUT_PATH); + ShowPrompt(false, STR_PATH_TYPE_BUILT_TO_OUT, pathstr, type, OUTPUT_PATH); if (in_output_path) GetDirContents(current_dir, current_path); } else { - ShowPrompt(false, "%s\n%s build failed", pathstr, type); + ShowPrompt(false, STR_PATH_TYPE_BUILD_FAILED, pathstr, type); if ((filetype & (GAME_NCCH|GAME_NCSD)) && - ShowPrompt(true, "%s\nfile failed conversion.\n \nVerify now?", pathstr)) { - ShowPrompt(false, "%s\nVerification %s", pathstr, - (VerifyGameFile(file_path) == 0) ? "success" : "failed"); + ShowPrompt(true, "%s\n%s", pathstr, STR_FILE_FAILED_CONVERSION_VERIFY_NOW)) { + ShowPrompt(false, "%s\n%s", pathstr, (VerifyGameFile(file_path) == 0) ? STR_VERIFICATION_SUCCESS : STR_VERIFICATION_FAILED); } } } @@ -1675,17 +1701,18 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan (user_select == tik_install) ? &InstallTicketFile : &InstallCifinishFile; bool to_emunand = false; if (CheckVirtualDrive("E:")) { - optionstr[0] = "Install to SysNAND"; - optionstr[1] = "Install to EmuNAND"; - user_select = (int) ShowSelectPrompt(2, optionstr, (n_marked > 1) ? - "%s%0.0s\n(%lu files selected)" : "%s%s", pathstr, tidstr, n_marked); + optionstr[0] = STR_INSTALL_TO_SYSNAND; + optionstr[1] = STR_INSTALL_TO_EMUNAND; + user_select = (int) ((n_marked > 1) ? + ShowSelectPrompt(2, optionstr, STR_PATH_N_FILES_SELECTED, pathstr, n_marked) : + ShowSelectPrompt(2, optionstr, "%s%s", pathstr, tidstr)); if (!user_select) return 0; else to_emunand = (user_select == 2); } - if ((n_marked > 1) && ShowPrompt(true, "Try to install all %lu selected files?", n_marked)) { + if ((n_marked > 1) && ShowPrompt(true, STR_TRY_TO_INSTALL_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; u32 n_other = 0; - ShowString("Trying to install %lu files...", n_marked); + ShowString(STR_TRYING_TO_INSTALL_N_FILES, n_marked); for (u32 i = 0; i < current_dir->n_entries; i++) { const char* path = current_dir->entry[i].path; if (!current_dir->entry[i].marked) @@ -1700,22 +1727,21 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan else { // on failure: show error, continue char lpathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(lpathstr, path, 32, 8); - if (ShowPrompt(true, "%s\nInstall failed\n \nContinue?", lpathstr)) continue; + if (ShowPrompt(true, "%s\n%s", lpathstr, STR_INSTALL_FAILED_CONTINUE)) continue; else break; } current_dir->entry[i].marked = false; } if (n_other) { - ShowPrompt(false, "%lu/%lu files installed ok\n%lu/%lu not of same type", + ShowPrompt(false, STR_N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE, n_success, n_marked, n_other, n_marked); - } else ShowPrompt(false, "%lu/%lu files installed ok", n_success, n_marked); + } else ShowPrompt(false, STR_N_OF_N_FILES_INSTALLED, n_success, n_marked); } else { u32 ret = (*InstallFunction)(file_path, to_emunand); - ShowPrompt(false, "%s\nInstall %s", pathstr, (ret == 0) ? "success" : "failed"); + ShowPrompt(false, "%s\n%s", pathstr, (ret == 0) ? STR_INSTALL_SUCCESS : STR_INSTALL_FAILED); if ((ret != 0) && (filetype & (GAME_NCCH|GAME_NCSD)) && - ShowPrompt(true, "%s\nfile failed install.\n \nVerify now?", pathstr)) { - ShowPrompt(false, "%s\nVerification %s", pathstr, - (VerifyGameFile(file_path) == 0) ? "success" : "failed"); + ShowPrompt(true, "%s\n%s", pathstr, STR_FILE_FAILED_INSTALL_VERIFY_NOW)) { + ShowPrompt(false, "%s\n%s", pathstr, (VerifyGameFile(file_path) == 0) ? STR_VERIFICATION_SUCCESS : STR_VERIFICATION_FAILED); } } return 0; @@ -1724,12 +1750,12 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan bool full_uninstall = false; // safety confirmation - optionstr[0] = "Keep ticket & savegame"; - optionstr[1] = "Uninstall everything"; - optionstr[2] = "Abort uninstall"; + optionstr[0] = STR_KEEP_TICKET_AND_SAVEGAME; + optionstr[1] = STR_UNINSTALL_EVERYTHING; + optionstr[2] = STR_ABORT_UNINSTALL; user_select = (int) (n_marked > 1) ? - ShowSelectPrompt(3, optionstr, "Uninstall %lu selected titles?", n_marked) : - ShowSelectPrompt(3, optionstr, "%s\nUninstall selected title?", pathstr); + ShowSelectPrompt(3, optionstr, STR_UNINSTALL_N_SELECTED_TITLES, n_marked) : + ShowSelectPrompt(3, optionstr, "%s\n%s", pathstr, STR_UNINSTALL_SELECTED_TITLE); full_uninstall = (user_select == 2); if (!user_select || (user_select == 3)) return 0; @@ -1747,11 +1773,11 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan if (UninstallGameDataTie(path, true, full_uninstall, full_uninstall) == 0) n_success++; } - ShowPrompt(false, "%lu/%lu titles uninstalled", n_success, n_marked); + ShowPrompt(false, STR_N_OF_N_TITLES_UNINSTALLED, n_success, n_marked); } else if (CheckWritePermissions(file_path)) { - ShowString("%s\nUninstalling, please wait...", pathstr); + ShowString("%s\n%s", pathstr, STR_UNINSTALLING_PLEASE_WAIT); if (UninstallGameDataTie(file_path, true, full_uninstall, full_uninstall) != 0) - ShowPrompt(false, "%s\nUninstall failed!", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_UNINSTALL_FAILED); ClearScreenF(true, false, COLOR_STD_BG); } @@ -1759,7 +1785,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan return 0; } else if (user_select == verify) { // -> verify game / nand file - if ((n_marked > 1) && ShowPrompt(true, "Try to verify all %lu selected files?", n_marked)) { + if ((n_marked > 1) && ShowPrompt(true, STR_TRY_TO_VERIFY_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; u32 n_other = 0; u32 n_processed = 0; @@ -1779,7 +1805,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan else { // on failure: show error, continue char lpathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(lpathstr, path, 32, 8); - if (ShowPrompt(true, "%s\nVerification failed\n \nContinue?", lpathstr)) { + if (ShowPrompt(true, "%s\n%s", lpathstr, STR_VERIFICATION_FAILED_CONTINUE)) { if (!(filetype & (GAME_CIA|GAME_TMD|GAME_NCSD|GAME_NCCH))) ShowProgress(0, n_marked, path); // restart progress bar continue; @@ -1787,21 +1813,19 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan } current_dir->entry[i].marked = false; } - if (n_other) ShowPrompt(false, "%lu/%lu files verified ok\n%lu/%lu not of same type", + if (n_other) ShowPrompt(false, STR_N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE, n_success, n_marked, n_other, n_marked); - else ShowPrompt(false, "%lu/%lu files verified ok", n_success, n_marked); + else ShowPrompt(false, STR_N_OF_N_FILES_VERIFIED, n_success, n_marked); } else { - ShowString("%s\nVerifying file, please wait...", pathstr); + ShowString("%s\n%s", pathstr, STR_VERIFYING_FILE_PLEASE_WAIT); if (filetype & IMG_NAND) { - ShowPrompt(false, "%s\nNAND validation %s", pathstr, - (ValidateNandDump(file_path) == 0) ? "success" : "failed"); - } else ShowPrompt(false, "%s\nVerification %s", pathstr, - (VerifyGameFile(file_path) == 0) ? "success" : "failed"); + ShowPrompt(false, "%s\n%s", pathstr, (ValidateNandDump(file_path) == 0) ? STR_NAND_VALIDATION_SUCCESS : STR_NAND_VALIDATION_FAILED); + } else ShowPrompt(false, "%s\n%s", pathstr, (VerifyGameFile(file_path) == 0) ? STR_VERIFICATION_SUCCESS : STR_VERIFICATION_FAILED); } return 0; } else if (user_select == tik_dump) { // dump ticket file - if ((n_marked > 1) && ShowPrompt(true, "Dump for all %lu selected files?", n_marked)) { + if ((n_marked > 1) && ShowPrompt(true, STR_DUMP_FOR_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; u32 n_legit = 0; bool force_legit = true; @@ -1817,20 +1841,18 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan current_dir->entry[i].marked = false; } if (force_legit && (n_success != n_marked)) - if (!ShowPrompt(true, "%lu/%lu legit tickets dumped.\n \nAttempt to dump all tickets?", - n_legit, n_marked)) break; + if (!ShowPrompt(true, STR_N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL, n_legit, n_marked)) break; if (!force_legit) break; force_legit = false; } - ShowPrompt(false, "%lu/%lu tickets dumped to %s", - n_success, n_marked, OUTPUT_PATH); + ShowPrompt(false, STR_N_OF_N_TICKETS_DUMPED_TO_OUT, n_success, n_marked, OUTPUT_PATH); } else { if (DumpTicketForGameFile(file_path, true) == 0) { - ShowPrompt(false, "%s\nTicket dumped to %s", pathstr, OUTPUT_PATH); - } else if (ShowPrompt(false, "%s\nLegit ticket not found.\n \nDump anyways?", pathstr)) { + ShowPrompt(false, STR_PATH_TICKET_DUMPED_TO_OUT, pathstr, OUTPUT_PATH); + } else if (ShowPrompt(false, STR_LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS, pathstr)) { if (DumpTicketForGameFile(file_path, false) == 0) - ShowPrompt(false, "%s\nTicket dumped to %s", pathstr, OUTPUT_PATH); - else ShowPrompt(false, "%s\nDump ticket failed!"); + ShowPrompt(false, STR_PATH_TICKET_DUMPED_TO_OUT, pathstr, OUTPUT_PATH); + else ShowPrompt(false, "%s\n%s", pathstr, STR_DUMP_TICKET_FAILED); } } return 0; @@ -1839,7 +1861,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan bool dec = (user_select == tik_build_dec); const char* path_out = (dec) ? OUTPUT_PATH "/" TIKDB_NAME_DEC : OUTPUT_PATH "/" TIKDB_NAME_ENC; if (BuildTitleKeyInfo(NULL, dec, false) != 0) return 1; // init database - ShowString("Building %s...", (dec) ? TIKDB_NAME_DEC : TIKDB_NAME_ENC); + ShowString(STR_BUILDING_X, (dec) ? TIKDB_NAME_DEC : TIKDB_NAME_ENC); if (n_marked > 1) { u32 n_success = 0; u32 n_other = 0; @@ -1855,18 +1877,17 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan if (BuildTitleKeyInfo(path, dec, false) == 0) n_success++; // ignore failures for now } if (BuildTitleKeyInfo(NULL, dec, true) == 0) { - if (n_other) ShowPrompt(false, "%s\n%lu/%lu files processed\n%lu/%lu files ignored", + if (n_other) ShowPrompt(false, STR_PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED, path_out, n_success, n_marked, n_other, n_marked); - else ShowPrompt(false, "%s\n%lu/%lu files processed", path_out, n_success, n_marked); - } else ShowPrompt(false, "%s\nBuild database failed.", path_out); - } else ShowPrompt(false, "%s\nBuild database %s.", path_out, - (BuildTitleKeyInfo(file_path, dec, true) == 0) ? "success" : "failed"); + else ShowPrompt(false, STR_PATH_N_OF_N_FILES_PROCESSED, path_out, n_success, n_marked); + } else ShowPrompt(false, "%s\n%s", path_out, STR_BUILD_DATABASE_FAILED); + } else ShowPrompt(false, "%s\n%s", path_out, (BuildTitleKeyInfo(file_path, dec, true) == 0) ? STR_BUILD_DATABASE_SUCCESS : STR_BUILD_DATABASE_FAILED); return 0; } else if (user_select == key_build) { // -> (Re)Build AES key database const char* path_out = OUTPUT_PATH "/" KEYDB_NAME; if (BuildKeyDb(NULL, false) != 0) return 1; // init database - ShowString("Building %s...", KEYDB_NAME); + ShowString(STR_BUILDING_X, KEYDB_NAME); if (n_marked > 1) { u32 n_success = 0; u32 n_other = 0; @@ -1882,16 +1903,15 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan if (BuildKeyDb(path, false) == 0) n_success++; // ignore failures for now } if (BuildKeyDb(NULL, true) == 0) { - if (n_other) ShowPrompt(false, "%s\n%lu/%lu files processed\n%lu/%lu files ignored", + if (n_other) ShowPrompt(false, STR_PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED, path_out, n_success, n_marked, n_other, n_marked); - else ShowPrompt(false, "%s\n%lu/%lu files processed", path_out, n_success, n_marked); - } else ShowPrompt(false, "%s\nBuild database failed.", path_out); - } else ShowPrompt(false, "%s\nBuild database %s.", path_out, - (BuildKeyDb(file_path, true) == 0) ? "success" : "failed"); + else ShowPrompt(false, STR_PATH_N_OF_N_FILES_PROCESSED, path_out, n_success, n_marked); + } else ShowPrompt(false, "%s\n%s", path_out, STR_BUILD_DATABASE_FAILED); + } else ShowPrompt(false, "%s\n%s", path_out, (BuildKeyDb(file_path, true) == 0) ? STR_BUILD_DATABASE_SUCCESS : STR_BUILD_DATABASE_FAILED); return 0; } else if (user_select == trim) { // -> Game file trimmer - if ((n_marked > 1) && ShowPrompt(true, "Try to trim all %lu selected files?", n_marked)) { + if ((n_marked > 1) && ShowPrompt(true, STR_TRY_TO_TRIM_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; u32 n_other = 0; u32 n_processed = 0; @@ -1914,7 +1934,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan } else { // on failure: show error, continue (should not happen) char lpathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(lpathstr, path, 32, 8); - if (ShowPrompt(true, "%s\nTrimming failed\n \nContinue?", lpathstr)) { + if (ShowPrompt(true, "%s\n%s", lpathstr, STR_TRIMMING_FAILED_CONTINUE)) { ShowProgress(0, n_marked, path); // restart progress bar continue; } else break; @@ -1922,9 +1942,9 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan current_dir->entry[i].marked = false; } FormatBytes(savingsstr, savings); - if (n_other) ShowPrompt(false, "%lu/%lu files trimmed ok\n%lu/%lu not of same type\n%s saved", + if (n_other) ShowPrompt(false, STR_N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED, n_success, n_marked, n_other, n_marked, savingsstr); - else ShowPrompt(false, "%lu/%lu files trimmed ok\n%s saved", n_success, n_marked, savingsstr); + else ShowPrompt(false, STR_N_OF_N_FILES_TRIMMED_X_SAVED, n_success, n_marked, savingsstr); if (n_success) GetDirContents(current_dir, current_path); } else { u64 trimsize = GetGameFileTrimmedSize(file_path); @@ -1937,14 +1957,14 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan FormatBytes(dsizestr, currentsize - trimsize); if (!trimsize || trimsize > currentsize) { - ShowPrompt(false, "%s\nFile can't be trimmed.", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_FILE_CANT_BE_TRIMMED); } else if (trimsize == currentsize) { - ShowPrompt(false, "%s\nFile is already trimmed.", pathstr); - } else if (ShowPrompt(true, "%s\nCurrent size: %s\nTrimmed size: %s\nDifference: %s\n \nTrim this file?", + ShowPrompt(false, "%s\n%s", pathstr, STR_FILE_ALREADY_TRIMMED); + } else if (ShowPrompt(true, STR_PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE, pathstr, csizestr, tsizestr, dsizestr)) { - if (TrimGameFile(file_path) != 0) ShowPrompt(false, "%s\nTrimming failed.", pathstr); + if (TrimGameFile(file_path) != 0) ShowPrompt(false, "%s\n%s", pathstr, STR_TRIMMING_FAILED); else { - ShowPrompt(false, "%s\nTrimmed by %s.", pathstr, dsizestr); + ShowPrompt(false, STR_PATH_TRIMMED_BY_X, pathstr, dsizestr); GetDirContents(current_dir, current_path); } } @@ -1952,7 +1972,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan return 0; } else if (user_select == rename) { // -> Game file renamer - if ((n_marked > 1) && ShowPrompt(true, "Try to rename all %lu selected files?", n_marked)) { + if ((n_marked > 1) && ShowPrompt(true, STR_TRY_TO_RENAME_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; ShowProgress(0, 0, ""); for (u32 i = 0; i < current_dir->n_entries; i++) { @@ -1963,9 +1983,9 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan n_success++; current_dir->entry[i].marked = false; } - ShowPrompt(false, "%lu/%lu renamed ok", n_success, n_marked); + ShowPrompt(false, STR_N_OF_N_RENAMED, n_success, n_marked); } else if (!GoodRenamer(&(current_dir->entry[*cursor]), true)) { - ShowPrompt(false, "%s\nCould not rename to good name", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_COULD_NOT_RENAME_TO_GOOD_NAME); } return 0; } @@ -1977,22 +1997,22 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan char* destdrv[2] = { NULL }; n_opt = 0; if (DriveType("1:")) { - optionstr[n_opt] = "SysNAND H&S inject"; + optionstr[n_opt] = STR_SYSNAND_H_AND_S_INJECT; destdrv[n_opt++] = "1:"; } if (DriveType("4:")) { - optionstr[n_opt] = "EmuNAND H&S inject"; + optionstr[n_opt] = STR_EMUNAND_H_AND_S_INJECT; destdrv[n_opt++] = "4:"; } user_select = (n_opt > 1) ? (int) ShowSelectPrompt(n_opt, optionstr, "%s", pathstr) : n_opt; if (user_select) { - ShowPrompt(false, "%s\nH&S inject %s", pathstr, - (InjectHealthAndSafety(file_path, destdrv[user_select-1]) == 0) ? "success" : "failed"); + ShowPrompt(false, "%s\n%s", pathstr, (InjectHealthAndSafety(file_path, destdrv[user_select-1]) == 0) ? + STR_H_AND_S_INJECT_SUCCESS : STR_H_AND_S_INJECT_FAILURE); } return 0; } else if (user_select == extrcode) { // -> Extract .code - if ((n_marked > 1) && ShowPrompt(true, "Try to extract all %lu selected files?", n_marked)) { + if ((n_marked > 1) && ShowPrompt(true, STR_TRY_EXTRACT_ALL_N_SELECTED_FILES, n_marked)) { u32 n_success = 0; u32 n_other = 0; u32 n_processed = 0; @@ -2018,15 +2038,15 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan } current_dir->entry[i].marked = false; } - if (n_other) ShowPrompt(false, "%lu/%lu files extracted ok\n%lu/%lu not of same type", + if (n_other) ShowPrompt(false, STR_N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE, n_success, n_marked, n_other, n_marked); - else ShowPrompt(false, "%lu/%lu files extracted ok", n_success, n_marked); + else ShowPrompt(false, STR_N_OF_N_FILES_EXTRACTED, n_success, n_marked); } else { char extstr[8] = { 0 }; - ShowString("%s\nExtracting .code, please wait...", pathstr); + ShowString("%s\n%s", pathstr, STR_EXTRACTING_DOT_CODE); if (ExtractCodeFromCxiFile((filetype & GAME_TMD) ? cxi_path : file_path, NULL, extstr) == 0) { - ShowPrompt(false, "%s\n%s extracted to " OUTPUT_PATH, pathstr, extstr); - } else ShowPrompt(false, "%s\n.code extract failed", pathstr); + ShowPrompt(false, STR_PATH_EXT_EXTRACTED_TO_OUT, pathstr, extstr, OUTPUT_PATH); + } else ShowPrompt(false, "%s\n%s", pathstr, STR_DOT_CODE_EXTRACT_FAILED); } return 0; } @@ -2034,30 +2054,30 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan char* destdrv[2] = { NULL }; n_opt = 0; if (DriveType("1:")) { - optionstr[n_opt] = "Transfer to SysNAND"; + optionstr[n_opt] = STR_TRANSFER_TO_SYSNAND; destdrv[n_opt++] = "1:"; } if (DriveType("4:")) { - optionstr[n_opt] = "Transfer to EmuNAND"; + optionstr[n_opt] = STR_TRANSFER_TO_EMUNAND; destdrv[n_opt++] = "4:"; } if (n_opt) { user_select = (n_opt > 1) ? (int) ShowSelectPrompt(n_opt, optionstr, "%s", pathstr) : 1; if (user_select) { - ShowPrompt(false, "%s\nCTRNAND transfer %s", pathstr, - (TransferCtrNandImage(file_path, destdrv[user_select-1]) == 0) ? "success" : "failed"); + ShowPrompt(false, "%s\n%s", pathstr, (TransferCtrNandImage(file_path, destdrv[user_select-1]) == 0) ? + STR_CTRNAND_TRANSFER_SUCCESS: STR_CTRNAND_TRANSFER_FAILED); } - } else ShowPrompt(false, "%s\nNo valid destination found"); + } else ShowPrompt(false, "%s\n%s", pathstr, STR_NO_VALID_DESTINATION_FOUND); return 0; } else if (user_select == restore) { // -> restore SysNAND (A9LH preserving) - ShowPrompt(false, "%s\nNAND restore %s", pathstr, - (SafeRestoreNandDump(file_path) == 0) ? "success" : "failed"); + ShowPrompt(false, "%s\n%s", pathstr, (SafeRestoreNandDump(file_path) == 0) ? + STR_NAND_RESTORE_SUCCESS : STR_NAND_RESTORE_FAILED); return 0; } else if (user_select == ncsdfix) { // -> inject sighaxed NCSD - ShowPrompt(false, "%s\nRebuild NCSD %s", pathstr, - (FixNandHeader(file_path, !(filetype == HDR_NAND)) == 0) ? "success" : "failed"); + ShowPrompt(false, "%s\n%s", pathstr, (FixNandHeader(file_path, !(filetype == HDR_NAND)) == 0) ? + STR_REBUILD_NCSD_SUCCESS : STR_REBUILD_NCSD_FAILED); GetDirContents(current_dir, current_path); InitExtFS(); // this might have fixed something, so try this return 0; @@ -2065,9 +2085,8 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan else if ((user_select == xorpad) || (user_select == xorpad_inplace)) { // -> build xorpads bool inplace = (user_select == xorpad_inplace); bool success = (BuildNcchInfoXorpads((inplace) ? current_path : OUTPUT_PATH, file_path) == 0); - ShowPrompt(false, "%s\nNCCHinfo padgen %s%s", pathstr, - (success) ? "success" : "failed", - (!success || inplace) ? "" : "\nOutput dir: " OUTPUT_PATH); + ShowPrompt(false, (success) ? STR_PATH_NCCHINFO_PADGEN_SUCCESS : STR_PATH_NCCHINFO_PADGEN_FAILED, + pathstr, (!success || inplace) ? '\0' : '\n', OUTPUT_PATH); GetDirContents(current_dir, current_path); for (; *cursor < current_dir->n_entries; (*cursor)++) { DirEntry* entry = &(current_dir->entry[*cursor]); @@ -2080,35 +2099,37 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan return 0; } else if (user_select == ebackup) { // -> update embedded backup - ShowString("%s\nUpdating embedded backup...", pathstr); + ShowString("%s\n%s", pathstr, STR_UPDATING_EMBEDDED_BACKUP); bool required = (CheckEmbeddedBackup(file_path) != 0); bool success = (required && (EmbedEssentialBackup(file_path) == 0)); - ShowPrompt(false, "%s\nBackup update: %s", pathstr, (!required) ? "not required" : - (success) ? "completed" : "failed!"); + ShowPrompt(false, "%s\n%s", pathstr, (!required) ? STR_BACKUP_UPDATE_NOT_REQUIRED : + (success) ? STR_BACKUP_UPDATE_COMPLETED : STR_BACKUP_UPDATE_FAILED); GetDirContents(current_dir, current_path); return 0; } else if (user_select == keyinit) { // -> initialise keys from aeskeydb.bin - if (ShowPrompt(true, "Warning: Keys are not verified.\nContinue on your own risk?")) - ShowPrompt(false, "%s\nAESkeydb init %s", pathstr, (InitKeyDb(file_path) == 0) ? "success" : "failed"); + if (ShowPrompt(true, "%s", STR_WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK)) + ShowPrompt(false, "%s\n%s", pathstr, (InitKeyDb(file_path) == 0) ? + STR_AESKEYDB_INIT_SUCCESS : STR_AESKEYDB_INIT_FAILED); return 0; } else if (user_select == keyinstall) { // -> install keys from aeskeydb.bin - ShowPrompt(false, "%s\nAESkeydb install %s", pathstr, (SafeInstallKeyDb(file_path) == 0) ? "success" : "failed"); + ShowPrompt(false, "%s\n%s", pathstr, (SafeInstallKeyDb(file_path) == 0) ? + STR_AESKEYDB_INSTALL_SUCCESS : STR_AESKEYDB_INSTALL_FAILED); return 0; } else if (user_select == install) { // -> install FIRM size_t firm_size = FileGetSize(file_path); u32 slots = 1; if (GetNandPartitionInfo(NULL, NP_TYPE_FIRM, NP_SUBTYPE_CTR, 1, NAND_SYSNAND) == 0) { - optionstr[0] = "Install to FIRM0"; - optionstr[1] = "Install to FIRM1"; - optionstr[2] = "Install to both"; + optionstr[0] = STR_INSTALL_TO_FIRM0; + optionstr[1] = STR_INSTALL_TO_FIRM1; + optionstr[2] = STR_INSTALL_TO_BOTH; // this only works up to FIRM1 - slots = ShowSelectPrompt(3, optionstr, "%s (%dkB)\nInstall to SysNAND?", pathstr, firm_size / 1024); - } else slots = ShowPrompt(true, "%s (%dkB)\nInstall to SysNAND?", pathstr, firm_size / 1024) ? 1 : 0; - if (slots) ShowPrompt(false, "%s (%dkB)\nInstall %s", pathstr, firm_size / 1024, - (SafeInstallFirm(file_path, slots) == 0) ? "success" : "failed!"); + slots = ShowSelectPrompt(3, optionstr, STR_PATH_N_KB_INSTALL_TO_SYSNAND, pathstr, firm_size / 1024); + } else slots = ShowPrompt(true, STR_PATH_N_KB_INSTALL_TO_SYSNAND, pathstr, firm_size / 1024) ? 1 : 0; + if (slots) ShowPrompt(false, (SafeInstallFirm(file_path, slots) == 0) ? + STR_PATH_N_KB_INSTALL_SUCCESS : STR_PATH_N_KB_INSTALL_FAILED, pathstr, firm_size / 1024); return 0; } else if (user_select == boot) { // -> boot FIRM @@ -2116,8 +2137,8 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan return 0; } else if (user_select == script) { // execute script - if (ShowPrompt(true, "%s\nWarning: Do not run scripts\nfrom untrusted sources.\n \nExecute script?", pathstr)) - ShowPrompt(false, "%s\nScript execute %s", pathstr, ExecuteGM9Script(file_path) ? "success" : "failure"); + if (ShowPrompt(true, "%s\n%s", pathstr, STR_WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS)) + ShowPrompt(false, "%s\n%s", pathstr, ExecuteGM9Script(file_path) ? STR_SCRIPT_EXECUTE_SUCCESS : STR_SCRIPT_EXECUTE_FAILURE); GetDirContents(current_dir, current_path); ClearScreenF(true, true, COLOR_STD_BG); return 0; @@ -2131,23 +2152,32 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan free(font); return 0; } + else if (user_select == translation) { // set translation + u8* translation = (u8*) malloc(0x20000); // arbitrary, should be enough by far + if (!translation) return 1; + u32 translation_size = FileGetData(file_path, translation, 0x20000, 0); + if (translation_size) SetLanguage(translation, translation_size); + ClearScreenF(true, true, COLOR_STD_BG); + free(translation); + return 0; + } else if (user_select == view) { // view gfx if (FileGraphicsViewer(file_path) != 0) - ShowPrompt(false, "%s\nError: Cannot view file\n(Hint: maybe it's too big)", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_CANNOT_VIEW_FILE); return 0; } else if (user_select == agbexport) { // export GBA VC save if (DumpGbaVcSavegame(file_path) == 0) - ShowPrompt(false, "Savegame dumped to " OUTPUT_PATH "."); - else ShowPrompt(false, "Savegame dump failed!"); + ShowPrompt(false, STR_SAVEGAME_DUMPED_TO_OUT, OUTPUT_PATH); + else ShowPrompt(false, "%s", STR_SAVEGAME_DUMP_FAILED); return 0; } else if (user_select == agbimport) { // import GBA VC save if (clipboard->n_entries != 1) { - ShowPrompt(false, "GBA VC savegame has to\nbe in the clipboard."); + ShowPrompt(false, "%s", STR_GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD); } else { - ShowPrompt(false, "Savegame inject %s.", - (InjectGbaVcSavegame(file_path, clipboard->entry[0].path) == 0) ? "success" : "failed!"); + ShowPrompt(false, "%s", + (InjectGbaVcSavegame(file_path, clipboard->entry[0].path) == 0) ? STR_SAVEGAME_INJECT_SUCCESS : STR_SAVEGAME_INJECT_FAILED); clipboard->n_entries = 0; } return 0; @@ -2155,10 +2185,13 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan else if (user_select == setup) { // set as default (font) if (filetype & FONT_RIFF) { if (SetAsSupportFile("font.frf", file_path)) - ShowPrompt(false, "%s\nFont will be active on next boot", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT); } else if (filetype & FONT_PBM) { if (SetAsSupportFile("font.pbm", file_path)) - ShowPrompt(false, "%s\nFont will be active on next boot", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT); + } else if (filetype & TRANSLATION) { + if (SetAsSupportFile("language.trf", file_path)) + ShowPrompt(false, "%s\n%s", pathstr, STR_LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT); } return 0; } @@ -2171,7 +2204,7 @@ u32 HomeMoreMenu(char* current_path) { if (GetNandPartitionInfo(&np_info, NP_TYPE_BONUS, NP_SUBTYPE_CTR, 0, NAND_SYSNAND) != 0) np_info.count = 0; const char* optionstr[8]; - const char* promptstr = "HOME more... menu.\nSelect action:"; + const char* promptstr = STR_HOME_MORE_MENU_SELECT_ACTION; u32 n_opt = 0; int sdformat = ++n_opt; int bonus = (np_info.count > 0x2000) ? (int) ++n_opt : -1; // 4MB minsize @@ -2184,18 +2217,18 @@ u32 HomeMoreMenu(char* current_path) { int sysinfo = ++n_opt; int readme = (FindVTarFileInfo(VRAM0_README_MD, NULL)) ? (int) ++n_opt : -1; - if (sdformat > 0) optionstr[sdformat - 1] = "SD format menu"; - if (bonus > 0) optionstr[bonus - 1] = "Bonus drive setup"; - if (multi > 0) optionstr[multi - 1] = "Switch EmuNAND"; - if (bsupport > 0) optionstr[bsupport - 1] = "Build support files"; - if (hsrestore > 0) optionstr[hsrestore - 1] = "Restore H&S"; - if (clock > 0) optionstr[clock - 1] = "Set RTC date&time"; - if (bright > 0) optionstr[bright - 1] = "Configure brightness"; - if (calib > 0) optionstr[calib - 1] = "Calibrate touchscreen"; - if (sysinfo > 0) optionstr[sysinfo - 1] = "System info"; - if (readme > 0) optionstr[readme - 1] = "Show ReadMe"; - - int user_select = ShowSelectPrompt(n_opt, optionstr, promptstr); + if (sdformat > 0) optionstr[sdformat - 1] = STR_SD_FORMAT_MENU; + if (bonus > 0) optionstr[bonus - 1] = STR_BONUS_DRIVE_MENU; + if (multi > 0) optionstr[multi - 1] = STR_SWITCH_EMUNAND; + if (bsupport > 0) optionstr[bsupport - 1] = STR_BUILD_SUPPORT_FILES; + if (hsrestore > 0) optionstr[hsrestore - 1] = STR_RESTORE_H_AND_S; + if (clock > 0) optionstr[clock - 1] = STR_SET_RTC_DATE_TIME; + if (bright > 0) optionstr[bright - 1] = STR_CONFGURE_BRIGHTNESS; + if (calib > 0) optionstr[calib - 1] = STR_CALIBRATE_TOUCHSCREEN; + if (sysinfo > 0) optionstr[sysinfo - 1] = STR_SYSTEM_INFO; + if (readme > 0) optionstr[readme - 1] = STR_SHOW_README; + + int user_select = ShowSelectPrompt(n_opt, optionstr, "%s", promptstr); if (user_select == sdformat) { // format SD card bool sd_state = CheckSDMountState(); char slabel[DRV_LABEL_LEN] = { '\0' }; @@ -2206,7 +2239,7 @@ u32 HomeMoreMenu(char* current_path) { DeinitSDCardFS(); if ((SdFormatMenu(slabel) == 0) || sd_state) {; while (!InitSDCardFS() && - ShowPrompt(true, "Initializing SD card failed! Retry?")); + ShowPrompt(true, "%s", STR_INITIALIZING_SD_FAILED_RETRY)); } ClearScreenF(true, true, COLOR_STD_BG); AutoEmuNandBase(true); @@ -2217,13 +2250,13 @@ u32 HomeMoreMenu(char* current_path) { else if (user_select == bonus) { // setup bonus drive if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & (DRV_BONUS|DRV_IMAGE))) clipboard->n_entries = 0; // remove bonus drive clipboard entries - if (!SetupBonusDrive()) ShowPrompt(false, "Setup failed!"); + if (!SetupBonusDrive()) ShowPrompt(false, "%s", STR_SETUP_FAILED); ClearScreenF(true, true, COLOR_STD_BG); GetDirContents(current_dir, current_path); return 0; } else if (user_select == multi) { // switch EmuNAND offset - while (ShowPrompt(true, "Current EmuNAND offset is %06X.\nSwitch to next offset?", GetEmuNandBase())) { + while (ShowPrompt(true, STR_CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT, GetEmuNandBase())) { if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & DRV_EMUNAND)) clipboard->n_entries = 0; // remove EmuNAND clipboard entries DismountDriveType(DRV_EMUNAND); @@ -2237,9 +2270,9 @@ u32 HomeMoreMenu(char* current_path) { bool tik_enc_sys = false; bool tik_enc_emu = false; if (BuildTitleKeyInfo(NULL, false, false) == 0) { - ShowString("Building " TIKDB_NAME_ENC " (SysNAND)..."); + ShowString(STR_BUILDING_X_SYSNAND, TIKDB_NAME_ENC); tik_enc_sys = (BuildTitleKeyInfo("1:/dbs/ticket.db", false, false) == 0); - ShowString("Building " TIKDB_NAME_ENC " (EmuNAND)..."); + ShowString(STR_BUILDING_X_EMUNAND, TIKDB_NAME_ENC); tik_enc_emu = (BuildTitleKeyInfo("4:/dbs/ticket.db", false, false) == 0); if (!tik_enc_sys || BuildTitleKeyInfo(NULL, false, true) != 0) tik_enc_sys = tik_enc_emu = false; @@ -2247,9 +2280,9 @@ u32 HomeMoreMenu(char* current_path) { bool tik_dec_sys = false; bool tik_dec_emu = false; if (BuildTitleKeyInfo(NULL, true, false) == 0) { - ShowString("Building " TIKDB_NAME_DEC " (SysNAND)..."); + ShowString(STR_BUILDING_X_SYSNAND, TIKDB_NAME_DEC); tik_dec_sys = (BuildTitleKeyInfo("1:/dbs/ticket.db", true, false) == 0); - ShowString("Building " TIKDB_NAME_DEC " (EmuNAND)..."); + ShowString(STR_BUILDING_X_EMUNAND, TIKDB_NAME_DEC); tik_dec_emu = (BuildTitleKeyInfo("4:/dbs/ticket.db", true, false) == 0); if (!tik_dec_sys || BuildTitleKeyInfo(NULL, true, true) != 0) tik_dec_sys = tik_dec_emu = false; @@ -2257,17 +2290,17 @@ u32 HomeMoreMenu(char* current_path) { bool seed_sys = false; bool seed_emu = false; if (BuildSeedInfo(NULL, false) == 0) { - ShowString("Building " SEEDINFO_NAME " (SysNAND)..."); + ShowString(STR_BUILDING_X_SYSNAND, SEEDINFO_NAME); seed_sys = (BuildSeedInfo("1:", false) == 0); - ShowString("Building " SEEDINFO_NAME " (EmuNAND)..."); + ShowString(STR_BUILDING_X_EMUNAND, SEEDINFO_NAME); seed_emu = (BuildSeedInfo("4:", false) == 0); if (!seed_sys || BuildSeedInfo(NULL, true) != 0) seed_sys = seed_emu = false; } - ShowPrompt(false, "Built in " OUTPUT_PATH ":\n \n%18.18-s %s\n%18.18-s %s\n%18.18-s %s", - TIKDB_NAME_ENC, tik_enc_sys ? tik_enc_emu ? "OK (Sys&Emu)" : "OK (Sys)" : "Failed", - TIKDB_NAME_DEC, tik_dec_sys ? tik_dec_emu ? "OK (Sys&Emu)" : "OK (Sys)" : "Failed", - SEEDINFO_NAME, seed_sys ? seed_emu ? "OK (Sys&Emu)" : "OK (Sys)" : "Failed"); + ShowPrompt(false, STR_BUILT_IN_OUT_STATUSES, OUTPUT_PATH, + TIKDB_NAME_ENC, tik_enc_sys ? tik_enc_emu ? STR_OK_SYS_EMU : STR_OK_SYS : STR_FAILED, + TIKDB_NAME_DEC, tik_dec_sys ? tik_dec_emu ? STR_OK_SYS_EMU : STR_OK_SYS : STR_FAILED, + SEEDINFO_NAME, seed_sys ? seed_emu ? STR_OK_SYS_EMU : STR_OK_SYS : STR_FAILED); GetDirContents(current_dir, current_path); return 0; } @@ -2275,9 +2308,9 @@ u32 HomeMoreMenu(char* current_path) { n_opt = 0; int sys = (CheckHealthAndSafetyInject("1:") == 0) ? (int) ++n_opt : -1; int emu = (CheckHealthAndSafetyInject("4:") == 0) ? (int) ++n_opt : -1; - if (sys > 0) optionstr[sys - 1] = "Restore H&S (SysNAND)"; - if (emu > 0) optionstr[emu - 1] = "Restore H&S (EmuNAND)"; - user_select = (n_opt > 1) ? ShowSelectPrompt(n_opt, optionstr, promptstr) : n_opt; + if (sys > 0) optionstr[sys - 1] = STR_RESTORE_H_AND_S_EMUNAND; + if (emu > 0) optionstr[emu - 1] = STR_RESTORE_H_AND_S_SYSNAND; + user_select = (n_opt > 1) ? ShowSelectPrompt(n_opt, optionstr, "%s", promptstr) : n_opt; if (user_select > 0) { InjectHealthAndSafety(NULL, (user_select == sys) ? "1:" : "4:"); GetDirContents(current_dir, current_path); @@ -2287,12 +2320,11 @@ u32 HomeMoreMenu(char* current_path) { else if (user_select == clock) { // RTC clock setter DsTime dstime; get_dstime(&dstime); - if (ShowRtcSetterPrompt(&dstime, "Set RTC date&time:")) { - char timestr[32]; + if (ShowRtcSetterPrompt(&dstime, "%s", STR_TITLE_SET_RTC_DATE_TIME)) { + char timestr[UTF_BUFFER_BYTESIZE(32)]; set_dstime(&dstime); GetTimeString(timestr, true, true); - ShowPrompt(false, "New RTC date&time is:\n%s\n \nHint: HOMEMENU time needs\nmanual adjustment after\nsetting the RTC.", - timestr); + ShowPrompt(false, STR_NEW_RTC_DATE_TIME_IS_TIME, timestr); } return 0; } @@ -2306,8 +2338,8 @@ u32 HomeMoreMenu(char* current_path) { return 0; } else if (user_select == calib) { // touchscreen calibration - ShowPrompt(false, "Touchscreen calibration %s!", - (ShowTouchCalibrationDialog()) ? "success" : "failed"); + ShowPrompt(false, "%s", + (ShowTouchCalibrationDialog()) ? STR_TOUCHSCREEN_CALIBRATION_SUCCESS : STR_TOUCHSCREEN_CALIBRATION_FAILED); return 0; } else if (user_select == sysinfo) { // Myria's system info @@ -2321,7 +2353,7 @@ u32 HomeMoreMenu(char* current_path) { else if (user_select == readme) { // Display GodMode9 readme u64 README_md_size; char* README_md = FindVTarFileInfo(VRAM0_README_MD, &README_md_size); - MemToCViewer(README_md, README_md_size, "GodMode9 ReadMe Table of Contents"); + MemToCViewer(README_md, README_md_size, STR_GODMODE9_README_TOC); return 0; } else return 1; @@ -2406,14 +2438,57 @@ u32 GodMode(int entrypoint) { } } + // language handling + bool language_loaded = false; + if (CheckSupportFile("language.trf")) { + char* translation = (char*) malloc(0x20000); // arbitrary, should be enough by far + if (translation) { + u32 translation_size = LoadSupportFile("language.trf", translation, 0x20000); + if (translation_size) language_loaded = SetLanguage(translation, translation_size); + free(translation); + } + } + + if (!language_loaded) { + SetLanguage(NULL, 0); + + char loadpath[256]; + if (LanguageMenu(loadpath, "Select Language for GodMode9:")) { + size_t fsize = FileGetSize(loadpath); + if (fsize > 0) { + char* data = (char*)malloc(fsize); + if (data) { + FileGetData(loadpath, data, fsize, 0); + SaveSupportFile("language.trf", data, fsize); + SetLanguage(data, fsize); + free(data); + } + } + + // Try load font with the same name + char *ext = strstr(loadpath, ".trf"); + strcpy(ext, ".frf"); + fsize = FileGetSize(loadpath); + if (fsize > 0) { + char* data = (char*)malloc(fsize); + if (data) { + FileGetData(loadpath, data, fsize, 0); + SaveSupportFile("font.frf", data, fsize); + SetFont(data, fsize); + free(data); + } + } + } + } + // check for embedded essential backup if (((entrypoint == ENTRY_NANDBOOT) || (entrypoint == ENTRY_B9S)) && !PathExist("S:/essential.exefs") && CheckGenuineNandNcsd() && - ShowPrompt(true, "Essential files backup not found.\nCreate one now?")) { + ShowPrompt(true, "%s", STR_ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW)) { if (EmbedEssentialBackup("S:/nand.bin") == 0) { u32 flags = BUILD_PATH | SKIP_ALL; PathCopy(OUTPUT_PATH, "S:/essential.exefs", &flags); - ShowPrompt(false, "Backup embedded in SysNAND\nand written to " OUTPUT_PATH "."); + ShowPrompt(false, STR_BACKUP_EMBEDDED_WRITTEN_TO_OUT, OUTPUT_PATH); } } @@ -2422,12 +2497,12 @@ u32 GodMode(int entrypoint) { DsTime dstime; get_dstime(&dstime); if ((DSTIMEGET(&dstime, bcd_Y) < 18) && - ShowPrompt(true, "RTC date&time seems to be\nwrong. Set it now?") && - ShowRtcSetterPrompt(&dstime, "Set RTC date&time:")) { - char timestr[32]; + ShowPrompt(true, "%s", STR_RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW) && + ShowRtcSetterPrompt(&dstime, "%s", STR_TITLE_SET_RTC_DATE_TIME)) { + char timestr[UTF_BUFFER_BYTESIZE(32)]; set_dstime(&dstime); GetTimeString(timestr, true, true); - ShowPrompt(false, "New RTC date&time is:\n%s\n \nHint: HOMEMENU time needs\nmanual adjustment after\nsetting the RTC.", timestr); + ShowPrompt(false, STR_NEW_RTC_DATE_TIME_IS_TIME, timestr); } } @@ -2445,17 +2520,17 @@ u32 GodMode(int entrypoint) { bootloader = false; while (HID_ReadState() & BUTTON_ANY); // wait until no buttons are pressed while (!bootloader && !godmode9) { - const char* optionstr[6] = { "Resume GodMode9", "Resume bootloader", "Select payload...", "Select script...", - "Poweroff system", "Reboot system" }; - int user_select = ShowSelectPrompt(6, optionstr, FLAVOR " bootloader menu.\nSelect action:"); + const char* optionstr[6] = { STR_RESUME_GODMODE9, STR_RESUME_BOOTLOADER, STR_SELECT_PAYLOAD, STR_SELECT_SCRIPT, + STR_POWEROFF_SYSTEM, STR_REBOOT_SYSTEM }; + int user_select = ShowSelectPrompt(6, optionstr, STR_FLAVOR_BOOTLOADER_SELECT_OPTION, FLAVOR); char loadpath[256]; if (user_select == 1) { godmode9 = true; } else if (user_select == 2) { bootloader = true; - } else if ((user_select == 3) && (FileSelectorSupport(loadpath, "Bootloader payloads menu.\nSelect payload:", PAYLOADS_DIR, "*.firm"))) { + } else if ((user_select == 3) && (FileSelectorSupport(loadpath, STR_BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD, PAYLOADS_DIR, "*.firm"))) { BootFirmHandler(loadpath, false, false); - } else if ((user_select == 4) && (FileSelectorSupport(loadpath, "Bootloader scripts menu.\nSelect script:", SCRIPTS_DIR, "*.gm9"))) { + } else if ((user_select == 4) && (FileSelectorSupport(loadpath, STR_BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT, SCRIPTS_DIR, "*.gm9"))) { ExecuteGM9Script(loadpath); } else if (user_select == 5) { exit_mode = GODMODE_EXIT_POWEROFF; @@ -2470,13 +2545,16 @@ u32 GodMode(int entrypoint) { if (bootloader) { const char* bootfirm_paths[] = { BOOTFIRM_PATHS }; if (IsBootableFirm(firm_in_mem, FIRM_MAX_SIZE)) { + DeinitExtFS(); + DeinitSDCardFS(); + PXI_DoCMD(PXICMD_LEGACY_BOOT, NULL, 0); PXI_Barrier(PXI_FIRMLAUNCH_BARRIER); BootFirm(firm_in_mem, "sdmc:/bootonce.firm"); } for (u32 i = 0; i < sizeof(bootfirm_paths) / sizeof(char*); i++) { BootFirmHandler(bootfirm_paths[i], false, (BOOTFIRM_TEMPS >> i) & 0x1); } - ShowPrompt(false, "No bootable FIRM found.\nNow resuming GodMode9..."); + ShowPrompt(false, "%s", STR_NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9); godmode9 = true; } @@ -2485,7 +2563,7 @@ u32 GodMode(int entrypoint) { clipboard = (DirStruct*) malloc(sizeof(DirStruct)); panedata = (PaneData*) malloc(N_PANES * sizeof(PaneData)); if (!current_dir || !clipboard || !panedata) { - ShowPrompt(false, "Out of memory."); // just to be safe + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); // just to be safe return exit_mode; } @@ -2499,7 +2577,7 @@ u32 GodMode(int entrypoint) { while (godmode9) { // this is the main loop // basic sanity checking if (!current_dir->n_entries) { // current dir is empty -> revert to root - ShowPrompt(false, "Invalid directory object"); + ShowPrompt(false, "%s", STR_INVALID_DIRECTORY_OBJECT); *current_path = '\0'; SetTitleManagerMode(false); DeinitExtFS(); // deinit and... @@ -2507,7 +2585,7 @@ u32 GodMode(int entrypoint) { GetDirContents(current_dir, current_path); cursor = 0; if (!current_dir->n_entries) { // should not happen, if it does fail gracefully - ShowPrompt(false, "Invalid root directory."); + ShowPrompt(false, "%s", STR_INVALID_ROOT_DIRECTORY); return exit_mode; } } @@ -2526,7 +2604,7 @@ u32 GodMode(int entrypoint) { // check write permissions if (~last_write_perm & GetWritePermissions()) { - if (ShowPrompt(true, "Write permissions were changed.\nRelock them?")) SetWritePermissions(last_write_perm, false); + if (ShowPrompt(true, "%s", STR_WRITE_PERMISSIONS_WERE_CHANGED_RELOCK)) SetWritePermissions(last_write_perm, false); last_write_perm = GetWritePermissions(); continue; } @@ -2539,8 +2617,10 @@ u32 GodMode(int entrypoint) { if ((pad_state & BUTTON_A) && (curr_entry->type != T_FILE) && (curr_entry->type != T_DOTDOT)) { // for dirs if (switched && !(DriveType(curr_entry->path) & (DRV_SEARCH|DRV_TITLEMAN))) { // exclude Y/Z const char* optionstr[8] = { NULL }; - char tpath[16] = { 0 }; - snprintf(tpath, 16, "%2.2s/dbs/title.db", curr_entry->path); + char tpath[16], copyToOut[UTF_BUFFER_BYTESIZE(64)], dumpToOut[UTF_BUFFER_BYTESIZE(64)]; + snprintf(tpath, sizeof(tpath), "%2.2s/dbs/title.db", curr_entry->path); + snprintf(copyToOut, sizeof(copyToOut), STR_COPY_TO_OUT, OUTPUT_PATH); + snprintf(dumpToOut, sizeof(dumpToOut), STR_DUMP_TO_OUT, OUTPUT_PATH); int n_opt = 0; int tman = (!(DriveType(curr_entry->path) & DRV_IMAGE) && ((strncmp(curr_entry->path, tpath, 16) == 0) || @@ -2551,43 +2631,41 @@ u32 GodMode(int entrypoint) { int dirnfo = ++n_opt; int stdcpy = (*current_path && strncmp(current_path, OUTPUT_PATH, 256) != 0) ? ++n_opt : -1; int rawdump = (!*current_path && (DriveType(curr_entry->path) & DRV_CART)) ? ++n_opt : -1; - if (tman > 0) optionstr[tman-1] = "Open title manager"; - if (srch_f > 0) optionstr[srch_f-1] = "Search for files..."; - if (fixcmac > 0) optionstr[fixcmac-1] = "Fix CMACs for drive"; - if (dirnfo > 0) optionstr[dirnfo-1] = (*current_path) ? "Show directory info" : "Show drive info"; - if (stdcpy > 0) optionstr[stdcpy-1] = "Copy to " OUTPUT_PATH; - if (rawdump > 0) optionstr[rawdump-1] = "Dump to " OUTPUT_PATH; + if (tman > 0) optionstr[tman-1] = STR_OPEN_TITLE_MANAGER; + if (srch_f > 0) optionstr[srch_f-1] = STR_SEARCH_FOR_FILES; + if (fixcmac > 0) optionstr[fixcmac-1] = STR_FIX_CMACS_FOR_DRIVE; + if (dirnfo > 0) optionstr[dirnfo-1] = (*current_path) ? STR_SHOW_DIRECTORY_INFO : STR_SHOW_DRIVE_INFO; + if (stdcpy > 0) optionstr[stdcpy-1] = copyToOut; + if (rawdump > 0) optionstr[rawdump-1] = dumpToOut; char namestr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(namestr, (*current_path) ? curr_entry->path : curr_entry->name, 32, 8); int user_select = ShowSelectPrompt(n_opt, optionstr, "%s", namestr); if (user_select == tman) { if (InitImgFS(tpath)) { SetTitleManagerMode(true); - snprintf(current_path, 256, "Y:"); + snprintf(current_path, sizeof(current_path), "Y:"); GetDirContents(current_dir, current_path); cursor = 1; scroll = 0; - } else ShowPrompt(false, "Failed setting up title manager!"); + } else ShowPrompt(false, "%s", STR_FAILED_SETTING_UP_TITLE_MANAGER); } else if (user_select == srch_f) { char searchstr[256]; - snprintf(searchstr, 256, "*"); + snprintf(searchstr, sizeof(searchstr), "*"); TruncateString(namestr, curr_entry->name, 20, 8); - if (ShowKeyboardOrPrompt(searchstr, 256, "Search %s?\nEnter search below.", namestr)) { + if (ShowKeyboardOrPrompt(searchstr, 256, STR_SEARCH_FILE_ENTER_SEARCH_BELOW, namestr)) { SetFSSearch(searchstr, curr_entry->path); - snprintf(current_path, 256, "Z:"); + snprintf(current_path, sizeof(current_path), "Z:"); GetDirContents(current_dir, current_path); - if (current_dir->n_entries) ShowPrompt(false, "Found %lu results.", current_dir->n_entries - 1); + if (current_dir->n_entries) ShowPrompt(false, STR_FOUND_N_RESULTS, current_dir->n_entries - 1); cursor = 1; scroll = 0; } } else if (user_select == fixcmac) { RecursiveFixFileCmac(curr_entry->path); - ShowPrompt(false, "Fix CMACs for drive finished."); + ShowPrompt(false, "%s", STR_FIX_CMACS_FOR_DRIVE_FINISHED); } else if (user_select == dirnfo) { if (DirFileAttrMenu(curr_entry->path, curr_entry->name)) { - ShowPrompt(false, "Failed to analyze %s\n", - (current_path[0] == '\0') ? "drive" : "dir" - ); + ShowPrompt(false, "%s",(current_path[0] == '\0') ? STR_FAILED_TO_ANALYZE_DRIVE : STR_FAILED_TO_ANALYZE_DIR); } } else if (user_select == stdcpy) { StandardCopy(&cursor, &scroll); @@ -2597,7 +2675,7 @@ u32 GodMode(int entrypoint) { } else { // one level up u32 user_select = 1; if (curr_drvtype & DRV_SEARCH) { // special menu for search drive - static const char* optionstr[2] = { "Open this folder", "Open containing folder" }; + const char* optionstr[2] = { STR_OPEN_THIS_FOLDER, STR_OPEN_CONTAINING_FOLDER }; char pathstr[UTF_BUFFER_BYTESIZE(32)]; TruncateString(pathstr, curr_entry->path, 32, 8); user_select = ShowSelectPrompt(2, optionstr, "%s", pathstr); @@ -2644,7 +2722,7 @@ u32 GodMode(int entrypoint) { } else if (switched && (pad_state & BUTTON_B)) { // unmount SD card if (!CheckSDMountState()) { while (!InitSDCardFS() && - ShowPrompt(true, "Initialising SD card failed! Retry?")); + ShowPrompt(true, "%s", STR_INITIALIZING_SD_FAILED_RETRY)); } else { DeinitSDCardFS(); if (clipboard->n_entries && !PathExist(clipboard->entry[0].path)) @@ -2711,7 +2789,7 @@ u32 GodMode(int entrypoint) { } } else if (!switched) { // standard unswitched command set if ((curr_drvtype & DRV_VIRTUAL) && (pad_state & BUTTON_X) && (*current_path != 'T')) { - ShowPrompt(false, "Not allowed in virtual path"); + ShowPrompt(false, "%s", STR_NOT_ALLOWED_IN_VIRTUAL_PATH); } else if (pad_state & BUTTON_X) { // delete a file u32 n_marked = 0; if (curr_entry->marked) { @@ -2719,22 +2797,22 @@ u32 GodMode(int entrypoint) { if (current_dir->entry[c].marked) n_marked++; } if (n_marked) { - if (ShowPrompt(true, "Delete %u path(s)?", n_marked)) { + if (ShowPrompt(true, STR_DELETE_N_PATHS, n_marked)) { u32 n_errors = 0; - ShowString("Deleting files, please wait..."); + ShowString("%s", STR_DELETING_FILES_PLEASE_WAIT); for (u32 c = 0; c < current_dir->n_entries; c++) if (current_dir->entry[c].marked && !PathDelete(current_dir->entry[c].path)) n_errors++; ClearScreenF(true, false, COLOR_STD_BG); - if (n_errors) ShowPrompt(false, "Failed deleting %u/%u path(s)", n_errors, n_marked); + if (n_errors) ShowPrompt(false, STR_FAILED_DELETING_N_OF_N_PATHS, n_errors, n_marked); } } else if (curr_entry->type != T_DOTDOT) { char namestr[UTF_BUFFER_BYTESIZE(28)]; TruncateString(namestr, curr_entry->name, 28, 12); - if (ShowPrompt(true, "Delete \"%s\"?", namestr)) { - ShowString("Deleting files, please wait..."); + if (ShowPrompt(true, STR_DELETE_FILE, namestr)) { + ShowString("%s", STR_DELETING_FILES_PLEASE_WAIT); if (!PathDelete(curr_entry->path)) - ShowPrompt(false, "Failed deleting:\n%s", namestr); + ShowPrompt(false, STR_FAILED_DELETING_PATH, namestr); ClearScreenF(true, false, COLOR_STD_BG); } } @@ -2754,23 +2832,23 @@ u32 GodMode(int entrypoint) { if (clipboard->n_entries) last_clipboard_size = clipboard->n_entries; } else if ((curr_drvtype & DRV_SEARCH) && (pad_state & BUTTON_Y)) { - ShowPrompt(false, "Not allowed in search drive"); + ShowPrompt(false, "%s", STR_NOT_ALLOWED_IN_SEARCH_DRIVE); } else if ((curr_drvtype & DRV_GAME) && (pad_state & BUTTON_Y)) { - ShowPrompt(false, "Not allowed in virtual game path"); + ShowPrompt(false, "%s", STR_NOT_ALLOWED_IN_VIRTUAL_GAME_PATH); } else if ((curr_drvtype & DRV_XORPAD) && (pad_state & BUTTON_Y)) { - ShowPrompt(false, "Not allowed in XORpad drive"); + ShowPrompt(false, "%s", STR_NOT_ALLOWED_IN_XORPAD_DRIVE); } else if ((curr_drvtype & DRV_CART) && (pad_state & BUTTON_Y)) { - ShowPrompt(false, "Not allowed in gamecart drive"); + ShowPrompt(false, "%s", STR_NOT_ALLOWED_IN_GAMECART_DRIVE); } else if (pad_state & BUTTON_Y) { // paste files - static const char* optionstr[2] = { "Copy path(s)", "Move path(s)" }; - char promptstr[64]; + const char* optionstr[2] = { STR_COPY_PATHS, STR_MOVE_PATHS }; + char promptstr[UTF_BUFFER_BYTESIZE(64)]; u32 flags = 0; u32 user_select; if (clipboard->n_entries == 1) { char namestr[UTF_BUFFER_BYTESIZE(20)]; TruncateString(namestr, clipboard->entry[0].name, 20, 12); - snprintf(promptstr, 64, "Paste \"%s\" here?", namestr); - } else snprintf(promptstr, 64, "Paste %lu paths here?", clipboard->n_entries); + snprintf(promptstr, sizeof(promptstr), STR_PASTE_FILE_HERE, namestr); + } else snprintf(promptstr, sizeof(promptstr), STR_PASTE_N_PATHS_HERE, clipboard->n_entries); user_select = ((DriveType(clipboard->entry[0].path) & curr_drvtype & DRV_STDFAT)) ? ShowSelectPrompt(2, optionstr, "%s", promptstr) : (ShowPrompt(true, "%s", promptstr) ? 1 : 0); if (user_select) { @@ -2781,12 +2859,12 @@ u32 GodMode(int entrypoint) { if (c < clipboard->n_entries - 1) flags |= ASK_ALL; if ((user_select == 1) && !PathCopy(current_path, clipboard->entry[c].path, &flags)) { if (c + 1 < clipboard->n_entries) { - if (!ShowPrompt(true, "Failed copying path:\n%s\nProcess remaining?", namestr)) break; - } else ShowPrompt(false, "Failed copying path:\n%s", namestr); + if (!ShowPrompt(true, STR_FAILED_COPYING_PATH_PROCESS_REMAINING, namestr)) break; + } else ShowPrompt(false, STR_FAILED_COPYING_PATH, namestr); } else if ((user_select == 2) && !PathMove(current_path, clipboard->entry[c].path, &flags)) { if (c + 1 < clipboard->n_entries) { - if (!ShowPrompt(true, "Failed moving path:\n%s\nProcess remaining?", namestr)) break; - } else ShowPrompt(false, "Failed moving path:\n%s", namestr); + if (!ShowPrompt(true, STR_FAILED_MOVING_PATH_PROCESS_REMAINING, namestr)) break; + } else ShowPrompt(false, STR_FAILED_MOVING_PATH, namestr); } } clipboard->n_entries = 0; @@ -2796,17 +2874,17 @@ u32 GodMode(int entrypoint) { } } else { // switched command set if ((curr_drvtype & DRV_VIRTUAL) && (pad_state & (BUTTON_X|BUTTON_Y))) { - ShowPrompt(false, "Not allowed in virtual path"); + ShowPrompt(false, "%s", STR_NOT_ALLOWED_IN_VIRTUAL_PATH); } else if ((curr_drvtype & DRV_ALIAS) && (pad_state & (BUTTON_X))) { - ShowPrompt(false, "Not allowed in alias path"); + ShowPrompt(false, "%s", STR_NOT_ALLOWED_IN_ALIAS_PATH); } else if ((pad_state & BUTTON_X) && (curr_entry->type != T_DOTDOT)) { // rename a file char newname[256]; char namestr[UTF_BUFFER_BYTESIZE(20)]; TruncateString(namestr, curr_entry->name, 20, 12); - snprintf(newname, 255, "%s", curr_entry->name); - if (ShowKeyboardOrPrompt(newname, 256, "Rename %s?\nEnter new name below.", namestr)) { + snprintf(newname, sizeof(newname), "%s", curr_entry->name); + if (ShowKeyboardOrPrompt(newname, 256, STR_RENAME_FILE_ENTER_NEW_NAME_BELOW, namestr)) { if (!PathRename(curr_entry->path, newname)) - ShowPrompt(false, "Failed renaming path:\n%s", namestr); + ShowPrompt(false, STR_FAILED_RENAMING_PATH, namestr); else { GetDirContents(current_dir, current_path); for (cursor = (current_dir->n_entries) ? current_dir->n_entries - 1 : 0; @@ -2814,20 +2892,19 @@ u32 GodMode(int entrypoint) { } } } else if (pad_state & BUTTON_Y) { // create an entry - static const char* optionstr[] = { "Create a folder", "Create a dummy file" }; - u32 type = ShowSelectPrompt(2, optionstr, "Create a new entry here?\nSelect type."); + const char* optionstr[] = { STR_CREATE_A_FOLDER, STR_CREATE_A_DUMMY_FILE }; + u32 type = ShowSelectPrompt(2, optionstr, "%s", STR_CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE); if (type) { - const char* typestr = (type == 1) ? "folder" : (type == 2) ? "file" : NULL; char ename[256]; u64 fsize = 0; - snprintf(ename, 255, (type == 1) ? "newdir" : "dummy.bin"); - if ((ShowKeyboardOrPrompt(ename, 256, "Create a new %s here?\nEnter name below.", typestr)) && - ((type != 2) || ((fsize = ShowNumberPrompt(0, "Create a new %s here?\nEnter file size below.", typestr)) != (u64) -1))) { + snprintf(ename, sizeof(ename), (type == 1) ? "newdir" : "dummy.bin"); + if ((ShowKeyboardOrPrompt(ename, 256, "%s", (type == 1) ? STR_CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW : STR_CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW)) && + ((type != 2) || ((fsize = ShowNumberPrompt(0, "%s", STR_CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW)) != (u64) -1))) { if (((type == 1) && !DirCreate(current_path, ename)) || ((type == 2) && !FileCreateDummy(current_path, ename, fsize))) { char namestr[UTF_BUFFER_BYTESIZE(36)]; TruncateString(namestr, ename, 36, 12); - ShowPrompt(false, "Failed creating %s:\n%s", typestr, namestr); + ShowPrompt(false, (type == 1) ? STR_FAILED_CREATING_FOLDER_PATH : STR_FAILED_CREATING_FILE_PATH, namestr); } else { GetDirContents(current_dir, current_path); for (cursor = (current_dir->n_entries) ? current_dir->n_entries - 1 : 0; @@ -2843,34 +2920,36 @@ u32 GodMode(int entrypoint) { break; } else if (pad_state & (BUTTON_HOME|BUTTON_POWER)) { // Home menu const char* optionstr[8]; - const char* buttonstr = (pad_state & BUTTON_HOME) ? "HOME" : "POWER"; + bool buttonhome = (pad_state & BUTTON_HOME); u32 n_opt = 0; int poweroff = ++n_opt; int reboot = ++n_opt; + int language = ++n_opt; int brick = (HID_ReadState() & BUTTON_R1) ? ++n_opt : 0; int titleman = ++n_opt; int scripts = ++n_opt; int payloads = ++n_opt; int more = ++n_opt; - if (poweroff > 0) optionstr[poweroff - 1] = "Poweroff system"; - if (reboot > 0) optionstr[reboot - 1] = "Reboot system"; - if (titleman > 0) optionstr[titleman - 1] = "Title manager"; - if (brick > 0) optionstr[brick - 1] = "Brick my 3DS"; - if (scripts > 0) optionstr[scripts - 1] = "Scripts..."; - if (payloads > 0) optionstr[payloads - 1] = "Payloads..."; - if (more > 0) optionstr[more - 1] = "More..."; + if (poweroff > 0) optionstr[poweroff - 1] = STR_POWEROFF_SYSTEM; + if (reboot > 0) optionstr[reboot - 1] = STR_REBOOT_SYSTEM; + if (titleman > 0) optionstr[titleman - 1] = STR_TITLE_MANAGER; + if (language > 0) optionstr[language - 1] = STR_LANGUAGE; + if (brick > 0) optionstr[brick - 1] = STR_BRICK_MY_3DS; + if (scripts > 0) optionstr[scripts - 1] = STR_SCRIPTS; + if (payloads > 0) optionstr[payloads - 1] = STR_PAYLOADS; + if (more > 0) optionstr[more - 1] = STR_MORE; int user_select = 0; - while ((user_select = ShowSelectPrompt(n_opt, optionstr, "%s button pressed.\nSelect action:", buttonstr)) && + while ((user_select = ShowSelectPrompt(n_opt, optionstr, "%s", buttonhome ? STR_HOME_BUTTON_PRESSED_SELECT_ACTION : STR_POWER_BUTTON_PRESSED_SELECT_ACTION)) && (user_select != poweroff) && (user_select != reboot)) { char loadpath[256]; if ((user_select == more) && (HomeMoreMenu(current_path) == 0)) break; // more... menu else if (user_select == titleman) { - static const char* tmoptionstr[4] = { - "[A:] SD CARD", - "[1:] NAND / TWL", - "[B:] SD CARD", - "[4:] NAND / TWL" + const char* tmoptionstr[4] = { + STR_A_DRIVE_SD_CARD, + STR_1_DRIVE_NAND_TWL, + STR_B_DRIVE_SD_CARD, + STR_4_DRIVE_NAND_TWL }; static const char* tmpaths[4] = { "A:/dbs/title.db", @@ -2880,31 +2959,63 @@ u32 GodMode(int entrypoint) { }; u32 tmnum = 2; if (!CheckSDMountState() || (tmnum = ShowSelectPrompt( - (CheckVirtualDrive("E:")) ? 4 : 2, tmoptionstr, - "Title manager menu.\nSelect titles source:", buttonstr))) { + (CheckVirtualDrive("E:")) ? 4 : 2, tmoptionstr, "%s", + STR_TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE))) { const char* tpath = tmpaths[tmnum-1]; if (InitImgFS(tpath)) { SetTitleManagerMode(true); - snprintf(current_path, 256, "Y:"); + snprintf(current_path, sizeof(current_path), "Y:"); GetDirContents(current_dir, current_path); ClearScreenF(true, true, COLOR_STD_BG); cursor = 1; scroll = 0; break; - } else ShowPrompt(false, "Failed setting up title manager!"); + } else ShowPrompt(false, "%s", STR_FAILED_SETTING_UP_TITLE_MANAGER); + } + } else if (user_select == language) { + if (!CheckSupportDir(LANGUAGES_DIR)) { + ShowPrompt(false, STR_LANGUAGES_DIRECTORY_NOT_FOUND, LANGUAGES_DIR); + } else if (LanguageMenu(loadpath, STR_HOME_LANGUAGE_MENU_SELECT_LANGUAGE)) { + size_t fsize = FileGetSize(loadpath); + if (fsize > 0) { + char* data = (char*)malloc(fsize); + if (data) { + FileGetData(loadpath, data, fsize, 0); + SaveSupportFile("language.trf", data, fsize); + SetLanguage(data, fsize); + free(data); + } + + // Try load font with the same name + char *ext = strstr(loadpath, ".trf"); + strcpy(ext, ".frf"); + fsize = FileGetSize(loadpath); + if (fsize > 0) { + char* data = (char*)malloc(fsize); + if (data) { + FileGetData(loadpath, data, fsize, 0); + SaveSupportFile("font.frf", data, fsize); + SetFont(data, fsize); + free(data); + } + } + } + GetDirContents(current_dir, current_path); + ClearScreenF(true, true, COLOR_STD_BG); + break; } } else if (user_select == scripts) { if (!CheckSupportDir(SCRIPTS_DIR)) { - ShowPrompt(false, "Scripts directory not found.\n(default path: 0:/gm9/" SCRIPTS_DIR ")"); - } else if (FileSelectorSupport(loadpath, "HOME scripts... menu.\nSelect script:", SCRIPTS_DIR, "*.gm9")) { + ShowPrompt(false, STR_SCRIPTS_DIRECTORY_NOT_FOUND, SCRIPTS_DIR); + } else if (FileSelectorSupport(loadpath, STR_HOME_SCRIPTS_MENU_SELECT_SCRIPT, SCRIPTS_DIR, "*.gm9")) { ExecuteGM9Script(loadpath); GetDirContents(current_dir, current_path); ClearScreenF(true, true, COLOR_STD_BG); break; } } else if (user_select == payloads) { - if (!CheckSupportDir(PAYLOADS_DIR)) ShowPrompt(false, "Payloads directory not found.\n(default path: 0:/gm9/" PAYLOADS_DIR ")"); - else if (FileSelectorSupport(loadpath, "HOME payloads... menu.\nSelect payload:", PAYLOADS_DIR, "*.firm")) + if (!CheckSupportDir(PAYLOADS_DIR)) ShowPrompt(false, STR_PAYLOADS_DIRECTORY_NOT_FOUND, PAYLOADS_DIR); + else if (FileSelectorSupport(loadpath, STR_HOME_PAYLOADS_MENU_SELECT_PAYLOAD, PAYLOADS_DIR, "*.firm")) BootFirmHandler(loadpath, false, false); } else if (user_select == brick) { Paint9(); // hiding a secret here @@ -2923,17 +3034,17 @@ u32 GodMode(int entrypoint) { } else if (pad_state & (CART_INSERT|CART_EJECT)) { if (!InitVCartDrive() && (pad_state & CART_INSERT) && (curr_drvtype & DRV_CART)) // reinit virtual cart drive - ShowPrompt(false, "Cart init failed!"); + ShowPrompt(false, "%s", STR_CART_INIT_FAILED); if (!(*current_path) || (curr_drvtype & DRV_CART)) GetDirContents(current_dir, current_path); // refresh dir contents } else if (pad_state & SD_INSERT) { - while (!InitSDCardFS() && ShowPrompt(true, "Initialising SD card failed! Retry?")); + while (!InitSDCardFS() && ShowPrompt(true, "%s", STR_INITIALIZING_SD_FAILED_RETRY)); ClearScreenF(true, true, COLOR_STD_BG); AutoEmuNandBase(true); InitExtFS(); GetDirContents(current_dir, current_path); } else if ((pad_state & SD_EJECT) && CheckSDMountState()) { - ShowPrompt(false, "!Unexpected SD card removal!\n \nTo prevent data loss, unmount\nbefore ejecting the SD card."); + ShowPrompt(false, "%s", STR_UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT); DeinitExtFS(); DeinitSDCardFS(); InitExtFS(); @@ -2959,6 +3070,7 @@ u32 GodMode(int entrypoint) { u32 ScriptRunner(int entrypoint) { // init font and show splash if (!SetFont(NULL, 0)) return GODMODE_EXIT_POWEROFF; + SetLanguage(NULL, 0); SplashInit("scriptrunner mode"); u64 timer = timer_start(); @@ -2986,9 +3098,11 @@ u32 ScriptRunner(int entrypoint) { ExecuteGM9Script("V:/" VRAM0_AUTORUN_GM9); } else if (PathExist("V:/" VRAM0_SCRIPTS)) { char loadpath[256]; - if (FileSelector(loadpath, FLAVOR " scripts menu.\nSelect script:", "V:/" VRAM0_SCRIPTS, "*.gm9", HIDE_EXT, false)) + char title[256]; + snprintf(title, sizeof(title), STR_FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT, FLAVOR); + if (FileSelector(loadpath, title, "V:/" VRAM0_SCRIPTS, "*.gm9", HIDE_EXT, false)) ExecuteGM9Script(loadpath); - } else ShowPrompt(false, "Compiled as script autorunner\nbut no script provided.\n \nDerp!"); + } else ShowPrompt(false, STR_COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP); // deinit DeinitExtFS(); diff --git a/arm9/source/language.c b/arm9/source/language.c new file mode 100644 index 000000000..d8cb65da8 --- /dev/null +++ b/arm9/source/language.c @@ -0,0 +1,188 @@ +#include "language.h" +#include "fsdrive.h" +#include "fsutil.h" +#include "support.h" +#include "ui.h" + +#define STRING(what, def) const char* STR_##what = NULL; +#include "language.inl" +#undef STRING + +static const char** translation_ptrs[] = { + #define STRING(what, def) &STR_##what, + #include "language.inl" + #undef STRING +}; + +static const char* translation_fallbacks[] = { + #define STRING(what, def) def, + #include "language.inl" + #undef STRING +}; + +static char* translation_data = NULL; + +typedef struct { + char name[32]; + char path[256]; +} Language; + +typedef struct { + char chunk_id[4]; // NOT null terminated + u32 size; +} RiffChunkHeader; + +typedef struct { + u32 version; + u32 count; + char languageName[32]; +} LanguageMeta; +STATIC_ASSERT(sizeof(LanguageMeta) == 40); + +bool SetLanguage(const void* translation, u32 translation_size) { + u32 str_count; + const void* ptr = translation; + const RiffChunkHeader* riff_header; + const RiffChunkHeader* chunk_header; + + // Free old translation data + if (translation_data) { + free(translation_data); + translation_data = NULL; + } + + if ((ptr = GetLanguage(translation, translation_size, NULL, &str_count, NULL))) { + // load total size + riff_header = translation; + + while ((u32)(ptr - translation) < riff_header->size + sizeof(RiffChunkHeader)) { + chunk_header = ptr; + + if (memcmp(chunk_header->chunk_id, "SDAT", 4) == 0) { // string data + if (chunk_header->size > 0) { + translation_data = malloc(chunk_header->size); + if (!translation_data) goto fallback; + + memcpy(translation_data, ptr + sizeof(RiffChunkHeader), chunk_header->size); + } + } else if (memcmp(chunk_header->chunk_id, "SMAP", 4) == 0) { // string map + // string data must come before the map + if (!translation_data && str_count > 0) goto fallback; + + u16* string_map = (u16*)(ptr + sizeof(RiffChunkHeader)); + + // Load all the strings + for (u32 i = 0; i < countof(translation_ptrs); i++) { + if (i < str_count) { + *translation_ptrs[i] = (translation_data + string_map[i]); + } else { + *translation_ptrs[i] = translation_fallbacks[i]; + } + } + } + + ptr += sizeof(RiffChunkHeader) + chunk_header->size; + } + + return true; + } + +fallback: + if (translation_data) { + free(translation_data); + translation_data = NULL; + } + + for (u32 i = 0; i < countof(translation_ptrs); i++) { + *translation_ptrs[i] = translation_fallbacks[i]; + } + + return false; +} + +const void* GetLanguage(const void* riff, const u32 riff_size, u32* version, u32* count, char* language_name) { + const void* ptr = riff; + const RiffChunkHeader* riff_header; + const RiffChunkHeader* chunk_header; + + // check header magic and load size + if (!ptr) return NULL; + riff_header = ptr; + if (memcmp(riff_header->chunk_id, "RIFF", 4) != 0) return NULL; + + // ensure enough space is allocated + if (riff_header->size > riff_size) return NULL; + + ptr += sizeof(RiffChunkHeader); + + while ((u32)(ptr - riff) < riff_header->size + sizeof(RiffChunkHeader)) { + chunk_header = ptr; + + // check for and load META section + if (memcmp(chunk_header->chunk_id, "META", 4) == 0) { + if (chunk_header->size != sizeof(LanguageMeta)) return NULL; + + const LanguageMeta *meta = ptr + sizeof(RiffChunkHeader); + if (meta->version != TRANSLATION_VER || meta->count > countof(translation_ptrs)) return NULL; + + // all good + if (version) *version = meta->version; + if (count) *count = meta->count; + if (language_name) strcpy(language_name, meta->languageName); + return ptr; + } + + ptr += sizeof(RiffChunkHeader) + chunk_header->size; + } + + return NULL; +} + +int compLanguage(const void* e1, const void* e2) { + const Language* entry2 = (const Language*) e2; + const Language* entry1 = (const Language*) e1; + return strncasecmp(entry1->name, entry2->name, 32); +} + +bool LanguageMenu(char* result, const char* title) { + DirStruct* langDir = (DirStruct*)malloc(sizeof(DirStruct)); + if (!langDir) return false; + + char path[256]; + if (!GetSupportDir(path, LANGUAGES_DIR)) return false; + GetDirContents(langDir, path); + + char* header = (char*)malloc(0x2C0); + Language* langs = (Language*)malloc(langDir->n_entries * sizeof(Language)); + int langCount = 0; + + // Find all valid files and get their language names + for (u32 i = 0; i < langDir->n_entries; i++) { + if (langDir->entry[i].type == T_FILE) { + size_t fsize = FileGetSize(langDir->entry[i].path); + FileGetData(langDir->entry[i].path, header, 0x2C0, 0); + if (GetLanguage(header, fsize, NULL, NULL, langs[langCount].name)) { + memcpy(langs[langCount].path, langDir->entry[i].path, 256); + langCount++; + } + } + } + + free(langDir); + free(header); + + qsort(langs, langCount, sizeof(Language), compLanguage); + + // Make an array of just the names for the select promt + const char* langNames[langCount]; + for (int i = 0; i < langCount; i++) { + langNames[i] = langs[i].name; + } + + u32 selected = ShowSelectPrompt(langCount, langNames, "%s", title); + if (selected > 0 && result) { + memcpy(result, langs[selected - 1].path, 256); + } + + return selected > 0; +} diff --git a/arm9/source/language.h b/arm9/source/language.h new file mode 100644 index 000000000..d2972ee92 --- /dev/null +++ b/arm9/source/language.h @@ -0,0 +1,12 @@ +#pragma once + +#include "common.h" + +#define STRING(what, def) extern const char* STR_##what; +#include "language.inl" +#undef STRING + +bool SetLanguage(const void* translation, u32 translation_size); +const void* GetLanguage(const void* riff, u32 riff_size, u32* version, u32* count, char* language_name); + +bool LanguageMenu(char* result, const char* title); diff --git a/arm9/source/system/vram0.h b/arm9/source/system/vram0.h index 62811a710..87b8986e2 100644 --- a/arm9/source/system/vram0.h +++ b/arm9/source/system/vram0.h @@ -18,14 +18,16 @@ #define VRAM0_EASTER_BIN "easter.bin" -#define VRAM0_OFFSET 0x080C0000 -#define VRAM0_LIMIT 0x00040000 +extern const char vram_data[]; +extern const char vram_data_end[]; + +#define VRAM0_OFFSET (uintptr_t)(vram_data) +#define VRAM0_LIMIT (uintptr_t)(vram_data_end - vram_data) #define TARDATA ((void*) VRAM0_OFFSET) #define TARDATA_(off) ((void*) (u32) (VRAM0_OFFSET + (off))) #define TARDATA_END TARDATA_(VRAM0_LIMIT) - #define CheckVram0Tar() \ (ValidateTarHeader(TARDATA, TARDATA_END) == 0) diff --git a/arm9/source/system/vram_data.s b/arm9/source/system/vram_data.s new file mode 100644 index 000000000..725768aab --- /dev/null +++ b/arm9/source/system/vram_data.s @@ -0,0 +1,8 @@ +.section .rodata.vram_data + +.align 2 +.global vram_data +vram_data: + .incbin "../output/vram0.tar" +.global vram_data_end +vram_data_end: diff --git a/arm9/source/system/xrq.c b/arm9/source/system/xrq.c index aa36af20f..c8367f2aa 100644 --- a/arm9/source/system/xrq.c +++ b/arm9/source/system/xrq.c @@ -6,6 +6,7 @@ #include "common.h" #include "fsinit.h" #include "fsutil.h" +#include "language.h" #include "qrcodegen.h" #include "power.h" #include "rtc.h" @@ -94,7 +95,7 @@ void XRQ_DumpRegisters(u32 xrq, u32 *regs) u32 draw_y_upd = draw_y + draw_height - 10; ClearScreen(MAIN_SCREEN, COLOR_STD_BG); - DrawStringF(MAIN_SCREEN, draw_x, draw_y, COLOR_STD_FONT, COLOR_STD_BG, dumpstr); + DrawStringF(MAIN_SCREEN, draw_x, draw_y, COLOR_STD_FONT, COLOR_STD_BG, "%s", dumpstr); /* Dump STACK */ sp = regs[13] & ~0xF; @@ -118,16 +119,17 @@ void XRQ_DumpRegisters(u32 xrq, u32 *regs) /* Draw QR Code */ u8 qrcode[qrcodegen_BUFFER_LEN_MAX]; u8 temp[qrcodegen_BUFFER_LEN_MAX]; - DrawStringF(MAIN_SCREEN, draw_x, draw_y_upd, COLOR_STD_FONT, COLOR_STD_BG, - "%-29.29s", "Generating QR code..."); + char tempstr[UTF_BUFFER_BYTESIZE(29)]; + ResizeString(tempstr, STR_GENERATING_QR_CODE, 29, 29, false); + DrawString(MAIN_SCREEN, tempstr, draw_x, draw_y_upd, COLOR_STD_FONT, COLOR_STD_BG); if (qrcodegen_encodeText(dumpstr, temp, qrcode, qrcodegen_Ecc_LOW, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true)) { DrawQrCode(ALT_SCREEN, qrcode); } /* Reinitialize SD */ - DrawStringF(MAIN_SCREEN, draw_x, draw_y_upd, COLOR_STD_FONT, COLOR_STD_BG, - "%-29.29s", "Reinitializing SD card..."); + ResizeString(tempstr, STR_REINITIALIZING_SD_CARD, 29, 29, false); + DrawString(MAIN_SCREEN, tempstr, draw_x, draw_y_upd, COLOR_STD_FONT, COLOR_STD_BG); while (!InitSDCardFS()) { if (InputWait(1) & BUTTON_POWER) PowerOff(); DeinitSDCardFS(); @@ -136,19 +138,19 @@ void XRQ_DumpRegisters(u32 xrq, u32 *regs) /* Dump to SD */ char path[64]; - snprintf(path, 64, "%s/exception_dump_%02lX%02lX%02lX%02lX%02lX%02lX.txt", OUTPUT_PATH, + snprintf(path, sizeof(path), "%s/exception_dump_%02lX%02lX%02lX%02lX%02lX%02lX.txt", OUTPUT_PATH, (u32) dstime.bcd_Y, (u32) dstime.bcd_M, (u32) dstime.bcd_D, (u32) dstime.bcd_h, (u32) dstime.bcd_m, (u32) dstime.bcd_s); - DrawStringF(MAIN_SCREEN, draw_x, draw_y_upd, COLOR_STD_FONT, COLOR_STD_BG, - "%-29.29s", "Dumping state to SD card..."); + ResizeString(tempstr, STR_DUMPING_STATE_TO_SD_CARD, 29, 29, false); + DrawString(MAIN_SCREEN, tempstr, draw_x, draw_y_upd, COLOR_STD_FONT, COLOR_STD_BG); FileSetData(path, dumpstr, wstr - dumpstr, 0, true); /* Deinit SD */ DeinitSDCardFS(); /* Done, wait for user power off */ - DrawStringF(MAIN_SCREEN, draw_x, draw_y_upd, COLOR_STD_FONT, COLOR_STD_BG, - "%-29.29s", "Press POWER to turn off"); + ResizeString(tempstr, STR_PRESS_POWER_TO_TURN_OFF, 29, 29, false); + DrawString(MAIN_SCREEN, tempstr, draw_x, draw_y_upd, COLOR_STD_FONT, COLOR_STD_BG); while (!(InputWait(0) & BUTTON_POWER)); PowerOff(); diff --git a/arm9/source/utils/ctrtransfer.c b/arm9/source/utils/ctrtransfer.c index 5258360bf..3f7177d05 100644 --- a/arm9/source/utils/ctrtransfer.c +++ b/arm9/source/utils/ctrtransfer.c @@ -2,6 +2,7 @@ #include "nandcmac.h" #include "fs.h" #include "essentials.h" +#include "language.h" #include "ui.h" #include "sha.h" @@ -63,11 +64,11 @@ u32 TransferCtrNandImage(const char* path_img, const char* drv) { char path_tickdb[32]; char path_tickdb_bak[32]; - snprintf(path_secnfo_a, 32, "%s/rw/sys/SecureInfo_A", drv); - snprintf(path_secnfo_b, 32, "%s/rw/sys/SecureInfo_B", drv); - snprintf(path_secnfo_c, 32, "%s/rw/sys/SecureInfo_C", drv); - snprintf(path_tickdb, 32, "%s/dbs/ticket.db", drv); - snprintf(path_tickdb_bak, 32, "%s/dbs/ticket.bak", drv); + snprintf(path_secnfo_a, sizeof(path_secnfo_a), "%s/rw/sys/SecureInfo_A", drv); + snprintf(path_secnfo_b, sizeof(path_secnfo_b), "%s/rw/sys/SecureInfo_B", drv); + snprintf(path_secnfo_c, sizeof(path_secnfo_c), "%s/rw/sys/SecureInfo_C", drv); + snprintf(path_tickdb, sizeof(path_tickdb), "%s/dbs/ticket.db", drv); + snprintf(path_tickdb_bak, sizeof(path_tickdb_bak), "%s/dbs/ticket.bak", drv); // special handling for out of region images (create SecureInfo_C) PathDelete(path_secnfo_c); // not required when transfering back to original region @@ -87,11 +88,11 @@ u32 TransferCtrNandImage(const char* path_img, const char* drv) { char path_movable[32]; char path_asr[96]; u8 sd_keyy[0x10] __attribute__((aligned(4))); - snprintf(path_movable, 32, "%s/private/movable.sed", drv); + snprintf(path_movable, sizeof(path_movable), "%s/private/movable.sed", drv); if (FileGetData(path_movable, sd_keyy, 0x10, 0x110) == 0x10) { u32 sha256sum[8]; sha_quick(sha256sum, sd_keyy, 0x10, SHA256_MODE); - snprintf(path_asr, 96, "%s/data/%08lx%08lx%08lx%08lx/sysdata/00010011/00000000", + snprintf(path_asr, sizeof(path_asr), "%s/data/%08lx%08lx%08lx%08lx/sysdata/00010011/00000000", drv, sha256sum[0], sha256sum[1], sha256sum[2], sha256sum[3]); PathDelete(path_asr); } @@ -102,17 +103,17 @@ u32 TransferCtrNandImage(const char* path_img, const char* drv) { char path_from[32]; char path_dbs[32]; u32 flags = OVERWRITE_ALL; - snprintf(path_dbs, 32, "%s/dbs", drv); + snprintf(path_dbs, sizeof(path_dbs), "%s/dbs", drv); for (u32 i = 0; i < sizeof(dbnames) / sizeof(char*); i++) { - snprintf(path_to, 32, "%s/dbs/%s", drv, dbnames[i]); - snprintf(path_from, 32, "7:/dbs/%s", dbnames[i]); + snprintf(path_to, sizeof(path_to), "%s/dbs/%s", drv, dbnames[i]); + snprintf(path_from, sizeof(path_from), "7:/dbs/%s", dbnames[i]); PathDelete(path_to); PathCopy(path_dbs, path_from, &flags); FixFileCmac(path_to, true); } - ShowString("Cleaning up titles, please wait..."); - snprintf(path_to, 32, "%s/title", drv); - snprintf(path_from, 32, "7:/title"); + ShowString("%s", STR_CLEANING_UP_TITLES_PLEASE_WAIT); + snprintf(path_to, sizeof(path_to), "%s/title", drv); + snprintf(path_from, sizeof(path_from), "7:/title"); PathDelete(path_to); PathCopy(drv, path_from, &flags); diff --git a/arm9/source/utils/gameutil.c b/arm9/source/utils/gameutil.c index 6ec9c4caf..ded8852f9 100644 --- a/arm9/source/utils/gameutil.c +++ b/arm9/source/utils/gameutil.c @@ -294,7 +294,7 @@ u32 LoadCdnTicketFile(Ticket** ticket, const char* path_cnt) { char* name_cetk = strrchr(path_cetk, '/'); if (!name_cetk) return 1; // will not happen name_cetk++; - snprintf(name_cetk, 256 - (name_cetk - path_cetk), "cetk"); + snprintf(name_cetk, sizeof(path_cetk) - (name_cetk - path_cetk), "cetk"); // ticket is loaded and validated here return LoadTicketFile(ticket, path_cetk); } @@ -313,7 +313,7 @@ u32 LoadTicketForTitleId(Ticket** ticket, const u64 title_id) { // path to ticket.db char path_ticketdb[32]; char drv = *path_store; - snprintf(path_ticketdb, 32, "%2.2s/dbs/ticket.db", + snprintf(path_ticketdb, sizeof(path_ticketdb), "%2.2s/dbs/ticket.db", ((drv == 'B') || (drv == '5') || (drv == '4')) ? "4:" : "1:"); // load ticket @@ -335,7 +335,7 @@ u32 GetTmdContentPath(char* path_content, const char* path_tmd) { // content path string char* name_content; - snprintf(path_content, 255, "%s", path_tmd); + snprintf(path_content, 256, "%s", path_tmd); path_content[255] = '\0'; name_content = strrchr(path_content, '/'); if (!name_content) return 1; // will not happen @@ -352,7 +352,7 @@ u32 GetTmdContentPath(char* path_content, const char* path_tmd) { free(tmd); return 1; } - snprintf(name_content, 255 - (name_content - path_content), cdn ? "%08lx" : + snprintf(name_content, 256 - (name_content - path_content), cdn ? "%08lx" : (memcmp(tmd->title_id, dlc_tid_high, sizeof(dlc_tid_high)) == 0) ? "00000000/%08lx.app" : "%08lx.app", getbe32(chunk->id)); free(tmd); @@ -418,7 +418,7 @@ u32 GetTitleIdTmdPath(char* path_tmd, const u64 title_id, bool from_emunand) { if (tid_high & 0x8000) tid_high = 0x00030000 | (tid_high&0xFF); char path_pat[64]; - snprintf(path_pat, 64, "%2.2s/title/%08lX/%08lX/content/*.tmd", + snprintf(path_pat, sizeof(path_pat), "%2.2s/title/%08lX/%08lX/content/*.tmd", drv, tid_high, tid_low); if (fvx_findpath(path_tmd, path_pat, FN_HIGHEST) != FR_OK) @@ -537,7 +537,7 @@ u32 VerifyNcchFile(const char* path, u32 offset, u32 size) { // fetch and check NCCH header fvx_lseek(&file, offset); if (GetNcchHeaders(&ncch, NULL, NULL, &file, cryptofix) != 0) { - if (!offset) ShowPrompt(false, "%s\nError: Not a NCCH file", pathstr); + if (!offset) ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_NOT_NCCH_FILE); fvx_close(&file); return 1; } @@ -545,7 +545,7 @@ u32 VerifyNcchFile(const char* path, u32 offset, u32 size) { // check NCCH size if (!size) size = fvx_size(&file) - offset; if ((fvx_size(&file) < offset) || (size < ncch.size * NCCH_MEDIA_UNIT)) { - if (!offset) ShowPrompt(false, "%s\nError: File is too small", pathstr); + if (!offset) ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_FILE_IS_TOO_SMALL); fvx_close(&file); return 1; } @@ -561,15 +561,15 @@ u32 VerifyNcchFile(const char* path, u32 offset, u32 size) { if (GetNcchHeaders(&ncch, NULL, &exefs, &file, cryptofix) == 0) { if (cryptofix_always) borkedflags = true; else { - const char* optionstr[3] = { "Attempt fix this time", "Attempt fix always", "Abort verification" }; - u32 user_select = ShowSelectPrompt(3, optionstr, "%s\nError: Bad crypto flags", pathstr); + const char* optionstr[3] = { STR_ATTEMPT_FIX_THIS_TIME, STR_ATTEMPT_FIX_ALWAYS, STR_ABORT_VERIFICATION }; + u32 user_select = ShowSelectPrompt(3, optionstr, "%s\n%s", pathstr, STR_ERROR_BAD_CRYPTO_FLAGS); if ((user_select == 1) || (user_select == 2)) borkedflags = true; if (user_select == 2) cryptofix_always = true; } } } if (!borkedflags) { - if (!offset) ShowPrompt(false, "%s\nError: Bad ExeFS header", pathstr); + if (!offset) ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_BAD_EXEFS_HEADER); fvx_close(&file); return 1; } @@ -578,14 +578,14 @@ u32 VerifyNcchFile(const char* path, u32 offset, u32 size) { // fetch and check ExtHeader fvx_lseek(&file, offset); if (ncch.size_exthdr && (GetNcchHeaders(&ncch, &exthdr, NULL, &file, cryptofix) != 0)) { - if (!offset) ShowPrompt(false, "%s\nError: Missing ExtHeader", pathstr); + if (!offset) ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_MISSING_EXTHEADER); fvx_close(&file); return 1; } // check / setup crypto if (SetupNcchCrypto(&ncch, NCCH_NOCRYPTO) != 0) { - if (!offset) ShowPrompt(false, "%s\nError: Crypto not set up", pathstr); + if (!offset) ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_CRYPTO_NOT_SET_UP); fvx_close(&file); return 1; } @@ -712,10 +712,10 @@ u32 VerifyNcchFile(const char* path, u32 offset, u32 size) { } if (!offset && (ver_exthdr|ver_exefs|ver_romfs)) { // verification summary - ShowPrompt(false, "%s\nNCCH verification failed:\nExtHdr/ExeFS/RomFS: %s/%s/%s", pathstr, - (!ncch.size_exthdr) ? "-" : (ver_exthdr == 0) ? "ok" : "fail", - (!ncch.size_exefs) ? "-" : (ver_exefs == 0) ? "ok" : "fail", - (!ncch.size_romfs) ? "-" : (ver_romfs == 0) ? "ok" : "fail"); + ShowPrompt(false, STR_PATH_NCCH_VERIFICATION_FAILED_INFO, pathstr, + (!ncch.size_exthdr) ? "-" : (ver_exthdr == 0) ? STR_OK : STR_FAIL, + (!ncch.size_exefs) ? "-" : (ver_exefs == 0) ? STR_OK : STR_FAIL, + (!ncch.size_romfs) ? "-" : (ver_romfs == 0) ? STR_OK : STR_FAIL); } fvx_close(&file); @@ -732,7 +732,7 @@ u32 VerifyNcsdFile(const char* path) { // load NCSD header if (LoadNcsdHeader(&ncsd, path) != 0) { - ShowPrompt(false, "%s\nError: Not a NCSD file", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_NOT_NCSD_FILE); return 1; } @@ -743,8 +743,8 @@ u32 VerifyNcsdFile(const char* path) { u32 size = partition->size * NCSD_MEDIA_UNIT; if (!size) continue; if (VerifyNcchFile(path, offset, size) != 0) { - ShowPrompt(false, "%s\nContent%lu (%08lX@%08lX):\nVerification failed", - pathstr, i, size, offset, i); + ShowPrompt(false, STR_PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED, + pathstr, i, size, offset); return 1; } } @@ -767,14 +767,14 @@ u32 VerifyCiaFile(const char* path) { if ((LoadCiaStub(cia, path) != 0) || (GetCiaInfo(&info, &(cia->header)) != 0) || (GetTitleKey(titlekey, (Ticket*)&(cia->ticket)) != 0)) { - ShowPrompt(false, "%s\nError: Probably not a CIA file", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_PROBABLY_NOT_CIA_FILE); free(cia); return 1; } // verify TMD if (VerifyTmd(&(cia->tmd)) != 0) { - ShowPrompt(false, "%s\nError: TMD probably corrupted", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_TMD_PROBABLY_CORRUPTED); free(cia); return 1; } @@ -788,8 +788,8 @@ u32 VerifyCiaFile(const char* path) { u16 index = getbe16(chunk->index); if (!(cnt_index[index/8] & (1 << (7-(index%8))))) continue; // don't check missing contents if (VerifyTmdContent(path, next_offset, chunk, titlekey) != 0) { - ShowPrompt(false, "%s\nID %08lX (%08llX@%08llX)\nVerification failed", - pathstr, getbe32(chunk->id), getbe64(chunk->size), next_offset, i); + ShowPrompt(false, STR_PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED, + pathstr, getbe32(chunk->id), getbe64(chunk->size), next_offset); free(cia); return 1; } @@ -821,7 +821,7 @@ u32 VerifyTmdFile(const char* path, bool cdn) { TitleMetaData* tmd = (TitleMetaData*) malloc(TMD_SIZE_MAX); TmdContentChunk* content_list = (TmdContentChunk*) (tmd + 1); if ((LoadTmdFile(tmd, path) != 0) || (VerifyTmd(tmd) != 0)) { - ShowPrompt(false, "%s\nError: TMD probably corrupted", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_TMD_PROBABLY_CORRUPTED); free(tmd); return 1; } @@ -834,7 +834,7 @@ u32 VerifyTmdFile(const char* path, bool cdn) { (BuildFakeTicket(ticket, tmd->title_id) == 0) && (FindTitleKey(ticket, tmd->title_id) == 0))) || (GetTitleKey(titlekey, ticket) != 0)) { - ShowPrompt(false, "%s\nError: CDN titlekey not found", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_CDN_TITLEKEY_NOT_FOUND); free(ticket); free(tmd); return 1; @@ -853,12 +853,12 @@ u32 VerifyTmdFile(const char* path, bool cdn) { (cdn) ? "%08lx" : (dlc) ? "00000000/%08lx.app" : "%08lx.app", getbe32(chunk->id)); TruncateString(pathstr, path_content, 32, 8); if (dlc && i && !PathExist(path_content)) { - if (!ignore_missing_dlc && !ShowPrompt(true, "%s\nDLC content is missing\n \nIgnore all and continue?", pathstr)) res = 1; + if (!ignore_missing_dlc && !ShowPrompt(true, "%s\n%s", pathstr, STR_DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE)) res = 1; ignore_missing_dlc = true; continue; } if (VerifyTmdContent(path_content, 0, chunk, titlekey) != 0) { - ShowPrompt(false, "%s\n%s", pathstr, PathExist(path_content) ? "Verification failed" : "Content is missing"); + ShowPrompt(false, "%s\n%s", pathstr, PathExist(path_content) ? STR_VERIFICATION_FAILED : STR_CONTENT_IS_MISSING); res = 1; } } @@ -927,7 +927,7 @@ u32 VerifyFirmFile(const char* path) { void* section = ((u8*) firm_buffer) + sct->offset; if (!(sct->size)) continue; if (sha_cmp(sct->hash, section, sct->size, SHA256_MODE) != 0) { - ShowPrompt(false, "%s\nSection %u hash mismatch", pathstr, i); + ShowPrompt(false, STR_PATH_SECTION_N_HASH_MISMATCH, pathstr, i); free(firm_buffer); return 1; } @@ -935,11 +935,11 @@ u32 VerifyFirmFile(const char* path) { // no arm11 / arm9 entrypoints? if (!header.entry_arm9) { - ShowPrompt(false, "%s\nARM9 entrypoint is missing", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ARM9_ENTRYPOINT_IS_MISSING); free(firm_buffer); return 1; } else if (!header.entry_arm11) { - ShowPrompt(false, "%s\nWarning: ARM11 entrypoint is missing", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_WARNING_ARM11_ENTRYPOINT_IS_MISSING); } free(firm_buffer); @@ -962,7 +962,7 @@ u32 VerifyBossFile(const char* path) { fvx_lseek(&file, 0); if ((fvx_read(&file, &boss, sizeof(BossHeader), &btr) != FR_OK) || (btr != sizeof(BossHeader)) || (ValidateBossHeader(&boss, 0) != 0)) { - ShowPrompt(false, "%s\nError: Not a BOSS file", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_NOT_A_BOSS_FILE); fvx_close(&file); return 1; } @@ -1007,7 +1007,7 @@ u32 VerifyBossFile(const char* path) { free(buffer); if (memcmp(hash, boss.hash_payload, 0x20) != 0) { - if (ShowPrompt(true, "%s\nBOSS payload hash mismatch.\n \nTry to fix it?", pathstr)) { + if (ShowPrompt(true, "%s\n%s", pathstr, STR_BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT)) { // fix hash, reencrypt BOSS header if required, write to file memcpy(boss.hash_payload, hash, 0x20); if (encrypted) CryptBoss((void*) &boss, 0, sizeof(BossHeader), &boss); @@ -1317,12 +1317,18 @@ u32 CryptCiaFile(const char* orig, const char* dest, u16 crypto) { // if not inplace: take over CIA metadata if (!inplace && (info.size_meta == CIA_META_SIZE)) { - CiaMeta* meta = (CiaMeta*) (void*) (cia + 1); + CiaMeta* meta = (CiaMeta*) malloc(sizeof(CiaMeta)); + if (!meta) { + free(cia); + return 1; + } if ((fvx_qread(orig, meta, info.offset_meta, CIA_META_SIZE, NULL) != FR_OK) || (fvx_qwrite(dest, meta, info.offset_meta, CIA_META_SIZE, NULL) != FR_OK)) { free(cia); + free(meta); return 1; } + free(meta); } // fix TMD hashes, write CIA stub to destination @@ -1452,12 +1458,12 @@ u32 CryptGameFile(const char* path, bool inplace, bool encrypt) { if (!inplace) { // build output name // build output name - snprintf(dest, 256, OUTPUT_PATH "/"); + snprintf(dest, sizeof(dest), OUTPUT_PATH "/"); char* dname = dest + strnlen(dest, 256); if ((strncmp(path + 1, ":/title/", 8) != 0) || (GetGoodName(dname, path, false) != 0)) { char* name = strrchr(path, '/'); if (!name) return 1; - snprintf(dest, 256, "%s/%s", OUTPUT_PATH, ++name); + snprintf(dest, sizeof(dest), "%s/%s", OUTPUT_PATH, ++name); } destptr = dest; } @@ -1555,13 +1561,13 @@ u32 CreateSaveData(const char* drv, u64 tid64, const char* name, u32 save_size, u8 sd_keyy[16] __attribute__((aligned(4))); char path_movable[32]; u32 sha256sum[8]; - snprintf(path_movable, 32, "%2.2s/private/movable.sed", drv); + snprintf(path_movable, sizeof(path_movable), "%2.2s/private/movable.sed", drv); if (fvx_qread(path_movable, sd_keyy, 0x110, 0x10, NULL) != FR_OK) return 1; memset(sd_keyy, 0x00, 16); sha_quick(sha256sum, sd_keyy, 0x10, SHA256_MODE); // build path u32 tid_low = (u32) (tid64 & 0xFFFFFFFF); - snprintf(path_save, 128, "%2.2s/data/%08lx%08lx%08lx%08lx/sysdata/%08lx%s", + snprintf(path_save, sizeof(path_save), "%2.2s/data/%08lx%08lx%08lx%08lx/sysdata/%08lx%s", drv, sha256sum[0], sha256sum[1], sha256sum[2], sha256sum[3], tid_low | 0x00020000, name ? "/00000000" : ""); return 0; @@ -1569,7 +1575,7 @@ u32 CreateSaveData(const char* drv, u64 tid64, const char* name, u32 save_size, GetInstallPath(path_save, drv, tid64, NULL, name ? "data/00000001.sav" : "data"); } else { char substr[64]; - snprintf(substr, 64, "data/%s", name); + snprintf(substr, sizeof(substr), "data/%s", name); GetInstallPath(path_save, drv, tid64, NULL, substr); } @@ -1942,9 +1948,9 @@ u32 InstallCiaSystemData(CiaStub* cia, const char* drv) { if (!syscmd) cmd->unknown = 0xFFFFFFFE; // mark this as custom built // generate all the paths - snprintf(path_titledb, 32, "%2.2s/dbs/title.db", + snprintf(path_titledb, sizeof(path_titledb), "%2.2s/dbs/title.db", (*drv == '2') ? "1:" : *drv == '5' ? "4:" : drv); - snprintf(path_ticketdb, 32, "%2.2s/dbs/ticket.db", + snprintf(path_ticketdb, sizeof(path_ticketdb), "%2.2s/dbs/ticket.db", ((*drv == 'A') || (*drv == '2')) ? "1:" : ((*drv == 'B') || (*drv == '5')) ? "4:" : drv); GetInstallPath(path_tmd, drv, tid64, NULL, "content/00000000.tmd"); @@ -2186,11 +2192,11 @@ u32 BuildCiaLegitTicket(Ticket* ticket, u8* title_id, const char* path_cnt, bool // check the tickets' console id, warn if it isn't zero if (copy && getbe32(ticket_tmp->console_id)) { static u32 default_action = 0; - static const char* optionstr[2] = - {"Generic ticket (\"pirate legit\")", "Personalized ticket (legit)"}; + const char* optionstr[2] = + {STR_GENERIC_TICKET_PIRATE_LEGIT, STR_PERSONALIZED_TICKET_LEGIT}; if (!default_action) { default_action = ShowSelectPrompt(2, optionstr, - "ID %016llX\nLegit ticket is personalized.\nUsing this is not recommended.\nChoose default action:", getbe64(title_id)); + STR_ID_N_LEGIT_TICKET_IS_PERSONALIZED_USING_THIS_NOT_RECOMMENDED_CHOOSE_DEFAULT_ACTION, getbe64(title_id)); ShowProgress(0, 0, path_cnt); } if (!default_action) { @@ -2216,7 +2222,7 @@ u32 BuildCiaLegitTicket(Ticket* ticket, u8* title_id, const char* path_cnt, bool ticket->commonkey_idx = ticket_tmp->commonkey_idx; free(ticket_tmp); } else if (FindTitleKey(ticket, title_id) != 0) { - ShowPrompt(false, "ID %016llX\nTitlekey not found.", getbe64(title_id)); + ShowPrompt(false, STR_ID_N_TITLEKEY_NOT_FOUND, getbe64(title_id)); return 1; } } else { @@ -2273,7 +2279,7 @@ u32 BuildCiaFromTadFile(const char* path_tad, const char* path_dest, bool force_ // check for legit TMD if (force_legit && ((ValidateTmdSignature(tmd) != 0) || VerifyTmd(tmd) != 0)) { - ShowPrompt(false, "ID %016llX\nTMD in TAD is not legit.", getbe64(title_id)); + ShowPrompt(false, STR_ID_N_TMD_IN_TAD_NOT_LEGIT, getbe64(title_id)); free(cia); return 1; } @@ -2357,7 +2363,7 @@ u32 BuildInstallFromTmdFileBuffered(const char* path_tmd, const char* path_dest, // check for legit TMD if (force_legit && ((ValidateTmdSignature(tmd) != 0) || VerifyTmd(tmd) != 0)) { - ShowPrompt(false, "ID %016llX\nTMD is not legit.", getbe64(title_id)); + ShowPrompt(false, STR_ID_N_TMD_NOT_LEGIT, getbe64(title_id)); return 1; } @@ -2412,13 +2418,13 @@ u32 BuildInstallFromTmdFileBuffered(const char* path_tmd, const char* path_dest, (cdn) ? "%08lx" : (dlc && !cdn) ? "00000000/%08lx.app" : "%08lx.app", getbe32(chunk->id)); if (!install && ((ret = InsertCiaContent(path_dest, path_content, 0, (u32) getbe64(chunk->size), chunk, titlekey, force_legit, false, cdn)) != 0)) { - ShowPrompt(false, "ID %016llX.%08lX\n%s", getbe64(title_id), getbe32(chunk->id), - (ret == 2) ? "Content is corrupt" : "Insert content failed"); + ShowPrompt(false, STR_ID_N_DOT_N_STATUS, getbe64(title_id), getbe32(chunk->id), + (ret == 2) ? STR_CONTENT_IS_CORRUPT : STR_INSERT_CONTENT_FAILED); return 1; } if (install && (InstallCiaContent(path_dest, path_content, 0, (u32) getbe64(chunk->size), chunk, title_id, titlekey, false, cdn) != 0)) { - ShowPrompt(false, "ID %016llX.%08lX\nInstall content failed", getbe64(title_id), getbe32(chunk->id)); + ShowPrompt(false, STR_ID_N_DOT_N_STATUS, getbe64(title_id), getbe32(chunk->id), STR_INSTALL_CONTENT_FAILED); return 1; } } @@ -2778,7 +2784,7 @@ u32 BuildCiaFromGameFile(const char* path, bool force_legit) { u32 ret = 0; // build output name - snprintf(dest, 256, OUTPUT_PATH "/"); + snprintf(dest, sizeof(dest), OUTPUT_PATH "/"); char* dname = dest + strnlen(dest, 256); if (!((filetype & (GAME_TMD|GAME_CDNTMD|GAME_TWLTMD|GAME_TIE)) || (strncmp(path + 1, ":/title/", 8) == 0)) || @@ -2787,8 +2793,8 @@ u32 BuildCiaFromGameFile(const char* path, bool force_legit) { if (!title_id) { char* name = strrchr(path, '/'); if (!name) return 1; - snprintf(dest, 256, "%s/%s", OUTPUT_PATH, ++name); - } else snprintf(dest, 256, "%s/%016llX", OUTPUT_PATH, title_id); + snprintf(dest, sizeof(dest), "%s/%s", OUTPUT_PATH, ++name); + } else snprintf(dest, sizeof(dest), "%s/%016llX", OUTPUT_PATH, title_id); } // replace extension char* dot = strrchr(dest, '.'); @@ -2861,7 +2867,7 @@ u32 InstallGameFile(const char* path, bool to_emunand) { if (((GetInstallDbsPath(path_db, drv, "title.db" ) != 0) || !fvx_qsize(path_db)) || ((GetInstallDbsPath(path_db, drv, "import.db") != 0) || !fvx_qsize(path_db)) || ((GetInstallDbsPath(path_db, drv, "ticket.db") != 0) || !fvx_qsize(path_db))) { - ShowPrompt(false, "Install error:\nThis system is missing one or\nmore .db files.\n \nMaybe the SD card is missing\nor uninitialized?"); + ShowPrompt(false, "%s", STR_INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_DB_FILES_MAYBE_SD_MISSING_OR_UNINITIALIZED); return 1; } @@ -2905,7 +2911,7 @@ u32 InstallCifinishFile(const char* path, bool to_emunand) { // check ticket db char path_ticketdb[32]; if ((GetInstallDbsPath(path_ticketdb, to_emunand ? "4:" : "1:", "ticket.db") != 0) || !fvx_qsize(path_ticketdb)) { - ShowPrompt(false, "Install error:\nThis system is missing the\nticket.db file."); + ShowPrompt(false, "%s", STR_INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB); return 1; } @@ -2938,7 +2944,7 @@ u32 InstallCifinishFile(const char* path, bool to_emunand) { } // check for forbidden title id (the "too large dlc") if ((TITLE_MAX_CONTENTS <= 1024) && (cftitle[i].title_id == 0x0004008C000CBD00)) { - ShowPrompt(false, "Skipped title:\nTitle with id 0004008C000CBD00\nneeds special compiler flags."); + ShowPrompt(false, "%s", STR_SKIPPED_TITLE_0004008C000CBD00_NEEDS_SPECIAL_COMPILE_FLAGS); ShowProgress(0, 0, path); continue; } @@ -2979,7 +2985,7 @@ u32 InstallTicketFile(const char* path, bool to_emunand) { // check ticket db char path_ticketdb[32]; if ((GetInstallDbsPath(path_ticketdb, to_emunand ? "4:" : "1:", "ticket.db") != 0) || !fvx_qsize(path_ticketdb)) { - ShowPrompt(false, "Install error:\nThis system is missing the\nticket.db file."); + ShowPrompt(false, "%s", STR_INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB); return 1; } @@ -2988,7 +2994,7 @@ u32 InstallTicketFile(const char* path, bool to_emunand) { if (LoadTicketFile(&ticket, path) != 0) return 1; if (ValidateTicketSignature(ticket) != 0) { - ShowPrompt(false, "%s\nError: Fake-signed ticket\n \nOnly valid signed tickets can\nbe installed to the system.", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_FAKE_SIGNED_TICKET_ONLY_VALID_SIGNED_TICKETS_CAN_BE_INSTALLED); free(ticket); return 1; } @@ -2996,7 +3002,7 @@ u32 InstallTicketFile(const char* path, bool to_emunand) { // check ticket console id u32 cid = getbe32(ticket->console_id); if (cid && (cid != (&ARM9_ITCM->otp)->deviceId)) { - ShowPrompt(false, "%s\nError: Unknown cid %08lX\n \nThis ticket does not belong to\nthis 3DS console.", pathstr, cid); + ShowPrompt(false, STR_PATH_ERROR_UNKNOWN_CID_N_THIS_TICKET_DOES_NOT_BELONG_TO_THIS_3DS, pathstr, cid); free(ticket); return 1; } @@ -3008,7 +3014,7 @@ u32 InstallTicketFile(const char* path, bool to_emunand) { } // let the user know we're working - ShowString("%s\nInstalling ticket...\n", pathstr); + ShowString("%s\n%s\n", pathstr, STR_INSTALLING_TICKET); // write ticket database // ensure remounting the old mount path @@ -3048,10 +3054,10 @@ u32 DumpTicketForGameFile(const char* path, bool force_legit) { // build output name char dest[256]; - snprintf(dest, 256, OUTPUT_PATH "/"); + snprintf(dest, sizeof(dest), OUTPUT_PATH "/"); char* dname = dest + strnlen(dest, 256); if (GetGoodName(dname, path, false) != 0) - snprintf(dest, 256, "%s/%016llX", OUTPUT_PATH, tid64); + snprintf(dest, sizeof(dest), "%s/%016llX", OUTPUT_PATH, tid64); // replace extension char* dot = strrchr(dest, '.'); @@ -3075,7 +3081,7 @@ u32 DumpCxiSrlFromTmdFile(const char* path) { char dest[256]; // prepare output name - snprintf(dest, 256, OUTPUT_PATH "/"); + snprintf(dest, sizeof(dest), OUTPUT_PATH "/"); char* dname = dest + strnlen(dest, 256); if (!CheckWritePermissions(dest)) return 1; @@ -3164,7 +3170,7 @@ u32 ExtractCodeFromCxiFile(const char* path, const char* path_out, char* extstr) // allocate memory u8* code = (u8*) malloc(code_max_size); if (!code) { - ShowPrompt(false, "Out of memory."); + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); return 1; } @@ -3188,7 +3194,7 @@ u32 ExtractCodeFromCxiFile(const char* path, const char* path_out, char* extstr) else if (ValidateAgbHeader((AgbHeader*)(void*) code) == 0) ext = ".gba"; } if (extstr) strncpy(extstr, ext, 7); - if (!path_out) snprintf(dest, 256, OUTPUT_PATH "/%016llX%s%s", ncch.programId, (exthdr.flag & 0x1) ? ".dec" : "", ext); + if (!path_out) snprintf(dest, sizeof(dest), OUTPUT_PATH "/%016llX%s%s", ncch.programId, (exthdr.flag & 0x1) ? ".dec" : "", ext); // write output file fvx_unlink(dest); @@ -3217,7 +3223,7 @@ u32 CompressCode(const char* path, const char* path_out) { if (!code_dec || !code_cmp) { if (code_dec != NULL) free(code_dec); if (code_cmp != NULL) free(code_cmp); - ShowPrompt(false, "Out of memory."); + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); return 1; } @@ -3290,11 +3296,21 @@ u64 GetGameFileTrimmedSize(const char* path) { trimsize = GetAnyFileTrimmedSize(path); } else if (filetype & GAME_NDS) { TwlHeader hdr; - if (fvx_qread(path, &hdr, 0, sizeof(TwlHeader), NULL) != FR_OK) + if (fvx_qread(path, &hdr, 0, sizeof(TwlHeader), NULL) != FR_OK) { return 0; - if (hdr.unit_code != 0x00) // DSi or NDS+DSi + } if (hdr.unit_code != 0x00) { // DSi or NDS+DSi trimsize = hdr.ntr_twl_rom_size; - else trimsize = hdr.ntr_rom_size + 0x88; // regular NDS + } else if (hdr.ntr_rom_size) { // regular NDS + trimsize = hdr.ntr_rom_size; + + // Check if immediately after the reported cart size + // is the magic number string 'ac' (auth code). + // If found, add 0x88 bytes for the download play RSA key. + u16 rsaMagic; + if(fvx_qread(path, &rsaMagic, trimsize, 2, NULL) == FR_OK && rsaMagic == 0x6361) { + trimsize += 0x88; + } + } } else { u8 hdr[0x200]; if (fvx_qread(path, &hdr, 0, 0x200, NULL) != FR_OK) @@ -3411,7 +3427,7 @@ u32 ShowGbaFileTitleInfo(const char* path, u16* screen) { if ((fvx_qread(path, &agb, 0, sizeof(AgbHeader), NULL) != FR_OK) || (ValidateAgbHeader(&agb) != 0)) return 1; ClearScreen(screen, COLOR_STD_BG); - ShowStringF(screen, "%.12s (AGB-%.4s)\n%s", agb.game_title, agb.game_code, AGB_DESTSTR(agb.game_code)); + ShowStringF(screen, "%.12s (AGB-%.4s)\n%s", agb.game_title, agb.game_code, AgbDestStr(agb.game_code)); return 0; } @@ -3499,7 +3515,7 @@ u32 ShowGameCheckerInfo(const char* path) { // load CIA stub if (LoadCiaStub(cia, path) != 0) { - ShowPrompt(false, "%s\nError: Probably not a CIA file", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_ERROR_PROBABLY_NOT_CIA_FILE); free(cia); free(tmd); return 1; @@ -3556,18 +3572,26 @@ u32 ShowGameCheckerInfo(const char* path) { state_tmd = (ValidateTmdSignature(tmd) == 0) ? 2 : 1; // CIA / title type string - char typestr[32]; + const char *typestr; if ((!state_ticket && (type&(GAME_CIA|GAME_TIE))) || !state_tmd || missing_first || (!is_dlc && (content_found != content_count))) - snprintf(typestr, 32, "Possibly Broken"); - else snprintf(typestr, 32, "%s %s%s", - console_id ? "Personal" : "Universal", - ((state_ticket == 2) && (state_tmd == 2)) ? "Legit" : - (state_tmd == 2) ? "Pirate Legit" : "Custom", - is_dlc ? " DLC" : ""); + typestr = STR_POSSIBLY_BROKEN; + else { + if (console_id) { + if (state_tmd == 2) { + if (state_ticket == 2) typestr = is_dlc ? STR_PERSONAL_LEGIT_DLC : STR_PERSONAL_LEGIT; + else typestr = is_dlc ? STR_PERSONAL_PIRATE_LEGIT_DLC : STR_PERSONAL_PIRATE_LEGIT; + } else typestr = is_dlc ? STR_PERSONAL_CUSTOM_DLC : STR_PERSONAL_CUSTOM; + } else { + if (state_tmd == 2) { + if (state_ticket == 2) typestr = is_dlc ? STR_UNIVERSAL_LEGIT_DLC : STR_UNIVERSAL_LEGIT; + else typestr = is_dlc ? STR_UNIVERSAL_PIRATE_LEGIT_DLC : STR_UNIVERSAL_PIRATE_LEGIT; + } else typestr = is_dlc ? STR_UNIVERSAL_CUSTOM_DLC : STR_UNIVERSAL_CUSTOM; + } + } char srcstr[5]; - snprintf(srcstr, 5, "%s", + snprintf(srcstr, sizeof(srcstr), "%s", (type & GAME_TIE) ? (tmd ? (sd_title ? "SD" : "NAND") : "UNK") : (type & GAME_CIA) ? "CIA" : (type & GAME_TMD) ? "TMD" : @@ -3575,30 +3599,23 @@ u32 ShowGameCheckerInfo(const char* path) { (type & GAME_TWLTMD) ? "TWL" : "UNK"); char contents_str[64]; - if (type & GAME_CIA) snprintf(contents_str, 64, "Contents in CIA: %lu/%lu", content_found, content_count); - else snprintf(contents_str, 64, "Contents in TMD: %lu", content_count); + if (type & GAME_CIA) snprintf(contents_str, sizeof(contents_str), STR_CONTENTS_IN_CIA_FOUND_TOTAL, content_found, content_count); + else snprintf(contents_str, sizeof(contents_str), STR_CONTENTS_IN_CIA_TOTAL, content_count); char conid_str[32] = { '\0' }; - if (type & (GAME_CIA|GAME_TIE)) snprintf(conid_str, 64, "Console ID: %08lX\n", console_id); + if (type & (GAME_CIA|GAME_TIE)) snprintf(conid_str, sizeof(conid_str), STR_CONSOLE_ID_N, console_id); // output results s32 state_verify = -1; while (true) { - if (!ShowPrompt(state_verify < 0, - "%s\n%s %s Title\n \n" - "Title ID: %016llX\n" - "Title version: %u.%u.%u\n" - "Contents size: %s\n" - "%s\n%s \n" - "Ticket/TMD: %s/%s\n" - "Verification: %s", + if (!ShowPrompt(state_verify < 0, STR_SHOW_GAME_INFO_DETAILS, pathstr, typestr, srcstr, title_id, (title_version>>10)&0x3F, (title_version>>4)&0x3F, (title_version)&0xF, bytestr, contents_str, conid_str, - (state_ticket == 0) ? "unknown" : (state_ticket == 2) ? "legit" : "illegit", - (state_tmd == 0) ? "invalid" : (state_tmd == 2) ? "legit" : "illegit", - (state_verify < 0) ? "pending\n \nProceed with verification?" : (state_verify == 0) ? "passed" : "failed") || + (state_ticket == 0) ? STR_STATE_UNKNOWN : (state_ticket == 2) ? STR_STATE_LEGIT : STR_STATE_ILLEGIT, + (state_tmd == 0) ? STR_STATE_INVALID : (state_tmd == 2) ? STR_STATE_LEGIT : STR_STATE_ILLEGIT, + (state_verify < 0) ? STR_STATE_PENDING_PROCEED_WITH_VERIFICATION : (state_verify == 0) ? STR_STATE_PASSED : STR_STATE_FAILED) || (state_verify >= 0)) break; state_verify = VerifyGameFile(path); } @@ -3644,7 +3661,7 @@ u32 BuildNcchInfoXorpads(const char* destdir, const char* path) { if (ret != 0) break; char dest[256]; // 256 is the maximum length of a full path - snprintf(dest, 256, "%s/%s", destdir, entry.filename); + snprintf(dest, sizeof(dest), "%s/%s", destdir, entry.filename); if (fvx_open(&fp_xorpad, dest, FA_WRITE | FA_CREATE_ALWAYS) == FR_OK) { if (!ShowProgress(0, 0, entry.filename)) ret = 1; for (u64 p = 0; (p < entry.size_b) && (ret == 0); p += STD_BUFFER_SIZE) { @@ -3674,7 +3691,7 @@ u32 GetHealthAndSafetyPaths(const char* drv, char* path_cxi, char* path_bak) { u8 secinfo[0x111]; u32 region = 0xFF; UINT br; - snprintf(path_secinfo, 32, "%s/rw/sys/SecureInfo_%c", drv, secchar); + snprintf(path_secinfo, sizeof(path_secinfo), "%s/rw/sys/SecureInfo_%c", drv, secchar); if ((fvx_qread(path_secinfo, secinfo, 0, 0x111, &br) != FR_OK) || (br != 0x111)) continue; @@ -3693,7 +3710,7 @@ u32 GetHealthAndSafetyPaths(const char* drv, char* path_cxi, char* path_bak) { TmdContentChunk* chunk = (TmdContentChunk*) (tmd + 1); for (u32 i = 0; i < 8; i++) { // 8 is an arbitrary number char path_tmd[64]; - snprintf(path_tmd, 64, "%s/title/00040010/%08lx/content/%08lx.tmd", drv, tidlow_hs, i); + snprintf(path_tmd, sizeof(path_tmd), "%s/title/00040010/%08lx/content/%08lx.tmd", drv, tidlow_hs, i); if (LoadTmdFile(tmd, path_tmd) != 0) continue; if (!getbe16(tmd->content_count)) break; if (path_cxi) snprintf(path_cxi, 64, "%s/title/00040010/%08lx/content/%08lx.app", drv, tidlow_hs, getbe32(chunk->id)); @@ -3721,7 +3738,7 @@ u32 InjectHealthAndSafety(const char* path, const char* destdrv) { // legacy stuff - remove mark file char path_mrk[32] = { 0 }; - snprintf(path_mrk, 32, "%s/%s", destdrv, "__gm9_hsbak.pth"); + snprintf(path_mrk, sizeof(path_mrk), "%s/%s", destdrv, "__gm9_hsbak.pth"); f_unlink(path_mrk); // get H&S paths @@ -3803,7 +3820,7 @@ u32 BuildTitleKeyInfo(const char* path, bool dec, bool dump) { memset(tik_info, 0, 16); if ((fvx_stat(path_out, NULL) == FR_OK) && - (ShowPrompt(true, "%s\nOutput file already exists.\nUpdate this?", path_out))) + (ShowPrompt(true, "%s\n%s", path_out, STR_OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS))) path_in = path_out; else return 0; } @@ -3896,7 +3913,7 @@ u32 BuildSeedInfo(const char* path, bool dump) { memset(seed_info, 0, 16); if ((fvx_stat(path_out, NULL) == FR_OK) && - (ShowPrompt(true, "%s\nOutput file already exists.\nUpdate this?", path_out))) { + (ShowPrompt(true, "%s\n%s", path_out, STR_OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS))) { path_in = path_out; inputtype = 1; } else return 0; @@ -4057,7 +4074,7 @@ u32 GetGoodName(char* name, const char* path, bool quick) { if (!quick && (type_donor & (GAME_CIA|GAME_TIE|GAME_TMD|GAME_CDNTMD|GAME_TWLTMD))) { u32 version = GetGameFileTitleVersion(path); if (version < 0x10000) - snprintf(version_str, 16, " (v%lu.%lu.%lu)", + snprintf(version_str, sizeof(version_str), " (v%lu.%lu.%lu)", (version>>10)&0x3F, (version>>4)&0x3F, version&0xF); } @@ -4116,17 +4133,17 @@ u32 GetGoodName(char* name, const char* path, bool quick) { if (twl->unit_code & 0x02) { // TWL char region[8] = { 0 }; - if (twl->region_flags == TWL_REGION_FREE) snprintf(region, 8, "W"); - snprintf(region, 8, "%s%s%s%s%s", + if (twl->region_flags == TWL_REGION_FREE) snprintf(region, sizeof(region), "W"); + snprintf(region, sizeof(region), "%s%s%s%s%s", (twl->region_flags & REGION_MASK_JPN) ? "J" : "", (twl->region_flags & REGION_MASK_USA) ? "U" : "", (twl->region_flags & REGION_MASK_EUR) ? "E" : "", (twl->region_flags & REGION_MASK_CHN) ? "C" : "", (twl->region_flags & REGION_MASK_KOR) ? "K" : ""); - if (strncmp(region, "JUECK", 8) == 0) snprintf(region, 8, "W"); - if (!*region) snprintf(region, 8, "UNK"); + if (strncmp(region, "JUECK", 8) == 0) snprintf(region, sizeof(region), "W"); + if (!*region) snprintf(region, sizeof(region), "UNK"); - char* unit_str = (twl->unit_code == TWL_UNITCODE_TWLNTR) ? "DSi Enhanced" : "DSi Exclusive"; + const char* unit_str = (twl->unit_code == TWL_UNITCODE_TWLNTR) ? STR_DSI_ENHANCED : STR_DSI_EXCLUSIVE; snprintf(name, 128, "%016llX%s %s (TWL-%.4s) (%s) (%s)%s.%s", twl->title_id, appid_str, title_name, twl->game_code, unit_str, region, version_str, ext); } else { // NTR @@ -4142,16 +4159,16 @@ u32 GetGoodName(char* name, const char* path, bool quick) { if (GetSmdhDescShort(title_name, smdh) != 0) return 1; char region[8] = { 0 }; - if (smdh->region_lockout == SMDH_REGION_FREE) snprintf(region, 8, "W"); - else snprintf(region, 8, "%s%s%s%s%s%s", + if (smdh->region_lockout == SMDH_REGION_FREE) snprintf(region, sizeof(region), "W"); + else snprintf(region, sizeof(region), "%s%s%s%s%s%s", (smdh->region_lockout & REGION_MASK_JPN) ? "J" : "", (smdh->region_lockout & REGION_MASK_USA) ? "U" : "", (smdh->region_lockout & REGION_MASK_EUR) ? "E" : "", (smdh->region_lockout & REGION_MASK_CHN) ? "C" : "", (smdh->region_lockout & REGION_MASK_KOR) ? "K" : "", (smdh->region_lockout & REGION_MASK_TWN) ? "T" : ""); - if (strncmp(region, "JUECKT", 8) == 0) snprintf(region, 8, "W"); - if (!*region) snprintf(region, 8, "UNK"); + if (strncmp(region, "JUECKT", 8) == 0) snprintf(region, sizeof(region), "W"); + if (!*region) snprintf(region, sizeof(region), "UNK"); snprintf(name, 128, "%016llX%s %s (%.16s) (%s)%s.%s", ncch->programId, appid_str, title_name, ncch->productcode, region, version_str, ext); diff --git a/arm9/source/utils/keydbutil.c b/arm9/source/utils/keydbutil.c index dbc38ebac..371f2bf32 100644 --- a/arm9/source/utils/keydbutil.c +++ b/arm9/source/utils/keydbutil.c @@ -1,6 +1,7 @@ #include "keydbutil.h" #include "fs.h" #include "ui.h" +#include "language.h" #include "unittype.h" #define MAX_KEYDB_SIZE (STD_BUFFER_SIZE) @@ -84,7 +85,7 @@ u32 BuildKeyDb(const char* path, bool dump) { AddKeyToDb(key_info, NULL); if ((fvx_stat(path_out, NULL) == FR_OK) && - (ShowPrompt(true, "%s\nOutput file already exists.\nUpdate this?", path_out))) + (ShowPrompt(true, "%s\n%s", path_out, STR_OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS))) path_in = path_out; else return 0; } diff --git a/arm9/source/utils/nandcmac.c b/arm9/source/utils/nandcmac.c index 569fdbff1..ab749af11 100644 --- a/arm9/source/utils/nandcmac.c +++ b/arm9/source/utils/nandcmac.c @@ -59,7 +59,7 @@ u32 SetupSlot0x30(char drv) { if ((drv == 'A') || (drv == 'S')) drv = '1'; else if ((drv == 'B') || (drv == 'E')) drv = '4'; - snprintf(movable_path, 32, "%c:/private/movable.sed", drv); + snprintf(movable_path, sizeof(movable_path), "%c:/private/movable.sed", drv); if (fvx_qread(movable_path, keyy, 0x110, 0x10, NULL) != FR_OK) return 1; setup_aeskeyY(0x30, keyy); use_aeskey(0x30); @@ -461,7 +461,7 @@ u32 RecursiveFixFileCmacWorker(char* path) { char* fname = path + strnlen(path, 255); *(fname++) = '/'; - ShowString("%s\nFixing CMACs, please wait...", pathstr); + ShowString("%s\n%s", pathstr, STR_FIXING_CMACS_PLEASE_WAIT); while (f_readdir(&pdir, &fno) == FR_OK) { if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0)) continue; // filter out virtual entries @@ -472,7 +472,7 @@ u32 RecursiveFixFileCmacWorker(char* path) { if (RecursiveFixFileCmacWorker(path) != 0) err = 1; } else if (CheckCmacPath(path) == 0) { // file, try to fix the CMAC if (FixFileCmac(path, true) != 0) err = 1; - ShowString("%s\nFixing CMACs, please wait...", pathstr); + ShowString("%s\n%s", pathstr, STR_FIXING_CMACS_PLEASE_WAIT); } } f_closedir(&pdir); diff --git a/arm9/source/utils/nandutil.c b/arm9/source/utils/nandutil.c index 745e4d19d..785ff32bc 100644 --- a/arm9/source/utils/nandutil.c +++ b/arm9/source/utils/nandutil.c @@ -150,7 +150,7 @@ u32 DumpGbaVcSavegameBuffered(const char* path, void* buffer) { // generate output path char path_vcsav[64]; - snprintf(path_vcsav, 64, OUTPUT_PATH "/%016llX.gbavc.sav", agbsave->title_id); + snprintf(path_vcsav, sizeof(path_vcsav), OUTPUT_PATH "/%016llX.gbavc.sav", agbsave->title_id); if (fvx_qwrite(path_vcsav, savegame, 0, agbsave->save_size, NULL) != FR_OK) return 1; // write fail return 0; @@ -159,7 +159,7 @@ u32 DumpGbaVcSavegameBuffered(const char* path, void* buffer) { u32 DumpGbaVcSavegame(const char* path) { u8* buffer = (u8*) malloc(AGBSAVE_MAX_SIZE); if (!buffer) { - ShowPrompt(false, "Out of memory."); + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); return 1; } @@ -177,7 +177,7 @@ u32 InjectGbaVcSavegameBuffered(const char* path, const char* path_vcsave, void* char* ext = strrchr(path_vcsave, '.'); if (!ext || ((strncasecmp(ext+1, "sav", 4) != 0) && (strncasecmp(ext+1, "srm", 4) != 0) && (strncasecmp(ext+1, "SaveRAM", 8) != 0))) return 1; // bad extension - if ((fvx_stat(path_vcsave, &fno) != FR_OK) || !GBASAVE_VALID(fno.fsize)) + if ((fvx_stat(path_vcsave, &fno) != FR_OK) || (!GBASAVE_VALID(fno.fsize) && !GBASAVE_VALID(fno.fsize - 16))) return 1; // bad size // read AGBsave header to memory @@ -207,7 +207,7 @@ u32 InjectGbaVcSavegameBuffered(const char* path, const char* path_vcsave, void* u32 slot = 0; // get the SD save path, check SD save size - snprintf(path_sd, 64, "A:/title/%08lx/%08lx/data/00000001.sav", + snprintf(path_sd, sizeof(path_sd), "A:/title/%08lx/%08lx/data/00000001.sav", getle32((u8*) &(agbsave->title_id) + 4), getle32((u8*) &(agbsave->title_id))); if ((fvx_stat(path_sd, &fno) != FR_OK) || (fno.fsize != max(AGBSAVE_MAX_SIZE, 2 * data_size))) return 1; // invalid / non-existant SD save @@ -234,7 +234,7 @@ u32 InjectGbaVcSavegameBuffered(const char* path, const char* path_vcsave, void* u32 InjectGbaVcSavegame(const char* path, const char* path_vcsave) { u8* buffer = (u8*) malloc(AGBSAVE_MAX_SIZE); if (!buffer) { - ShowPrompt(false, "Out of memory."); + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); return 1; } @@ -328,21 +328,20 @@ u32 ValidateNandDump(const char* path) { // check NAND header NandNcsdHeader ncsd; if ((ReadNandFile(&file, &ncsd, 0, 1, 0xFF) != 0) || (ValidateNandNcsdHeader(&ncsd) != 0)) { - ShowPrompt(false, "%s\nNCSD header is not valid", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_NCSD_HEADER_IS_NOT_VALID); fvx_close(&file); return 1; } // check size if (fvx_size(&file) < (GetNandNcsdMinSizeSectors(&ncsd) * 0x200)) { - ShowPrompt(false, "%s\nNAND dump misses data", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_NAND_DUMP_MISSING_DATA); fvx_close(&file); return 1; } // check TWL & CTR FAT partitions for (u32 i = 0; i < 2; i++) { - char* section_type = (i) ? "CTR" : "MBR"; if (i == 0) { // check TWL first, then CTR if (GetNandNcsdPartitionInfo(&info, NP_TYPE_STD, NP_SUBTYPE_TWL, 0, &ncsd) != 0) return 1; } else if ((GetNandNcsdPartitionInfo(&info, NP_TYPE_STD, NP_SUBTYPE_CTR, 0, &ncsd) != 0) && @@ -350,7 +349,7 @@ u32 ValidateNandDump(const char* path) { MbrHeader mbr; if ((ReadNandFile(&file, &mbr, info.sector, 1, info.keyslot) != 0) || (ValidateMbrHeader(&mbr) != 0)) { - ShowPrompt(false, "%s\nError: %s MBR is corrupt", pathstr, section_type); + ShowPrompt(false, "%s\n%s", pathstr, i ? STR_ERROR_CTR_MBR_IS_CORRUPT : STR_ERROR_TWL_MBR_IS_CORRUPT); fvx_close(&file); return 1; // impossible to happen } @@ -360,7 +359,7 @@ u32 ValidateNandDump(const char* path) { if (!p_sector) continue; if ((ReadNandFile(&file, fat, info.sector + p_sector, 1, info.keyslot) != 0) || (ValidateFatHeader(fat) != 0)) { - ShowPrompt(false, "%s\nError: %s partition%u is corrupt", pathstr, section_type, p); + ShowPrompt(false, i ? STR_PATH_ERROR_CTR_PARTITION_N_IS_CORRUPT : STR_PATH_ERROR_TWL_PARTITION_N_IS_CORRUPT, pathstr, p); fvx_close(&file); return 1; } @@ -374,7 +373,7 @@ u32 ValidateNandDump(const char* path) { // check all 8 firms, also check if ARM9 & ARM11 entrypoints are available for (u32 f = 0; f <= 8; f++) { if (GetNandNcsdPartitionInfo(&info, NP_TYPE_FIRM, NP_SUBTYPE_CTR, f, &ncsd) != 0) { - ShowPrompt(false, "%s\nNo valid FIRM found", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_NO_VALID_FIRM_FOUND); fvx_close(&file); free(firm); return 1; @@ -395,19 +394,19 @@ u32 ValidateNandDump(const char* path) { u32 SafeRestoreNandDump(const char* path) { if ((ValidateNandDump(path) != 0) && // NAND dump validation - !ShowPrompt(true, "Error: NAND dump is corrupt.\nStill continue?")) + !ShowPrompt(true, "%s", STR_ERROR_NAND_DUMP_IS_CORRUPT_STILL_CONTINUE)) return 1; if (!IS_UNLOCKED) { - ShowPrompt(false, "Error: System is locked."); + ShowPrompt(false, "%s", STR_ERROR_SYSTEM_IS_LOCKED); return 1; } if (fvx_stat("S:/essential.exefs", NULL) != FR_OK) { - if (ShowPrompt(true, "Essential files backup is required.\nCreate one now?")) + if (ShowPrompt(true, "%s", STR_ESSENTIAL_FILES_BACKUP_IS_REQUIRED_CREATE_ONE_NOW)) EmbedEssentialBackup("S:/nand.bin"); else return 1; } - if (!ShowUnlockSequence(5, "!WARNING!\n \nProceeding will overwrite the\nSysNAND with the provided dump.\n \n(B9S/A9LH will be left intact.)")) + if (!ShowUnlockSequence(5, "%s", STR_WARNING_PROCEEDING_WILL_OVERWRITE_SYSNAND_WITH_DUMP)) return 1; if (!SetWritePermissions(PERM_SYS_LVL1, true)) return 1; @@ -447,7 +446,7 @@ u32 SafeRestoreNandDump(const char* path) { break; } if (!header_inject || (ValidateNandNcsdHeader(&ncsd_img) != 0) || (ValidateMbrHeader(&twl_mbr_img) != 0)) { - ShowPrompt(false, "Image NCSD corrupt or customized,\nsafe restore is not possible!"); + ShowPrompt(false, "%s", STR_IMAGE_NCSD_CORRUPT_OR_CUSTOMIZED_SAFE_RESTORE_NOT_POSSIBLE); fvx_close(&file); return 1; } @@ -455,7 +454,7 @@ u32 SafeRestoreNandDump(const char* path) { // additional warning for elevated write permissions if (header_inject) { - if (!ShowPrompt(true, "!WARNING!\n \nNCSD differs between image and local,\nelevated write permissions required\n \nProceed on your own risk?") || + if (!ShowPrompt(true, "%s", STR_WARNING_NCSD_DIFFERS_BETWEEN_IMAGE_AND_LOCAL_ELEVATED_WRITE_PERMISSIONS_REQUIRED) || !SetWritePermissions(PERM_SYS_LVL3, true)) { fvx_close(&file); return 1; @@ -508,8 +507,8 @@ u32 SafeInstallFirmBuffered(const char* path, u32 slots, u8* buffer, u32 bufsiz) UINT firm_size; if ((fvx_qread(path, firm, 0, bufsiz, &firm_size) != FR_OK) || !firm_size || !IsInstallableFirm(firm, firm_size)) { - ShowPrompt(false, IsBootableFirm(firm, firm_size) ? - "%s\nNot a installable FIRM." : "%s\nFIRM load/verify error.", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, IsBootableFirm(firm, firm_size) ? + STR_NOT_AN_INSTALLABLE_FIRM : STR_FIRM_LOAD_VERIFY_ERROR); return 1; } @@ -524,7 +523,7 @@ u32 SafeInstallFirmBuffered(const char* path, u32 slots, u8* buffer, u32 bufsiz) if (!((slots>>s)&0x1)) continue; if ((GetNandPartitionInfo(&info, NP_TYPE_FIRM, NP_SUBTYPE_CTR, s, NAND_SYSNAND) != 0) || ((info.count * 0x200) < firm_size)) { - ShowPrompt(false, "%s\nFIRM%lu not found or too small.", pathstr, s); + ShowPrompt(false, STR_PATH_FIRM_N_NOT_FOUND_OR_TOO_SMALL, pathstr, s); return 1; } } @@ -534,7 +533,7 @@ u32 SafeInstallFirmBuffered(const char* path, u32 slots, u8* buffer, u32 bufsiz) bool fix_sector0x96 = false; ReadNandSectors(sector0x96, 0x96, 1, 0x11, NAND_SYSNAND); if (!IS_O3DS && !CheckSector0x96Crypto()) { - ShowPrompt(false, "%s\nSector 0x96 crypto fail.", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_SECTOR_0X96_CRYPTO_FAIL); return 1; } if (!IS_O3DS && (ValidateSecretSector(sector0x96) != 0)) { @@ -546,21 +545,21 @@ u32 SafeInstallFirmBuffered(const char* path, u32 slots, u8* buffer, u32 bufsiz) else *path_sector = '\0'; if ((fvx_qread(path_sector, sector0x96, 0, 0x200, NULL) != FR_OK) || (ValidateSecretSector(sector0x96) != 0)) { - ShowPrompt(false, "%s\nSector 0x96 is corrupted.\n \nProvide \"secret_sector.bin\"\nto fix sector 0x96.", pathstr); + ShowPrompt(false, "%s\n%s", pathstr, STR_SECTOR_0X96_CORRUPTED_PROVIDE_SECRET_SECTOR_BIN_TO_FIX); return 1; - } else if (ShowPrompt(true, "%s\nSector 0x96 is corrupted.\n \nFix sector 0x96 during\nthe installation?", pathstr)) { + } else if (ShowPrompt(true, "%s\n%s", pathstr, STR_SECTOR_0X96_CORRUPTED_FIX_DURING_INSTALLATION)) { fix_sector0x96 = true; } else return 1; } // all checked, ready to go - if (!ShowUnlockSequence(6, "!WARNING!\n \nProceeding will install the\nprovided FIRM to the SysNAND\nand inject sighax.\n \nInstalling an unsupported FIRM\nwill BRICK your console!")) return 1; + if (!ShowUnlockSequence(6, "%s", STR_WARNING_PROCEEDING_WILL_INSTALL_FIRM_TO_SYSNAND_AND_INJECT_SIGHAX_UNSUPPORTED_FIRM_WILL_BRICK)) return 1; // if (!SetWritePermissions(PERM_SYS_LVL3, true)) return 1; // one unlock sequence is enough // point of no return - ShowString(false, "Installing FIRM, please wait..."); + ShowString("%s", STR_INSTALLING_FIRM_PLEASE_WAIT); if (fix_sector0x96 && (WriteNandSectors(sector0x96, 0x96, 1, 0x11, NAND_SYSNAND) != 0)) { - ShowPrompt(false, "!THIS IS BAD!\n \nFailed writing sector 0x96.\nTry to fix before reboot!"); + ShowPrompt(false, "%s", STR_THIS_IS_BAD_FAILED_WRITING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT); return 1; } for (u32 s = 0; s < 8; s++) { @@ -568,16 +567,16 @@ u32 SafeInstallFirmBuffered(const char* path, u32 slots, u8* buffer, u32 bufsiz) if (!((slots>>s)&0x1)) continue; if ((GetNandPartitionInfo(&info, NP_TYPE_FIRM, NP_SUBTYPE_CTR, s, NAND_SYSNAND) != 0) || (WriteNandBytes(firm, info.sector*0x200, firm_size, info.keyslot, NAND_SYSNAND) != 0)) { - ShowPrompt(false, "!THIS IS BAD!\n \nFailed writing FIRM%lu.\nTry to fix before reboot!", s); + ShowPrompt(false, STR_THIS_IS_BAD_FAILED_WRITING_FIRM_N_TRY_FIX_BEFORE_REBOOT, s); return 1; } } // done, now check the installation - ShowString(false, "Checking installation, please wait..."); + ShowString("%s", STR_CHECKING_INSTALLATION_PLEASE_WAIT); if (fix_sector0x96 && ((ReadNandSectors(sector0x96, 0x96, 1, 0x11, NAND_SYSNAND) != 0) || (ValidateSecretSector(sector0x96) != 0))) { - ShowPrompt(false, "!THIS IS BAD!\n \nFailed verifying sector 0x96.\nTry to fix before reboot!"); + ShowPrompt(false, "%s", STR_THIS_IS_BAD_FAILED_VERIFYING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT); return 1; } for (u32 s = 0; s < 8; s++) { @@ -586,7 +585,7 @@ u32 SafeInstallFirmBuffered(const char* path, u32 slots, u8* buffer, u32 bufsiz) if ((GetNandPartitionInfo(&info, NP_TYPE_FIRM, NP_SUBTYPE_CTR, s, NAND_SYSNAND) != 0) || (ReadNandBytes(firm, info.sector*0x200, firm_size, info.keyslot, NAND_SYSNAND) != 0) || (sha_cmp(firm_sha, firm, firm_size, SHA256_MODE) != 0)) { - ShowPrompt(false, "!THIS IS BAD!\n \nFailed verifying FIRM%lu.\nTry to fix before reboot!", s); + ShowPrompt(false, STR_THIS_IS_BAD_FAILED_VERIFYING_FIRM_N_TRY_FIX_BEFORE_REBOOT, s); return 1; } } @@ -597,7 +596,7 @@ u32 SafeInstallFirmBuffered(const char* path, u32 slots, u8* buffer, u32 bufsiz) u32 SafeInstallFirm(const char* path, u32 slots) { u8* buffer = (u8*) malloc(FIRM_MAX_SIZE); if (!buffer) { - ShowPrompt(false, "Out of memory."); + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); return 1; } @@ -616,20 +615,20 @@ u32 SafeInstallKeyDb(const char* path) { // already installed? if ((ReadNandBytes(keydb, SECTOR_KEYDB*0x200, KEYDB_PERFECT_SIZE, 0xFF, NAND_SYSNAND) == 0) && (sha_cmp(perfect_sha, keydb, KEYDB_PERFECT_SIZE, SHA256_MODE) == 0)) { - ShowPrompt(false, "Perfect " KEYDB_NAME " is already installed!"); + ShowPrompt(false, STR_PERFECT_KEYDB_IS_ALREADY_INSTALLED, KEYDB_NAME); return 1; } // check input path... if ((fvx_qread(path, keydb, 0, KEYDB_PERFECT_SIZE, NULL) != FR_OK) || (sha_cmp(perfect_sha, keydb, KEYDB_PERFECT_SIZE, SHA256_MODE) != 0)) { - ShowPrompt(false, "%s\nNot a perfect " KEYDB_NAME " image.\nCannot install to NAND!", pathstr); + ShowPrompt(false, STR_PATH_NOT_PERFECT_KEYDB_IMAGE_CANNOT_INSTALL_TO_NAND, pathstr, KEYDB_NAME); return 1; } // point of no return, install key database if (WriteNandBytes(keydb, SECTOR_KEYDB*0x200, KEYDB_PERFECT_SIZE, 0xFF, NAND_SYSNAND) != 0) { - ShowPrompt(false, "%s\nFailed writing " KEYDB_NAME " to NAND!", pathstr); + ShowPrompt(false, STR_PATH_FAILED_WRITING_KEYDB_TO_NAND, pathstr, KEYDB_NAME); return 1; } diff --git a/arm9/source/utils/paint9.c b/arm9/source/utils/paint9.c index 7bedd0cf8..213adf0e9 100644 --- a/arm9/source/utils/paint9.c +++ b/arm9/source/utils/paint9.c @@ -3,6 +3,7 @@ #include "png.h" #include "hid.h" #include "ui.h" +#include "language.h" #define PAINT9_BRUSH_SIZE 15 // don't change! @@ -103,7 +104,7 @@ u32 Paint9(void) { u32 brush_id = 0; // clear screens, draw logo - const char* snapstr = "(use L+R to save)"; + const char* snapstr = STR_USE_L_R_TO_SAVE; u64 logo_size; u8* logo = FindVTarFileInfo(VRAM0_EASTER_BIN, &logo_size); ClearScreenF(true, true, COLOR_STD_BG); @@ -114,9 +115,9 @@ u32 Paint9(void) { DrawBitmap(TOP_SCREEN, -1, -1, logo_width, logo_height, bitmap); free(bitmap); } - } else DrawStringF(TOP_SCREEN, 10, 10, COLOR_STD_FONT, COLOR_TRANSPARENT, "(" VRAM0_EASTER_BIN " not found)"); + } else DrawStringF(TOP_SCREEN, 10, 10, COLOR_STD_FONT, COLOR_TRANSPARENT, STR_EASTER_NOT_FOUND, VRAM0_EASTER_BIN); DrawStringF(TOP_SCREEN, SCREEN_WIDTH_TOP - 10 - GetDrawStringWidth(snapstr), - SCREEN_HEIGHT - 10 - GetDrawStringHeight(snapstr), COLOR_STD_FONT, COLOR_TRANSPARENT, snapstr); + SCREEN_HEIGHT - 10 - GetDrawStringHeight(snapstr), COLOR_STD_FONT, COLOR_TRANSPARENT, "%s", snapstr); // outline canvas DrawRectangle(BOT_SCREEN, 0, 0, 30, SCREEN_HEIGHT, outline_bg); diff --git a/arm9/source/utils/scripting.c b/arm9/source/utils/scripting.c index 1f6b0e9a8..41ebe07a1 100644 --- a/arm9/source/utils/scripting.c +++ b/arm9/source/utils/scripting.c @@ -422,7 +422,7 @@ void upd_var(const char* name) { if (FileGetData(path, sd_keyy, 0x10, 0x110) == 0x10) { u32 sha256sum[8]; sha_quick(sha256sum, sd_keyy, 0x10, SHA256_MODE); - snprintf(env_id0, 32+1, "%08lx%08lx%08lx%08lx", + snprintf(env_id0, sizeof(env_id0), "%08lx%08lx%08lx%08lx", sha256sum[0], sha256sum[1], sha256sum[2], sha256sum[3]); } else snprintf(env_id0, 0xF, "UNKNOWN"); set_var(env_id0_name, env_id0); @@ -435,8 +435,8 @@ void upd_var(const char* name) { get_dstime(&dstime); char env_date[16+1]; char env_time[16+1]; - snprintf(env_date, 16, "%02lX%02lX%02lX", (u32) dstime.bcd_Y, (u32) dstime.bcd_M, (u32) dstime.bcd_D); - snprintf(env_time, 16, "%02lX%02lX%02lX", (u32) dstime.bcd_h, (u32) dstime.bcd_m, (u32) dstime.bcd_s); + snprintf(env_date, sizeof(env_date), "%02lX%02lX%02lX", (u32) dstime.bcd_Y, (u32) dstime.bcd_M, (u32) dstime.bcd_D); + snprintf(env_time, sizeof(env_time), "%02lX%02lX%02lX", (u32) dstime.bcd_h, (u32) dstime.bcd_m, (u32) dstime.bcd_s); if (!name || (strncmp(name, "DATESTAMP", _VAR_NAME_LEN) == 0)) set_var("DATESTAMP", env_date); if (!name || (strncmp(name, "TIMESTAMP", _VAR_NAME_LEN) == 0)) set_var("TIMESTAMP", env_time); } @@ -445,7 +445,7 @@ void upd_var(const char* name) { if (!name || (strncmp(name, "EMUBASE", _VAR_NAME_LEN) == 0)) { u32 emu_base = GetEmuNandBase(); char emu_base_str[8+1]; - snprintf(emu_base_str, 8+1, "%08lX", emu_base); + snprintf(emu_base_str, sizeof(emu_base_str), "%08lX", emu_base); set_var("EMUBASE", emu_base_str); } @@ -527,7 +527,6 @@ bool init_vars(const char* path_script) { set_var("RDTYPE", IS_DEVKIT ? "devkit" : "retail"); // devkit / retail char* ptr = set_var("GM9VER", VERSION); // GodMode9 version, truncated below while (*(ptr++) != '\0') if (*ptr == '-') *ptr = '\0'; - upd_var(NULL); // set all dynamic environment vars return true; } @@ -572,11 +571,11 @@ cmd_id get_cmd_id(char* cmd, u32 len, u32 flags, u32 argc, char* err_str) { } if (!cmd_entry) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "unknown cmd"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_UNKNOWN_CMD); } else if (cmd_entry->n_args != argc) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "bad # of args"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_BAD_NUMBER_OF_ARGS); } else if (~(cmd_entry->allowed_flags|_FLG('o')|_FLG('s')) & flags) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "unrecognized flags"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_UNRECOGNIZED_FLAGS); } else return cmd_entry->id; return CMD_ID_NONE; @@ -609,7 +608,7 @@ u32 get_flag(char* str, u32 len, char* err_str) { else if (strncmp(str, "--explorer", len) == 0) flag_char = 'x'; if (((flag_char < 'a') || (flag_char > 'z')) && ((flag_char < '0') || (flag_char > '5'))) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "illegal flag"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ILLEGAL_FLAG); return 0; } @@ -629,7 +628,7 @@ char* get_string(char* ptr, const char* line_end, u32* len, char** next, char* e str = ++ptr; for (; ((*ptr != '\"') || (*(ptr-1) == '\\')) && (ptr < line_end); ptr++, (*len)++); if (ptr >= line_end) { // failed if unresolved quotes - if (err_str) snprintf(err_str, _ERR_STR_LEN, "unresolved quotes"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_UNRESOLVED_QUOTES); return NULL; } *next = ptr + 1; @@ -651,29 +650,29 @@ char* skip_block(char* ptr, bool ignore_else, bool stop_after_end) { // grab first string char* str = NULL; - u32 str_len = 0; - if (!(str = get_string(ptr, line_end, &str_len, &ptr, NULL)) || (str >= line_end)) { + u32 STR_SCRIPTERR_len = 0; + if (!(str = get_string(ptr, line_end, &STR_SCRIPTERR_len, &ptr, NULL)) || (str >= line_end)) { // string error or empty line ptr = line_end + 1; continue; } // check string - if (MATCH_STR(str, str_len, _CMD_END)) { // stop at end + if (MATCH_STR(str, STR_SCRIPTERR_len, _CMD_END)) { // stop at end return line_start; // end of block found - } else if (!ignore_else && MATCH_STR(str, str_len, _CMD_ELSE)) { // stop at else + } else if (!ignore_else && MATCH_STR(str, STR_SCRIPTERR_len, _CMD_ELSE)) { // stop at else return line_start; // end of block found - } else if (!ignore_else && MATCH_STR(str, str_len, _CMD_ELIF)) { // stop at elif + } else if (!ignore_else && MATCH_STR(str, STR_SCRIPTERR_len, _CMD_ELIF)) { // stop at elif return line_start; // end of block found - } else if (MATCH_STR(str, str_len, _CMD_IF)) { + } else if (MATCH_STR(str, STR_SCRIPTERR_len, _CMD_IF)) { ptr = line_start = skip_block(line_end + 1, true, false); if (ptr == NULL) return NULL; line_end = strchr(ptr, '\n'); if (!line_end) line_end = ptr + strlen(ptr); - str = get_string(ptr, line_end, &str_len, &ptr, NULL); - if (!(MATCH_STR(str, str_len, _CMD_END))) return NULL; + str = get_string(ptr, line_end, &STR_SCRIPTERR_len, &ptr, NULL); + if (!(MATCH_STR(str, STR_SCRIPTERR_len, _CMD_END))) return NULL; if (stop_after_end) return line_end + 1; } @@ -694,19 +693,19 @@ char* find_next(char* ptr) { // grab first string char* str = NULL; - u32 str_len = 0; - if (!(str = get_string(ptr, line_end, &str_len, &ptr, NULL)) || (str >= line_end)) { + u32 STR_SCRIPTERR_len = 0; + if (!(str = get_string(ptr, line_end, &STR_SCRIPTERR_len, &ptr, NULL)) || (str >= line_end)) { // string error or empty line ptr = line_end + 1; continue; } // check string - if (MATCH_STR(str, str_len, _CMD_IF)) { // skip 'if' blocks + if (MATCH_STR(str, STR_SCRIPTERR_len, _CMD_IF)) { // skip 'if' blocks ptr = skip_block(ptr, true, true); - } else if (MATCH_STR(str, str_len, _CMD_END) || MATCH_STR(str, str_len, _CMD_FOR)) { + } else if (MATCH_STR(str, STR_SCRIPTERR_len, _CMD_END) || MATCH_STR(str, STR_SCRIPTERR_len, _CMD_FOR)) { ptr = NULL; // this should not happen here - } else if (MATCH_STR(str, str_len, _CMD_NEXT)) { + } else if (MATCH_STR(str, STR_SCRIPTERR_len, _CMD_NEXT)) { return line_start; } @@ -739,28 +738,28 @@ char* find_label(const char* label, const char* last_found) { // search for label char* str = NULL; - u32 str_len = 0; - if (!(str = get_string(ptr, line_end, &str_len, &ptr, NULL))) continue; // string error, ignore line + u32 STR_SCRIPTERR_len = 0; + if (!(str = get_string(ptr, line_end, &STR_SCRIPTERR_len, &ptr, NULL))) continue; // string error, ignore line else if (str >= line_end) continue; // empty line if (*str == '@') { // label found - str++; str_len--; + str++; STR_SCRIPTERR_len--; // compare it manually (also check for '*' at end) u32 pdiff = 0; - for (; (pdiff < str_len) && (label[pdiff] == str[pdiff]); pdiff++); + for (; (pdiff < STR_SCRIPTERR_len) && (label[pdiff] == str[pdiff]); pdiff++); if ((pdiff < label_len) && (label[pdiff] != '*')) continue; // no match // otherwise: potential regular or wildcard match // may be a match, see if there are more strings after it - if (!(str = get_string(ptr, line_end, &str_len, &ptr, NULL))) continue; // string error, ignore line + if (!(str = get_string(ptr, line_end, &STR_SCRIPTERR_len, &ptr, NULL))) continue; // string error, ignore line else if ((str < line_end) && (*str != '#')) continue; // neither end of line nor comment return line_start; // match found - } else if (MATCH_STR(str, str_len, _CMD_IF)) { + } else if (MATCH_STR(str, STR_SCRIPTERR_len, _CMD_IF)) { next = skip_block(line_start, true, true); - } else if (MATCH_STR(str, str_len, _CMD_FOR)) { + } else if (MATCH_STR(str, STR_SCRIPTERR_len, _CMD_FOR)) { next = find_next(line_start); } // otherwise: irrelevant line } @@ -782,8 +781,8 @@ bool for_handler(char* path, const char* dir, const char* pattern, bool recursiv } if (dir) { // open a dir - snprintf(lpattern, 64, "%s", pattern); - snprintf(ldir, 256, "%s", dir); + snprintf(lpattern, sizeof(lpattern), "%s", pattern); + snprintf(ldir, sizeof(ldir), "%s", dir); if (dp) return false; // <- this should never happen if (fvx_opendir(&fdir[0], dir) != FR_OK) return false; @@ -848,10 +847,10 @@ bool parse_line(const char* line_start, const char* line_end, cmd_id* cmdid, u32 if (!flag_add) return false; // not a proper flag *flags |= flag_add; } else if (*argc >= _MAX_ARGS) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "too many arguments"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_TOO_MANY_ARGUMENTS); return false; // too many arguments } else if (!expand_arg(argv[(*argc)++], str, len)) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "argument expand failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ARGUMENT_EXPAND_FAILED); return false; // arg expand failed } } @@ -882,7 +881,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { // check the argument // "not true" or "not false" ret = (strncmp(argv[0], _ARG_FALSE, _ARG_MAX_LEN) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "'not' an error"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_QUOTE_NOT_AN_ERROR); } else if (id == CMD_ID_IF) { // check the argument @@ -891,13 +890,13 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { ifcnt++; if (syntax_error && err_str) - snprintf(err_str, _ERR_STR_LEN, "syntax error after 'if'"); + snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SYNTAX_ERROR_AFTER_IF); ret = !syntax_error; } else if (id == CMD_ID_ELIF) { // check syntax errors if (ifcnt == 0) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "'elif' without 'if'"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ELIF_WITHOUT_IF); syntax_error = true; return false; } @@ -908,13 +907,13 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { ((strncmp(argv[0], _ARG_TRUE, _ARG_MAX_LEN) == 0) ? 0 : _SKIP_BLOCK); if (syntax_error && err_str) - snprintf(err_str, _ERR_STR_LEN, "syntax error after 'elif'"); + snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SYNTAX_ERROR_AFTER_ELIF); ret = !syntax_error; } else if (id == CMD_ID_ELSE) { // check syntax errors if (ifcnt == 0) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "'else' without 'if'"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ELSE_WITHOUT_IF); syntax_error = true; return false; } @@ -927,7 +926,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { else if (id == CMD_ID_END) { // check syntax errors if (ifcnt == 0){ - if (err_str) snprintf(err_str, _ERR_STR_LEN, "'end' without 'if'"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_END_WITHOUT_IF); syntax_error = true; return false; } @@ -942,11 +941,11 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { // cheating alert(!): actually this does nothing much // just sets up the for_handler and skips to 'next' if (for_ptr) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "'for' inside 'for'"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FOR_INSIDE_FOR); syntax_error = true; return false; } else if (!for_handler(NULL, argv[0], argv[1], flags & _FLG('r'))) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "dir not found"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_DIR_NOT_FOUND); skip_state = _SKIP_TO_NEXT; ret = false; } else { @@ -959,11 +958,11 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { char* var = set_var(_VAR_FORPATH, ""); ret = true; if (!for_ptr) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "'next' without 'for'"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_NEXT_WITHOUT_FOR); syntax_error = true; return false; } else if (!var) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "forpath error"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FORPATH_ERROR); ret = false; } else { if (!for_handler(var, NULL, NULL, false)) *var = '\0'; @@ -981,7 +980,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { jump_ptr = find_label(argv[0], NULL); if (!jump_ptr) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "label not found"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_LABEL_NOT_FOUND); } } else if (id == CMD_ID_LABELSEL) { @@ -1022,12 +1021,12 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { if (!result) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "user abort"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_USER_ABORT); } else jump_ptr = options_jmp[result-1]; } else if (id == CMD_ID_KEYCHK) { ret = CheckButton(StringToButton(argv[0])); - if (!ret && err_str) snprintf(err_str, _ERR_STR_LEN, "key not pressed"); + if (!ret && err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_KEY_NOT_PRESSED); } else if (id == CMD_ID_ECHO) { ShowPrompt(false, "%s", argv[0]); @@ -1044,12 +1043,12 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { DrawQrCode(ALT_SCREEN, qrcode); ShowPrompt(false, "%s", argv[0]); memcpy(ALT_SCREEN, screen_copy, screen_size); - } else if (err_str) snprintf(err_str, _ERR_STR_LEN, "out of memory"); + } else if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_OUT_OF_MEMORY); free(screen_copy); } else if (id == CMD_ID_ASK) { ret = ShowPrompt(true, "%s", argv[0]); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "user abort"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_USER_ABORT); } else if (id == CMD_ID_INPUT) { char input[_VAR_CNT_LEN] = { 0 }; @@ -1058,10 +1057,10 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { input[_VAR_CNT_LEN - 1] = '\0'; ret = ShowKeyboardOrPrompt(input, _VAR_CNT_LEN, "%s", argv[0]); if (ret) set_var(argv[1], ""); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "user abort"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_USER_ABORT); if (ret) { ret = set_var(argv[1], input); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_VAR_FAIL); } } else if ((id == CMD_ID_FILESEL) || (id == CMD_ID_DIRSEL)) { @@ -1075,31 +1074,31 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { path[_VAR_CNT_LEN - 1] = '\0'; if (strncmp(path, "Z:", 2) == 0) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "forbidden drive"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FORBIDDEN_DRIVE); } else if (id == CMD_ID_FILESEL) { char* npattern = strrchr(path, '/'); if (!npattern) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "invalid path"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_INVALID_PATH); } else { u32 flags_ext = (flags & _FLG('d')) ? 0 : NO_DIRS; *(npattern++) = '\0'; ret = FileSelector(choice, argv[0], path, npattern, flags_ext, (flags & _FLG('x'))); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "fileselect abort"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FILESELECT_ABORT); } } else { ret = FileSelector(choice, argv[0], path, NULL, NO_FILES | SELECT_DIRS, (flags & _FLG('x'))); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "dirselect abort"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_DIRSELECT_ABORT); } if (ret) { ret = set_var(argv[2], choice); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_VAR_FAIL); } } else if (id == CMD_ID_SET) { ret = set_var(argv[0], argv[1]); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "set fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SET_FAIL); } else if (id == CMD_ID_STRSPLIT) { char str[_ARG_MAX_LEN]; @@ -1111,16 +1110,16 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { char* found; if (flags & _FLG('f')) found = strchr(str, *argv[2]); else found = strrchr(str, *argv[2]); - if (!found && err_str) snprintf(err_str, _ERR_STR_LEN, "char not found"); + if (!found && err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_CHAR_NOT_FOUND); if (found) { if (flags & _FLG('b')) { *found = '\0'; ret = set_var(argv[0], str); } else ret = set_var(argv[0], found+1); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_VAR_FAIL); } - } else if (err_str) snprintf(err_str, _ERR_STR_LEN, "argv[2] is not a char"); + } else if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ARGV_2_IS_NOT_CHAR); } else if (id == CMD_ID_STRREP) { char str[_ARG_MAX_LEN]; @@ -1128,29 +1127,29 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { str[_ARG_MAX_LEN - 1] = '\0'; if (strnlen(argv[2], _ARG_MAX_LEN) != 2) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "argv[2] must be 2 chars"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ARGV_2_MUST_BE_2_CHARS); ret = false; } else { for (u32 i = 0; (i < _ARG_MAX_LEN) && str[i]; i++) { if (str[i] == argv[2][0]) str[i] = argv[2][1]; } ret = set_var(argv[0], str); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_VAR_FAIL); } } else if (id == CMD_ID_CHK) { if (flags & _FLG('u')) { ret = (strncasecmp(argv[0], argv[1], _VAR_CNT_LEN) != 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "arg match"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ARG_MATCH); } else { ret = (strncasecmp(argv[0], argv[1], _VAR_CNT_LEN) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "no arg match"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_NO_ARG_MATCH); } } else if (id == CMD_ID_ALLOW) { if (flags & _FLG('a')) ret = CheckDirWritePermissions(argv[0]); else ret = CheckWritePermissions(argv[0]); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "permission fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_PERMISSION_FAIL); } else if (id == CMD_ID_CP) { u32 flags_ext = BUILD_PATH; @@ -1162,7 +1161,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { else if (flags & _FLG('k')) flags_ext |= SKIP_ALL; else if (flags & _FLG('p')) flags_ext |= APPEND_ALL; ret = PathMoveCopy(argv[1], argv[0], &flags_ext, false); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "copy fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_COPY_FAIL); } else if (id == CMD_ID_MV) { u32 flags_ext = BUILD_PATH; @@ -1171,7 +1170,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { if (flags & _FLG('w')) flags_ext |= OVERWRITE_ALL; else if (flags & _FLG('k')) flags_ext |= SKIP_ALL; ret = PathMoveCopy(argv[1], argv[0], &flags_ext, true); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "move fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_MOVE_FAIL); } else if (id == CMD_ID_INJECT) { char* atstr_dst = strrchr(argv[1], '@'); @@ -1183,7 +1182,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { u32 flags_ext = ALLOW_EXPAND; if (flags & _FLG('n')) flags_ext |= NO_CANCEL; ret = FileInjectFile(argv[1], argv[0], at_dst, at_org, sz_org, &flags_ext); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "inject fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_INJECT_FAIL); } else if (id == CMD_ID_FILL) { u32 flags_ext = ALLOW_EXPAND; @@ -1191,21 +1190,21 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { u8 fillbyte = 0; if ((strnlen(argv[1], _ARG_MAX_LEN) != 2) || !strntohex(argv[1], &fillbyte, 1)) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "fillbyte fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FILLBYTE_FAIL); } else { if (flags & _FLG('n')) flags_ext |= NO_CANCEL; ret = FileSetByte(argv[0], at_org, sz_org, fillbyte, &flags_ext); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "fill fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FILL_FAIL); } } else if (id == CMD_ID_FDUMMY) { u32 fsize; if (sscanf(argv[1], "%lX", &fsize) != 1) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "bad filesize"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_BAD_FILESIZE); } else { ret = FileCreateDummy(argv[0], NULL, fsize); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "create dummy fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_CREATE_DUMMY_FILE); } } else if (id == CMD_ID_RM) { @@ -1213,15 +1212,15 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { TruncateString(pathstr, argv[0], 24, 8); ShowString("Deleting %s...", pathstr); ret = PathDelete(argv[0]); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "remove fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_REMOVE_FAIL); } else if (id == CMD_ID_MKDIR) { ret = (CheckWritePermissions(argv[0])) && (fvx_rmkdir(argv[0]) == FR_OK); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "makedir fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_MAKEDIR_FAIL); } else if (id == CMD_ID_MOUNT) { ret = InitImgFS(argv[0]); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "mount fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_MOUNT_FAIL); } else if (id == CMD_ID_UMOUNT) { InitImgFS(NULL); @@ -1230,37 +1229,37 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { char path[_VAR_CNT_LEN]; u8 mode = (flags & _FLG('f')) ? FN_LOWEST : FN_HIGHEST; ret = (fvx_findpath(path, argv[0], mode) == FR_OK); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "find fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FIND_FAIL); if (ret) { ret = set_var(argv[1], path); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_VAR_FAIL); } } else if (id == CMD_ID_FINDNOT) { char path[_VAR_CNT_LEN]; ret = (fvx_findnopath(path, argv[0]) == FR_OK); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "findnot fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FINDNOT_FAIL); if (ret) { ret = set_var(argv[1], path); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_VAR_FAIL); } } else if (id == CMD_ID_FGET) { u8 data[(_VAR_CNT_LEN-1)/2]; if (sz_org == 0) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "no size given"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_NO_SIZE_GIVEN); } else if (sz_org > (_VAR_CNT_LEN-1)/2) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "size too big"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_FIRM_TOO_BIG); } else if (FileGetData(argv[0], data, sz_org, at_org) != sz_org) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "read fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_READ_FAIL); } else { char* var = set_var(argv[1], ""); if (!var) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_VAR_FAIL); } else { if (flags & _FLG('e')) { // flip data for (u32 i = 0; i < (sz_org >> 1); i++) { @@ -1270,7 +1269,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { } } ret = hexntostr(data, var, sz_org); - if (!ret && err_str) snprintf(err_str, _ERR_STR_LEN, "conversion fail"); + if (!ret && err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_CONVERSION_FAIL); } } } @@ -1287,13 +1286,13 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { } if (!len) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "invalid data"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_INVALID_DATA); } else if (sz_org > len) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "size too big"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SIZE_TOO_BIG); } else if (!FileSetData(argv[0], data, sz_org, at_org, false)) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "write fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_WRITE_FAIL); } } else if (id == CMD_ID_SHA) { @@ -1302,32 +1301,32 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { u8 hash_cmp[0x20]; if (!FileGetSha(argv[0], hash_fil, at_org, sz_org, flags & _FLG('1'))) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "sha arg0 fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SHA_ARG0_FAIL); } else if ((FileGetData(argv[1], hash_cmp, hashlen, 0) != hashlen) && !strntohex(argv[1], hash_cmp, hashlen)) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "sha arg1 fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SHA_ARG1_FAIL); } else { ret = (memcmp(hash_fil, hash_cmp, hashlen) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "sha does not match"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SHA_DOES_NOT_MATCH); } } else if (id == CMD_ID_SHAGET) { const u8 hashlen = (flags & _FLG('1')) ? 20 : 32; u8 hash_fil[0x20]; if (!(ret = FileGetSha(argv[0], hash_fil, at_org, sz_org, flags & _FLG('1')))) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "sha arg0 fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SHA_ARG0_FAIL); } else if (!strchr(argv[1], ':')) { char hash_str[64+1]; if (flags & _FLG('1')) - snprintf(hash_str, 64+1, "%016llX%016llX%08lX", getbe64(hash_fil + 0), getbe64(hash_fil + 8), + snprintf(hash_str, sizeof(hash_str), "%016llX%016llX%08lX", getbe64(hash_fil + 0), getbe64(hash_fil + 8), getbe32(hash_fil + 16)); else - snprintf(hash_str, 64+1, "%016llX%016llX%016llX%016llX", getbe64(hash_fil + 0), getbe64(hash_fil + 8), + snprintf(hash_str, sizeof(hash_str), "%016llX%016llX%016llX%016llX", getbe64(hash_fil + 0), getbe64(hash_fil + 8), getbe64(hash_fil + 16), getbe64(hash_fil + 24)); ret = set_var(argv[1], hash_str); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_VAR_FAIL); } else if (!(ret = FileSetData(argv[1], hash_fil, hashlen, 0, true))) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "sha write fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SHA_WRITE_FAIL); } } else if (id == CMD_ID_DUMPTXT) { @@ -1336,65 +1335,65 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { if (flags & _FLG('p')) offset = FileGetSize(argv[0]); if (!(ret = FileSetData(argv[0], argv[1], len, offset, offset == 0)) || !(ret = FileSetData(argv[0], "\n", 1, offset + len, false))) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "file write fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_WRITE_FAIL); } } else if (id == CMD_ID_FIXCMAC) { - ShowString("Fixing CMACs..."); + ShowString("%s", STR_FIXING_CMACS_PLEASE_WAIT); ret = (RecursiveFixFileCmac(argv[0]) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "fixcmac failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FIXCMAC_FAILED); } else if (id == CMD_ID_VERIFY) { u64 filetype = IdentifyFileType(argv[0]); if (filetype & IMG_NAND) ret = (ValidateNandDump(argv[0]) == 0); else ret = (VerifyGameFile(argv[0]) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "verification failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_VERIFICATION_FAILED); } else if (id == CMD_ID_DECRYPT) { u64 filetype = IdentifyFileType(argv[0]); if (filetype & BIN_KEYDB) ret = (CryptAesKeyDb(argv[0], true, false) == 0); else ret = (CryptGameFile(argv[0], true, false) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "decrypt failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_DECRYPT_FAILED); } else if (id == CMD_ID_ENCRYPT) { u64 filetype = IdentifyFileType(argv[0]); if (filetype & BIN_KEYDB) ret = (CryptAesKeyDb(argv[0], true, true) == 0); else ret = (CryptGameFile(argv[0], true, true) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "encrypt failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ENCRYPT_FAILED); } else if (id == CMD_ID_BUILDCIA) { ret = (BuildCiaFromGameFile(argv[0], (flags & _FLG('l'))) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "build CIA failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_BUILD_CIA_FAILED); } else if (id == CMD_ID_INSTALL) { ret = (InstallGameFile(argv[0], (flags & _FLG('e'))) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "install game failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_INSTALL_GAME_FAILED); } else if (id == CMD_ID_EXTRCODE) { u64 filetype = IdentifyFileType(argv[0]); if (!FTYPE_HASCODE(filetype)) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "does not contain .code"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_DOES_NOT_CONTAIN_DOT_CODE); } else { - ShowString("Extracting .code, please wait..."); + ShowString("%s", STR_EXTRACTING_DOT_CODE); ret = (ExtractCodeFromCxiFile(argv[0], argv[1], NULL) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "extract .code failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_EXTRACT_DOT_CODE_FAILED); } } else if (id == CMD_ID_CMPRCODE) { - ShowString("Compressing .code, please wait..."); + ShowString("%s", STR_COMPRESSING_DOT_CODE); ret = (CompressCode(argv[0], argv[1]) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "compress .code failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_COMPRESS_DOT_CODE_FAILED); } else if (id == CMD_ID_SDUMP) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "build failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_BUILD_FAILED); if ((strncasecmp(argv[0], TIKDB_NAME_ENC, _ARG_MAX_LEN) == 0) || (strncasecmp(argv[0], TIKDB_NAME_DEC, _ARG_MAX_LEN) == 0)) { bool tik_dec = (strncasecmp(argv[0], TIKDB_NAME_DEC, _ARG_MAX_LEN) == 0); if (flags & _FLG('w')) fvx_unlink(tik_dec ? OUTPUT_PATH "/" TIKDB_NAME_DEC : OUTPUT_PATH "/" TIKDB_NAME_ENC); if (BuildTitleKeyInfo(NULL, tik_dec, false) == 0) { - ShowString("Building to " OUTPUT_PATH ":\n%s ...", argv[0]); + ShowString(STR_BUILDING_TO_OUT_ARG, OUTPUT_PATH, argv[0]); if (((BuildTitleKeyInfo("1:/dbs/ticket.db", tik_dec, false) == 0) || (BuildTitleKeyInfo("4:/dbs/ticket.db", tik_dec, false) == 0)) && (BuildTitleKeyInfo(NULL, tik_dec, true) == 0)) @@ -1403,31 +1402,31 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { } else if (strncasecmp(argv[0], SEEDINFO_NAME, _ARG_MAX_LEN) == 0) { if (flags & _FLG('w')) fvx_unlink(OUTPUT_PATH "/" SEEDINFO_NAME); if (BuildSeedInfo(NULL, false) == 0) { - ShowString("Building to " OUTPUT_PATH ":\n%s ...", argv[0]); + ShowString(STR_BUILDING_TO_OUT_ARG, OUTPUT_PATH, argv[0]); if (((BuildSeedInfo("1:", false) == 0) || (BuildSeedInfo("4:", false) == 0)) && (BuildSeedInfo(NULL, true) == 0)) ret = true; } } else { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "unknown file"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_UNKNOWN_FILE); } } else if (id == CMD_ID_APPLYIPS) { ret = (ApplyIPSPatch(argv[0], argv[1], argv[2]) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "apply IPS failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_APPLY_IPS_FAILD); } else if (id == CMD_ID_APPLYBPS) { ret = (ApplyBPSPatch(argv[0], argv[1], argv[2]) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "apply BPS failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_APPLY_BPS_FAILED); } else if (id == CMD_ID_APPLYBPM) { ret = (ApplyBPMPatch(argv[0], argv[1], argv[2]) == 0); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "apply BPM failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_APPLY_BPM_FAILED); } else if (id == CMD_ID_TEXTVIEW) { ret = FileTextViewer(argv[0], false); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "textviewer failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_TEXTVIEWER_FAILED); } else if (id == CMD_ID_CARTDUMP) { CartData* cdata = (CartData*) malloc(sizeof(CartData)); @@ -1435,16 +1434,16 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { u64 fsize; ret = false; if (!cdata || !buf) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "out of memory"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_OUT_OF_MEMORY); } else if (sscanf(argv[1], "%llX", &fsize) != 1) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "bad dumpsize"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_BAD_DUMPSIZE); } else if (InitCartRead(cdata) != 0){ - if (err_str) snprintf(err_str, _ERR_STR_LEN, "cart init fail"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_CART_INIT_FAIL); } else { SetSecureAreaEncryption(flags & _FLG('e')); fvx_unlink(argv[0]); ret = true; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "cart dump failed"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_CART_DUMP_FAILED); for (u64 p = 0; p < fsize; p += STD_BUFFER_SIZE) { u64 len = min((fsize - p), STD_BUFFER_SIZE); ShowProgress(p, fsize, argv[0]); @@ -1465,7 +1464,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { fvx_closedir(&fdir); ret = true; } else { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "not a dir"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_NOT_A_DIR); ret = false; } } @@ -1473,7 +1472,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { if (fvx_stat(argv[0], NULL) == FR_OK) { ret = true; } else { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "file not found"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FILE_NOT_FOUND); ret = false; } } @@ -1481,14 +1480,14 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { u8* firm = (u8*) malloc(FIRM_MAX_SIZE); if (!firm) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "out of memory"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_OUT_OF_MEMORY); } else { size_t firm_size = FileGetData(argv[0], firm, FIRM_MAX_SIZE, 0); ret = firm_size && IsBootableFirm(firm, firm_size); if (ret) { char fixpath[256] = { 0 }; if ((*argv[0] == '0') || (*argv[0] == '1')) - snprintf(fixpath, 256, "%s%s", (*argv[0] == '0') ? "sdmc" : "nand", argv[0] + 1); + snprintf(fixpath, sizeof(fixpath), "%s%s", (*argv[0] == '0') ? "sdmc" : "nand", argv[0] + 1); else strncpy(fixpath, argv[0], 256); fixpath[255] = '\0'; DeinitExtFS(); @@ -1497,26 +1496,26 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { PXI_Barrier(PXI_FIRMLAUNCH_BARRIER); BootFirm((FirmHeader*)(void*)firm, fixpath); while(1); - } else if (err_str) snprintf(err_str, _ERR_STR_LEN, "not a bootable firm"); + } else if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_NOT_A_BOOTABLE_FIRM); free(firm); } } else if (id == CMD_ID_SWITCHSD) { DeinitExtFS(); if (!(ret = CheckSDMountState())) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "SD not mounted"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_SD_NOT_MOUNTED); } else { u32 pad_state; DeinitSDCardFS(); - ShowString("%s\n \nEject SD card...", argv[0]); + ShowString("%s\n \n%s", argv[0], STR_EJECT_SD_CARD); while (!((pad_state = InputWait(0)) & (BUTTON_B|SD_EJECT))); if (pad_state & SD_EJECT) { - ShowString("%s\n \nInsert SD card...", argv[0]); + ShowString("%s\n \n%s", argv[0], STR_INSERT_SD_CARD); while (!((pad_state = InputWait(0)) & (BUTTON_B|SD_INSERT))); } if (pad_state & BUTTON_B) { ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "user abort"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_USER_ABORT); } } InitSDCardFS(); @@ -1544,10 +1543,10 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { } else { // command not recognized / bad number of arguments ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "unknown error"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_UNKNOWN_ERROR); } - if (ret && err_str) snprintf(err_str, _ERR_STR_LEN, "command success"); + if (ret && err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_COMMAND_SUCCESS); return ret; } @@ -1575,7 +1574,7 @@ bool run_line(const char* line_start, const char* line_end, u32* flags, char* er // control flow command handling // block out of control flow commands if (if_cond && IS_CTRLFLOW_CMD(cmdid)) { - if (err_str) snprintf(err_str, _ERR_STR_LEN, "control flow error"); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_CONTROL_FLOW_ERROR); syntax_error = true; return false; } @@ -1632,7 +1631,7 @@ void MemTextView(const char* text, u32 len, char* line0, int off_disp, int lno, u32 x_txt = (TV_LNOS >= 0) ? TV_HPAD + ((TV_LNOS+1)*FONT_WIDTH_EXT) : TV_HPAD; u32 x_lno = TV_HPAD; u32 p_al = 0; - u32 p_ar = TV_LLEN_DISP - strnlen(ar_str, 16); + u32 p_ar = TV_LLEN_DISP - strlen(ar_str); u32 x_al = x_txt + (p_al * FONT_WIDTH_EXT); u32 x_ar = x_txt + (p_ar * FONT_WIDTH_EXT); @@ -1659,11 +1658,11 @@ void MemTextView(const char* text, u32 len, char* line0, int off_disp, int lno, if (cmt_start <= 0) color_text = script_color_comment; // build text string - snprintf(txtstr, TV_LLEN_DISP + 1, "%-*.*s", (int) TV_LLEN_DISP, (int) TV_LLEN_DISP, ""); + snprintf(txtstr, sizeof(txtstr), "%-*.*s", (int) TV_LLEN_DISP, (int) TV_LLEN_DISP, ""); if (ncpy) memcpy(txtstr, ptr + off_disp, ncpy); for (char* d = txtstr; *d; d++) if (*d < ' ') *d = ' '; - if (al) memcpy(txtstr + p_al, al_str, strnlen(al_str, 16)); - if (ar) memcpy(txtstr + p_ar, ar_str, strnlen(ar_str, 16)); + if (al) memcpy(txtstr + p_al, al_str, strlen(al_str)); + if (ar) memcpy(txtstr + p_ar, ar_str, strlen(ar_str)); // draw line number & text DrawString(TOP_SCREEN, txtstr, x_txt, y, color_text, COLOR_STD_BG); @@ -1680,8 +1679,8 @@ void MemTextView(const char* text, u32 len, char* line0, int off_disp, int lno, } // colorize arrows - if (al) DrawStringF(TOP_SCREEN, x_al, y, COLOR_TVOFFS, COLOR_TRANSPARENT, al_str); - if (ar) DrawStringF(TOP_SCREEN, x_ar, y, COLOR_TVOFFS, COLOR_TRANSPARENT, ar_str); + if (al) DrawStringF(TOP_SCREEN, x_al, y, COLOR_TVOFFS, COLOR_TRANSPARENT, "%s", al_str); + if (ar) DrawStringF(TOP_SCREEN, x_ar, y, COLOR_TVOFFS, COLOR_TRANSPARENT, "%s", ar_str); // advance pointer / line number for (char* c = ptr; c < ptr_next; c++) if (*c == '\n') ++nln; @@ -1694,7 +1693,7 @@ bool MemTextViewer(const char* text, u32 len, u32 start, bool as_script) { // check if this really is text if (!ValidateText(text, len)) { - ShowPrompt(false, "Error: Invalid text data"); + ShowPrompt(false, "%s", STR_ERROR_INVALID_TEXT_DATA); return false; } @@ -1702,8 +1701,7 @@ bool MemTextViewer(const char* text, u32 len, u32 start, bool as_script) { ClearScreenF(true, true, COLOR_STD_BG); // instructions - static const char* instr = "Textviewer Controls:\n \n↑↓→←(+R) - Scroll\nR+Y - Toggle wordwrap\nR+X - Goto line #\nB - Exit\n"; - ShowString(instr); + ShowString("%s", STR_TEXTVIEWER_CONTROLS_DETAILS); // set script colors if (as_script) { @@ -1742,9 +1740,9 @@ bool MemTextViewer(const char* text, u32 len, u32 start, bool as_script) { else if (pad_state & BUTTON_RIGHT) off_disp += step_lr; else if (pad_state & BUTTON_LEFT) off_disp -= step_lr; else if (switched && (pad_state & BUTTON_X)) { - u64 lnext64 = ShowNumberPrompt(lcurr, "Current line: %i\nEnter new line below.", lcurr); + u64 lnext64 = ShowNumberPrompt(lcurr, STR_CURRENT_LINE_N_ENTER_NEW_LINE_BELOW, lcurr); if (lnext64 && (lnext64 != (u64) -1)) line0_next = line_seek(text, len, 0, line0, (int) lnext64 - lcurr); - ShowString(instr); + ShowString("%s", STR_TEXTVIEWER_CONTROLS_DETAILS); } else if (switched && (pad_state & BUTTON_Y)) { ww = ww ? 0 : TV_LLEN_DISP; line0_next = line_seek(text, len, ww, line0, 0); @@ -1780,7 +1778,7 @@ bool MemToCViewer(const char* text, u32 len, const char* title) { // check if this really is text if (!ValidateText(text, len)) { - ShowPrompt(false, "Error: Invalid text data"); + ShowPrompt(false, "%s", STR_ERROR_INVALID_TEXT_DATA); return false; } @@ -1819,7 +1817,7 @@ bool MemToCViewer(const char* text, u32 len, const char* title) { for (; IS_WHITESPACE(*caption); caption++); for (; caption[len] != '\n' && caption[len] != '\r'; len++); DrawStringF(BOT_SCREEN, x0 + (lvl-1) * (FONT_WIDTH_EXT/2), y0, text_color, COLOR_STD_BG, - "%*.*s", len, len, caption); + "%*.*s", (int) len, (int) len, caption); y0 += FONT_HEIGHT_EXT + (2*TV_VPAD); } @@ -1887,7 +1885,7 @@ bool ExecuteGM9Script(const char* path_script) { if (!var_buffer || !script_buffer) { if (var_buffer) free(var_buffer); if (script_buffer) free(script_buffer); - ShowPrompt(false, "Out of memory."); + ShowPrompt(false, "%s", STR_OUT_OF_MEMORY); return false; } @@ -1931,7 +1929,7 @@ bool ExecuteGM9Script(const char* path_script) { if (!preview_mode || (preview_mode > 2) || !preview_mode_local) ClearScreen(TOP_SCREEN, COLOR_STD_BG); if (preview_mode > 2) { - char* preview_str = get_var("PREVIEW_MODE", NULL); + const char* preview_str = get_var("PREVIEW_MODE", NULL); u32 bitmap_width, bitmap_height; u16* bitmap = NULL; @@ -1947,7 +1945,7 @@ bool ExecuteGM9Script(const char* path_script) { DrawBitmap(TOP_SCREEN, -1, -1, bitmap_width, bitmap_height, bitmap); free(bitmap); } else if (ShowGameFileIcon(preview_str, TOP_SCREEN) != 0) { - if (strncmp(preview_str, "off", _VAR_CNT_LEN) == 0) preview_str = "(preview disabled)"; + if (strncmp(preview_str, "off", _VAR_CNT_LEN) == 0) preview_str = STR_PREVIEW_DISABLED; DrawStringCenter(TOP_SCREEN, COLOR_STD_FONT, COLOR_STD_BG, "%s", preview_str); } @@ -1987,14 +1985,14 @@ bool ExecuteGM9Script(const char* path_script) { if ((skip_state == _SKIP_BLOCK) || (skip_state == _SKIP_TILL_END)) { skip_ptr = skip_block(line_end + 1, (skip_state == _SKIP_TILL_END), false); if (!skip_ptr) { - snprintf(err_str, _ERR_STR_LEN, "unclosed conditional"); + snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_UNCLOSED_CONDITIONAL); result = false; syntax_error = true; } } else if (skip_state == _SKIP_TO_NEXT) { skip_ptr = find_next(ptr); if (!skip_ptr) { - snprintf(err_str, _ERR_STR_LEN, "'for' without 'next'"); + snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_FOR_WITHOUT_NEXT); result = false; syntax_error = true; } @@ -2002,7 +2000,7 @@ bool ExecuteGM9Script(const char* path_script) { } else if (skip_state == _SKIP_TO_FOR) { skip_ptr = for_ptr; if (!skip_ptr) { - snprintf(err_str, _ERR_STR_LEN, "'next' without 'for'"); + snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_NEXT_WITHOUT_FOR); result = false; syntax_error = true; } @@ -2018,7 +2016,7 @@ bool ExecuteGM9Script(const char* path_script) { if (!*err_str) { char* msg_fail = get_var("ERRORMSG", NULL); if (msg_fail && *msg_fail) ShowPrompt(false, "%s", msg_fail); - else snprintf(err_str, _ERR_STR_LEN, "error message fail"); + else snprintf(err_str, _ERR_STR_LEN, "%s", STR_SCRIPTERR_ERROR_MESSAGE_FAIL); } if (*err_str) { char line_str[32+1]; @@ -2026,9 +2024,9 @@ bool ExecuteGM9Script(const char* path_script) { char* lptr1 = line_end; for (; IS_WHITESPACE(*lptr0) && (lptr0 < lptr1); lptr0++); // skip whitespaces if ((lptr1 > lptr0) && (*(lptr1-1) == '\r')) lptr1--; // handle \r - if (lptr1 - lptr0 > 32) snprintf(line_str, 32+1, "%.29s...", lptr0); - else snprintf(line_str, 32+1, "%.*s", lptr1 - lptr0, lptr0); - ShowPrompt(false, "%s\nline %lu: %s\n%s", path_str, lno, err_str, line_str); + if (lptr1 - lptr0 > 32) snprintf(line_str, sizeof(line_str), "%.29s...", lptr0); + else snprintf(line_str, sizeof(line_str), "%.*s", lptr1 - lptr0, lptr0); + ShowPrompt(false, STR_PATH_LINE_N_ERR_LINE, path_str, lno, err_str, line_str); } } if (!(flags & _FLG('o'))) { // failed if not optional @@ -2057,11 +2055,11 @@ bool ExecuteGM9Script(const char* path_script) { if (result) { // all fine(?) up to this point if (ifcnt) { // check for unresolved 'if' - ShowPrompt(false, "%s\nend of script: unresolved 'if'", path_str); + ShowPrompt(false, "%s\n%s", path_str, STR_END_OF_SCRIPT_UNRESOLVED_IF); result = false; } if (for_ptr) { // check for unresolved 'for' - ShowPrompt(false, "%s\nend of script: unresolved 'for'", path_str); + ShowPrompt(false, "%s\n%s", path_str, STR_END_OF_SCRIPT_UNRESOLVED_FOR); for_handler(NULL, NULL, NULL, false); result = false; } diff --git a/arm9/source/utils/sysinfo.c b/arm9/source/utils/sysinfo.c index c290b0ab5..3d3b2724d 100644 --- a/arm9/source/utils/sysinfo.c +++ b/arm9/source/utils/sysinfo.c @@ -1,6 +1,7 @@ #include "common.h" #include "i2c.h" #include "itcm.h" +#include "language.h" #include "region.h" #include "unittype.h" #include "essentials.h" // For SecureInfo / movable @@ -28,23 +29,24 @@ static const struct { }; STATIC_ASSERT(countof(s_modelNames) == NUM_MODELS); -// Table of sales regions. -static const struct { - char serial_char; - const char* name; -} s_salesRegions[] = { - // Typical regions. - { 'J', "Japan" }, - { 'W', "Americas" }, // "W" = worldwide? - { 'E', "Europe" }, - { 'C', "China" }, - { 'K', "Korea" }, - { 'T', "Taiwan" }, - // Manufacturing regions that have another region's region lock. - { 'U', "United Kingdom" }, - { 'S', "Middle East" }, // "S" = Saudi Arabia? Singapore? (Southeast Asia included.) - { 'A', "Australia" }, -}; +// Sales regions. +const char* salesRegion(char serial_char) { + switch(serial_char) { + // Typical regions. + case 'J': return STR_REGION_JAPAN; + case 'W': return STR_REGION_AMERICAS; // "W" = worldwide? + case 'E': return STR_REGION_EUROPE; + case 'C': return STR_REGION_CHINA; + case 'K': return STR_REGION_KOREA; + case 'T': return STR_REGION_TAIWAN; + // Manufacturing regions that have another region's region lock. + case 'U': return STR_REGION_UNITED_KINGDOM; + case 'S': return STR_REGION_MIDDLE_EAST; // "S" = Saudi Arabia? Singapore? (Southeast Asia included.) + case 'A': return STR_REGION_AUSTRALIA; + case 'B': return STR_REGION_BRAZIL; + default: return STR_REGION_UNKNOWN; + } +} // Structure of system information. typedef struct _SysInfo { @@ -59,8 +61,8 @@ typedef struct _SysInfo { // From SecureInfo_A/B char sub_model[15 + 1]; char serial[15 + 1]; - char system_region[15 + 1]; - char sales_region[15 + 1]; + char system_region[64 + 1]; + char sales_region[64 + 1]; // From movable.sed char friendcodeseed[16 + 1]; char movablekeyy[32 + 1]; @@ -164,7 +166,7 @@ void GetSysInfo_SecureInfo(SysInfo* info, char nand_drive) { // Decode region. if (data.region < SMDH_NUM_REGIONS) { - strncpy(info->system_region, g_regionNamesLong[data.region], countof(info->system_region)); + strncpy(info->system_region, regionNameLong(data.region), countof(info->system_region)); info->system_region[countof(info->system_region) - 1] = '\0'; } @@ -232,13 +234,8 @@ void GetSysInfo_SecureInfo(SysInfo* info, char nand_drive) { // Determine the sales region from the second letter of the prefix. if (second_letter != '\0') { - for (unsigned x = 0; x < countof(s_salesRegions); ++x) { - if (s_salesRegions[x].serial_char == second_letter) { - strncpy(info->sales_region, s_salesRegions[x].name, countof(info->sales_region)); - info->sales_region[countof(info->sales_region) - 1] = '\0'; - break; - } - } + strncpy(info->sales_region, salesRegion(second_letter), countof(info->sales_region)); + info->sales_region[countof(info->sales_region) - 1] = '\0'; } // Determine the sub-model from the first two digits of the digit part. @@ -598,18 +595,18 @@ void MyriaSysinfo(char* sysinfo_txt) { GetSysInfo_TWLN(&info, '1'); char** meow = &sysinfo_txt; - MeowSprintf(meow, "Model: %s (%s)\r\n", info.model, info.sub_model); - MeowSprintf(meow, "Serial: %s\r\n", info.serial); - MeowSprintf(meow, "Region (system): %s\r\n", info.system_region); - MeowSprintf(meow, "Region (sales): %s\r\n", info.sales_region); - MeowSprintf(meow, "SoC manufacturing date: %s\r\n", info.soc_date); - MeowSprintf(meow, "System assembly date: %s\r\n", info.assembly_date); - MeowSprintf(meow, "Original firmware: %s\r\n", info.original_firmware); + MeowSprintf(meow, STR_SYSINFO_MODEL, info.model, info.sub_model); + MeowSprintf(meow, STR_SYSINFO_SERIAL, info.serial); + MeowSprintf(meow, STR_SYSINFO_REGION_SYSTEM, info.system_region); + MeowSprintf(meow, STR_SYSINFO_REGION_SALES, info.sales_region); + MeowSprintf(meow, STR_SYSINFO_SOC_MANUFACTURING_DATE, info.soc_date); + MeowSprintf(meow, STR_SYSINFO_SYSTEM_ASSEMBLY_DATE, info.assembly_date); + MeowSprintf(meow, STR_SYSINFO_ORIGINAL_FIRMWARE, info.original_firmware); MeowSprintf(meow, "\r\n"); - MeowSprintf(meow, "Friendcode seed: %s\r\n", info.friendcodeseed); - MeowSprintf(meow, "SD keyY: %s\r\n", info.movablekeyy); - MeowSprintf(meow, "NAND CID: %s\r\n", info.nand_cid); - MeowSprintf(meow, "SD CID: %s\r\n", info.sd_cid); - MeowSprintf(meow, "System ID0: %s\r\n", info.nand_id0); - MeowSprintf(meow, "System ID1: %s\r\n", info.nand_id1); + MeowSprintf(meow, STR_SYSINFO_FRIENDCODE_SEED, info.friendcodeseed); + MeowSprintf(meow, STR_SYSINFO_SD_KEYY, info.movablekeyy); + MeowSprintf(meow, STR_SYSINFO_NAND_CID, info.nand_cid); + MeowSprintf(meow, STR_SYSINFO_SD_CID, info.sd_cid); + MeowSprintf(meow, STR_SYSINFO_SYSTEM_ID0, info.nand_id0); + MeowSprintf(meow, STR_SYSINFO_SYSTEM_ID1, info.nand_id1); } diff --git a/arm9/source/virtual/vbdri.c b/arm9/source/virtual/vbdri.c index 2783dc5ae..b743cdd6a 100644 --- a/arm9/source/virtual/vbdri.c +++ b/arm9/source/virtual/vbdri.c @@ -5,6 +5,7 @@ #include "bdri.h" #include "vff.h" #include "ui.h" +#include "language.h" #define VBDRI_MAX_ENTRIES 8192 // Completely arbitrary @@ -65,7 +66,7 @@ bool SortVBDRITickets() { if (!tick_info) return false; - ShowString("Sorting tickets, please wait ..."); + ShowString("%s", STR_SORTING_TICKETS_PLEASE_WAIT); for (u32 i = 0; i < num_entries - 1; i++) { Ticket* ticket; diff --git a/arm9/source/virtual/vkeydb.c b/arm9/source/virtual/vkeydb.c index 1ae7f0aa8..b3d8973b3 100644 --- a/arm9/source/virtual/vkeydb.c +++ b/arm9/source/virtual/vkeydb.c @@ -53,11 +53,11 @@ bool ReadVKeyDbDir(VirtualFile* vfile, VirtualDir* vdir) { if (++vdir->index < (int) n_keys) { AesKeyInfo* key_entry = key_info + vdir->index; u32 keyslot = key_entry->slot; - char typestr[16] = { 0 }; + char typestr[16]; char* unitext = (key_entry->keyUnitType == KEYS_DEVKIT) ? ".dev" : (key_entry->keyUnitType == KEYS_RETAIL) ? ".ret" : ""; - snprintf(typestr, 12 + 1, "%s%.10s", (key_entry->type == 'I') ? "IV" : + snprintf(typestr, sizeof(typestr), "%s%.10s", (key_entry->type == 'I') ? "IV" : (key_entry->type == 'X') ? "X" : (key_entry->type == 'Y') ? "Y" : "", key_entry->id); memset(vfile, 0, sizeof(VirtualFile)); diff --git a/crowdin.yml b/crowdin.yml new file mode 100644 index 000000000..863c75990 --- /dev/null +++ b/crowdin.yml @@ -0,0 +1,7 @@ +project_id_env: GM9_CROWDIN_ID +api_token_env: CROWDIN_TOKEN +preserve_hierarchy: true + +files: + - source: /resources/languages/source.json + translation: /resources/languages/%two_letters_code%.json diff --git a/data/font_default.frf b/data/font_default.frf index 65f86e6d9..dee9c9811 100644 Binary files a/data/font_default.frf and b/data/font_default.frf differ diff --git a/resources/GodMode9_splash.png b/resources/GodMode9_splash.png index 9d65ccc62..6b464a1d0 100644 Binary files a/resources/GodMode9_splash.png and b/resources/GodMode9_splash.png differ diff --git a/resources/GodMode9_splash_default.png b/resources/GodMode9_splash_default.png new file mode 100644 index 000000000..9d65ccc62 Binary files /dev/null and b/resources/GodMode9_splash_default.png differ diff --git a/resources/fonts/font_6x10.pbm b/resources/fonts/font_6x10.pbm index aaee90617..245b6a7d9 100644 Binary files a/resources/fonts/font_6x10.pbm and b/resources/fonts/font_6x10.pbm differ diff --git a/resources/fonts/font_6x10.txt b/resources/fonts/font_6x10.txt index 4ad1b8996..99c676026 100644 --- a/resources/fonts/font_6x10.txt +++ b/resources/fonts/font_6x10.txt @@ -1,35 +1,17 @@ -0x0020 0x0021 0x0022 0x0023 0x0024 0x0025 0x0026 0x0027 0x0028 0x0029 0x002A 0x002B 0x002C 0x002D 0x002E 0x002F -0x0030 0x0031 0x0032 0x0033 0x0034 0x0035 0x0036 0x0037 0x0038 0x0039 0x003A 0x003B 0x003C 0x003D 0x003E 0x003F -0x0040 0x0041 0x0042 0x0043 0x0044 0x0045 0x0046 0x0047 0x0048 0x0049 0x004A 0x004B 0x004C 0x004D 0x004E 0x004F -0x0050 0x0051 0x0052 0x0053 0x0054 0x0055 0x0056 0x0057 0x0058 0x0059 0x005A 0x005B 0x005C 0x005D 0x005E 0x005F -0x0060 0x0061 0x0062 0x0063 0x0064 0x0065 0x0066 0x0067 0x0068 0x0069 0x006A 0x006B 0x006C 0x006D 0x006E 0x006F -0x0070 0x0071 0x0072 0x0073 0x0074 0x0075 0x0076 0x0077 0x0078 0x0079 0x007A 0x007B 0x007C 0x007D 0x007E 0x00A0 -0x00A1 0x00A2 0x00A3 0x00A4 0x00A5 0x00A6 0x00A7 0x00A8 0x00A9 0x00AA 0x00AB 0x00AC 0x00AE 0x00B0 0x00B1 0x00B2 -0x00B3 0x00B4 0x00B5 0x00B6 0x00B7 0x00BA 0x00BB 0x00BC 0x00BD 0x00BF 0x00C0 0x00C1 0x00C2 0x00C3 0x00C4 0x00C5 -0x00C6 0x00C7 0x00C8 0x00C9 0x00CA 0x00CB 0x00CC 0x00CD 0x00CE 0x00CF 0x00D0 0x00D1 0x00D2 0x00D3 0x00D4 0x00D5 -0x00D6 0x00D7 0x00D8 0x00D9 0x00DA 0x00DB 0x00DC 0x00DD 0x00DE 0x00DF 0x00E0 0x00E1 0x00E2 0x00E3 0x00E4 0x00E5 -0x00E6 0x00E7 0x00E8 0x00E9 0x00EA 0x00EB 0x00EC 0x00ED 0x00EE 0x00EF 0x00F0 0x00F1 0x00F2 0x00F3 0x00F4 0x00F5 -0x00F6 0x00F7 0x00F8 0x00F9 0x00FA 0x00FB 0x00FC 0x00FD 0x00FE 0x00FF 0x0192 0x0393 0x0398 0x03A3 0x03A6 0x03A9 -0x03B1 0x03B4 0x03B5 0x03C0 0x03C3 0x03C4 0x03C6 0x0401 0x0404 0x0406 0x0407 0x0410 0x0411 0x0412 0x0413 0x0414 -0x0415 0x0416 0x0417 0x0418 0x0419 0x041A 0x041B 0x041C 0x041D 0x041E 0x041F 0x0420 0x0421 0x0422 0x0423 0x0424 -0x0425 0x0426 0x0427 0x0428 0x0429 0x042A 0x042B 0x042C 0x042D 0x042E 0x042F 0x0430 0x0431 0x0432 0x0433 0x0434 -0x0435 0x0436 0x0437 0x0438 0x0439 0x043A 0x043B 0x043C 0x043D 0x043E 0x043F 0x0440 0x0441 0x0442 0x0443 0x0444 -0x0445 0x0446 0x0447 0x0448 0x0449 0x044A 0x044B 0x044C 0x044D 0x044E 0x044F 0x0451 0x0454 0x0456 0x0457 0x2022 -0x203C 0x207F 0x20A7 0x20AC 0x2122 0x2190 0x2191 0x2192 0x2193 0x2194 0x2195 0x21A8 0x2219 0x221A 0x221E 0x221F -0x2229 0x2248 0x2261 0x2264 0x2265 0x2302 0x2310 0x2320 0x2321 0x2500 0x2502 0x250C 0x2510 0x2514 0x2518 0x251C -0x2524 0x252C 0x2534 0x253C 0x2550 0x2551 0x2552 0x2553 0x2554 0x2555 0x2556 0x2557 0x2558 0x2559 0x255A 0x255B -0x255C 0x255D 0x255E 0x255F 0x2560 0x2561 0x2562 0x2563 0x2564 0x2565 0x2566 0x2567 0x2568 0x2569 0x256A 0x256B -0x256C 0x2580 0x2584 0x2588 0x258C 0x2590 0x2591 0x2592 0x2593 0x25A0 0x25A1 0x25AC 0x25B2 0x25B3 0x25BA 0x25BC -0x25BD 0x25C4 0x25C6 0x25C7 0x25CB 0x25CE 0x25CF 0x25D8 0x25D9 0x2605 0x263A 0x263B 0x263C 0x2640 0x2642 0x2660 -0x2663 0x2665 0x2666 0x266A 0x266B 0x3000 0x3041 0x3042 0x3043 0x3044 0x3045 0x3046 0x3047 0x3048 0x3049 0x304A -0x304B 0x304C 0x304D 0x304E 0x304F 0x3050 0x3051 0x3052 0x3053 0x3054 0x3055 0x3056 0x3057 0x3058 0x3059 0x305A -0x305B 0x305C 0x305D 0x305E 0x305F 0x3060 0x3061 0x3062 0x3063 0x3064 0x3065 0x3066 0x3067 0x3068 0x3069 0x306A -0x306B 0x306C 0x306D 0x306E 0x306F 0x3070 0x3071 0x3072 0x3073 0x3074 0x3075 0x3076 0x3077 0x3078 0x3079 0x307A -0x307B 0x307C 0x307D 0x307E 0x307F 0x3080 0x3081 0x3082 0x3083 0x3084 0x3085 0x3086 0x3087 0x3088 0x3089 0x308A -0x308B 0x308C 0x308D 0x308E 0x308F 0x3090 0x3091 0x3092 0x3093 0x3094 0x3095 0x3096 0x309B 0x309C 0x309D 0x309E -0x309F 0x30A1 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 0x30A9 0x30AA 0x30AB 0x30AC 0x30AD 0x30AE 0x30AF -0x30B0 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 0x30B9 0x30BA 0x30BB 0x30BC 0x30BD 0x30BE 0x30BF -0x30C0 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 0x30C9 0x30CA 0x30CB 0x30CC 0x30CD 0x30CE 0x30CF -0x30D0 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 0x30D9 0x30DA 0x30DB 0x30DC 0x30DD 0x30DE 0x30DF -0x30E0 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 0x30E9 0x30EA 0x30EB 0x30EC 0x30ED 0x30EE 0x30EF -0x30F0 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0x30F7 0x30F8 0x30F9 0x30FA 0x30FB 0x30FC 0x30FD 0x30FE 0x30FF +0x0021 0x0022 0x0023 0x0024 0x0025 0x0026 0x0027 0x0028 0x0029 0x002A 0x002B 0x002C 0x002D 0x002E 0x002F 0x0030 0x0031 0x0032 0x0033 0x0034 0x0035 0x0036 0x0037 0x0038 0x0039 0x003A 0x003B 0x003C 0x003D 0x003E 0x003F 0x0040 0x0041 0x0042 0x0043 0x0044 0x0045 0x0046 0x0047 0x0048 0x0049 0x004A 0x004B 0x004C 0x004D 0x004E 0x004F 0x0050 0x0051 0x0052 0x0053 0x0054 0x0055 0x0056 0x0057 0x0058 0x0059 0x005A 0x005B 0x005C 0x005D 0x005E 0x005F 0x0060 0x0061 0x0062 0x0063 0x0064 0x0065 0x0066 0x0067 0x0068 0x0069 0x006A 0x006B 0x006C 0x006D 0x006E 0x006F 0x0070 0x0071 0x0072 0x0073 0x0074 0x0075 0x0076 0x0077 0x0078 0x0079 0x007A 0x007B 0x007C 0x007D 0x007E +0x00A0 0x00A1 0x00A2 0x00A3 0x00A4 0x00A5 0x00A6 0x00A7 0x00A8 0x00A9 0x00AA 0x00AB 0x00AC 0x00AE 0x00B0 0x00B1 0x00B2 0x00B3 0x00B4 0x00B5 0x00B6 0x00B7 0x00BA 0x00BB 0x00BC 0x00BD 0x00BF 0x00C0 0x00C1 0x00C2 0x00C3 0x00C4 0x00C5 0x00C6 0x00C7 0x00C8 0x00C9 0x00CA 0x00CB 0x00CC 0x00CD 0x00CE 0x00CF 0x00D0 0x00D1 0x00D2 0x00D3 0x00D4 0x00D5 0x00D6 0x00D7 0x00D8 0x00D9 0x00DA 0x00DB 0x00DC 0x00DD 0x00DE 0x00DF 0x00E0 0x00E1 0x00E2 0x00E3 0x00E4 0x00E5 0x00E6 0x00E7 0x00E8 0x00E9 0x00EA 0x00EB 0x00EC 0x00ED 0x00EE 0x00EF 0x00F0 0x00F1 0x00F2 0x00F3 0x00F4 0x00F5 0x00F6 0x00F7 0x00F8 0x00F9 0x00FA 0x00FB 0x00FC 0x00FD 0x00FE 0x00FF 0x0102 0x0103 0x0104 +0x0105 0x0106 0x0107 0x0118 0x0119 0x0141 0x0142 0x0143 0x0144 0x0151 0x015A 0x015B 0x0179 0x017A 0x017B 0x017C 0x015E 0x015F 0x0162 0x0163 0x0171 0x0192 0x0218 0x0219 0x021A 0x021B 0x2022 0x203C 0x207F 0x20A7 0x20AC 0x2122 0x2194 0x2195 0x21A8 0x2219 0x221A 0x221E 0x221F 0x2229 0x2248 0x2261 0x2264 0x2265 0x2302 0x2310 0x2320 0x2321 0x2550 0x2551 0x2552 0x2553 0x2554 0x2555 0x2556 0x2557 0x2558 0x2559 0x255A 0x255B 0x255C 0x255D 0x255E 0x255F 0x2560 0x2561 0x2562 0x2563 0x2564 0x2565 0x2566 0x2567 0x2568 0x2569 0x256A 0x256B 0x256C 0x2580 0x2584 0x2588 0x258C 0x2590 0x2591 0x2592 0x2593 0x25A0 0x25A1 0x25AC 0x25B2 0x25B3 0x25BA 0x25BC 0x25BD 0x25C4 +0x25C6 0x25C7 0x25CB 0x25CE 0x25CF 0x25D8 0x25D9 0x2605 0x263A 0x263B 0x263C 0x2640 0x2642 0x2660 0x2663 0x2665 0x2666 0x266A 0x266B 0x7B80 0xE000 0xE001 0xE002 0xE003 0xE004 0xE005 0xE006 0xE079 0xE07A 0xE07B 0xE07C 0xE07D 0xE07E 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x3000 0x3001 0x3002 0xFF0C 0xFF0E 0x30FB 0xFF1A 0xFF1B 0xFF1F 0xFF01 0x309B 0x309C 0x00B4 0xFF40 0x00A8 0xFF3E 0xFFE3 0xFF3F 0x30FD 0x30FE 0x309D 0x309E 0x3003 0x4EDD 0x3005 0x3006 0x3007 0x30FC 0x2015 0x2010 0xFF0F 0xFF3C 0xFF5E 0x2225 0xFF5C 0x2026 0x2025 0x2018 0x2019 0x201C 0x201D 0xFF08 0xFF09 0x3014 0x3015 0xFF3B 0xFF3D 0xFF5B 0xFF5D 0x3008 0x3009 0x300A 0x300B 0x300C 0x300D 0x300E 0x300F 0x3010 0x3011 0xFF0B 0xFF0D 0x00B1 0x00D7 0x00F7 0xFF1D 0x2260 0xFF1C 0xFF1E 0x2266 0x2267 0x221E 0x2234 0x2642 0x2640 0x00B0 0x2032 0x2033 0x2103 0xFFE5 0xFF04 0xFFE0 0xFFE1 0xFF05 0xFF03 0xFF06 0xFF0A 0xFF20 0x00A7 0x2606 0x2605 0x25CB 0x25CF 0x25CE 0x25C7 +0x25C6 0x25A1 0x25A0 0x25B3 0x25B2 0x25BD 0x25BC 0x203B 0x3012 0x2192 0x2190 0x2191 0x2193 0x3013 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x2208 0x220B 0x2286 0x2287 0x2282 0x2283 0x222A 0x2229 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x2227 0x2228 0xFFE2 0x21D2 0x21D4 0x2200 0x2203 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x2220 0x22A5 0x2312 0x2202 0x2207 0x2261 0x2252 0x226A 0x226B 0x221A 0x223D 0x221D 0x2235 0x222B 0x222C 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x212B 0x2030 0x266F 0x266D 0x266A 0x2020 0x2021 0x00B6 0x0020 0x0020 0x0020 0x0020 0x25EF +0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0xFF21 0xFF22 0xFF23 0xFF24 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C 0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0xFF41 0xFF42 0xFF43 0xFF44 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C 0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0x3000 0x3000 0x3000 0x3000 +0x3041 0x3042 0x3043 0x3044 0x3045 0x3046 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C 0x304D 0x304E 0x304F 0x3050 0x3051 0x3052 0x3053 0x3054 0x3055 0x3056 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C 0x305D 0x305E 0x305F 0x3060 0x3061 0x3062 0x3063 0x3064 0x3065 0x3066 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C 0x306D 0x306E 0x306F 0x3070 0x3071 0x3072 0x3073 0x3074 0x3075 0x3076 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C 0x307D 0x307E 0x307F 0x3080 0x3081 0x3082 0x3083 0x3084 0x3085 0x3086 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C 0x308D 0x308E 0x308F 0x3090 0x3091 0x3092 0x3093 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 +0x30A1 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 0x30A9 0x30AA 0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 0x30B9 0x30BA 0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 0x30C9 0x30CA 0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 0x30D9 0x30DA 0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 0x30E9 0x30EA 0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 +0x0391 0x0392 0x0393 0x0394 0x0395 0x0396 0x0397 0x0398 0x0399 0x039A 0x039B 0x039C 0x039D 0x039E 0x039F 0x03A0 0x03A1 0x03A3 0x03A4 0x03A5 0x03A6 0x03A7 0x03A8 0x03A9 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x03B1 0x03B2 0x03B3 0x03B4 0x03B5 0x03B6 0x03B7 0x03B8 0x03B9 0x03BA 0x03BB 0x03BC 0x03BD 0x03BE 0x03BF 0x03C0 0x03C1 0x03C3 0x03C4 0x03C5 0x03C6 0x03C7 0x03C8 0x03C9 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0410 0x0411 0x0412 0x0413 0x0414 0x0415 0x0401 0x0416 0x0417 0x0418 0x0419 0x041A 0x041B 0x041C 0x041D 0x041E 0x041F 0x0420 0x0421 0x0422 0x0423 0x0424 0x0425 0x0426 0x0427 0x0428 0x0429 0x042A 0x042B 0x042C 0x042D 0x042E 0x042F 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0430 0x0431 0x0432 0x0433 0x0434 0x0435 0x0451 0x0436 0x0437 0x0438 0x0439 0x043A 0x043B 0x043C 0x043D 0x043E 0x043F 0x0440 0x0441 0x0442 0x0443 0x0444 0x0445 0x0446 0x0447 0x0448 0x0449 0x044A 0x044B 0x044C 0x044D 0x044E 0x044F 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x2500 0x2502 0x250C 0x2510 0x2518 0x2514 0x251C 0x252C 0x2524 0x2534 0x253C 0x2501 0x2503 0x250F 0x2513 0x251B 0x2517 0x2523 0x2533 0x252B 0x253B 0x254B 0x2520 0x252F 0x2528 0x2537 0x253F 0x251D 0x2530 0x2525 0x2538 0x2542 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0386 0x0388 0x0389 0x038A 0x038C 0x038E 0x038F 0x0390 0x03AA 0x03AB 0x03AC 0x03AD 0x03AE 0x03AF 0x03B0 0x03C2 0x03CA 0x03CB 0x03CC 0x03CD 0x03CE 0x0406 0x0407 0x0456 0x0457 0x0490 0x0491 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x65E5 0x672C 0x8A9E 0x7409 0x7403 0x8AF8 0x4E2D 0x6587 0x7B80 0x4F53 0x7E41 0x9AD4 0xD55C 0xAD6D 0xC5B4 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 \ No newline at end of file diff --git a/resources/fonts/font_6x10_japanese.pbm b/resources/fonts/font_6x10_japanese.pbm new file mode 100644 index 000000000..75374137e Binary files /dev/null and b/resources/fonts/font_6x10_japanese.pbm differ diff --git a/resources/fonts/font_6x10_japanese.txt b/resources/fonts/font_6x10_japanese.txt new file mode 100644 index 000000000..51200ad1b --- /dev/null +++ b/resources/fonts/font_6x10_japanese.txt @@ -0,0 +1,94 @@ +0x3000 0x3001 0x3002 0xFF0C 0xFF0E 0x30FB 0xFF1A 0xFF1B 0xFF1F 0xFF01 0x309B 0x309C 0x00B4 0xFF40 0x00A8 0xFF3E 0xFFE3 0xFF3F 0x30FD 0x30FE 0x309D 0x309E 0x3003 0x4EDD 0x3005 0x3006 0x3007 0x30FC 0x2015 0x2010 0xFF0F 0xFF3C 0xFF5E 0x2225 0xFF5C 0x2026 0x2025 0x2018 0x2019 0x201C 0x201D 0xFF08 0xFF09 0x3014 0x3015 0xFF3B 0xFF3D 0xFF5B 0xFF5D 0x3008 0x3009 0x300A 0x300B 0x300C 0x300D 0x300E 0x300F 0x3010 0x3011 0xFF0B 0xFF0D 0x00B1 0x00D7 0x00F7 0xFF1D 0x2260 0xFF1C 0xFF1E 0x2266 0x2267 0x221E 0x2234 0x2642 0x2640 0x00B0 0x2032 0x2033 0x2103 0xFFE5 0xFF04 0xFFE0 0xFFE1 0xFF05 0xFF03 0xFF06 0xFF0A 0xFF20 0x00A7 0x2606 0x2605 0x25CB 0x25CF 0x25CE 0x25C7 +0x25C6 0x25A1 0x25A0 0x25B3 0x25B2 0x25BD 0x25BC 0x203B 0x3012 0x2192 0x2190 0x2191 0x2193 0x3013 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x2208 0x220B 0x2286 0x2287 0x2282 0x2283 0x222A 0x2229 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x2227 0x2228 0xFFE2 0x21D2 0x21D4 0x2200 0x2203 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x2220 0x22A5 0x2312 0x2202 0x2207 0x2261 0x2252 0x226A 0x226B 0x221A 0x223D 0x221D 0x2235 0x222B 0x222C 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x212B 0x2030 0x266F 0x266D 0x266A 0x2020 0x2021 0x00B6 0x0020 0x0020 0x0020 0x0020 0x25EF +0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0xFF21 0xFF22 0xFF23 0xFF24 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C 0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0xFF41 0xFF42 0xFF43 0xFF44 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C 0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0x3000 0x3000 0x3000 0x3000 +0x3041 0x3042 0x3043 0x3044 0x3045 0x3046 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C 0x304D 0x304E 0x304F 0x3050 0x3051 0x3052 0x3053 0x3054 0x3055 0x3056 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C 0x305D 0x305E 0x305F 0x3060 0x3061 0x3062 0x3063 0x3064 0x3065 0x3066 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C 0x306D 0x306E 0x306F 0x3070 0x3071 0x3072 0x3073 0x3074 0x3075 0x3076 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C 0x307D 0x307E 0x307F 0x3080 0x3081 0x3082 0x3083 0x3084 0x3085 0x3086 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C 0x308D 0x308E 0x308F 0x3090 0x3091 0x3092 0x3093 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 +0x30A1 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 0x30A9 0x30AA 0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 0x30B9 0x30BA 0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 0x30C9 0x30CA 0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 0x30D9 0x30DA 0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 0x30E9 0x30EA 0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 +0x0391 0x0392 0x0393 0x0394 0x0395 0x0396 0x0397 0x0398 0x0399 0x039A 0x039B 0x039C 0x039D 0x039E 0x039F 0x03A0 0x03A1 0x03A3 0x03A4 0x03A5 0x03A6 0x03A7 0x03A8 0x03A9 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x03B1 0x03B2 0x03B3 0x03B4 0x03B5 0x03B6 0x03B7 0x03B8 0x03B9 0x03BA 0x03BB 0x03BC 0x03BD 0x03BE 0x03BF 0x03C0 0x03C1 0x03C3 0x03C4 0x03C5 0x03C6 0x03C7 0x03C8 0x03C9 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0410 0x0411 0x0412 0x0413 0x0414 0x0415 0x0401 0x0416 0x0417 0x0418 0x0419 0x041A 0x041B 0x041C 0x041D 0x041E 0x041F 0x0420 0x0421 0x0422 0x0423 0x0424 0x0425 0x0426 0x0427 0x0428 0x0429 0x042A 0x042B 0x042C 0x042D 0x042E 0x042F 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0430 0x0431 0x0432 0x0433 0x0434 0x0435 0x0451 0x0436 0x0437 0x0438 0x0439 0x043A 0x043B 0x043C 0x043D 0x043E 0x043F 0x0440 0x0441 0x0442 0x0443 0x0444 0x0445 0x0446 0x0447 0x0448 0x0449 0x044A 0x044B 0x044C 0x044D 0x044E 0x044F 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x2500 0x2502 0x250C 0x2510 0x2518 0x2514 0x251C 0x252C 0x2524 0x2534 0x253C 0x2501 0x2503 0x250F 0x2513 0x251B 0x2517 0x2523 0x2533 0x252B 0x253B 0x254B 0x2520 0x252F 0x2528 0x2537 0x253F 0x251D 0x2530 0x2525 0x2538 0x2542 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x4E9C 0x5516 0x5A03 0x963F 0x54C0 0x611B 0x6328 0x59F6 0x9022 0x8475 0x831C 0x7A50 0x60AA 0x63E1 0x6E25 0x65ED 0x8466 0x82A6 0x9BF5 0x6893 0x5727 0x65A1 0x6271 0x5B9B 0x59D0 0x867B 0x98F4 0x7D62 0x7DBE 0x9B8E 0x6216 0x7C9F 0x88B7 0x5B89 0x5EB5 0x6309 0x6697 0x6848 0x95C7 0x978D 0x674F 0x4EE5 0x4F0A 0x4F4D 0x4F9D 0x5049 0x56F2 0x5937 0x59D4 0x5A01 0x5C09 0x60DF 0x610F 0x6170 0x6613 0x6905 0x70BA 0x754F 0x7570 0x79FB 0x7DAD 0x7DEF 0x80C3 0x840E 0x8863 0x8B02 0x9055 0x907A 0x533B 0x4E95 0x4EA5 0x57DF 0x80B2 0x90C1 0x78EF 0x4E00 0x58F1 0x6EA2 0x9038 0x7A32 0x8328 0x828B 0x9C2F 0x5141 0x5370 0x54BD 0x54E1 0x56E0 0x59FB 0x5F15 0x98F2 0x6DEB 0x80E4 0x852D +0x9662 0x9670 0x96A0 0x97FB 0x540B 0x53F3 0x5B87 0x70CF 0x7FBD 0x8FC2 0x96E8 0x536F 0x9D5C 0x7ABA 0x4E11 0x7893 0x81FC 0x6E26 0x5618 0x5504 0x6B1D 0x851A 0x9C3B 0x59E5 0x53A9 0x6D66 0x74DC 0x958F 0x5642 0x4E91 0x904B 0x96F2 0x834F 0x990C 0x53E1 0x55B6 0x5B30 0x5F71 0x6620 0x66F3 0x6804 0x6C38 0x6CF3 0x6D29 0x745B 0x76C8 0x7A4E 0x9834 0x82F1 0x885B 0x8A60 0x92ED 0x6DB2 0x75AB 0x76CA 0x99C5 0x60A6 0x8B01 0x8D8A 0x95B2 0x698E 0x53AD 0x5186 0x5712 0x5830 0x5944 0x5BB4 0x5EF6 0x6028 0x63A9 0x63F4 0x6CBF 0x6F14 0x708E 0x7114 0x7159 0x71D5 0x733F 0x7E01 0x8276 0x82D1 0x8597 0x9060 0x925B 0x9D1B 0x5869 0x65BC 0x6C5A 0x7525 0x51F9 0x592E 0x5965 0x5F80 0x5FDC +0x62BC 0x65FA 0x6A2A 0x6B27 0x6BB4 0x738B 0x7FC1 0x8956 0x9D2C 0x9D0E 0x9EC4 0x5CA1 0x6C96 0x837B 0x5104 0x5C4B 0x61B6 0x81C6 0x6876 0x7261 0x4E59 0x4FFA 0x5378 0x6069 0x6E29 0x7A4F 0x97F3 0x4E0B 0x5316 0x4EEE 0x4F55 0x4F3D 0x4FA1 0x4F73 0x52A0 0x53EF 0x5609 0x590F 0x5AC1 0x5BB6 0x5BE1 0x79D1 0x6687 0x679C 0x67B6 0x6B4C 0x6CB3 0x706B 0x73C2 0x798D 0x79BE 0x7A3C 0x7B87 0x82B1 0x82DB 0x8304 0x8377 0x83EF 0x83D3 0x8766 0x8AB2 0x5629 0x8CA8 0x8FE6 0x904E 0x971E 0x868A 0x4FC4 0x5CE8 0x6211 0x7259 0x753B 0x81E5 0x82BD 0x86FE 0x8CC0 0x96C5 0x9913 0x99D5 0x4ECB 0x4F1A 0x89E3 0x56DE 0x584A 0x58CA 0x5EFB 0x5FEB 0x602A 0x6094 0x6062 0x61D0 0x6212 0x62D0 0x6539 +0x9B41 0x6666 0x68B0 0x6D77 0x7070 0x754C 0x7686 0x7D75 0x82A5 0x87F9 0x958B 0x968E 0x8C9D 0x51F1 0x52BE 0x5916 0x54B3 0x5BB3 0x5D16 0x6168 0x6982 0x6DAF 0x788D 0x84CB 0x8857 0x8A72 0x93A7 0x9AB8 0x6D6C 0x99A8 0x86D9 0x57A3 0x67FF 0x86CE 0x920E 0x5283 0x5687 0x5404 0x5ED3 0x62E1 0x64B9 0x683C 0x6838 0x6BBB 0x7372 0x78BA 0x7A6B 0x899A 0x89D2 0x8D6B 0x8F03 0x90ED 0x95A3 0x9694 0x9769 0x5B66 0x5CB3 0x697D 0x984D 0x984E 0x639B 0x7B20 0x6A2B 0x6A7F 0x68B6 0x9C0D 0x6F5F 0x5272 0x559D 0x6070 0x62EC 0x6D3B 0x6E07 0x6ED1 0x845B 0x8910 0x8F44 0x4E14 0x9C39 0x53F6 0x691B 0x6A3A 0x9784 0x682A 0x515C 0x7AC3 0x84B2 0x91DC 0x938C 0x565B 0x9D28 0x6822 0x8305 0x8431 +0x7CA5 0x5208 0x82C5 0x74E6 0x4E7E 0x4F83 0x51A0 0x5BD2 0x520A 0x52D8 0x52E7 0x5DFB 0x559A 0x582A 0x59E6 0x5B8C 0x5B98 0x5BDB 0x5E72 0x5E79 0x60A3 0x611F 0x6163 0x61BE 0x63DB 0x6562 0x67D1 0x6853 0x68FA 0x6B3E 0x6B53 0x6C57 0x6F22 0x6F97 0x6F45 0x74B0 0x7518 0x76E3 0x770B 0x7AFF 0x7BA1 0x7C21 0x7DE9 0x7F36 0x7FF0 0x809D 0x8266 0x839E 0x89B3 0x8ACC 0x8CAB 0x9084 0x9451 0x9593 0x9591 0x95A2 0x9665 0x97D3 0x9928 0x8218 0x4E38 0x542B 0x5CB8 0x5DCC 0x73A9 0x764C 0x773C 0x5CA9 0x7FEB 0x8D0B 0x96C1 0x9811 0x9854 0x9858 0x4F01 0x4F0E 0x5371 0x559C 0x5668 0x57FA 0x5947 0x5B09 0x5BC4 0x5C90 0x5E0C 0x5E7E 0x5FCC 0x63EE 0x673A 0x65D7 0x65E2 0x671F 0x68CB 0x68C4 +0x6A5F 0x5E30 0x6BC5 0x6C17 0x6C7D 0x757F 0x7948 0x5B63 0x7A00 0x7D00 0x5FBD 0x898F 0x8A18 0x8CB4 0x8D77 0x8ECC 0x8F1D 0x98E2 0x9A0E 0x9B3C 0x4E80 0x507D 0x5100 0x5993 0x5B9C 0x622F 0x6280 0x64EC 0x6B3A 0x72A0 0x7591 0x7947 0x7FA9 0x87FB 0x8ABC 0x8B70 0x63AC 0x83CA 0x97A0 0x5409 0x5403 0x55AB 0x6854 0x6A58 0x8A70 0x7827 0x6775 0x9ECD 0x5374 0x5BA2 0x811A 0x8650 0x9006 0x4E18 0x4E45 0x4EC7 0x4F11 0x53CA 0x5438 0x5BAE 0x5F13 0x6025 0x6551 0x673D 0x6C42 0x6C72 0x6CE3 0x7078 0x7403 0x7A76 0x7AAE 0x7B08 0x7D1A 0x7CFE 0x7D66 0x65E7 0x725B 0x53BB 0x5C45 0x5DE8 0x62D2 0x62E0 0x6319 0x6E20 0x865A 0x8A31 0x8DDD 0x92F8 0x6F01 0x79A6 0x9B5A 0x4EA8 0x4EAB 0x4EAC +0x4F9B 0x4FA0 0x50D1 0x5147 0x7AF6 0x5171 0x51F6 0x5354 0x5321 0x537F 0x53EB 0x55AC 0x5883 0x5CE1 0x5F37 0x5F4A 0x602F 0x6050 0x606D 0x631F 0x6559 0x6A4B 0x6CC1 0x72C2 0x72ED 0x77EF 0x80F8 0x8105 0x8208 0x854E 0x90F7 0x93E1 0x97FF 0x9957 0x9A5A 0x4EF0 0x51DD 0x5C2D 0x6681 0x696D 0x5C40 0x66F2 0x6975 0x7389 0x6850 0x7C81 0x50C5 0x52E4 0x5747 0x5DFE 0x9326 0x65A4 0x6B23 0x6B3D 0x7434 0x7981 0x79BD 0x7B4B 0x7DCA 0x82B9 0x83CC 0x887F 0x895F 0x8B39 0x8FD1 0x91D1 0x541F 0x9280 0x4E5D 0x5036 0x53E5 0x533A 0x72D7 0x7396 0x77E9 0x82E6 0x8EAF 0x99C6 0x99C8 0x99D2 0x5177 0x611A 0x865E 0x55B0 0x7A7A 0x5076 0x5BD3 0x9047 0x9685 0x4E32 0x6ADB 0x91E7 0x5C51 0x5C48 +0x6398 0x7A9F 0x6C93 0x9774 0x8F61 0x7AAA 0x718A 0x9688 0x7C82 0x6817 0x7E70 0x6851 0x936C 0x52F2 0x541B 0x85AB 0x8A13 0x7FA4 0x8ECD 0x90E1 0x5366 0x8888 0x7941 0x4FC2 0x50BE 0x5211 0x5144 0x5553 0x572D 0x73EA 0x578B 0x5951 0x5F62 0x5F84 0x6075 0x6176 0x6167 0x61A9 0x63B2 0x643A 0x656C 0x666F 0x6842 0x6E13 0x7566 0x7A3D 0x7CFB 0x7D4C 0x7D99 0x7E4B 0x7F6B 0x830E 0x834A 0x86CD 0x8A08 0x8A63 0x8B66 0x8EFD 0x981A 0x9D8F 0x82B8 0x8FCE 0x9BE8 0x5287 0x621F 0x6483 0x6FC0 0x9699 0x6841 0x5091 0x6B20 0x6C7A 0x6F54 0x7A74 0x7D50 0x8840 0x8A23 0x6708 0x4EF6 0x5039 0x5026 0x5065 0x517C 0x5238 0x5263 0x55A7 0x570F 0x5805 0x5ACC 0x5EFA 0x61B2 0x61F8 0x62F3 0x6372 +0x691C 0x6A29 0x727D 0x72AC 0x732E 0x7814 0x786F 0x7D79 0x770C 0x80A9 0x898B 0x8B19 0x8CE2 0x8ED2 0x9063 0x9375 0x967A 0x9855 0x9A13 0x9E78 0x5143 0x539F 0x53B3 0x5E7B 0x5F26 0x6E1B 0x6E90 0x7384 0x73FE 0x7D43 0x8237 0x8A00 0x8AFA 0x9650 0x4E4E 0x500B 0x53E4 0x547C 0x56FA 0x59D1 0x5B64 0x5DF1 0x5EAB 0x5F27 0x6238 0x6545 0x67AF 0x6E56 0x72D0 0x7CCA 0x88B4 0x80A1 0x80E1 0x83F0 0x864E 0x8A87 0x8DE8 0x9237 0x96C7 0x9867 0x9F13 0x4E94 0x4E92 0x4F0D 0x5348 0x5449 0x543E 0x5A2F 0x5F8C 0x5FA1 0x609F 0x68A7 0x6A8E 0x745A 0x7881 0x8A9E 0x8AA4 0x8B77 0x9190 0x4E5E 0x9BC9 0x4EA4 0x4F7C 0x4FAF 0x5019 0x5016 0x5149 0x516C 0x529F 0x52B9 0x52FE 0x539A 0x53E3 0x5411 +0x540E 0x5589 0x5751 0x57A2 0x597D 0x5B54 0x5B5D 0x5B8F 0x5DE5 0x5DE7 0x5DF7 0x5E78 0x5E83 0x5E9A 0x5EB7 0x5F18 0x6052 0x614C 0x6297 0x62D8 0x63A7 0x653B 0x6602 0x6643 0x66F4 0x676D 0x6821 0x6897 0x69CB 0x6C5F 0x6D2A 0x6D69 0x6E2F 0x6E9D 0x7532 0x7687 0x786C 0x7A3F 0x7CE0 0x7D05 0x7D18 0x7D5E 0x7DB1 0x8015 0x8003 0x80AF 0x80B1 0x8154 0x818F 0x822A 0x8352 0x884C 0x8861 0x8B1B 0x8CA2 0x8CFC 0x90CA 0x9175 0x9271 0x783F 0x92FC 0x95A4 0x964D 0x9805 0x9999 0x9AD8 0x9D3B 0x525B 0x52AB 0x53F7 0x5408 0x58D5 0x62F7 0x6FE0 0x8C6A 0x8F5F 0x9EB9 0x514B 0x523B 0x544A 0x56FD 0x7A40 0x9177 0x9D60 0x9ED2 0x7344 0x6F09 0x8170 0x7511 0x5FFD 0x60DA 0x9AA8 0x72DB 0x8FBC +0x6B64 0x9803 0x4ECA 0x56F0 0x5764 0x58BE 0x5A5A 0x6068 0x61C7 0x660F 0x6606 0x6839 0x68B1 0x6DF7 0x75D5 0x7D3A 0x826E 0x9B42 0x4E9B 0x4F50 0x53C9 0x5506 0x5D6F 0x5DE6 0x5DEE 0x67FB 0x6C99 0x7473 0x7802 0x8A50 0x9396 0x88DF 0x5750 0x5EA7 0x632B 0x50B5 0x50AC 0x518D 0x6700 0x54C9 0x585E 0x59BB 0x5BB0 0x5F69 0x624D 0x63A1 0x683D 0x6B73 0x6E08 0x707D 0x91C7 0x7280 0x7815 0x7826 0x796D 0x658E 0x7D30 0x83DC 0x88C1 0x8F09 0x969B 0x5264 0x5728 0x6750 0x7F6A 0x8CA1 0x51B4 0x5742 0x962A 0x583A 0x698A 0x80B4 0x54B2 0x5D0E 0x57FC 0x7895 0x9DFA 0x4F5C 0x524A 0x548B 0x643E 0x6628 0x6714 0x67F5 0x7A84 0x7B56 0x7D22 0x932F 0x685C 0x9BAD 0x7B39 0x5319 0x518A 0x5237 +0x5BDF 0x62F6 0x64AE 0x64E6 0x672D 0x6BBA 0x85A9 0x96D1 0x7690 0x9BD6 0x634C 0x9306 0x9BAB 0x76BF 0x6652 0x4E09 0x5098 0x53C2 0x5C71 0x60E8 0x6492 0x6563 0x685F 0x71E6 0x73CA 0x7523 0x7B97 0x7E82 0x8695 0x8B83 0x8CDB 0x9178 0x9910 0x65AC 0x66AB 0x6B8B 0x4ED5 0x4ED4 0x4F3A 0x4F7F 0x523A 0x53F8 0x53F2 0x55E3 0x56DB 0x58EB 0x59CB 0x59C9 0x59FF 0x5B50 0x5C4D 0x5E02 0x5E2B 0x5FD7 0x601D 0x6307 0x652F 0x5B5C 0x65AF 0x65BD 0x65E8 0x679D 0x6B62 0x6B7B 0x6C0F 0x7345 0x7949 0x79C1 0x7CF8 0x7D19 0x7D2B 0x80A2 0x8102 0x81F3 0x8996 0x8A5E 0x8A69 0x8A66 0x8A8C 0x8AEE 0x8CC7 0x8CDC 0x96CC 0x98FC 0x6B6F 0x4E8B 0x4F3C 0x4F8D 0x5150 0x5B57 0x5BFA 0x6148 0x6301 0x6642 +0x6B21 0x6ECB 0x6CBB 0x723E 0x74BD 0x75D4 0x78C1 0x793A 0x800C 0x8033 0x81EA 0x8494 0x8F9E 0x6C50 0x9E7F 0x5F0F 0x8B58 0x9D2B 0x7AFA 0x8EF8 0x5B8D 0x96EB 0x4E03 0x53F1 0x57F7 0x5931 0x5AC9 0x5BA4 0x6089 0x6E7F 0x6F06 0x75BE 0x8CEA 0x5B9F 0x8500 0x7BE0 0x5072 0x67F4 0x829D 0x5C61 0x854A 0x7E1E 0x820E 0x5199 0x5C04 0x6368 0x8D66 0x659C 0x716E 0x793E 0x7D17 0x8005 0x8B1D 0x8ECA 0x906E 0x86C7 0x90AA 0x501F 0x52FA 0x5C3A 0x6753 0x707C 0x7235 0x914C 0x91C8 0x932B 0x82E5 0x5BC2 0x5F31 0x60F9 0x4E3B 0x53D6 0x5B88 0x624B 0x6731 0x6B8A 0x72E9 0x73E0 0x7A2E 0x816B 0x8DA3 0x9152 0x9996 0x5112 0x53D7 0x546A 0x5BFF 0x6388 0x6A39 0x7DAC 0x9700 0x56DA 0x53CE 0x5468 +0x5B97 0x5C31 0x5DDE 0x4FEE 0x6101 0x62FE 0x6D32 0x79C0 0x79CB 0x7D42 0x7E4D 0x7FD2 0x81ED 0x821F 0x8490 0x8846 0x8972 0x8B90 0x8E74 0x8F2F 0x9031 0x914B 0x916C 0x96C6 0x919C 0x4EC0 0x4F4F 0x5145 0x5341 0x5F93 0x620E 0x67D4 0x6C41 0x6E0B 0x7363 0x7E26 0x91CD 0x9283 0x53D4 0x5919 0x5BBF 0x6DD1 0x795D 0x7E2E 0x7C9B 0x587E 0x719F 0x51FA 0x8853 0x8FF0 0x4FCA 0x5CFB 0x6625 0x77AC 0x7AE3 0x821C 0x99FF 0x51C6 0x5FAA 0x65EC 0x696F 0x6B89 0x6DF3 0x6E96 0x6F64 0x76FE 0x7D14 0x5DE1 0x9075 0x9187 0x9806 0x51E6 0x521D 0x6240 0x6691 0x66D9 0x6E1A 0x5EB6 0x7DD2 0x7F72 0x66F8 0x85AF 0x85F7 0x8AF8 0x52A9 0x53D9 0x5973 0x5E8F 0x5F90 0x6055 0x92E4 0x9664 0x50B7 0x511F +0x52DD 0x5320 0x5347 0x53EC 0x54E8 0x5546 0x5531 0x5617 0x5968 0x59BE 0x5A3C 0x5BB5 0x5C06 0x5C0F 0x5C11 0x5C1A 0x5E84 0x5E8A 0x5EE0 0x5F70 0x627F 0x6284 0x62DB 0x638C 0x6377 0x6607 0x660C 0x662D 0x6676 0x677E 0x68A2 0x6A1F 0x6A35 0x6CBC 0x6D88 0x6E09 0x6E58 0x713C 0x7126 0x7167 0x75C7 0x7701 0x785D 0x7901 0x7965 0x79F0 0x7AE0 0x7B11 0x7CA7 0x7D39 0x8096 0x83D6 0x848B 0x8549 0x885D 0x88F3 0x8A1F 0x8A3C 0x8A54 0x8A73 0x8C61 0x8CDE 0x91A4 0x9266 0x937E 0x9418 0x969C 0x9798 0x4E0A 0x4E08 0x4E1E 0x4E57 0x5197 0x5270 0x57CE 0x5834 0x58CC 0x5B22 0x5E38 0x60C5 0x64FE 0x6761 0x6756 0x6D44 0x72B6 0x7573 0x7A63 0x84B8 0x8B72 0x91B8 0x9320 0x5631 0x57F4 0x98FE +0x62ED 0x690D 0x6B96 0x71ED 0x7E54 0x8077 0x8272 0x89E6 0x98DF 0x8755 0x8FB1 0x5C3B 0x4F38 0x4FE1 0x4FB5 0x5507 0x5A20 0x5BDD 0x5BE9 0x5FC3 0x614E 0x632F 0x65B0 0x664B 0x68EE 0x699B 0x6D78 0x6DF1 0x7533 0x75B9 0x771F 0x795E 0x79E6 0x7D33 0x81E3 0x82AF 0x85AA 0x89AA 0x8A3A 0x8EAB 0x8F9B 0x9032 0x91DD 0x9707 0x4EBA 0x4EC1 0x5203 0x5875 0x58EC 0x5C0B 0x751A 0x5C3D 0x814E 0x8A0A 0x8FC5 0x9663 0x976D 0x7B25 0x8ACF 0x9808 0x9162 0x56F3 0x53A8 0x9017 0x5439 0x5782 0x5E25 0x63A8 0x6C34 0x708A 0x7761 0x7C8B 0x7FE0 0x8870 0x9042 0x9154 0x9310 0x9318 0x968F 0x745E 0x9AC4 0x5D07 0x5D69 0x6570 0x67A2 0x8DA8 0x96DB 0x636E 0x6749 0x6919 0x83C5 0x9817 0x96C0 0x88FE +0x6F84 0x647A 0x5BF8 0x4E16 0x702C 0x755D 0x662F 0x51C4 0x5236 0x52E2 0x59D3 0x5F81 0x6027 0x6210 0x653F 0x6574 0x661F 0x6674 0x68F2 0x6816 0x6B63 0x6E05 0x7272 0x751F 0x76DB 0x7CBE 0x8056 0x58F0 0x88FD 0x897F 0x8AA0 0x8A93 0x8ACB 0x901D 0x9192 0x9752 0x9759 0x6589 0x7A0E 0x8106 0x96BB 0x5E2D 0x60DC 0x621A 0x65A5 0x6614 0x6790 0x77F3 0x7A4D 0x7C4D 0x7E3E 0x810A 0x8CAC 0x8D64 0x8DE1 0x8E5F 0x78A9 0x5207 0x62D9 0x63A5 0x6442 0x6298 0x8A2D 0x7A83 0x7BC0 0x8AAC 0x96EA 0x7D76 0x820C 0x8749 0x4ED9 0x5148 0x5343 0x5360 0x5BA3 0x5C02 0x5C16 0x5DDD 0x6226 0x6247 0x64B0 0x6813 0x6834 0x6CC9 0x6D45 0x6D17 0x67D3 0x6F5C 0x714E 0x717D 0x65CB 0x7A7F 0x7BAD 0x7DDA +0x7E4A 0x7FA8 0x817A 0x821B 0x8239 0x85A6 0x8A6E 0x8CCE 0x8DF5 0x9078 0x9077 0x92AD 0x9291 0x9583 0x9BAE 0x524D 0x5584 0x6F38 0x7136 0x5168 0x7985 0x7E55 0x81B3 0x7CCE 0x564C 0x5851 0x5CA8 0x63AA 0x66FE 0x66FD 0x695A 0x72D9 0x758F 0x758E 0x790E 0x7956 0x79DF 0x7C97 0x7D20 0x7D44 0x8607 0x8A34 0x963B 0x9061 0x9F20 0x50E7 0x5275 0x53CC 0x53E2 0x5009 0x55AA 0x58EE 0x594F 0x723D 0x5B8B 0x5C64 0x531D 0x60E3 0x60F3 0x635C 0x6383 0x633F 0x63BB 0x64CD 0x65E9 0x66F9 0x5DE3 0x69CD 0x69FD 0x6F15 0x71E5 0x4E89 0x75E9 0x76F8 0x7A93 0x7CDF 0x7DCF 0x7D9C 0x8061 0x8349 0x8358 0x846C 0x84BC 0x85FB 0x88C5 0x8D70 0x9001 0x906D 0x9397 0x971C 0x9A12 0x50CF 0x5897 0x618E +0x81D3 0x8535 0x8D08 0x9020 0x4FC3 0x5074 0x5247 0x5373 0x606F 0x6349 0x675F 0x6E2C 0x8DB3 0x901F 0x4FD7 0x5C5E 0x8CCA 0x65CF 0x7D9A 0x5352 0x8896 0x5176 0x63C3 0x5B58 0x5B6B 0x5C0A 0x640D 0x6751 0x905C 0x4ED6 0x591A 0x592A 0x6C70 0x8A51 0x553E 0x5815 0x59A5 0x60F0 0x6253 0x67C1 0x8235 0x6955 0x9640 0x99C4 0x9A28 0x4F53 0x5806 0x5BFE 0x8010 0x5CB1 0x5E2F 0x5F85 0x6020 0x614B 0x6234 0x66FF 0x6CF0 0x6EDE 0x80CE 0x817F 0x82D4 0x888B 0x8CB8 0x9000 0x902E 0x968A 0x9EDB 0x9BDB 0x4EE3 0x53F0 0x5927 0x7B2C 0x918D 0x984C 0x9DF9 0x6EDD 0x7027 0x5353 0x5544 0x5B85 0x6258 0x629E 0x62D3 0x6CA2 0x6FEF 0x7422 0x8A17 0x9438 0x6FC1 0x8AFE 0x8338 0x51E7 0x86F8 0x53EA +0x53E9 0x4F46 0x9054 0x8FB0 0x596A 0x8131 0x5DFD 0x7AEA 0x8FBF 0x68DA 0x8C37 0x72F8 0x9C48 0x6A3D 0x8AB0 0x4E39 0x5358 0x5606 0x5766 0x62C5 0x63A2 0x65E6 0x6B4E 0x6DE1 0x6E5B 0x70AD 0x77ED 0x7AEF 0x7BAA 0x7DBB 0x803D 0x80C6 0x86CB 0x8A95 0x935B 0x56E3 0x58C7 0x5F3E 0x65AD 0x6696 0x6A80 0x6BB5 0x7537 0x8AC7 0x5024 0x77E5 0x5730 0x5F1B 0x6065 0x667A 0x6C60 0x75F4 0x7A1A 0x7F6E 0x81F4 0x8718 0x9045 0x99B3 0x7BC9 0x755C 0x7AF9 0x7B51 0x84C4 0x9010 0x79E9 0x7A92 0x8336 0x5AE1 0x7740 0x4E2D 0x4EF2 0x5B99 0x5FE0 0x62BD 0x663C 0x67F1 0x6CE8 0x866B 0x8877 0x8A3B 0x914E 0x92F3 0x99D0 0x6A17 0x7026 0x732A 0x82E7 0x8457 0x8CAF 0x4E01 0x5146 0x51CB 0x558B 0x5BF5 +0x5E16 0x5E33 0x5E81 0x5F14 0x5F35 0x5F6B 0x5FB4 0x61F2 0x6311 0x66A2 0x671D 0x6F6E 0x7252 0x753A 0x773A 0x8074 0x8139 0x8178 0x8776 0x8ABF 0x8ADC 0x8D85 0x8DF3 0x929A 0x9577 0x9802 0x9CE5 0x52C5 0x6357 0x76F4 0x6715 0x6C88 0x73CD 0x8CC3 0x93AE 0x9673 0x6D25 0x589C 0x690E 0x69CC 0x8FFD 0x939A 0x75DB 0x901A 0x585A 0x6802 0x63B4 0x69FB 0x4F43 0x6F2C 0x67D8 0x8FBB 0x8526 0x7DB4 0x9354 0x693F 0x6F70 0x576A 0x58F7 0x5B2C 0x7D2C 0x722A 0x540A 0x91E3 0x9DB4 0x4EAD 0x4F4E 0x505C 0x5075 0x5243 0x8C9E 0x5448 0x5824 0x5B9A 0x5E1D 0x5E95 0x5EAD 0x5EF7 0x5F1F 0x608C 0x62B5 0x633A 0x63D0 0x68AF 0x6C40 0x7887 0x798E 0x7A0B 0x7DE0 0x8247 0x8A02 0x8AE6 0x8E44 0x9013 +0x90B8 0x912D 0x91D8 0x9F0E 0x6CE5 0x6458 0x64E2 0x6575 0x6EF4 0x7684 0x7B1B 0x9069 0x93D1 0x6EBA 0x54F2 0x5FB9 0x64A4 0x8F4D 0x8FED 0x9244 0x5178 0x586B 0x5929 0x5C55 0x5E97 0x6DFB 0x7E8F 0x751C 0x8CBC 0x8EE2 0x985B 0x70B9 0x4F1D 0x6BBF 0x6FB1 0x7530 0x96FB 0x514E 0x5410 0x5835 0x5857 0x59AC 0x5C60 0x5F92 0x6597 0x675C 0x6E21 0x767B 0x83DF 0x8CED 0x9014 0x90FD 0x934D 0x7825 0x783A 0x52AA 0x5EA6 0x571F 0x5974 0x6012 0x5012 0x515A 0x51AC 0x51CD 0x5200 0x5510 0x5854 0x5858 0x5957 0x5B95 0x5CF6 0x5D8B 0x60BC 0x6295 0x642D 0x6771 0x6843 0x68BC 0x68DF 0x76D7 0x6DD8 0x6E6F 0x6D9B 0x706F 0x71C8 0x5F53 0x75D8 0x7977 0x7B49 0x7B54 0x7B52 0x7CD6 0x7D71 0x5230 +0x8463 0x8569 0x85E4 0x8A0E 0x8B04 0x8C46 0x8E0F 0x9003 0x900F 0x9419 0x9676 0x982D 0x9A30 0x95D8 0x50CD 0x52D5 0x540C 0x5802 0x5C0E 0x61A7 0x649E 0x6D1E 0x77B3 0x7AE5 0x80F4 0x8404 0x9053 0x9285 0x5CE0 0x9D07 0x533F 0x5F97 0x5FB3 0x6D9C 0x7279 0x7763 0x79BF 0x7BE4 0x6BD2 0x72EC 0x8AAD 0x6803 0x6A61 0x51F8 0x7A81 0x6934 0x5C4A 0x9CF6 0x82EB 0x5BC5 0x9149 0x701E 0x5678 0x5C6F 0x60C7 0x6566 0x6C8C 0x8C5A 0x9041 0x9813 0x5451 0x66C7 0x920D 0x5948 0x90A3 0x5185 0x4E4D 0x51EA 0x8599 0x8B0E 0x7058 0x637A 0x934B 0x6962 0x99B4 0x7E04 0x7577 0x5357 0x6960 0x8EDF 0x96E3 0x6C5D 0x4E8C 0x5C3C 0x5F10 0x8FE9 0x5302 0x8CD1 0x8089 0x8679 0x5EFF 0x65E5 0x4E73 0x5165 +0x5982 0x5C3F 0x97EE 0x4EFB 0x598A 0x5FCD 0x8A8D 0x6FE1 0x79B0 0x7962 0x5BE7 0x8471 0x732B 0x71B1 0x5E74 0x5FF5 0x637B 0x649A 0x71C3 0x7C98 0x4E43 0x5EFC 0x4E4B 0x57DC 0x56A2 0x60A9 0x6FC3 0x7D0D 0x80FD 0x8133 0x81BF 0x8FB2 0x8997 0x86A4 0x5DF4 0x628A 0x64AD 0x8987 0x6777 0x6CE2 0x6D3E 0x7436 0x7834 0x5A46 0x7F75 0x82AD 0x99AC 0x4FF3 0x5EC3 0x62DD 0x6392 0x6557 0x676F 0x76C3 0x724C 0x80CC 0x80BA 0x8F29 0x914D 0x500D 0x57F9 0x5A92 0x6885 0x6973 0x7164 0x72FD 0x8CB7 0x58F2 0x8CE0 0x966A 0x9019 0x877F 0x79E4 0x77E7 0x8429 0x4F2F 0x5265 0x535A 0x62CD 0x67CF 0x6CCA 0x767D 0x7B94 0x7C95 0x8236 0x8584 0x8FEB 0x66DD 0x6F20 0x7206 0x7E1B 0x83AB 0x99C1 0x9EA6 +0x51FD 0x7BB1 0x7872 0x7BB8 0x8087 0x7B48 0x6AE8 0x5E61 0x808C 0x7551 0x7560 0x516B 0x9262 0x6E8C 0x767A 0x9197 0x9AEA 0x4F10 0x7F70 0x629C 0x7B4F 0x95A5 0x9CE9 0x567A 0x5859 0x86E4 0x96BC 0x4F34 0x5224 0x534A 0x53CD 0x53DB 0x5E06 0x642C 0x6591 0x677F 0x6C3E 0x6C4E 0x7248 0x72AF 0x73ED 0x7554 0x7E41 0x822C 0x85E9 0x8CA9 0x7BC4 0x91C6 0x7169 0x9812 0x98EF 0x633D 0x6669 0x756A 0x76E4 0x78D0 0x8543 0x86EE 0x532A 0x5351 0x5426 0x5983 0x5E87 0x5F7C 0x60B2 0x6249 0x6279 0x62AB 0x6590 0x6BD4 0x6CCC 0x75B2 0x76AE 0x7891 0x79D8 0x7DCB 0x7F77 0x80A5 0x88AB 0x8AB9 0x8CBB 0x907F 0x975E 0x98DB 0x6A0B 0x7C38 0x5099 0x5C3E 0x5FAE 0x6787 0x6BD8 0x7435 0x7709 0x7F8E +0x9F3B 0x67CA 0x7A17 0x5339 0x758B 0x9AED 0x5F66 0x819D 0x83F1 0x8098 0x5F3C 0x5FC5 0x7562 0x7B46 0x903C 0x6867 0x59EB 0x5A9B 0x7D10 0x767E 0x8B2C 0x4FF5 0x5F6A 0x6A19 0x6C37 0x6F02 0x74E2 0x7968 0x8868 0x8A55 0x8C79 0x5EDF 0x63CF 0x75C5 0x79D2 0x82D7 0x9328 0x92F2 0x849C 0x86ED 0x9C2D 0x54C1 0x5F6C 0x658C 0x6D5C 0x7015 0x8CA7 0x8CD3 0x983B 0x654F 0x74F6 0x4E0D 0x4ED8 0x57E0 0x592B 0x5A66 0x5BCC 0x51A8 0x5E03 0x5E9C 0x6016 0x6276 0x6577 0x65A7 0x666E 0x6D6E 0x7236 0x7B26 0x8150 0x819A 0x8299 0x8B5C 0x8CA0 0x8CE6 0x8D74 0x961C 0x9644 0x4FAE 0x64AB 0x6B66 0x821E 0x8461 0x856A 0x90E8 0x5C01 0x6953 0x98A8 0x847A 0x8557 0x4F0F 0x526F 0x5FA9 0x5E45 0x670D +0x798F 0x8179 0x8907 0x8986 0x6DF5 0x5F17 0x6255 0x6CB8 0x4ECF 0x7269 0x9B92 0x5206 0x543B 0x5674 0x58B3 0x61A4 0x626E 0x711A 0x596E 0x7C89 0x7CDE 0x7D1B 0x96F0 0x6587 0x805E 0x4E19 0x4F75 0x5175 0x5840 0x5E63 0x5E73 0x5F0A 0x67C4 0x4E26 0x853D 0x9589 0x965B 0x7C73 0x9801 0x50FB 0x58C1 0x7656 0x78A7 0x5225 0x77A5 0x8511 0x7B86 0x504F 0x5909 0x7247 0x7BC7 0x7DE8 0x8FBA 0x8FD4 0x904D 0x4FBF 0x52C9 0x5A29 0x5F01 0x97AD 0x4FDD 0x8217 0x92EA 0x5703 0x6355 0x6B69 0x752B 0x88DC 0x8F14 0x7A42 0x52DF 0x5893 0x6155 0x620A 0x66AE 0x6BCD 0x7C3F 0x83E9 0x5023 0x4FF8 0x5305 0x5446 0x5831 0x5949 0x5B9D 0x5CF0 0x5CEF 0x5D29 0x5E96 0x62B1 0x6367 0x653E 0x65B9 0x670B +0x6CD5 0x6CE1 0x70F9 0x7832 0x7E2B 0x80DE 0x82B3 0x840C 0x84EC 0x8702 0x8912 0x8A2A 0x8C4A 0x90A6 0x92D2 0x98FD 0x9CF3 0x9D6C 0x4E4F 0x4EA1 0x508D 0x5256 0x574A 0x59A8 0x5E3D 0x5FD8 0x5FD9 0x623F 0x66B4 0x671B 0x67D0 0x68D2 0x5192 0x7D21 0x80AA 0x81A8 0x8B00 0x8C8C 0x8CBF 0x927E 0x9632 0x5420 0x982C 0x5317 0x50D5 0x535C 0x58A8 0x64B2 0x6734 0x7267 0x7766 0x7A46 0x91E6 0x52C3 0x6CA1 0x6B86 0x5800 0x5E4C 0x5954 0x672C 0x7FFB 0x51E1 0x76C6 0x6469 0x78E8 0x9B54 0x9EBB 0x57CB 0x59B9 0x6627 0x679A 0x6BCE 0x54E9 0x69D9 0x5E55 0x819C 0x6795 0x9BAA 0x67FE 0x9C52 0x685D 0x4EA6 0x4FE3 0x53C8 0x62B9 0x672B 0x6CAB 0x8FC4 0x4FAD 0x7E6D 0x9EBF 0x4E07 0x6162 0x6E80 +0x6F2B 0x8513 0x5473 0x672A 0x9B45 0x5DF3 0x7B95 0x5CAC 0x5BC6 0x871C 0x6E4A 0x84D1 0x7A14 0x8108 0x5999 0x7C8D 0x6C11 0x7720 0x52D9 0x5922 0x7121 0x725F 0x77DB 0x9727 0x9D61 0x690B 0x5A7F 0x5A18 0x51A5 0x540D 0x547D 0x660E 0x76DF 0x8FF7 0x9298 0x9CF4 0x59EA 0x725D 0x6EC5 0x514D 0x68C9 0x7DBF 0x7DEC 0x9762 0x9EBA 0x6478 0x6A21 0x8302 0x5984 0x5B5F 0x6BDB 0x731B 0x76F2 0x7DB2 0x8017 0x8499 0x5132 0x6728 0x9ED9 0x76EE 0x6762 0x52FF 0x9905 0x5C24 0x623B 0x7C7E 0x8CB0 0x554F 0x60B6 0x7D0B 0x9580 0x5301 0x4E5F 0x51B6 0x591C 0x723A 0x8036 0x91CE 0x5F25 0x77E2 0x5384 0x5F79 0x7D04 0x85AC 0x8A33 0x8E8D 0x9756 0x67F3 0x85AE 0x9453 0x6109 0x6108 0x6CB9 0x7652 +0x8AED 0x8F38 0x552F 0x4F51 0x512A 0x52C7 0x53CB 0x5BA5 0x5E7D 0x60A0 0x6182 0x63D6 0x6709 0x67DA 0x6E67 0x6D8C 0x7336 0x7337 0x7531 0x7950 0x88D5 0x8A98 0x904A 0x9091 0x90F5 0x96C4 0x878D 0x5915 0x4E88 0x4F59 0x4E0E 0x8A89 0x8F3F 0x9810 0x50AD 0x5E7C 0x5996 0x5BB9 0x5EB8 0x63DA 0x63FA 0x64C1 0x66DC 0x694A 0x69D8 0x6D0B 0x6EB6 0x7194 0x7528 0x7AAF 0x7F8A 0x8000 0x8449 0x84C9 0x8981 0x8B21 0x8E0A 0x9065 0x967D 0x990A 0x617E 0x6291 0x6B32 0x6C83 0x6D74 0x7FCC 0x7FFC 0x6DC0 0x7F85 0x87BA 0x88F8 0x6765 0x83B1 0x983C 0x96F7 0x6D1B 0x7D61 0x843D 0x916A 0x4E71 0x5375 0x5D50 0x6B04 0x6FEB 0x85CD 0x862D 0x89A7 0x5229 0x540F 0x5C65 0x674E 0x68A8 0x7406 0x7483 +0x75E2 0x88CF 0x88E1 0x91CC 0x96E2 0x9678 0x5F8B 0x7387 0x7ACB 0x844E 0x63A0 0x7565 0x5289 0x6D41 0x6E9C 0x7409 0x7559 0x786B 0x7C92 0x9686 0x7ADC 0x9F8D 0x4FB6 0x616E 0x65C5 0x865C 0x4E86 0x4EAE 0x50DA 0x4E21 0x51CC 0x5BEE 0x6599 0x6881 0x6DBC 0x731F 0x7642 0x77AD 0x7A1C 0x7CE7 0x826F 0x8AD2 0x907C 0x91CF 0x9675 0x9818 0x529B 0x7DD1 0x502B 0x5398 0x6797 0x6DCB 0x71D0 0x7433 0x81E8 0x8F2A 0x96A3 0x9C57 0x9E9F 0x7460 0x5841 0x6D99 0x7D2F 0x985E 0x4EE4 0x4F36 0x4F8B 0x51B7 0x52B1 0x5DBA 0x601C 0x73B2 0x793C 0x82D3 0x9234 0x96B7 0x96F6 0x970A 0x9E97 0x9F62 0x66A6 0x6B74 0x5217 0x52A3 0x70C8 0x88C2 0x5EC9 0x604B 0x6190 0x6F23 0x7149 0x7C3E 0x7DF4 0x806F +0x84EE 0x9023 0x932C 0x5442 0x9B6F 0x6AD3 0x7089 0x8CC2 0x8DEF 0x9732 0x52B4 0x5A41 0x5ECA 0x5F04 0x6717 0x697C 0x6994 0x6D6A 0x6F0F 0x7262 0x72FC 0x7BED 0x8001 0x807E 0x874B 0x90CE 0x516D 0x9E93 0x7984 0x808B 0x9332 0x8AD6 0x502D 0x548C 0x8A71 0x6B6A 0x8CC4 0x8107 0x60D1 0x67A0 0x9DF2 0x4E99 0x4E98 0x9C10 0x8A6B 0x85C1 0x8568 0x6900 0x6E7E 0x7897 0x8155 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 0x3000 +0x5F0C 0x4E10 0x4E15 0x4E2A 0x4E31 0x4E36 0x4E3C 0x4E3F 0x4E42 0x4E56 0x4E58 0x4E82 0x4E85 0x8C6B 0x4E8A 0x8212 0x5F0D 0x4E8E 0x4E9E 0x4E9F 0x4EA0 0x4EA2 0x4EB0 0x4EB3 0x4EB6 0x4ECE 0x4ECD 0x4EC4 0x4EC6 0x4EC2 0x4ED7 0x4EDE 0x4EED 0x4EDF 0x4EF7 0x4F09 0x4F5A 0x4F30 0x4F5B 0x4F5D 0x4F57 0x4F47 0x4F76 0x4F88 0x4F8F 0x4F98 0x4F7B 0x4F69 0x4F70 0x4F91 0x4F6F 0x4F86 0x4F96 0x5118 0x4FD4 0x4FDF 0x4FCE 0x4FD8 0x4FDB 0x4FD1 0x4FDA 0x4FD0 0x4FE4 0x4FE5 0x501A 0x5028 0x5014 0x502A 0x5025 0x5005 0x4F1C 0x4FF6 0x5021 0x5029 0x502C 0x4FFE 0x4FEF 0x5011 0x5006 0x5043 0x5047 0x6703 0x5055 0x5050 0x5048 0x505A 0x5056 0x506C 0x5078 0x5080 0x509A 0x5085 0x50B4 0x50B2 +0x50C9 0x50CA 0x50B3 0x50C2 0x50D6 0x50DE 0x50E5 0x50ED 0x50E3 0x50EE 0x50F9 0x50F5 0x5109 0x5101 0x5102 0x5116 0x5115 0x5114 0x511A 0x5121 0x513A 0x5137 0x513C 0x513B 0x513F 0x5140 0x5152 0x514C 0x5154 0x5162 0x7AF8 0x5169 0x516A 0x516E 0x5180 0x5182 0x56D8 0x518C 0x5189 0x518F 0x5191 0x5193 0x5195 0x5196 0x51A4 0x51A6 0x51A2 0x51A9 0x51AA 0x51AB 0x51B3 0x51B1 0x51B2 0x51B0 0x51B5 0x51BD 0x51C5 0x51C9 0x51DB 0x51E0 0x8655 0x51E9 0x51ED 0x51F0 0x51F5 0x51FE 0x5204 0x520B 0x5214 0x520E 0x5227 0x522A 0x522E 0x5233 0x5239 0x524F 0x5244 0x524B 0x524C 0x525E 0x5254 0x526A 0x5274 0x5269 0x5273 0x527F 0x527D 0x528D 0x5294 0x5292 0x5271 0x5288 0x5291 0x8FA8 +0x8FA7 0x52AC 0x52AD 0x52BC 0x52B5 0x52C1 0x52CD 0x52D7 0x52DE 0x52E3 0x52E6 0x98ED 0x52E0 0x52F3 0x52F5 0x52F8 0x52F9 0x5306 0x5308 0x7538 0x530D 0x5310 0x530F 0x5315 0x531A 0x5323 0x532F 0x5331 0x5333 0x5338 0x5340 0x5346 0x5345 0x4E17 0x5349 0x534D 0x51D6 0x535E 0x5369 0x536E 0x5918 0x537B 0x5377 0x5382 0x5396 0x53A0 0x53A6 0x53A5 0x53AE 0x53B0 0x53B6 0x53C3 0x7C12 0x96D9 0x53DF 0x66FC 0x71EE 0x53EE 0x53E8 0x53ED 0x53FA 0x5401 0x543D 0x5440 0x542C 0x542D 0x543C 0x542E 0x5436 0x5429 0x541D 0x544E 0x548F 0x5475 0x548E 0x545F 0x5471 0x5477 0x5470 0x5492 0x547B 0x5480 0x5476 0x5484 0x5490 0x5486 0x54C7 0x54A2 0x54B8 0x54A5 0x54AC 0x54C4 0x54C8 0x54A8 +0x54AB 0x54C2 0x54A4 0x54BE 0x54BC 0x54D8 0x54E5 0x54E6 0x550F 0x5514 0x54FD 0x54EE 0x54ED 0x54FA 0x54E2 0x5539 0x5540 0x5563 0x554C 0x552E 0x555C 0x5545 0x5556 0x5557 0x5538 0x5533 0x555D 0x5599 0x5580 0x54AF 0x558A 0x559F 0x557B 0x557E 0x5598 0x559E 0x55AE 0x557C 0x5583 0x55A9 0x5587 0x55A8 0x55DA 0x55C5 0x55DF 0x55C4 0x55DC 0x55E4 0x55D4 0x5614 0x55F7 0x5616 0x55FE 0x55FD 0x561B 0x55F9 0x564E 0x5650 0x71DF 0x5634 0x5636 0x5632 0x5638 0x566B 0x5664 0x562F 0x566C 0x566A 0x5686 0x5680 0x568A 0x56A0 0x5694 0x568F 0x56A5 0x56AE 0x56B6 0x56B4 0x56C2 0x56BC 0x56C1 0x56C3 0x56C0 0x56C8 0x56CE 0x56D1 0x56D3 0x56D7 0x56EE 0x56F9 0x5700 0x56FF 0x5704 0x5709 +0x5708 0x570B 0x570D 0x5713 0x5718 0x5716 0x55C7 0x571C 0x5726 0x5737 0x5738 0x574E 0x573B 0x5740 0x574F 0x5769 0x57C0 0x5788 0x5761 0x577F 0x5789 0x5793 0x57A0 0x57B3 0x57A4 0x57AA 0x57B0 0x57C3 0x57C6 0x57D4 0x57D2 0x57D3 0x580A 0x57D6 0x57E3 0x580B 0x5819 0x581D 0x5872 0x5821 0x5862 0x584B 0x5870 0x6BC0 0x5852 0x583D 0x5879 0x5885 0x58B9 0x589F 0x58AB 0x58BA 0x58DE 0x58BB 0x58B8 0x58AE 0x58C5 0x58D3 0x58D1 0x58D7 0x58D9 0x58D8 0x58E5 0x58DC 0x58E4 0x58DF 0x58EF 0x58FA 0x58F9 0x58FB 0x58FC 0x58FD 0x5902 0x590A 0x5910 0x591B 0x68A6 0x5925 0x592C 0x592D 0x5932 0x5938 0x593E 0x7AD2 0x5955 0x5950 0x594E 0x595A 0x5958 0x5962 0x5960 0x5967 0x596C 0x5969 +0x5978 0x5981 0x599D 0x4F5E 0x4FAB 0x59A3 0x59B2 0x59C6 0x59E8 0x59DC 0x598D 0x59D9 0x59DA 0x5A25 0x5A1F 0x5A11 0x5A1C 0x5A09 0x5A1A 0x5A40 0x5A6C 0x5A49 0x5A35 0x5A36 0x5A62 0x5A6A 0x5A9A 0x5ABC 0x5ABE 0x5ACB 0x5AC2 0x5ABD 0x5AE3 0x5AD7 0x5AE6 0x5AE9 0x5AD6 0x5AFA 0x5AFB 0x5B0C 0x5B0B 0x5B16 0x5B32 0x5AD0 0x5B2A 0x5B36 0x5B3E 0x5B43 0x5B45 0x5B40 0x5B51 0x5B55 0x5B5A 0x5B5B 0x5B65 0x5B69 0x5B70 0x5B73 0x5B75 0x5B78 0x6588 0x5B7A 0x5B80 0x5B83 0x5BA6 0x5BB8 0x5BC3 0x5BC7 0x5BC9 0x5BD4 0x5BD0 0x5BE4 0x5BE6 0x5BE2 0x5BDE 0x5BE5 0x5BEB 0x5BF0 0x5BF6 0x5BF3 0x5C05 0x5C07 0x5C08 0x5C0D 0x5C13 0x5C20 0x5C22 0x5C28 0x5C38 0x5C39 0x5C41 0x5C46 0x5C4E 0x5C53 +0x5C50 0x5C4F 0x5B71 0x5C6C 0x5C6E 0x4E62 0x5C76 0x5C79 0x5C8C 0x5C91 0x5C94 0x599B 0x5CAB 0x5CBB 0x5CB6 0x5CBC 0x5CB7 0x5CC5 0x5CBE 0x5CC7 0x5CD9 0x5CE9 0x5CFD 0x5CFA 0x5CED 0x5D8C 0x5CEA 0x5D0B 0x5D15 0x5D17 0x5D5C 0x5D1F 0x5D1B 0x5D11 0x5D14 0x5D22 0x5D1A 0x5D19 0x5D18 0x5D4C 0x5D52 0x5D4E 0x5D4B 0x5D6C 0x5D73 0x5D76 0x5D87 0x5D84 0x5D82 0x5DA2 0x5D9D 0x5DAC 0x5DAE 0x5DBD 0x5D90 0x5DB7 0x5DBC 0x5DC9 0x5DCD 0x5DD3 0x5DD2 0x5DD6 0x5DDB 0x5DEB 0x5DF2 0x5DF5 0x5E0B 0x5E1A 0x5E19 0x5E11 0x5E1B 0x5E36 0x5E37 0x5E44 0x5E43 0x5E40 0x5E4E 0x5E57 0x5E54 0x5E5F 0x5E62 0x5E64 0x5E47 0x5E75 0x5E76 0x5E7A 0x9EBC 0x5E7F 0x5EA0 0x5EC1 0x5EC2 0x5EC8 0x5ED0 0x5ECF +0x5ED6 0x5EE3 0x5EDD 0x5EDA 0x5EDB 0x5EE2 0x5EE1 0x5EE8 0x5EE9 0x5EEC 0x5EF1 0x5EF3 0x5EF0 0x5EF4 0x5EF8 0x5EFE 0x5F03 0x5F09 0x5F5D 0x5F5C 0x5F0B 0x5F11 0x5F16 0x5F29 0x5F2D 0x5F38 0x5F41 0x5F48 0x5F4C 0x5F4E 0x5F2F 0x5F51 0x5F56 0x5F57 0x5F59 0x5F61 0x5F6D 0x5F73 0x5F77 0x5F83 0x5F82 0x5F7F 0x5F8A 0x5F88 0x5F91 0x5F87 0x5F9E 0x5F99 0x5F98 0x5FA0 0x5FA8 0x5FAD 0x5FBC 0x5FD6 0x5FFB 0x5FE4 0x5FF8 0x5FF1 0x5FDD 0x60B3 0x5FFF 0x6021 0x6060 0x6019 0x6010 0x6029 0x600E 0x6031 0x601B 0x6015 0x602B 0x6026 0x600F 0x603A 0x605A 0x6041 0x606A 0x6077 0x605F 0x604A 0x6046 0x604D 0x6063 0x6043 0x6064 0x6042 0x606C 0x606B 0x6059 0x6081 0x608D 0x60E7 0x6083 0x609A +0x6084 0x609B 0x6096 0x6097 0x6092 0x60A7 0x608B 0x60E1 0x60B8 0x60E0 0x60D3 0x60B4 0x5FF0 0x60BD 0x60C6 0x60B5 0x60D8 0x614D 0x6115 0x6106 0x60F6 0x60F7 0x6100 0x60F4 0x60FA 0x6103 0x6121 0x60FB 0x60F1 0x610D 0x610E 0x6147 0x613E 0x6128 0x6127 0x614A 0x613F 0x613C 0x612C 0x6134 0x613D 0x6142 0x6144 0x6173 0x6177 0x6158 0x6159 0x615A 0x616B 0x6174 0x616F 0x6165 0x6171 0x615F 0x615D 0x6153 0x6175 0x6199 0x6196 0x6187 0x61AC 0x6194 0x619A 0x618A 0x6191 0x61AB 0x61AE 0x61CC 0x61CA 0x61C9 0x61F7 0x61C8 0x61C3 0x61C6 0x61BA 0x61CB 0x7F79 0x61CD 0x61E6 0x61E3 0x61F6 0x61FA 0x61F4 0x61FF 0x61FD 0x61FC 0x61FE 0x6200 0x6208 0x6209 0x620D 0x620C 0x6214 0x621B +0x621E 0x6221 0x622A 0x622E 0x6230 0x6232 0x6233 0x6241 0x624E 0x625E 0x6263 0x625B 0x6260 0x6268 0x627C 0x6282 0x6289 0x627E 0x6292 0x6293 0x6296 0x62D4 0x6283 0x6294 0x62D7 0x62D1 0x62BB 0x62CF 0x62FF 0x62C6 0x64D4 0x62C8 0x62DC 0x62CC 0x62CA 0x62C2 0x62C7 0x629B 0x62C9 0x630C 0x62EE 0x62F1 0x6327 0x6302 0x6308 0x62EF 0x62F5 0x6350 0x633E 0x634D 0x641C 0x634F 0x6396 0x638E 0x6380 0x63AB 0x6376 0x63A3 0x638F 0x6389 0x639F 0x63B5 0x636B 0x6369 0x63BE 0x63E9 0x63C0 0x63C6 0x63E3 0x63C9 0x63D2 0x63F6 0x63C4 0x6416 0x6434 0x6406 0x6413 0x6426 0x6436 0x651D 0x6417 0x6428 0x640F 0x6467 0x646F 0x6476 0x644E 0x652A 0x6495 0x6493 0x64A5 0x64A9 0x6488 0x64BC +0x64DA 0x64D2 0x64C5 0x64C7 0x64BB 0x64D8 0x64C2 0x64F1 0x64E7 0x8209 0x64E0 0x64E1 0x62AC 0x64E3 0x64EF 0x652C 0x64F6 0x64F4 0x64F2 0x64FA 0x6500 0x64FD 0x6518 0x651C 0x6505 0x6524 0x6523 0x652B 0x6534 0x6535 0x6537 0x6536 0x6538 0x754B 0x6548 0x6556 0x6555 0x654D 0x6558 0x655E 0x655D 0x6572 0x6578 0x6582 0x6583 0x8B8A 0x659B 0x659F 0x65AB 0x65B7 0x65C3 0x65C6 0x65C1 0x65C4 0x65CC 0x65D2 0x65DB 0x65D9 0x65E0 0x65E1 0x65F1 0x6772 0x660A 0x6603 0x65FB 0x6773 0x6635 0x6636 0x6634 0x661C 0x664F 0x6644 0x6649 0x6641 0x665E 0x665D 0x6664 0x6667 0x6668 0x665F 0x6662 0x6670 0x6683 0x6688 0x668E 0x6689 0x6684 0x6698 0x669D 0x66C1 0x66B9 0x66C9 0x66BE 0x66BC +0x66C4 0x66B8 0x66D6 0x66DA 0x66E0 0x663F 0x66E6 0x66E9 0x66F0 0x66F5 0x66F7 0x670F 0x6716 0x671E 0x6726 0x6727 0x9738 0x672E 0x673F 0x6736 0x6741 0x6738 0x6737 0x6746 0x675E 0x6760 0x6759 0x6763 0x6764 0x6789 0x6770 0x67A9 0x677C 0x676A 0x678C 0x678B 0x67A6 0x67A1 0x6785 0x67B7 0x67EF 0x67B4 0x67EC 0x67B3 0x67E9 0x67B8 0x67E4 0x67DE 0x67DD 0x67E2 0x67EE 0x67B9 0x67CE 0x67C6 0x67E7 0x6A9C 0x681E 0x6846 0x6829 0x6840 0x684D 0x6832 0x684E 0x68B3 0x682B 0x6859 0x6863 0x6877 0x687F 0x689F 0x688F 0x68AD 0x6894 0x689D 0x689B 0x6883 0x6AAE 0x68B9 0x6874 0x68B5 0x68A0 0x68BA 0x690F 0x688D 0x687E 0x6901 0x68CA 0x6908 0x68D8 0x6922 0x6926 0x68E1 0x690C 0x68CD +0x68D4 0x68E7 0x68D5 0x6936 0x6912 0x6904 0x68D7 0x68E3 0x6925 0x68F9 0x68E0 0x68EF 0x6928 0x692A 0x691A 0x6923 0x6921 0x68C6 0x6979 0x6977 0x695C 0x6978 0x696B 0x6954 0x697E 0x696E 0x6939 0x6974 0x693D 0x6959 0x6930 0x6961 0x695E 0x695D 0x6981 0x696A 0x69B2 0x69AE 0x69D0 0x69BF 0x69C1 0x69D3 0x69BE 0x69CE 0x5BE8 0x69CA 0x69DD 0x69BB 0x69C3 0x69A7 0x6A2E 0x6991 0x69A0 0x699C 0x6995 0x69B4 0x69DE 0x69E8 0x6A02 0x6A1B 0x69FF 0x6B0A 0x69F9 0x69F2 0x69E7 0x6A05 0x69B1 0x6A1E 0x69ED 0x6A14 0x69EB 0x6A0A 0x6A12 0x6AC1 0x6A23 0x6A13 0x6A44 0x6A0C 0x6A72 0x6A36 0x6A78 0x6A47 0x6A62 0x6A59 0x6A66 0x6A48 0x6A38 0x6A22 0x6A90 0x6A8D 0x6AA0 0x6A84 0x6AA2 0x6AA3 +0x6A97 0x8617 0x6ABB 0x6AC3 0x6AC2 0x6AB8 0x6AB3 0x6AAC 0x6ADE 0x6AD1 0x6ADF 0x6AAA 0x6ADA 0x6AEA 0x6AFB 0x6B05 0x8616 0x6AFA 0x6B12 0x6B16 0x9B31 0x6B1F 0x6B38 0x6B37 0x76DC 0x6B39 0x98EE 0x6B47 0x6B43 0x6B49 0x6B50 0x6B59 0x6B54 0x6B5B 0x6B5F 0x6B61 0x6B78 0x6B79 0x6B7F 0x6B80 0x6B84 0x6B83 0x6B8D 0x6B98 0x6B95 0x6B9E 0x6BA4 0x6BAA 0x6BAB 0x6BAF 0x6BB2 0x6BB1 0x6BB3 0x6BB7 0x6BBC 0x6BC6 0x6BCB 0x6BD3 0x6BDF 0x6BEC 0x6BEB 0x6BF3 0x6BEF 0x9EBE 0x6C08 0x6C13 0x6C14 0x6C1B 0x6C24 0x6C23 0x6C5E 0x6C55 0x6C62 0x6C6A 0x6C82 0x6C8D 0x6C9A 0x6C81 0x6C9B 0x6C7E 0x6C68 0x6C73 0x6C92 0x6C90 0x6CC4 0x6CF1 0x6CD3 0x6CBD 0x6CD7 0x6CC5 0x6CDD 0x6CAE 0x6CB1 0x6CBE +0x6CBA 0x6CDB 0x6CEF 0x6CD9 0x6CEA 0x6D1F 0x884D 0x6D36 0x6D2B 0x6D3D 0x6D38 0x6D19 0x6D35 0x6D33 0x6D12 0x6D0C 0x6D63 0x6D93 0x6D64 0x6D5A 0x6D79 0x6D59 0x6D8E 0x6D95 0x6FE4 0x6D85 0x6DF9 0x6E15 0x6E0A 0x6DB5 0x6DC7 0x6DE6 0x6DB8 0x6DC6 0x6DEC 0x6DDE 0x6DCC 0x6DE8 0x6DD2 0x6DC5 0x6DFA 0x6DD9 0x6DE4 0x6DD5 0x6DEA 0x6DEE 0x6E2D 0x6E6E 0x6E2E 0x6E19 0x6E72 0x6E5F 0x6E3E 0x6E23 0x6E6B 0x6E2B 0x6E76 0x6E4D 0x6E1F 0x6E43 0x6E3A 0x6E4E 0x6E24 0x6EFF 0x6E1D 0x6E38 0x6E82 0x6EAA 0x6E98 0x6EC9 0x6EB7 0x6ED3 0x6EBD 0x6EAF 0x6EC4 0x6EB2 0x6ED4 0x6ED5 0x6E8F 0x6EA5 0x6EC2 0x6E9F 0x6F41 0x6F11 0x704C 0x6EEC 0x6EF8 0x6EFE 0x6F3F 0x6EF2 0x6F31 0x6EEF 0x6F32 0x6ECC +0x6F3E 0x6F13 0x6EF7 0x6F86 0x6F7A 0x6F78 0x6F81 0x6F80 0x6F6F 0x6F5B 0x6FF3 0x6F6D 0x6F82 0x6F7C 0x6F58 0x6F8E 0x6F91 0x6FC2 0x6F66 0x6FB3 0x6FA3 0x6FA1 0x6FA4 0x6FB9 0x6FC6 0x6FAA 0x6FDF 0x6FD5 0x6FEC 0x6FD4 0x6FD8 0x6FF1 0x6FEE 0x6FDB 0x7009 0x700B 0x6FFA 0x7011 0x7001 0x700F 0x6FFE 0x701B 0x701A 0x6F74 0x701D 0x7018 0x701F 0x7030 0x703E 0x7032 0x7051 0x7063 0x7099 0x7092 0x70AF 0x70F1 0x70AC 0x70B8 0x70B3 0x70AE 0x70DF 0x70CB 0x70DD 0x70D9 0x7109 0x70FD 0x711C 0x7119 0x7165 0x7155 0x7188 0x7166 0x7162 0x714C 0x7156 0x716C 0x718F 0x71FB 0x7184 0x7195 0x71A8 0x71AC 0x71D7 0x71B9 0x71BE 0x71D2 0x71C9 0x71D4 0x71CE 0x71E0 0x71EC 0x71E7 0x71F5 0x71FC +0x71F9 0x71FF 0x720D 0x7210 0x721B 0x7228 0x722D 0x722C 0x7230 0x7232 0x723B 0x723C 0x723F 0x7240 0x7246 0x724B 0x7258 0x7274 0x727E 0x7282 0x7281 0x7287 0x7292 0x7296 0x72A2 0x72A7 0x72B9 0x72B2 0x72C3 0x72C6 0x72C4 0x72CE 0x72D2 0x72E2 0x72E0 0x72E1 0x72F9 0x72F7 0x500F 0x7317 0x730A 0x731C 0x7316 0x731D 0x7334 0x732F 0x7329 0x7325 0x733E 0x734E 0x734F 0x9ED8 0x7357 0x736A 0x7368 0x7370 0x7378 0x7375 0x737B 0x737A 0x73C8 0x73B3 0x73CE 0x73BB 0x73C0 0x73E5 0x73EE 0x73DE 0x74A2 0x7405 0x746F 0x7425 0x73F8 0x7432 0x743A 0x7455 0x743F 0x745F 0x7459 0x7441 0x745C 0x7469 0x7470 0x7463 0x746A 0x7476 0x747E 0x748B 0x749E 0x74A7 0x74CA 0x74CF 0x74D4 0x73F1 +0x74E0 0x74E3 0x74E7 0x74E9 0x74EE 0x74F2 0x74F0 0x74F1 0x74F8 0x74F7 0x7504 0x7503 0x7505 0x750C 0x750E 0x750D 0x7515 0x7513 0x751E 0x7526 0x752C 0x753C 0x7544 0x754D 0x754A 0x7549 0x755B 0x7546 0x755A 0x7569 0x7564 0x7567 0x756B 0x756D 0x7578 0x7576 0x7586 0x7587 0x7574 0x758A 0x7589 0x7582 0x7594 0x759A 0x759D 0x75A5 0x75A3 0x75C2 0x75B3 0x75C3 0x75B5 0x75BD 0x75B8 0x75BC 0x75B1 0x75CD 0x75CA 0x75D2 0x75D9 0x75E3 0x75DE 0x75FE 0x75FF 0x75FC 0x7601 0x75F0 0x75FA 0x75F2 0x75F3 0x760B 0x760D 0x7609 0x761F 0x7627 0x7620 0x7621 0x7622 0x7624 0x7634 0x7630 0x763B 0x7647 0x7648 0x7646 0x765C 0x7658 0x7661 0x7662 0x7668 0x7669 0x766A 0x7667 0x766C 0x7670 +0x7672 0x7676 0x7678 0x767C 0x7680 0x7683 0x7688 0x768B 0x768E 0x7696 0x7693 0x7699 0x769A 0x76B0 0x76B4 0x76B8 0x76B9 0x76BA 0x76C2 0x76CD 0x76D6 0x76D2 0x76DE 0x76E1 0x76E5 0x76E7 0x76EA 0x862F 0x76FB 0x7708 0x7707 0x7704 0x7729 0x7724 0x771E 0x7725 0x7726 0x771B 0x7737 0x7738 0x7747 0x775A 0x7768 0x776B 0x775B 0x7765 0x777F 0x777E 0x7779 0x778E 0x778B 0x7791 0x77A0 0x779E 0x77B0 0x77B6 0x77B9 0x77BF 0x77BC 0x77BD 0x77BB 0x77C7 0x77CD 0x77D7 0x77DA 0x77DC 0x77E3 0x77EE 0x77FC 0x780C 0x7812 0x7926 0x7820 0x792A 0x7845 0x788E 0x7874 0x7886 0x787C 0x789A 0x788C 0x78A3 0x78B5 0x78AA 0x78AF 0x78D1 0x78C6 0x78CB 0x78D4 0x78BE 0x78BC 0x78C5 0x78CA 0x78EC +0x78E7 0x78DA 0x78FD 0x78F4 0x7907 0x7912 0x7911 0x7919 0x792C 0x792B 0x7940 0x7960 0x7957 0x795F 0x795A 0x7955 0x7953 0x797A 0x797F 0x798A 0x799D 0x79A7 0x9F4B 0x79AA 0x79AE 0x79B3 0x79B9 0x79BA 0x79C9 0x79D5 0x79E7 0x79EC 0x79E1 0x79E3 0x7A08 0x7A0D 0x7A18 0x7A19 0x7A20 0x7A1F 0x7980 0x7A31 0x7A3B 0x7A3E 0x7A37 0x7A43 0x7A57 0x7A49 0x7A61 0x7A62 0x7A69 0x9F9D 0x7A70 0x7A79 0x7A7D 0x7A88 0x7A97 0x7A95 0x7A98 0x7A96 0x7AA9 0x7AC8 0x7AB0 0x7AB6 0x7AC5 0x7AC4 0x7ABF 0x9083 0x7AC7 0x7ACA 0x7ACD 0x7ACF 0x7AD5 0x7AD3 0x7AD9 0x7ADA 0x7ADD 0x7AE1 0x7AE2 0x7AE6 0x7AED 0x7AF0 0x7B02 0x7B0F 0x7B0A 0x7B06 0x7B33 0x7B18 0x7B19 0x7B1E 0x7B35 0x7B28 0x7B36 0x7B50 +0x7B7A 0x7B04 0x7B4D 0x7B0B 0x7B4C 0x7B45 0x7B75 0x7B65 0x7B74 0x7B67 0x7B70 0x7B71 0x7B6C 0x7B6E 0x7B9D 0x7B98 0x7B9F 0x7B8D 0x7B9C 0x7B9A 0x7B8B 0x7B92 0x7B8F 0x7B5D 0x7B99 0x7BCB 0x7BC1 0x7BCC 0x7BCF 0x7BB4 0x7BC6 0x7BDD 0x7BE9 0x7C11 0x7C14 0x7BE6 0x7BE5 0x7C60 0x7C00 0x7C07 0x7C13 0x7BF3 0x7BF7 0x7C17 0x7C0D 0x7BF6 0x7C23 0x7C27 0x7C2A 0x7C1F 0x7C37 0x7C2B 0x7C3D 0x7C4C 0x7C43 0x7C54 0x7C4F 0x7C40 0x7C50 0x7C58 0x7C5F 0x7C64 0x7C56 0x7C65 0x7C6C 0x7C75 0x7C83 0x7C90 0x7CA4 0x7CAD 0x7CA2 0x7CAB 0x7CA1 0x7CA8 0x7CB3 0x7CB2 0x7CB1 0x7CAE 0x7CB9 0x7CBD 0x7CC0 0x7CC5 0x7CC2 0x7CD8 0x7CD2 0x7CDC 0x7CE2 0x9B3B 0x7CEF 0x7CF2 0x7CF4 0x7CF6 0x7CFA 0x7D06 +0x7D02 0x7D1C 0x7D15 0x7D0A 0x7D45 0x7D4B 0x7D2E 0x7D32 0x7D3F 0x7D35 0x7D46 0x7D73 0x7D56 0x7D4E 0x7D72 0x7D68 0x7D6E 0x7D4F 0x7D63 0x7D93 0x7D89 0x7D5B 0x7D8F 0x7D7D 0x7D9B 0x7DBA 0x7DAE 0x7DA3 0x7DB5 0x7DC7 0x7DBD 0x7DAB 0x7E3D 0x7DA2 0x7DAF 0x7DDC 0x7DB8 0x7D9F 0x7DB0 0x7DD8 0x7DDD 0x7DE4 0x7DDE 0x7DFB 0x7DF2 0x7DE1 0x7E05 0x7E0A 0x7E23 0x7E21 0x7E12 0x7E31 0x7E1F 0x7E09 0x7E0B 0x7E22 0x7E46 0x7E66 0x7E3B 0x7E35 0x7E39 0x7E43 0x7E37 0x7E32 0x7E3A 0x7E67 0x7E5D 0x7E56 0x7E5E 0x7E59 0x7E5A 0x7E79 0x7E6A 0x7E69 0x7E7C 0x7E7B 0x7E83 0x7DD5 0x7E7D 0x8FAE 0x7E7F 0x7E88 0x7E89 0x7E8C 0x7E92 0x7E90 0x7E93 0x7E94 0x7E96 0x7E8E 0x7E9B 0x7E9C 0x7F38 0x7F3A +0x7F45 0x7F4C 0x7F4D 0x7F4E 0x7F50 0x7F51 0x7F55 0x7F54 0x7F58 0x7F5F 0x7F60 0x7F68 0x7F69 0x7F67 0x7F78 0x7F82 0x7F86 0x7F83 0x7F88 0x7F87 0x7F8C 0x7F94 0x7F9E 0x7F9D 0x7F9A 0x7FA3 0x7FAF 0x7FB2 0x7FB9 0x7FAE 0x7FB6 0x7FB8 0x8B71 0x7FC5 0x7FC6 0x7FCA 0x7FD5 0x7FD4 0x7FE1 0x7FE6 0x7FE9 0x7FF3 0x7FF9 0x98DC 0x8006 0x8004 0x800B 0x8012 0x8018 0x8019 0x801C 0x8021 0x8028 0x803F 0x803B 0x804A 0x8046 0x8052 0x8058 0x805A 0x805F 0x8062 0x8068 0x8073 0x8072 0x8070 0x8076 0x8079 0x807D 0x807F 0x8084 0x8086 0x8085 0x809B 0x8093 0x809A 0x80AD 0x5190 0x80AC 0x80DB 0x80E5 0x80D9 0x80DD 0x80C4 0x80DA 0x80D6 0x8109 0x80EF 0x80F1 0x811B 0x8129 0x8123 0x812F 0x814B +0x968B 0x8146 0x813E 0x8153 0x8151 0x80FC 0x8171 0x816E 0x8165 0x8166 0x8174 0x8183 0x8188 0x818A 0x8180 0x8182 0x81A0 0x8195 0x81A4 0x81A3 0x815F 0x8193 0x81A9 0x81B0 0x81B5 0x81BE 0x81B8 0x81BD 0x81C0 0x81C2 0x81BA 0x81C9 0x81CD 0x81D1 0x81D9 0x81D8 0x81C8 0x81DA 0x81DF 0x81E0 0x81E7 0x81FA 0x81FB 0x81FE 0x8201 0x8202 0x8205 0x8207 0x820A 0x820D 0x8210 0x8216 0x8229 0x822B 0x8238 0x8233 0x8240 0x8259 0x8258 0x825D 0x825A 0x825F 0x8264 0x8262 0x8268 0x826A 0x826B 0x822E 0x8271 0x8277 0x8278 0x827E 0x828D 0x8292 0x82AB 0x829F 0x82BB 0x82AC 0x82E1 0x82E3 0x82DF 0x82D2 0x82F4 0x82F3 0x82FA 0x8393 0x8303 0x82FB 0x82F9 0x82DE 0x8306 0x82DC 0x8309 0x82D9 +0x8335 0x8334 0x8316 0x8332 0x8331 0x8340 0x8339 0x8350 0x8345 0x832F 0x832B 0x8317 0x8318 0x8385 0x839A 0x83AA 0x839F 0x83A2 0x8396 0x8323 0x838E 0x8387 0x838A 0x837C 0x83B5 0x8373 0x8375 0x83A0 0x8389 0x83A8 0x83F4 0x8413 0x83EB 0x83CE 0x83FD 0x8403 0x83D8 0x840B 0x83C1 0x83F7 0x8407 0x83E0 0x83F2 0x840D 0x8422 0x8420 0x83BD 0x8438 0x8506 0x83FB 0x846D 0x842A 0x843C 0x855A 0x8484 0x8477 0x846B 0x84AD 0x846E 0x8482 0x8469 0x8446 0x842C 0x846F 0x8479 0x8435 0x84CA 0x8462 0x84B9 0x84BF 0x849F 0x84D9 0x84CD 0x84BB 0x84DA 0x84D0 0x84C1 0x84C6 0x84D6 0x84A1 0x8521 0x84FF 0x84F4 0x8517 0x8518 0x852C 0x851F 0x8515 0x8514 0x84FC 0x8540 0x8563 0x8558 0x8548 +0x8541 0x8602 0x854B 0x8555 0x8580 0x85A4 0x8588 0x8591 0x858A 0x85A8 0x856D 0x8594 0x859B 0x85EA 0x8587 0x859C 0x8577 0x857E 0x8590 0x85C9 0x85BA 0x85CF 0x85B9 0x85D0 0x85D5 0x85DD 0x85E5 0x85DC 0x85F9 0x860A 0x8613 0x860B 0x85FE 0x85FA 0x8606 0x8622 0x861A 0x8630 0x863F 0x864D 0x4E55 0x8654 0x865F 0x8667 0x8671 0x8693 0x86A3 0x86A9 0x86AA 0x868B 0x868C 0x86B6 0x86AF 0x86C4 0x86C6 0x86B0 0x86C9 0x8823 0x86AB 0x86D4 0x86DE 0x86E9 0x86EC 0x86DF 0x86DB 0x86EF 0x8712 0x8706 0x8708 0x8700 0x8703 0x86FB 0x8711 0x8709 0x870D 0x86F9 0x870A 0x8734 0x873F 0x8737 0x873B 0x8725 0x8729 0x871A 0x8760 0x875F 0x8778 0x874C 0x874E 0x8774 0x8757 0x8768 0x876E 0x8759 +0x8753 0x8763 0x876A 0x8805 0x87A2 0x879F 0x8782 0x87AF 0x87CB 0x87BD 0x87C0 0x87D0 0x96D6 0x87AB 0x87C4 0x87B3 0x87C7 0x87C6 0x87BB 0x87EF 0x87F2 0x87E0 0x880F 0x880D 0x87FE 0x87F6 0x87F7 0x880E 0x87D2 0x8811 0x8816 0x8815 0x8822 0x8821 0x8831 0x8836 0x8839 0x8827 0x883B 0x8844 0x8842 0x8852 0x8859 0x885E 0x8862 0x886B 0x8881 0x887E 0x889E 0x8875 0x887D 0x88B5 0x8872 0x8882 0x8897 0x8892 0x88AE 0x8899 0x88A2 0x888D 0x88A4 0x88B0 0x88BF 0x88B1 0x88C3 0x88C4 0x88D4 0x88D8 0x88D9 0x88DD 0x88F9 0x8902 0x88FC 0x88F4 0x88E8 0x88F2 0x8904 0x890C 0x890A 0x8913 0x8943 0x891E 0x8925 0x892A 0x892B 0x8941 0x8944 0x893B 0x8936 0x8938 0x894C 0x891D 0x8960 0x895E +0x8966 0x8964 0x896D 0x896A 0x896F 0x8974 0x8977 0x897E 0x8983 0x8988 0x898A 0x8993 0x8998 0x89A1 0x89A9 0x89A6 0x89AC 0x89AF 0x89B2 0x89BA 0x89BD 0x89BF 0x89C0 0x89DA 0x89DC 0x89DD 0x89E7 0x89F4 0x89F8 0x8A03 0x8A16 0x8A10 0x8A0C 0x8A1B 0x8A1D 0x8A25 0x8A36 0x8A41 0x8A5B 0x8A52 0x8A46 0x8A48 0x8A7C 0x8A6D 0x8A6C 0x8A62 0x8A85 0x8A82 0x8A84 0x8AA8 0x8AA1 0x8A91 0x8AA5 0x8AA6 0x8A9A 0x8AA3 0x8AC4 0x8ACD 0x8AC2 0x8ADA 0x8AEB 0x8AF3 0x8AE7 0x8AE4 0x8AF1 0x8B14 0x8AE0 0x8AE2 0x8AF7 0x8ADE 0x8ADB 0x8B0C 0x8B07 0x8B1A 0x8AE1 0x8B16 0x8B10 0x8B17 0x8B20 0x8B33 0x97AB 0x8B26 0x8B2B 0x8B3E 0x8B28 0x8B41 0x8B4C 0x8B4F 0x8B4E 0x8B49 0x8B56 0x8B5B 0x8B5A 0x8B6B +0x8B5F 0x8B6C 0x8B6F 0x8B74 0x8B7D 0x8B80 0x8B8C 0x8B8E 0x8B92 0x8B93 0x8B96 0x8B99 0x8B9A 0x8C3A 0x8C41 0x8C3F 0x8C48 0x8C4C 0x8C4E 0x8C50 0x8C55 0x8C62 0x8C6C 0x8C78 0x8C7A 0x8C82 0x8C89 0x8C85 0x8C8A 0x8C8D 0x8C8E 0x8C94 0x8C7C 0x8C98 0x621D 0x8CAD 0x8CAA 0x8CBD 0x8CB2 0x8CB3 0x8CAE 0x8CB6 0x8CC8 0x8CC1 0x8CE4 0x8CE3 0x8CDA 0x8CFD 0x8CFA 0x8CFB 0x8D04 0x8D05 0x8D0A 0x8D07 0x8D0F 0x8D0D 0x8D10 0x9F4E 0x8D13 0x8CCD 0x8D14 0x8D16 0x8D67 0x8D6D 0x8D71 0x8D73 0x8D81 0x8D99 0x8DC2 0x8DBE 0x8DBA 0x8DCF 0x8DDA 0x8DD6 0x8DCC 0x8DDB 0x8DCB 0x8DEA 0x8DEB 0x8DDF 0x8DE3 0x8DFC 0x8E08 0x8E09 0x8DFF 0x8E1D 0x8E1E 0x8E10 0x8E1F 0x8E42 0x8E35 0x8E30 0x8E34 0x8E4A +0x8E47 0x8E49 0x8E4C 0x8E50 0x8E48 0x8E59 0x8E64 0x8E60 0x8E2A 0x8E63 0x8E55 0x8E76 0x8E72 0x8E7C 0x8E81 0x8E87 0x8E85 0x8E84 0x8E8B 0x8E8A 0x8E93 0x8E91 0x8E94 0x8E99 0x8EAA 0x8EA1 0x8EAC 0x8EB0 0x8EC6 0x8EB1 0x8EBE 0x8EC5 0x8EC8 0x8ECB 0x8EDB 0x8EE3 0x8EFC 0x8EFB 0x8EEB 0x8EFE 0x8F0A 0x8F05 0x8F15 0x8F12 0x8F19 0x8F13 0x8F1C 0x8F1F 0x8F1B 0x8F0C 0x8F26 0x8F33 0x8F3B 0x8F39 0x8F45 0x8F42 0x8F3E 0x8F4C 0x8F49 0x8F46 0x8F4E 0x8F57 0x8F5C 0x8F62 0x8F63 0x8F64 0x8F9C 0x8F9F 0x8FA3 0x8FAD 0x8FAF 0x8FB7 0x8FDA 0x8FE5 0x8FE2 0x8FEA 0x8FEF 0x9087 0x8FF4 0x9005 0x8FF9 0x8FFA 0x9011 0x9015 0x9021 0x900D 0x901E 0x9016 0x900B 0x9027 0x9036 0x9035 0x9039 0x8FF8 +0x904F 0x9050 0x9051 0x9052 0x900E 0x9049 0x903E 0x9056 0x9058 0x905E 0x9068 0x906F 0x9076 0x96A8 0x9072 0x9082 0x907D 0x9081 0x9080 0x908A 0x9089 0x908F 0x90A8 0x90AF 0x90B1 0x90B5 0x90E2 0x90E4 0x6248 0x90DB 0x9102 0x9112 0x9119 0x9132 0x9130 0x914A 0x9156 0x9158 0x9163 0x9165 0x9169 0x9173 0x9172 0x918B 0x9189 0x9182 0x91A2 0x91AB 0x91AF 0x91AA 0x91B5 0x91B4 0x91BA 0x91C0 0x91C1 0x91C9 0x91CB 0x91D0 0x91D6 0x91DF 0x91E1 0x91DB 0x91FC 0x91F5 0x91F6 0x921E 0x91FF 0x9214 0x922C 0x9215 0x9211 0x925E 0x9257 0x9245 0x9249 0x9264 0x9248 0x9295 0x923F 0x924B 0x9250 0x929C 0x9296 0x9293 0x929B 0x925A 0x92CF 0x92B9 0x92B7 0x92E9 0x930F 0x92FA 0x9344 0x932E +0x9319 0x9322 0x931A 0x9323 0x933A 0x9335 0x933B 0x935C 0x9360 0x937C 0x936E 0x9356 0x93B0 0x93AC 0x93AD 0x9394 0x93B9 0x93D6 0x93D7 0x93E8 0x93E5 0x93D8 0x93C3 0x93DD 0x93D0 0x93C8 0x93E4 0x941A 0x9414 0x9413 0x9403 0x9407 0x9410 0x9436 0x942B 0x9435 0x9421 0x943A 0x9441 0x9452 0x9444 0x945B 0x9460 0x9462 0x945E 0x946A 0x9229 0x9470 0x9475 0x9477 0x947D 0x945A 0x947C 0x947E 0x9481 0x947F 0x9582 0x9587 0x958A 0x9594 0x9596 0x9598 0x9599 0x95A0 0x95A8 0x95A7 0x95AD 0x95BC 0x95BB 0x95B9 0x95BE 0x95CA 0x6FF6 0x95C3 0x95CD 0x95CC 0x95D5 0x95D4 0x95D6 0x95DC 0x95E1 0x95E5 0x95E2 0x9621 0x9628 0x962E 0x962F 0x9642 0x964C 0x964F 0x964B 0x9677 0x965C 0x965E +0x965D 0x965F 0x9666 0x9672 0x966C 0x968D 0x9698 0x9695 0x9697 0x96AA 0x96A7 0x96B1 0x96B2 0x96B0 0x96B4 0x96B6 0x96B8 0x96B9 0x96CE 0x96CB 0x96C9 0x96CD 0x894D 0x96DC 0x970D 0x96D5 0x96F9 0x9704 0x9706 0x9708 0x9713 0x970E 0x9711 0x970F 0x9716 0x9719 0x9724 0x972A 0x9730 0x9739 0x973D 0x973E 0x9744 0x9746 0x9748 0x9742 0x9749 0x975C 0x9760 0x9764 0x9766 0x9768 0x52D2 0x976B 0x9771 0x9779 0x9785 0x977C 0x9781 0x977A 0x9786 0x978B 0x978F 0x9790 0x979C 0x97A8 0x97A6 0x97A3 0x97B3 0x97B4 0x97C3 0x97C6 0x97C8 0x97CB 0x97DC 0x97ED 0x9F4F 0x97F2 0x7ADF 0x97F6 0x97F5 0x980F 0x980C 0x9838 0x9824 0x9821 0x9837 0x983D 0x9846 0x984F 0x984B 0x986B 0x986F 0x9870 +0x9871 0x9874 0x9873 0x98AA 0x98AF 0x98B1 0x98B6 0x98C4 0x98C3 0x98C6 0x98E9 0x98EB 0x9903 0x9909 0x9912 0x9914 0x9918 0x9921 0x991D 0x991E 0x9924 0x9920 0x992C 0x992E 0x993D 0x993E 0x9942 0x9949 0x9945 0x9950 0x994B 0x9951 0x9952 0x994C 0x9955 0x9997 0x9998 0x99A5 0x99AD 0x99AE 0x99BC 0x99DF 0x99DB 0x99DD 0x99D8 0x99D1 0x99ED 0x99EE 0x99F1 0x99F2 0x99FB 0x99F8 0x9A01 0x9A0F 0x9A05 0x99E2 0x9A19 0x9A2B 0x9A37 0x9A45 0x9A42 0x9A40 0x9A43 0x9A3E 0x9A55 0x9A4D 0x9A5B 0x9A57 0x9A5F 0x9A62 0x9A65 0x9A64 0x9A69 0x9A6B 0x9A6A 0x9AAD 0x9AB0 0x9ABC 0x9AC0 0x9ACF 0x9AD1 0x9AD3 0x9AD4 0x9ADE 0x9ADF 0x9AE2 0x9AE3 0x9AE6 0x9AEF 0x9AEB 0x9AEE 0x9AF4 0x9AF1 0x9AF7 +0x9AFB 0x9B06 0x9B18 0x9B1A 0x9B1F 0x9B22 0x9B23 0x9B25 0x9B27 0x9B28 0x9B29 0x9B2A 0x9B2E 0x9B2F 0x9B32 0x9B44 0x9B43 0x9B4F 0x9B4D 0x9B4E 0x9B51 0x9B58 0x9B74 0x9B93 0x9B83 0x9B91 0x9B96 0x9B97 0x9B9F 0x9BA0 0x9BA8 0x9BB4 0x9BC0 0x9BCA 0x9BB9 0x9BC6 0x9BCF 0x9BD1 0x9BD2 0x9BE3 0x9BE2 0x9BE4 0x9BD4 0x9BE1 0x9C3A 0x9BF2 0x9BF1 0x9BF0 0x9C15 0x9C14 0x9C09 0x9C13 0x9C0C 0x9C06 0x9C08 0x9C12 0x9C0A 0x9C04 0x9C2E 0x9C1B 0x9C25 0x9C24 0x9C21 0x9C30 0x9C47 0x9C32 0x9C46 0x9C3E 0x9C5A 0x9C60 0x9C67 0x9C76 0x9C78 0x9CE7 0x9CEC 0x9CF0 0x9D09 0x9D08 0x9CEB 0x9D03 0x9D06 0x9D2A 0x9D26 0x9DAF 0x9D23 0x9D1F 0x9D44 0x9D15 0x9D12 0x9D41 0x9D3F 0x9D3E 0x9D46 0x9D48 +0x9D5D 0x9D5E 0x9D64 0x9D51 0x9D50 0x9D59 0x9D72 0x9D89 0x9D87 0x9DAB 0x9D6F 0x9D7A 0x9D9A 0x9DA4 0x9DA9 0x9DB2 0x9DC4 0x9DC1 0x9DBB 0x9DB8 0x9DBA 0x9DC6 0x9DCF 0x9DC2 0x9DD9 0x9DD3 0x9DF8 0x9DE6 0x9DED 0x9DEF 0x9DFD 0x9E1A 0x9E1B 0x9E1E 0x9E75 0x9E79 0x9E7D 0x9E81 0x9E88 0x9E8B 0x9E8C 0x9E92 0x9E95 0x9E91 0x9E9D 0x9EA5 0x9EA9 0x9EB8 0x9EAA 0x9EAD 0x9761 0x9ECC 0x9ECE 0x9ECF 0x9ED0 0x9ED4 0x9EDC 0x9EDE 0x9EDD 0x9EE0 0x9EE5 0x9EE8 0x9EEF 0x9EF4 0x9EF6 0x9EF7 0x9EF9 0x9EFB 0x9EFC 0x9EFD 0x9F07 0x9F08 0x76B7 0x9F15 0x9F21 0x9F2C 0x9F3E 0x9F4A 0x9F52 0x9F54 0x9F63 0x9F5F 0x9F60 0x9F61 0x9F66 0x9F67 0x9F6C 0x9F6A 0x9F77 0x9F72 0x9F76 0x9F95 0x9F9C 0x9FA0 +0x582F 0x69C7 0x9059 0x7464 0x51DC 0x7199 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0021 0x0022 0x0023 0x0024 0x0025 0x0026 0x0027 0x0028 0x0029 0x002A 0x002B 0x002C 0x002D 0x002E 0x002F 0x0030 0x0031 0x0032 0x0033 0x0034 0x0035 0x0036 0x0037 0x0038 0x0039 0x003A 0x003B 0x003C 0x003D 0x003E 0x003F 0x0040 0x0041 0x0042 0x0043 0x0044 0x0045 0x0046 0x0047 0x0048 0x0049 0x004A 0x004B 0x004C 0x004D 0x004E 0x004F 0x0050 0x0051 0x0052 0x0053 0x0054 0x0055 0x0056 0x0057 0x0058 0x0059 0x005A 0x005B 0x005C 0x005D 0x005E 0x005F 0x0060 0x0061 0x0062 0x0063 0x0064 0x0065 0x0066 0x0067 0x0068 0x0069 0x006A 0x006B 0x006C 0x006D 0x006E 0x006F 0x0070 0x0071 0x0072 0x0073 0x0074 0x0075 0x0076 0x0077 0x0078 0x0079 0x007A 0x007B 0x007C 0x007D 0x007E +0x00A0 0x00A1 0x00A2 0x00A3 0x00A4 0x00A5 0x00A6 0x00A7 0x00A8 0x00A9 0x00AA 0x00AB 0x00AC 0x00AE 0x00B0 0x00B1 0x00B2 0x00B3 0x00B4 0x00B5 0x00B6 0x00B7 0x00BA 0x00BB 0x00BC 0x00BD 0x00BF 0x00C0 0x00C1 0x00C2 0x00C3 0x00C4 0x00C5 0x00C6 0x00C7 0x00C8 0x00C9 0x00CA 0x00CB 0x00CC 0x00CD 0x00CE 0x00CF 0x00D0 0x00D1 0x00D2 0x00D3 0x00D4 0x00D5 0x00D6 0x00D7 0x00D8 0x00D9 0x00DA 0x00DB 0x00DC 0x00DD 0x00DE 0x00DF 0x00E0 0x00E1 0x00E2 0x00E3 0x00E4 0x00E5 0x00E6 0x00E7 0x00E8 0x00E9 0x00EA 0x00EB 0x00EC 0x00ED 0x00EE 0x00EF 0x00F0 0x00F1 0x00F2 0x00F3 0x00F4 0x00F5 0x00F6 0x00F7 0x00F8 0x00F9 0x00FA 0x00FB 0x00FC 0x00FD 0x00FE 0x00FF 0x0102 0x0103 0x0104 +0x0105 0x0106 0x0107 0x0118 0x0119 0x0141 0x0142 0x0143 0x0144 0x0151 0x015A 0x015B 0x0179 0x017A 0x017B 0x017C 0x015E 0x015F 0x0162 0x0163 0x0171 0x0192 0x0218 0x0219 0x021A 0x021B 0x2022 0x203C 0x207F 0x20A7 0x20AC 0x2122 0x2194 0x2195 0x21A8 0x2219 0x221A 0x221E 0x221F 0x2229 0x2248 0x2261 0x2264 0x2265 0x2302 0x2310 0x2320 0x2321 0x2550 0x2551 0x2552 0x2553 0x2554 0x2555 0x2556 0x2557 0x2558 0x2559 0x255A 0x255B 0x255C 0x255D 0x255E 0x255F 0x2560 0x2561 0x2562 0x2563 0x2564 0x2565 0x2566 0x2567 0x2568 0x2569 0x256A 0x256B 0x256C 0x2580 0x2584 0x2588 0x258C 0x2590 0x2591 0x2592 0x2593 0x25A0 0x25A1 0x25AC 0x25B2 0x25B3 0x25BA 0x25BC 0x25BD 0x25C4 +0x25C6 0x25C7 0x25CB 0x25CE 0x25CF 0x25D8 0x25D9 0x2605 0x263A 0x263B 0x263C 0x2640 0x2642 0x2660 0x2663 0x2665 0x2666 0x266A 0x266B 0x7B80 0xE000 0xE001 0xE002 0xE003 0xE004 0xE005 0xE006 0xE079 0xE07A 0xE07B 0xE07C 0xE07D 0xE07E 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0386 0x0388 0x0389 0x038A 0x038C 0x038E 0x038F 0x0390 0x03AA 0x03AB 0x03AC 0x03AD 0x03AE 0x03AF 0x03B0 0x03C2 0x03CA 0x03CB 0x03CC 0x03CD 0x03CE 0x0406 0x0407 0x0456 0x0457 0x0490 0x0491 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x65E5 0x672C 0x8A9E 0x7409 0x7403 0x8AF8 0x4E2D 0x6587 0x7B80 0x4F53 0x7E41 0x9AD4 0xD55C 0xAD6D 0xC5B4 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 +0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 0x0020 \ No newline at end of file diff --git a/resources/gm9/languages/ja.frf b/resources/gm9/languages/ja.frf new file mode 100644 index 000000000..295357d6c Binary files /dev/null and b/resources/gm9/languages/ja.frf differ diff --git a/resources/languages/de.json b/resources/languages/de.json new file mode 100644 index 000000000..b29f24529 --- /dev/null +++ b/resources/languages/de.json @@ -0,0 +1,621 @@ +{ + "GM9_LANGUAGE": "Deutsch", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%4$02lX.%3$02lX.%1$s%2$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ",", + "THOUSAND_SEPARATOR": ".", + "FIRM_TOO_BIG": "FIRM zu groß, kann nicht booten", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nWarnung: Boote keine FIRMs\naus nicht vertrauenswürdigen\nQuellen.\n\nFIRM booten?", + "NOT_BOOTABLE_FIRM": "Nicht ein bootfähiger FIRM.", + "FIRM_ENCRYPTED": "FIRM ist verschlüsselt.\n\nVor dem Booten entschlüsseln?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Erstelle eine Kopie unter %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Versuche trotzdem zu booten", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Warnung: Versuche, von einem nicht unterstütztem\nOrt zu booten.", + "ROOT": "[stammverzeichnis]", + "LOADING": "LADEN...", + "PANE_N": "FENSTER #%lu", + "CURRENT": "AKTUELL", + "DIR": "(ordner)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAMdrive FAT)", + "GAME_VIRTUAL": "(Spiel Virtuell)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND Virtuell)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND Virtuell)", + "IMAGE_FAT": "(Abbild FAT)", + "XORPAD_VIRTUAL": "(XORpad Virtuell)", + "MEMORY_VIRTUAL": "(Speicher Virtuell)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Gamecart Virtuell)", + "VRAM_VIRTUAL": "(VRAM Virtuell)", + "SEARCH": "(Suche)", + "TITLEMANAGER_VIRTUAL": "(TitelVerwalter Virtuell)", + "LAB_SDCARD": "SD-KARTE", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUAL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUAL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "GAMECART", + "LAB_GAME_IMAGE": "SPIEL ABBILD", + "LAB_AESKEYDB_IMAGE": "AESKEYDB ABBILD", + "LAB_BDRI_IMAGE": "BRDI ABBILD", + "LAB_DISA_DIFF_IMAGE": "DISA/DIFF ABBILD", + "LAB_MEMORY_VIRTUAL": "SPEICHER VIRTUELL", + "LAB_VRAM_VIRTUAL": "VRAM VIRTUELL", + "LAB_TITLE_MANAGER": "TITEL VERWALTER", + "LAB_LAST_SEARCH": "LETZTE SUCHE", + "LAB_FAT_IMAGE": "FAT ABBILD", + "LAB_BONUS_DRIVE": "BONUS DRIVE", + "LAB_RAMDRIVE": "RAMDRIVE", + "LAB_NOLABEL": "NOLABEL", + "N_BYTE": "%s Byte", + "BYTE": " Byte", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[ZWISCHENABLAGE]", + "PLUS_N_MORE": "+ %lu weitere", + "MARK_DELETE_COPY": "L - MARKIERE Dateien (benutze mit ↑↓→←)\nX - LÖSCHE / [+R] UMBENENNE Datei(en)\nY - KOPIERE Dateien / [+R] ERSTELLE Einträge\n", + "MARK_DELETE_PASTE": "L - MARKIERE Dataien (benutze mit ↑↓→←)\nX - LÖSCHE / [+R] UMBENENNE Datei(en)\nY - Dateien Einfügen / [+R] ERSTELLE Einträge\n", + "RELOCK_WRITE_PERMISSION": "R+Y - Schreibrechte erneut sperren\n", + "UNMOUNT_IMAGE": "R+X - Abbild aushängen\n", + "UNMOUNT_SD": "R+B - SD-Karte aushängen\n", + "REMOUNT_SD": "R+B - SD-Karte wieder einhängen\n", + "DIRECTORY_OPTIONS": "R+A - Verzeichnisoptionen\n", + "DRIVE_OPTIONS": "R+A - Laufwerkoptionen\n", + "MAKE_SCREENSHOT": "R+L - Mache einen Screenshot\n", + "PREV_NEXT_PANE": "R+←→ - Wechsele zum vorherigen/nächsten Fenster\n", + "CLEAR_CLIPBOARD": "SELECT - Zwischenablage leeren\n", + "RESTORE_CLIPBOARD": "SELECT - Zwischenablage wiederherstellen\n", + "REBOOT_POWEROFF_HOME": "START - Neustarten / [+R] Ausschalten\nHOME Knopf für HOME-Menü", + "NO_EMUNAND": "Kein EmuNAND", + "REDNAND_SIZE_MIN": "RedNAND-Größe (min)", + "GW_EMUNAND_SIZE_FULL": "GW-EmuNAND-Größe (voll)", + "MULTINAND_SIZE_2X": "MultiNAND-Größe (2x)", + "MULTINAND_SIZE_3X": "MultiNAND-Größe (3x)", + "MULTINAND_SIZE_4X": "MultiNAND-Größe (4x)", + "USER_INPUT": "Nutzereingabe...", + "AUTO": "Auto", + "16KB_CLUSTERS": "16KB-Cluster", + "32KB_CLUSTERS": "32KB-Cluster", + "64KB_CLUSTERS": "64KB-Cluster", + "SD_NOT_DETECTED": "Fehler: SD-Karte nicht erkannt.", + "FORMAT_SD_CHOOSE_EMUNAND": "SD-Karte formatieren (%lluMB)?\nEmuNAND-Größe auswählen:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "Die Größe der SD-Karte ist %lluMB.\nEmuNAND-Größe (MB) unten eingeben:", + "FORMAT_SD_CHOOSE_CLUSTER": "SD-Karte (%lluMB) formatieren?\nCluster-Größe auswählen:", + "FORMAT_SD_ENTER_LABEL": "SD-Karte (%lluMB) formatieren?\nBeschriftung eingeben:", + "FORMAT_SD_FAILED": "SD-Formatierung: fehlgeschlagen!", + "REDNAND_TYPE": "RedNAND-Typ", + "REDNAND_TYPE_MULTI": "RedNAND-Typ (multi)", + "REDNAND_TYPE_SINGLE": "RedNAND-Typ (einzel)", + "GW_EMUNAND_TYPE": "GW EmuNAND-Typ", + "DONT_SET_UP": "Nicht einrichten", + "CHOOSE_EMUNAND_TYPE": "Einzurichtenden EmuNAND-Typ auswählen:", + "CLONE_SYSNAND_TO_REDNAND": "SysNAND zu RedNAND klonen?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "Klonen von SysNAND zu EmuNAND: fehlgeschlagen!", + "PRESS_A_TO_CONTINUE": "Drücke um fortzufahren", + "HEXEDITOR_CONTROLS": "Hexeditor-Tastenbelegung:\n↑↓→←(+R) - Scrollen\nR+Y - Ansicht wechseln\nX - Suche / gehe zu...\nA - Veränderungsmodus betreten\nA+↑↓→← - Wert verändern\nB - Beenden\n", + "NOT_FOUND": "Nicht gefunden!", + "GO_TO_OFFSET": "Gehe zu Versatz", + "SEARCH_FOR_STRING": "Nach Text suchen", + "SEARCH_FOR_DATA": "Nach Daten suchen", + "CURRENT_OFFSET_SELECT_ACTION": "Aktueller Versatz: %08lX\nAktion auswählen:", + "CURRENT_OFFSET_ENTER_NEW": "Aktueller Versatz: %08lX\nNeuen Versatz unten eingeben.", + "ENTER_SEARCH_REPEAT_SEARCH": "Gebe den Suchbegriff ein.\n(R+X um die Suche zu wiederholen)", + "MADE_EDITS_SAVE_CHANGES": "Sie haben Änderungen an %lu Stelle(n) vorgenommen.\nÄnderungen in die Datei schreiben?", + "FAILED_WRITING_TO_FILE": "Schreiben in die Datei fehlgeschlagen!", + "CALCULATING_SHA_FAILED": "Berechnung von SHA-%s: fehlgeschlagen!", + "SHA_VERIFICATION_PASSED": "\nSHA-Verifizierung: erfolgreich!", + "SHA_VERIFICATION_FAILED": "\nSHA-Verifizierung fehlgeschlagen", + "IDENTICAL_WITH_PREVIOUS": "\nIdentisch mit der vorherigen Datei:\n", + "WRITE_SHA_FILE": "\nSHA-Datei erstellen?", + "WRITE_SHA1_FILE": "\n.SHA1-Datei erstellen?", + "CALCULATING_CMAC_FAILED": "Berechnung von CMAC: fehlgeschlagen!", + "CMAC_VERIFICATION_PASSED": "CMAC-Verifizierung: erfolgreich!", + "CMAC_VERIFICATION_FAILED": "CMAC-Verifizierung: fehlgeschlagen!", + "FIX_CMAC_IN_FILE": "\nCMAC in Datei reparieren?", + "FIXING_CMAC_FAILED": "Reparieren von CMAC: fehlgeschlagen!", + "COPY_ALL_SELECTED_ITEMS": "Alle %lu ausgewählten Elemente kopieren?", + "FAILED_COPYING_ITEM": "Kopieren vom Element fehlgeschlagen", + "ITEMS_COPIED_TO_OUT": "%lu Elemente nach %s kopiert", + "PATH_COPIED_TO_OUT": "%s\nKopiert nach %s", + "CART_INIT_FAILED": "Karteninitialisierung fehlgeschlagen!", + "CART_DETECTED_SIZE_INPUT_BELOW": "Karte: %s\nErkannte Größe: %s\n \nGebe Dumpgröße unten ein.", + "NDS_CART_DECRYPT_SECURE_AREA": "Karte: %s\nNDS-Karte erkannt\nSecure-Area entschlüsseln?", + "FAILED_DUMPING_CART": "%s\nDumpen der Karte fehlgeschlagen", + "PATH_DUMPED_TO_OUT": "%s\nUnter %s gedumpt", + "CREATED": "erstellt", + "MODIFIED": "geändert", + "ANALYZING_DRIVE": "Untersuche Laufwerk, bitte warten...", + "ANALYZING_DIR": "Untersuche Verzeichnis, bitte warten...", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu Dateien & %lu Unterverzeichnisse\n%s Gesamtgröße\n \nFreier Speicherplatz: %s\nBelegter Speicherplatz: %s\nGesamter Speicherplatz: %s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu Dateien & %lu Unterverzeichnisse\n%s Gesamtgröße", + "FILESIZE_X": "dateigröße: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %snur lesbar [%c] %sversteckt\n[%c] %ssystem [%c] %sarchiv\n[%c] %svirtuell\n%s", + "UDRL_CHANGE_ATTRIBUTES": " (↑↓→← um Attribute zu verändern)\n", + "A_TO_CONTINUE": "( um fortzufahren)", + "A_APPLY_B_CANCEL": "( um anzuwenden, um abzubrechen)", + "A_YES_B_NO": "( ja, nein)", + "A_SELECT_B_CANCEL": "( auswählen, abbrechen)", + "HOLD_B_TO_CANCEL": "(halte B um abzubrechen)", + "FAILED_TO_SET_ATTRIBUTES": "Setzen von Attributen fehlgeschlagen!", + "NAND_IMAGE_OPTIONS": "NAND-Abbild-Optionnen...", + "CTRNAND_OPTIONS": "CTRNAND-Optionen...", + "MOUNT_FAT_IMAGE": "Als FAT-Abbild einhängen", + "CIA_IMAGE_OPTIONS": "CIA-Abbild-Optionen...", + "NCSD_IMAGE_OPTIONS": "NCSD-Abbild-Optionen...", + "NCCH_IMAGE_OPTIONS": "NCCH-Abbild-Optionen...", + "MOUNT_AS_EXEFS_IMAGE": "Als EXEFS-Abbild einhängen", + "MOUNT_AS_ROMFS_IMAGE": "Als ROMFS-Abbild einhängen", + "TMD_FILE_OPTIONS": "TMD-Datei-Optionen...", + "TMD_CDN_OPTIONS": "TMD/CDN-Optionen...", + "TMD_TWL_OPTIONS": "TMD/TWL-Optionen...", + "MANAGE_TITLE": "Titel Verwalten...", + "BOSS_FILE_OPTIONS": "BOSS-Datei-Optionen...", + "DECRYPT_NUS_CDN_FILE": "NUS/CDN-Datei entschlüsseln", + "SHOW_SMDH_TITLE_INFO": "SMDH-Titelinfo anzeigen", + "NDS_IMAGE_OPTIONS": "NDS-Abbild-Optionen...", + "GBA_IMAGE_OPTIONS": "GBA-Abbild-Optionen...", + "TICKET_OPTIONS": "Ticket-Optionen...", + "TAD_IMAGE_OPTIONS": "TAD-Abbild-Optionen...", + "SHOW_3DSX_TITLE_INFO": "3DSX-Titelinfo anzeigen", + "FIRM_IMAGE_OPTIONS": "FIRM-Abbild-Optionen...", + "AGBSAVE_OPTIONS": "AGBSAVE-Optionen...", + "DUMP_GBA_VC_SAVE": "GBA-VC-Speicherstand dumpen", + "TICKET_DB_OPTIONS": "Ticket.db-Optionen...", + "MOUNT_AS_DIFF_IMAGE": "Als DIFF-Abbild einhängen", + "MOUNT_AS_DISA_IAMGE": "Als DISA-Abbild einhängen", + "INSTALL_CIFINISH_BIN": "cifinish.bin installieren", + "TITLEKEY_OPTIONS": "Titlekey-Optionen...", + "AESKEYDB_OPTIONS": "AESkeydb-Optionen...", + "BUILD_X": "Build %s", + "NCCHINFO_OPTIONS": "NCCHinfo-Optionen...", + "EXECUTE_GM9_SCRIPT": "GM9-Skript ausführen", + "FONT_OPTIONS": "Schriftoptionen...", + "LANGUAGE_OPTIONS": "Sprachoptionen...", + "VIEW_PNG_FILE": "PNG-Datei anzeigen", + "REBUILD_NCSD_HEADER": "NCSD-Header neu erstellen", + "SHOW_IN_HEXEDITOR": "Im Hexeditor anzeigen", + "CALCULATE_SHA256": "SHA-256 berechnen", + "CALCULATE_SHA1": "SHA-1 berechnen", + "SHOW_FILE_INFO": "Datei-Info anzeigen", + "SHOW_IN_TEXTVIEWER": "Im Textbetrachter anzeigen", + "CALCULATE_CMAC": "CMAC berechnen", + "COPY_TO_OUT": "Nach %s kopieren", + "DUMP_TO_OUT": "Unter %s dumpen", + "INJECT_DATA_AT_OFFSET": "Daten @versatz injizieren", + "OPEN_THIS_FOLDER": "Dieses Verzeichnis öffnen", + "OPEN_CONTAINING_FOLDER": "Beinhaltendes Verzeichnis öffnen", + "OPEN_TITLE_FOLDER": "Titelorder öffnen", + "PATH_N_FILES_SELECTED": "%s\n(%lu Dateien ausgewählt)", + "CHECK_CURRENT_CMAC_ONLY": "Nur aktuelles CMAC überprüfen", + "VERIFY_CMAC_FOR_ALL": "CMAC für alle überprüfen", + "FIX_CMAC_FOR_ALL": "CMAC für alle reparieren", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%lu Dateien ok/repariert/insgesamt\n%lu/%lu haben kein CMAC", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%lu Dateien erfolgreich verifiziert\n%lu/%lu Dataien repariert", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%lu Dateien erfolgreich verifiziert\n%lu/%lu haben kein CMAC", + "N_OF_N_FILES_VERIFIED": "%lu/%lu Dateien erfolgreich verifiziert", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "Daten von %s injizieren?\nVersatz unten eingeben.", + "FAILED_INJECTING_PATH": "Injizieren von %s fehlgeschlagen", + "MOUNT_CXI_NDS_TO_DRIVE": "CXI/NDS an Laufwerk einhängen", + "MOUNT_IMAGE_TO_DRIVE": "Abbild an Laufwerk einhängen", + "RESTORE_SYSNAND_SAFE": "SysNAND wiederherstellen (sicher)", + "UPDATE_EMBEDDED_BACKUP": "Eingebettetes backup aktualisieren", + "SHOW_TITLE_INFO": "Titel-Info anzeigen", + "DECRYPT_FILE": "Datei entschlüsseln (...)", + "DECRYPT_FILE_OUT": "Datei entschlüsseln (%s)", + "ENCRYPT_FILE": "Datei verschlüsseln (...)", + "ENCRYPT_FILE_OUT": "Datei verschlüsseln (%s)", + "BUILD_CIA_FROM_FILE": "CIA aus Datei erstellen", + "BUILD_CIA_STANDARD": "CIA erstellen (standard)", + "BUILD_CIA_LEGIT": "CIA erstellen (legit)", + "DUMP_CXI_NDS_FILE": "CXI/NDS-Datei dumpen", + "INSTALL_GAME_IMAGE": "Spielabbild installieren", + "INSTALL_TICKET": "Ticket installieren", + "DUMP_TICKET_FILE": "Ticket-Datei dumpen", + "UNINSTALL_TITLE": "Titel deinstallieren", + "VERIFY_FILE": "Datei verifizieren", + "TRANSFER_IMAGE_TO_CTRNAND": "Abbild auf CTRNAND übertragen", + "INJECT_TO_H_AND_S": "In G&S injizieren", + "TRIM_FILE": "Datei trimmen", + "RENAME_FILE": "Datei umbenennen", + "BUILD_XORPADS_SD": "XORpads erstrellen (auf SD)", + "BUILD_XORPADS_INPLACE": "XORpads erstellen (an Ort und Stelle)", + "EXTRACT_X": "%s extrahieren", + "INIT_X": "%s einrichten", + "INSTALL_X": "%s installieren", + "INSTALL_FIRM": "FIRM installieren", + "BOOT_FIRM": "FIRM booten", + "SET_AS_ACTIVE_FONT": "Als aktive Schriftart festlegen", + "SET_AS_ACTIVE_LANGUAGE": "Als aktive Sprache festlegen", + "DUMP_BA_VC_SAVE": "GBA-VC-Spielstand dumpen", + "INJECT_GBA_VC_SAVE": "GBA-VC-Spielstand injizieren", + "SET_AS_DEFAULT": "Als Standard festlegen", + "MOUNTING_IMAGE_FAILED": "Einhängen vom Abbild: fehlgeschlagen", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nEingehängt als Laufwerk unter %s\nPfad jetzt betreten?", + "DECRYPT_TO_OUT": "Unter %s entschlüsseln", + "DECRYPT_INPLACE": "An Ort und Stelle entschlüsseln", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "Versuchen, alle %lu ausgewählten Dateien zu entschlüsseln?", + "TRYING_TO_DECRYPT_N_FILES": "Versuche, %lu Dateien zu entschlüsseln...", + "DECRYPTION_FAILED_CONTINUE": "Entschlüsseln fehlgeschlagen\n\nFortfahren?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu Dateien erfolgreich entschlüsselt\n%lu/%lu nicht verschlüsselt\n%lu/%lu nicht vom gleichen Typ", + "N_OF_N_FILES_DECRYPTED": "%lu/%lu Dateien erfolgreich entschlüsselt", + "N_FILES_WRITTEN_TO_OUT": "%lu Dateien in %s geschrieben", + "FILE_NOT_ENCRYPTED": "Datei ist nicht verschlüsselt", + "DECRYPTION_SUCCESS": "Entschlüsseln erfolgreich", + "DECRYPTION_FAILED": "Entschlüsseln fehlgeschlagen", + "PATH_DECRYPTED_TO_OUT": "%s\nEntschlüsselt nach %s", + "ENCRYPT_TO_OUT": "Nach %s verschlüsseln", + "ENCRYPT_INPLACE": "An Ort und Stelle verschlüsseln", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "Versuchen, alle %lu ausgewählten Dateien zu verschlüsseln?", + "TRYING_TO_ENCRYPT_N_FILES": "Versuche, %lu Dateien zu verschlüsseln...", + "ENCRYPTION_FAILED_CONTINUE": "Verschlüsseln fehlgeschlagen\n\nFortfahren?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu Dateien erfolgreich verschlüsselt\n%lu/%lu nicht vom gleichen Typ", + "N_OF_N_FILES_ENCRYPTED": "%lu/%lu Dateien erfolgreich verschlüsselt", + "ENCRYPTION_SUCCESS": "Verschlüsseln erfolgreich", + "ENCRYPTION_FAILED": "Verschlüsseln fehlgeschlagen", + "PATH_ENCRYPTED_TO_OUT": "%s\nVerschlüsselt unter %s", + "TRY_TO_PROCESS_N_SELECTED_FILES": "Versuchen, alle %lu ausgewählten Dateien zu verarbeiten?", + "PATH_BUILD_TYPE_FAILED_CONTINUE": "%s\nErstellen von %s fehlgeschlagen\n\nForfahren?", + "N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE": "%lu/%lu %s-Dateien erfolgreich erstellt\n%lu/%lu nicht vom gleichen Typ", + "N_OF_N_TYPES_BUILT": "%lu/%lu %s-Dateien erfolgreich erstellt", + "N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED": "Konvertierung von %lu Datei(en) fehlgeschlagen.\nVerifizierung ist empfohlen.", + "PATH_TYPE_BUILT_TO_OUT": "%s\n%s unter %s erstellt", + "PATH_TYPE_BUILD_FAILED": "%s\nErstellung von %s fehlgeschlagen", + "FILE_FAILED_CONVERSION_VERIFY_NOW": "Konvertierung von Datei fehlgeschlagen\n\nJetzt verifizieren?", + "VERIFICATION_SUCCESS": "Verifizierung erfolgreich", + "VERIFICATION_FAILED": "Verifizierung fehlgeschlagen", + "CONTENT_IS_MISSING": "Inhalt fehlt", + "INSTALL_TO_SYSNAND": "Auf SysNAND installieren", + "INSTALL_TO_EMUNAND": "Auf EmuNAND installieren", + "TRY_TO_INSTALL_N_SELECTED_FILES": "Versuchen, alle %lu ausgewählten Dateien zu installieren?", + "TRYING_TO_INSTALL_N_FILES": "Versuche, alle %lu Dateien zu installieren...", + "INSTALL_FAILED_CONTINUE": "Installation fehlgeschlagen\n\nFortfahren?", + "N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu Dateien erfolgreich installiert\n%lu/%lu nicht vom gleichen Typ", + "N_OF_N_FILES_INSTALLED": "%lu/%lu Dateien erfolgreich installiert", + "INSTALL_SUCCESS": "Installation erfolgreich", + "INSTALL_FAILED": "Installation fehlgeschlagen", + "FILE_FAILED_INSTALL_VERIFY_NOW": "Installation der Datei fehlgeschlagen.\n\nJetzt verifizieren?", + "KEEP_TICKET_AND_SAVEGAME": "Ticket und Spielstand behalten", + "UNINSTALL_EVERYTHING": "Alles deinstallieren", + "ABORT_UNINSTALL": "Deinstallation abbrechen", + "UNINSTALL_N_SELECTED_TITLES": "%lu ausgewählte Titel deinstallieren?", + "UNINSTALL_SELECTED_TITLE": "Ausgewählten Titel deinstallieren?", + "N_OF_N_TITLES_UNINSTALLED": "%lu/%lu Titel deinstalliert", + "UNINSTALLING_PLEASE_WAIT": "Deinstallieren, bitte warten...", + "UNINSTALL_FAILED": "Deinstallation fehlgeschlagen!", + "TRY_TO_VERIFY_N_SELECTED_FILES": "Versuche, alle %lu ausgewählten Titel zu verifizieren?", + "VERIFICATION_FAILED_CONTINUE": "Verifizierung fehlgeschlagen\n\nFortfahren?", + "N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu Dateien erfolgreich verifiziert\n%lu/%lu nicht vom gleichen Typ", + "VERIFYING_FILE_PLEASE_WAIT": "Verifiziere Datei, bitte warten...", + "NAND_VALIDATION_SUCCESS": "NAND-Überprüfung erfolgreich", + "NAND_VALIDATION_FAILED": "NAND-Überprüfung fehlgeschlagen", + "DUMP_FOR_N_SELECTED_FILES": "Für alle %lu ausgewählten Dateien dumpen?", + "N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL": "%lu/%lu legit-Tickets gedumpt.\n\nVersuchen, alle Tickets zu dumpen?", + "N_OF_N_TICKETS_DUMPED_TO_OUT": "%lu/%lu Tickets nach %s gedumpt", + "PATH_TICKET_DUMPED_TO_OUT": "%s\nTicket nach %s gedumpt", + "LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS": "%s\nLegit-Ticket nicht gefunden\n\nTrotzdem dumpen?", + "DUMP_TICKET_FAILED": "Dumpen vom Ticket fehlgeschlagen!", + "BUILDING_X": "Erstelle %s...", + "BUILDING_X_SYSNAND": "Erstelle %s (SysNAND)...", + "BUILDING_X_EMUNAND": "Erstelle %s (EmuNAND)...", + "PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED": "%s\n%lu/%lu Dateien verarbeitet\n%lu/%lu Dateien ignoriert", + "PATH_N_OF_N_FILES_PROCESSED": "%s\n%lu/%lu Dateien verarbeitet", + "BUILD_DATABASE_SUCCESS": "Datenbankerstellung erfolgreich.", + "BUILD_DATABASE_FAILED": "Datenbankerstellung fehlgeschlagen.", + "TRY_TO_TRIM_N_SELECTED_FILES": "Alle %lu ausgewählten Dateien trimmen?", + "TRIMMING_FAILED_CONTINUE": "Trimmen fehlgeschlagen\n\nFortfahren?", + "N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED": "%lu/%lu Dateien erfolgreich getrimmt\n%lu/%lu nicht vom gleichen Typ\n%s gespeichert", + "N_OF_N_FILES_TRIMMED_X_SAVED": "%lu/%lu Dateien erfolgreich getrimmt\n%s gespeichert", + "FILE_CANT_BE_TRIMMED": "Datei kann nicht getrimmt werden.", + "FILE_ALREADY_TRIMMED": "Datei ist bereits getrimmt.", + "PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE": "%s\nAktuelle Größe: %s\nGetrimmte Größe: %s\nUnterschied: %s\n\nDiese Datei trimmen?", + "TRIMMING_FAILED": "Trimmen fehlgeschlagen.", + "PATH_TRIMMED_BY_X": "%s\n%s getrimmt.", + "TRY_TO_RENAME_N_SELECTED_FILES": "Versuchen, alle %lu ausgewählten Dateien umzubenennen?", + "N_OF_N_RENAMED": "%lu/%lu erfolgreich umbenannt", + "COULD_NOT_RENAME_TO_GOOD_NAME": "Konnte nicht zum guten Namen umbenennen", + "SYSNAND_H_AND_S_INJECT": "SysNAND H&S inject", + "EMUNAND_H_AND_S_INJECT": "EmuNAND H&S inject", + "H_AND_S_INJECT_SUCCESS": "H&S inject success", + "H_AND_S_INJECT_FAILURE": "H&S inject failure", + "TRY_EXTRACT_ALL_N_SELECTED_FILES": "Try to extract all %lu selected files?", + "N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files extracted ok\n%lu/%lu not of same type", + "N_OF_N_FILES_EXTRACTED": "%lu/%lu files extracted ok", + "EXTRACTING_DOT_CODE": "Extracting .code, please wait...", + "PATH_EXT_EXTRACTED_TO_OUT": "%s\n%s extracted to %s", + "DOT_CODE_EXTRACT_FAILED": ".code extract failed", + "TRANSFER_TO_SYSNAND": "Transfer to SysNAND", + "TRANSFER_TO_EMUNAND": "Transfer to EmuNAND", + "CTRNAND_TRANSFER_SUCCESS": "CTRNAND transfer success", + "CTRNAND_TRANSFER_FAILED": "CTRNAND transfer failed", + "NO_VALID_DESTINATION_FOUND": "No valid destination found", + "NAND_RESTORE_SUCCESS": "NAND restore success", + "NAND_RESTORE_FAILED": "NAND restore failed", + "REBUILD_NCSD_SUCCESS": "Rebuild NCSD success", + "REBUILD_NCSD_FAILED": "Rebuild NCSD failed", + "PATH_NCCHINFO_PADGEN_SUCCESS": "%s\nNCCHinfo padgen success%cOutput dir: %s", + "PATH_NCCHINFO_PADGEN_FAILED": "%s\nNCCHinfo padgen failed%c%0.0s", + "UPDATING_EMBEDDED_BACKUP": "Updating embedded backup...", + "BACKUP_UPDATE_NOT_REQUIRED": "Backup update: not required", + "BACKUP_UPDATE_COMPLETED": "Backup update: completed", + "BACKUP_UPDATE_FAILED": "Backup update: failed!", + "WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK": "Warning: Keys are not verified.\nContinue on your own risk?", + "AESKEYDB_INIT_SUCCESS": "AESkeydb init success", + "AESKEYDB_INIT_FAILED": "AESkeydb init failed", + "AESKEYDB_INSTALL_SUCCESS": "AESkeydb install success", + "AESKEYDB_INSTALL_FAILED": "AESkeydb install failed", + "INSTALL_TO_FIRM0": "Install to FIRM0", + "INSTALL_TO_FIRM1": "Install to FIRM1", + "INSTALL_TO_BOTH": "Install to both", + "PATH_N_KB_INSTALL_TO_SYSNAND": "%s (%dkB)\nInstall to SysNAND?", + "PATH_N_KB_INSTALL_SUCCESS": "%s (%dkB)\nInstall success", + "PATH_N_KB_INSTALL_FAILED": "%s (%dkB)\nInstall failed", + "WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS": "Warning: Do not run scripts\nfrom untrusted sources.\n \nExecute script?", + "SCRIPT_EXECUTE_SUCCESS": "Script execute success", + "SCRIPT_EXECUTE_FAILURE": "Script execute failure", + "ERROR_CANNOT_VIEW_FILE": "Error: Cannot view file\n(Hint: maybe it's too big)", + "SAVEGAME_DUMPED_TO_OUT": "Savegame dumped to %s.", + "SAVEGAME_DUMP_FAILED": "Savegame dump failed!", + "GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD": "GBA VC savegame has to\nbe in the clipboard.", + "SAVEGAME_INJECT_SUCCESS": "Savegame inject success.", + "SAVEGAME_INJECT_FAILED": "Savegame inject failed!", + "FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Font will be active on next boot", + "LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Language will be active on next boot", + "HOME_MORE_MENU_SELECT_ACTION": "HOME more... menu.\nSelect action:", + "SD_FORMAT_MENU": "SD format menu", + "BONUS_DRIVE_MENU": "Bonus drive setup", + "SWITCH_EMUNAND": "EmuNAND wechseln", + "BUILD_SUPPORT_FILES": "Unterstützungsdateien erstellen", + "RESTORE_H_AND_S": "G&S wiederherstellen", + "SET_RTC_DATE_TIME": "RTC Datum/Uhrzeit einstellen", + "CONFGURE_BRIGHTNESS": "Helligkeit konfigurieren", + "CALIBRATE_TOUCHSCREEN": "Touchscreen kalibrieren", + "SYSTEM_INFO": "Systeminformation", + "SHOW_README": "ReadMe anzeigen", + "INITIALIZING_SD_FAILED_RETRY": "Initialisieren von SD-Karte fehlgeschlagen! Erneut versuchen?", + "SETUP_FAILED": "Einrichtung fehlgeschlagen!", + "CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT": "Aktueller EmuNAND-Versatz ist %06lX.\nZum nächsten Versatz wechseln?", + "BUILT_IN_OUT_STATUSES": "Erstellt unter %s:\n\n%-18.18s %s\n%-18.18s %s\n%-18.18s %s", + "OK_SYS_EMU": "OK (Sys&Emu)", + "OK_SYS": "OK (Sys)", + "FAILED": "Fehlgeschlagen", + "RESTORE_H_AND_S_EMUNAND": "G&S wiederherstellen (EmuNAND)", + "RESTORE_H_AND_S_SYSNAND": "G&S wiederherstellen (SysNAND)", + "TITLE_SET_RTC_DATE_TIME": "RTC Datum/Uhrzeit einstellen:", + "NEW_RTC_DATE_TIME_IS_TIME": "Neue(s) RTC-Datum/Uhrzeit ist:\n%s\n\nTipp: HOME-Menü benötigt\nmanuelles einstellen nach\nRTC-Einstellung.", + "TOUCHSCREEN_CALIBRATION_SUCCESS": "Touchscreen-kalibrierung erfolgreich!", + "TOUCHSCREEN_CALIBRATION_FAILED": "Touchscreen-kalibrierung fehlgeschlagen!", + "GODMODE9_README_TOC": "GodMode9 ReadMe Inhaltsverzeichnis", + "ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW": "Essenzielle-Dateien-Backup nicht gefunden.\nJetzt eins erstellen?", + "BACKUP_EMBEDDED_WRITTEN_TO_OUT": "Backup im SysNAND eingebettet\nund unter %s geschrieben.", + "RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW": "RTC-Datum/Uhrzeit könnte\nfalsch sein. Jetzt einstellen?", + "RESUME_GODMODE9": "GodMode9 fortsetzen", + "RESUME_BOOTLOADER": "Bootloader fortsetzen", + "SELECT_PAYLOAD": "Payload auswählen...", + "SELECT_SCRIPT": "Skript auswählen...", + "POWEROFF_SYSTEM": "System ausschalten", + "REBOOT_SYSTEM": "System neustarten", + "FLAVOR_BOOTLOADER_SELECT_OPTION": "%s Bootloader-Menü.\nAktion auswählen:", + "BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD": "Bootloader-Payloads-Menü.\nPayload auswählen:", + "BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT": "Bootloader-Skripte-Menü.\nSkript auswählen:", + "NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9": "Kein bootfähiges FIRM gefunden.\nSetze GodMode9 fort...", + "OUT_OF_MEMORY": "Nicht genügend Arbeitsspeicher.", + "INVALID_DIRECTORY_OBJECT": "Ungültiges Verzeichnisobjekt", + "INVALID_ROOT_DIRECTORY": "Ungültiges Wurzelverzeichnis.", + "WRITE_PERMISSIONS_WERE_CHANGED_RELOCK": "Schreibrechte wurden verändert.\nDiese wieder sperren?", + "OPEN_TITLE_MANAGER": "Titel-Verwalter öffnen", + "SEARCH_FOR_FILES": "Nach Dateien suchen...", + "FIX_CMACS_FOR_DRIVE": "CMACs für Laufwerk reparieren", + "SHOW_DIRECTORY_INFO": "Verzeichnis-Info anzeigen", + "SHOW_DRIVE_INFO": "Laufwerk-Info anzeigen", + "FAILED_SETTING_UP_TITLE_MANAGER": "Einrichtung des Titel-Verwalters fehlgeschlagen!", + "SEARCH_FILE_ENTER_SEARCH_BELOW": "Suche %s?\nSuchbegriffe unten eingeben.", + "FOUND_N_RESULTS": "Habe %lu Ergebnisse gefunden.", + "FIX_CMACS_FOR_DRIVE_FINISHED": "CMAC-Reparatur für Laufwerk beendet.", + "FAILED_TO_ANALYZE_DRIVE": "Laufwerkanalyse fehlgeschlagen\n", + "FAILED_TO_ANALYZE_DIR": "Verzeichnisanalyse fehlgeschlagen\n", + "NOT_ALLOWED_IN_VIRTUAL_PATH": "In einem virtuellem Pfad nicht erlaubt", + "DELETE_N_PATHS": "%lu Pfad(e) löschen?", + "DELETING_FILES_PLEASE_WAIT": "Lösche Dateien, bitte warte...", + "FAILED_DELETING_N_OF_N_PATHS": "Löschen von %lu/%lu Pfad(en) fehlgeschlagen", + "DELETE_FILE": "\"%s\" löschen?", + "FAILED_DELETING_PATH": "Löschen fehlgeschlagen:\n%s", + "NOT_ALLOWED_IN_SEARCH_DRIVE": "Im Suchlaufwerk nicht erlaubt", + "NOT_ALLOWED_IN_VIRTUAL_GAME_PATH": "Im virtuellen Spielpfad nichterlaubt", + "NOT_ALLOWED_IN_XORPAD_DRIVE": "Im XORpad-Laufwerk nicht erlaubt", + "NOT_ALLOWED_IN_GAMECART_DRIVE": "Im Gamecart-Laufwerk nicht erlaubt", + "NOT_ALLOWED_IN_ALIAS_PATH": "Im Alias-Pfad nicht erlaubt", + "COPY_PATHS": "Pfad(e) kopieren", + "MOVE_PATHS": "Pfad(e) verschieben", + "PASTE_FILE_HERE": "\"%s\" hier einfügen?", + "PASTE_N_PATHS_HERE": "%lu Pfade hier einfügen?", + "FAILED_COPYING_PATH_PROCESS_REMAINING": "Kopieren vom Pfad fehlgeschlagen:\n%s\nDen Rest verarbeiten?", + "FAILED_COPYING_PATH": "Kopieren vom Pfad fehlgeschlagen:\n%s", + "FAILED_MOVING_PATH_PROCESS_REMAINING": "Verschieben vom Pfad fehlgeschlagen:\n%s\nDen Rest verarbeiten?", + "FAILED_MOVING_PATH": "Verschieben vom Pfad fehlgeschlagen:\n%s", + "RENAME_FILE_ENTER_NEW_NAME_BELOW": "%s umbenennen?\nNeuen Namen unten eingeben.", + "FAILED_RENAMING_PATH": "Umbenennen vom Pfad fehlgeschlagen:\n%s", + "CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE": "Hier einen neuen Eintrag erstellen?\nWähle einen Typ aus.", + "CREATE_A_FOLDER": "Verzeichnis erstellen", + "CREATE_A_DUMMY_FILE": "Eine Platzhalterdatei erstellen", + "CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW": "Hier ein neues Verzeichnis erstellen?\nGebe unten den Namen ein.", + "CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW": "Hier eine neue Datei erstellen?\nGebe unten den Namen ein.", + "CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW": "Hier ein(e) neue(s) %s erstellen?\nGebe unten den Namen ein.", + "FAILED_CREATING_FOLDER_PATH": "Erstellen des Verzeichnisses fehlgeschlagen:\n%s", + "FAILED_CREATING_FILE_PATH": "Erstellen der Datei fehlgeschlagen:\n%s", + "TITLE_MANAGER": "Titel-Verwalter", + "BRICK_MY_3DS": "Meinen 3DS bricken", + "LANGUAGE": "Sprache...", + "SCRIPTS": "Skripte...", + "PAYLOADS": "Payloads...", + "MORE": "Mehr...", + "BRACKET_MORE": "[mehr...]", + "HOME_BUTTON_PRESSED_SELECT_ACTION": "HOME-Knopf betätigt.\nAktion auswählen:", + "POWER_BUTTON_PRESSED_SELECT_ACTION": "POWER-Schalter betätigt.\nAktion auswählen:", + "1_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "4_DRIVE_NAND_TWL": "[4:] NAND / TWL", + "A_DRIVE_SD_CARD": "[A:] SD-KARTE", + "B_DRIVE_SD_CARD": "[B:] SD-KARTE", + "TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE": "Titel-Verwalter-Menü.\nQuelle von Titlen auswählen:", + "LANGUAGES_DIRECTORY_NOT_FOUND": "Sprachverzeichnis nicht gefunden.\n(Standardpfad: 0:/gm9/%s)", + "SCRIPTS_DIRECTORY_NOT_FOUND": "Skriptverzeichnis nicht gefunden.\n(Standardpfad: 0:/gm9/%s)", + "HOME_LANGUAGE_MENU_SELECT_LANGUAGE": "HOME-Sprachen... Menü.\nSprache auswählen:", + "HOME_SCRIPTS_MENU_SELECT_SCRIPT": "HOME-Skripte... Menü.\nSkript auswählen:", + "PAYLOADS_DIRECTORY_NOT_FOUND": "Payloads-Verzeichnis nicht gefunden.\n(Standardpfad: 0:/gm9/%s)", + "HOME_PAYLOADS_MENU_SELECT_PAYLOAD": "HOME-Payloads... Menü.\nPayload auswählen:", + "UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT": "!Unerwartetes entfernen der SD-Karte!\n\nUm Datenverluste zu vermeiden,\nhänge die SD-Karte aus bevor du\nsie entfernst.", + "FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT": "%s Skript-Menü.\nSkript auswählen:", + "COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP": "Als Skript-Autorunner kompiliert,\naber kein Skript wurde angegeben.\n\nDerp!", + "KEYBOARD_CONTROLS_DETAILS": "Tastaturbedienung:\n←/→ - Cursor bewegen\nR - Caps / Capslock\nX - Zeichen löschen\nY - Zeichen einfügen\nA - Bestätigen\nB - Abbrechen\n\nSELECT wechselt zur\nklassischen eingabe", + "TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS": "Berühre die roten Kreuze, um\ndeinen Touchscreen zu kalibrieren.\n\nBenutze einen Touchpen für die\nbesten Ergebnisse!", + "INVALID": "UNGÜLTIG", + "TO_PROCEED_ENTER_THIS": "Um fortzufahren, gebe dies ein:", + "TO_PROCEED_HOLD_X": "Um fortzufahren, halte :", + "N_MORE": " [%d weitere]", + "CANCEL": "abbrechen", + "R_FAST_SCROLL_L_CLEAR_DATA": "R - (↑↓) schnelles scrollen\nL - Eingabe leeren", + "X_REMOVE_CHAR_Y_INSERT_CHAR": "X - Zeichen entfernen\nY - Zeichen einfügen", + "ETA_N_MIN_N_SEC": "ETA %02llum%02llus", + "BRIGHTNESS_CONTROLS": "[←] Helligkeit verringern\n[→] Helligkeit erhöhen\n \n[X] Nutze Lautstärkeregler\n[A] Aktuelle Helligkeit einstellen\n[B] Abbrechen", + "SEARCHING_PLEASE_WAIT": "Suche, bitte warten...", + "RENAME_TO_GOOD_NAME": "In guten Namen umbenennen?", + "SD_WRITE_PROTECTED_CANT_CONTINUE": "SD-Karte ist schreibgeschützt!\nKann nicht fortfahren.", + "SYSNAND_LVL_N": "SysNAND (lvl%lu)", + "EMUNAND_LVL_N": "EmuNAND (lvl%lu)", + "GAME_IMAGES": "Spielabbilder", + "GAMECART_SAVES": "Gamecart-Spielstände", + "IMAGES": "Abbilder", + "MEMORY_AREAS": "Speicherbereiche", + "SD_SYSTEM_DATA": "SD-Systemdaten", + "SD_CARD": "SD-Karte", + "RAM_DRIVE": "RAM-Laufwerk", + "WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW": "Schreiben in %s ist gesperrt!\nEs jetzt entsperren?", + "UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED": "Entsperren von Schreibrechten für\n%s ist nicht erlaubt.", + "ENABLE_BASE_WRITE": "Du möchtest vielleicht die Basis-\nSchreibrechte entsperren.", + "ENABLE_SD_WRITE": "Du möchtest vielleicht die SD-Karten-\nSchreibrechte entsperren.", + "ENABLE_IMAGE_WRITE": "Du möchtest vielleicht die Abbild-\nSchreibrechte entsperren.", + "ENABLE_RAM_DRIVE_WRITE": "Du möchtest vielleicht die RAM-Laufwerk-\nSchreibrechte entsperren.", + "ENABLE_EMUNAND_0_WRITE": "Du möchtest vielleicht die EmuNAND-\nlvl0-Schreibrechte entsperren.", + "ENABLE_SYSNAND_0_WRITE": "Du möchtest vielleicht die SysNAND-\nlvl0-Schreibrechte entsperren.", + "ENABLE_EMUNAND_1_WRITE": "Du möchtest vielleicht die EmuNAND-\nlvl1-Schreibrechte entsperren.\n\nDies ermöglicht dir, wiederherstellbare\nSystemdaten, Nutzerdaten & Spielstände\nzu modifizieren.", + "ENABLE_SYSNAND_1_WRITE": "Du möchtest vielleicht die EmuNAND-\nlvl1-Schreibrechte entsperren.\n\nDies ermöglicht dir, Systemdaten,\nNutzerdaten & Spielstände zu\nmodifizieren.", + "ENABLE_GAMECART_SAVE_WRITE": "Sie möchten vielleicht die Gamecart-\nSpielstand-Schreibrechte entsperren.", + "ENABLE_SYSNAND_2_WRITE": "!Du solltest vorsichtig sein!\n\nDu möchtest vielleicht die SysNAND-\nlvl2-Schreibrechte entsperren.\n\nDies ermöglicht dir, nichtwiederherstellbare\nSystemdaten zu modifizieren!", + "ENABLE_MEMORY_WRITE": "!Du solltest vorsichtig sein!\n\nDu möchtest vielleicht die Arbeitsspeicher-\nSchreibrechte entsperren.\n\nDas Schreiben in einigen Bereichen könnte\nzu unerwarteten Ergebnissen führen.", + "ENABLE_SD_DATA_WRITE": "!DIES IST NICHT EMPFOHLEN!\n\nDu möchtest vielleicht die SD-\nDaten-Schreibrechte entsperren.\n\nAlles hier ist verschlüsselt. Es wird\nempfohlen, die A:/B: Laufwerke für\nÄnderungen an Installationen,\nNutzerdaten und Spielständen zu\ntätigen.", + "ENABLE_SYSNAND_3_WRITE": "!DIES IST DEINE EINZIGE WARNUNG!\n\nDu möchtest vielleicht die SysNAND-\nlvl3-Schreibrechte entsperren.\n\nDies ermöglicht dir, deine Bootloader-\nInstallation und/oder wichtige\nSystemdateien zu ÜBERSCHREIBEN\nund/oder deine Konsole zu BRICKEN!", + "UNLOCK_WRITE_NOT_ALLOWED": "Das entsperren von Schreibrechten\nist nicht erlaubt.", + "CANT_UNLOCK_WRITE_TRY_GODMODE9": "Kann Schreibrechte nicht entsperren.\nNutze stattdessen GodMode9!", + "ERROR_SD_TOO_SMALL": "Fehler: SD-Karte ist zu klein", + "WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA": "!WARNUNG!\n\nFortfahren wird diese SD-Karte\nformatieren. Dies wird ALLE Daten\nunwiderruflich löschen.", + "FORMAT_BONUS_DRIVE_DELETE_ALL_DATA": "Bonus-Laufwerk formatieren?\nDies wird ALLE Daten\nunwiderruflich löschen.", + "FORMATTING_SD_PLEASE_WAIT": "Formatiere SD-Karte, bitte warten...", + "FORMATTING_DRIVE_PLEASE_WAIT": "Formatiere Laufwerk, bitte warten...", + "ERROR_SD_CARD_IO_FAILURE": "Fehler: SD-Karte E/A-Fehler", + "FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK": "Datei ist derzeit eingehängt.\nAushängen zum Entsperren?", + "ERROR_CANT_INJECT_FILE_INTO_ITSELF": "Fehler: Kann Datei nicht in sich\nselbst Injizieren", + "OPERATION_WOULD_WRITE_BEYOND_EOF": "Vorgang würde über das Ende der Datei\nhinaus schreiben", + "NOT_ENOUGH_DATA_IN_FILE": "Nicht genügend Daten in der Datei", + "CANCEL_IS_NOT_ALLOWED_HERE": "Abbrechen ist hier nicht erlaubt", + "B_DETECTED_CANCEL": "B-Knopf erkannt. Abbrechen?", + "ERROR_CANNOT_APPEND_FOLDER": "Fehler: Kann ein Verzeichnis nicht anhängen", + "ERROR_OVERWRITING_FILE_WITH_DIR": "Fehler: Überschreiben einer Datei\nmit einem Verzeichnis", + "ERROR_OVERWRITING_DIR_WITH_FILE": "Fehler: Überschreiben eines Verzeichnisses\nmit einer Datei", + "ERROR_CANNOT_OPEN_DESTINATION_FILE": "Fehler: Kann Zieldatei nicht öffnen", + "ERROR_NOT_ENOUGH_SPACE_AVAILABLE": "Fehler: Nicht genügend Speicherplatz verfügbar", + "ERROR_ONLY_FAT_FILES_CAN_BE_MOVED": "Fehler: Nur FAT-Dateien können\nverschoben werden", + "ERROR_DESTINATION_IS_PART_OF_ORIGIN": "Fehler: Ziel ist Teil vom Ursprung", + "ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME": "Ziel ist gleich Ursprung\nEinen anderen Namen auswählen?", + "CHOOSE_NEW_NAME": "Einen neuen Namen auswählen", + "OVERWRITE_FILES": "Datei(en) überschreiben", + "SKIP_FILES": "Datei(en) überspringen", + "OVERWRITE_ALL": "Alle überschreiben", + "SKIP_ALL": "Alle überspringen", + "DESTINATION_ALREADY_EXISTS": "Ziel ist bereits vorhanden:\n%s", + "CHOOSE_NEW_DESTINATION_NAME": "Einen neuen Zielnamen auswählen", + "COPY_OPERATION_IS_NOT_ALLOWED": "Kopiervorgang ist nicht zulässig", + "DESTINATION_EQUALS_ORIGIN": "Ziel ist gleich Ursprung", + "ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD": "Eintrag nicht gefunden: %s\nStattdessen in %s injizieren?", + "FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE": "File smaller than available space:\n%s (%s)\n%s (%s)\nContinue?", + "NO_USABLE_ENTRIES_FOUND": "No usable entries found.", + "BEAT_NO_ERROR": "No error", + "BEAT_END_OF_ACTION_LIST": "End of action list", + "BEAT_ABORTED_BY_USER": "Aborted by user", + "BEAT_FAILED_TO_READ_WRITE_FILE": "Failed to read/write file", + "BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF": "Attempted to write beyond end of file", + "BEAT_INVALID_PATCH_FILE": "Invalid patch file", + "BEAT_INVALID_INPUT_FILE": "Invalid input file", + "BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH": "Output file checksum mismatch", + "BEAT_FILE_CHECKSUM_FAILED": "File checksum failed", + "BEAT_EXPECTED_MORE_PATCH_DATA": "Expected more patch data", + "BEAT_OUT_OF_MEMORY": "Out of memory", + "BEAT_UNKNOWN_ERROR": "Unknown error", + "FAILED_TO_INITIALIZE_BPM_FILE": "Failed to initialize BPM file:\n%s", + "FAILED_TO_INITIALIZE_BPS_FILE": "Failed to initialize BPS file:\n%s", + "PATCH_SUCCESSFULLY_APPLIED": "Patch successfully applied", + "PATCHING_ABORTED_BY_USER": "Patching aborted by user", + "FAILED_TO_RUN_PATCH": "Failed to run patch:\n%s", + "DECOMPRESSING_DOT_CODE": "Decompressing .code...", + "DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Decompressing .code...\nB button detected. Cancel?", + "COMPRESSING_DOT_CODE": "Compressing .code...", + "COMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Compressing .code...\nB button detected. Cancel?", + "PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE": "The patch is most likely not intended for this file.", + "YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT": "You most likely applied the patch on the output file.", + "PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED": "The patch is technically valid,\nbut seems scrambled or malformed.", + "PATCH_IS_INVALID": "The patch is invalid.", + "FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT": "One or both files are bigger than 16MB.\nThe IPS format doesn't support that.", + "REQUESTED_FILE_PATH_WAS_INVALID": "Der angeforderte Dateipfad war ungültig.", + "PATCHING_CANCELED": "Patchen abgebrochen.", + "NOT_ENOUGH_MEMORY": "Nicht genügend Speicherplatz.", + "REGION_AMERICAS": "Amerika", + "REGION_AUSTRALIA": "Australien", + "REGION_BRAZIL": "Brasilien", + "REGION_CHINA": "China", + "REGION_EUROPE": "Europa", + "REGION_FRANCE": "Frankreich", + "REGION_GERMANY": "Deutschland", + "REGION_ITALY": "Italien", + "REGION_JAPAN": "Japan", + "REGION_KOREA": "Korea", + "REGION_SPAIN": "Spanien", + "REGION_TAIWAN": "Taiwan", + "REGION_UNKNOWN": "Unbekannt", + "REGION_UNITED_KINGDOM": "Vereinigtes Königreich", + "REGION_MIDDLE_EAST": "Mittlerer Osten", + "GENERATING_QR_CODE": "Generiere QR-Code...", + "REINITIALIZING_SD_CARD": "Initialisiere SD-Karte erneut...", + "DUMPING_STATE_TO_SD_CARD": "Dumpe Status auf SD-Karte...", + "PRESS_POWER_TO_TURN_OFF": "Drücke POWER um auszuschalten", + "CLEANING_UP_TITLES_PLEASE_WAIT": "Bereinige Titel, bitte warten...", + "ERROR_NOT_NCCH_FILE": "Fehler: Nicht eine NCCH-Datei", + "ERROR_FILE_IS_TOO_SMALL": "Fehler: Datei ist zu klein", + "ATTEMPT_FIX_THIS_TIME": "Versuche, diesmal zu korrigieren", + "ATTEMPT_FIX_ALWAYS": "Immer versuchen, zu korrigieren", + "ABORT_VERIFICATION": "Verfizierung abbrechen", + "ERROR_BAD_CRYPTO_FLAGS": "Fehler: Falsche Crypto-Flags", + "ERROR_BAD_EXEFS_HEADER": "Fehler: Fehlerhafter ExeFS-Header", + "ERROR_MISSING_EXTHEADER": "Fehler: Fehlender ExtHeader", + "ERROR_CRYPTO_NOT_SET_UP": "Fehler: Crypto nicht eingerichtet", + "PATH_NCCH_VERIFICATION_FAILED_INFO": "%s\nNCCH-Verifizierung fehlgeschlagen:\nExtHdr/ExeFS/RomFS: %s/%s/%s", + "OK": "erfolg", + "FAIL": "fehler", + "ERROR_NOT_NCSD_FILE": "Fehler: Nicht eine NCSD-Datei", + "PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nInhalt%lu (%08lX@%08lX):\nVerifizierung fehlgeschlagen", + "ERROR_PROBABLY_NOT_CIA_FILE": "Fehler: Wahrscheinlich nicht eine CIA-Datei", + "ERROR_TMD_PROBABLY_CORRUPTED": "Fehler: TMD wahrscheinlich beschädigt", + "PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nID %08lX (%08llX@%08llX)\nVerifizierung fehlgeschlagen", + "ERROR_CDN_TITLEKEY_NOT_FOUND": "Fehler: CDN-Titlekey nicht gefunden", + "DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE": "DLC-Inhalt fehlt\n\nAlle ignorieren und fortfahren?" +} diff --git a/resources/languages/en.json b/resources/languages/en.json new file mode 100644 index 000000000..e5f51c519 --- /dev/null +++ b/resources/languages/en.json @@ -0,0 +1,4 @@ +{ + "GM9_LANGUAGE": "English", + "GM9_TRANS_VER": 1 +} diff --git a/resources/languages/es.json b/resources/languages/es.json new file mode 100644 index 000000000..a9d87cf60 --- /dev/null +++ b/resources/languages/es.json @@ -0,0 +1,702 @@ +{ + "GM9_LANGUAGE": "Español", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%4$02lX/%3$02lX/%1$s%2$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ",", + "THOUSAND_SEPARATOR": ".", + "FIRM_TOO_BIG": "FIRM muy grande, imposible ejecutar", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nADVERTENCIA: No ejecutes FIRMs\nde fuentes no confiables\n \n¿Ejecutar FIRM?", + "NOT_BOOTABLE_FIRM": "No es un FIRM ejecutable.", + "FIRM_ENCRYPTED": "Este FIRM está cifrado.\n\n¿Desencriptar antes de ejecutarlo?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Crear una copia en %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Intentar ejecutarlo de todas formas", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Advertencia: Estás intentando\nejecutar un Firm desde una\nubicación no soportada.", + "ROOT": "[raíz]", + "LOADING": "CARGANDO...", + "PANE_N": "PANEL #%lu", + "CURRENT": "ACTUAL", + "DIR": "(dir)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(Disco RAM FAT)", + "GAME_VIRTUAL": "(Juego Virtual)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND Virtual)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND Virtual)", + "IMAGE_FAT": "(Imagen FAT)", + "XORPAD_VIRTUAL": "(XORpad Virtual)", + "MEMORY_VIRTUAL": "(Memoria Virtual)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Cartucho Virtual)", + "VRAM_VIRTUAL": "(VRAM Virtual)", + "SEARCH": "(Buscar)", + "TITLEMANAGER_VIRTUAL": "(Gest. Títulos Virtual)", + "LAB_SDCARD": "Tar. SD", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUAL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUAL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "CARTUCHO", + "LAB_GAME_IMAGE": "IMAGEN JUEGO", + "LAB_AESKEYDB_IMAGE": "IMAGEN AESKEYDB", + "LAB_BDRI_IMAGE": "IMAGEN BDRI", + "LAB_DISA_DIFF_IMAGE": "IMAGEN DISA/DIFF", + "LAB_MEMORY_VIRTUAL": "MEMORIA VIRTUAL", + "LAB_VRAM_VIRTUAL": "VRAM VIRTUAL", + "LAB_TITLE_MANAGER": "GESTOR DE TÍTULOS", + "LAB_LAST_SEARCH": "ÚLTIMA BÚSQUEDA", + "LAB_FAT_IMAGE": "IMAGEN FAT", + "LAB_BONUS_DRIVE": "DISCO EXTRA", + "LAB_RAMDRIVE": "DISCO RAM", + "LAB_NOLABEL": "SIN NOMBRE", + "N_BYTE": "%s Byte", + "BYTE": " Byte", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[PORTAPAPELES]", + "PLUS_N_MORE": "+ %lu más", + "MARK_DELETE_COPY": "L - MARCAR archivos (usar con ↑↓→←)\nX - BORRAR / [+R] RENOMBRAR\nY - COPIAR / [+R] CREAR\n", + "MARK_DELETE_PASTE": "L - MARCAR archivos (usar con ↑↓→←)\nX - BORRAR / [+R] RENOMBRAR\nY - PEGAR / [+R] CREAR\n", + "RELOCK_WRITE_PERMISSION": "R+Y - Bloquear escritura\n", + "UNMOUNT_IMAGE": "R+X - Desmontar imagen\n", + "UNMOUNT_SD": "R+B - Desmontar Tarjeta SD\n", + "REMOUNT_SD": "R+B - Montar tarjeta SD\n", + "DIRECTORY_OPTIONS": "R+A - Opciones de carpeta\n", + "DRIVE_OPTIONS": "R+A - Opciones de disco\n", + "MAKE_SCREENSHOT": "R+L - Capturar pantalla\n", + "PREV_NEXT_PANE": "R+←→ - Cambiar de panel\n", + "CLEAR_CLIPBOARD": "SELECT - Vaciar portapapeles\n", + "RESTORE_CLIPBOARD": "SELECT - Restaurar Portapapeles\n", + "REBOOT_POWEROFF_HOME": "START - Reiniciar / [+R] Apagar\nBotón HOME - Menú HOME", + "NO_EMUNAND": "No EmuNAND", + "REDNAND_SIZE_MIN": "Tamaño de RedNAND (mín)", + "GW_EMUNAND_SIZE_FULL": "Tamaño de EmuNAND GW (llena)", + "MULTINAND_SIZE_2X": "Tamaño MultiNAND (x2)", + "MULTINAND_SIZE_3X": "Tamaño MultiNAND (x3)", + "MULTINAND_SIZE_4X": "Tamaño MultiNAND (x4)", + "USER_INPUT": "Entrada del usuario...", + "AUTO": "Auto", + "16KB_CLUSTERS": "Asig. 16KB", + "32KB_CLUSTERS": "Asig. 32KB", + "64KB_CLUSTERS": "Asig. 64KB", + "SD_NOT_DETECTED": "Error: Tarjeta SD no detectada.", + "FORMAT_SD_CHOOSE_EMUNAND": "¿Formatear tarjeta SD (%lluMB)?\nEscoge tamaño de la EmuNAND:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "El tamaño de la tarjeta es %lluMB.\nIntroduce el tamaño (MB) de la EmuNAND:", + "FORMAT_SD_CHOOSE_CLUSTER": "¿Formatear tarjeta SD (%lluMB)?\nEscoge asignación de página:", + "FORMAT_SD_ENTER_LABEL": "¿Formatear tarjeta SD (%lluMB)?\nIntroduce nombre:", + "FORMAT_SD_FAILED": "¡Fallo al formatear la tarjeta SD!", + "REDNAND_TYPE": "Tipo de RedNAND", + "REDNAND_TYPE_MULTI": "Tipo de RedNAND (multiple)", + "REDNAND_TYPE_SINGLE": "Tipo de RedNAND (única)", + "GW_EMUNAND_TYPE": "Tipo de EmuNAND GW", + "DONT_SET_UP": "No configurar", + "CHOOSE_EMUNAND_TYPE": "Escoge el tipo de EmuNAND a configurar:", + "CLONE_SYSNAND_TO_REDNAND": "Clonar SysNAND a RedNAND?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "¡Fallo al clonar SysNAND a EmuNAND!", + "PRESS_A_TO_CONTINUE": "Presiona para continuar", + "HEXEDITOR_CONTROLS": "Controles Edit. Hex:\n\n↑↓→←(+R) - Desplazarse\nR+Y - Cambiar vista\nX - Buscar / Ir a...\nA - Modo Edición\nA+↑↓→← - Editar valor\nB - Salir\n", + "NOT_FOUND": "¡No se encontró!", + "GO_TO_OFFSET": "Ir al offset", + "SEARCH_FOR_STRING": "Buscar hilo", + "SEARCH_FOR_DATA": "Buscar datos", + "CURRENT_OFFSET_SELECT_ACTION": "Offset actual: %08lX\nSeleccionar acción:", + "CURRENT_OFFSET_ENTER_NEW": "Offset actual: %08lX\nIntroduce nuevo offset.", + "ENTER_SEARCH_REPEAT_SEARCH": "Introduce hilo a buscar.\n(R+X para repetir búsqueda)", + "MADE_EDITS_SAVE_CHANGES": "Haz cambiado %lu valor(es).\n¿Guardar cambios al archivo?", + "FAILED_WRITING_TO_FILE": "¡Fallo al guardar cambios!", + "CALCULATING_SHA_FAILED": "¡Fallo al calcular SHA-%s!", + "SHA_VERIFICATION_PASSED": "\n¡Éxito al verificar SHA!", + "SHA_VERIFICATION_FAILED": "\nFallo al verificar SHA", + "IDENTICAL_WITH_PREVIOUS": "\nIdentico al archivo anterior:\n", + "WRITE_SHA_FILE": "\n¿Guardar en archivo .SHA?", + "WRITE_SHA1_FILE": "\n¿Guardar en archivo .SHA1?", + "CALCULATING_CMAC_FAILED": "¡Fallo al calcular CMAC!", + "CMAC_VERIFICATION_PASSED": "¡Éxito al verificar CMAC!", + "CMAC_VERIFICATION_FAILED": "¡Fallo al verificar CMAC!", + "FIX_CMAC_IN_FILE": "\n¿Corregir CMAC en archivo?", + "FIXING_CMAC_FAILED": "¡Fallo al corregir CMAC!", + "COPY_ALL_SELECTED_ITEMS": "¿Copiar los %lu elementos seleccionados?", + "FAILED_COPYING_ITEM": "Fallo al copiar elemento", + "ITEMS_COPIED_TO_OUT": "%lu elementos copiados en %s", + "PATH_COPIED_TO_OUT": "%s\nCopiado en %s", + "CART_INIT_FAILED": "¡Fallo al iniciar el cartucho!", + "CART_DETECTED_SIZE_INPUT_BELOW": "Cartucho: %s\nTamaño detectado: %s\n\nIntroduce el tamaño del archivo volcado.", + "NDS_CART_DECRYPT_SECURE_AREA": "Cartucho: %s\nCartucho de NDS detectado\n¿Descifrar area asegurada?", + "FAILED_DUMPING_CART": "%s\nFallo al volcar el cartucho", + "PATH_DUMPED_TO_OUT": "%s\nArchivo volcado en %s", + "CREATED": "creado", + "MODIFIED": "modificado", + "ANALYZING_DRIVE": "Analizando disco, espera...", + "ANALYZING_DIR": "Analizando carpeta, espera...", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu archivos y %lu subcarpetas\nTamaño total: %s\n\nEspacio libre: %s\nEspacio usado: %s\nEspacio total: %s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu archivos y %lu subcarpetas\nTamaño total: %s", + "FILESIZE_X": "Tamaño del archivo: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %s solo lectura [%c] %s oculto\n[%c] %s sistema [%c] %s archivo\n[%c] %s virtual\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→← para cambiar atributos)\n", + "A_TO_CONTINUE": "( para continuar)", + "A_APPLY_B_CANCEL": "( Aplicar, Cancelar)", + "A_YES_B_NO": "( sí, no)", + "A_SELECT_B_CANCEL": "( seleccionar, cancelar)", + "HOLD_B_TO_CANCEL": "(mantén B para cancelar)", + "FAILED_TO_SET_ATTRIBUTES": "¡Fallo al establecer atributos!", + "NAND_IMAGE_OPTIONS": "Opciones de imágen NAND...", + "CTRNAND_OPTIONS": "Opciones de CTRNAND...", + "MOUNT_FAT_IMAGE": "Montar como imagen FAT", + "CIA_IMAGE_OPTIONS": "CIA opciones de imagen...", + "NCSD_IMAGE_OPTIONS": "NCSD opciones de imagen...", + "NCCH_IMAGE_OPTIONS": "NCCH opciones de imagen...", + "MOUNT_AS_EXEFS_IMAGE": "Montar como imagen EXEFS", + "MOUNT_AS_ROMFS_IMAGE": "Montar como imagen ROMFS", + "TMD_FILE_OPTIONS": "Opciones de archivo TMD...", + "TMD_CDN_OPTIONS": "Opciones de TMD/CDN...", + "TMD_TWL_OPTIONS": "Opciones de archivo TMD/TWL...", + "MANAGE_TITLE": "Gestionar Título...", + "BOSS_FILE_OPTIONS": "Opciones de archivo BOSS...", + "DECRYPT_NUS_CDN_FILE": "Descifrar archivo NUS/CDN", + "SHOW_SMDH_TITLE_INFO": "Mostrar información de título SMDH", + "NDS_IMAGE_OPTIONS": "NDS opciones de imagen...", + "GBA_IMAGE_OPTIONS": "GBA opciones de imagen...", + "TICKET_OPTIONS": "Opciones de ticket...", + "TAD_IMAGE_OPTIONS": "TAD opciones de imagen...", + "SHOW_3DSX_TITLE_INFO": "Mostrar información del título 3DSX", + "FIRM_IMAGE_OPTIONS": "FIRM opciones de imagen...", + "AGBSAVE_OPTIONS": "Opciones AGBSAVE...", + "DUMP_GBA_VC_SAVE": "Volcar guardado de VC GBA", + "TICKET_DB_OPTIONS": "Opciones de Ticket.db...", + "MOUNT_AS_DIFF_IMAGE": "Montar como imagen DIFF", + "MOUNT_AS_DISA_IAMGE": "Montar como imagen DISA", + "INSTALL_CIFINISH_BIN": "Instalar cifinish.bin", + "TITLEKEY_OPTIONS": "Titlekey options...", + "AESKEYDB_OPTIONS": "Opciones de AESkeydb...", + "BUILD_X": "Generar %s", + "NCCHINFO_OPTIONS": "Opciones de NCCHinfo...", + "EXECUTE_GM9_SCRIPT": "Ejecutar script GM9", + "FONT_OPTIONS": "Opciones de fuente...", + "LANGUAGE_OPTIONS": "Opciones de idioma...", + "VIEW_PNG_FILE": "Ver archivo PNG", + "REBUILD_NCSD_HEADER": "Reconstruir cabecera NCSD", + "SHOW_IN_HEXEDITOR": "Mostrar en Hexeditor", + "CALCULATE_SHA256": "Calcular SHA-256", + "CALCULATE_SHA1": "Calcular SHA-1", + "SHOW_FILE_INFO": "Mostrar información del archivo", + "SHOW_IN_TEXTVIEWER": "Mostrar en Textviewer", + "CALCULATE_CMAC": "Calcular CMAC", + "COPY_TO_OUT": "Copia a %s", + "DUMP_TO_OUT": "Volcar a %s", + "INJECT_DATA_AT_OFFSET": "Inyectar datos @offset", + "OPEN_THIS_FOLDER": "Abrir esta carpeta", + "OPEN_CONTAINING_FOLDER": "Abrir carpeta contenedora", + "OPEN_TITLE_FOLDER": "Abrir carpeta de título", + "PATH_N_FILES_SELECTED": "%s\n(%lu archivos seleccionados)", + "CHECK_CURRENT_CMAC_ONLY": "Comprobar sólo CMAC actual", + "VERIFY_CMAC_FOR_ALL": "Verificar CMAC para todos", + "FIX_CMAC_FOR_ALL": "Corregir CMAC para todos", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%lu archivos correctos/corregidos/total\n%lu/%lu no tienen CMAC", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%lu archivos verificados\n%lu/%lu archivos corregidos", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%lu archivos verificados\n%lu/%lu no tienen CMAC", + "N_OF_N_FILES_VERIFIED": "%lu/%lu archivos verificados", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "¿Inyectar datos de %s?\nEspecifica el offset deseado.", + "FAILED_INJECTING_PATH": "Fallo al indectar %s", + "MOUNT_CXI_NDS_TO_DRIVE": "Montar CXI/NDS a disco", + "MOUNT_IMAGE_TO_DRIVE": "Montar imagen a disco", + "RESTORE_SYSNAND_SAFE": "Restaurar SysNAND (seguro)", + "UPDATE_EMBEDDED_BACKUP": "Actualizar respaldo integrado", + "SHOW_TITLE_INFO": "Mostrar información de título", + "DECRYPT_FILE": "Descifrar archivo (...)", + "DECRYPT_FILE_OUT": "Descifrar archivo (%s)", + "ENCRYPT_FILE": "Cifrar archivo (...)", + "ENCRYPT_FILE_OUT": "Cifrar archivo (%s)", + "BUILD_CIA_FROM_FILE": "Generar CIA desde archivo", + "BUILD_CIA_STANDARD": "Generar CIA (estándar)", + "BUILD_CIA_LEGIT": "Generar CIA (legítimo)", + "DUMP_CXI_NDS_FILE": "Volcar archivo CXI/NDS", + "INSTALL_GAME_IMAGE": "Instalar imagen de juego", + "INSTALL_TICKET": "Instalar ticket", + "DUMP_TICKET_FILE": "Volcar archivo de ticket", + "UNINSTALL_TITLE": "Desinstalar título", + "VERIFY_FILE": "Verificar archivo", + "TRANSFER_IMAGE_TO_CTRNAND": "Transferir imagen a CTRNAND", + "INJECT_TO_H_AND_S": "Inyectar a S&S", + "TRIM_FILE": "Recortar archivo", + "RENAME_FILE": "Renombrar archivo", + "BUILD_XORPADS_SD": "Generar XORPads (salida DS)", + "BUILD_XORPADS_INPLACE": "Generar XORpads (en sitio)", + "EXTRACT_X": "Extraer %s", + "INIT_X": "Iniciar %s", + "INSTALL_X": "Instalar %s", + "INSTALL_FIRM": "Instalar FIRM", + "BOOT_FIRM": "Ejecutar FIRM", + "SET_AS_ACTIVE_FONT": "Establecer como fuente activa", + "SET_AS_ACTIVE_LANGUAGE": "Establecer como idioma activo", + "DUMP_BA_VC_SAVE": "Volcar guardado de VC GBA", + "INJECT_GBA_VC_SAVE": "Inyectar guardado de VC GBA", + "SET_AS_DEFAULT": "Establecer como predeterminado", + "MOUNTING_IMAGE_FAILED": "Fallo al montar imagen", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nMontado como disco %s\n¿Entrar a directorio?", + "DECRYPT_TO_OUT": "Descifrar a %s", + "DECRYPT_INPLACE": "Descfirar en sitio", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "¿Descifrar los %lu archivos seleccionados?", + "TRYING_TO_DECRYPT_N_FILES": "Intentando descifrar %lu archivos...", + "DECRYPTION_FAILED_CONTINUE": "Fallo al descifrar\n\n¿Continuar?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu archivos descifrados\n%lu/%lu sin encripción\n%lu/%lu no son del mismo tipo", + "N_OF_N_FILES_DECRYPTED": "%lu/%lu archivos descifrados", + "N_FILES_WRITTEN_TO_OUT": "%lu archivos escritos en %s", + "FILE_NOT_ENCRYPTED": "Archivo no cifrado", + "DECRYPTION_SUCCESS": "Éxito al descifrar", + "DECRYPTION_FAILED": "Fallo al descifrar", + "PATH_DECRYPTED_TO_OUT": "%s\nDescifrado a %s", + "ENCRYPT_TO_OUT": "Cifrar a %s", + "ENCRYPT_INPLACE": "Cifrar en sitio", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "¿Intentar cifrar los %lu archivos seleccionados?", + "TRYING_TO_ENCRYPT_N_FILES": "Intentando cifrar %lu archivos...", + "ENCRYPTION_FAILED_CONTINUE": "El cifrado ha fallado\n \n¿Continuar?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu archivos cifrados ok\n%lu/%lu no son del mismo tipo", + "N_OF_N_FILES_ENCRYPTED": "%lu/%lu archivos cifrados correctamente", + "ENCRYPTION_SUCCESS": "Cifrado con éxito", + "ENCRYPTION_FAILED": "Fallo al cifrar", + "PATH_ENCRYPTED_TO_OUT": "%s\nCifrado a %s", + "TRY_TO_PROCESS_N_SELECTED_FILES": "¿Intentar procesar los %lu archivos seleccionados?", + "PATH_BUILD_TYPE_FAILED_CONTINUE": "%s\nFalló al construir %s\n \n¿Continuar?", + "N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE": "%lu/%lu %ss construidos correctamente\n%lu%lu no son del mismo tipo", + "N_OF_N_TYPES_BUILT": "%lu/%lu %ss construidos correctamente", + "N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED": "Falló al convertir %lu archivo(s).\nSe recomienda verificarlos.", + "PATH_TYPE_BUILT_TO_OUT": "%s\n%s construido a %s", + "PATH_TYPE_BUILD_FAILED": "%s\nFalló al construir %s", + "FILE_FAILED_CONVERSION_VERIFY_NOW": "La conversión del archivo falló.\n \n¿Verificar ahora?", + "VERIFICATION_SUCCESS": "Verificación exitosa", + "VERIFICATION_FAILED": "Verificación fallida", + "CONTENT_IS_MISSING": "Falta el contenido", + "INSTALL_TO_SYSNAND": "Instalar a SysNAND", + "INSTALL_TO_EMUNAND": "Instalar a EmuNAND", + "TRY_TO_INSTALL_N_SELECTED_FILES": "¿Intentar instalar los %lu archivos seleccionados?", + "TRYING_TO_INSTALL_N_FILES": "Intentando instalar %lu archivos...", + "INSTALL_FAILED_CONTINUE": "Error al instalar\n \n¿Continuar?", + "N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files installed ok\n%lu/%lu not of same type", + "N_OF_N_FILES_INSTALLED": "%lu/%lu files installed ok", + "INSTALL_SUCCESS": "Install success", + "INSTALL_FAILED": "Install failed", + "FILE_FAILED_INSTALL_VERIFY_NOW": "file failed install.\n \nVerify now?", + "KEEP_TICKET_AND_SAVEGAME": "Keep ticket & savegame", + "UNINSTALL_EVERYTHING": "Uninstall everything", + "ABORT_UNINSTALL": "Abort uninstall", + "UNINSTALL_N_SELECTED_TITLES": "Uninstall %lu selected titles?", + "UNINSTALL_SELECTED_TITLE": "Uninstall selected title?", + "N_OF_N_TITLES_UNINSTALLED": "%lu/%lu titles uninstalled", + "UNINSTALLING_PLEASE_WAIT": "Uninstalling, please wait...", + "UNINSTALL_FAILED": "Uninstall failed!", + "TRY_TO_VERIFY_N_SELECTED_FILES": "Try to verify all %lu selected files?", + "VERIFICATION_FAILED_CONTINUE": "Verification failed\n \nContinue?", + "N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files verified ok\n%lu/%lu not of same type", + "VERIFYING_FILE_PLEASE_WAIT": "Verifying file, please wait...", + "NAND_VALIDATION_SUCCESS": "NAND validation success", + "NAND_VALIDATION_FAILED": "NAND validation failed", + "DUMP_FOR_N_SELECTED_FILES": "Dump for all %lu selected files?", + "N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL": "%lu/%lu legit tickets dumped.\n \nAttempt to dump all tickets?", + "N_OF_N_TICKETS_DUMPED_TO_OUT": "%lu/%lu tickets dumped to %s", + "PATH_TICKET_DUMPED_TO_OUT": "%s\nTicket dumped to %s", + "LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS": "%s\nLegit ticket not found.\n \nDump anyways?", + "DUMP_TICKET_FAILED": "Ticket de descarga fallido!", + "BUILDING_X": "Creando %s...", + "BUILDING_X_SYSNAND": "Creando %s (SysNAND)...", + "BUILDING_X_EMUNAND": "Creando %s (EmuNAND)...", + "PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED": "%s\n%lu/%lu files processed\n%lu/%lu files ignored", + "PATH_N_OF_N_FILES_PROCESSED": "%s\n%lu/%lu files processed", + "BUILD_DATABASE_SUCCESS": "Build database success.", + "BUILD_DATABASE_FAILED": "Build database failed.", + "TRY_TO_TRIM_N_SELECTED_FILES": "Try to trim all %lu selected files?", + "TRIMMING_FAILED_CONTINUE": "Recorte fallido\n\nContinuar?","N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED": "%lu/%lu files trimmed ok\n%lu/%lu not of same type\n%s saved", + "N_OF_N_FILES_TRIMMED_X_SAVED": "%lu/%lu files trimmed ok\n%s saved", + "FILE_CANT_BE_TRIMMED": "File can't be trimmed.", + "FILE_ALREADY_TRIMMED": "File is already trimmed.", + "PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE": "%s\nCurrent size: %s\nTrimmed size: %s\nDifference: %s\n \nTrim this file?", + "TRIMMING_FAILED": "Trimming failed.", + "PATH_TRIMMED_BY_X": "%s\nTrimmed by %s.", + "TRY_TO_RENAME_N_SELECTED_FILES": "Try to rename all %lu selected files?", + "N_OF_N_RENAMED": "%lu/%lu renamed ok", + "COULD_NOT_RENAME_TO_GOOD_NAME": "Could not rename to good name", + "SYSNAND_H_AND_S_INJECT": "SysNAND H&S inject", + "EMUNAND_H_AND_S_INJECT": "EmuNAND H&S inject", + "H_AND_S_INJECT_SUCCESS": "H&S inject success", + "H_AND_S_INJECT_FAILURE": "H&S inject failure", + "TRY_EXTRACT_ALL_N_SELECTED_FILES": "Try to extract all %lu selected files?", + "N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files extracted ok\n%lu/%lu not of same type", + "N_OF_N_FILES_EXTRACTED": "%lu/%lu files extracted ok", + "EXTRACTING_DOT_CODE": "Extracting .code, please wait...", + "PATH_EXT_EXTRACTED_TO_OUT": "%s\n%s extracted to %s", + "DOT_CODE_EXTRACT_FAILED": ".code extract failed", + "TRANSFER_TO_SYSNAND": "Transferir a SysNAND", + "TRANSFER_TO_EMUNAND": "Transferir a SysNAND", + "CTRNAND_TRANSFER_SUCCESS": "CTRNAND transfer success", + "CTRNAND_TRANSFER_FAILED": "CTRNAND transfer failed", + "NO_VALID_DESTINATION_FOUND": "No valid destination found", + "NAND_RESTORE_SUCCESS": "NAND restore success", + "NAND_RESTORE_FAILED": "NAND restore failed", + "REBUILD_NCSD_SUCCESS": "Rebuild NCSD success", + "REBUILD_NCSD_FAILED": "Rebuild NCSD failed", + "PATH_NCCHINFO_PADGEN_SUCCESS": "%s\nNCCHinfo padgen success%cOutput dir: %s", + "PATH_NCCHINFO_PADGEN_FAILED": "%s\nNCCHinfo padgen failed%c%0.0s", + "UPDATING_EMBEDDED_BACKUP": "Updating embedded backup...", + "BACKUP_UPDATE_NOT_REQUIRED": "Backup update: not required", + "BACKUP_UPDATE_COMPLETED": "Backup update: completed", + "BACKUP_UPDATE_FAILED": "Backup update: failed!", + "WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK": "Warning: Keys are not verified.\nContinue on your own risk?", + "AESKEYDB_INIT_SUCCESS": "AESkeydb init success", + "AESKEYDB_INIT_FAILED": "AESkeydb init failed", + "AESKEYDB_INSTALL_SUCCESS": "AESkeydb install success", + "AESKEYDB_INSTALL_FAILED": "AESkeydb install failed", + "INSTALL_TO_FIRM0": "Instalar a FIRM0", + "INSTALL_TO_FIRM1": "Instalar a FIRM1", + "INSTALL_TO_BOTH": "Instalar a ambos", + "PATH_N_KB_INSTALL_TO_SYSNAND": "%s (%dkB)\nInstall to SysNAND?", + "PATH_N_KB_INSTALL_SUCCESS": "%s (%dkB)\nInstall success", + "PATH_N_KB_INSTALL_FAILED": "%s (%dkB)\nInstall failed", + "WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS": "Warning: Do not run scripts\nfrom untrusted sources.\n \nExecute script?", + "SCRIPT_EXECUTE_SUCCESS": "Script execute success", + "SCRIPT_EXECUTE_FAILURE": "Script execute failure", + "ERROR_CANNOT_VIEW_FILE": "Error: Cannot view file\n(Hint: maybe it's too big)", + "SAVEGAME_DUMPED_TO_OUT": "Savegame dumped to %s.", + "SAVEGAME_DUMP_FAILED": "Savegame dump failed!", + "GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD": "GBA VC savegame has to\nbe in the clipboard.", + "SAVEGAME_INJECT_SUCCESS": "Savegame inject success.", + "SAVEGAME_INJECT_FAILED": "Savegame inject failed!", + "FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Font will be active on next boot", + "LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Language will be active on next boot", + "HOME_MORE_MENU_SELECT_ACTION": "HOME more... menu.\nSelect action:", + "SD_FORMAT_MENU": "SD format menu", + "BONUS_DRIVE_MENU": "Bonus drive setup", + "SWITCH_EMUNAND": "Cambiar EmuNAND", + "BUILD_SUPPORT_FILES": "Build support files", + "RESTORE_H_AND_S": "Restore H&S", + "SET_RTC_DATE_TIME": "Set RTC date&time", + "CONFGURE_BRIGHTNESS": "Configure brightness", + "CALIBRATE_TOUCHSCREEN": "Calibrate touchscreen", + "SYSTEM_INFO": "System info", + "SHOW_README": "Show ReadMe", + "INITIALIZING_SD_FAILED_RETRY": "Initializing SD card failed! Retry?", + "SETUP_FAILED": "Setup failed!", + "CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT": "Current EmuNAND offset is %06lX.\nSwitch to next offset?", + "BUILT_IN_OUT_STATUSES": "Built in %s:\n \n%-18.18s %s\n%-18.18s %s\n%-18.18s %s", + "OK_SYS_EMU": "OK (Sys&Emu)", + "OK_SYS": "OK (Sys)", + "FAILED": "Failed", + "RESTORE_H_AND_S_EMUNAND": "Restore H&S (EmuNAND)", + "RESTORE_H_AND_S_SYSNAND": "Restore H&S (SysNAND)", + "TITLE_SET_RTC_DATE_TIME": "Set RTC date&time:", + "NEW_RTC_DATE_TIME_IS_TIME": "New RTC date&time is:\n%s\n \nHint: HOMEMENU time needs\nmanual adjustment after\nsetting the RTC.", + "TOUCHSCREEN_CALIBRATION_SUCCESS": "Touchscreen calibration success!", + "TOUCHSCREEN_CALIBRATION_FAILED": "Touchscreen calibration failed!", + "GODMODE9_README_TOC": "GodMode9 ReadMe Table of Contents", + "ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW": "Essential files backup not found.\nCreate one now?", + "BACKUP_EMBEDDED_WRITTEN_TO_OUT": "Backup embedded in SysNAND\nand written to %s.", + "RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW": "RTC date&time seems to be\nwrong. Set it now?", + "RESUME_GODMODE9": "Reanudar GodMode9", + "RESUME_BOOTLOADER": "Resume bootloader", + "SELECT_PAYLOAD": "Select payload...", + "SELECT_SCRIPT": "Seleccionar script...", + "POWEROFF_SYSTEM": "Poweroff system", + "REBOOT_SYSTEM": "Reiniciar sistema", + "FLAVOR_BOOTLOADER_SELECT_OPTION": "%s bootloader menu.\nSelect action:", + "BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD": "Bootloader payloads menu.\nSelect payload:", + "BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT": "Bootloader scripts menu.\nSelect script:", + "NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9": "No bootable FIRM found.\nNow resuming GodMode9...", + "OUT_OF_MEMORY": "Out of memory.", + "INVALID_DIRECTORY_OBJECT": "Invalid directory object", + "INVALID_ROOT_DIRECTORY": "Invalid root directory.", + "WRITE_PERMISSIONS_WERE_CHANGED_RELOCK": "Write permissions were changed.\nRelock them?", + "OPEN_TITLE_MANAGER": "Open title manager", + "SEARCH_FOR_FILES": "Search for files...", + "FIX_CMACS_FOR_DRIVE": "Fix CMACs for drive", + "SHOW_DIRECTORY_INFO": "Show directory info", + "SHOW_DRIVE_INFO": "Show drive info", + "FAILED_SETTING_UP_TITLE_MANAGER": "Failed setting up title manager!", + "SEARCH_FILE_ENTER_SEARCH_BELOW": "Search %s?\nEnter search below.", + "FOUND_N_RESULTS": "Found %lu results.", + "FIX_CMACS_FOR_DRIVE_FINISHED": "Fix CMACs for drive finished.", + "FAILED_TO_ANALYZE_DRIVE": "Failed to analyze drive\n", + "FAILED_TO_ANALYZE_DIR": "Failed to analyze dir\n", + "NOT_ALLOWED_IN_VIRTUAL_PATH": "Not allowed in virtual path", + "DELETE_N_PATHS": "Delete %lu path(s)?", + "DELETING_FILES_PLEASE_WAIT": "Deleting files, please wait...", + "FAILED_DELETING_N_OF_N_PATHS": "Failed deleting %lu/%lu path(s)", + "DELETE_FILE": "Delete \"%s\"?", + "FAILED_DELETING_PATH": "Failed deleting:\n%s", + "NOT_ALLOWED_IN_SEARCH_DRIVE": "Not allowed in search drive", + "NOT_ALLOWED_IN_VIRTUAL_GAME_PATH": "Not allowed in virtual game path", + "NOT_ALLOWED_IN_XORPAD_DRIVE": "Not allowed in XORpad drive", + "NOT_ALLOWED_IN_GAMECART_DRIVE": "Not allowed in gamecart drive", + "NOT_ALLOWED_IN_ALIAS_PATH": "Not allowed in alias path", + "COPY_PATHS": "Copy path(s)", + "MOVE_PATHS": "Move path(s)", + "PASTE_FILE_HERE": "Paste \"%s\" here?", + "PASTE_N_PATHS_HERE": "Paste %lu paths here?", + "FAILED_COPYING_PATH_PROCESS_REMAINING": "Failed copying path:\n%s\nProcess remaining?", + "FAILED_COPYING_PATH": "Failed copying path:\n%s", + "FAILED_MOVING_PATH_PROCESS_REMAINING": "Failed moving path:\n%s\nProcess remaining?", + "FAILED_MOVING_PATH": "Failed moving path:\n%s", + "RENAME_FILE_ENTER_NEW_NAME_BELOW": "Rename %s?\nEnter new name below.", + "FAILED_RENAMING_PATH": "Failed renaming path:\n%s", + "CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE": "Create a new entry here?\nSelect type.", + "CREATE_A_FOLDER": "Create a folder", + "CREATE_A_DUMMY_FILE": "Create a dummy file", + "CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW": "Create a new folder here?\nEnter name below.", + "CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW": "Create a new file here?\nEnter name below.", + "CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW": "Create a new %s here?\nEnter file size below.", + "FAILED_CREATING_FOLDER_PATH": "Failed creating folder:\n%s", + "FAILED_CREATING_FILE_PATH": "Failed creating file:\n%s", + "TITLE_MANAGER": "Title manager", + "BRICK_MY_3DS": "Brick my 3DS", + "LANGUAGE": "Idioma...", + "SCRIPTS": "Scripts...", + "PAYLOADS": "Payloads...", + "MORE": "More...", + "BRACKET_MORE": "[more...]", + "HOME_BUTTON_PRESSED_SELECT_ACTION": "HOME button pressed.\nSelect action:", + "POWER_BUTTON_PRESSED_SELECT_ACTION": "POWER button pressed.\nSelect action:", + "1_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "4_DRIVE_NAND_TWL": "[4:] NAND / TWL", + "A_DRIVE_SD_CARD": "[A:] SD CARD", + "B_DRIVE_SD_CARD": "[B:] SD CARD", + "TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE": "Title manager menu.\nSelect titles source:", + "LANGUAGES_DIRECTORY_NOT_FOUND": "Languages directory not found.\n(default path: 0:/gm9/%s)", + "SCRIPTS_DIRECTORY_NOT_FOUND": "Scripts directory not found.\n(default path: 0:/gm9/%s)", + "HOME_LANGUAGE_MENU_SELECT_LANGUAGE": "HOME language... menu.\nSelect language:", + "HOME_SCRIPTS_MENU_SELECT_SCRIPT": "HOME scripts... menu.\nSelect script:", + "PAYLOADS_DIRECTORY_NOT_FOUND": "Payloads directory not found.\n(default path: 0:/gm9/%s)", + "HOME_PAYLOADS_MENU_SELECT_PAYLOAD": "HOME payloads... menu.\nSelect payload:", + "UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT": "!Unexpected SD card removal!\n \nTo prevent data loss, unmount\nbefore ejecting the SD card.", + "FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT": "%s scripts menu.\nSelect script:", + "COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP": "Compiled as script autorunner\nbut no script provided.\n \nDerp!", + "KEYBOARD_CONTROLS_DETAILS": "Keyboard Controls:\n \n←/→ - Move cursor\nR - Caps / Capslock\nX - Delete char\nY - Insert char\nA - Submit\nB - Cancel\n \nSELECT switches to\nclassic prompt", + "TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS": "Touch the red crosshairs to\ncalibrate your touchscreen.\n \nUse the stylus for best\nresults!", + "INVALID": "INVALID", + "TO_PROCEED_ENTER_THIS": "To proceed, enter this:", + "TO_PROCEED_HOLD_X": "To proceed, hold :", + "N_MORE": " [%d more]", + "CANCEL": "cancel", + "R_FAST_SCROLL_L_CLEAR_DATA": "R - (↑↓) fast scroll\nL - clear data", + "X_REMOVE_CHAR_Y_INSERT_CHAR": "X - remove char\nY - insert char", + "ETA_N_MIN_N_SEC": "ETA %02llum%02llus", + "BRIGHTNESS_CONTROLS": "[←] Decrease brightness\n[→] Increase brightness\n \n[X] Use volume slider control\n[A] Set current brightness\n[B] Cancel", + "SEARCHING_PLEASE_WAIT": "Searching, please wait...", + "RENAME_TO_GOOD_NAME": "Rename to good name?", + "SD_WRITE_PROTECTED_CANT_CONTINUE": "SD card is write protected!\nCan't continue.", + "SYSNAND_LVL_N": "SysNAND (lvl%lu)", + "EMUNAND_LVL_N": "EmuNAND (lvl%lu)", + "GAME_IMAGES": "game images", + "GAMECART_SAVES": "gamecart saves", + "IMAGES": "images", + "MEMORY_AREAS": "memory areas", + "SD_SYSTEM_DATA": "SD system data", + "SD_CARD": "Tarjeta SD", + "RAM_DRIVE": "RAM drive", + "WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW": "Writing to %s is locked!\nUnlock it now?", + "UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED": "Unlock write permission for\n%s is not allowed.", + "ENABLE_BASE_WRITE": "You want to enable base\nwriting permissions.", + "ENABLE_SD_WRITE": "You want to enable SD card\nwriting permissions.", + "ENABLE_IMAGE_WRITE": "You want to enable image\nwriting permissions.", + "ENABLE_RAM_DRIVE_WRITE": "You want to enable RAM drive\nwriting permissions.", + "ENABLE_EMUNAND_0_WRITE": "You want to enable EmuNAND\nlvl0 writing permissions.", + "ENABLE_SYSNAND_0_WRITE": "You want to enable SysNAND\nlvl0 writing permissions.", + "ENABLE_EMUNAND_1_WRITE": "You want to enable EmuNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nrecoverable system data,\nuser data & savegames.", + "ENABLE_SYSNAND_1_WRITE": "You want to enable SysNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nsystem data, installations,\nuser data & savegames.", + "ENABLE_GAMECART_SAVE_WRITE": "You want to enable gamecart\nsave writing permissions.", + "ENABLE_SYSNAND_2_WRITE": "!Better be careful!\n \nYou want to enable SysNAND\nlvl2 writing permissions.\n \nThis enables you to modify\nirrecoverable system data!", + "ENABLE_MEMORY_WRITE": "!Better be careful!\n \nYou want to enable memory\nwriting permissions.\n \nWriting to certain areas may\nlead to unexpected results.", + "ENABLE_SD_DATA_WRITE": "!THIS IS NOT RECOMMENDED!\n \nYou want to enable SD data\nwriting permissions.\n \nEverything here is encrypted.\nIt is recommended to use the\nA:/B: drives for modification\nof installations, user data &\nsavegames instead.", + "ENABLE_SYSNAND_3_WRITE": "!THIS IS YOUR ONLY WARNING!\n \nYou want to enable SysNAND\nlvl3 writing permissions.\n \nThis enables you to OVERWRITE\nyour bootloader installation,\nessential system files and/or\nBRICK your console!", + "UNLOCK_WRITE_NOT_ALLOWED": "Unlock write permission is not allowed.", + "CANT_UNLOCK_WRITE_TRY_GODMODE9": "Can't unlock write permission.\nTry GodMode9 instead!", + "ERROR_SD_TOO_SMALL": "Error: SD card is too small", + "WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA": "!WARNING!\n \nProceeding will format this SD.\nThis will irreversibly delete\nALL data on it.", + "FORMAT_BONUS_DRIVE_DELETE_ALL_DATA": "Format the bonus drive?\nThis will irreversibly delete\nALL data on it.", + "FORMATTING_SD_PLEASE_WAIT": "Formatting SD, please wait...", + "FORMATTING_DRIVE_PLEASE_WAIT": "Formatting drive, please wait...", + "ERROR_SD_CARD_IO_FAILURE": "Error: SD card i/o failure", + "FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK": "File is currently mounted.\nUnmount to unlock?", + "ERROR_CANT_INJECT_FILE_INTO_ITSELF": "Error: Can't inject file into itself", + "OPERATION_WOULD_WRITE_BEYOND_EOF": "Operation would write beyond end of file", + "NOT_ENOUGH_DATA_IN_FILE": "Not enough data in file", + "CANCEL_IS_NOT_ALLOWED_HERE": "Cancel is not allowed here", + "B_DETECTED_CANCEL": "B button detected. Cancel?", + "ERROR_CANNOT_APPEND_FOLDER": "Error: Cannot append a folder", + "ERROR_OVERWRITING_FILE_WITH_DIR": "Error: Overwriting file with dir", + "ERROR_OVERWRITING_DIR_WITH_FILE": "Error: Overwriting dir with file", + "ERROR_CANNOT_OPEN_DESTINATION_FILE": "Error: Cannot open destination file", + "ERROR_NOT_ENOUGH_SPACE_AVAILABLE": "Error: Not enough space available", + "ERROR_ONLY_FAT_FILES_CAN_BE_MOVED": "Error: Only FAT files can be moved", + "ERROR_DESTINATION_IS_PART_OF_ORIGIN": "Error: Destination is part of origin", + "ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME": "Destination equals origin\nChoose another name?", + "CHOOSE_NEW_NAME": "Choose new name", + "OVERWRITE_FILES": "Overwrite file(s)", + "SKIP_FILES": "Skip file(s)", + "OVERWRITE_ALL": "Overwrite all", + "SKIP_ALL": "Omitir todo", + "DESTINATION_ALREADY_EXISTS": "Destination already exists:\n%s", + "CHOOSE_NEW_DESTINATION_NAME": "Choose new destination name", + "COPY_OPERATION_IS_NOT_ALLOWED": "Copy operation is not allowed", + "DESTINATION_EQUALS_ORIGIN": "Destination equals origin", + "ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD": "Entry not found: %s\nInject into %s instead?", + "FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE": "File smaller than available space:\n%s (%s)\n%s (%s)\nContinue?", + "NO_USABLE_ENTRIES_FOUND": "No usable entries found.", + "BEAT_NO_ERROR": "No error", + "BEAT_END_OF_ACTION_LIST": "End of action list", + "BEAT_ABORTED_BY_USER": "Aborted by user", + "BEAT_FAILED_TO_READ_WRITE_FILE": "Failed to read/write file", + "BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF": "Attempted to write beyond end of file", + "BEAT_INVALID_PATCH_FILE": "Invalid patch file", + "BEAT_INVALID_INPUT_FILE": "Invalid input file", + "BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH": "Output file checksum mismatch", + "BEAT_FILE_CHECKSUM_FAILED": "File checksum failed", + "BEAT_EXPECTED_MORE_PATCH_DATA": "Expected more patch data", + "BEAT_OUT_OF_MEMORY": "Out of memory", + "BEAT_UNKNOWN_ERROR": "Unknown error", + "FAILED_TO_INITIALIZE_BPM_FILE": "Failed to initialize BPM file:\n%s", + "FAILED_TO_INITIALIZE_BPS_FILE": "Failed to initialize BPS file:\n%s", + "PATCH_SUCCESSFULLY_APPLIED": "Patch successfully applied", + "PATCHING_ABORTED_BY_USER": "Patching aborted by user", + "FAILED_TO_RUN_PATCH": "Failed to run patch:\n%s", + "DECOMPRESSING_DOT_CODE": "Decompressing .code...", + "DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Decompressing .code...\nB button detected. Cancel?", + "COMPRESSING_DOT_CODE": "Compressing .code...", + "COMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Compressing .code...\nB button detected. Cancel?", + "PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE": "The patch is most likely not intended for this file.", + "YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT": "You most likely applied the patch on the output file.", + "PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED": "The patch is technically valid,\nbut seems scrambled or malformed.", + "PATCH_IS_INVALID": "The patch is invalid.", + "FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT": "One or both files are bigger than 16MB.\nThe IPS format doesn't support that.", + "REQUESTED_FILE_PATH_WAS_INVALID": "The requested file path was invalid.", + "PATCHING_CANCELED": "Patching canceled.", + "NOT_ENOUGH_MEMORY": "Not enough memory.", + "REGION_AMERICAS": "América", + "REGION_AUSTRALIA": "Australia", + "REGION_BRAZIL": "Brasil", + "REGION_CHINA": "China", + "REGION_EUROPE": "Europa", + "REGION_FRANCE": "Francia", + "REGION_GERMANY": "Alemania", + "REGION_ITALY": "Italia", + "REGION_JAPAN": "Japón", + "REGION_KOREA": "Corea", + "REGION_SPAIN": "España", + "REGION_TAIWAN": "Taiwán", + "REGION_UNKNOWN": "Desconocido", + "REGION_UNITED_KINGDOM": "Reino Unido", + "REGION_MIDDLE_EAST": "Oriente Medio", + "GENERATING_QR_CODE": "Generating QR code...", + "REINITIALIZING_SD_CARD": "Reinitializing SD card...", + "DUMPING_STATE_TO_SD_CARD": "Dumping state to SD card...", + "PRESS_POWER_TO_TURN_OFF": "Press POWER to turn off", + "CLEANING_UP_TITLES_PLEASE_WAIT": "Cleaning up titles, please wait...", + "ERROR_NOT_NCCH_FILE": "Error: Not an NCCH file", + "ERROR_FILE_IS_TOO_SMALL": "Error: File is too small", + "ATTEMPT_FIX_THIS_TIME": "Attempt fix this time", + "ATTEMPT_FIX_ALWAYS": "Attempt fix always", + "ABORT_VERIFICATION": "Abort verification", + "ERROR_BAD_CRYPTO_FLAGS": "Error: Bad crypto flags", + "ERROR_BAD_EXEFS_HEADER": "Error: Bad ExeFS header", + "ERROR_MISSING_EXTHEADER": "Error: Missing ExtHeader", + "ERROR_CRYPTO_NOT_SET_UP": "Error: Crypto not set up", + "PATH_NCCH_VERIFICATION_FAILED_INFO": "%s\nNCCH verification failed:\nExtHdr/ExeFS/RomFS: %s/%s/%s", + "OK": "ok", + "FAIL": "fail", + "ERROR_NOT_NCSD_FILE": "Error: Not an NCSD file", + "PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nContent%lu (%08lX@%08lX):\nVerification failed", + "ERROR_PROBABLY_NOT_CIA_FILE": "Error: Probably not a CIA file", + "ERROR_TMD_PROBABLY_CORRUPTED": "Error: TMD probably corrupted", + "PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nID %08lX (%08llX@%08llX)\nVerification failed", + "ERROR_CDN_TITLEKEY_NOT_FOUND": "Error: CDN titlekey not found", + "DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE": "DLC content is missing\n \nIgnore all and continue?", + "PATH_SECTION_N_HASH_MISMATCH": "%s\nSection %lu hash mismatch", + "ARM9_ENTRYPOINT_IS_MISSING": "ARM9 entrypoint is missing", + "WARNING_ARM11_ENTRYPOINT_IS_MISSING": "Warning: ARM11 entrypoint is missing", + "ERROR_NOT_A_BOSS_FILE": "Error: Not a BOSS file", + "BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT": "BOSS payload hash mismatch.\n \nTry to fix it?", + "GENERIC_TICKET_PIRATE_LEGIT": "Generic ticket (\"pirate legit\")", + "PERSONALIZED_TICKET_LEGIT": "Personalized ticket (legit)", + "ID_N_LEGIT_TICKET_IS_PERSONALIZED_USING_THIS_NOT_RECOMMENDED_CHOOSE_DEFAULT_ACTION": "ID %016llX\nLegit ticket is personalized.\nUsing this is not recommended.\nChoose default action:", + "ID_N_TITLEKEY_NOT_FOUND": "ID %016llX\nTitlekey not found.", + "ID_N_TMD_IN_TAD_NOT_LEGIT": "ID %016llX\nTMD in TAD is not legit.", + "ID_N_TMD_NOT_LEGIT": "ID %016llX\nTMD is not legit.", + "ID_N_DOT_N_STATUS": "ID %016llX.%08lX\n%s", + "CONTENT_IS_CORRUPT": "El contenido está corrupto", + "INSERT_CONTENT_FAILED": "Insert content failed", + "INSTALL_CONTENT_FAILED": "Install content failed", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_DB_FILES_MAYBE_SD_MISSING_OR_UNINITIALIZED": "Install error:\nThis system is missing one or\nmore .db files.\n \nMaybe the SD card is missing\nor uninitialized?", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB": "Install error:\nThis system is missing the\nticket.db file.", + "SKIPPED_TITLE_0004008C000CBD00_NEEDS_SPECIAL_COMPILE_FLAGS": "Skipped title:\nTitle with id 0004008C000CBD00\nneeds special compiler flags.", + "ERROR_FAKE_SIGNED_TICKET_ONLY_VALID_SIGNED_TICKETS_CAN_BE_INSTALLED": "Error: Fake-signed ticket\n \nOnly valid signed tickets can\nbe installed to the system.", + "PATH_ERROR_UNKNOWN_CID_N_THIS_TICKET_DOES_NOT_BELONG_TO_THIS_3DS": "%s\nError: Unknown cid %08lX\n \nThis ticket does not belong to\nthis 3DS console.", + "INSTALLING_TICKET": "Installing ticket...", + "POSSIBLY_BROKEN": "Possibly Broken", + "PERSONAL_LEGIT": "Personal Legit", + "PERSONAL_LEGIT_DLC": "Personal Legit DLC", + "PERSONAL_PIRATE_LEGIT": "Personal Pirate Legit", + "PERSONAL_PIRATE_LEGIT_DLC": "Personal Pirate Legit DLC", + "PERSONAL_CUSTOM": "Personal Custom", + "PERSONAL_CUSTOM_DLC": "Personal Custom DLC", + "UNIVERSAL_LEGIT": "Universal Legit", + "UNIVERSAL_LEGIT_DLC": "Universal Legit DLC", + "UNIVERSAL_PIRATE_LEGIT": "Universal Pirate Legit", + "UNIVERSAL_PIRATE_LEGIT_DLC": "Universal Pirate Legit DLC", + "UNIVERSAL_CUSTOM": "Universal Custom", + "UNIVERSAL_CUSTOM_DLC": "Universal Custom DLC", + "CONTENTS_IN_CIA_FOUND_TOTAL": "Contents in CIA: %lu/%lu", + "CONTENTS_IN_CIA_TOTAL": "Contents in TMD: %lu", + "CONSOLE_ID_N": "Console ID: %08lX\n", + "SHOW_GAME_INFO_DETAILS": "%s\n%s %s Title\n \nTitle ID: %016llX\nTitle version: %lu.%lu.%lu\nContents size: %s\n%s\n%s \nTicket/TMD: %s/%s\nVerification: %s", + "STATE_LEGIT": "legit", + "STATE_ILLEGIT": "illegit", + "STATE_UNKNOWN": "unknown", + "STATE_INVALID": "invalid", + "STATE_PENDING_PROCEED_WITH_VERIFICATION": "pending\n \nProceed with verification?", + "STATE_PASSED": "passed", + "STATE_FAILED": "failed", + "OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS": "Output file already exists.\nUpdate this?", + "DSI_ENHANCED": "DSi Enhanced", + "DSI_EXCLUSIVE": "DSi Exclusive", + "FIXING_CMACS_PLEASE_WAIT": "Fixing CMACs, please wait...", + "NCSD_HEADER_IS_NOT_VALID": "NCSD header is not valid", + "NAND_DUMP_MISSING_DATA": "NAND dump missing data", + "ERROR_CTR_MBR_IS_CORRUPT": "Error: CTR MBR is corrupt", + "ERROR_TWL_MBR_IS_CORRUPT": "Error: TWL MBR is corrupt", + "PATH_ERROR_CTR_PARTITION_N_IS_CORRUPT": "%s\nError: CTR partition%lu is corrupt", + "PATH_ERROR_TWL_PARTITION_N_IS_CORRUPT": "%s\nError: TWL partition%lu is corrupt", + "NO_VALID_FIRM_FOUND": "No valid FIRM found", + "ERROR_NAND_DUMP_IS_CORRUPT_STILL_CONTINUE": "Error: NAND dump is corrupt.\nStill continue?", + "ERROR_SYSTEM_IS_LOCKED": "Error: System is locked.", + "ESSENTIAL_FILES_BACKUP_IS_REQUIRED_CREATE_ONE_NOW": "Essential files backup is required.\nCreate one now?", + "WARNING_PROCEEDING_WILL_OVERWRITE_SYSNAND_WITH_DUMP": "!WARNING!\n \nProceeding will overwrite the\nSysNAND with the provided dump.\n \n(B9S/A9LH will be left intact.)", + "IMAGE_NCSD_CORRUPT_OR_CUSTOMIZED_SAFE_RESTORE_NOT_POSSIBLE": "Image NCSD corrupt or customized,\nsafe restore is not possible!", + "WARNING_NCSD_DIFFERS_BETWEEN_IMAGE_AND_LOCAL_ELEVATED_WRITE_PERMISSIONS_REQUIRED": "!WARNING!\n \nNCSD differs between image and local,\nelevated write permissions required\n \nProceed on your own risk?", + "NOT_AN_INSTALLABLE_FIRM": "Not a installable FIRM.", + "FIRM_LOAD_VERIFY_ERROR": "FIRM load/verify error.", + "PATH_FIRM_N_NOT_FOUND_OR_TOO_SMALL": "%s\nFIRM%lu not found or too small.", + "SECTOR_0X96_CRYPTO_FAIL": "Sector 0x96 crypto fail.", + "SECTOR_0X96_CORRUPTED_PROVIDE_SECRET_SECTOR_BIN_TO_FIX": "Sector 0x96 is corrupted.\n \nProvide \"secret_sector.bin\"\nto fix sector 0x96.", + "SECTOR_0X96_CORRUPTED_FIX_DURING_INSTALLATION": "Sector 0x96 is corrupted.\n \nFix sector 0x96 during\nthe installation?", + "WARNING_PROCEEDING_WILL_INSTALL_FIRM_TO_SYSNAND_AND_INJECT_SIGHAX_UNSUPPORTED_FIRM_WILL_BRICK": "!WARNING!\n \nProceeding will install the\nprovided FIRM to the SysNAND\nand inject sighax.\n \nInstalling an unsupported FIRM\nwill BRICK your console!", + "INSTALLING_FIRM_PLEASE_WAIT": "Installing FIRM, please wait...", + "THIS_IS_BAD_FAILED_WRITING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed writing sector 0x96.\nTry to fix before reboot!", + "THIS_IS_BAD_FAILED_WRITING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed writing FIRM%lu.\nTry to fix before reboot!", + "CHECKING_INSTALLATION_PLEASE_WAIT": "Checking installation, please wait...", + "THIS_IS_BAD_FAILED_VERIFYING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed verifying sector 0x96.\nTry to fix before reboot!", + "THIS_IS_BAD_FAILED_VERIFYING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed verifying FIRM%lu.\nTry to fix before reboot!", + "PERFECT_KEYDB_IS_ALREADY_INSTALLED": "Perfect %s is already installed!", + "PATH_NOT_PERFECT_KEYDB_IMAGE_CANNOT_INSTALL_TO_NAND": "%s\nNot a perfect %s image.\nCannot install to NAND!", + "PATH_FAILED_WRITING_KEYDB_TO_NAND": "%s\nFailed writing %s to NAND!", + "USE_L_R_TO_SAVE": "(use L+R to save)", + "EASTER_NOT_FOUND": "(%s not found)", + "BUILDING_TO_OUT_ARG": "Creando a %s: %s...", + "EJECT_SD_CARD": "Expulsar tarjeta SD..." +} diff --git a/resources/languages/fr.json b/resources/languages/fr.json new file mode 100644 index 000000000..402204d03 --- /dev/null +++ b/resources/languages/fr.json @@ -0,0 +1,726 @@ +{ + "GM9_LANGUAGE": "Français", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%4$02lX/%3$02lX/%1$s%2$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ",", + "THOUSAND_SEPARATOR": " ", + "FIRM_TOO_BIG": "FIRM trop grand, impossible de démarrer", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nAttention : Ne démarrez pas\nles FIRMs provenant\nde sources non fiables.\n \nDémarrer le FIRM ?", + "NOT_BOOTABLE_FIRM": "N'est pas un FIRM démarrable.", + "FIRM_ENCRYPTED": "Le FIRM est crypté.\n \nDécrypter avant le démarrage ?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Faire une copie à %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Essayer de démarrer quand même", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Attention : Tentative de démarrage à partir d'un emplacement\nnon pris en charge.", + "ROOT": "[racine]", + "LOADING": "CHARGEMENT…", + "PANE_N": "VOLET #%lu", + "CURRENT": "CURRENT", + "DIR": "(dos)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(Lecteur RAM FAT)", + "GAME_VIRTUAL": "(Jeu virtuel)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND virtuelle)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND virtuelle)", + "IMAGE_FAT": "(Image FAT)", + "XORPAD_VIRTUAL": "(XORpad virtuel)", + "MEMORY_VIRTUAL": "(Mémoire virtuelle)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Carte de jeu virtuelle)", + "VRAM_VIRTUAL": "(VRAM virtuelle)", + "SEARCH": "(Search)", + "TITLEMANAGER_VIRTUAL": "(TitleManager Virtual)", + "LAB_SDCARD": "Carte SD", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUELLE", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUELLE", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUELLE", + "LAB_GAMECART": "CARTE DE JEU", + "LAB_GAME_IMAGE": "IMAGE DU JEU", + "LAB_AESKEYDB_IMAGE": "IMAGE AESKEYDB", + "LAB_BDRI_IMAGE": "IMAGE BDRI", + "LAB_DISA_DIFF_IMAGE": "IMAGE DISA/DIFF", + "LAB_MEMORY_VIRTUAL": "MÉMOIRE VIRTUELLE", + "LAB_VRAM_VIRTUAL": "VRAM VIRTUELLE", + "LAB_TITLE_MANAGER": "GESTIONNAIRE DE TITRES", + "LAB_LAST_SEARCH": "DERNIÈRE RECHERCHE", + "LAB_FAT_IMAGE": "IMAGE FAT", + "LAB_BONUS_DRIVE": "LECTEUR BONUS", + "LAB_RAMDRIVE": "LECTEUR RAM", + "LAB_NOLABEL": "AUCUN LABEL", + "N_BYTE": "%s octet", + "BYTE": " Octet", + "KB": " ko", + "MB": " Mo", + "GB": " Go", + "CLIPBOARD": "[PRESSE-PAPIER]", + "PLUS_N_MORE": "+ %lu en plus", + "MARK_DELETE_COPY": "L - MARQUER les fichiers (avec ↑↓→←)\nX - SUPPRIMER / [+R] RENOMMER fichier(s)\nY - COPIER fichier(s) / [+R] CRÉER une entrée\n", + "MARK_DELETE_PASTE": "L - MARQUER les fichiers (avec ↑↓→←)\nX - SUPPRIMER / [+R] RENOMMER fichier(s)\nY - COLLER fichier(s) / [+R] CRÉER une entrée\n", + "RELOCK_WRITE_PERMISSION": "R+Y - Verrouiller les droits d'écriture\n", + "UNMOUNT_IMAGE": "R+X - Démonter l'image\n", + "UNMOUNT_SD": "R+B - Démonter la carte SD\n", + "REMOUNT_SD": "R+B - Remonter la carte SD\n", + "DIRECTORY_OPTIONS": "R+A - Options du répertoire\n", + "DRIVE_OPTIONS": "R+A - Options du lecteur\n", + "MAKE_SCREENSHOT": "R+L - Faire une capture d'écran\n", + "PREV_NEXT_PANE": "R+←→ - Passer au volet précédent/suivant\n", + "CLEAR_CLIPBOARD": "SELECT - Vider le presse-papiers\n", + "RESTORE_CLIPBOARD": "SELECT - Restaurer le presse-papier\n", + "REBOOT_POWEROFF_HOME": "START - Redémarrer / [+R] Éteindre\nHOME - aller au menu HOME", + "NO_EMUNAND": "Aucune EmuNAND", + "REDNAND_SIZE_MIN": "Taille de la RedNAND (min)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNAND size (full)", + "MULTINAND_SIZE_2X": "Taille MultiNAND (x2)", + "MULTINAND_SIZE_3X": "Taille MultiNAND (x3)", + "MULTINAND_SIZE_4X": "Taille MultiNAND (x4)", + "USER_INPUT": "User input...", + "AUTO": "Auto", + "16KB_CLUSTERS": "Clusters de 16 ko", + "32KB_CLUSTERS": "Clusters de 32 ko", + "64KB_CLUSTERS": "Clusters de 64 ko", + "SD_NOT_DETECTED": "Erreur : carte SD non détectée.", + "FORMAT_SD_CHOOSE_EMUNAND": "Formater la carte SD (%lluMo) ?\nChoisissez la taille EmuNAND :", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "La taille de la carte SD est de %lluMB.\nEntrez la taille EmuNAND (Mo) ci-dessous :", + "FORMAT_SD_CHOOSE_CLUSTER": "Formater la carte SD (%lluMo) ?\nChoisissez la taille d'allocation :", + "FORMAT_SD_ENTER_LABEL": "Formater la carte SD (%lluMo) ?\nEntrez le nom :", + "FORMAT_SD_FAILED": "Formatage SD : échec !", + "REDNAND_TYPE": "Type de la RedNAND", + "REDNAND_TYPE_MULTI": "Type de la RedNAND (multiple)", + "REDNAND_TYPE_SINGLE": "Type de la RedNAND (simple)", + "GW_EMUNAND_TYPE": "GW EmuNAND type", + "DONT_SET_UP": "Don't set up", + "CHOOSE_EMUNAND_TYPE": "Choisissez le type d'EmuNAND à configurer :", + "CLONE_SYSNAND_TO_REDNAND": "Cloner la SysNAND vers la RedNAND ?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "Clonage de la SysNAND vers l'EmuNAND : échec !", + "PRESS_A_TO_CONTINUE": "Appuyez sur pour continuer", + "HEXEDITOR_CONTROLS": "Commandes de l'éditeur hexadécimal :\n \n↑↓→←(+R) - Défiler\nR+Y - Changer de vue\nX - Rechercher / aller à…\nA - Entrer en mode édition\nA+↑↓→← - Modifier la valeur\nB - Quitter\n", + "NOT_FOUND": "Not found!", + "GO_TO_OFFSET": "Aller à l'offset", + "SEARCH_FOR_STRING": "Recherche de chaîne", + "SEARCH_FOR_DATA": "Recherche de données", + "CURRENT_OFFSET_SELECT_ACTION": "Current offset: %08lX\nSelect action:", + "CURRENT_OFFSET_ENTER_NEW": "Current offset: %08lX\nEnter new offset below.", + "ENTER_SEARCH_REPEAT_SEARCH": "Enter search string below.\n(R+X to repeat search)", + "MADE_EDITS_SAVE_CHANGES": "You made edits in %lu place(s).\nWrite changes to file?", + "FAILED_WRITING_TO_FILE": "Impossible d'écrire dans le fichier !", + "CALCULATING_SHA_FAILED": "Calcul SHA-%s : échec !", + "SHA_VERIFICATION_PASSED": "\nVérification SHA : réussie !", + "SHA_VERIFICATION_FAILED": "\nVérification SHA : échec !", + "IDENTICAL_WITH_PREVIOUS": "\n \nIdentique au fichier précédent :\n", + "WRITE_SHA_FILE": "\n \nÉcrire un fichier .SHA ?", + "WRITE_SHA1_FILE": "\n \nÉcrire un fichier .SHA1 ?", + "CALCULATING_CMAC_FAILED": "Calcul du CMAC : échec !", + "CMAC_VERIFICATION_PASSED": "Vérification du CMAC : réussie !", + "CMAC_VERIFICATION_FAILED": "Vérification du CMAC : échec !", + "FIX_CMAC_IN_FILE": "\n \nCorriger le CMAC du fichier ?", + "FIXING_CMAC_FAILED": "Correction du CMAC : échec !", + "COPY_ALL_SELECTED_ITEMS": "Copier les %lu éléments sélectionnés ?", + "FAILED_COPYING_ITEM": "Impossible de copier l'élément", + "ITEMS_COPIED_TO_OUT": "%lu éléments copiés vers %s", + "PATH_COPIED_TO_OUT": "%s\nCopié dans %s", + "CART_INIT_FAILED": "Cart init failed!", + "CART_DETECTED_SIZE_INPUT_BELOW": "Cart: %s\nDetected size: %s\n \nInput dump size below.", + "NDS_CART_DECRYPT_SECURE_AREA": "Cart: %s\nNDS cart detected\nDecrypt the secure area?", + "FAILED_DUMPING_CART": "%s\nFailed dumping cart", + "PATH_DUMPED_TO_OUT": "%s\nDumpé vers %s", + "CREATED": "créé ", + "MODIFIED": "modifié ", + "ANALYZING_DRIVE": "Analyse du disque, veuillez patienter…", + "ANALYZING_DIR": "Analyse du dossier, veuillez patienter…", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu files & %lu subdirs\n%s total size\n \nspace free: %s\nspace used: %s\nspace total: %s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu files & %lu subdirs\n%s total size", + "FILESIZE_X": "taille fichier : %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %slect. seule [%c] %scaché\n[%c] %ssystème [%c] %sarchive\n[%c] %svirtuel\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→← pour changer les attributs)\n", + "A_TO_CONTINUE": "( pour continuer)", + "A_APPLY_B_CANCEL": "( pour appliquer, pour annuler)", + "A_YES_B_NO": "( oui, non)", + "A_SELECT_B_CANCEL": "( sélectionner, annuler)", + "HOLD_B_TO_CANCEL": "(maintenez B pour annuler)", + "FAILED_TO_SET_ATTRIBUTES": "Impossible de définir les attributs !", + "NAND_IMAGE_OPTIONS": "Options d'image NAND…", + "CTRNAND_OPTIONS": "Options CTRNAND…", + "MOUNT_FAT_IMAGE": "Monter en tant qu'image FAT", + "CIA_IMAGE_OPTIONS": "Options d'image CIA…", + "NCSD_IMAGE_OPTIONS": "Options d'image NCSD…", + "NCCH_IMAGE_OPTIONS": "Options d'image NCCH…", + "MOUNT_AS_EXEFS_IMAGE": "Monter en tant qu'image EXEFS", + "MOUNT_AS_ROMFS_IMAGE": "Monter en tant qu'image ROMFS", + "TMD_FILE_OPTIONS": "Options de fichier TMD…", + "TMD_CDN_OPTIONS": "Options TMD/CDN…", + "TMD_TWL_OPTIONS": "Options TMD/TWL…", + "MANAGE_TITLE": "Gérer le titre…", + "BOSS_FILE_OPTIONS": "Options de fichier BOSS…", + "DECRYPT_NUS_CDN_FILE": "Décrypter fichier NUS/CDN", + "SHOW_SMDH_TITLE_INFO": "Afficher infos titre SMDH", + "NDS_IMAGE_OPTIONS": "Options d'image NDS…", + "GBA_IMAGE_OPTIONS": "Options d'image GBA…", + "TICKET_OPTIONS": "Options de ticket…", + "TAD_IMAGE_OPTIONS": "Options d'image TAD…", + "SHOW_3DSX_TITLE_INFO": "Afficher infos titre 3DSX", + "FIRM_IMAGE_OPTIONS": "Options d'image FIRM…", + "AGBSAVE_OPTIONS": "Options AGBSAVE…", + "DUMP_GBA_VC_SAVE": "Dumper sauvegarde GBA CV", + "TICKET_DB_OPTIONS": "Options Ticket.db…", + "MOUNT_AS_DIFF_IMAGE": "Monter en tant qu'image DIFF", + "MOUNT_AS_DISA_IAMGE": "Monter en tant qu'image DISA", + "INSTALL_CIFINISH_BIN": "Installer cifinish.bin", + "TITLEKEY_OPTIONS": "Titlekey options...", + "AESKEYDB_OPTIONS": "Options AESkeydb…", + "BUILD_X": "Générer %s", + "NCCHINFO_OPTIONS": "Options NCCHinfo…", + "EXECUTE_GM9_SCRIPT": "Exécuter script GM9", + "FONT_OPTIONS": "Paramètres de la police…", + "LANGUAGE_OPTIONS": "Paramètres de la langue…", + "VIEW_PNG_FILE": "Voir le fichier PNG", + "REBUILD_NCSD_HEADER": "Régénérer en-tête NCSD", + "SHOW_IN_HEXEDITOR": "Éditeur hexadécimal", + "CALCULATE_SHA256": "Calculer SHA-256", + "CALCULATE_SHA1": "Calculer SHA-1", + "SHOW_FILE_INFO": "Afficher infos fichier", + "SHOW_IN_TEXTVIEWER": "Visionneuse de textes", + "CALCULATE_CMAC": "Calculer le CMAC", + "COPY_TO_OUT": "Copier vers %s", + "DUMP_TO_OUT": "Dumper vers %s", + "INJECT_DATA_AT_OFFSET": "Inject data @offset", + "OPEN_THIS_FOLDER": "Ouvrir ce dossier", + "OPEN_CONTAINING_FOLDER": "Ouvrir le dossier contenant", + "OPEN_TITLE_FOLDER": "Ouvrir le dossier du titre", + "PATH_N_FILES_SELECTED": "%s\n(%lu fichiers sélectionnés)", + "CHECK_CURRENT_CMAC_ONLY": "Vérifier le CMAC actuel uniq.", + "VERIFY_CMAC_FOR_ALL": "Vérifier le CMAC pour tous", + "FIX_CMAC_FOR_ALL": "Corriger le CMAC pour tous", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%lu fichiers ok/corrigés/au total\n%lu/%lu n'ont pas de CMAC", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%lu fichiers vérifiés ok\n%lu/%lu fichiers corrigés", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%lu fichiers vérifiés ok\n%lu/%lu n'ont pas de CMAC", + "N_OF_N_FILES_VERIFIED": "%lu/%lu fichiers vérifiés ok", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "Inject data from %s?\nSpecify offset below.", + "FAILED_INJECTING_PATH": "Failed injecting %s", + "MOUNT_CXI_NDS_TO_DRIVE": "Monter CXI/NDS sur le lecteur", + "MOUNT_IMAGE_TO_DRIVE": "Monter l'image sur le lecteur", + "RESTORE_SYSNAND_SAFE": "Restaurer la SysNAND (sans risque)", + "UPDATE_EMBEDDED_BACKUP": "Update embedded backup", + "SHOW_TITLE_INFO": "Afficher infos titre", + "DECRYPT_FILE": "Déchiffrer le fichier (…)", + "DECRYPT_FILE_OUT": "Déchiffrer le fichier (%s)", + "ENCRYPT_FILE": "Chiffrer le fichier (…)", + "ENCRYPT_FILE_OUT": "Chiffrer le fichier (%s)", + "BUILD_CIA_FROM_FILE": "Générer CIA à partir du fichier", + "BUILD_CIA_STANDARD": "Générer CIA (standard)", + "BUILD_CIA_LEGIT": "Générer CIA (authentique)", + "DUMP_CXI_NDS_FILE": "Dumper fichier CXI/NDS", + "INSTALL_GAME_IMAGE": "Installer l'image du jeu", + "INSTALL_TICKET": "Installer le ticket", + "DUMP_TICKET_FILE": "Dumper le fichier ticket", + "UNINSTALL_TITLE": "Désinstaller le titre", + "VERIFY_FILE": "Vérifier le fichier", + "TRANSFER_IMAGE_TO_CTRNAND": "Transférer image vers CTRNAND", + "INJECT_TO_H_AND_S": "Injecter dans S&S", + "TRIM_FILE": "Tronquer le fichier", + "RENAME_FILE": "Renommer le fichier", + "BUILD_XORPADS_SD": "Build XORpads (SD output)", + "BUILD_XORPADS_INPLACE": "Build XORpads (inplace)", + "EXTRACT_X": "Extraire %s", + "INIT_X": "Init %s", + "INSTALL_X": "Installer %s", + "INSTALL_FIRM": "Installer le FIRM", + "BOOT_FIRM": "Démarrer le FIRM", + "SET_AS_ACTIVE_FONT": "Définir comme police active", + "SET_AS_ACTIVE_LANGUAGE": "Définir comme langue active", + "DUMP_BA_VC_SAVE": "Dumper sauvegarde GBA CV", + "INJECT_GBA_VC_SAVE": "Injecter sauvegarde GBA CV", + "SET_AS_DEFAULT": "Définir par défaut", + "MOUNTING_IMAGE_FAILED": "Montage de l'image : échec", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nMonté en tant que lecteur %s\nS'y rendre tout se suite ?", + "DECRYPT_TO_OUT": "Déchiffrer vers %s", + "DECRYPT_INPLACE": "Déchiffrer en place", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "Essayer de déchiffrer les %lu fichiers sélectionnés ?", + "TRYING_TO_DECRYPT_N_FILES": "Tentative de déchiffrement de %lu fichiers…", + "DECRYPTION_FAILED_CONTINUE": "Échec du déchiffrement\n \nContinuer ?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu fichiers déchiffrés ok\n%lu/%lu non chiffrés\n%lu/%lu pas du même type", + "N_OF_N_FILES_DECRYPTED": "%lu/%lu fichiers déchiffrés ok", + "N_FILES_WRITTEN_TO_OUT": "%lu fichiers écrits vers %s", + "FILE_NOT_ENCRYPTED": "Le fichier n'est pas chiffré", + "DECRYPTION_SUCCESS": "Déchiffrement réussi", + "DECRYPTION_FAILED": "Échec du déchiffrement", + "PATH_DECRYPTED_TO_OUT": "%s\nDéchiffré vers %s", + "ENCRYPT_TO_OUT": "Chiffrer vers %s", + "ENCRYPT_INPLACE": "Chiffrer en place", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "Essayer de chiffrer les %lu fichiers sélectionnés ?", + "TRYING_TO_ENCRYPT_N_FILES": "Tentative de chiffrement de %lu fichiers…", + "ENCRYPTION_FAILED_CONTINUE": "Échec du chiffrement\n \nContinuer ?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu fichiers chiffrés ok\n%lu/%lu pas du même type", + "N_OF_N_FILES_ENCRYPTED": "%lu/%lu fichiers chiffrés ok", + "ENCRYPTION_SUCCESS": "Chiffrement réussi", + "ENCRYPTION_FAILED": "Échec du chiffrement", + "PATH_ENCRYPTED_TO_OUT": "%s\nChiffré vers %s", + "TRY_TO_PROCESS_N_SELECTED_FILES": "Essayer de traiter les %lu fichiers sélectionnés ?", + "PATH_BUILD_TYPE_FAILED_CONTINUE": "%s\nLa génération de %s a échoué\n \nContinuer ?", + "N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE": "%lu/%lu %ss générés ok\n%lu/%lu pas du même type", + "N_OF_N_TYPES_BUILT": "%lu/%lu %ss générés ok", + "N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED": "La conversion a échoué pour %s fichier(s).\nUne vérification est recommandée.", + "PATH_TYPE_BUILT_TO_OUT": "%s\n%s générés vers %s", + "PATH_TYPE_BUILD_FAILED": "%s\n%s n'a pu être généré", + "FILE_FAILED_CONVERSION_VERIFY_NOW": "conversion du fichier échouée.\n \nVérifier maintenant ?", + "VERIFICATION_SUCCESS": "Vérification réussie", + "VERIFICATION_FAILED": "Échec de la vérification", + "CONTENT_IS_MISSING": "Le contenu est manquant", + "INSTALL_TO_SYSNAND": "Installer sur la SysNAND", + "INSTALL_TO_EMUNAND": "Installer sur l'EmuNAND", + "TRY_TO_INSTALL_N_SELECTED_FILES": "Essayer d'installer les %lu fichiers sélectionnés ?", + "TRYING_TO_INSTALL_N_FILES": "Tentative d'installation de %lu fichiers…", + "INSTALL_FAILED_CONTINUE": "Échec de l'installation\n \nContinuer ?", + "N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu fichiers installés ok\n%lu/%lu pas du même type", + "N_OF_N_FILES_INSTALLED": "%lu/%lu fichiers installés ok", + "INSTALL_SUCCESS": "Installation réussie", + "INSTALL_FAILED": "Échec de l'installation", + "FILE_FAILED_INSTALL_VERIFY_NOW": "installation du fichier échouée.\n \nVérifier maintenant ?", + "KEEP_TICKET_AND_SAVEGAME": "Conserver ticket et sauvegarde", + "UNINSTALL_EVERYTHING": "Tout désinstaller", + "ABORT_UNINSTALL": "Annuler désinstallation", + "UNINSTALL_N_SELECTED_TITLES": "Désinstaller les %lu titres sélectionnés ?", + "UNINSTALL_SELECTED_TITLE": "Désinstaller le titre sélectionné ?", + "N_OF_N_TITLES_UNINSTALLED": "%lu/%lu titres désinstallés", + "UNINSTALLING_PLEASE_WAIT": "Désinstallation, veuillez patienter…", + "UNINSTALL_FAILED": "Échec de la désinstallation !", + "TRY_TO_VERIFY_N_SELECTED_FILES": "Essayer de vérifier les %lu fichiers sélectionnés ?", + "VERIFICATION_FAILED_CONTINUE": "Échec de la vérification\n \nContinuer ?", + "N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu fichiers vérifiés ok\n%lu/%lu pas du même type", + "VERIFYING_FILE_PLEASE_WAIT": "Vérification du fichier, veuillez patienter…", + "NAND_VALIDATION_SUCCESS": "Validation de la NAND réussie", + "NAND_VALIDATION_FAILED": "Échec de la validation de la NAND", + "DUMP_FOR_N_SELECTED_FILES": "Dumper les %lu fichiers sélectionnés ?", + "N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL": "%lu/%lu tickets authentiques dumpés.\n \nTenter de dumper tous les tickets ?", + "N_OF_N_TICKETS_DUMPED_TO_OUT": "%lu/%lu tickets dumpés vers %s", + "PATH_TICKET_DUMPED_TO_OUT": "%s\nTicket dumpé vers %s", + "LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS": "%s\nLe ticket authentique n'a pas été trouvé.\n \nDumper quand même ?", + "DUMP_TICKET_FAILED": "Échec du dumping du ticket !", + "BUILDING_X": "Building %s...", + "BUILDING_X_SYSNAND": "Building %s (SysNAND)...", + "BUILDING_X_EMUNAND": "Building %s (EmuNAND)...", + "PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED": "%s\n%lu/%lu fichiers traités\n%lu/%lu fichiers ignorés", + "PATH_N_OF_N_FILES_PROCESSED": "%s\n%lu/%lu fichiers traités", + "BUILD_DATABASE_SUCCESS": "Génération de la base de données réussie.", + "BUILD_DATABASE_FAILED": "Échec de la génération de la base de données.", + "TRY_TO_TRIM_N_SELECTED_FILES": "Essayer de tronquer les %lu fichiers sélectionnés ?", + "TRIMMING_FAILED_CONTINUE": "Échec du troncage\n \nContinuer ?", + "N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED": "%lu/%lu fichiers tronqués ok\n%lu/%lu pas du même type\n%s enregistrés", + "N_OF_N_FILES_TRIMMED_X_SAVED": "%lu/%lu fichiers tronqués ok\n%s enregistrés", + "FILE_CANT_BE_TRIMMED": "Impossible de tronquer le fichier.", + "FILE_ALREADY_TRIMMED": "Le fichier est déjà tronqué.", + "PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE": "%s\nTaille actuelle : %s\nTaille tronquée : %s\nDifférence : %s\n \nTronquer ce fichier ?", + "TRIMMING_FAILED": "Échec du troncage.", + "PATH_TRIMMED_BY_X": "%s\nTronqué par %s.", + "TRY_TO_RENAME_N_SELECTED_FILES": "Essayer de renommer les %lu fichiers sélectionnés ?", + "N_OF_N_RENAMED": "%lu/%lu renommés ok", + "COULD_NOT_RENAME_TO_GOOD_NAME": "Could not rename to good name", + "SYSNAND_H_AND_S_INJECT": "SysNAND H&S inject", + "EMUNAND_H_AND_S_INJECT": "EmuNAND H&S inject", + "H_AND_S_INJECT_SUCCESS": "Injection dans S&S réussie", + "H_AND_S_INJECT_FAILURE": "Échec de l'injection dans S&S", + "TRY_EXTRACT_ALL_N_SELECTED_FILES": "Essayer d'extraire les %lu fichiers sélectionnés ?", + "N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu fichiers extraits ok\n%lu/%lu pas du même type", + "N_OF_N_FILES_EXTRACTED": "%lu/%lu fichiers extraits ok", + "EXTRACTING_DOT_CODE": "Extraction de .code, veuillez patienter…", + "PATH_EXT_EXTRACTED_TO_OUT": "%s\n%s extrait vers %s", + "DOT_CODE_EXTRACT_FAILED": "Échec de l'extraction de .code", + "TRANSFER_TO_SYSNAND": "Transférer vers lz SysNAND", + "TRANSFER_TO_EMUNAND": "Transférer vers l'EmuNAND", + "CTRNAND_TRANSFER_SUCCESS": "Transfert de la CTRNAND réussie", + "CTRNAND_TRANSFER_FAILED": "Échec du transfert de la CTRNAND", + "NO_VALID_DESTINATION_FOUND": "Aucune destination valide n'a été trouvée", + "NAND_RESTORE_SUCCESS": "Restauration de la NAND réussie", + "NAND_RESTORE_FAILED": "Échec de la restauration de la NAND", + "REBUILD_NCSD_SUCCESS": "Régénération du NCSD réussie", + "REBUILD_NCSD_FAILED": "Échec de la régénération du NCSD", + "PATH_NCCHINFO_PADGEN_SUCCESS": "%s\nNCCHinfo padgen success%cOutput dir: %s", + "PATH_NCCHINFO_PADGEN_FAILED": "%s\nNCCHinfo padgen failed%c%0.0s", + "UPDATING_EMBEDDED_BACKUP": "Updating embedded backup...", + "BACKUP_UPDATE_NOT_REQUIRED": "Backup update: not required", + "BACKUP_UPDATE_COMPLETED": "Backup update: completed", + "BACKUP_UPDATE_FAILED": "Backup update: failed!", + "WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK": "Attention : Les clés ne sont pas vérifiées.\nPoursuivre à vos risques et périls ?", + "AESKEYDB_INIT_SUCCESS": "AESkeydb init success", + "AESKEYDB_INIT_FAILED": "AESkeydb init failed", + "AESKEYDB_INSTALL_SUCCESS": "AESkeydb install success", + "AESKEYDB_INSTALL_FAILED": "AESkeydb install failed", + "INSTALL_TO_FIRM0": "Installer sur FIRM0", + "INSTALL_TO_FIRM1": "Installer sur FIRM1", + "INSTALL_TO_BOTH": "Installer sur les deux", + "PATH_N_KB_INSTALL_TO_SYSNAND": "%s (%d ko)\nInstaller sur la SysNAND ?", + "PATH_N_KB_INSTALL_SUCCESS": "%s (%d ko)\nInstallation réussie", + "PATH_N_KB_INSTALL_FAILED": "%s (%dkB)\nInstall failed", + "WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS": "Attention : N'exécutez pas les scripts\nprovenant de sources non fiables.\n \nExécuter le script ?", + "SCRIPT_EXECUTE_SUCCESS": "Exécution du script réussie", + "SCRIPT_EXECUTE_FAILURE": "Échec de l'exécution du script", + "ERROR_CANNOT_VIEW_FILE": "Error: Cannot view file\n(Hint: maybe it's too big)", + "SAVEGAME_DUMPED_TO_OUT": "Sauvegarde dumpée vers %s.", + "SAVEGAME_DUMP_FAILED": "Échec du dump de la sauvegarde !", + "GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD": "La sauvegarde GBA CV doit être\ndans le presse-papiers.", + "SAVEGAME_INJECT_SUCCESS": "Injection de la sauvegarde réussie.", + "SAVEGAME_INJECT_FAILED": "Échec de l'injection de la sauvegarde !", + "FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT": "La police sera active au prochain démarrage", + "LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Language will be active on next boot", + "HOME_MORE_MENU_SELECT_ACTION": "HOME more... menu.\nSelect action:", + "SD_FORMAT_MENU": "SD format menu", + "BONUS_DRIVE_MENU": "Bonus drive setup", + "SWITCH_EMUNAND": "Switch EmuNAND", + "BUILD_SUPPORT_FILES": "Build support files", + "RESTORE_H_AND_S": "Restaurer S&S", + "SET_RTC_DATE_TIME": "Régler date et heure HTR", + "CONFGURE_BRIGHTNESS": "Configurer la luminosité", + "CALIBRATE_TOUCHSCREEN": "Calibrer l'écran tactile", + "SYSTEM_INFO": "Infos système", + "SHOW_README": "Afficher le ReadMe", + "INITIALIZING_SD_FAILED_RETRY": "Initializing SD card failed! Retry?", + "SETUP_FAILED": "Setup failed!", + "CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT": "Current EmuNAND offset is %06lX.\nSwitch to next offset?", + "BUILT_IN_OUT_STATUSES": "Built in %s:\n \n%-18.18s %s\n%-18.18s %s\n%-18.18s %s", + "OK_SYS_EMU": "OK (Sys&Emu)", + "OK_SYS": "OK (Sys)", + "FAILED": "Failed", + "RESTORE_H_AND_S_EMUNAND": "Restaurer S&S (EmuNAND)", + "RESTORE_H_AND_S_SYSNAND": "Restaurer S&S (SysNAND)", + "TITLE_SET_RTC_DATE_TIME": "Régler date et heure HTR :", + "NEW_RTC_DATE_TIME_IS_TIME": "La nouvelle date et heure HTR est :\n%s\n \nRemarque : L'heure HOMEMENU\ndoit être réglée manuellement\naprès le réglage de l'heure HTR.", + "TOUCHSCREEN_CALIBRATION_SUCCESS": "Calibration de l'écran tactile réussie !", + "TOUCHSCREEN_CALIBRATION_FAILED": "Impossible de calibrer l'écran tactile !", + "GODMODE9_README_TOC": "GodMode9 ReadMe Table of Contents", + "ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW": "Essential files backup not found.\nCreate one now?", + "BACKUP_EMBEDDED_WRITTEN_TO_OUT": "Backup embedded in SysNAND\nand written to %s.", + "RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW": "La date et l'heure HTR\nsemblent être erronées.\nLes régler maintenant ?", + "RESUME_GODMODE9": "Resume GodMode9", + "RESUME_BOOTLOADER": "Resume bootloader", + "SELECT_PAYLOAD": "Sélectionner la charge utile…", + "SELECT_SCRIPT": "Sélectionner le script…", + "POWEROFF_SYSTEM": "Éteindre le système", + "REBOOT_SYSTEM": "Redémarrer le système", + "FLAVOR_BOOTLOADER_SELECT_OPTION": "%s bootloader menu.\nSelect action:", + "BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD": "Menu du chargeur d'amorçage\ndes charges utiles.\nSélectionner la charge utile :", + "BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT": "Bootloader scripts menu.\nSelect script:", + "NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9": "No bootable FIRM found.\nNow resuming GodMode9...", + "OUT_OF_MEMORY": "Mémoire insuffisante.", + "INVALID_DIRECTORY_OBJECT": "Invalid directory object", + "INVALID_ROOT_DIRECTORY": "Invalid root directory.", + "WRITE_PERMISSIONS_WERE_CHANGED_RELOCK": "Write permissions were changed.\nRelock them?", + "OPEN_TITLE_MANAGER": "Ouvrir le gestionnaire de titres", + "SEARCH_FOR_FILES": "Rechercher des titres…", + "FIX_CMACS_FOR_DRIVE": "Réparer les CMACs du lecteur", + "SHOW_DIRECTORY_INFO": "Afficher infos dossier", + "SHOW_DRIVE_INFO": "Afficher infos lecteur", + "FAILED_SETTING_UP_TITLE_MANAGER": "Failed setting up title manager!", + "SEARCH_FILE_ENTER_SEARCH_BELOW": "Search %s?\nEnter search below.", + "FOUND_N_RESULTS": "%lu résultats trouvés.", + "FIX_CMACS_FOR_DRIVE_FINISHED": "Fix CMACs for drive finished.", + "FAILED_TO_ANALYZE_DRIVE": "Impossible d'analyser le lecteur\n", + "FAILED_TO_ANALYZE_DIR": "Impossible d'analyser le répertoire\n", + "NOT_ALLOWED_IN_VIRTUAL_PATH": "Non autorisé dans le chemin virtuel", + "DELETE_N_PATHS": "Supprimer %lu chemin(s) ?", + "DELETING_FILES_PLEASE_WAIT": "Suppression des fichiers, veuillez patienter…", + "FAILED_DELETING_N_OF_N_PATHS": "Impossible de supprimer %lu/%lu chemin(s)", + "DELETE_FILE": "Supprimer « %s » ?", + "FAILED_DELETING_PATH": "Impossible de supprimer :\n%s", + "NOT_ALLOWED_IN_SEARCH_DRIVE": "Non autorisé dans le lecteur de recherche", + "NOT_ALLOWED_IN_VIRTUAL_GAME_PATH": "Non autorisé dans le chemin de jeu virtuel", + "NOT_ALLOWED_IN_XORPAD_DRIVE": "Non autorisé dans le lecteur XORpad", + "NOT_ALLOWED_IN_GAMECART_DRIVE": "Non autorisé dans le lecteur de la carte de jeu", + "NOT_ALLOWED_IN_ALIAS_PATH": "Not allowed in alias path", + "COPY_PATHS": "Copier le(s) chemin(s)", + "MOVE_PATHS": "Déplacer le(s) chemin(s)", + "PASTE_FILE_HERE": "Coller « %s » ici ?", + "PASTE_N_PATHS_HERE": "Coller les %lu chemins ici ?", + "FAILED_COPYING_PATH_PROCESS_REMAINING": "Impossible de copier le chemin :\n%s\nTraiter les éléments restants ?", + "FAILED_COPYING_PATH": "Impossible de copier le chemin :\n%s", + "FAILED_MOVING_PATH_PROCESS_REMAINING": "Impossible de déplacer le chemin :\n%s\nTraiter les éléments restants ?", + "FAILED_MOVING_PATH": "Impossible de déplacer le chemin :\n%s", + "RENAME_FILE_ENTER_NEW_NAME_BELOW": "Renommer %s ?\nSaisissez le nouveau nom ci-dessous.", + "FAILED_RENAMING_PATH": "Impossible de renommer le chemin :\n%s", + "CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE": "Create a new entry here?\nSelect type.", + "CREATE_A_FOLDER": "Créer un dossier", + "CREATE_A_DUMMY_FILE": "Créer un fichier vide", + "CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW": "Créer un nouveau dossier ici ?\nSaisissez le nom ci-dessous.", + "CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW": "Créer un nouveau fichier ici ?\nSaisissez le nom ci-dessous.", + "CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW": "Create a new %s here?\nEnter file size below.", + "FAILED_CREATING_FOLDER_PATH": "Impossible de créer le dossier :\n%s", + "FAILED_CREATING_FILE_PATH": "Impossible de créer le fichier :\n%s", + "TITLE_MANAGER": "Gestionnaire de titres", + "BRICK_MY_3DS": "Bricker ma 3DS", + "LANGUAGE": "Langue…", + "SCRIPTS": "Scripts…", + "PAYLOADS": "Charges utiles…", + "MORE": "Plus…", + "BRACKET_MORE": "[plus…]", + "HOME_BUTTON_PRESSED_SELECT_ACTION": "Bouton HOME pressé.\nSélectionner l'action :", + "POWER_BUTTON_PRESSED_SELECT_ACTION": "Bouton POWER pressé.\nSélectionner l'action :", + "1_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "4_DRIVE_NAND_TWL": "[4:] NAND / TWL", + "A_DRIVE_SD_CARD": "[A:] CARTE SD", + "B_DRIVE_SD_CARD": "[B:] CARTE SD", + "TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE": "Title manager menu.\nSelect titles source:", + "LANGUAGES_DIRECTORY_NOT_FOUND": "Languages directory not found.\n(default path: 0:/gm9/%s)", + "SCRIPTS_DIRECTORY_NOT_FOUND": "Scripts directory not found.\n(default path: 0:/gm9/%s)", + "HOME_LANGUAGE_MENU_SELECT_LANGUAGE": "HOME language... menu.\nSelect language:", + "HOME_SCRIPTS_MENU_SELECT_SCRIPT": "HOME scripts... menu.\nSelect script:", + "PAYLOADS_DIRECTORY_NOT_FOUND": "Le répertoire des charges utiles\nn'a pas été trouvé.\n(chemin par défaut : 0:/gm9/%s)", + "HOME_PAYLOADS_MENU_SELECT_PAYLOAD": "HOME payloads... menu.\nSelect payload:", + "UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT": "!Unexpected SD card removal!\n \nTo prevent data loss, unmount\nbefore ejecting the SD card.", + "FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT": "%s scripts menu.\nSelect script:", + "COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP": "Compiled as script autorunner\nbut no script provided.\n \nDerp!", + "KEYBOARD_CONTROLS_DETAILS": "Keyboard Controls:\n \n←/→ - Move cursor\nR - Caps / Capslock\nX - Delete char\nY - Insert char\nA - Submit\nB - Cancel\n \nSELECT switches to\nclassic prompt", + "TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS": "Touch the red crosshairs to\ncalibrate your touchscreen.\n \nUse the stylus for best\nresults!", + "INVALID": "INVALIDE", + "TO_PROCEED_ENTER_THIS": "Pour continuer, entrez ceci :", + "TO_PROCEED_HOLD_X": "Pour continuer, maintenez :", + "N_MORE": " [%d de plus]", + "CANCEL": "annuler", + "R_FAST_SCROLL_L_CLEAR_DATA": "R - (↑↓) défilement rapide\nL - effacer les données", + "X_REMOVE_CHAR_Y_INSERT_CHAR": "X - supprimer le caractère\nY - insérer le caractère", + "ETA_N_MIN_N_SEC": "ETA %02llum%02llus", + "BRIGHTNESS_CONTROLS": "[←] Decrease brightness\n[→] Increase brightness\n \n[X] Use volume slider control\n[A] Set current brightness\n[B] Cancel", + "SEARCHING_PLEASE_WAIT": "Recherche en cours, veuillez patienter…", + "RENAME_TO_GOOD_NAME": "Renommer en un meilleur nom ?", + "SD_WRITE_PROTECTED_CANT_CONTINUE": "La carte SD est protégée en écriture !\nImpossible de continuer.", + "SYSNAND_LVL_N": "SysNAND (lvl%lu)", + "EMUNAND_LVL_N": "EmuNAND (lvl%lu)", + "GAME_IMAGES": "images de la jeu", + "GAMECART_SAVES": "sauvegardes de la carte de jeu", + "IMAGES": "images", + "MEMORY_AREAS": "zones de mémoire", + "SD_SYSTEM_DATA": "Données du système SD", + "SD_CARD": "Carte SD", + "RAM_DRIVE": "Lecteur RAM", + "WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW": "L'écriture dans %s est verrouillée !\nDéverrouiller maintenant ?", + "UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED": "Le déverrouillage de\nla permission d'écriture pour\n%s n'est pas autorisé.", + "ENABLE_BASE_WRITE": "Vous souhaitez activer les\npermissions d'écriture de\nbase.", + "ENABLE_SD_WRITE": "Vous souhaitez activer les\npermissions d'écriture de\nla carte SD.", + "ENABLE_IMAGE_WRITE": "Vous souhaitez activer les\npermissions d'écriture\nd'images.", + "ENABLE_RAM_DRIVE_WRITE": "You want to enable RAM drive\nwriting permissions.", + "ENABLE_EMUNAND_0_WRITE": "You want to enable EmuNAND\nlvl0 writing permissions.", + "ENABLE_SYSNAND_0_WRITE": "You want to enable SysNAND\nlvl0 writing permissions.", + "ENABLE_EMUNAND_1_WRITE": "You want to enable EmuNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nrecoverable system data,\nuser data & savegames.", + "ENABLE_SYSNAND_1_WRITE": "You want to enable SysNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nsystem data, installations,\nuser data & savegames.", + "ENABLE_GAMECART_SAVE_WRITE": "You want to enable gamecart\nsave writing permissions.", + "ENABLE_SYSNAND_2_WRITE": "!Better be careful!\n \nYou want to enable SysNAND\nlvl2 writing permissions.\n \nThis enables you to modify\nirrecoverable system data!", + "ENABLE_MEMORY_WRITE": "!Better be careful!\n \nYou want to enable memory\nwriting permissions.\n \nWriting to certain areas may\nlead to unexpected results.", + "ENABLE_SD_DATA_WRITE": "!THIS IS NOT RECOMMENDED!\n \nYou want to enable SD data\nwriting permissions.\n \nEverything here is encrypted.\nIt is recommended to use the\nA:/B: drives for modification\nof installations, user data &\nsavegames instead.", + "ENABLE_SYSNAND_3_WRITE": "!THIS IS YOUR ONLY WARNING!\n \nYou want to enable SysNAND\nlvl3 writing permissions.\n \nThis enables you to OVERWRITE\nyour bootloader installation,\nessential system files and/or\nBRICK your console!", + "UNLOCK_WRITE_NOT_ALLOWED": "Unlock write permission is not allowed.", + "CANT_UNLOCK_WRITE_TRY_GODMODE9": "Can't unlock write permission.\nTry GodMode9 instead!", + "ERROR_SD_TOO_SMALL": "Erreur : La carte SD est trop petite", + "WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA": "!WARNING!\n \nProceeding will format this SD.\nThis will irreversibly delete\nALL data on it.", + "FORMAT_BONUS_DRIVE_DELETE_ALL_DATA": "Format the bonus drive?\nThis will irreversibly delete\nALL data on it.", + "FORMATTING_SD_PLEASE_WAIT": "Formatage de la carte SD, veuillez patienter…", + "FORMATTING_DRIVE_PLEASE_WAIT": "Formatage du lecteur, veuillez patienter…", + "ERROR_SD_CARD_IO_FAILURE": "Error: SD card i/o failure", + "FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK": "Le fichier est actuellement monté.\nDémonter pour déverrouiller ?", + "ERROR_CANT_INJECT_FILE_INTO_ITSELF": "Erreur : Impossible d'injecter\nun fichier dans lui-même", + "OPERATION_WOULD_WRITE_BEYOND_EOF": "L'opération écrirait au-delà de la fin du fichier", + "NOT_ENOUGH_DATA_IN_FILE": "Pas assez de données dans le fichier", + "CANCEL_IS_NOT_ALLOWED_HERE": "L'annulation n'est pas autorisée ici", + "B_DETECTED_CANCEL": "Bouton B détecté. Annuler ?", + "ERROR_CANNOT_APPEND_FOLDER": "Erreur : Impossible d'ajouter un dossier", + "ERROR_OVERWRITING_FILE_WITH_DIR": "Error: Overwriting file with dir", + "ERROR_OVERWRITING_DIR_WITH_FILE": "Error: Overwriting dir with file", + "ERROR_CANNOT_OPEN_DESTINATION_FILE": "Error: Cannot open destination file", + "ERROR_NOT_ENOUGH_SPACE_AVAILABLE": "Erreur : Pas assez d'espace disponible", + "ERROR_ONLY_FAT_FILES_CAN_BE_MOVED": "Erreur : Seuls les fichiers FAT\npeuvent être déplacés", + "ERROR_DESTINATION_IS_PART_OF_ORIGIN": "Erreur : La destination\nfait partie de l'origine", + "ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME": "La destination équivaut à l'origine\nChoisir un autre nom ?", + "CHOOSE_NEW_NAME": "Choississez un nouveau nom", + "OVERWRITE_FILES": "Écraser le(s) fichier(s)", + "SKIP_FILES": "Ignorer le(s) fichier(s)", + "OVERWRITE_ALL": "Écraser tout", + "SKIP_ALL": "Ignorer tout", + "DESTINATION_ALREADY_EXISTS": "La destination existe déjà :\n%s", + "CHOOSE_NEW_DESTINATION_NAME": "Choisissez un nouveau nom de destination", + "COPY_OPERATION_IS_NOT_ALLOWED": "L'opération de copie n'est pas autorisée", + "DESTINATION_EQUALS_ORIGIN": "La destination équivaut à l'origine", + "ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD": "Entrée non trouvée : %s\nInjecter dans %s à la place ?", + "FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE": "Fichier plus petit que l'espace disponible :\n%s (%s)\n%s (%s)\nContinuer ?", + "NO_USABLE_ENTRIES_FOUND": "Aucune entrée utilisable n'a été trouvée.", + "BEAT_NO_ERROR": "Aucune erreur", + "BEAT_END_OF_ACTION_LIST": "Fin de la liste d'actions", + "BEAT_ABORTED_BY_USER": "Interrompu par l'utilisateur", + "BEAT_FAILED_TO_READ_WRITE_FILE": "Impossible de lire/écrire le fichier", + "BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF": "Tentative d'écriture au-delà de la fin du fichier", + "BEAT_INVALID_PATCH_FILE": "Fichier patch invalide", + "BEAT_INVALID_INPUT_FILE": "Fichier d'entrée invalide", + "BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH": "Mauvaise correspondance de la\nsomme de contrôle du fichier de sortie", + "BEAT_FILE_CHECKSUM_FAILED": "Échec de la somme de contrôle du fichier", + "BEAT_EXPECTED_MORE_PATCH_DATA": "Plus de données du patch\nétaient attendues", + "BEAT_OUT_OF_MEMORY": "Mémoire insuffisante", + "BEAT_UNKNOWN_ERROR": "Erreur inconnue", + "FAILED_TO_INITIALIZE_BPM_FILE": "Échec de l'initialisation du fichier BPM :\n%s", + "FAILED_TO_INITIALIZE_BPS_FILE": "Échec de l'initialisation du fichier BPS :\n%s", + "PATCH_SUCCESSFULLY_APPLIED": "Le patch a été appliqué avec succès", + "PATCHING_ABORTED_BY_USER": "Patchage interrompu par l'utilisateur", + "FAILED_TO_RUN_PATCH": "Échec de l'exécution du patch :\n%s", + "DECOMPRESSING_DOT_CODE": "Décompression de .code…", + "DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Décompression de .code…\nBouton B détecté. Annuler ?", + "COMPRESSING_DOT_CODE": "Compression de .code…", + "COMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Compression de .code…\nBouton B détecté. Annuler ?", + "PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE": "The patch is most likely not intended for this file.", + "YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT": "You most likely applied the patch on the output file.", + "PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED": "The patch is technically valid,\nbut seems scrambled or malformed.", + "PATCH_IS_INVALID": "The patch is invalid.", + "FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT": "One or both files are bigger than 16MB.\nThe IPS format doesn't support that.", + "REQUESTED_FILE_PATH_WAS_INVALID": "The requested file path was invalid.", + "PATCHING_CANCELED": "Patching canceled.", + "NOT_ENOUGH_MEMORY": "Not enough memory.", + "REGION_AMERICAS": "Amériques", + "REGION_AUSTRALIA": "Australie", + "REGION_BRAZIL": "Brésil", + "REGION_CHINA": "Chine", + "REGION_EUROPE": "Europe", + "REGION_FRANCE": "France", + "REGION_GERMANY": "Allemagne", + "REGION_ITALY": "Italie", + "REGION_JAPAN": "Japon", + "REGION_KOREA": "Corée", + "REGION_SPAIN": "Espagne", + "REGION_TAIWAN": "Taïwan", + "REGION_UNKNOWN": "Inconnu", + "REGION_UNITED_KINGDOM": "Royaume-Uni", + "REGION_MIDDLE_EAST": "Moyen-Orient", + "GENERATING_QR_CODE": "Generating QR code...", + "REINITIALIZING_SD_CARD": "Reinitializing SD card...", + "DUMPING_STATE_TO_SD_CARD": "Dumping state to SD card...", + "PRESS_POWER_TO_TURN_OFF": "Press POWER to turn off", + "CLEANING_UP_TITLES_PLEASE_WAIT": "Cleaning up titles, please wait...", + "ERROR_NOT_NCCH_FILE": "Error: Not an NCCH file", + "ERROR_FILE_IS_TOO_SMALL": "Error: File is too small", + "ATTEMPT_FIX_THIS_TIME": "Attempt fix this time", + "ATTEMPT_FIX_ALWAYS": "Attempt fix always", + "ABORT_VERIFICATION": "Abort verification", + "ERROR_BAD_CRYPTO_FLAGS": "Error: Bad crypto flags", + "ERROR_BAD_EXEFS_HEADER": "Error: Bad ExeFS header", + "ERROR_MISSING_EXTHEADER": "Error: Missing ExtHeader", + "ERROR_CRYPTO_NOT_SET_UP": "Error: Crypto not set up", + "PATH_NCCH_VERIFICATION_FAILED_INFO": "%s\nNCCH verification failed:\nExtHdr/ExeFS/RomFS: %s/%s/%s", + "OK": "ok", + "FAIL": "fail", + "ERROR_NOT_NCSD_FILE": "Error: Not an NCSD file", + "PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nContent%lu (%08lX@%08lX):\nVerification failed", + "ERROR_PROBABLY_NOT_CIA_FILE": "Error: Probably not a CIA file", + "ERROR_TMD_PROBABLY_CORRUPTED": "Error: TMD probably corrupted", + "PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nID %08lX (%08llX@%08llX)\nVerification failed", + "ERROR_CDN_TITLEKEY_NOT_FOUND": "Error: CDN titlekey not found", + "DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE": "DLC content is missing\n \nIgnore all and continue?", + "PATH_SECTION_N_HASH_MISMATCH": "%s\nSection %lu hash mismatch", + "ARM9_ENTRYPOINT_IS_MISSING": "ARM9 entrypoint is missing", + "WARNING_ARM11_ENTRYPOINT_IS_MISSING": "Warning: ARM11 entrypoint is missing", + "ERROR_NOT_A_BOSS_FILE": "Error: Not a BOSS file", + "BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT": "Mauvaise correspondance du\nhachage de la charge utile BOSS.\n \nTenter de le corriger ?", + "GENERIC_TICKET_PIRATE_LEGIT": "Generic ticket (\"pirate legit\")", + "PERSONALIZED_TICKET_LEGIT": "Personalized ticket (legit)", + "ID_N_LEGIT_TICKET_IS_PERSONALIZED_USING_THIS_NOT_RECOMMENDED_CHOOSE_DEFAULT_ACTION": "ID %016llX\nLegit ticket is personalized.\nUsing this is not recommended.\nChoose default action:", + "ID_N_TITLEKEY_NOT_FOUND": "ID %016llX\nTitlekey not found.", + "ID_N_TMD_IN_TAD_NOT_LEGIT": "ID %016llX\nTMD in TAD is not legit.", + "ID_N_TMD_NOT_LEGIT": "ID %016llX\nTMD is not legit.", + "ID_N_DOT_N_STATUS": "ID %016llX.%08lX\n%s", + "CONTENT_IS_CORRUPT": "Content is corrupt", + "INSERT_CONTENT_FAILED": "Insert content failed", + "INSTALL_CONTENT_FAILED": "Install content failed", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_DB_FILES_MAYBE_SD_MISSING_OR_UNINITIALIZED": "Install error:\nThis system is missing one or\nmore .db files.\n \nMaybe the SD card is missing\nor uninitialized?", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB": "Install error:\nThis system is missing the\nticket.db file.", + "SKIPPED_TITLE_0004008C000CBD00_NEEDS_SPECIAL_COMPILE_FLAGS": "Skipped title:\nTitle with id 0004008C000CBD00\nneeds special compiler flags.", + "ERROR_FAKE_SIGNED_TICKET_ONLY_VALID_SIGNED_TICKETS_CAN_BE_INSTALLED": "Error: Fake-signed ticket\n \nOnly valid signed tickets can\nbe installed to the system.", + "PATH_ERROR_UNKNOWN_CID_N_THIS_TICKET_DOES_NOT_BELONG_TO_THIS_3DS": "%s\nError: Unknown cid %08lX\n \nThis ticket does not belong to\nthis 3DS console.", + "INSTALLING_TICKET": "Installing ticket...", + "POSSIBLY_BROKEN": "Possibly Broken", + "PERSONAL_LEGIT": "Personal Legit", + "PERSONAL_LEGIT_DLC": "Personal Legit DLC", + "PERSONAL_PIRATE_LEGIT": "Personal Pirate Legit", + "PERSONAL_PIRATE_LEGIT_DLC": "Personal Pirate Legit DLC", + "PERSONAL_CUSTOM": "Personal Custom", + "PERSONAL_CUSTOM_DLC": "Personal Custom DLC", + "UNIVERSAL_LEGIT": "Universal Legit", + "UNIVERSAL_LEGIT_DLC": "Universal Legit DLC", + "UNIVERSAL_PIRATE_LEGIT": "Universal Pirate Legit", + "UNIVERSAL_PIRATE_LEGIT_DLC": "Universal Pirate Legit DLC", + "UNIVERSAL_CUSTOM": "Universal Custom", + "UNIVERSAL_CUSTOM_DLC": "Universal Custom DLC", + "CONTENTS_IN_CIA_FOUND_TOTAL": "Contents in CIA: %lu/%lu", + "CONTENTS_IN_CIA_TOTAL": "Contents in TMD: %lu", + "CONSOLE_ID_N": "Console ID: %08lX\n", + "SHOW_GAME_INFO_DETAILS": "%s\n%s %s Title\n \nTitle ID: %016llX\nTitle version: %lu.%lu.%lu\nContents size: %s\n%s\n%s \nTicket/TMD: %s/%s\nVerification: %s", + "STATE_LEGIT": "authentique", + "STATE_ILLEGIT": "inauthentique", + "STATE_UNKNOWN": "inconnu", + "STATE_INVALID": "invalide", + "STATE_PENDING_PROCEED_WITH_VERIFICATION": "pending\n \nProceed with verification?", + "STATE_PASSED": "passed", + "STATE_FAILED": "failed", + "OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS": "Output file already exists.\nUpdate this?", + "DSI_ENHANCED": "Optimisé DSi", + "DSI_EXCLUSIVE": "Exclusif DSi", + "FIXING_CMACS_PLEASE_WAIT": "Fixing CMACs, please wait...", + "NCSD_HEADER_IS_NOT_VALID": "NCSD header is not valid", + "NAND_DUMP_MISSING_DATA": "NAND dump missing data", + "ERROR_CTR_MBR_IS_CORRUPT": "Error: CTR MBR is corrupt", + "ERROR_TWL_MBR_IS_CORRUPT": "Error: TWL MBR is corrupt", + "PATH_ERROR_CTR_PARTITION_N_IS_CORRUPT": "%s\nErreur : La partition CTR%lu est corrompue", + "PATH_ERROR_TWL_PARTITION_N_IS_CORRUPT": "%s\nErreur : La partition TWL%lu est corrompue", + "NO_VALID_FIRM_FOUND": "Aucun FIRM valide n'a été trouvé", + "ERROR_NAND_DUMP_IS_CORRUPT_STILL_CONTINUE": "Erreur : Le dump de la NAND\nest corrompu.\nContinuer quand même ?", + "ERROR_SYSTEM_IS_LOCKED": "Erreur : Le système est verrouillé.", + "ESSENTIAL_FILES_BACKUP_IS_REQUIRED_CREATE_ONE_NOW": "Essential files backup is required.\nCreate one now?", + "WARNING_PROCEEDING_WILL_OVERWRITE_SYSNAND_WITH_DUMP": "!WARNING!\n \nProceeding will overwrite the\nSysNAND with the provided dump.\n \n(B9S/A9LH will be left intact.)", + "IMAGE_NCSD_CORRUPT_OR_CUSTOMIZED_SAFE_RESTORE_NOT_POSSIBLE": "Image NCSD corrupt or customized,\nsafe restore is not possible!", + "WARNING_NCSD_DIFFERS_BETWEEN_IMAGE_AND_LOCAL_ELEVATED_WRITE_PERMISSIONS_REQUIRED": "!WARNING!\n \nNCSD differs between image and local,\nelevated write permissions required\n \nProceed on your own risk?", + "NOT_AN_INSTALLABLE_FIRM": "Not a installable FIRM.", + "FIRM_LOAD_VERIFY_ERROR": "FIRM load/verify error.", + "PATH_FIRM_N_NOT_FOUND_OR_TOO_SMALL": "%s\nFIRM%lu not found or too small.", + "SECTOR_0X96_CRYPTO_FAIL": "Sector 0x96 crypto fail.", + "SECTOR_0X96_CORRUPTED_PROVIDE_SECRET_SECTOR_BIN_TO_FIX": "Sector 0x96 is corrupted.\n \nProvide \"secret_sector.bin\"\nto fix sector 0x96.", + "SECTOR_0X96_CORRUPTED_FIX_DURING_INSTALLATION": "Sector 0x96 is corrupted.\n \nFix sector 0x96 during\nthe installation?", + "WARNING_PROCEEDING_WILL_INSTALL_FIRM_TO_SYSNAND_AND_INJECT_SIGHAX_UNSUPPORTED_FIRM_WILL_BRICK": "!WARNING!\n \nProceeding will install the\nprovided FIRM to the SysNAND\nand inject sighax.\n \nInstalling an unsupported FIRM\nwill BRICK your console!", + "INSTALLING_FIRM_PLEASE_WAIT": "Installing FIRM, please wait...", + "THIS_IS_BAD_FAILED_WRITING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed writing sector 0x96.\nTry to fix before reboot!", + "THIS_IS_BAD_FAILED_WRITING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed writing FIRM%lu.\nTry to fix before reboot!", + "CHECKING_INSTALLATION_PLEASE_WAIT": "Checking installation, please wait...", + "THIS_IS_BAD_FAILED_VERIFYING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed verifying sector 0x96.\nTry to fix before reboot!", + "THIS_IS_BAD_FAILED_VERIFYING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed verifying FIRM%lu.\nTry to fix before reboot!", + "PERFECT_KEYDB_IS_ALREADY_INSTALLED": "Perfect %s is already installed!", + "PATH_NOT_PERFECT_KEYDB_IMAGE_CANNOT_INSTALL_TO_NAND": "%s\nNot a perfect %s image.\nCannot install to NAND!", + "PATH_FAILED_WRITING_KEYDB_TO_NAND": "%s\nFailed writing %s to NAND!", + "USE_L_R_TO_SAVE": "(utilisez L+R pour enregistrer)", + "EASTER_NOT_FOUND": "(%s not found)", + "BUILDING_TO_OUT_ARG": "Building to %s:\n%s ...", + "EJECT_SD_CARD": "Eject SD card...", + "INSERT_SD_CARD": "Insert SD card...", + "SCRIPTERR_UNKNOWN_CMD": "cmd inconnu", + "SCRIPTERR_BAD_NUMBER_OF_ARGS": "bad # of args", + "SCRIPTERR_UNRECOGNIZED_FLAGS": "unrecognized flags", + "SCRIPTERR_ILLEGAL_FLAG": "illegal flag", + "SCRIPTERR_UNRESOLVED_QUOTES": "unresolved quotes", + "SCRIPTERR_TOO_MANY_ARGUMENTS": "too many arguments", + "SCRIPTERR_ARGUMENT_EXPAND_FAILED": "argument expand failed", + "SCRIPTERR_QUOTE_NOT_AN_ERROR": "'not' an error", + "SCRIPTERR_SYNTAX_ERROR_AFTER_IF": "syntax error after 'if'", + "SCRIPTERR_ELIF_WITHOUT_IF": "'elif' without 'if'", + "SCRIPTERR_SYNTAX_ERROR_AFTER_ELIF": "erreur de syntaxe après 'elif'", + "SCRIPTERR_ELSE_WITHOUT_IF": "'else' sans 'if'", + "SCRIPTERR_END_WITHOUT_IF": "'end' sans 'if'", + "SCRIPTERR_FOR_INSIDE_FOR": "'for' dans un 'for'", + "SCRIPTERR_DIR_NOT_FOUND": "dir not found", + "SCRIPTERR_FOR_WITHOUT_NEXT": "'for' sans 'next'", + "SCRIPTERR_NEXT_WITHOUT_FOR": "'next' sans 'for'", + "SCRIPTERR_FORPATH_ERROR": "forpath error", + "SCRIPTERR_LABEL_NOT_FOUND": "label not found", + "SCRIPTERR_USER_ABORT": "user abort", + "SCRIPTERR_KEY_NOT_PRESSED": "key not pressed", + "SCRIPTERR_OUT_OF_MEMORY": "mémoire insuffisante" +} diff --git a/resources/languages/id.json b/resources/languages/id.json new file mode 100644 index 000000000..84a1d99ca --- /dev/null +++ b/resources/languages/id.json @@ -0,0 +1,809 @@ +{ + "GM9_LANGUAGE": "Bahasa Indonesia", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "(Thn-Bln-Hari) %1$s%2$02lX-%3$02lX-%4$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ".", + "THOUSAND_SEPARATOR": ",", + "FIRM_TOO_BIG": "FIRM terlalu besar, tak bisa di-boot", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nPeringatan: Jangan boot-kan FIRM\ndari sumber tidak jelas.\n \nBoot-kan FIRM?", + "NOT_BOOTABLE_FIRM": "Bukan FIRM bisa di-boot.", + "FIRM_ENCRYPTED": "FIRM terenkripsi.\n \nDekripsi-kan sebelum di-boot?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Buat salinan di %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Coba di-boot saja", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Peringatan: Mencoba mem-boot dari\nlokasi yang tak didukung.", + "ROOT": "[akar]", + "LOADING": "MEMUAT...", + "PANE_N": "PANEL #%lu", + "CURRENT": "SAAT INI", + "DIR": "(dir)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(Kandar-RAM FAT)", + "GAME_VIRTUAL": "(P'mainan Virtual)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND Virtual)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND Virtual)", + "IMAGE_FAT": "(Citra FAT)", + "XORPAD_VIRTUAL": "(XORpad Virtual)", + "MEMORY_VIRTUAL": "(Memori Virtual)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Kartrid Virtual)", + "VRAM_VIRTUAL": "(VRAM Virtual)", + "SEARCH": "(Cari)", + "TITLEMANAGER_VIRTUAL": "(TitleManager Virtual)", + "LAB_SDCARD": "KARTU SD", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUAL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUAL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "KARTRID", + "LAB_GAME_IMAGE": "CITRA P'MAINAN", + "LAB_AESKEYDB_IMAGE": "CITRA AESKEYDB", + "LAB_BDRI_IMAGE": "CITRA BDRI", + "LAB_DISA_DIFF_IMAGE": "CITRA DISA/DIFF", + "LAB_MEMORY_VIRTUAL": "MEMORI VIRTUAL", + "LAB_VRAM_VIRTUAL": "VRAM VIRTUAL", + "LAB_TITLE_MANAGER": "PENGELOLA JUDUL", + "LAB_LAST_SEARCH": "CARIAN TERAKHIR", + "LAB_FAT_IMAGE": "CITRA FAT", + "LAB_BONUS_DRIVE": "KANDAR BONUS", + "LAB_RAMDRIVE": "KANDAR-RAM", + "LAB_NOLABEL": "TANPA LABEL", + "N_BYTE": "%s Bita", + "BYTE": " Bita", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[PAPAN-KLIP]", + "PLUS_N_MORE": "+ %lu lagi", + "MARK_DELETE_COPY": "L - TANDAI berkas (dengan ↑↓→←)\nX - HAPUS / [+R] UBAH NAMA berkas\nY - SALIN berkas / [+R] BUAT entri\n", + "MARK_DELETE_PASTE": "L - TANDAI berkas (dengan ↑↓→←)\nX - HAPUS / [+R] UBAH NAMA berkas\nY - TEMPEL berkas / [+R] BUAT entri\n", + "RELOCK_WRITE_PERMISSION": "R+Y - Tutup lagi izin tulis\n", + "UNMOUNT_IMAGE": "R+X - Lepas mount citra\n", + "UNMOUNT_SD": "R+B - Lepas mount kartu SD\n", + "REMOUNT_SD": "R+B - Mount ulang kartu SD\n", + "DIRECTORY_OPTIONS": "R+A - Opsi direktori\n", + "DRIVE_OPTIONS": "R+A - Opsi kandar\n", + "MAKE_SCREENSHOT": "R+L - Tangkap layar\n", + "PREV_NEXT_PANE": "R+←→ - Pindah ke panel sblm/brkt\n", + "CLEAR_CLIPBOARD": "SELECT - Kosongkan Papan Klip\n", + "RESTORE_CLIPBOARD": "SELECT - Pulihkan Papan Klip\n", + "REBOOT_POWEROFF_HOME": "START - Boot ulang / [+R] Matikan daya\nHOME - untuk ke HOME menu", + "NO_EMUNAND": "Tak ada EmuNAND", + "REDNAND_SIZE_MIN": "Ukuran RedNAND (min)", + "GW_EMUNAND_SIZE_FULL": "Ukuran EmuNAND GW (penuh)", + "MULTINAND_SIZE_2X": "Ukuran MultiNAND (2x)", + "MULTINAND_SIZE_3X": "Ukuran MultiNAND (3x)", + "MULTINAND_SIZE_4X": "Ukuran MultiNAND (4x)", + "USER_INPUT": "Masukan pengguna...", + "AUTO": "Otomatis", + "16KB_CLUSTERS": "Gugus 16KB", + "32KB_CLUSTERS": "Gugus 32KB", + "64KB_CLUSTERS": "Gugus 64KB", + "SD_NOT_DETECTED": "Galat: Kartu SD tidak terbaca.", + "FORMAT_SD_CHOOSE_EMUNAND": "Formatkan kartu SD (%lluMB)?\nPilih ukuran EmuNAND:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "Ukuran kartu SD-nya %lluMB.\nMasukkan ukuran EmuNAND (MB) di bawah:", + "FORMAT_SD_CHOOSE_CLUSTER": "Formatkan kartu SD (%lluMB)?\nPilih ukuran gugusnya:", + "FORMAT_SD_ENTER_LABEL": "Formatkan kartu SD (%lluMB)?\nMasukkan label:", + "FORMAT_SD_FAILED": "Memformat SD: gagal!", + "REDNAND_TYPE": "Jenis RedNAND", + "REDNAND_TYPE_MULTI": "Jenis RedNAND (banyak)", + "REDNAND_TYPE_SINGLE": "Jenis RedNAND (tunggal)", + "GW_EMUNAND_TYPE": "Jenis EmuNAND GW", + "DONT_SET_UP": "Jangan diatur", + "CHOOSE_EMUNAND_TYPE": "Pilih jenis EmuNAND untuk diatur:", + "CLONE_SYSNAND_TO_REDNAND": "Klonakan SysNAND ke RedNAND?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "Mengklona SysNAND ke EmuNAND: gagal!", + "PRESS_A_TO_CONTINUE": "Tekan untuk lanjut", + "HEXEDITOR_CONTROLS": "Kendali Hexeditor:\n \n↑↓→←(+R) - Gulir\nR+Y - Ubah tampilan\nX - Cari / ke...\nA - Masuk mode sunting\nA+↑↓→← - Sunting nilai\nB - Keluar\n", + "NOT_FOUND": "Tak ditemukan!", + "GO_TO_OFFSET": "Masuk ke offset", + "SEARCH_FOR_STRING": "Cari untaian", + "SEARCH_FOR_DATA": "Cari data", + "CURRENT_OFFSET_SELECT_ACTION": "Offset saat ini: %08lX\nPilih tindakan:", + "CURRENT_OFFSET_ENTER_NEW": "Offset saat ini: %08lX\nMasukkan offset baru.", + "ENTER_SEARCH_REPEAT_SEARCH": "Masukkan untaian pencarian.\n(R+X - ulangi pencarian)", + "MADE_EDITS_SAVE_CHANGES": "Anda menyunting di %lu tempat.\nTulis ubahannya ke berkas?", + "FAILED_WRITING_TO_FILE": "Gagal menulis ke berkas!", + "CALCULATING_SHA_FAILED": "Memperhitung SHA-%s: gagal!", + "SHA_VERIFICATION_PASSED": "\nVerifikasi SHA: lolos!", + "SHA_VERIFICATION_FAILED": "\nVerifikasi SHA: gagal", + "IDENTICAL_WITH_PREVIOUS": "\n \nIdentik dengan berkas sebelumnya:\n", + "WRITE_SHA_FILE": "\n \nTulis berkas .SHA?", + "WRITE_SHA1_FILE": "\n \nTulis berkas .SHA1?", + "CALCULATING_CMAC_FAILED": "Memperhitung CMAC: gagal!", + "CMAC_VERIFICATION_PASSED": "Verifikasi CMAC: lolos!", + "CMAC_VERIFICATION_FAILED": "Verifikasi CMAC: gagal!", + "FIX_CMAC_IN_FILE": "\n \nPerbaiki CMAC di berkas?", + "FIXING_CMAC_FAILED": "Memperbaiki CMAC: gagal!", + "COPY_ALL_SELECTED_ITEMS": "Salin %lu butir terpilih?", + "FAILED_COPYING_ITEM": "Gagal menyalin butir", + "ITEMS_COPIED_TO_OUT": "%lu butir disalin ke %s", + "PATH_COPIED_TO_OUT": "%s\nDisalin ke %s", + "CART_INIT_FAILED": "Inisialisasi kartrid, gagal!", + "CART_DETECTED_SIZE_INPUT_BELOW": "Kartrid: %s\nUkuran terbaca: %s\n \nUkuran dump masukan di bawah.", + "NDS_CART_DECRYPT_SECURE_AREA": "Kartrid: %s\nKartrid NDS terbaca\nDekripsikan area aman?", + "FAILED_DUMPING_CART": "%s\nGagal men-dump kartrid", + "PATH_DUMPED_TO_OUT": "%s\nDi-dump ke %s", + "CREATED": "dibuat", + "MODIFIED": "diubah", + "ANALYZING_DRIVE": "Menganalisis kandar, mohon tunggu...", + "ANALYZING_DIR": "Menganalisis dir, mohon tunggu...", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu berkas & %lu subdirektori\njumlah ukuran %s\n \nruang luang: %s\nruang terpakai: %s\njumlah: %s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu berkas & %lu subdirektori\njumlah ukuran %s", + "FILESIZE_X": "ukuran-berkas: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %shanya baca [%c] %st'sembunyi\n[%c] %ssistem [%c] %sarsip\n[%c] %svirtual\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→← untuk ubah atribut)\n", + "A_TO_CONTINUE": "( untuk lanjut)", + "A_APPLY_B_CANCEL": "( - terapkan, - batal)", + "A_YES_B_NO": "( iya, tidak)", + "A_SELECT_B_CANCEL": "( pilih, batal)", + "HOLD_B_TO_CANCEL": "(tahan B untuk batal)", + "FAILED_TO_SET_ATTRIBUTES": "Gagal mengatur atribut!", + "NAND_IMAGE_OPTIONS": "Opsi citra NAND...", + "CTRNAND_OPTIONS": "Opsi CTRNAND...", + "MOUNT_FAT_IMAGE": "Mount sebagai citra FAT", + "CIA_IMAGE_OPTIONS": "Opsi citra CIA...", + "NCSD_IMAGE_OPTIONS": "Opsi citra NCSD...", + "NCCH_IMAGE_OPTIONS": "Opsi citra NCCH...", + "MOUNT_AS_EXEFS_IMAGE": "Mount sebagai citra EXEFS", + "MOUNT_AS_ROMFS_IMAGE": "Mount sebagai citra ROMFS", + "TMD_FILE_OPTIONS": "Opsi berkas TMD...", + "TMD_CDN_OPTIONS": "Opsi TMD/CDN...", + "TMD_TWL_OPTIONS": "Opsi TMD/TWL...", + "MANAGE_TITLE": "Kelola Judul...", + "BOSS_FILE_OPTIONS": "Opsi berkas BOSS...", + "DECRYPT_NUS_CDN_FILE": "Dekripsikan berkas NUS/CDN", + "SHOW_SMDH_TITLE_INFO": "Tampilkan info SMDH ini", + "NDS_IMAGE_OPTIONS": "Opsi citra NDS...", + "GBA_IMAGE_OPTIONS": "Opsi citra GBA...", + "TICKET_OPTIONS": "Opsi ticket...", + "TAD_IMAGE_OPTIONS": "Opsi citra TAD...", + "SHOW_3DSX_TITLE_INFO": "Tampilkan info 3DSX ini", + "FIRM_IMAGE_OPTIONS": "Opsi citra FIRM...", + "AGBSAVE_OPTIONS": "Opsi AGBSAVE...", + "DUMP_GBA_VC_SAVE": "Dump-kan simpanan GBA VC", + "TICKET_DB_OPTIONS": "Opsi Ticket.db ...", + "MOUNT_AS_DIFF_IMAGE": "Mount sebagai citra DIFF", + "MOUNT_AS_DISA_IAMGE": "Mount sebagai citra DISA", + "INSTALL_CIFINISH_BIN": "Pasang cifinish.bin", + "TITLEKEY_OPTIONS": "Opsi Titlekey...", + "AESKEYDB_OPTIONS": "Opsi AESkeydb...", + "BUILD_X": "Bina %s", + "NCCHINFO_OPTIONS": "Opsi NCCHinfo...", + "EXECUTE_GM9_SCRIPT": "Jalankan naskah GM9", + "FONT_OPTIONS": "Opsi fonta...", + "LANGUAGE_OPTIONS": "Ubah bahasa...", + "VIEW_PNG_FILE": "Lihat berkas PNG", + "REBUILD_NCSD_HEADER": "Bina ulang tajuk atas NCSD", + "SHOW_IN_HEXEDITOR": "Tampilkan di Hexeditor", + "CALCULATE_SHA256": "Perhitung SHA-256", + "CALCULATE_SHA1": "Perhitung SHA-1", + "SHOW_FILE_INFO": "Tampilkan info berkas", + "SHOW_IN_TEXTVIEWER": "Tampilkan di Textviewer", + "CALCULATE_CMAC": "Perhitung CMAC", + "COPY_TO_OUT": "Salin ke %s", + "DUMP_TO_OUT": "Dump-kan ke %s", + "INJECT_DATA_AT_OFFSET": "Suntik data @offset", + "OPEN_THIS_FOLDER": "Buka folder ini", + "OPEN_CONTAINING_FOLDER": "Buka folder yang berisi", + "OPEN_TITLE_FOLDER": "Buka folder judul", + "PATH_N_FILES_SELECTED": "%s\n(%lu berkas terpilih)", + "CHECK_CURRENT_CMAC_ONLY": "Periksa CMAC saat ini saja", + "VERIFY_CMAC_FOR_ALL": "Verifikasi CMAC semuanya", + "FIX_CMAC_FOR_ALL": "Perbaiki CMAC semuanya", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%lu berkasnya ok/diperbaiki/ditotal\n%lu/%lu tidak ada CMAC", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%lu berkas terverifikasi\n%lu/%lu berkas diperbaiki", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%lu berkas terverifikasi\n%lu/%lu tidak ada CMAC", + "N_OF_N_FILES_VERIFIED": "%lu/%lu berkas terverifikasi", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "Suntik data dari %s?\nTentukan offset di bawah.", + "FAILED_INJECTING_PATH": "Gagal menyuntik %s", + "MOUNT_CXI_NDS_TO_DRIVE": "Mount-kan CXI/NDS ke kandar", + "MOUNT_IMAGE_TO_DRIVE": "Mount-kan citra ke kandar", + "RESTORE_SYSNAND_SAFE": "Pulihkan SysNAND (cara aman)", + "UPDATE_EMBEDDED_BACKUP": "Perbarui cadangan tersemat", + "SHOW_TITLE_INFO": "Tampilkan info judul", + "DECRYPT_FILE": "Dekripsikan berkas (...)", + "DECRYPT_FILE_OUT": "Dekripsikan berkas (%s)", + "ENCRYPT_FILE": "Enkripsikan berkas (...)", + "ENCRYPT_FILE_OUT": "Enkripsikan berkas (%s)", + "BUILD_CIA_FROM_FILE": "Bina CIA dari berkas", + "BUILD_CIA_STANDARD": "Bina CIA (standar)", + "BUILD_CIA_LEGIT": "Bina CIA (autentik)", + "DUMP_CXI_NDS_FILE": "Dump-kan berkas CXI/NDS", + "INSTALL_GAME_IMAGE": "Pasang citra permainan", + "INSTALL_TICKET": "Pasang ticket", + "DUMP_TICKET_FILE": "Dump-kan berkas ticket", + "UNINSTALL_TITLE": "Copot judul p'mainan", + "VERIFY_FILE": "Verifikasi berkas", + "TRANSFER_IMAGE_TO_CTRNAND": "Transfer citra ke CTRNAND", + "INJECT_TO_H_AND_S": "Suntik ke H&S", + "TRIM_FILE": "Pangkas berkas", + "RENAME_FILE": "Ubah nama berkas", + "BUILD_XORPADS_SD": "Bina XORpads (keluaran SD)", + "BUILD_XORPADS_INPLACE": "Bina XORpads (di tempat)", + "EXTRACT_X": "Ekstrak %s", + "INIT_X": "Init %s", + "INSTALL_X": "Pasang %s", + "INSTALL_FIRM": "Pasang FIRM", + "BOOT_FIRM": "Boot-kan FIRM", + "SET_AS_ACTIVE_FONT": "Atur sebagai fonta aktif", + "SET_AS_ACTIVE_LANGUAGE": "Atur sebagai bahasa aktif", + "DUMP_BA_VC_SAVE": "Dump-kan simpanan GBA VC", + "INJECT_GBA_VC_SAVE": "Suntik simpanan GBA VC", + "SET_AS_DEFAULT": "Atur sebagai bawaan", + "MOUNTING_IMAGE_FAILED": "Me-mount citra: gagal", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nDi-mount sebagai kandar %s\nLihat isi jalur?", + "DECRYPT_TO_OUT": "Dekripsikan ke %s", + "DECRYPT_INPLACE": "Dekripsi di tempat", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "Mau dekripsikan %lu berkas terpilih?", + "TRYING_TO_DECRYPT_N_FILES": "Mencoba dekripsikan %lu berkas...", + "DECRYPTION_FAILED_CONTINUE": "Dekripsi, gagal\n \nLanjutkan?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu berkas terdekripsi\n%lu/%lu tidak dienkripsi\n%lu/%lu bukan jenis yang sama", + "N_OF_N_FILES_DECRYPTED": "%lu/%lu berkas terdekripsi", + "N_FILES_WRITTEN_TO_OUT": "%lu berkas ditulis ke %s", + "FILE_NOT_ENCRYPTED": "Berkas tidak dienkripsi", + "DECRYPTION_SUCCESS": "Dekripsi berhasil", + "DECRYPTION_FAILED": "Dekripsi, gagal", + "PATH_DECRYPTED_TO_OUT": "%s\nDidekripsi ke %s", + "ENCRYPT_TO_OUT": "Enkripsikan ke %s", + "ENCRYPT_INPLACE": "Enkripsi di tempat", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "Mau enkripsikan %lu berkas terpilih?", + "TRYING_TO_ENCRYPT_N_FILES": "Mencoba enkripsikan %lu berkas...", + "ENCRYPTION_FAILED_CONTINUE": "Enkripsi, gagal\n \nLanjutkan?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu berkas terenkripsi\n%lu/%lu bukan jenis yang sama", + "N_OF_N_FILES_ENCRYPTED": "%lu/%lu berkas terenkripsi", + "ENCRYPTION_SUCCESS": "Enkripsi berhasil", + "ENCRYPTION_FAILED": "Enkripsi, gagal", + "PATH_ENCRYPTED_TO_OUT": "%s\nDienkripsi ke %s", + "TRY_TO_PROCESS_N_SELECTED_FILES": "Mau olah %lu berkas terpilih?", + "PATH_BUILD_TYPE_FAILED_CONTINUE": "%s\nBinaan %s, gagal\n \nLanjutkan?", + "N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE": "%lu/%lu %s terbina\n%lu/%lu bukan jenis yang sama", + "N_OF_N_TYPES_BUILT": "%lu/%lu %s terbina", + "N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED": "Gagal mengonversi %lu berkas.\nDianjurkan melakukan verifikasi.", + "PATH_TYPE_BUILT_TO_OUT": "%s\n%s dibina ke %s", + "PATH_TYPE_BUILD_FAILED": "%s\nBinaan %s, gagal", + "FILE_FAILED_CONVERSION_VERIFY_NOW": "gagal mengonversi berkas.\n \nVerifikasikan?", + "VERIFICATION_SUCCESS": "Verifikasi berhasil", + "VERIFICATION_FAILED": "Verifikasi, gagal", + "CONTENT_IS_MISSING": "Isi berkas hilang", + "INSTALL_TO_SYSNAND": "Pasang ke SysNAND", + "INSTALL_TO_EMUNAND": "Pasang ke EmuNAND", + "TRY_TO_INSTALL_N_SELECTED_FILES": "Mau pasang %lu berkas terpilih?", + "TRYING_TO_INSTALL_N_FILES": "Mencoba pasang %lu berkas...", + "INSTALL_FAILED_CONTINUE": "Pemasangan, gagal\n \nLanjutkan?", + "N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu berkas terpasang\n%lu/%lu bukan jenis yang sama", + "N_OF_N_FILES_INSTALLED": "%lu/%lu berkas terpasang", + "INSTALL_SUCCESS": "Pemasangan berhasil", + "INSTALL_FAILED": "Pemasangan, gagal", + "FILE_FAILED_INSTALL_VERIFY_NOW": "gagal memasang berkas.\n \nVerifikasikan?", + "KEEP_TICKET_AND_SAVEGAME": "Biarkan ticket & simpanan", + "UNINSTALL_EVERYTHING": "Copot semuanya", + "ABORT_UNINSTALL": "Gugurkan pencopotan", + "UNINSTALL_N_SELECTED_TITLES": "Copot %lu judul terpilih?", + "UNINSTALL_SELECTED_TITLE": "Copot judul terpilih?", + "N_OF_N_TITLES_UNINSTALLED": "%lu/%lu judulnya dicopot", + "UNINSTALLING_PLEASE_WAIT": "Mencopot, mohon tunggu...", + "UNINSTALL_FAILED": "Pencopotan, gagal!", + "TRY_TO_VERIFY_N_SELECTED_FILES": "Mau verifikasikan %lu berkas terpilih?", + "VERIFICATION_FAILED_CONTINUE": "Verifikasi, gagal\n \nLanjutkan?", + "N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu berkas terverifikasi\n%lu/%lu bukan jenis yang sama", + "VERIFYING_FILE_PLEASE_WAIT": "Memverifikasi berkas, mohon tunggu...", + "NAND_VALIDATION_SUCCESS": "Pengabsahan NAND berhasil", + "NAND_VALIDATION_FAILED": "Pengabsahan NAND, gagal", + "DUMP_FOR_N_SELECTED_FILES": "Dump-kan %lu berkas terpilih?", + "N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL": "%lu/%lu ticket autentik di-dump.\n \nMau coba dump semua ticket?", + "N_OF_N_TICKETS_DUMPED_TO_OUT": "%lu/%lu ticket di-dump ke %s", + "PATH_TICKET_DUMPED_TO_OUT": "%s\nTicket di-dump ke %s", + "LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS": "%s\nTicket autentik tak ditemukan.\n \nDi-dump saja?", + "DUMP_TICKET_FAILED": "Membuat dump ticket, gagal!", + "BUILDING_X": "Membina %s...", + "BUILDING_X_SYSNAND": "Membina %s (SysNAND)...", + "BUILDING_X_EMUNAND": "Membina %s (EmuNAND)...", + "PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED": "%s\n%lu/%lu berkas diolah\n%lu/%lu berkas diabaikan", + "PATH_N_OF_N_FILES_PROCESSED": "%s\n%lu/%lu berkas diolah", + "BUILD_DATABASE_SUCCESS": "Pangkalan data berhasil dibina.", + "BUILD_DATABASE_FAILED": "Pangkalan data gagal dibina.", + "TRY_TO_TRIM_N_SELECTED_FILES": "Mau pangkas %lu berkas terpilih?", + "TRIMMING_FAILED_CONTINUE": "Pemangkasan, gagal\n \nLanjutkan?", + "N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED": "%lu/%lu berkas terpangkas\n%lu/%lu bukan jenis yang sama\n%s disimpan", + "N_OF_N_FILES_TRIMMED_X_SAVED": "%lu/%lu berkas terpangkas\n%s disimpan", + "FILE_CANT_BE_TRIMMED": "Berkas tak bisa dipangkas.", + "FILE_ALREADY_TRIMMED": "Berkas telah dipangkas.", + "PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE": "%s\nUkuran saat ini: %s\nSetelah pangkas: %s\nPerbedaan: %s\n \nPangkas berkas ini?", + "TRIMMING_FAILED": "Pemangkasan, gagal.", + "PATH_TRIMMED_BY_X": "%s\nDipangkas %s.", + "TRY_TO_RENAME_N_SELECTED_FILES": "Mau ubah nama %lu berkas terpilih?", + "N_OF_N_RENAMED": "%lu/%lu terubah nama", + "COULD_NOT_RENAME_TO_GOOD_NAME": "Tidak bisa diubah nama ke nama bagus", + "SYSNAND_H_AND_S_INJECT": "Suntik H&S di SysNAND", + "EMUNAND_H_AND_S_INJECT": "Suntik H&S di EmuNAND", + "H_AND_S_INJECT_SUCCESS": "H&S berhasil disuntik", + "H_AND_S_INJECT_FAILURE": "H&S gagal disuntik", + "TRY_EXTRACT_ALL_N_SELECTED_FILES": "Mau ekstrak %lu berkas terpilih?", + "N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu berkas terekstrak\n%lu/%lu bukan jenis yang sama", + "N_OF_N_FILES_EXTRACTED": "%lu/%lu berkas terekstrak", + "EXTRACTING_DOT_CODE": "Mengekstrak .code, mohon tunggu...", + "PATH_EXT_EXTRACTED_TO_OUT": "%s\n%s diekstrak ke %s", + "DOT_CODE_EXTRACT_FAILED": "Gagal mengekstrak .code", + "TRANSFER_TO_SYSNAND": "Transfer ke SysNAND", + "TRANSFER_TO_EMUNAND": "Transfer ke EmuNAND", + "CTRNAND_TRANSFER_SUCCESS": "Transfer CTRNAND, berhasil", + "CTRNAND_TRANSFER_FAILED": "Transfer CTRNAND, gagal", + "NO_VALID_DESTINATION_FOUND": "Tidak ada destinasi yang absah", + "NAND_RESTORE_SUCCESS": "Pemulihan NAND, berhasil", + "NAND_RESTORE_FAILED": "Pemulihan NAND, gagal", + "REBUILD_NCSD_SUCCESS": "Bina ulang NCSD, berhasil", + "REBUILD_NCSD_FAILED": "Bina ulang NCSD, gagal", + "PATH_NCCHINFO_PADGEN_SUCCESS": "%s\nPadgen dari NCCHinfo, berhasil%cDir keluaran: %s", + "PATH_NCCHINFO_PADGEN_FAILED": "%s\nPadgen dari NCCHinfo, gagal%c%0.0s", + "UPDATING_EMBEDDED_BACKUP": "Memperbarui cadangan tersemat...", + "BACKUP_UPDATE_NOT_REQUIRED": "Pembaruan cadangan: tak diperlukan", + "BACKUP_UPDATE_COMPLETED": "Pembaruan cadangan: selesai", + "BACKUP_UPDATE_FAILED": "Pembaruan cadangan: gagal!", + "WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK": "Peringatan: Key belum diverifikasi.\nTanggung risiko dan lanjutkan?", + "AESKEYDB_INIT_SUCCESS": "Init dari AESkeydb, berhasil", + "AESKEYDB_INIT_FAILED": "Init dari AESkeydb, gagal", + "AESKEYDB_INSTALL_SUCCESS": "Pemasangan AESkeydb, berhasil", + "AESKEYDB_INSTALL_FAILED": "Pemasangan AESkeydb, gagal", + "INSTALL_TO_FIRM0": "Pasang ke FIRM0", + "INSTALL_TO_FIRM1": "Pasang ke FIRM1", + "INSTALL_TO_BOTH": "Pasang ke keduanya", + "PATH_N_KB_INSTALL_TO_SYSNAND": "%s (%dkB)\nPasang ke SysNAND?", + "PATH_N_KB_INSTALL_SUCCESS": "%s (%dkB)\nPemasangan, berhasil", + "PATH_N_KB_INSTALL_FAILED": "%s (%dkB)\nPemasangan, gagal", + "WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS": "Peringatan: Jangan jalankan\nnaskah dari sumber tidak jelas.\n \nLaksanakan naskah?", + "SCRIPT_EXECUTE_SUCCESS": "Eksekusi naskah, berhasil", + "SCRIPT_EXECUTE_FAILURE": "Eksekusi naskah, gagal", + "ERROR_CANNOT_VIEW_FILE": "Galat: Berkas tak bisa dilihat\n(Peunjuk: mungkin terlalu besar)", + "SAVEGAME_DUMPED_TO_OUT": "Simpanan di-dump ke %s.", + "SAVEGAME_DUMP_FAILED": "Simpanan gagal di-dump!", + "GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD": "Simpanan GBA VC harus\nberada di papan klip.", + "SAVEGAME_INJECT_SUCCESS": "Simpanan berhasil disuntik.", + "SAVEGAME_INJECT_FAILED": "Simpanan gagal disuntik!", + "FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Fonta akan aktif pada boot berikutnya", + "LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Bahasa akan aktif pada boot berikutnya", + "HOME_MORE_MENU_SELECT_ACTION": "HOME - menu \"lagi...\"\nPilih tindakan:", + "SD_FORMAT_MENU": "Menu pemformatan SD", + "BONUS_DRIVE_MENU": "Penyiapan kandar bonus", + "SWITCH_EMUNAND": "Alihkan EmuNAND", + "BUILD_SUPPORT_FILES": "Bina berkas dukungan", + "RESTORE_H_AND_S": "Pulihkan H&S", + "SET_RTC_DATE_TIME": "Atur tanggal&waktu RTC", + "CONFGURE_BRIGHTNESS": "Konfigurasi kecerahan", + "CALIBRATE_TOUCHSCREEN": "Kalibrasi layar sentuh", + "SYSTEM_INFO": "Informasi sistem", + "SHOW_README": "Tampilkan ReadMe", + "INITIALIZING_SD_FAILED_RETRY": "Inisialisasi kartu SD, gagal! Coba lagi?", + "SETUP_FAILED": "Penyiapan, gagal!", + "CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT": "Offset EmuNAND saat ini %06lX.\nBeralih ke offset berikutnya?", + "BUILT_IN_OUT_STATUSES": "Dibina di %s:\n \n%-18.18s %s\n%-18.18s %s\n%-18.18s %s", + "OK_SYS_EMU": "OK (Sys&Emu)", + "OK_SYS": "OK (Sys)", + "FAILED": "Gagal", + "RESTORE_H_AND_S_EMUNAND": "Pulihkan H&S (EmuNAND)", + "RESTORE_H_AND_S_SYSNAND": "Pulihkan H&S (SysNAND)", + "TITLE_SET_RTC_DATE_TIME": "Atur tanggal&waktu RTC:", + "NEW_RTC_DATE_TIME_IS_TIME": "Tanggal&waktu RTC baru:\n%s\n \nPeunjuk: Waktu di HOMEMENU\nperlu disesuaikan manual\nsetelah mengatur RTC.", + "TOUCHSCREEN_CALIBRATION_SUCCESS": "Kalibrasi layar sentuh, berhasil!", + "TOUCHSCREEN_CALIBRATION_FAILED": "Kalibrasi layar sentuh, gagal!", + "GODMODE9_README_TOC": "Daftar Isi dari ReadMe GodMode9", + "ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW": "Cadangan berkas esensial tak ditemukan.\nMau buat baru?", + "BACKUP_EMBEDDED_WRITTEN_TO_OUT": "Cadangan disemat di SysNAND\ndan ditulis ke %s.", + "RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW": "Tanggal&waktu RTC terlihat\nsalah. Atur sekarang?", + "RESUME_GODMODE9": "Lanjut lagi GodMode9", + "RESUME_BOOTLOADER": "Lanjut lagi bootloader", + "SELECT_PAYLOAD": "Pilih payload...", + "SELECT_SCRIPT": "Pilih naskah...", + "POWEROFF_SYSTEM": "Matikan daya sistem", + "REBOOT_SYSTEM": "Boot ulang sistem", + "FLAVOR_BOOTLOADER_SELECT_OPTION": "Menu bootloader %s.\nPilih tindakan:", + "BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD": "Menu payload-bootloader.\nPilih payload:", + "BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT": "Menu naskah-bootloader.\nPilih skrip:", + "NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9": "Tidak ada FIRM bisa di-boot.\nGodMode9 dilanjutkan lagi...", + "OUT_OF_MEMORY": "Kehabisan memori.", + "INVALID_DIRECTORY_OBJECT": "Objek direktori tak absah", + "INVALID_ROOT_DIRECTORY": "Direktori akar tak absah.", + "WRITE_PERMISSIONS_WERE_CHANGED_RELOCK": "Izin penulisan telah diubah.\nTutup lagi izinnya?", + "OPEN_TITLE_MANAGER": "Buka pengelola judul", + "SEARCH_FOR_FILES": "Cari berkas...", + "FIX_CMACS_FOR_DRIVE": "Perbaiki CMAC untuk kandar", + "SHOW_DIRECTORY_INFO": "Tampilkan info direktori", + "SHOW_DRIVE_INFO": "Tampilkan info kandar", + "FAILED_SETTING_UP_TITLE_MANAGER": "Gagal menyiapkan pengelola judul!", + "SEARCH_FILE_ENTER_SEARCH_BELOW": "Cari %s?\nTulis pencarian di bawah.", + "FOUND_N_RESULTS": "Ditemukan %lu hasil.", + "FIX_CMACS_FOR_DRIVE_FINISHED": "Perbaikan CMAC untuk kandar, selesai.", + "FAILED_TO_ANALYZE_DRIVE": "Gagal menganalisis kandar\n", + "FAILED_TO_ANALYZE_DIR": "Gagal menganalisis dir\n", + "NOT_ALLOWED_IN_VIRTUAL_PATH": "Tidak boleh di jalur virtual", + "DELETE_N_PATHS": "Hapus %lu jalur?", + "DELETING_FILES_PLEASE_WAIT": "Menghapus berkas, mohon tunggu...", + "FAILED_DELETING_N_OF_N_PATHS": "Gagal menghapus %lu/%lu jalur", + "DELETE_FILE": "Hapus \"%s\"?", + "FAILED_DELETING_PATH": "Gagal menghapus:\n%s", + "NOT_ALLOWED_IN_SEARCH_DRIVE": "Tidak boleh di kandar pencarian", + "NOT_ALLOWED_IN_VIRTUAL_GAME_PATH": "Tidak boleh di jalur permainan virtual", + "NOT_ALLOWED_IN_XORPAD_DRIVE": "Tidak boleh di kandar XORpad", + "NOT_ALLOWED_IN_GAMECART_DRIVE": "Tidak boleh di kandar kartrid", + "NOT_ALLOWED_IN_ALIAS_PATH": "Tidak boleh di jalur alias", + "COPY_PATHS": "Salin jalur", + "MOVE_PATHS": "Pindahkan jalur", + "PASTE_FILE_HERE": "Tempel \"%s\" di sini?", + "PASTE_N_PATHS_HERE": "Tempel %lu jalur di sini?", + "FAILED_COPYING_PATH_PROCESS_REMAINING": "Gagal menyalin jalur:\n%s\nOlah saja sisanya?", + "FAILED_COPYING_PATH": "Gagal menyalin jalur:\n%s", + "FAILED_MOVING_PATH_PROCESS_REMAINING": "Gagal memindahkan jalur:\n%s\nOlah saja sisanya?", + "FAILED_MOVING_PATH": "Gagal memindahkan jalur:\n%s", + "RENAME_FILE_ENTER_NEW_NAME_BELOW": "Ubah nama %s?\nTulis nama baru di bawah.", + "FAILED_RENAMING_PATH": "Gagal mengubah nama jalur:\n%s", + "CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE": "Buat entri baru di sini?\nPilih jenis.", + "CREATE_A_FOLDER": "Buat folder", + "CREATE_A_DUMMY_FILE": "Buat berkas kosong", + "CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW": "Buat folder baru di sini?\nTulis namanya di bawah.", + "CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW": "Buat berkas baru di sini?\nTulis namanya di bawah.", + "CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW": "Buat %s baru di sini?\nTulis ukuran berkasnya.", + "FAILED_CREATING_FOLDER_PATH": "Gagal membuat folder:\n%s", + "FAILED_CREATING_FILE_PATH": "Gagal membuat berkas:\n%s", + "TITLE_MANAGER": "Pengelola judul", + "BRICK_MY_3DS": "Buat 3DS saya brick", + "LANGUAGE": "Bahasa...", + "SCRIPTS": "Naskah...", + "PAYLOADS": "Payload...", + "MORE": "Lagi...", + "BRACKET_MORE": "[lagi...]", + "HOME_BUTTON_PRESSED_SELECT_ACTION": "Tombol HOME ditekan.\nPilih tindakan:", + "POWER_BUTTON_PRESSED_SELECT_ACTION": "Tombol POWER ditekan.\nPilih tindakan:", + "1_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "4_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "A_DRIVE_SD_CARD": "[A:] KARTU SD", + "B_DRIVE_SD_CARD": "[B:] KARTU SD", + "TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE": "Menu pengelola judul.\nPilih sumber judul:", + "LANGUAGES_DIRECTORY_NOT_FOUND": "Direktori bahasa tak ditemukan.\n(jalur bawaan: 0:/gm9/%s)", + "SCRIPTS_DIRECTORY_NOT_FOUND": "Direktori naskah tak ditemukan.\n(jalur bawaan: 0:/gm9/%s)", + "HOME_LANGUAGE_MENU_SELECT_LANGUAGE": "HOME - menu \"bahasa...\"\nPilih bahasa:", + "HOME_SCRIPTS_MENU_SELECT_SCRIPT": "HOME - menu \"naskah...\"\nPilih naskah:", + "PAYLOADS_DIRECTORY_NOT_FOUND": "Direktori payload tak ditemukan.\n(jalur bawaan: 0:/gm9/%s)", + "HOME_PAYLOADS_MENU_SELECT_PAYLOAD": "HOME - menu \"payload...\"\nPilih payload:", + "UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT": "!Kartu SD tiba-tiba terlepas!\n \nKartu SD harus dilepas mount\ndahulu agar data tidak hilang.", + "FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT": "Menu naskah %s.\nPilih naskah:", + "COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP": "Dikompilasi jadi naskah auto-jalan\ntapi malah tidak ada naskah.\n \nKeliru!", + "KEYBOARD_CONTROLS_DETAILS": "Kendali Papan Ketik:\n \n←/→ - Geraki kursor\nR - Besar kecil (tahan)\nX - Hapus karakter\nY - Sisip karakter\nA - Kirim\nB - Batal\n \nSELECT - beralih ke\nprompt klasik", + "TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS": "Sentuh tanda bidik merah untuk\nkalibrasi layar sentuh.\n \nPakai stilus untuk hasil\nlebih bagus!", + "INVALID": "TAK ABSAH", + "TO_PROCEED_ENTER_THIS": "Untuk lanjut, tekan ini:", + "TO_PROCEED_HOLD_X": "Untuk lanjut, tahan :", + "N_MORE": " [%d lagi]", + "CANCEL": "batal", + "R_FAST_SCROLL_L_CLEAR_DATA": "R - (↑↓) gulir cepat\nL - kosongkan data", + "X_REMOVE_CHAR_Y_INSERT_CHAR": "X - hapus karakter\nY - sisip karakter", + "ETA_N_MIN_N_SEC": "Sisa %02llumnt%02lludtk", + "BRIGHTNESS_CONTROLS": "[←] Kurangi kecerahan\n[→] Tingkatkan kecerahan\n \n[X] Pakai penggeser volume\n[A] Atur kecerahan saat ini\n[B] Batal", + "SEARCHING_PLEASE_WAIT": "Mencari, mohon tunggu...", + "RENAME_TO_GOOD_NAME": "Ubah nama ke nama bagus?", + "SD_WRITE_PROTECTED_CANT_CONTINUE": "Penulisan kartu SD dikunci!\nTidak bisa lanjut.", + "SYSNAND_LVL_N": "SysNAND (lvl%lu)", + "EMUNAND_LVL_N": "EmuNAND (lvl%lu)", + "GAME_IMAGES": "citra permainan", + "GAMECART_SAVES": "simpanan kartrid", + "IMAGES": "citra", + "MEMORY_AREAS": "area memori", + "SD_SYSTEM_DATA": "Data sistem SD", + "SD_CARD": "Kartu SD", + "RAM_DRIVE": "Kandar RAM", + "WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW": "Menulis ke %s sudah dikunci!\nBuka izinnya?", + "UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED": "Membuka izin penulisan untuk\n%s tidak diizinkan.", + "ENABLE_BASE_WRITE": "Anda ingin mengaktifkan\nizin penulisan dasar.", + "ENABLE_SD_WRITE": "Anda ingin mengaktifkan\nizin penulisan kartu SD.", + "ENABLE_IMAGE_WRITE": "Anda ingin mengaktifkan\nizin penulisan citra.", + "ENABLE_RAM_DRIVE_WRITE": "Anda ingin mengaktifkan\nizin penulisan kandar RAM.", + "ENABLE_EMUNAND_0_WRITE": "Anda ingin mengaktifkan\nizin penulisan lvl0 EmuNAND.", + "ENABLE_SYSNAND_0_WRITE": "Anda ingin mengaktifkan\nizin penulisan lvl0 SysNAND.", + "ENABLE_EMUNAND_1_WRITE": "Anda ingin mengaktifkan\nizin penulisan lvl1 EmuNAND.\n \nIni mengizinkan data sistem\nyang bisa dipulih, data pengguna\n& simpanan bisa diubah.", + "ENABLE_SYSNAND_1_WRITE": "Anda ingin mengaktifkan\nizin penulisan lvl1 SysNAND.\n \nIni mengizinkan data sistem\nyang bisa dipulih, data pengguna\n& simpanan bisa diubah.", + "ENABLE_GAMECART_SAVE_WRITE": "Anda ingin mengaktifkan izin\npenulisan simpanan kartrid.", + "ENABLE_SYSNAND_2_WRITE": "!Harus hati-hati!\n \nAnda ingin mengaktifkan\nizin penulisan lvl2 SysNAND.\n \nIni mengizinkan data sistem\ntak terpulihkan bisa diubah!", + "ENABLE_MEMORY_WRITE": "!Harus hati-hati!\n \nAnda ingin mengaktifkan\nizin penulisan memori.\n \nMenulis ke area tertentu akan\nberakibat hasil yang tak terduga.", + "ENABLE_SD_DATA_WRITE": "!SANGAT TIDAK DIANJURKAN!\n \nAnda ingin mengaktifkan\nizin penulisan kartu SD.\n \nBerkas di sini terenkripsi semua.\nDianjurkan memakai kandar\nA:/B: jika ingin memodifikasi\npemasangan, data pengguna &\nsimpanan permainan saja.", + "ENABLE_SYSNAND_3_WRITE": "!PERINGATAN, SANGAT BAHAYA!\n \nIzin penulisan lvl3 ke\nSysNAND akan diaktifkan.\n \nIni mengizikan pemasangan\nbootloader dan berkas sistem\nesensial bisa DITIMPA, dan/\natau MERUSAK PARAH konsol!", + "UNLOCK_WRITE_NOT_ALLOWED": "Membuka izin penulisan tidak diizinkan.", + "CANT_UNLOCK_WRITE_TRY_GODMODE9": "Tidak bisa membuka izin tulis.\nCoba dengan GodMode9!", + "ERROR_SD_TOO_SMALL": "Galat: Ukuran kartu SD kecil sekali", + "WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA": "!PERINGATAN!\n \nJika lanjut, kartu SD ini akan\ndiformat. SEMUA datanya\nakan dihapus permanen.", + "FORMAT_BONUS_DRIVE_DELETE_ALL_DATA": "Formatkan kandar bonus?\nSEMUA datanya akan\ndihapus permanen.", + "FORMATTING_SD_PLEASE_WAIT": "Memformat kartu SD, mohon tunggu...", + "FORMATTING_DRIVE_PLEASE_WAIT": "Memformat kandar, mohon tunggu...", + "ERROR_SD_CARD_IO_FAILURE": "Galat: I/O kartu SD, gagal", + "FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK": "Berkas sedang di-mount.\nLepas mount untuk buka izin?", + "ERROR_CANT_INJECT_FILE_INTO_ITSELF": "Galat: Tak bisa disuntik\nke berkas itu sendiri", + "OPERATION_WOULD_WRITE_BEYOND_EOF": "Operasi akan menulis melebihi ujung berkas", + "NOT_ENOUGH_DATA_IN_FILE": "Tidak cukup data dalam berkas", + "CANCEL_IS_NOT_ALLOWED_HERE": "Di sini tidak diziinkan batal", + "B_DETECTED_CANCEL": "Terdeteksi tombol B. Batalkan?", + "ERROR_CANNOT_APPEND_FOLDER": "Galat: Tidak bisa membubuh folder", + "ERROR_OVERWRITING_FILE_WITH_DIR": "Galat: Menimpa berkas dengan dir", + "ERROR_OVERWRITING_DIR_WITH_FILE": "Galat: Menimpa dir dengan berkas", + "ERROR_CANNOT_OPEN_DESTINATION_FILE": "Galat: Berkas destinasi tak bisa dibuka", + "ERROR_NOT_ENOUGH_SPACE_AVAILABLE": "Galat: Tidak tersedia cukup ruang", + "ERROR_ONLY_FAT_FILES_CAN_BE_MOVED": "Galat: Hanya berkas FAT\nyang bisa dipindah", + "ERROR_DESTINATION_IS_PART_OF_ORIGIN": "Galat: Destinasi tadi\nbagian dari asalnya", + "ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME": "Destinasi tadi sama seasalnya\nPilih nama yang lain?", + "CHOOSE_NEW_NAME": "Pilih nama baru", + "OVERWRITE_FILES": "Timpa berkas", + "SKIP_FILES": "Lewati berkas", + "OVERWRITE_ALL": "Timpa semua", + "SKIP_ALL": "Lewati semua", + "DESTINATION_ALREADY_EXISTS": "Destinasi sudah ada:\n%s", + "CHOOSE_NEW_DESTINATION_NAME": "Pilih nama destinasi baru", + "COPY_OPERATION_IS_NOT_ALLOWED": "Penyalinan ini tidak diizinkan", + "DESTINATION_EQUALS_ORIGIN": "Destinasi tadi sama seasalnya", + "ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD": "Entri tak ditemukan: %s\nSuntik ke %s saja?", + "FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE": "Berkas lebih kecil dari ruang yang ada:\n%s (%s)\n%s (%s)\nLanjutkan?", + "NO_USABLE_ENTRIES_FOUND": "Tidak ada entri yang bisa dipakai.", + "BEAT_NO_ERROR": "Tak ada galat", + "BEAT_END_OF_ACTION_LIST": "Ujung daftar tindakan", + "BEAT_ABORTED_BY_USER": "Digugurkan pengguna", + "BEAT_FAILED_TO_READ_WRITE_FILE": "Gagal membaca/nulis berkas", + "BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF": "Berusaha menulis melebihi ujung berkas", + "BEAT_INVALID_PATCH_FILE": "Tambalan tak absah", + "BEAT_INVALID_INPUT_FILE": "Berkas masukan tak absah", + "BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH": "Jumlah-periksa berkas\nkeluaran tak cocok", + "BEAT_FILE_CHECKSUM_FAILED": "Jumlah-periksa berkas, gagal", + "BEAT_EXPECTED_MORE_PATCH_DATA": "Diharapkan lebih banyak\ndata tambalan", + "BEAT_OUT_OF_MEMORY": "Kehabisan memori", + "BEAT_UNKNOWN_ERROR": "Galat tak diketahui", + "FAILED_TO_INITIALIZE_BPM_FILE": "Gagal me'inisialisasi berkas BPM:\n%s", + "FAILED_TO_INITIALIZE_BPS_FILE": "Gagal me'inisialisasi berkas BPS:\n%s", + "PATCH_SUCCESSFULLY_APPLIED": "Tambalan berhasil diterapkan", + "PATCHING_ABORTED_BY_USER": "Penambalan digugurkan pengguna", + "FAILED_TO_RUN_PATCH": "Gagal menjalankan tambal:\n%s", + "DECOMPRESSING_DOT_CODE": "Melepas pampat .code...", + "DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Melepas pampat .code...\nTombol B terdeteksi. Batalkan?", + "COMPRESSING_DOT_CODE": "Memampat .code...", + "COMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Memampat.code...\nTombol B terdeteksi. Batalkan?", + "PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE": "Tambalan ini kemungkinan tidak ditujukan\nuntuk berkas ini.", + "YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT": "Kemungkinan Anda menerapkan tambalan\nke berkas keluaran.", + "PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED": "Tambalan secara teknis absah,\ntapi terlihat kacau atau amburadul.", + "PATCH_IS_INVALID": "Tambalan ini tidak absah.", + "FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT": "Ada satu atau dua berkas yang lebih dari 16MB.\nFormat IPS tidak mendukung ukuran itu.", + "REQUESTED_FILE_PATH_WAS_INVALID": "Jalur berkas yang diminta tidak absah.", + "PATCHING_CANCELED": "Penambalan dibatalkan.", + "NOT_ENOUGH_MEMORY": "Memori tidak cukup.", + "REGION_AMERICAS": "Amerika", + "REGION_AUSTRALIA": "Australia", + "REGION_BRAZIL": "Brazil", + "REGION_CHINA": "Tiongkok", + "REGION_EUROPE": "Eropa", + "REGION_FRANCE": "Prancis", + "REGION_GERMANY": "Jerman", + "REGION_ITALY": "Italia", + "REGION_JAPAN": "Jepang", + "REGION_KOREA": "Korea", + "REGION_SPAIN": "Spanyol", + "REGION_TAIWAN": "Taiwan", + "REGION_UNKNOWN": "Tak diketahui", + "REGION_UNITED_KINGDOM": "Inggris Raya", + "REGION_MIDDLE_EAST": "Timur Tengah", + "GENERATING_QR_CODE": "Membuat kode QR...", + "REINITIALIZING_SD_CARD": "Inisialisasi ulang kartu SD...", + "DUMPING_STATE_TO_SD_CARD": "Men-dump status ke kartu SD...", + "PRESS_POWER_TO_TURN_OFF": "Tekan POWER untuk matikan daya", + "CLEANING_UP_TITLES_PLEASE_WAIT": "Membersihkan judul, mohon tunggu...", + "ERROR_NOT_NCCH_FILE": "Galat: Bukan berkas NCCH", + "ERROR_FILE_IS_TOO_SMALL": "Galat: Ukuran berkas kecil sekali", + "ATTEMPT_FIX_THIS_TIME": "Kali ini coba diperbaiki", + "ATTEMPT_FIX_ALWAYS": "Selalu coba diperbaiki", + "ABORT_VERIFICATION": "Gugurkan verifikasi", + "ERROR_BAD_CRYPTO_FLAGS": "Galat: Panji crypto buruk", + "ERROR_BAD_EXEFS_HEADER": "Galat: Tajuk atas ExeFS buruk", + "ERROR_MISSING_EXTHEADER": "Galat: ExtHeader hilang", + "ERROR_CRYPTO_NOT_SET_UP": "Galat: Crypto belum disiapkan", + "PATH_NCCH_VERIFICATION_FAILED_INFO": "%s\nVerifikasi NCCH, gagal:\nExtHdr/ExeFS/RomFS: %s/%s/%s", + "OK": "ok", + "FAIL": "gagal", + "ERROR_NOT_NCSD_FILE": "Galat: Bukan berkas NCSD", + "PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nIsi berkas%lu (%08lX@%08lX):\nVerifikasi, gagal", + "ERROR_PROBABLY_NOT_CIA_FILE": "Galat: Mungkin bukan berkas CIA", + "ERROR_TMD_PROBABLY_CORRUPTED": "Galat: TMD mungkin rusak", + "PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nID %08lX (%08llX@%08llX)\nVerifikasi, gagal", + "ERROR_CDN_TITLEKEY_NOT_FOUND": "Galat: Titlekey CDN tak ditemukan", + "DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE": "Konten DLC tidak ada\n \nAbaikan semua dan lanjut?", + "PATH_SECTION_N_HASH_MISMATCH": "%s\nHash bagian %lu tak cocok", + "ARM9_ENTRYPOINT_IS_MISSING": "Titik masuk ARM9 hilang", + "WARNING_ARM11_ENTRYPOINT_IS_MISSING": "Peringatan: Titik masuk ARM11 hilang", + "ERROR_NOT_A_BOSS_FILE": "Galat: Bukan berkas BOSS", + "BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT": "Hash payload BOSS tak cocok.\n \nMau coba perbaiki?", + "GENERIC_TICKET_PIRATE_LEGIT": "Ticket generik (\"autentik bajakan\")", + "PERSONALIZED_TICKET_LEGIT": "Ticket tepersonalisasi (autentik)", + "ID_N_LEGIT_TICKET_IS_PERSONALIZED_USING_THIS_NOT_RECOMMENDED_CHOOSE_DEFAULT_ACTION": "ID %016llX\nTicket autentik dipersonalisasi.\nIni tidak dianjurkan dipakai.\nPilih tindakan bawaan:", + "ID_N_TITLEKEY_NOT_FOUND": "ID %016llX\nTitlekey tak ditemukan.", + "ID_N_TMD_IN_TAD_NOT_LEGIT": "ID %016llX\nTMD di TAD tidak autentik.", + "ID_N_TMD_NOT_LEGIT": "ID %016llX\nTMD tidak autentik.", + "ID_N_DOT_N_STATUS": "ID %016llX.%08lX\n%s", + "CONTENT_IS_CORRUPT": "Isi berkas rusak", + "INSERT_CONTENT_FAILED": "Menyisip isi berkas, gagal", + "INSTALL_CONTENT_FAILED": "Memasang isi berkas, gagal", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_DB_FILES_MAYBE_SD_MISSING_OR_UNINITIALIZED": "Galat pasang:\nSistem ini kehilangan satu\natau lebih berkas .db.\n \nMungkin kartu SD hilang\natau belum inisialiasi?", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB": "Galat pasang:\nSistem ini kehilangan\nberkas ticket.db.", + "SKIPPED_TITLE_0004008C000CBD00_NEEDS_SPECIAL_COMPILE_FLAGS": "Judul dilewati:\nJudul ber-ID 0004008C000CBD00\nperlu panji kompilator khusus.", + "ERROR_FAKE_SIGNED_TICKET_ONLY_VALID_SIGNED_TICKETS_CAN_BE_INSTALLED": "Galat: Ticket terdaftar-palsu\n \nHanya ticket terdaftar-absah\nyang bisa dipasang ke sistem.", + "PATH_ERROR_UNKNOWN_CID_N_THIS_TICKET_DOES_NOT_BELONG_TO_THIS_3DS": "%s\nGalat: CID tak diketahui %08lX\n \nTicker ini bukan milik\nkonsol 3DS ini.", + "INSTALLING_TICKET": "Memasang ticket...", + "POSSIBLY_BROKEN": "Kemungkinan Rusak", + "PERSONAL_LEGIT": "Autentik Pribadi", + "PERSONAL_LEGIT_DLC": "DLC Autentik Pribadi", + "PERSONAL_PIRATE_LEGIT": "Autentik Bajakan Pribadi", + "PERSONAL_PIRATE_LEGIT_DLC": "DLC Autentik Bajakan Pribadi", + "PERSONAL_CUSTOM": "Kustom Pribadi", + "PERSONAL_CUSTOM_DLC": "DLC Kustom Pribadi", + "UNIVERSAL_LEGIT": "Autentik Universal", + "UNIVERSAL_LEGIT_DLC": "DLC Autentik Universal", + "UNIVERSAL_PIRATE_LEGIT": "Autentik Bajakan Universal", + "UNIVERSAL_PIRATE_LEGIT_DLC": "DLC Autentik Bajakan Universal", + "UNIVERSAL_CUSTOM": "Kustom Universal", + "UNIVERSAL_CUSTOM_DLC": "DLC Kustom Universal", + "CONTENTS_IN_CIA_FOUND_TOTAL": "Isi berkas di CIA: %lu/%lu", + "CONTENTS_IN_CIA_TOTAL": "Isi berkas di TMD: %lu", + "CONSOLE_ID_N": "ID Konsol: %08lX\n", + "SHOW_GAME_INFO_DETAILS": "%s\nJudul ini %s %s\n \nID judul: %016llX\nVersi judul: %lu.%lu.%lu\nUkuran isi: %s\n%s\n%s \nTicket/TMD: %s/%s\nVerifikasi: %s", + "STATE_LEGIT": "autentik", + "STATE_ILLEGIT": "tak autentik", + "STATE_UNKNOWN": "tak diketahui", + "STATE_INVALID": "tak absah", + "STATE_PENDING_PROCEED_WITH_VERIFICATION": "menunda\n \nLanjut dengan verifikasi?", + "STATE_PASSED": "lolos", + "STATE_FAILED": "gagal", + "OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS": "Berkas keluaran sudah ada.\nPerbarui ini?", + "DSI_ENHANCED": "DSi Enhanced", + "DSI_EXCLUSIVE": "DSi Exclusive", + "FIXING_CMACS_PLEASE_WAIT": "Memperbaiki CMAC, mohon tunggu...", + "NCSD_HEADER_IS_NOT_VALID": "Tajuk atas NCSD tidak absah", + "NAND_DUMP_MISSING_DATA": "Dump dari NAND ada data hilang", + "ERROR_CTR_MBR_IS_CORRUPT": "Galat: MBR di CTR rusak", + "ERROR_TWL_MBR_IS_CORRUPT": "Galat: MBR di TWL rusak", + "PATH_ERROR_CTR_PARTITION_N_IS_CORRUPT": "%s\nGalat: Partisi CTR%lu rusak", + "PATH_ERROR_TWL_PARTITION_N_IS_CORRUPT": "%s\nGalat: Partisi TWL%lu rusak", + "NO_VALID_FIRM_FOUND": "Tidak ada FIRM yang absah", + "ERROR_NAND_DUMP_IS_CORRUPT_STILL_CONTINUE": "Galat: Dump dari NAND, rusak.\nTetap lanjutkan?", + "ERROR_SYSTEM_IS_LOCKED": "Galat: Sistem dikunci.", + "ESSENTIAL_FILES_BACKUP_IS_REQUIRED_CREATE_ONE_NOW": "Cadangan berkas esensial diperlukan.\nMau buat baru?", + "WARNING_PROCEEDING_WILL_OVERWRITE_SYSNAND_WITH_DUMP": "!PERINGATAN!\n \nProses ini akan menimpa SysNAND\ndengan dump yang ditaruh.\n \n(B9S/A9LH akan dibiarkan utuh)", + "IMAGE_NCSD_CORRUPT_OR_CUSTOMIZED_SAFE_RESTORE_NOT_POSSIBLE": "Citra NCSD sudah rusak atau diubah suai,\npemulihan aman tidak akan bisa!", + "WARNING_NCSD_DIFFERS_BETWEEN_IMAGE_AND_LOCAL_ELEVATED_WRITE_PERMISSIONS_REQUIRED": "PERINGATAN!\n \nNCSD berbeda antara citra dan lokal,\nperlu izin tulis yang lebih tinggi\n \nTanggung risiko dan lanjutkan?", + "NOT_AN_INSTALLABLE_FIRM": "Bukan FIRM bisa dipasang.", + "FIRM_LOAD_VERIFY_ERROR": "Muat/verifikasi FIRM, galat.", + "PATH_FIRM_N_NOT_FOUND_OR_TOO_SMALL": "%s\nFIRM%lu tak ditemukan atau kecil sekali.", + "SECTOR_0X96_CRYPTO_FAIL": "Crypto sektor 0x96, gagal.", + "SECTOR_0X96_CORRUPTED_PROVIDE_SECRET_SECTOR_BIN_TO_FIX": "Sektor 0x96 rusak.\n \nSediakan \"secret_sector.bin\"\nuntuk perbaiki sektor 0x96.", + "SECTOR_0X96_CORRUPTED_FIX_DURING_INSTALLATION": "Sektor 0x96 rusak.\n \nPerbaiki sektor 0x96 selama\npemasangan?", + "WARNING_PROCEEDING_WILL_INSTALL_FIRM_TO_SYSNAND_AND_INJECT_SIGHAX_UNSUPPORTED_FIRM_WILL_BRICK": "!PERINGATAN!\n \nJika lanjut, FIRM yang ditaruh\nakan dipasang ke SysNAND\ndan menyuntik sighax.\n \nMemasang FIRM tak didukung\nakan MERUSAK PARAH konsol!", + "INSTALLING_FIRM_PLEASE_WAIT": "Memasang FIRM, mohon tunggu...", + "THIS_IS_BAD_FAILED_WRITING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!WAH BAHAYA!\n \nGagal menulis sektor 0x96.\nPerbaiki sebelum di-boot ulang!", + "THIS_IS_BAD_FAILED_WRITING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!WAH BAHAYA!\n \nGagal menulis FIRM%lu.\nPerbaiki sebelum di-boot ulang!", + "CHECKING_INSTALLATION_PLEASE_WAIT": "Memeriksa pemasangan, mohon tunggu...", + "THIS_IS_BAD_FAILED_VERIFYING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!WAH BAHAYA!\n \nGagal memverif' sektor 0x96.\nPerbaiki sebelum di-boot ulang!", + "THIS_IS_BAD_FAILED_VERIFYING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!WAH BAHAYA!\n \nGagal memverif' FIRM%lu.\nPerbaiki sebelum di-boot ulang!", + "PERFECT_KEYDB_IS_ALREADY_INSTALLED": "%s sempurna telah terpasang!", + "PATH_NOT_PERFECT_KEYDB_IMAGE_CANNOT_INSTALL_TO_NAND": "%s\nBukan citra %s sempurna.\nTak bisa dipasang ke NAND!", + "PATH_FAILED_WRITING_KEYDB_TO_NAND": "%s\nGagal menulis %s ke NAND!", + "USE_L_R_TO_SAVE": "(simpan dengan L+R)", + "EASTER_NOT_FOUND": "(%s tak ditemukan)", + "BUILDING_TO_OUT_ARG": "Membina ke %s:\n%s ...", + "EJECT_SD_CARD": "Keluarkan kartu SD...", + "INSERT_SD_CARD": "Sisipkan kartu SD...", + "SCRIPTERR_UNKNOWN_CMD": "cmd tak diketahui", + "SCRIPTERR_BAD_NUMBER_OF_ARGS": "ada # arg buruk", + "SCRIPTERR_UNRECOGNIZED_FLAGS": "panji tak dikenali", + "SCRIPTERR_ILLEGAL_FLAG": "panji ilegal", + "SCRIPTERR_UNRESOLVED_QUOTES": "kutipan blm dipecahkan", + "SCRIPTERR_TOO_MANY_ARGUMENTS": "terlalu banyak argumen", + "SCRIPTERR_ARGUMENT_EXPAND_FAILED": "perluas argumen, gagal", + "SCRIPTERR_QUOTE_NOT_AN_ERROR": "galat kata 'not'", + "SCRIPTERR_SYNTAX_ERROR_AFTER_IF": "galat sintaks setelah 'if'", + "SCRIPTERR_ELIF_WITHOUT_IF": "'elif' tanpa 'if'", + "SCRIPTERR_SYNTAX_ERROR_AFTER_ELIF": "galat sintaks setelah 'elif'", + "SCRIPTERR_ELSE_WITHOUT_IF": "'else' tanpa 'if'", + "SCRIPTERR_END_WITHOUT_IF": "'end' tanpa 'if'", + "SCRIPTERR_FOR_INSIDE_FOR": "'for' di dalam 'for'", + "SCRIPTERR_DIR_NOT_FOUND": "dir tak ditemukan", + "SCRIPTERR_FOR_WITHOUT_NEXT": "'for' tanpa 'next'", + "SCRIPTERR_NEXT_WITHOUT_FOR": "'next' tanpa 'for'", + "SCRIPTERR_FORPATH_ERROR": "galat forpath", + "SCRIPTERR_LABEL_NOT_FOUND": "label tak ditemukan", + "SCRIPTERR_USER_ABORT": "gugurkan pengguna", + "SCRIPTERR_KEY_NOT_PRESSED": "tombol belum ditekan", + "SCRIPTERR_OUT_OF_MEMORY": "kehabisan memori", + "SCRIPTERR_VAR_FAIL": "peubah gagal", + "SCRIPTERR_FORBIDDEN_DRIVE": "kandar terlarang", + "SCRIPTERR_INVALID_PATH": "jalur tidak absah", + "SCRIPTERR_FILESELECT_ABORT": "gugurkan pilih-berkas", + "SCRIPTERR_DIRSELECT_ABORT": "gugurkan pilih-dir", + "SCRIPTERR_SET_FAIL": "atur gagal", + "SCRIPTERR_CHAR_NOT_FOUND": "char tak ditemukan", + "SCRIPTERR_ARGV_2_IS_NOT_CHAR": "argv[2] bukan huruf char", + "SCRIPTERR_ARGV_2_MUST_BE_2_CHARS": "argv[2] harus 2 karakter", + "SCRIPTERR_ARG_MATCH": "arg cocok", + "SCRIPTERR_NO_ARG_MATCH": "tak ada arg cocok", + "SCRIPTERR_PERMISSION_FAIL": "izin gagal", + "SCRIPTERR_COPY_FAIL": "salin gagal", + "SCRIPTERR_MOVE_FAIL": "pindah gagal", + "SCRIPTERR_INJECT_FAIL": "gagal suntik", + "SCRIPTERR_FILLBYTE_FAIL": "fillbyte gagal", + "SCRIPTERR_FILL_FAIL": "mengisi gagal", + "SCRIPTERR_BAD_FILESIZE": "ukuran berkas buruk", + "SCRIPTERR_CREATE_DUMMY_FILE": "buat brks kosong gagal", + "SCRIPTERR_REMOVE_FAIL": "menghapus gagal", + "SCRIPTERR_MAKEDIR_FAIL": "buat dir gagal", + "SCRIPTERR_MOUNT_FAIL": "mount gagal", + "SCRIPTERR_FIND_FAIL": "cari gagal", + "SCRIPTERR_FINDNOT_FAIL": "cari not, gagal", + "SCRIPTERR_NO_SIZE_GIVEN": "tak ada ukuran", + "SCRIPTERR_SIZE_TOO_BIG": "ukuran terlalu besar", + "SCRIPTERR_READ_FAIL": "baca gagal", + "SCRIPTERR_CONVERSION_FAIL": "konversi gagal", + "SCRIPTERR_INVALID_DATA": "data tidak absah", + "SCRIPTERR_WRITE_FAIL": "tulis gagal", + "SCRIPTERR_SHA_ARG0_FAIL": "arg0 sha gagal", + "SCRIPTERR_SHA_ARG1_FAIL": "arg1 sha gagal", + "SCRIPTERR_SHA_DOES_NOT_MATCH": "sha tidak cocok", + "SCRIPTERR_SHA_WRITE_FAIL": "tulis sha gagal", + "SCRIPTERR_FILE_WRITE_FAIL": "tulis berkas gagal", + "SCRIPTERR_FIXCMAC_FAILED": "perbaiki cmac, gagal", + "SCRIPTERR_VERIFICATION_FAILED": "verifikasi, gagal", + "SCRIPTERR_DECRYPT_FAILED": "dekripsi, gagal", + "SCRIPTERR_ENCRYPT_FAILED": "enkripsi, gagal", + "SCRIPTERR_BUILD_CIA_FAILED": "bina CIA, gagal", + "SCRIPTERR_INSTALL_GAME_FAILED": "pasang p'mainan, gagal", + "SCRIPTERR_DOES_NOT_CONTAIN_DOT_CODE": "tidak terdapat .code", + "SCRIPTERR_EXTRACT_DOT_CODE_FAILED": "ekstraksi .code, gagal", + "SCRIPTERR_COMPRESS_DOT_CODE_FAILED": "pemampatan .code, gagal", + "SCRIPTERR_BUILD_FAILED": "bina, gagal", + "SCRIPTERR_UNKNOWN_FILE": "berkas tak diketahui", + "SCRIPTERR_APPLY_IPS_FAILD": "menerap IPS, gagal", + "SCRIPTERR_APPLY_BPS_FAILED": "menerap BPS, gagal", + "SCRIPTERR_APPLY_BPM_FAILED": "menerap BPM, gagal", + "SCRIPTERR_TEXTVIEWER_FAILED": "textviewer, gagal", + "SCRIPTERR_BAD_DUMPSIZE": "ukuran dump buruk", + "SCRIPTERR_CART_INIT_FAIL": "init kartrid gagal", + "SCRIPTERR_CART_DUMP_FAILED": "men-dump kartrid gagal", + "SCRIPTERR_NOT_A_DIR": "bukan dir", + "SCRIPTERR_FILE_NOT_FOUND": "berkas tak ditemukan", + "SCRIPTERR_NOT_A_BOOTABLE_FIRM": "bukan firm bisa di-boot", + "SCRIPTERR_SD_NOT_MOUNTED": "SD tidak di-mount", + "SCRIPTERR_UNKNOWN_ERROR": "galat tak diketahui", + "SCRIPTERR_COMMAND_SUCCESS": "perintah, berhasil", + "SCRIPTERR_CONTROL_FLOW_ERROR": "aliran kendali galat", + "SCRIPTERR_UNCLOSED_CONDITIONAL": "syarat yang blm selesai", + "SCRIPTERR_ERROR_MESSAGE_FAIL": "pesan galat gagal", + "ERROR_INVALID_TEXT_DATA": "Galat: Data teks tak absah", + "TEXTVIEWER_CONTROLS_DETAILS": "Kendali Textviewer:\n \n↑↓→←(+R) - Gulir\nR+Y - Ganti bungkus kata\nR+X - Ke barisan #\nB - Keluar\n", + "CURRENT_LINE_N_ENTER_NEW_LINE_BELOW": "Barisan saat ini: %i\nMasukkan barisan baru.", + "PREVIEW_DISABLED": "(pratayang dinonaktif)", + "PATH_LINE_N_ERR_LINE": "%s\nbarisan %lu: %s\n%s", + "END_OF_SCRIPT_UNRESOLVED_IF": "ujung naskah: 'if' blm dipecahkan", + "END_OF_SCRIPT_UNRESOLVED_FOR": "ujung naskah: 'for' blm dipecahkan", + "SYSINFO_MODEL": "Model: %s (%s)\n", + "SYSINFO_SERIAL": "Serial: %s\n", + "SYSINFO_REGION_SYSTEM": "Daerah (sistem): %s\n", + "SYSINFO_REGION_SALES": "Daerah (penjualan): %s\n", + "SYSINFO_SOC_MANUFACTURING_DATE": "Tanggal manufaktur SoC: %s\n", + "SYSINFO_SYSTEM_ASSEMBLY_DATE": "Tanggal perakitan sistem: %s\n", + "SYSINFO_ORIGINAL_FIRMWARE": "Firmware asli: %s\n", + "SYSINFO_FRIENDCODE_SEED": "Seed kode teman: %s\n", + "SYSINFO_SD_KEYY": "KeyY SD: %s\n", + "SYSINFO_NAND_CID": "CID NAND: %s\n", + "SYSINFO_SD_CID": "CID SD: %s\n", + "SYSINFO_SYSTEM_ID0": "ID0 sistem: %s\n", + "SYSINFO_SYSTEM_ID1": "ID1 sistem: %s\n", + "SORTING_TICKETS_PLEASE_WAIT": "Mengurut ticket, mohon tunggu..." +} diff --git a/resources/languages/it.json b/resources/languages/it.json new file mode 100644 index 000000000..aad410dca --- /dev/null +++ b/resources/languages/it.json @@ -0,0 +1,206 @@ +{ + "GM9_LANGUAGE": "Italiano", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%4$02lX/%3$02lX/%1$s%2$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ",", + "THOUSAND_SEPARATOR": ".", + "FIRM_TOO_BIG": "FIRM troppo grande, non può essere avviato", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nAttenzione: Non avviare FIRM\nAvviare FIRM?", + "NOT_BOOTABLE_FIRM": "Non un FIRM avviabile.", + "FIRM_ENCRYPTED": "FIRM è criptato.\n\nDecriptare prima dell'avvio?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Fare una copia in %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Provare comunque ad avviare il sistema", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Attenzione: Tentativo di avvio da una posizione\nnon supportato.", + "ROOT": "[radice]", + "LOADING": "CARICAMENTO...", + "PANE_N": "PANE #%lu", + "CURRENT": "CORRENTE", + "DIR": "(ele)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAMdrive FAT)", + "GAME_VIRTUAL": "(Gioco Virtuale)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND Virtuale)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND Virtuale)", + "IMAGE_FAT": "(Immagine FAT)", + "XORPAD_VIRTUAL": "(XORpad Virtuale)", + "MEMORY_VIRTUAL": "(Memoria Virtuale)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Gamecart Virtuale)", + "VRAM_VIRTUAL": "(VRAM Virtuale)", + "SEARCH": "(Ricerca)", + "TITLEMANAGER_VIRTUAL": "(TitoloManager Virtuale)", + "LAB_SDCARD": "SDCARD", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUAL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUAL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "GAMECART", + "LAB_GAME_IMAGE": "GAME IMAGE", + "LAB_AESKEYDB_IMAGE": "AESKEYDB IMAGE", + "LAB_BDRI_IMAGE": "BDRI IMAGE", + "LAB_DISA_DIFF_IMAGE": "DISA/DIFF IMAGE", + "LAB_MEMORY_VIRTUAL": "MEMORY VIRTUAL", + "LAB_VRAM_VIRTUAL": "VRAM VIRTUAL", + "LAB_TITLE_MANAGER": "TITLE MANAGER", + "LAB_LAST_SEARCH": "LAST SEARCH", + "LAB_FAT_IMAGE": "FAT IMAGE", + "LAB_BONUS_DRIVE": "BONUS DRIVE", + "LAB_RAMDRIVE": "RAMDRIVE", + "LAB_NOLABEL": "NOLABEL", + "N_BYTE": "%s Byte", + "BYTE": " Byte", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[CLIPBOARD]", + "PLUS_N_MORE": "+ %lu more", + "MARK_DELETE_COPY": "L - MARK files (use with ↑↓→←)\nX - DELETE / [+R] RENAME file(s)\nY - COPY files / [+R] CREATE entry\n", + "MARK_DELETE_PASTE": "L - MARK files (use with ↑↓→←)\nX - DELETE / [+R] RENAME file(s)\nY - PASTE files / [+R] CREATE entry\n", + "RELOCK_WRITE_PERMISSION": "R+Y - Relock write permissions\n", + "UNMOUNT_IMAGE": "R+X - Unmount image\n", + "UNMOUNT_SD": "R+B - Unmount SD card\n", + "REMOUNT_SD": "R+B - Remount SD card\n", + "DIRECTORY_OPTIONS": "R+A - Directory options\n", + "DRIVE_OPTIONS": "R+A - Drive options\n", + "MAKE_SCREENSHOT": "R+L - Make a Screenshot\n", + "PREV_NEXT_PANE": "R+←→ - Switch to prev/next pane\n", + "CLEAR_CLIPBOARD": "SELECT - Clear Clipboard\n", + "RESTORE_CLIPBOARD": "SELECT - Restore Clipboard\n", + "REBOOT_POWEROFF_HOME": "START - Reboot / [+R] Poweroff\nHOME button for HOME menu", + "NO_EMUNAND": "No EmuNAND", + "REDNAND_SIZE_MIN": "RedNAND size (min)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNAND size (full)", + "MULTINAND_SIZE_2X": "MultiNAND size (2x)", + "MULTINAND_SIZE_3X": "MultiNAND size (3x)", + "MULTINAND_SIZE_4X": "MultiNAND size (4x)", + "USER_INPUT": "User input...", + "AUTO": "Auto", + "16KB_CLUSTERS": "16KB Clusters", + "32KB_CLUSTERS": "32KB Clusters", + "64KB_CLUSTERS": "64KB Clusters", + "SD_NOT_DETECTED": "Error: SD card not detected.", + "FORMAT_SD_CHOOSE_EMUNAND": "Format SD card (%lluMB)?\nChoose EmuNAND size:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "SD card size is %lluMB.\nEnter EmuNAND size (MB) below:", + "FORMAT_SD_CHOOSE_CLUSTER": "Format SD card (%lluMB)?\nChoose cluster size:", + "FORMAT_SD_ENTER_LABEL": "Format SD card (%lluMB)?\nEnter label:", + "FORMAT_SD_FAILED": "Format SD: failed!", + "REDNAND_TYPE": "RedNAND type", + "REDNAND_TYPE_MULTI": "RedNAND type (multi)", + "REDNAND_TYPE_SINGLE": "RedNAND type (single)", + "GW_EMUNAND_TYPE": "GW EmuNAND type", + "DONT_SET_UP": "Non impostare", + "CHOOSE_EMUNAND_TYPE": "Scegliere il tipo di EmuNAND da impostare:", + "CLONE_SYSNAND_TO_REDNAND": "Clonare SysNAND in RedNAND?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "Clonazione di SysNAND su EmuNAND: fallita!", + "PRESS_A_TO_CONTINUE": "Premere per continuare", + "HEXEDITOR_CONTROLS": "Controlli Hexeditor:\n\n↑↓→←(+R) - Pergamena\nR+Y - Vista dell'interruttore\nX - Ricerca / andare...\nA - Entrare in modalità di modifica\nA+↑↓→← - Valore di modifica\nB - Uscita", + "NOT_FOUND": "Non trovato!", + "GO_TO_OFFSET": "Andare a compensare", + "SEARCH_FOR_STRING": "Cerca la stringa", + "SEARCH_FOR_DATA": "Ricerca dei dati", + "CURRENT_OFFSET_SELECT_ACTION": "Offset attuale: %08lX\nSelezionare l'azione:", + "CURRENT_OFFSET_ENTER_NEW": "Offset attuale: %08lX\nInserire il nuovo offset qui sotto.", + "ENTER_SEARCH_REPEAT_SEARCH": "Immettere la stringa di ricerca qui sotto.\n(R+X per ripetere la ricerca)", + "MADE_EDITS_SAVE_CHANGES": "Hai apportato modifiche in %lu luogo(hi).\nScrivere le modifiche sul file?", + "FAILED_WRITING_TO_FILE": "Scrittura fallita sul file!", + "CALCULATING_SHA_FAILED": "Calcolo di SHA-%s: fallito!", + "SHA_VERIFICATION_PASSED": "\nVerifica SHA: superata!", + "SHA_VERIFICATION_FAILED": "\nVerifica SHA: fallita", + "IDENTICAL_WITH_PREVIOUS": "\n\nIdentico al file precedente:", + "WRITE_SHA_FILE": "\n\nScrivere il file .SHA?", + "WRITE_SHA1_FILE": "\n\nScrivere il file .SHA1?", + "CALCULATING_CMAC_FAILED": "Calcolo del CMAC: fallito!", + "CMAC_VERIFICATION_PASSED": "Verifica CMAC: superata!", + "CMAC_VERIFICATION_FAILED": "Verifica CMAC: fallita!", + "FIX_CMAC_IN_FILE": "\n\nCorreggere il CMAC nel file?", + "FIXING_CMAC_FAILED": "Correzione del CMAC: fallita!", + "COPY_ALL_SELECTED_ITEMS": "Copiare tutti gli elementi %lu selezionati?", + "FAILED_COPYING_ITEM": "Copia dell'elemento non riuscita", + "ITEMS_COPIED_TO_OUT": "Gli elementi di %lu copiati in %s", + "PATH_COPIED_TO_OUT": "%s\nCopiato in %s", + "CART_INIT_FAILED": "L'avvio del carrello è fallito!", + "CART_DETECTED_SIZE_INPUT_BELOW": "Carrello: %s\nDimensione rilevata: %s\n \nDimensione del dump in ingresso sotto.", + "NDS_CART_DECRYPT_SECURE_AREA": "Carrello: %s\nRilevato carrello NDS\nDecriptare l'area protetta?", + "FAILED_DUMPING_CART": "%s\nCarrello di scarico fallito", + "PATH_DUMPED_TO_OUT": "%s\nScaricato in %s", + "CREATED": "creato", + "MODIFIED": "modificato", + "ANALYZING_DRIVE": "Analisi dell'unità, attendere...", + "ANALYZING_DIR": "Analisi della dir, attendere...", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu file e %lu sottodirectory\ndimensione totale %s\n \nspazio libero: %s\nspazio utilizzato: %s\nspazio totale: %s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu file e %lu sottodirectory\ndimensione totale %s", + "FILESIZE_X": "dimensionefile: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %sdi sola lettura [%c] %snascosto\n[%c] %ssistema [%c] %sarchivio\n[%c] %svirtuale\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→← per modificare gli attributi)", + "A_TO_CONTINUE": "( per continuare)", + "A_APPLY_B_CANCEL": "( per applicare, per annullare)", + "A_YES_B_NO": "( sì, no)", + "A_SELECT_B_CANCEL": "( seleziona, annulla)", + "HOLD_B_TO_CANCEL": "(tenere premuto B per annullare)", + "FAILED_TO_SET_ATTRIBUTES": "Impossibile impostare gli attributi!", + "NAND_IMAGE_OPTIONS": "NAND image options...", + "CTRNAND_OPTIONS": "CTRNAND options...", + "MOUNT_FAT_IMAGE": "Mount as FAT image", + "CIA_IMAGE_OPTIONS": "CIA image options...", + "NCSD_IMAGE_OPTIONS": "NCSD image options...", + "NCCH_IMAGE_OPTIONS": "NCCH image options...", + "MOUNT_AS_EXEFS_IMAGE": "Mount as EXEFS image", + "MOUNT_AS_ROMFS_IMAGE": "Mount as ROMFS image", + "TMD_FILE_OPTIONS": "TMD file options...", + "TMD_CDN_OPTIONS": "TMD/CDN options...", + "TMD_TWL_OPTIONS": "TMD/TWL options...", + "MANAGE_TITLE": "Manage Title...", + "BOSS_FILE_OPTIONS": "BOSS file options...", + "DECRYPT_NUS_CDN_FILE": "Decrypt NUS/CDN file", + "SHOW_SMDH_TITLE_INFO": "Show SMDH title info", + "NDS_IMAGE_OPTIONS": "NDS image options...", + "GBA_IMAGE_OPTIONS": "GBA image options...", + "TICKET_OPTIONS": "Ticket options...", + "TAD_IMAGE_OPTIONS": "TAD image options...", + "SHOW_3DSX_TITLE_INFO": "Show 3DSX title info", + "FIRM_IMAGE_OPTIONS": "FIRM image options...", + "AGBSAVE_OPTIONS": "AGBSAVE options...", + "DUMP_GBA_VC_SAVE": "Dump GBA VC save", + "TICKET_DB_OPTIONS": "Ticket.db options...", + "MOUNT_AS_DIFF_IMAGE": "Mount as DIFF image", + "MOUNT_AS_DISA_IAMGE": "Mount as DISA image", + "INSTALL_CIFINISH_BIN": "Install cifinish.bin", + "TITLEKEY_OPTIONS": "Titlekey options...", + "AESKEYDB_OPTIONS": "AESkeydb options...", + "BUILD_X": "Build %s", + "NCCHINFO_OPTIONS": "NCCHinfo options...", + "EXECUTE_GM9_SCRIPT": "Execute GM9 script", + "FONT_OPTIONS": "Font options...", + "LANGUAGE_OPTIONS": "Language options...", + "VIEW_PNG_FILE": "View PNG file", + "REBUILD_NCSD_HEADER": "Rebuild NCSD header", + "SHOW_IN_HEXEDITOR": "Show in Hexeditor", + "CALCULATE_SHA256": "Calculate SHA-256", + "CALCULATE_SHA1": "Calculate SHA-1", + "SHOW_FILE_INFO": "Show file info", + "SHOW_IN_TEXTVIEWER": "Show in Textviewer", + "CALCULATE_CMAC": "Calculate CMAC", + "COPY_TO_OUT": "Copy to %s", + "DUMP_TO_OUT": "Dump to %s", + "INJECT_DATA_AT_OFFSET": "Inject data @offset", + "OPEN_THIS_FOLDER": "Open this folder", + "OPEN_CONTAINING_FOLDER": "Open containing folder", + "OPEN_TITLE_FOLDER": "Open title folder", + "PATH_N_FILES_SELECTED": "%s\n(%lu files selected)", + "CHECK_CURRENT_CMAC_ONLY": "Check current CMAC only", + "VERIFY_CMAC_FOR_ALL": "Verificare il CMAC per tutti", + "FIX_CMAC_FOR_ALL": "Fissare il CMAC per tutti", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%lu file ok/fissati/totali\n\"%lu/%lu\" non hanno CMAC" +} diff --git a/resources/languages/ja-KANA.json b/resources/languages/ja-KANA.json new file mode 100644 index 000000000..113ca3d54 --- /dev/null +++ b/resources/languages/ja-KANA.json @@ -0,0 +1,270 @@ +{ + "GM9_LANGUAGE": "にほんご", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%1$s%2$02lXねん%3$02lXがつ%4$02lXにち %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ".", + "THOUSAND_SEPARATOR": ",", + "FIRM_TOO_BIG": "FIRMがおおきすぎるので、きどうできません。", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nちゅうい: しんらいできないソースから\nFIRMをきどうしないでください。\n \nFIRMをきどうしますか?", + "NOT_BOOTABLE_FIRM": "%s\nきどうできるFIRMではありません。", + "FIRM_ENCRYPTED": "FIRMがあんごうかされています。\n \nきどうまえにふくごうかしますか?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "%s/temp.firmにコピーをさくせいしますか?", + "TRY_BOOT_ANYWAYS": "とにかくきどうしてみる", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "けいこく: サポートされていない\nばしょからブートしようとしています。", + "ROOT": "[root]", + "LOADING": "ロードちゅう…", + "PANE_N": "ペイン %lu", + "CURRENT": "げんざい", + "DIR": "(dir)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAMドライブFAT)", + "GAME_VIRTUAL": "(ゲームバーチャル)", + "SYSNAND_FAT": "(システムNAND FAT)", + "SYSNAND_VIRTUAL": "(システムNAND バーチャル)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND バーチャル)", + "IMAGE_FAT": "(イメージFAT)", + "XORPAD_VIRTUAL": "(XORパッドバーチャル)", + "MEMORY_VIRTUAL": "(メモリバーチャル)", + "ALIAS_FAT": "(エイリアスFAT)", + "GAMECART_VIRTUAL": "(ゲームカートバーチャル)", + "VRAM_VIRTUAL": "(VRAMバーチャル)", + "SEARCH": "(けんさく)", + "TITLEMANAGER_VIRTUAL": "(タイトルマネージャーバーチャル)", + "LAB_SDCARD": "SDカード", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUAL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUAL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "ゲームカード", + "LAB_GAME_IMAGE": "ゲームイメージ", + "LAB_AESKEYDB_IMAGE": "AESKEYDBイメージ", + "LAB_BDRI_IMAGE": "BDRIイメージ", + "LAB_DISA_DIFF_IMAGE": "DISA/DIFFイメージ", + "LAB_MEMORY_VIRTUAL": "メモリバーチャル", + "LAB_VRAM_VIRTUAL": "VRAMバーチャル", + "LAB_TITLE_MANAGER": "タイトルマネージャー", + "LAB_LAST_SEARCH": "まえのけんさく", + "LAB_FAT_IMAGE": "FATイメージ", + "LAB_BONUS_DRIVE": "ボーナスドライブ", + "LAB_RAMDRIVE": "RAMドライブ", + "LAB_NOLABEL": "ラベルなし", + "N_BYTE": "%sバイト", + "BYTE": "バイト", + "KB": "kB", + "MB": "MB", + "GB": "GB", + "CLIPBOARD": "[クリップボード]", + "PLUS_N_MORE": "+ と%luこ", + "MARK_DELETE_COPY": "L - ファイルをマーク (↑↓→←をしよう)\nX - ファイルをさくじょ / [+R] なまえをへんこう\nY - ファイルをコピー / [+R] エントリをさくせい\n", + "MARK_DELETE_PASTE": "L - ファイルをマーク (↑↓→←をしよう)\nX - ファイルをさくじょ / [+R] なまえをへんこう\nY - ファイルをはりつける / [+R] エントリをさくせい\n", + "RELOCK_WRITE_PERMISSION": "R+Y - かきこみのきょかをさいロック\n", + "UNMOUNT_IMAGE": "R+X - イメージをマウントかいじょ\n", + "UNMOUNT_SD": "R+B - SDカードをマウントかいじょ\n", + "REMOUNT_SD": "R+B - SDカードをさいマウント\n", + "DIRECTORY_OPTIONS": "R+A - ディレクトリオプション\n", + "DRIVE_OPTIONS": "R+A - ドライブオプション\n", + "MAKE_SCREENSHOT": "R+L - スクリーンショットをさくせい\n", + "PREV_NEXT_PANE": "R+←→ - まえ・つぎのペインにきりかえる\n", + "CLEAR_CLIPBOARD": "SELECT - クリップポードのしょうきょ\n", + "RESTORE_CLIPBOARD": "SELECT - クリップボードのふくげん\n", + "REBOOT_POWEROFF_HOME": "START - さいきどう / [+R] でんげんオフ\nホームボタンでホームメニュー", + "NO_EMUNAND": "EmuNANDなし", + "REDNAND_SIZE_MIN": "RedNANDサイズ(さいてい)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNANDサイズ(フル)", + "MULTINAND_SIZE_2X": "マルチNANDサイズ(2x)", + "MULTINAND_SIZE_3X": "マルチNANDサイズ(3x)", + "MULTINAND_SIZE_4X": "マルチNANDサイズ(4x)", + "USER_INPUT": "ユーザーにゅうりょく…", + "AUTO": "じどう", + "16KB_CLUSTERS": "16KBクラスター", + "32KB_CLUSTERS": "32KBクラスター", + "64KB_CLUSTERS": "64KBクラスター", + "SD_NOT_DETECTED": "エラー: SDカードをけんしゅつされませんでした。", + "FORMAT_SD_CHOOSE_EMUNAND": "SDカード(%lluMB)をフォーマットしますか?\nEmuNANDサイズをせんたくしてください。", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "SDカードサイズは%lluMBです。\nEmuNANDサイズ(MB)をいかににゅうりょくしてください。", + "FORMAT_SD_CHOOSE_CLUSTER": "SDカード(%lluMB)をフォーマットしますか?\nクラスターサイズをせんたくしてください。", + "FORMAT_SD_ENTER_LABEL": "SDカード(%lluMB)をフォーマットしますか?\nラベルをにゅうりょくしてください。", + "FORMAT_SD_FAILED": "SDのフォーマット: しっぱい!", + "REDNAND_TYPE": "RedNANDタイプ", + "REDNAND_TYPE_MULTI": "RedNANDタイプ(ふくすう)", + "REDNAND_TYPE_SINGLE": "RedNANDタイプ(たんいつ)", + "GW_EMUNAND_TYPE": "GW EmuNANDタイプ", + "DONT_SET_UP": "せっていしない", + "CHOOSE_EMUNAND_TYPE": "せんたくされるEmuNANDタイプをせんたくしてください。", + "CLONE_SYSNAND_TO_REDNAND": "RedNANDにSysNANDをコピーしますか?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "EmuNANDにシステムNANDをコピー:  しっぱい!", + "PRESS_A_TO_CONTINUE": "をおしてつづける", + "HEXEDITOR_CONTROLS": "16しんエディタのコントロール:\n \n↑↓→←(+R) - スクロール\nR+Y - ひょうじをきりかえる\nX - けんさく・いどう…\nA - へんしゅうモードにする\nA+↑↓→← - あたいをへんしゅう\nB - しゅうりょう\n", + "NOT_FOUND": "ありません!", + "GO_TO_OFFSET": "オフセットへいどう", + "SEARCH_FOR_STRING": "もじれつでけんさく", + "SEARCH_FOR_DATA": "データでけんさく", + "CURRENT_OFFSET_SELECT_ACTION": "げんざいのオフセット: %08lX\nアクションをせんたく:", + "CURRENT_OFFSET_ENTER_NEW": "げんざいのオフセット: %08lX\nいかにあたらしいオフセットをにゅうりょくしてください。", + "ENTER_SEARCH_REPEAT_SEARCH": "いかにけんさくするもじれつをにゅうりょくしてください。\n(R+Xでけんさくをくりかえします)", + "MADE_EDITS_SAVE_CHANGES": "%luこのばしょがへんこうされました。\nへんこうをファイルにかきこみますか?", + "FAILED_WRITING_TO_FILE": "ファイルへのかきこみにしっぱいしました!", + "CALCULATING_SHA_FAILED": "SHA-%sのけいさん: しっぱい!", + "SHA_VERIFICATION_PASSED": "\nSHAけんしょう: せいこう!", + "SHA_VERIFICATION_FAILED": "\nSHAけんしょう: しっぱい", + "IDENTICAL_WITH_PREVIOUS": "\n \nまえのファイルとおなじです。\n", + "WRITE_SHA_FILE": "\n \n.SHAファイルをさくせいしますか?", + "WRITE_SHA1_FILE": "\n \n.SHA1ファイルをさくせいしますか?", + "CALCULATING_CMAC_FAILED": "CMACのけいさん: しっぱい!", + "CMAC_VERIFICATION_PASSED": "CMACけんしょう: せいこう!", + "CMAC_VERIFICATION_FAILED": "CMACけんしょう: しっぱい!", + "FIX_CMAC_IN_FILE": "\n \nファイルにCMACをしゅうせいしますか?", + "FIXING_CMAC_FAILED": "CMACのしゅうせい: しっぱいしました!", + "COPY_ALL_SELECTED_ITEMS": "%luこのせんたくされたこうもくをすべてコピーしますか?", + "FAILED_COPYING_ITEM": "項目のコピーにしっぱいしました", + "ITEMS_COPIED_TO_OUT": "%luこのこうもくは%sにコピーしました", + "PATH_COPIED_TO_OUT": "%s\n%sにコピーしました", + "CART_INIT_FAILED": "カードのしょきかにしっぱいしました!", + "CART_DETECTED_SIZE_INPUT_BELOW": "カード: %s\nけんしゅつされたサイズ: %s\n \nいかにダンプサイズをにゅうりょくしてください。", + "NDS_CART_DECRYPT_SECURE_AREA": "カード: %s\nNDSカードが検出\nセキュアエリアをふくごうかしますか?", + "FAILED_DUMPING_CART": "%s\nカードのダンプにしっぱいしました", + "PATH_DUMPED_TO_OUT": "%s\n%sにダンプしました", + "CREATED": "さくせいび", + "MODIFIED": "こうしんび", + "ANALYZING_DRIVE": "ドライブをぶんせきしています、しばらくおまちください。", + "ANALYZING_DIR": "フォルダをぶんせきしています、おまちください。", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%luファイルと%luフォルダ\n%sごうけいサイズ\n \nあきようりょう:%s\nしようようりょう:%s\nごうけいようりょう:%s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%luファイルと%luフォルダ\n%sごうけいサイズ", + "FILESIZE_X": "ファイルサイズ: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %sよみとりせんよう [%c] %sかくし\n[%c] %sシステム [%c] %sアーカイブ\n[%c] %sバーチャル\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→←でぞくせいをへんこうする)\n", + "A_TO_CONTINUE": "(でつづける)", + "A_APPLY_B_CANCEL": "(でてきよう、でキャンセル)", + "A_YES_B_NO": "(はい、いいえ)", + "A_SELECT_B_CANCEL": "(せんたく、キャンセル)", + "HOLD_B_TO_CANCEL": "(Bをながおしでキャンセル)", + "FAILED_TO_SET_ATTRIBUTES": "ぞくせいのせっていにしっぱいしました!", + "NAND_IMAGE_OPTIONS": "NANDイメージオプション…", + "CTRNAND_OPTIONS": "CTRNANDオプション…", + "MOUNT_FAT_IMAGE": "FATイメージとしてマウント", + "CIA_IMAGE_OPTIONS": "CIAイメージオプション…", + "NCSD_IMAGE_OPTIONS": "NCSDイメージオプション…", + "NCCH_IMAGE_OPTIONS": "NCCHイメージオプション…", + "MOUNT_AS_EXEFS_IMAGE": "EXEFSイメージとしてマウント", + "MOUNT_AS_ROMFS_IMAGE": "ROMFSイメージとしてマウント", + "TMD_FILE_OPTIONS": "TMDファイルオプション…", + "TMD_CDN_OPTIONS": "TMD/CDNオプション…", + "TMD_TWL_OPTIONS": "TMD/TWLオプション…", + "MANAGE_TITLE": "タイトルをかんり…", + "BOSS_FILE_OPTIONS": "BOSSファイルオプション…", + "DECRYPT_NUS_CDN_FILE": "NUS/CDNファイルをふくごうか", + "SHOW_SMDH_TITLE_INFO": "SMDHタイトルのじょうほうをひょうじ", + "NDS_IMAGE_OPTIONS": "NDSイメージオプション…", + "GBA_IMAGE_OPTIONS": "GBAイメージオプション…", + "TICKET_OPTIONS": "チケットオプション…", + "TAD_IMAGE_OPTIONS": "TADイメージオプション…", + "SHOW_3DSX_TITLE_INFO": "3DSXタイトルのじょうほうをひょうじ", + "FIRM_IMAGE_OPTIONS": "FIRMイメージオプション…", + "AGBSAVE_OPTIONS": "AGBSAVEオプション…", + "DUMP_GBA_VC_SAVE": "GBA VCのセーブをダンプ", + "TICKET_DB_OPTIONS": "Ticket.dbオプション…", + "MOUNT_AS_DIFF_IMAGE": "DIFFイメージとしてマウント", + "MOUNT_AS_DISA_IAMGE": "DISAイメージとしてマウント", + "INSTALL_CIFINISH_BIN": "cifinish.binをインストール", + "TITLEKEY_OPTIONS": "タイトルキーオプション…", + "AESKEYDB_OPTIONS": "AESkeydbオプション…", + "BUILD_X": "%sをさくせい", + "NCCHINFO_OPTIONS": "NCCHinfoオプション…", + "EXECUTE_GM9_SCRIPT": "GM9スクリプトをじっこう", + "FONT_OPTIONS": "フォントオプション…", + "LANGUAGE_OPTIONS": "言語オプション…", + "VIEW_PNG_FILE": "PNGファイルをひょうじ", + "REBUILD_NCSD_HEADER": "NCSDヘッダーをさいさくせい", + "SHOW_IN_HEXEDITOR": "16しんエディタでひょうじ", + "CALCULATE_SHA256": "SHA-256をけいさん", + "CALCULATE_SHA1": "SHA-1をけいさん", + "SHOW_FILE_INFO": "ファイルじょうほうをひょうじ", + "SHOW_IN_TEXTVIEWER": "テキストビューアーでひょうじ", + "CALCULATE_CMAC": "CMACをけいさん", + "COPY_TO_OUT": "%sにコピー", + "DUMP_TO_OUT": "%sにダンプ", + "INJECT_DATA_AT_OFFSET": "オフセットにデータをそうにゅう", + "OPEN_THIS_FOLDER": "このフォルダをひらく", + "OPEN_CONTAINING_FOLDER": "がんゆうフォルダをひらく", + "OPEN_TITLE_FOLDER": "タイトルフォルダをひらく", + "PATH_N_FILES_SELECTED": "%s\n(%luこのせんたくされたファイル)", + "CHECK_CURRENT_CMAC_ONLY": "げんざいのCMACのみをかくにんする", + "VERIFY_CMAC_FOR_ALL": "すべてのCMACをかくにんする", + "FIX_CMAC_FOR_ALL": "すべてのCMACをしゅうせいする", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%luファイルがOK/しゅうせい/ごうけい\n%lu/%luがCMACなし", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%luファイルがけんしょうずみ\n%lu/%luファイルがしゅうせいずみ", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%luファイルがけんしょうずみ\n%lu/%luファイルがCMACなし", + "N_OF_N_FILES_VERIFIED": "%lu/%luファイルがけんしょうずみ", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "%sからデータをそうにゅうしますか?\nいかにオフセットをにゅうりょくしてください。", + "FAILED_INJECTING_PATH": "%sのそうにゅうにしっぱいしました", + "MOUNT_CXI_NDS_TO_DRIVE": "CXI/NDSをドライブにマウント", + "MOUNT_IMAGE_TO_DRIVE": "イメージをドライブにマウント", + "RESTORE_SYSNAND_SAFE": "システムNANDをふくげん(あんぜん)", + "UPDATE_EMBEDDED_BACKUP": "うめこみバックアップをこうしん", + "SHOW_TITLE_INFO": "タイトルじょうほうをひょうじ", + "DECRYPT_FILE": "ファイルをふくごうか (...)", + "DECRYPT_FILE_OUT": "ファイルをふくごうか(%sへ)", + "ENCRYPT_FILE": "ファイルをあんごうか (...)", + "ENCRYPT_FILE_OUT": "ファイルをあんごうか(%sへ)", + "BUILD_CIA_FROM_FILE": "ファイルからCIAをさくせい", + "BUILD_CIA_STANDARD": "CIAをさくせい(ひょうじゅん)", + "BUILD_CIA_LEGIT": "CIAをさくせい(ごうほう)", + "DUMP_CXI_NDS_FILE": "CXI/NDSファイルをダンプ", + "INSTALL_GAME_IMAGE": "ゲームイメージをインストール", + "INSTALL_TICKET": "チケットをインストール", + "DUMP_TICKET_FILE": "チケットファイルをダンプ", + "UNINSTALL_TITLE": "タイトルをアンインストール", + "VERIFY_FILE": "ファイルをけんしょう", + "TRANSFER_IMAGE_TO_CTRNAND": "CTRNANDにイメージをてんそう", + "INJECT_TO_H_AND_S": "けんこうとあんぜんにそうにゅう", + "TRIM_FILE": "ファイルをトリミング", + "RENAME_FILE": "ファイルのなまえをへんこう", + "BUILD_XORPADS_SD": "XORパッドをさくせい(SDからしゅつりょく)", + "BUILD_XORPADS_INPLACE": "XORパッドをさくせい(コピーしない)", + "EXTRACT_X": "%sをかいとう", + "INIT_X": "%sをせってい", + "INSTALL_X": "%sをインストール", + "INSTALL_FIRM": "FIRMをインストール", + "BOOT_FIRM": "FIRMをきどう", + "SET_AS_ACTIVE_FONT": "しようされるフォントにせってい", + "SET_AS_ACTIVE_LANGUAGE": "しようされるげんごにせってい", + "DUMP_BA_VC_SAVE": "GBC VCセーブをダンプ", + "INJECT_GBA_VC_SAVE": "GBA VCセーブをそうにゅう", + "SET_AS_DEFAULT": "デフォルトとしてせってい", + "MOUNTING_IMAGE_FAILED": "イメージをマウント:しっぱいしました", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nトライブ%sとしてマウントしました\nいますぐドライブにいどうしますか?", + "DECRYPT_TO_OUT": "%sにふくごう", + "DECRYPT_INPLACE": "コピーしないでふくごう", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "%luこのせんたくしたすべてのファイルをふくごうしますか?", + "TRYING_TO_DECRYPT_N_FILES": "%luこのファイルをふくごうしています…", + "DECRYPTION_FAILED_CONTINUE": "ふくごうかにしっぱいしました\n \nつづけますか?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%luファイルふくごうかずみ\n%lu/%luファイルあんごうかされていない\n%lu/%luおなじしゅるいではない", + "N_OF_N_FILES_DECRYPTED": "%lu/%luファイルふくごうずみ", + "N_FILES_WRITTEN_TO_OUT": "%2$sに%1$luこファイルがかきこみました", + "FILE_NOT_ENCRYPTED": "ファイルはあんごうかされていません", + "DECRYPTION_SUCCESS": "ふくごうかがせいこうしました", + "DECRYPTION_FAILED": "ふくごうかにしっぱいしました", + "PATH_DECRYPTED_TO_OUT": "%s\n%sにふくごうしました", + "ENCRYPT_TO_OUT": "%sにあんごうか", + "ENCRYPT_INPLACE": "コピーしないであんごうか", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "%luこのせんたくしたすべてのファイルをあんごうかしますか?", + "TRYING_TO_ENCRYPT_N_FILES": "%luこのファイルをあんごうかしています。", + "ENCRYPTION_FAILED_CONTINUE": "あんごうかにしっぱいしました\n \nつづけますか?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%luファイルあんごうかずみ\n%lu/%luおなじしゅるいではない", + "N_OF_N_FILES_ENCRYPTED": "%lu/%luファイルあんごうかずみ", + "ENCRYPTION_SUCCESS": "あんごうかがせいこうしました", + "ENCRYPTION_FAILED": "あんごうかにしっぱいしました", + "PATH_ENCRYPTED_TO_OUT": "%s\n%sにあんごうかしました", + "TRY_TO_PROCESS_N_SELECTED_FILES": "%luこのせんたくしたすべてのファイルをしょりしますか?" +} diff --git a/resources/languages/ja.json b/resources/languages/ja.json new file mode 100644 index 000000000..e1ea1a8bc --- /dev/null +++ b/resources/languages/ja.json @@ -0,0 +1,809 @@ +{ + "GM9_LANGUAGE": "日本語", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%1$s%2$02lX年%3$02lX月%4$02lX日 %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ".", + "THOUSAND_SEPARATOR": ",", + "FIRM_TOO_BIG": "FIRMが大きすぎるので、起動できません。", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\n注意: 信頼できないソースから\nFIRMを起動しないでください。\n \nFIRMを起動しますか?", + "NOT_BOOTABLE_FIRM": "%s\n起動できるFIRMではありません。", + "FIRM_ENCRYPTED": "FIRMが暗号化されています。\n \n起動前に復号化しますか?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "%s/temp.firmにコピーを作成しますか?", + "TRY_BOOT_ANYWAYS": "とにかく起動してみる", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "警告: サポートされていない\n場所からブートしようとしています。", + "ROOT": "[root]", + "LOADING": "ロード中…", + "PANE_N": "ペイン %lu", + "CURRENT": "現在", + "DIR": "(dir)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAMドライブFAT)", + "GAME_VIRTUAL": "(ゲームバーチャル)", + "SYSNAND_FAT": "(システムNAND FAT)", + "SYSNAND_VIRTUAL": "(システムNAND バーチャル)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND バーチャル)", + "IMAGE_FAT": "(イメージFAT)", + "XORPAD_VIRTUAL": "(XORパッドバーチャル)", + "MEMORY_VIRTUAL": "(メモリバーチャル)", + "ALIAS_FAT": "(エイリアスFAT)", + "GAMECART_VIRTUAL": "(ゲームカートバーチャル)", + "VRAM_VIRTUAL": "(VRAMバーチャル)", + "SEARCH": "(検索)", + "TITLEMANAGER_VIRTUAL": "(タイトルマネージャーバーチャル)", + "LAB_SDCARD": "SDカード", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUAL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUAL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "ゲームカート", + "LAB_GAME_IMAGE": "ゲームイメージ", + "LAB_AESKEYDB_IMAGE": "AESKEYDBイメージ", + "LAB_BDRI_IMAGE": "BDRIイメージ", + "LAB_DISA_DIFF_IMAGE": "DISA/DIFFイメージ", + "LAB_MEMORY_VIRTUAL": "メモリバーチャル", + "LAB_VRAM_VIRTUAL": "VRAMバーチャル", + "LAB_TITLE_MANAGER": "タイトルマネージャー", + "LAB_LAST_SEARCH": "前検索", + "LAB_FAT_IMAGE": "FATイメージ", + "LAB_BONUS_DRIVE": "ボーナスドライブ", + "LAB_RAMDRIVE": "RAMドライブ", + "LAB_NOLABEL": "ラベルなし", + "N_BYTE": "%sバイト", + "BYTE": "バイト", + "KB": "kB", + "MB": "MB", + "GB": "GB", + "CLIPBOARD": "[クリップボード]", + "PLUS_N_MORE": "+ と%lu個", + "MARK_DELETE_COPY": "L - ファイルをマーク (↑↓→←と使用)\nX - ファイルを削除 / [+R] 名前を変更\nY - ファイルをコピー / [+R] エントリを作成\n", + "MARK_DELETE_PASTE": "L - ファイルをマーク (↑↓→←と使用)\nX - ファイルを削除 / [+R] 名前を変更\nY - ファイルを貼り付ける / [+R] エントリを作成\n", + "RELOCK_WRITE_PERMISSION": "R+Y - 書き込みの許可を再ロック\n", + "UNMOUNT_IMAGE": "R+X - イメージをマウント解除\n", + "UNMOUNT_SD": "R+B - SDカードをマウント解除\n", + "REMOUNT_SD": "R+B - SDカードを再マウント\n", + "DIRECTORY_OPTIONS": "R+A - ディレクトリオプション\n", + "DRIVE_OPTIONS": "R+A - ドライブオプション\n", + "MAKE_SCREENSHOT": "R+L - スクリーンショットを作成\n", + "PREV_NEXT_PANE": "R+←→ - 前・次のペインに切り替える\n", + "CLEAR_CLIPBOARD": "SELECT - クリップポードの消去\n", + "RESTORE_CLIPBOARD": "SELECT - クリップボードの復元\n", + "REBOOT_POWEROFF_HOME": "START - 再起動 / [+R] 電源オフ\nHOMEボタンでHOMEメニュー", + "NO_EMUNAND": "EmuNANDなし", + "REDNAND_SIZE_MIN": "RedNANDサイズ(最低)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNANDサイズ(フル)", + "MULTINAND_SIZE_2X": "マルチNANDサイズ(2x)", + "MULTINAND_SIZE_3X": "マルチNANDサイズ(3x)", + "MULTINAND_SIZE_4X": "マルチNANDサイズ(4x)", + "USER_INPUT": "ユーザー入力…", + "AUTO": "自動", + "16KB_CLUSTERS": "16KBクラスター", + "32KB_CLUSTERS": "32KBクラスター", + "64KB_CLUSTERS": "64KBクラスター", + "SD_NOT_DETECTED": "エラー: SDカードを検出されない", + "FORMAT_SD_CHOOSE_EMUNAND": "SDカード(%lluMB)をフォーマットしますか?\nEmuNANDサイズを選択さてください。", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "SDカードサイズは%lluMB。\nEmuNANDサイズ(MB)をいかに入力してください。", + "FORMAT_SD_CHOOSE_CLUSTER": "SDカード(%lluMB)をフォーマットしますか?\nクラスターサイズを選択してください。", + "FORMAT_SD_ENTER_LABEL": "SDカード(%lluMB)をフォーマットしますか?\nラベルを入力してください。", + "FORMAT_SD_FAILED": "SDのフォーマット: 失敗!", + "REDNAND_TYPE": "RedNANDタイプ", + "REDNAND_TYPE_MULTI": "RedNANDタイプ(複数)", + "REDNAND_TYPE_SINGLE": "RedNANDタイプ(単一)", + "GW_EMUNAND_TYPE": "GW EmuNANDタイプ", + "DONT_SET_UP": "設定しない", + "CHOOSE_EMUNAND_TYPE": "設定されるEmuNANDタイプを選択してください。", + "CLONE_SYSNAND_TO_REDNAND": "RedNANDにSysNANDをコピーしますか?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "EmuNANDにシステムNANDをコピー:  失敗!", + "PRESS_A_TO_CONTINUE": "を押して続ける", + "HEXEDITOR_CONTROLS": "16進エディタのコントロール:\n \n↑↓→←(+R) - スクロール\nR+Y - 表示を切り替える\nX - 検索・移動…\nA - 編集モードにする\nA+↑↓→← - 値を編集\nB - 終了\n", + "NOT_FOUND": "ありません!", + "GO_TO_OFFSET": "オフセットへ移動", + "SEARCH_FOR_STRING": "文字列で検索", + "SEARCH_FOR_DATA": "データで検索", + "CURRENT_OFFSET_SELECT_ACTION": "現在のオフセット: %08lX\nアクションを選択:", + "CURRENT_OFFSET_ENTER_NEW": "現在のオフセット: %08lX\n以下に新しいオフセットを入力してください。", + "ENTER_SEARCH_REPEAT_SEARCH": "以下に検索する文字列を入力してください。\n(R+Xで検索を繰り返します)", + "MADE_EDITS_SAVE_CHANGES": "%lu個の場所が変更されました。\n変更をファイルに書き込みますか?", + "FAILED_WRITING_TO_FILE": "ファイルへの書き込みに失敗しました!", + "CALCULATING_SHA_FAILED": "SHA-%sの計算: 失敗!", + "SHA_VERIFICATION_PASSED": "\nSHA検証: 成功!", + "SHA_VERIFICATION_FAILED": "\nSHA検証: 失敗", + "IDENTICAL_WITH_PREVIOUS": "\n \n前ファイルと同じです。\n", + "WRITE_SHA_FILE": "\n \n.SHAファイルを作成しますか?", + "WRITE_SHA1_FILE": "\n \n.SHA1ファイルを作成しますか?", + "CALCULATING_CMAC_FAILED": "CMACの計算: 失敗!", + "CMAC_VERIFICATION_PASSED": "CMAC検証: 成功!", + "CMAC_VERIFICATION_FAILED": "CMAC検証: 失敗!", + "FIX_CMAC_IN_FILE": "\n \nファイルにCMACを修正します?", + "FIXING_CMAC_FAILED": "CMACの修正: 失敗しました!", + "COPY_ALL_SELECTED_ITEMS": "%lu個の選択された項目をすべてコピーしますか?", + "FAILED_COPYING_ITEM": "項目をコピーに失敗しました", + "ITEMS_COPIED_TO_OUT": "%lu個の項目は%sにコピーしました", + "PATH_COPIED_TO_OUT": "%s\n%sにコピーしました", + "CART_INIT_FAILED": "カートの初期化に失敗しました!", + "CART_DETECTED_SIZE_INPUT_BELOW": "カート: %s\n検出されたサイズ: %s\n \n以下にダンプサイズを入力してください。", + "NDS_CART_DECRYPT_SECURE_AREA": "カート: %s\nNDSカートが検出\nセキュアエリアを復号化します?", + "FAILED_DUMPING_CART": "%s\nカートをダンプに失敗しました", + "PATH_DUMPED_TO_OUT": "%s\n%sにダンプしました", + "CREATED": "作成日", + "MODIFIED": "更新日", + "ANALYZING_DRIVE": "ドライブを分析中。お待ちください。", + "ANALYZING_DIR": "フォルダを分析中。お待ちください。", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%luファイルと%luフォルダ\n%s合計サイズ\n \n空き容量:%s\n使用容量:%s\n合計容量:%s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%luファイルと%luフォルダ\n%s合計サイズ", + "FILESIZE_X": "ファイルサイズ: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %s読み取り専用 [%c] %s隠し\n[%c] %sシステム [%c] %sアーカイブ\n[%c] %sバーチャル\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→←で属性を変更する)\n", + "A_TO_CONTINUE": "(で続ける)", + "A_APPLY_B_CANCEL": "(で適用、でキャンセル)", + "A_YES_B_NO": "(はい、いいえ)", + "A_SELECT_B_CANCEL": "(選択、キャンセル)", + "HOLD_B_TO_CANCEL": "(Bを長押しするとキャンセル)", + "FAILED_TO_SET_ATTRIBUTES": "属性の設定に失敗しました!", + "NAND_IMAGE_OPTIONS": "NANDイメージオプション…", + "CTRNAND_OPTIONS": "CTRNANDオプション…", + "MOUNT_FAT_IMAGE": "FATイメージとしてマウント", + "CIA_IMAGE_OPTIONS": "CIAイメージオプション…", + "NCSD_IMAGE_OPTIONS": "NCSDイメージオプション…", + "NCCH_IMAGE_OPTIONS": "NCCHイメージオプション…", + "MOUNT_AS_EXEFS_IMAGE": "EXEFSイメージとしてマウント", + "MOUNT_AS_ROMFS_IMAGE": "ROMFSイメージとしてマウント", + "TMD_FILE_OPTIONS": "TMDファイルオプション…", + "TMD_CDN_OPTIONS": "TMD/CDNオプション…", + "TMD_TWL_OPTIONS": "TMD/TWLオプション…", + "MANAGE_TITLE": "タイトルを管理…", + "BOSS_FILE_OPTIONS": "BOSSファイルオプション…", + "DECRYPT_NUS_CDN_FILE": "NUS/CDNファイルを復号化", + "SHOW_SMDH_TITLE_INFO": "SMDHタイトルの情報を表示", + "NDS_IMAGE_OPTIONS": "NDSイメージオプション…", + "GBA_IMAGE_OPTIONS": "GBAイメージオプション…", + "TICKET_OPTIONS": "チケットオプション…", + "TAD_IMAGE_OPTIONS": "TADイメージオプション…", + "SHOW_3DSX_TITLE_INFO": "3DSXタイトルの情報を表示", + "FIRM_IMAGE_OPTIONS": "FIRMイメージオプション…", + "AGBSAVE_OPTIONS": "AGBSAVEオプション…", + "DUMP_GBA_VC_SAVE": "GBA VCのセーブをダンプ", + "TICKET_DB_OPTIONS": "Ticket.dbオプション…", + "MOUNT_AS_DIFF_IMAGE": "DIFFイメージとしてマウント", + "MOUNT_AS_DISA_IAMGE": "DISAイメージとしてマウント", + "INSTALL_CIFINISH_BIN": "cifinish.binをインストール", + "TITLEKEY_OPTIONS": "タイトルキーオプション…", + "AESKEYDB_OPTIONS": "AESkeydbオプション…", + "BUILD_X": "%sを作成", + "NCCHINFO_OPTIONS": "NCCHinfoオプション…", + "EXECUTE_GM9_SCRIPT": "GM9スクリプトを実行", + "FONT_OPTIONS": "フォントオプション…", + "LANGUAGE_OPTIONS": "言語オプション…", + "VIEW_PNG_FILE": "PNGファイルを表示", + "REBUILD_NCSD_HEADER": "NCSDヘッダーを再作成", + "SHOW_IN_HEXEDITOR": "16進エディタで表示", + "CALCULATE_SHA256": "SHA-256を計算", + "CALCULATE_SHA1": "SHA-1を計算", + "SHOW_FILE_INFO": "ファイル情報を表示", + "SHOW_IN_TEXTVIEWER": "テキストビューアーで表示", + "CALCULATE_CMAC": "CMACを計算", + "COPY_TO_OUT": "%sにコピー", + "DUMP_TO_OUT": "%sにダンプ", + "INJECT_DATA_AT_OFFSET": "オフセットにデータを挿入", + "OPEN_THIS_FOLDER": "このフォルダを開く", + "OPEN_CONTAINING_FOLDER": "含有フォルダを開く", + "OPEN_TITLE_FOLDER": "タイトルフォルダを開く", + "PATH_N_FILES_SELECTED": "%s\n(%lu個の選択されたファイル)", + "CHECK_CURRENT_CMAC_ONLY": "現在のCMACのみを確認する", + "VERIFY_CMAC_FOR_ALL": "すべてのCMACを確認する", + "FIX_CMAC_FOR_ALL": "すべてのCMACを修正する", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%luファイルがOK/修正/合計\n%lu/%luがCMACなし", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%luファイル検証済み\n%lu/%luファイル修正済み", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%luファイル検証済み\n%lu/%luファイルCMACなし", + "N_OF_N_FILES_VERIFIED": "%lu/%luファイル検証済み", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "%sからデータを挿入しますか?\n以下にオフセットを入力してください。", + "FAILED_INJECTING_PATH": "%sの挿入に失敗しました", + "MOUNT_CXI_NDS_TO_DRIVE": "CXI/NDSをドライブにマウント", + "MOUNT_IMAGE_TO_DRIVE": "イメージをドライブにマウント", + "RESTORE_SYSNAND_SAFE": "システムNANDを復元 (安全)", + "UPDATE_EMBEDDED_BACKUP": "埋め込みバックアップを更新", + "SHOW_TITLE_INFO": "タイトル情報を表示", + "DECRYPT_FILE": "ファイルを復号化", + "DECRYPT_FILE_OUT": "ファイルを復号化 (%sへ)", + "ENCRYPT_FILE": "ファイルを暗号化", + "ENCRYPT_FILE_OUT": "ファイルを暗号化 (%sへ)", + "BUILD_CIA_FROM_FILE": "ファイルからCIAを作成", + "BUILD_CIA_STANDARD": "CIAを作成 (標準)", + "BUILD_CIA_LEGIT": "CIAを作成 (合法)", + "DUMP_CXI_NDS_FILE": "CXI/NDSファイルをダンプ", + "INSTALL_GAME_IMAGE": "ゲームイメージをインストール", + "INSTALL_TICKET": "チケットをインストール", + "DUMP_TICKET_FILE": "チケットファイルをダンプ", + "UNINSTALL_TITLE": "タイトルをアンインストール", + "VERIFY_FILE": "ファイルを検証", + "TRANSFER_IMAGE_TO_CTRNAND": "CTRNANDにイメージを転送", + "INJECT_TO_H_AND_S": "健康と安全に挿入", + "TRIM_FILE": "ファイルをトリミング", + "RENAME_FILE": "ファイルの名前を変更", + "BUILD_XORPADS_SD": "XORパッドを作成 (SD出力)", + "BUILD_XORPADS_INPLACE": "XORパッドを作成 (コピーしない)", + "EXTRACT_X": "%sを解凍", + "INIT_X": "%sを設定", + "INSTALL_X": "%sをインストール", + "INSTALL_FIRM": "FIRMをインストール", + "BOOT_FIRM": "FIRMを起動", + "SET_AS_ACTIVE_FONT": "使用されるフォントに設定", + "SET_AS_ACTIVE_LANGUAGE": "使用される言語に設定", + "DUMP_BA_VC_SAVE": "GBC VCセーブをダンプ", + "INJECT_GBA_VC_SAVE": "GBA VCセーブを注入", + "SET_AS_DEFAULT": "デフォルトとして設定", + "MOUNTING_IMAGE_FAILED": "イメージをマウント: 失敗", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nトライブ%sとしてマウントしました\n今すぐドライブに移動しますか?", + "DECRYPT_TO_OUT": "%sに復号", + "DECRYPT_INPLACE": "コピーしないで復号", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "%lu個の選択したすべてのファイルを復号しますか?", + "TRYING_TO_DECRYPT_N_FILES": "%lu個のファイルを復号しよう中…", + "DECRYPTION_FAILED_CONTINUE": "復号化に失敗しました\n \n続けますか?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%luファイル復号済み\n%lu/%luファイル暗号されない\n%lu/%lu同じ種類でない", + "N_OF_N_FILES_DECRYPTED": "%lu/%luファイル復号済み", + "N_FILES_WRITTEN_TO_OUT": "%2$sに%1$lu個ファイルが書き込みました", + "FILE_NOT_ENCRYPTED": "ファイルは暗号されていません", + "DECRYPTION_SUCCESS": "復号化が成功しました", + "DECRYPTION_FAILED": "復号化に失敗しました", + "PATH_DECRYPTED_TO_OUT": "%s\n%sに復号しました", + "ENCRYPT_TO_OUT": "%sに暗号", + "ENCRYPT_INPLACE": "コピーしないで暗号", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "%lu個の選択したすべてのファイルを暗号しますか?", + "TRYING_TO_ENCRYPT_N_FILES": "%lu個のファイルを暗号しよう中。", + "ENCRYPTION_FAILED_CONTINUE": "暗号化に失敗しました\n \n続けますか?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%luファイル暗号済み\n%lu/%lu同じ種類でない", + "N_OF_N_FILES_ENCRYPTED": "%lu/%luファイル暗号済み", + "ENCRYPTION_SUCCESS": "暗号化が成功しました", + "ENCRYPTION_FAILED": "暗号化に失敗しました", + "PATH_ENCRYPTED_TO_OUT": "%s\n%sに暗号しました", + "TRY_TO_PROCESS_N_SELECTED_FILES": "%lu個の選択したすべてのファイルを処理しますか?", + "PATH_BUILD_TYPE_FAILED_CONTINUE": "%s\n%sを作成に失敗しました\n \n続けますか?", + "N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE": "%lu/%lu %s作成済み\n%lu/%lu同じ種類でない", + "N_OF_N_TYPES_BUILT": "%lu/%lu %s作成済み", + "N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED": "%lu個ファイルの変換に失敗しました。\n検証をおすすまします。", + "PATH_TYPE_BUILT_TO_OUT": "%1$s\n%3$sへ%2$sが作成しました", + "PATH_TYPE_BUILD_FAILED": "%s\n%sの作成に失敗しました", + "FILE_FAILED_CONVERSION_VERIFY_NOW": "ファイルの変換に失敗しました。\n \n今すぐ検証しますか?", + "VERIFICATION_SUCCESS": "検証が成功しました", + "VERIFICATION_FAILED": "検証に失敗しました", + "CONTENT_IS_MISSING": "コンテンツがありません", + "INSTALL_TO_SYSNAND": "システムNANDにインストール", + "INSTALL_TO_EMUNAND": "EmuNANDにインストール", + "TRY_TO_INSTALL_N_SELECTED_FILES": "%lu個の選択したすべてのファイルをインストールしますか?", + "TRYING_TO_INSTALL_N_FILES": "%lu個のファイルをインストールしよう中。", + "INSTALL_FAILED_CONTINUE": "インストールに失敗しました\n \n続けますか?", + "N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE": "%lu/%luファイルインストール済み\n%lu/%lu同じ種類でない", + "N_OF_N_FILES_INSTALLED": "%lu/%luファイルインストール済み", + "INSTALL_SUCCESS": "インストールが成功しました", + "INSTALL_FAILED": "インストールに失敗しました", + "FILE_FAILED_INSTALL_VERIFY_NOW": "ファイルのインストールに失敗しました。\n \n今すぐ検証しますか?", + "KEEP_TICKET_AND_SAVEGAME": "チケットとセーブゲームを保存する", + "UNINSTALL_EVERYTHING": "すべてをアンインストールする", + "ABORT_UNINSTALL": "アンインストールを中止する", + "UNINSTALL_N_SELECTED_TITLES": "%lu個の選択されたタイトルをすべてアンインストールしますか?", + "UNINSTALL_SELECTED_TITLE": "選択されたタイトルをアンインストールしますか?", + "N_OF_N_TITLES_UNINSTALLED": "%lu/%luタイトルアンインストール済み", + "UNINSTALLING_PLEASE_WAIT": "アンインストール中。お待ちください。", + "UNINSTALL_FAILED": "アンインストールに失敗しました!", + "TRY_TO_VERIFY_N_SELECTED_FILES": "%lu個の選択したすべてのファイルを検証しますか?", + "VERIFICATION_FAILED_CONTINUE": "検証に失敗しました\n \n続けますか?", + "N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE": "%lu/%luファイル検証済み\n%lu/%lu同じ種類でない", + "VERIFYING_FILE_PLEASE_WAIT": "ファイルを検証中。お待ちください。", + "NAND_VALIDATION_SUCCESS": "NAND検証が成功しました", + "NAND_VALIDATION_FAILED": "NAND検証に失敗しました", + "DUMP_FOR_N_SELECTED_FILES": "%lu個の選択したすべてのファイルでダンプしますか?", + "N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL": "%lu/%lu合法チケットをダンプしました。\n \nすべてのチッケトをダンプしようしますか?", + "N_OF_N_TICKETS_DUMPED_TO_OUT": "%lu/%luチケットが%sにダンプしました。", + "PATH_TICKET_DUMPED_TO_OUT": "%s\nチケットが%sにダンプしました", + "LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS": "%s\n合法チケットがありません。\n \nとにかくダンプしますか?", + "DUMP_TICKET_FAILED": "チケットをダンプに失敗しました!", + "BUILDING_X": "%sを作成中…", + "BUILDING_X_SYSNAND": "%sを作成中… (システムNAND)", + "BUILDING_X_EMUNAND": "%sを作成中… (EmuNAND)", + "PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED": "%s\n%lu/%luファイル処理済み\n%lu/%luファイル無視済み", + "PATH_N_OF_N_FILES_PROCESSED": "%s\n%lu/%luファイル処理済み", + "BUILD_DATABASE_SUCCESS": "データベースを作成が成功しました。", + "BUILD_DATABASE_FAILED": "データベースを作成に失敗しました。", + "TRY_TO_TRIM_N_SELECTED_FILES": "%lu個の選択したすべてのファイルをトリミングしますか?", + "TRIMMING_FAILED_CONTINUE": "トリミングに失敗しました\n \n続けますか?", + "N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED": "%lu/%luファイルトリミング済み\n%lu/%lu同じ種類でない\n%s保存された", + "N_OF_N_FILES_TRIMMED_X_SAVED": "%lu/%luファイルトリミング済み\n%s保存された", + "FILE_CANT_BE_TRIMMED": "ファイルをトリミングできません。", + "FILE_ALREADY_TRIMMED": "ファイルが既にトリミングされています。", + "PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE": "%s\n現在サイズ: %s\nトリミングサイズ: %s\n差分: %s\n \nファイルをトリミングしますか?", + "TRIMMING_FAILED": "トリミングに失敗しました。", + "PATH_TRIMMED_BY_X": "%s\n%sでトリミングしました。", + "TRY_TO_RENAME_N_SELECTED_FILES": "%lu個の選択したすべてのファイルの名前を変更しますか?", + "N_OF_N_RENAMED": "%lu/%lu名前変更済み", + "COULD_NOT_RENAME_TO_GOOD_NAME": "名前を良い名前に変更できませんでした", + "SYSNAND_H_AND_S_INJECT": "システムNANDの健康と安全に挿入", + "EMUNAND_H_AND_S_INJECT": "EmuNANDの健康と安全に挿入", + "H_AND_S_INJECT_SUCCESS": "健康と安全に挿入が成功しました", + "H_AND_S_INJECT_FAILURE": "健康と安全に挿入に失敗しました", + "TRY_EXTRACT_ALL_N_SELECTED_FILES": "%lu個の選択したすべてのファイルを解凍しますか?", + "N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE": "%lu/%luファイル解凍済み\n%lu/%lu同じ種類でない", + "N_OF_N_FILES_EXTRACTED": "%lu/%luファイル解凍済み", + "EXTRACTING_DOT_CODE": ".codeを解凍中。お待ちください。", + "PATH_EXT_EXTRACTED_TO_OUT": "%1$s\n%3$sへ%2$sを解凍しました", + "DOT_CODE_EXTRACT_FAILED": ".codeの解凍に失敗しました", + "TRANSFER_TO_SYSNAND": "システムNANDへ転送", + "TRANSFER_TO_EMUNAND": "EmuNANDへ転送", + "CTRNAND_TRANSFER_SUCCESS": "CTRNAND転送が成功しました", + "CTRNAND_TRANSFER_FAILED": "CTRNAND転送に失敗しました", + "NO_VALID_DESTINATION_FOUND": "有効な移動先がありません", + "NAND_RESTORE_SUCCESS": "NAND復元が成功しました", + "NAND_RESTORE_FAILED": "NAND復元に失敗しました", + "REBUILD_NCSD_SUCCESS": "NCSDの再作成が成功しました", + "REBUILD_NCSD_FAILED": "NCSDの再作成に失敗しました", + "PATH_NCCHINFO_PADGEN_SUCCESS": "%s\nNCCHinfoのパッド作成が成功しました%c出力場所: %s", + "PATH_NCCHINFO_PADGEN_FAILED": "%s\nNCCHinfoのパッド作成に失敗しました%c%0.0s", + "UPDATING_EMBEDDED_BACKUP": "埋め込みバックアップを更新中…", + "BACKUP_UPDATE_NOT_REQUIRED": "バックアップ更新: 不要", + "BACKUP_UPDATE_COMPLETED": "バックアップ更新: 成功", + "BACKUP_UPDATE_FAILED": "バックアップ更新: 失敗!", + "WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK": "警告: キーが検証されていません。\n自己責任で続けますか?", + "AESKEYDB_INIT_SUCCESS": "AESkeydbを設定が成功しました", + "AESKEYDB_INIT_FAILED": "AESkeydbを設定に失敗しました", + "AESKEYDB_INSTALL_SUCCESS": "AESkeydbをインストールが成功しました", + "AESKEYDB_INSTALL_FAILED": "AESkeydbをインストールに失敗しました", + "INSTALL_TO_FIRM0": "FIRM0にインストール", + "INSTALL_TO_FIRM1": "FIRM1にインストール", + "INSTALL_TO_BOTH": "両方にインストール", + "PATH_N_KB_INSTALL_TO_SYSNAND": "%s (%dkB)\nシステムNANDにインストールしますか?", + "PATH_N_KB_INSTALL_SUCCESS": "%s (%dkB)\nインストール成功", + "PATH_N_KB_INSTALL_FAILED": "%s (%dkB)\nインストール失敗", + "WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS": "警告: 信頼できないソースから\nスクリプトを実行しないでください。\n \nスクリプトを実行しますか?", + "SCRIPT_EXECUTE_SUCCESS": "スクリプト実行成功", + "SCRIPT_EXECUTE_FAILURE": "スクリプト実行失敗", + "ERROR_CANNOT_VIEW_FILE": "エラー: ファイルを表示できません\n(ヒント: 大きすぎるかもしれません)", + "SAVEGAME_DUMPED_TO_OUT": "セーブゲームは%sにダンプしました。", + "SAVEGAME_DUMP_FAILED": "セーブゲームをダンプに失敗しました!", + "GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD": "GBA VCセーブゲームは\nクリップボードにある必要があります。", + "SAVEGAME_INJECT_SUCCESS": "セーブゲームを注入が成功しました。", + "SAVEGAME_INJECT_FAILED": "セーブゲームを注入に失敗しました!", + "FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT": "フォントは次の起動時に使用になります", + "LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT": "言語は次の起動時に使用になります", + "HOME_MORE_MENU_SELECT_ACTION": "HOMEのその他…メニュー\nアクションを選択:", + "SD_FORMAT_MENU": "SDフォーマットメニュー", + "BONUS_DRIVE_MENU": "ボーナスドライブのセットアップ", + "SWITCH_EMUNAND": "EmuNANDを切り替える", + "BUILD_SUPPORT_FILES": "サポートファイルを作成", + "RESTORE_H_AND_S": "健康と安全を復元", + "SET_RTC_DATE_TIME": "RTCの日時を設定", + "CONFGURE_BRIGHTNESS": "明るさを設定", + "CALIBRATE_TOUCHSCREEN": "タッチスクリーンを調整", + "SYSTEM_INFO": "システム情報", + "SHOW_README": "READMEを表示", + "INITIALIZING_SD_FAILED_RETRY": "SDカードの初期化に失敗しました!再試行しますか?", + "SETUP_FAILED": "設定に失敗しました!", + "CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT": "現在のEmuNANDオフセットは%06lXです。\n次のオフセットに切り替えますか?", + "BUILT_IN_OUT_STATUSES": "%sに作成しました。\n \n%-18.18s %s\n%-18.18s %s\n%-18.18s %s", + "OK_SYS_EMU": "OK (システムとEmu)", + "OK_SYS": "OK (システム)", + "FAILED": "失敗", + "RESTORE_H_AND_S_EMUNAND": "健康と安全を復元(EmuNAND)", + "RESTORE_H_AND_S_SYSNAND": "健康と安全を復元(システムNAND)", + "TITLE_SET_RTC_DATE_TIME": "RTCの日時を設定:", + "NEW_RTC_DATE_TIME_IS_TIME": "新しいRTC日時は:\n%s\n \nヒント: HOMEメニューの時刻は、\nRTCを設定した後、\n手動で調整する必要があります。", + "TOUCHSCREEN_CALIBRATION_SUCCESS": "タッチスクリーン調整が成功しました!", + "TOUCHSCREEN_CALIBRATION_FAILED": "タッチスクリーン調整に失敗しました!", + "GODMODE9_README_TOC": "GodMode9 READMEの目次", + "ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW": "必須ファイルのバックアップがありません。\n今すぐ作成しますか?", + "BACKUP_EMBEDDED_WRITTEN_TO_OUT": "バックアップはシステムNANDに埋め取れ、\n%sに書き込みました。", + "RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW": "RTC日時が間違っているようです。\n今すぐ設定しますか?", + "RESUME_GODMODE9": "GodMode9へ続ける", + "RESUME_BOOTLOADER": "ブートローダーへ続ける", + "SELECT_PAYLOAD": "ペイロードを選択…", + "SELECT_SCRIPT": "スクリプトを選択…", + "POWEROFF_SYSTEM": "本体を電源オフ", + "REBOOT_SYSTEM": "本体を再起動", + "FLAVOR_BOOTLOADER_SELECT_OPTION": "%sブートローダーメニュー\nアクションを選択:", + "BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD": "ブートローダーのペイロードメニュー\nペイロードを選択:", + "BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT": "ブートローダーのスクリプトメニュー\nスクリプトを選択:", + "NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9": "起動可能なFIRMがありません。\nGodMode9を開始中...", + "OUT_OF_MEMORY": "メモリ不足です。", + "INVALID_DIRECTORY_OBJECT": "無効なディレクトリオブジェクト", + "INVALID_ROOT_DIRECTORY": "無効なルートディレクトリ", + "WRITE_PERMISSIONS_WERE_CHANGED_RELOCK": "書き込み権限が変更されました。\n再ロックしますか?", + "OPEN_TITLE_MANAGER": "タイトルマネージャーを開く", + "SEARCH_FOR_FILES": "ファイルを検索…", + "FIX_CMACS_FOR_DRIVE": "ドライブのCMACを修正", + "SHOW_DIRECTORY_INFO": "ディレクトリ情報を表示", + "SHOW_DRIVE_INFO": "ドライブ情報を表示", + "FAILED_SETTING_UP_TITLE_MANAGER": "タイトルマネージャーの設定に失敗しました!", + "SEARCH_FILE_ENTER_SEARCH_BELOW": "%sを検索しますか?\n以下に検索を入力してください。", + "FOUND_N_RESULTS": "%lu件の結果が見つかりました。", + "FIX_CMACS_FOR_DRIVE_FINISHED": "ドライブのCMACを修正が完了しました。", + "FAILED_TO_ANALYZE_DRIVE": "ドライブを解析に失敗しました\n", + "FAILED_TO_ANALYZE_DIR": "ドライブを解析に失敗しました\n", + "NOT_ALLOWED_IN_VIRTUAL_PATH": "バーチャルパスでは不可", + "DELETE_N_PATHS": "%lu個のパスを削除しますか?", + "DELETING_FILES_PLEASE_WAIT": "ファイルを削除中。お待ちください。", + "FAILED_DELETING_N_OF_N_PATHS": "%lu/%luパスの削除に失敗しました", + "DELETE_FILE": "「%s」を削除しますか?", + "FAILED_DELETING_PATH": "%s\nの削除に失敗しました。", + "NOT_ALLOWED_IN_SEARCH_DRIVE": "検索ドライブでは不可", + "NOT_ALLOWED_IN_VIRTUAL_GAME_PATH": "バーチャルゲームパスでは不可", + "NOT_ALLOWED_IN_XORPAD_DRIVE": "XORパッドドライブでは不可", + "NOT_ALLOWED_IN_GAMECART_DRIVE": "ゲームカートドライブでは不可", + "NOT_ALLOWED_IN_ALIAS_PATH": "エイリアスパスでは不可", + "COPY_PATHS": "パスをコピー", + "MOVE_PATHS": "パスを移動", + "PASTE_FILE_HERE": "ここに「%s」を貼り付けますか?", + "PASTE_N_PATHS_HERE": "%lu個パスをここに貼り付けますか?", + "FAILED_COPYING_PATH_PROCESS_REMAINING": "%s\nのコピーに失敗しました。\n残りを処理しますか?", + "FAILED_COPYING_PATH": "%s\nのコピーに失敗しました。", + "FAILED_MOVING_PATH_PROCESS_REMAINING": "%s\nの移動に失敗しました。\n残りを処理しますか?", + "FAILED_MOVING_PATH": "%s\nの移動に失敗しました。", + "RENAME_FILE_ENTER_NEW_NAME_BELOW": "%sの名前を変更しますか?\n新しい名前を以下に入力してください。", + "FAILED_RENAMING_PATH": "%s\nの名前を変更に失敗しました。", + "CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE": "ここで新しいエントリを作成しますか?\nタイプを選択してください。", + "CREATE_A_FOLDER": "フォルダを作成", + "CREATE_A_DUMMY_FILE": "空きファイルを作成", + "CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW": "ここで新しいフォルダを作成しますか?\n以下に名前を入力してください。", + "CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW": "ここで新しいファイルを作成しますか?\n以下に名前を入力してください。", + "CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW": "ここで新しい%sを作成しますか?\n以下にファイルサイズを入力してください。", + "FAILED_CREATING_FOLDER_PATH": "%s\nフォルダの作成に失敗しました。", + "FAILED_CREATING_FILE_PATH": "%s\nファイルの作成に失敗しました。", + "TITLE_MANAGER": "タイトルマネージャー", + "BRICK_MY_3DS": "3DSをBRICKする", + "LANGUAGE": "言語…", + "SCRIPTS": "スクリプト…", + "PAYLOADS": "ペイロード…", + "MORE": "その他…", + "BRACKET_MORE": "[さらに…]", + "HOME_BUTTON_PRESSED_SELECT_ACTION": "HOMEボタンが押された。\nアクションを選択:", + "POWER_BUTTON_PRESSED_SELECT_ACTION": "POWERボタンが押された。\nアクションを選択:", + "1_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "4_DRIVE_NAND_TWL": "[4:] NAND / TWL", + "A_DRIVE_SD_CARD": "[A:] SDカード", + "B_DRIVE_SD_CARD": "[B:] SDカード", + "TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE": "タイトルマネージャーメニュー\nタイトル元を選択してください。", + "LANGUAGES_DIRECTORY_NOT_FOUND": "言語フォルダがありません。\n(デフォルトパス:0:/gm9/%s)", + "SCRIPTS_DIRECTORY_NOT_FOUND": "スクリプトフォルダがありません。\n(デフォルトパス:0:/gm9/%s)", + "HOME_LANGUAGE_MENU_SELECT_LANGUAGE": "HOMEの言語…メニュー\n言語を選択:", + "HOME_SCRIPTS_MENU_SELECT_SCRIPT": "HOMEのスクリプト…メニュー\nスクリプトを選択:", + "PAYLOADS_DIRECTORY_NOT_FOUND": "ペイロードフォルダがありません。\n(デフォルトパス:0:/gm9/%s)", + "HOME_PAYLOADS_MENU_SELECT_PAYLOAD": "HOMEのペイロード…メニュー\nペイロードを選択:", + "UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT": "‼予期しないSDカードの取り出し‼\n \nデータの損失を防ぐために、SDカードを取り出す前に\nマウントを解除してください。", + "FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT": "%sのスクリプト…メニュー\nスクリプトを選択:", + "COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP": "スクリプト自動実行機としてコンパイルされましたが、\nスクリプトが含まれませんでした。\n \nバカ!", + "KEYBOARD_CONTROLS_DETAILS": "キーボードのコントロール:\n \n←/→ - カーソルを移動\nR - 大文字・小文字(ロック)\nX - 文字を削除\nY - 文字を挿入\nA - 送信\nB - キャンセル\n \nSELECTで古いプロンプトに切り替わる", + "TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS": "赤い十字をタッチして、\nタッチスクリーンを調整してください。\n \n最良の結果を得るには、\nタッチペンを使用してください!", + "INVALID": "無効", + "TO_PROCEED_ENTER_THIS": "続けるには、これを入力してください。", + "TO_PROCEED_HOLD_X": "続けるには、を長押してください。", + "N_MORE": " [と%d個]", + "CANCEL": "キャンセル", + "R_FAST_SCROLL_L_CLEAR_DATA": "R - (↑↓) 高速スクロール\nL - データをクリア", + "X_REMOVE_CHAR_Y_INSERT_CHAR": "X - 文字を削除\nY - 文字を挿入", + "ETA_N_MIN_N_SEC": "残り%02llu分%02llu秒", + "BRIGHTNESS_CONTROLS": "[→] 明るさを上げる\n[←] 明るさを下げる\n \n[X] 音量スライダーでコントロール\n[A] 現在の明るさを設定\n[B] キャンセル", + "SEARCHING_PLEASE_WAIT": "検索中です。お待ちください。", + "RENAME_TO_GOOD_NAME": "名前を良い名前に変更しますか?", + "SD_WRITE_PROTECTED_CANT_CONTINUE": "SDカードが書き込み禁止になっている!\n続行できません。", + "SYSNAND_LVL_N": "システムNAND(レベル%lu)", + "EMUNAND_LVL_N": "EmuNAND(レベル%lu)", + "GAME_IMAGES": "ゲームイメージ", + "GAMECART_SAVES": "ゲームカートセーブ", + "IMAGES": "イメージ", + "MEMORY_AREAS": "メモリ領域", + "SD_SYSTEM_DATA": "SDシステムデータ", + "SD_CARD": "SDカード", + "RAM_DRIVE": "RAMドライブ", + "WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW": "%sへの書き込みがロックされています!\n今すぐロックを解除しますか?", + "UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED": "%sの書き込み権限のロックを\n解除することができません。", + "ENABLE_BASE_WRITE": "普通の書き込み権限を有効にしたい。", + "ENABLE_SD_WRITE": "SDカードの書き込み権限を有効にしたい。", + "ENABLE_IMAGE_WRITE": "イメージの書き込み権限を有効にしたい。", + "ENABLE_RAM_DRIVE_WRITE": "RAMドライブの書き込み権限を有効にしたい。", + "ENABLE_EMUNAND_0_WRITE": "EmuNANDレベル0の書き込み権限を有効にしたい。", + "ENABLE_SYSNAND_0_WRITE": "システムNANDレベル0の書き込み権限を有効にしたい。", + "ENABLE_EMUNAND_1_WRITE": "EmuNANDレベル1の書き込み権限を有効にしたい。\n \nこれにより、回復可能なシステムデータ、ユーザー\nデータ、セーブゲームを変更するが許可になります。", + "ENABLE_SYSNAND_1_WRITE": "EmuNANDレベル1の書き込み権限を有効にしたい。\n \nこれにより、システムデータ、インストール、ユーザー\nデータ、セーブゲームを変更するが許可になります。", + "ENABLE_GAMECART_SAVE_WRITE": "ゲームカートのセーブの書き込み権限を有効にしたい。", + "ENABLE_SYSNAND_2_WRITE": "‼気をつけて‼\n \nシステムNANDレベル2の書き込み権限を有効にしたい。\n \nこれにより、回復不能なシステムデータを\n変更するが許可になります!", + "ENABLE_MEMORY_WRITE": "‼気をつけて‼\n \nメモリの書き込み権限を有効にしたい。\n \n特定の地域に書き込むと、予期せぬ\n結果に繋がら可能性があります。", + "ENABLE_SD_DATA_WRITE": " ・・・・・・・・・・・\n‼これはおすすめしません‼\n \nSDデータの書き込み権限を有効にしたい。\n\nここはすべて暗号化されています。\nインストール、ユーザーデータ、セーブゲームの変更では\n代わりに、A:/B:ドライブを使用するをおすすめします。", + "ENABLE_SYSNAND_3_WRITE": " ・ ・ ・ ・ ・ ・ ・ ・ ・ ・\n‼ こ れ は 唯 一 の 警 告 で す ‼\n‼ THIS IS THE ONLY WARNING ‼\n \nシステムNANDレベル3の書き込み権限を有効にしたい。\n \nこれにより、ブートローダーと必須システムファイルを\n・上書きする・や本体を・BRICKする・(壊す)\nが許可になります!", + "UNLOCK_WRITE_NOT_ALLOWED": "書き込み権限のロックを解除することができません。", + "CANT_UNLOCK_WRITE_TRY_GODMODE9": "書き込み権限の解除ができません。\n代わりにGodMode9をお試しください。", + "ERROR_SD_TOO_SMALL": "エラー: SDカードが小さすぎます", + "WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA": " ・ ・\n‼ 警 告 ‼\n \n続けると、このSDをフォーマットします。\nこれにより、・すべて・のデータを元に戻せない削除されます。", + "FORMAT_BONUS_DRIVE_DELETE_ALL_DATA": "ボーナスドライブをフォーマットしますか?\nこれにより、・すべて・のデータを元に戻せない削除されます。", + "FORMATTING_SD_PLEASE_WAIT": "SDをフォーマット中。お待ちください。", + "FORMATTING_DRIVE_PLEASE_WAIT": "ドライブをフォーマット中。お待ちください。", + "ERROR_SD_CARD_IO_FAILURE": "エラー: SDカード入出力失敗", + "FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK": "ファイルは現在マウントされています。\nマウントを解除してロックを解除しますか?", + "ERROR_CANT_INJECT_FILE_INTO_ITSELF": "エラー: ファイルを自体に挿入できません", + "OPERATION_WOULD_WRITE_BEYOND_EOF": "操作はファイルの終わりを超えて書き込まれます", + "NOT_ENOUGH_DATA_IN_FILE": "ファイル内のデータが不足しています", + "CANCEL_IS_NOT_ALLOWED_HERE": "ここではキャンセルができません", + "B_DETECTED_CANCEL": "Bボタンが検出されました。キャンセルしますか?", + "ERROR_CANNOT_APPEND_FOLDER": "エラー: フォルダを追加できません", + "ERROR_OVERWRITING_FILE_WITH_DIR": "エラー: ファイルをフォルダで上書きする", + "ERROR_OVERWRITING_DIR_WITH_FILE": "エラー: フォルダをファイルで上書きする", + "ERROR_CANNOT_OPEN_DESTINATION_FILE": "エラー: ファイル先を開くことができません", + "ERROR_NOT_ENOUGH_SPACE_AVAILABLE": "エラー: 空き容量が不足しています", + "ERROR_ONLY_FAT_FILES_CAN_BE_MOVED": "エラー: FATファイルのみを移動できます", + "ERROR_DESTINATION_IS_PART_OF_ORIGIN": "エラー: 先は元の一部です", + "ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME": "先は元と同じです。\n別の名前を選択しますか?", + "CHOOSE_NEW_NAME": "新しい名前を選択", + "OVERWRITE_FILES": "ファイルを上書き", + "SKIP_FILES": "ファイルをスキップ", + "OVERWRITE_ALL": "すべて上書き", + "SKIP_ALL": "すべてスキップ", + "DESTINATION_ALREADY_EXISTS": "%s\nは既に存在します。", + "CHOOSE_NEW_DESTINATION_NAME": "パス先の新しい名前を選択してください", + "COPY_OPERATION_IS_NOT_ALLOWED": "コピー操作は許可されていません", + "DESTINATION_EQUALS_ORIGIN": "先は元と同じです。", + "ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD": "%sがありません。\n代わりに、 %sに挿入しますか?", + "FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE": "利用可能な領域より小さいファイル。\n%s (%s)\n%s (%s)\n続けますか?", + "NO_USABLE_ENTRIES_FOUND": "使用可能なエントリがありません。", + "BEAT_NO_ERROR": "エラーなし", + "BEAT_END_OF_ACTION_LIST": "アクションリストの最後", + "BEAT_ABORTED_BY_USER": "ユーザーによる中止", + "BEAT_FAILED_TO_READ_WRITE_FILE": "ファイルの読み取り・書き込みに失敗しました", + "BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF": "ファイルの終わりを越えて書き込もうとした", + "BEAT_INVALID_PATCH_FILE": "無効なパッチファイル", + "BEAT_INVALID_INPUT_FILE": "無効な入力ファイル", + "BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH": "出力ファイルのチェックサムが一致しません", + "BEAT_FILE_CHECKSUM_FAILED": "ファイルのチェックサムに失敗しました", + "BEAT_EXPECTED_MORE_PATCH_DATA": "より多くのパッチデータを予期しています", + "BEAT_OUT_OF_MEMORY": "メモリ不足です", + "BEAT_UNKNOWN_ERROR": "不明なエラー", + "FAILED_TO_INITIALIZE_BPM_FILE": "%s\nのBPMファイルの初期化に失敗しました。", + "FAILED_TO_INITIALIZE_BPS_FILE": "%s\nのBPSファイルの初期化に失敗しました。", + "PATCH_SUCCESSFULLY_APPLIED": "パッチが正常に当てました", + "PATCHING_ABORTED_BY_USER": "ユーザーによってパッチが中止されました", + "FAILED_TO_RUN_PATCH": "%s\nのパッチの実行に失敗しました。", + "DECOMPRESSING_DOT_CODE": ".codeを解凍中…", + "DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL": ".codeを解凍中…\nBボタンが検出されました。キャンセルしますか?", + "COMPRESSING_DOT_CODE": ".codeを圧縮中…", + "COMPRESSING_DOT_CODE_B_DETECTED_CANCEL": ".codeを圧縮中…\nBボタンが検出されました。キャンセルしますか?", + "PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE": "パッチはおそらくこのファイルに意図されていません。", + "YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT": "出力ファイルにパッチをおそらく当てました。", + "PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED": "パッチは技術的に有効ですが、\nスクランブルや不正ようです。", + "PATCH_IS_INVALID": "パッチは無効です。", + "FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT": "一つまたは両方のファイルが16MBより大きい。\nIPSフォーマットはそれをサポートしていません。", + "REQUESTED_FILE_PATH_WAS_INVALID": "要求されたファイルパスが無効です。", + "PATCHING_CANCELED": "パッチの当てがキャンセルしました。", + "NOT_ENOUGH_MEMORY": "メモリ不足です。", + "REGION_AMERICAS": "アメリカ", + "REGION_AUSTRALIA": "オーストラリア", + "REGION_BRAZIL": "ブラジル", + "REGION_CHINA": "中国", + "REGION_EUROPE": "ヨーロッパ", + "REGION_FRANCE": "フランス", + "REGION_GERMANY": "ドイツ", + "REGION_ITALY": "イタリア", + "REGION_JAPAN": "日本", + "REGION_KOREA": "韓国", + "REGION_SPAIN": "スペイン", + "REGION_TAIWAN": "台湾", + "REGION_UNKNOWN": "不明", + "REGION_UNITED_KINGDOM": "イギリス", + "REGION_MIDDLE_EAST": "中東", + "GENERATING_QR_CODE": "QRコードの生成…", + "REINITIALIZING_SD_CARD": "SDカードを再初期化中…", + "DUMPING_STATE_TO_SD_CARD": "SDカードに状態をダンプ中…", + "PRESS_POWER_TO_TURN_OFF": "POWERを押して電源オフにする", + "CLEANING_UP_TITLES_PLEASE_WAIT": "タイトルをクリーンアップ中。お待ちください。", + "ERROR_NOT_NCCH_FILE": "エラー: NCCHファイルではない", + "ERROR_FILE_IS_TOO_SMALL": "エラー: ファイルが小さすぎます", + "ATTEMPT_FIX_THIS_TIME": "今回、修正を試みます", + "ATTEMPT_FIX_ALWAYS": "常、修正を試みます", + "ABORT_VERIFICATION": "検証を中止", + "ERROR_BAD_CRYPTO_FLAGS": "エラー: 不正な暗号化フラグ", + "ERROR_BAD_EXEFS_HEADER": "エラー: 不正なExeFSヘッダ", + "ERROR_MISSING_EXTHEADER": "エラー: ExtHeaderがありません", + "ERROR_CRYPTO_NOT_SET_UP": "エラー: 暗号化が設定されていません", + "PATH_NCCH_VERIFICATION_FAILED_INFO": "%s\nNCCHの検証に失敗しました。\nExtHdr/ExeFS/RomFS: %s/%s/%s", + "OK": "OK", + "FAIL": "失敗", + "ERROR_NOT_NCSD_FILE": "エラー: NCSDファイルではない", + "PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%1$s\nコンテンツ第%2$lu個(%4$08lXで%3$08lX):\n検証に失敗しました", + "ERROR_PROBABLY_NOT_CIA_FILE": "エラー: おそらくNCSDファイルではない", + "ERROR_TMD_PROBABLY_CORRUPTED": "エラー: TMDがおそらく破損しています", + "PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%1$s\nID第%2$lu個(%4$08lXで%3$08lX):\n検証に失敗しました", + "ERROR_CDN_TITLEKEY_NOT_FOUND": "エラー: CDNのタイトルキーがありません", + "DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE": "DLCコンテンツがありません\n \nすべてを無視して続けますか?", + "PATH_SECTION_N_HASH_MISMATCH": "%s\n第%lu部のハッシュが一致しません", + "ARM9_ENTRYPOINT_IS_MISSING": "ARM9のエントリポイントがありません", + "WARNING_ARM11_ENTRYPOINT_IS_MISSING": "警告: ARM11のエントリポイントがありません", + "ERROR_NOT_A_BOSS_FILE": "エラー: BOSSファイルではない", + "BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT": "BOSSペイロードのハッシュが一致しません。\n \n修正してみますか?", + "GENERIC_TICKET_PIRATE_LEGIT": "一般的なチケット(\"海賊合法\")", + "PERSONALIZED_TICKET_LEGIT": "個人的なチケット(合法)", + "ID_N_LEGIT_TICKET_IS_PERSONALIZED_USING_THIS_NOT_RECOMMENDED_CHOOSE_DEFAULT_ACTION": "ID第%016llX個\n合法のチケットは個人的です。\nこれを使用することはおすすめしません。\nデフォルトのアクションを選択してください。", + "ID_N_TITLEKEY_NOT_FOUND": "ID第%016llX個\nタイトルキーがありません。", + "ID_N_TMD_IN_TAD_NOT_LEGIT": "ID第%016llX個\nTADのTMDは合法ではない。", + "ID_N_TMD_NOT_LEGIT": "ID第%016llX個\nTMDは合法ではない。", + "ID_N_DOT_N_STATUS": "ID第%016llX.%08lX個\n%s", + "CONTENT_IS_CORRUPT": "コンテンツが破損しています", + "INSERT_CONTENT_FAILED": "コンテンツを挿入に失敗しました", + "INSTALL_CONTENT_FAILED": "コンテンツをインストールに失敗しました", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_DB_FILES_MAYBE_SD_MISSING_OR_UNINITIALIZED": "インストールエラー:\nこの本体には、1つ以上の.dbファイルがありません。\n \nもしかしSDカードがなくなりまたは\n初期化されていませんことができますか?", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB": "インストールエラー:\nこの本体には、ticket.dbファイルがありません。", + "SKIPPED_TITLE_0004008C000CBD00_NEEDS_SPECIAL_COMPILE_FLAGS": "タイトルをスキップしました。\nID 0004008C000CBD00のタイトルは、特別な\nコンパイラフラグ必要があります。", + "ERROR_FAKE_SIGNED_TICKET_ONLY_VALID_SIGNED_TICKETS_CAN_BE_INSTALLED": "エラー: 偽署名付きチケット\n \n有効な署名付きチケットのみは、\n本体にインストールできます。", + "PATH_ERROR_UNKNOWN_CID_N_THIS_TICKET_DOES_NOT_BELONG_TO_THIS_3DS": "%s\nエラー: 不明なCID %08lX\n \nチケットはこの3DS本体に属していません。", + "INSTALLING_TICKET": "チケットをインストール中…", + "POSSIBLY_BROKEN": "破損の可能性あり", + "PERSONAL_LEGIT": "個人的な合法", + "PERSONAL_LEGIT_DLC": "個人的な合法DLC", + "PERSONAL_PIRATE_LEGIT": "個人的な海賊合法", + "PERSONAL_PIRATE_LEGIT_DLC": "個人的な海賊合法DLC", + "PERSONAL_CUSTOM": "個人的なカスタム", + "PERSONAL_CUSTOM_DLC": "個人的なカスタムDLC", + "UNIVERSAL_LEGIT": "普遍的な合法", + "UNIVERSAL_LEGIT_DLC": "普遍的な合法DLC", + "UNIVERSAL_PIRATE_LEGIT": "普遍的な海賊合法", + "UNIVERSAL_PIRATE_LEGIT_DLC": "普遍的な海賊合法DLC", + "UNIVERSAL_CUSTOM": "普遍的なカスタム", + "UNIVERSAL_CUSTOM_DLC": "普遍的なカスタムDLC", + "CONTENTS_IN_CIA_FOUND_TOTAL": "CIAのコンテンツ数: %lu/%lu", + "CONTENTS_IN_CIA_TOTAL": "TMDのコンテンツ数: %lu個", + "CONSOLE_ID_N": "本体ID: %08lX\n", + "SHOW_GAME_INFO_DETAILS": "%s\n%sの%sタイトル\n \nタイトルID: %016llX\nタイトルバージョン: %lu.%lu.%lu\nコンテンツサイズ: %s\n%s\n%s \nチケット/TMD: %s/%s\n検証: %s", + "STATE_LEGIT": "合法", + "STATE_ILLEGIT": "非合法", + "STATE_UNKNOWN": "不明", + "STATE_INVALID": "無効", + "STATE_PENDING_PROCEED_WITH_VERIFICATION": "未決\n \n検証に続けますか?", + "STATE_PASSED": "合格", + "STATE_FAILED": "失敗", + "OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS": "出力ファイルがすでに存在する。\nこれを更新しますか?", + "DSI_ENHANCED": "DSi対応", + "DSI_EXCLUSIVE": "DSi専用", + "FIXING_CMACS_PLEASE_WAIT": "CMACを修正中。お待ちください。", + "NCSD_HEADER_IS_NOT_VALID": "NCSDヘッダーが無効です", + "NAND_DUMP_MISSING_DATA": "NANDダンプはデータ欠落しています", + "ERROR_CTR_MBR_IS_CORRUPT": "エラー: CTR MBRが破損しています", + "ERROR_TWL_MBR_IS_CORRUPT": "エラー: TWL MBRが破損しています", + "PATH_ERROR_CTR_PARTITION_N_IS_CORRUPT": "%s\nエラー: CTRパーティション第%luが破損しています", + "PATH_ERROR_TWL_PARTITION_N_IS_CORRUPT": "%s\nエラー: TWLパーティション第%luが破損しています", + "NO_VALID_FIRM_FOUND": "有効なFIRMがありません", + "ERROR_NAND_DUMP_IS_CORRUPT_STILL_CONTINUE": "エラー: NANDダンプが破損しています。\nまだ続けますか?", + "ERROR_SYSTEM_IS_LOCKED": "エラー: 本体がロックされています", + "ESSENTIAL_FILES_BACKUP_IS_REQUIRED_CREATE_ONE_NOW": "必須ファイルのバックアップ必要があります。\n今すぐ作成しますか?", + "WARNING_PROCEEDING_WILL_OVERWRITE_SYSNAND_WITH_DUMP": " ・ ・\n‼ 警 告 ‼\n \n続けると、システムNANDが与えられたダンプで上書きされます。\n \n(B9S/A9LHはそのまま残ります)", + "IMAGE_NCSD_CORRUPT_OR_CUSTOMIZED_SAFE_RESTORE_NOT_POSSIBLE": "イメージのNCSDが破損またはカスタムです。\n安全な復元はできません!", + "WARNING_NCSD_DIFFERS_BETWEEN_IMAGE_AND_LOCAL_ELEVATED_WRITE_PERMISSIONS_REQUIRED": " ・ ・\n‼ 警 告 ‼\n\nNCSDはイメージとローカルで異なるので、\n昇格書き込み権限必要があります。\n\n自己責任で続けますか?", + "NOT_AN_INSTALLABLE_FIRM": "インストール可能なFIRMではない。", + "FIRM_LOAD_VERIFY_ERROR": "FIRMの読み取り・検証失敗。", + "PATH_FIRM_N_NOT_FOUND_OR_TOO_SMALL": "%s\nFIRM%luがありませんまたは小さすぎます。", + "SECTOR_0X96_CRYPTO_FAIL": "セクタ0x96暗号化に失敗しました。", + "SECTOR_0X96_CORRUPTED_PROVIDE_SECRET_SECTOR_BIN_TO_FIX": "セクタ0x96が破損しています。\n \nセクタ0x96を修正するには、\n「secret_sector.bin」を与えてください。", + "SECTOR_0X96_CORRUPTED_FIX_DURING_INSTALLATION": "セクタ0x96が破損しています。\n \nインストール中にセクタ0x96を修正しますか?", + "WARNING_PROCEEDING_WILL_INSTALL_FIRM_TO_SYSNAND_AND_INJECT_SIGHAX_UNSUPPORTED_FIRM_WILL_BRICK": " ・ ・\n‼ 警 告 ‼\n \n続けると、与えられたFIRMをシステムNANDに\nインストールし、sighaxを挿入します。\n \nサポートされていないFIRMをインストールすると、\n本体をBRICKします!(壊れます!)", + "INSTALLING_FIRM_PLEASE_WAIT": "インストール中。お待ちください。", + "THIS_IS_BAD_FAILED_WRITING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": " ・・・・・・・\n‼これは悪いです‼\n \nセクタ0x96の書き込みに失敗しました。\n再起動する前に修正してみてください!", + "THIS_IS_BAD_FAILED_WRITING_FIRM_N_TRY_FIX_BEFORE_REBOOT": " ・・・・・・・\n‼これは悪いです‼\n \nFIRM%luの書き込みに失敗しました。\n再起動する前に修正してみてください!", + "CHECKING_INSTALLATION_PLEASE_WAIT": "インストールを確認中。お待ちください。", + "THIS_IS_BAD_FAILED_VERIFYING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": " ・・・・・・・\n‼これは悪いです‼\n \nセクタ0x96の検証に失敗しました。\n再起動する前に修正してみてください!", + "THIS_IS_BAD_FAILED_VERIFYING_FIRM_N_TRY_FIX_BEFORE_REBOOT": " ・・・・・・・\n‼これは悪いです‼\n \nFIRM%luの検証に失敗しました。\n再起動する前に修正してみてください!", + "PERFECT_KEYDB_IS_ALREADY_INSTALLED": "完全な%sはインストール済みです。", + "PATH_NOT_PERFECT_KEYDB_IMAGE_CANNOT_INSTALL_TO_NAND": "%s\n完全な%sイメージではない。\nNANDにインストールできません!", + "PATH_FAILED_WRITING_KEYDB_TO_NAND": "%s\n%sをNANDへの書き込みに失敗しました!", + "USE_L_R_TO_SAVE": "(L+Rで保存)", + "EASTER_NOT_FOUND": "(%sがありません)", + "BUILDING_TO_OUT_ARG": "%sに作成中…\n%s", + "EJECT_SD_CARD": "SDカードを取り出す…", + "INSERT_SD_CARD": "SDカードを挿入…", + "SCRIPTERR_UNKNOWN_CMD": "不明コマンド", + "SCRIPTERR_BAD_NUMBER_OF_ARGS": "不正な引数数", + "SCRIPTERR_UNRECOGNIZED_FLAGS": "不明フラグ", + "SCRIPTERR_ILLEGAL_FLAG": "禁止フラグ", + "SCRIPTERR_UNRESOLVED_QUOTES": "未解決な引用符", + "SCRIPTERR_TOO_MANY_ARGUMENTS": "多すぎる引数", + "SCRIPTERR_ARGUMENT_EXPAND_FAILED": "引数展開失敗", + "SCRIPTERR_QUOTE_NOT_AN_ERROR": "「not」エラー", + "SCRIPTERR_SYNTAX_ERROR_AFTER_IF": "「if」後の構文エラー", + "SCRIPTERR_ELIF_WITHOUT_IF": "「if」のない「elif」", + "SCRIPTERR_SYNTAX_ERROR_AFTER_ELIF": "「elif」後の構文エラー", + "SCRIPTERR_ELSE_WITHOUT_IF": "「if」のない「else」", + "SCRIPTERR_END_WITHOUT_IF": "「if」のない「end」", + "SCRIPTERR_FOR_INSIDE_FOR": "「for」の中「for」", + "SCRIPTERR_DIR_NOT_FOUND": "フォルダありません", + "SCRIPTERR_FOR_WITHOUT_NEXT": "「next」のない「for」", + "SCRIPTERR_NEXT_WITHOUT_FOR": "「for」のない「next」", + "SCRIPTERR_FORPATH_ERROR": "forpathエラー", + "SCRIPTERR_LABEL_NOT_FOUND": "ラベルありません", + "SCRIPTERR_USER_ABORT": "ユーザー中止", + "SCRIPTERR_KEY_NOT_PRESSED": "キー押されていない", + "SCRIPTERR_OUT_OF_MEMORY": "メモリ不足", + "SCRIPTERR_VAR_FAIL": "変数失敗", + "SCRIPTERR_FORBIDDEN_DRIVE": "禁止ドライブ", + "SCRIPTERR_INVALID_PATH": "無効パス", + "SCRIPTERR_FILESELECT_ABORT": "ファイル選択中止", + "SCRIPTERR_DIRSELECT_ABORT": "フォルダ選択中止", + "SCRIPTERR_SET_FAIL": "設定失敗", + "SCRIPTERR_CHAR_NOT_FOUND": "charありません", + "SCRIPTERR_ARGV_2_IS_NOT_CHAR": "argv[2]はcharではない", + "SCRIPTERR_ARGV_2_MUST_BE_2_CHARS": "argv[2]は2文字でなければなりません", + "SCRIPTERR_ARG_MATCH": "引数一致", + "SCRIPTERR_NO_ARG_MATCH": "引数不一致", + "SCRIPTERR_PERMISSION_FAIL": "権限失敗", + "SCRIPTERR_COPY_FAIL": "コピー失敗", + "SCRIPTERR_MOVE_FAIL": "移動失敗", + "SCRIPTERR_INJECT_FAIL": "注入失敗", + "SCRIPTERR_FILLBYTE_FAIL": "fillbyte失敗", + "SCRIPTERR_FILL_FAIL": "埋め失敗", + "SCRIPTERR_BAD_FILESIZE": "無効ファイルサイズ", + "SCRIPTERR_CREATE_DUMMY_FILE": "ダミー作成失敗", + "SCRIPTERR_REMOVE_FAIL": "削除失敗", + "SCRIPTERR_MAKEDIR_FAIL": "フォルダ作成失敗", + "SCRIPTERR_MOUNT_FAIL": "マウント失敗", + "SCRIPTERR_FIND_FAIL": "検索失敗", + "SCRIPTERR_FINDNOT_FAIL": "not検索失敗", + "SCRIPTERR_NO_SIZE_GIVEN": "サイズありません", + "SCRIPTERR_SIZE_TOO_BIG": "多すぎるサイズ", + "SCRIPTERR_READ_FAIL": "読み込み失敗", + "SCRIPTERR_CONVERSION_FAIL": "変換失敗", + "SCRIPTERR_INVALID_DATA": "無効データ", + "SCRIPTERR_WRITE_FAIL": "書き込み失敗", + "SCRIPTERR_SHA_ARG0_FAIL": "SHA第0引数失敗", + "SCRIPTERR_SHA_ARG1_FAIL": "SHA第1引数失敗", + "SCRIPTERR_SHA_DOES_NOT_MATCH": "SHA不一致", + "SCRIPTERR_SHA_WRITE_FAIL": "SHA書き込み失敗", + "SCRIPTERR_FILE_WRITE_FAIL": "ファイル書き込み失敗", + "SCRIPTERR_FIXCMAC_FAILED": "CMAC修正失敗", + "SCRIPTERR_VERIFICATION_FAILED": "検証失敗", + "SCRIPTERR_DECRYPT_FAILED": "復号失敗", + "SCRIPTERR_ENCRYPT_FAILED": "暗号失敗", + "SCRIPTERR_BUILD_CIA_FAILED": "CIA作成失敗", + "SCRIPTERR_INSTALL_GAME_FAILED": "ゲームインストール失敗", + "SCRIPTERR_DOES_NOT_CONTAIN_DOT_CODE": ".code含まない", + "SCRIPTERR_EXTRACT_DOT_CODE_FAILED": ".code解凍失敗", + "SCRIPTERR_COMPRESS_DOT_CODE_FAILED": ".code圧縮失敗", + "SCRIPTERR_BUILD_FAILED": "作成失敗", + "SCRIPTERR_UNKNOWN_FILE": "不明ファイル", + "SCRIPTERR_APPLY_IPS_FAILD": "IPS当てる失敗", + "SCRIPTERR_APPLY_BPS_FAILED": "BPS当てる失敗", + "SCRIPTERR_APPLY_BPM_FAILED": "BPM当てる失敗", + "SCRIPTERR_TEXTVIEWER_FAILED": "テキストビューアー失敗", + "SCRIPTERR_BAD_DUMPSIZE": "不良ダンプサイズ", + "SCRIPTERR_CART_INIT_FAIL": "カート初期化失敗", + "SCRIPTERR_CART_DUMP_FAILED": "カートダンプ失敗", + "SCRIPTERR_NOT_A_DIR": "フォルダではない", + "SCRIPTERR_FILE_NOT_FOUND": "ファイルありません", + "SCRIPTERR_NOT_A_BOOTABLE_FIRM": "起動できるFIRMではない", + "SCRIPTERR_SD_NOT_MOUNTED": "SDマウントされていない", + "SCRIPTERR_UNKNOWN_ERROR": "不明なエラー", + "SCRIPTERR_COMMAND_SUCCESS": "コマンド成功", + "SCRIPTERR_CONTROL_FLOW_ERROR": "制御流れエラー", + "SCRIPTERR_UNCLOSED_CONDITIONAL": "未解決条件付き", + "SCRIPTERR_ERROR_MESSAGE_FAIL": "エラーメッセージ失敗", + "ERROR_INVALID_TEXT_DATA": "エラー: 無効なテキストデータ", + "TEXTVIEWER_CONTROLS_DETAILS": "テキストビューアーのコントロル\n \n↑↓→←(+R) - スクロール\nR+Y - ワードラップを切り替え\nR+X - 行番号に移動\nB - 終了\n", + "CURRENT_LINE_N_ENTER_NEW_LINE_BELOW": "現在の行: %i\n以下に新しい行を入力してください。", + "PREVIEW_DISABLED": "(プレビュー無効)", + "PATH_LINE_N_ERR_LINE": "%s\n第%lu行: %s\n%s", + "END_OF_SCRIPT_UNRESOLVED_IF": "スクリプトの終わり: 未解決の「if」", + "END_OF_SCRIPT_UNRESOLVED_FOR": "スクリプトの終わり: 未解決の「for」", + "SYSINFO_MODEL": "モデル: %s (%s)\n", + "SYSINFO_SERIAL": "シリアル: %s\n", + "SYSINFO_REGION_SYSTEM": "地域(本体): %s\n", + "SYSINFO_REGION_SALES": "地域(販売): %s\n", + "SYSINFO_SOC_MANUFACTURING_DATE": "SoC製造日: %s\n", + "SYSINFO_SYSTEM_ASSEMBLY_DATE": "本体組立日:  %s\n", + "SYSINFO_ORIGINAL_FIRMWARE": "元のファームウェア: %s\n", + "SYSINFO_FRIENDCODE_SEED": "フレンドコードのシード: %s\n", + "SYSINFO_SD_KEYY": "SDキーY: %s\n", + "SYSINFO_NAND_CID": "NAND CID: %s\n", + "SYSINFO_SD_CID": "SD CID: %s\n", + "SYSINFO_SYSTEM_ID0": "本体ID0: %s\n", + "SYSINFO_SYSTEM_ID1": "本体ID1: %s\n", + "SORTING_TICKETS_PLEASE_WAIT": "チケットを並べ替えています。お待ちください。" +} diff --git a/resources/languages/nl.json b/resources/languages/nl.json new file mode 100644 index 000000000..9788c58b9 --- /dev/null +++ b/resources/languages/nl.json @@ -0,0 +1,700 @@ +{ + "GM9_LANGUAGE": "Nederlands", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%4$02lX-%3$02lX-%1$s%2$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ",", + "THOUSAND_SEPARATOR": ".", + "FIRM_TOO_BIG": "FIRM te groot, kan niet opstarten", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nOpgepast: start geen FIRMs\nop van onbetrouwbare bronnen.\n\nStart FIRM op?", + "NOT_BOOTABLE_FIRM": "Geen opstartbare FIRM.", + "FIRM_ENCRYPTED": "FIRM is versleuteld.\n\nOntsleutelen voor het opstarten?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Kopiëren naar %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Probeer toch op te starten", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Opgepast: poging om op te starten\nvan een niet-ondersteunde locatie.", + "ROOT": "[root]", + "LOADING": "LADEN...", + "PANE_N": "PANEEL #%lu", + "CURRENT": "HUIDIGE", + "DIR": "(map)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAM-schijf FAT)", + "GAME_VIRTUAL": "(Game Virtueel)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND Virtueel)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND Virtueel)", + "IMAGE_FAT": "(Schijfkopie FAT)", + "XORPAD_VIRTUAL": "(XORpad Virtueel)", + "MEMORY_VIRTUAL": "(Geheugen Virtueel)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Spelkaart Virtueel)", + "VRAM_VIRTUAL": "(VRAM Virtueel)", + "SEARCH": "(Zoeken)", + "TITLEMANAGER_VIRTUAL": "(TitleManager Virtueel)", + "LAB_SDCARD": "SDKAART", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUEEL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUEEL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUEEL", + "LAB_GAMECART": "SPELKAART", + "LAB_GAME_IMAGE": "GAMEKOPIE", + "LAB_AESKEYDB_IMAGE": "AESKEYDB KOPIE", + "LAB_BDRI_IMAGE": "BDRI-KOPIE", + "LAB_DISA_DIFF_IMAGE": "DISA/DIFF-KOPIE", + "LAB_MEMORY_VIRTUAL": "GEHEUGEN VIRTUEEL", + "LAB_VRAM_VIRTUAL": "VRAM VIRTUEEL", + "LAB_TITLE_MANAGER": "Beheer titels", + "LAB_LAST_SEARCH": "LAATSTE ZOEKOPDRACHT", + "LAB_FAT_IMAGE": "FAT-schijfkopie", + "LAB_BONUS_DRIVE": "BONUS-SCHIJF", + "LAB_RAMDRIVE": "RAM-schijf", + "LAB_NOLABEL": "GEENLABEL", + "N_BYTE": "%s Bytes", + "BYTE": " Byte", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[KLEMBORD]", + "PLUS_N_MORE": "+ %lu meer", + "MARK_DELETE_COPY": "L - MARKEER bestand (gebruiken met ↑↓→←)\nX - VERWIJDER / [+R] HERNOEM bestand\nY - KOPIEER bestand / [+R] MAAK nieuw bestand", + "MARK_DELETE_PASTE": "L - MARKEER bestand (gebruiken met ↑↓→←)\nX - VERWIJDER / [+R] HERNOEM bestand\nY - PLAK bestand / [+R] MAAK nieuw bestand", + "RELOCK_WRITE_PERMISSION": "R+Y - Schrijfrechten opnieuw vergrendelen\n", + "UNMOUNT_IMAGE": "R+X - Ontkoppel schijfkopie", + "UNMOUNT_SD": "R+B - Ontkoppel SD-kaart", + "REMOUNT_SD": "R+B - Herplaats SD-kaart", + "DIRECTORY_OPTIONS": "R+A - Mapopties", + "DRIVE_OPTIONS": "R+A - Schijfopties", + "MAKE_SCREENSHOT": "R+L - Maak een screenshot\n", + "PREV_NEXT_PANE": "R+←→ - Ga naar vorig/volgend paneel", + "CLEAR_CLIPBOARD": "SELECT - Wis klembord", + "RESTORE_CLIPBOARD": "SELECT - Herstel klembord", + "REBOOT_POWEROFF_HOME": "START - Herstart / [+R] Sluit af\nHOME-knop voor HOME-menu", + "NO_EMUNAND": "Geen EmuNAND", + "REDNAND_SIZE_MIN": "RedNAND-grootte (min)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNAND-grootte (volledig)", + "MULTINAND_SIZE_2X": "MultiNAND-grootte (2x)", + "MULTINAND_SIZE_3X": "MultiNAND-grootte (3x)", + "MULTINAND_SIZE_4X": "MultiNAND-grootte (4x)", + "USER_INPUT": "Gebruikersinvoer...", + "AUTO": "Auto", + "16KB_CLUSTERS": "16KB Clusters", + "32KB_CLUSTERS": "32KB Clusters", + "64KB_CLUSTERS": "64KB Clusters", + "SD_NOT_DETECTED": "Fout: SD-kaart niet gedetecteerd.", + "FORMAT_SD_CHOOSE_EMUNAND": "Formatteer SD-kaart (%lluMB)?\nKies EmuNAND-grootte:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "SD-kaartgrootte is %lluMB.\nVoer hieronder de EmuNAND-grootte (MB) in:", + "FORMAT_SD_CHOOSE_CLUSTER": "Formatteer SD-kaart (%lluMB)?\nKies clustergrootte:", + "FORMAT_SD_ENTER_LABEL": "Formatteer SD-kaart (%lluMB)?\nVoer label in:", + "FORMAT_SD_FAILED": "SD formatteren: mislukt!", + "REDNAND_TYPE": "RedNAND-type", + "REDNAND_TYPE_MULTI": "RedNAND-type (multi)", + "REDNAND_TYPE_SINGLE": "RedNAND-type (single)", + "GW_EMUNAND_TYPE": "GW EmuNAND-type", + "DONT_SET_UP": "Niet instellen", + "CHOOSE_EMUNAND_TYPE": "Kies EmuNAND-type om in te stellen:", + "CLONE_SYSNAND_TO_REDNAND": "SysNAND naar RedNAND kopiëren?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "Kopiëren van SysNAND naar EmuNAND: mislukt!", + "PRESS_A_TO_CONTINUE": "Druk op om verder te gaan", + "HEXEDITOR_CONTROLS": "Hex-editor toetsen:\n\n↑↓→←(+R) - Scroll\nR+Y - Wissel van beeld\nX - Zoek / ga...\nA - Open bewerkingsmodus\nA+↑↓→← - Waarde aanpassen\nB - Afsluiten", + "NOT_FOUND": "Niet gevonden!", + "GO_TO_OFFSET": "Ga naar offset", + "SEARCH_FOR_STRING": "Zoek naar tekst", + "SEARCH_FOR_DATA": "Zoek naar gegevens", + "CURRENT_OFFSET_SELECT_ACTION": "Huidige offset: %08lX\nSelecteer actie:", + "CURRENT_OFFSET_ENTER_NEW": "Huidige offset: %08lX\nVul hieronder de nieuwe offset in.", + "ENTER_SEARCH_REPEAT_SEARCH": "Voer de zoekterm hieronder in.\n(R+X om zoekopdracht te herhalen)", + "MADE_EDITS_SAVE_CHANGES": "Je maakte bewerkingen op %lu plaats(en).\nWijzigingen naar bestand opslaan?", + "FAILED_WRITING_TO_FILE": "Schrijven naar bestand mislukt!", + "CALCULATING_SHA_FAILED": "Berekenen van SHA-%s mislukt!", + "SHA_VERIFICATION_PASSED": "\nSHA-verificatie: geslaagd!", + "SHA_VERIFICATION_FAILED": "\nSHA-verificatie: mislukt", + "IDENTICAL_WITH_PREVIOUS": "\n \nIdentiek aan het vorige bestand:\n", + "WRITE_SHA_FILE": "\n \nSchrijf .SHA bestand?", + "WRITE_SHA1_FILE": "\n \nSchrijf .SHA1 bestand?", + "CALCULATING_CMAC_FAILED": "Berekenen van CMAC: mislukt!", + "CMAC_VERIFICATION_PASSED": "CMAC-verificatie: geslaagd!", + "CMAC_VERIFICATION_FAILED": "CMAC-verificatie: mislukt!", + "FIX_CMAC_IN_FILE": "\nRepareer CMAC in bestand?", + "FIXING_CMAC_FAILED": "CMAC repareren: mislukt!", + "COPY_ALL_SELECTED_ITEMS": "Alle %lu geselecteerde items kopiëren?", + "FAILED_COPYING_ITEM": "Kopiëren van item mislukt", + "ITEMS_COPIED_TO_OUT": "%lu items gekopieerd naar %s", + "PATH_COPIED_TO_OUT": "%s\nGekopieerd naar %s", + "CART_INIT_FAILED": "Spelkaartinitialisatie mislukt!", + "CART_DETECTED_SIZE_INPUT_BELOW": "Spelkaart: %s\nGedetecteerde grootte: %s\n \nVoer de dumpgrootte hieronder in.", + "NDS_CART_DECRYPT_SECURE_AREA": "Spelkaart: %s\nNDS-kaart gedetecteerd\nDecrypteer de 'secure area'?", + "FAILED_DUMPING_CART": "%s\nDumpen spelkaart mislukt", + "PATH_DUMPED_TO_OUT": "%s\nGedumpt naar %s", + "CREATED": "gemaakt", + "MODIFIED": "gewijzigd", + "ANALYZING_DRIVE": "Schijf analyseren, even geduld...", + "ANALYZING_DIR": "Map analyseren, even geduld...", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu bestanden & %lu mappen\ntotale grootte %s\n \nvrije ruimte: %s\ngebruikte ruimte: %s\ntotaal: %s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu bestanden & %lu mappen\ntotale grootte %s", + "FILESIZE_X": "bestandsgrootte: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %salleen lezen [%c] %sverborgen\n[%c] %ssysteem [%c] %sarchief\n[%c] %svirtueel\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→← om attributen te wijzigen)\n", + "A_TO_CONTINUE": "( om verder te gaan)", + "A_APPLY_B_CANCEL": "( om toe te passen, om te annuleren)", + "A_YES_B_NO": "( ja, nee)", + "A_SELECT_B_CANCEL": "( selecteer, annuleer)", + "HOLD_B_TO_CANCEL": "(houd B ingedrukt om te annuleren)", + "FAILED_TO_SET_ATTRIBUTES": "Attributen instellen mislukt!", + "NAND_IMAGE_OPTIONS": "NAND-schijfkopieinstellingen...", + "CTRNAND_OPTIONS": "CTRNAND-instellingen...", + "MOUNT_FAT_IMAGE": "Koppel als FAT-schijfkopie", + "CIA_IMAGE_OPTIONS": "CIA-schijfkopieinstellingen...", + "NCSD_IMAGE_OPTIONS": "NCSD-schijfkopieinstellingen...", + "NCCH_IMAGE_OPTIONS": "NCCH-schijfkopieinstellingen...", + "MOUNT_AS_EXEFS_IMAGE": "Koppel als EXEFS-schijfkopie", + "MOUNT_AS_ROMFS_IMAGE": "Koppel als ROMFS-schijfkopie", + "TMD_FILE_OPTIONS": "TMD-bestandsinstellingen...", + "TMD_CDN_OPTIONS": "TMD/CDN-instellingen...", + "TMD_TWL_OPTIONS": "TMD/TWL-instellingen...", + "MANAGE_TITLE": "Titel beheren...", + "BOSS_FILE_OPTIONS": "BOSS-bestandsinstellingen...", + "DECRYPT_NUS_CDN_FILE": "Decodeer NUS/CDN-bestand", + "SHOW_SMDH_TITLE_INFO": "Toon SMDH titelinfo", + "NDS_IMAGE_OPTIONS": "NDS-schijfkopieinstellingen...", + "GBA_IMAGE_OPTIONS": "GBA-schijfkopieinstellingen...", + "TICKET_OPTIONS": "Ticketinstellingen...", + "TAD_IMAGE_OPTIONS": "TAD-schijfkopieinstellingen...", + "SHOW_3DSX_TITLE_INFO": "Toon 3DSX titelinfo", + "FIRM_IMAGE_OPTIONS": "FIRM-schijfkopieinstellingen...", + "AGBSAVE_OPTIONS": "AGBSAVE-instellingen...", + "DUMP_GBA_VC_SAVE": "Dump GBA VC save", + "TICKET_DB_OPTIONS": "Ticket.db-instellingen...", + "MOUNT_AS_DIFF_IMAGE": "Koppel als DIFF-schijfkopie", + "MOUNT_AS_DISA_IAMGE": "Koppel als DISA-kopie", + "INSTALL_CIFINISH_BIN": "Installeer cifinish.bin", + "TITLEKEY_OPTIONS": "Ticketinstellingen...", + "AESKEYDB_OPTIONS": "AESkeydb-instellingen...", + "BUILD_X": "Build %s", + "NCCHINFO_OPTIONS": "NCCHinfo-instellingen...", + "EXECUTE_GM9_SCRIPT": "GM9-script uitvoeren", + "FONT_OPTIONS": "Lettertype-instellingen...", + "LANGUAGE_OPTIONS": "Taalinstellingen...", + "VIEW_PNG_FILE": "PNG-bestand bekijken", + "REBUILD_NCSD_HEADER": "Herbouw NCSD-header", + "SHOW_IN_HEXEDITOR": "Toon in Hexeditor", + "CALCULATE_SHA256": "Bereken SHA-256", + "CALCULATE_SHA1": "Bereken SHA-1", + "SHOW_FILE_INFO": "Toon bestandsinfo", + "SHOW_IN_TEXTVIEWER": "Toon in Tekstviewer", + "CALCULATE_CMAC": "Bereken CMAC", + "COPY_TO_OUT": "Kopiëren naar %s", + "DUMP_TO_OUT": "Dumpen naar %s", + "INJECT_DATA_AT_OFFSET": "Gegevens injecteren @offset", + "OPEN_THIS_FOLDER": "Open deze map", + "OPEN_CONTAINING_FOLDER": "Open bijbehorende map", + "OPEN_TITLE_FOLDER": "Open titel-map", + "PATH_N_FILES_SELECTED": "%s\n(%lu bestanden geselecteerd)", + "CHECK_CURRENT_CMAC_ONLY": "Controleer alleen de huidige CMAC", + "VERIFY_CMAC_FOR_ALL": "Controleer CMAC voor alle", + "FIX_CMAC_FOR_ALL": "Herstel CMAC voor alle", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%lu bestanden ok/gefixt/totaal\n%lu/%lu hebben geen CMAC", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%lu bestanden ok geverifieerd\n%lu/%lu bestanden opgelost", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%lu bestanden ok geverifieerd\n%lu/%lu hebben geen CMAC", + "N_OF_N_FILES_VERIFIED": "%lu/%lu bestanden ok geverifieerd", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "Injecteer gegevens van %s?\nSpecificeer de offset hieronder.", + "FAILED_INJECTING_PATH": "%s injecteren mislukt", + "MOUNT_CXI_NDS_TO_DRIVE": "Koppel CXI/NDS naar schijf", + "MOUNT_IMAGE_TO_DRIVE": "Koppel kopie naar schijf", + "RESTORE_SYSNAND_SAFE": "Herstel SysNAND (veilig)", + "UPDATE_EMBEDDED_BACKUP": "Ingesloten back-up bijwerken", + "SHOW_TITLE_INFO": "Toon titelinfo", + "DECRYPT_FILE": "Decodeer bestand (...)", + "DECRYPT_FILE_OUT": "Decodeer bestand (%s)", + "ENCRYPT_FILE": "Versleutel bestand (...)", + "ENCRYPT_FILE_OUT": "Versleutel bestand (%s)", + "BUILD_CIA_FROM_FILE": "Bouw CIA vanuit bestand", + "BUILD_CIA_STANDARD": "Bouw CIA (standaard)", + "BUILD_CIA_LEGIT": "Bouw CIA (legitiem)", + "DUMP_CXI_NDS_FILE": "Dump CXI/NDS-bestand", + "INSTALL_GAME_IMAGE": "Installeer game-kopie", + "INSTALL_TICKET": "Installeer ticket", + "DUMP_TICKET_FILE": "Dump ticket-bestand", + "UNINSTALL_TITLE": "Deïnstalleer titel", + "VERIFY_FILE": "Verifieer bestand", + "TRANSFER_IMAGE_TO_CTRNAND": "Kopie verplaatsen naar CTRNAND", + "INJECT_TO_H_AND_S": "Injecteer naar H&S", + "TRIM_FILE": "Trim bestand", + "RENAME_FILE": "Hernoem bestand", + "BUILD_XORPADS_SD": "Bouw XORpads (SD-uitgang)", + "BUILD_XORPADS_INPLACE": "Bouw XORpads (inplaats)", + "EXTRACT_X": "%s uitpakken", + "INIT_X": "Init %s", + "INSTALL_X": "Installeer %s", + "INSTALL_FIRM": "Installeer FIRM", + "BOOT_FIRM": "Start FIRM", + "SET_AS_ACTIVE_FONT": "Instellen als actief lettertype", + "SET_AS_ACTIVE_LANGUAGE": "Instellen als actieve taal", + "DUMP_BA_VC_SAVE": "Dump GBA VC save", + "INJECT_GBA_VC_SAVE": "Injecteer GBA VC save", + "SET_AS_DEFAULT": "Instellen als standaard", + "MOUNTING_IMAGE_FAILED": "Kopie koppelen: mislukt", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nGekoppeld als schijf %s\nNu het pad in gaan?", + "DECRYPT_TO_OUT": "Decodeer naar %s", + "DECRYPT_INPLACE": "Decodeer inplaats", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "Proberen alle %lu bestanden te ontsleutelen?", + "TRYING_TO_DECRYPT_N_FILES": "%lu bestanden aan het proberen te ontsleutelen...", + "DECRYPTION_FAILED_CONTINUE": "Ontsleuteling mislukt\n\nDoorgaan?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu bestanden goed ontsleuteld\n%lu/%lu niet versleuteld\n%lu/%lu niet van hetzelfde type", + "N_OF_N_FILES_DECRYPTED": "%lu/%lu bestanden goed ontsleuteld", + "N_FILES_WRITTEN_TO_OUT": "%lu bestanden naar %s geschreven", + "FILE_NOT_ENCRYPTED": "Bestand is niet versleuteld", + "DECRYPTION_SUCCESS": "Ontsleuteling gelukt", + "DECRYPTION_FAILED": "Ontsleuteling mislukt", + "PATH_DECRYPTED_TO_OUT": "%s\nOntsleuteld naar %s", + "ENCRYPT_TO_OUT": "Versleutelen naar %s", + "ENCRYPT_INPLACE": "Encrypt inplace", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "Proberen alle %lu geselecteerde bestanden te versleutelen?", + "TRYING_TO_ENCRYPT_N_FILES": "%lu bestanden aan het proberen te versleutelen...", + "ENCRYPTION_FAILED_CONTINUE": "Versleuteling mislukt\n\nDoorgaan?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files encrypted ok\n%lu/%lu not of same type", + "N_OF_N_FILES_ENCRYPTED": "%lu/%lu files encrypted ok", + "ENCRYPTION_SUCCESS": "Encryption success", + "ENCRYPTION_FAILED": "Encryption failed", + "PATH_ENCRYPTED_TO_OUT": "%s\nEncrypted to %s", + "TRY_TO_PROCESS_N_SELECTED_FILES": "Try to process all %lu selected files?", + "PATH_BUILD_TYPE_FAILED_CONTINUE": "%s\nBuild %s failed\n \nContinue?", + "N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE": "%lu/%lu %ss built ok\n%lu/%lu not of same type", + "N_OF_N_TYPES_BUILT": "%lu/%lu %ss built ok", + "N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED": "%lu file(s) failed conversion.\nVerification is recommended.", + "PATH_TYPE_BUILT_TO_OUT": "%s\n%s built to %s", + "PATH_TYPE_BUILD_FAILED": "%s\n%s build failed", + "FILE_FAILED_CONVERSION_VERIFY_NOW": "file failed conversion.\n \nVerify now?", + "VERIFICATION_SUCCESS": "Verification success", + "VERIFICATION_FAILED": "Verification failed", + "CONTENT_IS_MISSING": "Content is missing", + "INSTALL_TO_SYSNAND": "Install to SysNAND", + "INSTALL_TO_EMUNAND": "Install to EmuNAND", + "TRY_TO_INSTALL_N_SELECTED_FILES": "Try to install all %lu selected files?", + "TRYING_TO_INSTALL_N_FILES": "Trying to install %lu files...", + "INSTALL_FAILED_CONTINUE": "Install failed\n \nContinue?", + "N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files installed ok\n%lu/%lu not of same type", + "N_OF_N_FILES_INSTALLED": "%lu/%lu files installed ok", + "INSTALL_SUCCESS": "Install success", + "INSTALL_FAILED": "Install failed", + "FILE_FAILED_INSTALL_VERIFY_NOW": "file failed install.\n \nVerify now?", + "KEEP_TICKET_AND_SAVEGAME": "Keep ticket & savegame", + "UNINSTALL_EVERYTHING": "Uninstall everything", + "ABORT_UNINSTALL": "Abort uninstall", + "UNINSTALL_N_SELECTED_TITLES": "Uninstall %lu selected titles?", + "UNINSTALL_SELECTED_TITLE": "Uninstall selected title?", + "N_OF_N_TITLES_UNINSTALLED": "%lu/%lu titles uninstalled", + "UNINSTALLING_PLEASE_WAIT": "Uninstalling, please wait...", + "UNINSTALL_FAILED": "Uninstall failed!", + "TRY_TO_VERIFY_N_SELECTED_FILES": "Try to verify all %lu selected files?", + "VERIFICATION_FAILED_CONTINUE": "Verification failed\n \nContinue?", + "N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files verified ok\n%lu/%lu not of same type", + "VERIFYING_FILE_PLEASE_WAIT": "Verifying file, please wait...", + "NAND_VALIDATION_SUCCESS": "NAND validation success", + "NAND_VALIDATION_FAILED": "NAND validation failed", + "DUMP_FOR_N_SELECTED_FILES": "Dump for all %lu selected files?", + "N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL": "%lu/%lu legit tickets dumped.\n \nAttempt to dump all tickets?", + "N_OF_N_TICKETS_DUMPED_TO_OUT": "%lu/%lu tickets dumped to %s", + "PATH_TICKET_DUMPED_TO_OUT": "%s\nTicket dumped to %s", + "LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS": "%s\nLegit ticket not found.\n \nDump anyways?", + "DUMP_TICKET_FAILED": "Dump ticket failed!", + "BUILDING_X": "Building %s...", + "BUILDING_X_SYSNAND": "Building %s (SysNAND)...", + "BUILDING_X_EMUNAND": "Building %s (EmuNAND)...", + "PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED": "%s\n%lu/%lu files processed\n%lu/%lu files ignored", + "PATH_N_OF_N_FILES_PROCESSED": "%s\n%lu/%lu files processed", + "BUILD_DATABASE_SUCCESS": "Build database success.", + "BUILD_DATABASE_FAILED": "Build database failed.", + "TRY_TO_TRIM_N_SELECTED_FILES": "Try to trim all %lu selected files?", + "TRIMMING_FAILED_CONTINUE": "Trimming failed\n \nContinue?", + "N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED": "%lu/%lu files trimmed ok\n%lu/%lu not of same type\n%s saved", + "N_OF_N_FILES_TRIMMED_X_SAVED": "%lu/%lu files trimmed ok\n%s saved", + "FILE_CANT_BE_TRIMMED": "File can't be trimmed.", + "FILE_ALREADY_TRIMMED": "File is already trimmed.", + "PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE": "%s\nCurrent size: %s\nTrimmed size: %s\nDifference: %s\n \nTrim this file?", + "TRIMMING_FAILED": "Trimming failed.", + "PATH_TRIMMED_BY_X": "%s\nTrimmed by %s.", + "TRY_TO_RENAME_N_SELECTED_FILES": "Try to rename all %lu selected files?", + "N_OF_N_RENAMED": "%lu/%lu renamed ok", + "COULD_NOT_RENAME_TO_GOOD_NAME": "Could not rename to good name", + "SYSNAND_H_AND_S_INJECT": "SysNAND H&S inject", + "EMUNAND_H_AND_S_INJECT": "EmuNAND H&S inject", + "H_AND_S_INJECT_SUCCESS": "H&S inject success", + "H_AND_S_INJECT_FAILURE": "H&S inject failure", + "TRY_EXTRACT_ALL_N_SELECTED_FILES": "Try to extract all %lu selected files?", + "N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files extracted ok\n%lu/%lu not of same type", + "N_OF_N_FILES_EXTRACTED": "%lu/%lu files extracted ok", + "EXTRACTING_DOT_CODE": "Extracting .code, please wait...", + "PATH_EXT_EXTRACTED_TO_OUT": "%s\n%s extracted to %s", + "DOT_CODE_EXTRACT_FAILED": ".code extract failed", + "TRANSFER_TO_SYSNAND": "Transfer to SysNAND", + "TRANSFER_TO_EMUNAND": "Transfer to EmuNAND", + "CTRNAND_TRANSFER_SUCCESS": "CTRNAND transfer success", + "CTRNAND_TRANSFER_FAILED": "CTRNAND transfer failed", + "NO_VALID_DESTINATION_FOUND": "No valid destination found", + "NAND_RESTORE_SUCCESS": "NAND restore success", + "NAND_RESTORE_FAILED": "NAND restore failed", + "REBUILD_NCSD_SUCCESS": "Rebuild NCSD success", + "REBUILD_NCSD_FAILED": "Rebuild NCSD failed", + "PATH_NCCHINFO_PADGEN_SUCCESS": "%s\nNCCHinfo padgen success%cOutput dir: %s", + "PATH_NCCHINFO_PADGEN_FAILED": "%s\nNCCHinfo padgen failed%c%0.0s", + "UPDATING_EMBEDDED_BACKUP": "Updating embedded backup...", + "BACKUP_UPDATE_NOT_REQUIRED": "Backup update: not required", + "BACKUP_UPDATE_COMPLETED": "Backup update: completed", + "BACKUP_UPDATE_FAILED": "Backup update: failed!", + "WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK": "Warning: Keys are not verified.\nContinue on your own risk?", + "AESKEYDB_INIT_SUCCESS": "AESkeydb init success", + "AESKEYDB_INIT_FAILED": "AESkeydb init failed", + "AESKEYDB_INSTALL_SUCCESS": "AESkeydb install success", + "AESKEYDB_INSTALL_FAILED": "AESkeydb install failed", + "INSTALL_TO_FIRM0": "Install to FIRM0", + "INSTALL_TO_FIRM1": "Install to FIRM1", + "INSTALL_TO_BOTH": "Install to both", + "PATH_N_KB_INSTALL_TO_SYSNAND": "%s (%dkB)\nInstall to SysNAND?", + "PATH_N_KB_INSTALL_SUCCESS": "%s (%dkB)\nInstall success", + "PATH_N_KB_INSTALL_FAILED": "%s (%dkB)\nInstall failed", + "WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS": "Warning: Do not run scripts\nfrom untrusted sources.\n \nExecute script?", + "SCRIPT_EXECUTE_SUCCESS": "Script execute success", + "SCRIPT_EXECUTE_FAILURE": "Script execute failure", + "ERROR_CANNOT_VIEW_FILE": "Error: Cannot view file\n(Hint: maybe it's too big)", + "SAVEGAME_DUMPED_TO_OUT": "Savegame dumped to %s.", + "SAVEGAME_DUMP_FAILED": "Savegame dump failed!", + "GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD": "GBA VC savegame has to\nbe in the clipboard.", + "SAVEGAME_INJECT_SUCCESS": "Savegame inject success.", + "SAVEGAME_INJECT_FAILED": "Savegame inject failed!", + "FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Font will be active on next boot", + "LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Language will be active on next boot", + "HOME_MORE_MENU_SELECT_ACTION": "HOME more... menu.\nSelect action:", + "SD_FORMAT_MENU": "SD format menu", + "BONUS_DRIVE_MENU": "Bonus drive setup", + "SWITCH_EMUNAND": "Switch EmuNAND", + "BUILD_SUPPORT_FILES": "Build support files", + "RESTORE_H_AND_S": "Restore H&S", + "SET_RTC_DATE_TIME": "Set RTC date&time", + "CONFGURE_BRIGHTNESS": "Configure brightness", + "CALIBRATE_TOUCHSCREEN": "Calibrate touchscreen", + "SYSTEM_INFO": "System info", + "SHOW_README": "Show ReadMe", + "INITIALIZING_SD_FAILED_RETRY": "Initializing SD card failed! Retry?", + "SETUP_FAILED": "Setup failed!", + "CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT": "Current EmuNAND offset is %06lX.\nSwitch to next offset?", + "BUILT_IN_OUT_STATUSES": "Built in %s:\n \n%-18.18s %s\n%-18.18s %s\n%-18.18s %s", + "OK_SYS_EMU": "OK (Sys&Emu)", + "OK_SYS": "OK (Sys)", + "FAILED": "Failed", + "RESTORE_H_AND_S_EMUNAND": "Restore H&S (EmuNAND)", + "RESTORE_H_AND_S_SYSNAND": "Restore H&S (SysNAND)", + "TITLE_SET_RTC_DATE_TIME": "Set RTC date&time:", + "NEW_RTC_DATE_TIME_IS_TIME": "New RTC date&time is:\n%s\n \nHint: HOMEMENU time needs\nmanual adjustment after\nsetting the RTC.", + "TOUCHSCREEN_CALIBRATION_SUCCESS": "Touchscreen calibration success!", + "TOUCHSCREEN_CALIBRATION_FAILED": "Touchscreen calibration failed!", + "GODMODE9_README_TOC": "GodMode9 ReadMe Table of Contents", + "ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW": "Essential files backup not found.\nCreate one now?", + "BACKUP_EMBEDDED_WRITTEN_TO_OUT": "Backup embedded in SysNAND\nand written to %s.", + "RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW": "RTC date&time seems to be\nwrong. Set it now?", + "RESUME_GODMODE9": "Resume GodMode9", + "RESUME_BOOTLOADER": "Resume bootloader", + "SELECT_PAYLOAD": "Select payload...", + "SELECT_SCRIPT": "Select script...", + "POWEROFF_SYSTEM": "Poweroff system", + "REBOOT_SYSTEM": "Reboot system", + "FLAVOR_BOOTLOADER_SELECT_OPTION": "%s bootloader menu.\nSelect action:", + "BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD": "Bootloader payloads menu.\nSelect payload:", + "BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT": "Bootloader scripts menu.\nSelect script:", + "NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9": "No bootable FIRM found.\nNow resuming GodMode9...", + "OUT_OF_MEMORY": "Out of memory.", + "INVALID_DIRECTORY_OBJECT": "Invalid directory object", + "INVALID_ROOT_DIRECTORY": "Invalid root directory.", + "WRITE_PERMISSIONS_WERE_CHANGED_RELOCK": "Write permissions were changed.\nRelock them?", + "OPEN_TITLE_MANAGER": "Open title manager", + "SEARCH_FOR_FILES": "Search for files...", + "FIX_CMACS_FOR_DRIVE": "Fix CMACs for drive", + "SHOW_DIRECTORY_INFO": "Show directory info", + "SHOW_DRIVE_INFO": "Show drive info", + "FAILED_SETTING_UP_TITLE_MANAGER": "Failed setting up title manager!", + "SEARCH_FILE_ENTER_SEARCH_BELOW": "Search %s?\nEnter search below.", + "FOUND_N_RESULTS": "Found %lu results.", + "FIX_CMACS_FOR_DRIVE_FINISHED": "Fix CMACs for drive finished.", + "FAILED_TO_ANALYZE_DRIVE": "Failed to analyze drive\n", + "FAILED_TO_ANALYZE_DIR": "Failed to analyze dir\n", + "NOT_ALLOWED_IN_VIRTUAL_PATH": "Not allowed in virtual path", + "DELETE_N_PATHS": "Delete %lu path(s)?", + "DELETING_FILES_PLEASE_WAIT": "Deleting files, please wait...", + "FAILED_DELETING_N_OF_N_PATHS": "Failed deleting %lu/%lu path(s)", + "DELETE_FILE": "Delete \"%s\"?", + "FAILED_DELETING_PATH": "Failed deleting:\n%s", + "NOT_ALLOWED_IN_SEARCH_DRIVE": "Not allowed in search drive", + "NOT_ALLOWED_IN_VIRTUAL_GAME_PATH": "Not allowed in virtual game path", + "NOT_ALLOWED_IN_XORPAD_DRIVE": "Not allowed in XORpad drive", + "NOT_ALLOWED_IN_GAMECART_DRIVE": "Not allowed in gamecart drive", + "NOT_ALLOWED_IN_ALIAS_PATH": "Not allowed in alias path", + "COPY_PATHS": "Copy path(s)", + "MOVE_PATHS": "Move path(s)", + "PASTE_FILE_HERE": "Paste \"%s\" here?", + "PASTE_N_PATHS_HERE": "Paste %lu paths here?", + "FAILED_COPYING_PATH_PROCESS_REMAINING": "Failed copying path:\n%s\nProcess remaining?", + "FAILED_COPYING_PATH": "Failed copying path:\n%s", + "FAILED_MOVING_PATH_PROCESS_REMAINING": "Failed moving path:\n%s\nProcess remaining?", + "FAILED_MOVING_PATH": "Failed moving path:\n%s", + "RENAME_FILE_ENTER_NEW_NAME_BELOW": "Rename %s?\nEnter new name below.", + "FAILED_RENAMING_PATH": "Failed renaming path:\n%s", + "CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE": "Create a new entry here?\nSelect type.", + "CREATE_A_FOLDER": "Create a folder", + "CREATE_A_DUMMY_FILE": "Create a dummy file", + "CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW": "Create a new folder here?\nEnter name below.", + "CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW": "Create a new file here?\nEnter name below.", + "CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW": "Create a new %s here?\nEnter file size below.", + "FAILED_CREATING_FOLDER_PATH": "Failed creating folder:\n%s", + "FAILED_CREATING_FILE_PATH": "Failed creating file:\n%s", + "TITLE_MANAGER": "Title manager", + "BRICK_MY_3DS": "Brick my 3DS", + "LANGUAGE": "Language...", + "SCRIPTS": "Scripts...", + "PAYLOADS": "Payloads...", + "MORE": "More...", + "BRACKET_MORE": "[more...]", + "HOME_BUTTON_PRESSED_SELECT_ACTION": "HOME button pressed.\nSelect action:", + "POWER_BUTTON_PRESSED_SELECT_ACTION": "POWER button pressed.\nSelect action:", + "1_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "4_DRIVE_NAND_TWL": "[4:] NAND / TWL", + "A_DRIVE_SD_CARD": "[A:] SD CARD", + "B_DRIVE_SD_CARD": "[B:] SD CARD", + "TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE": "Title manager menu.\nSelect titles source:", + "LANGUAGES_DIRECTORY_NOT_FOUND": "Languages directory not found.\n(default path: 0:/gm9/%s)", + "SCRIPTS_DIRECTORY_NOT_FOUND": "Scripts directory not found.\n(default path: 0:/gm9/%s)", + "HOME_LANGUAGE_MENU_SELECT_LANGUAGE": "HOME language... menu.\nSelect language:", + "HOME_SCRIPTS_MENU_SELECT_SCRIPT": "HOME scripts... menu.\nSelect script:", + "PAYLOADS_DIRECTORY_NOT_FOUND": "Payloads directory not found.\n(default path: 0:/gm9/%s)", + "HOME_PAYLOADS_MENU_SELECT_PAYLOAD": "HOME payloads... menu.\nSelect payload:", + "UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT": "!Unexpected SD card removal!\n \nTo prevent data loss, unmount\nbefore ejecting the SD card.", + "FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT": "%s scripts menu.\nSelect script:", + "COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP": "Compiled as script autorunner\nbut no script provided.\n \nDerp!", + "KEYBOARD_CONTROLS_DETAILS": "Keyboard Controls:\n \n←/→ - Move cursor\nR - Caps / Capslock\nX - Delete char\nY - Insert char\nA - Submit\nB - Cancel\n \nSELECT switches to\nclassic prompt", + "TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS": "Touch the red crosshairs to\ncalibrate your touchscreen.\n \nUse the stylus for best\nresults!", + "INVALID": "INVALID", + "TO_PROCEED_ENTER_THIS": "To proceed, enter this:", + "TO_PROCEED_HOLD_X": "To proceed, hold :", + "N_MORE": " [%d more]", + "CANCEL": "cancel", + "R_FAST_SCROLL_L_CLEAR_DATA": "R - (↑↓) fast scroll\nL - clear data", + "X_REMOVE_CHAR_Y_INSERT_CHAR": "X - remove char\nY - insert char", + "ETA_N_MIN_N_SEC": "ETA %02llum%02llus", + "BRIGHTNESS_CONTROLS": "[←] Decrease brightness\n[→] Increase brightness\n \n[X] Use volume slider control\n[A] Set current brightness\n[B] Cancel", + "SEARCHING_PLEASE_WAIT": "Searching, please wait...", + "RENAME_TO_GOOD_NAME": "Rename to good name?", + "SD_WRITE_PROTECTED_CANT_CONTINUE": "SD card is write protected!\nCan't continue.", + "SYSNAND_LVL_N": "SysNAND (lvl%lu)", + "EMUNAND_LVL_N": "EmuNAND (lvl%lu)", + "GAME_IMAGES": "game images", + "GAMECART_SAVES": "gamecart saves", + "IMAGES": "images", + "MEMORY_AREAS": "memory areas", + "SD_SYSTEM_DATA": "SD system data", + "SD_CARD": "SD card", + "RAM_DRIVE": "RAM drive", + "WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW": "Writing to %s is locked!\nUnlock it now?", + "UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED": "Unlock write permission for\n%s is not allowed.", + "ENABLE_BASE_WRITE": "You want to enable base\nwriting permissions.", + "ENABLE_SD_WRITE": "You want to enable SD card\nwriting permissions.", + "ENABLE_IMAGE_WRITE": "You want to enable image\nwriting permissions.", + "ENABLE_RAM_DRIVE_WRITE": "You want to enable RAM drive\nwriting permissions.", + "ENABLE_EMUNAND_0_WRITE": "You want to enable EmuNAND\nlvl0 writing permissions.", + "ENABLE_SYSNAND_0_WRITE": "You want to enable SysNAND\nlvl0 writing permissions.", + "ENABLE_EMUNAND_1_WRITE": "You want to enable EmuNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nrecoverable system data,\nuser data & savegames.", + "ENABLE_SYSNAND_1_WRITE": "You want to enable SysNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nsystem data, installations,\nuser data & savegames.", + "ENABLE_GAMECART_SAVE_WRITE": "You want to enable gamecart\nsave writing permissions.", + "ENABLE_SYSNAND_2_WRITE": "!Better be careful!\n \nYou want to enable SysNAND\nlvl2 writing permissions.\n \nThis enables you to modify\nirrecoverable system data!", + "ENABLE_MEMORY_WRITE": "!Better be careful!\n \nYou want to enable memory\nwriting permissions.\n \nWriting to certain areas may\nlead to unexpected results.", + "ENABLE_SD_DATA_WRITE": "!THIS IS NOT RECOMMENDED!\n \nYou want to enable SD data\nwriting permissions.\n \nEverything here is encrypted.\nIt is recommended to use the\nA:/B: drives for modification\nof installations, user data &\nsavegames instead.", + "ENABLE_SYSNAND_3_WRITE": "!THIS IS YOUR ONLY WARNING!\n \nYou want to enable SysNAND\nlvl3 writing permissions.\n \nThis enables you to OVERWRITE\nyour bootloader installation,\nessential system files and/or\nBRICK your console!", + "UNLOCK_WRITE_NOT_ALLOWED": "Unlock write permission is not allowed.", + "CANT_UNLOCK_WRITE_TRY_GODMODE9": "Can't unlock write permission.\nTry GodMode9 instead!", + "ERROR_SD_TOO_SMALL": "Error: SD card is too small", + "WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA": "!WARNING!\n \nProceeding will format this SD.\nThis will irreversibly delete\nALL data on it.", + "FORMAT_BONUS_DRIVE_DELETE_ALL_DATA": "Format the bonus drive?\nThis will irreversibly delete\nALL data on it.", + "FORMATTING_SD_PLEASE_WAIT": "Formatting SD, please wait...", + "FORMATTING_DRIVE_PLEASE_WAIT": "Formatting drive, please wait...", + "ERROR_SD_CARD_IO_FAILURE": "Error: SD card i/o failure", + "FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK": "File is currently mounted.\nUnmount to unlock?", + "ERROR_CANT_INJECT_FILE_INTO_ITSELF": "Error: Can't inject file into itself", + "OPERATION_WOULD_WRITE_BEYOND_EOF": "Operation would write beyond end of file", + "NOT_ENOUGH_DATA_IN_FILE": "Not enough data in file", + "CANCEL_IS_NOT_ALLOWED_HERE": "Cancel is not allowed here", + "B_DETECTED_CANCEL": "B button detected. Cancel?", + "ERROR_CANNOT_APPEND_FOLDER": "Error: Cannot append a folder", + "ERROR_OVERWRITING_FILE_WITH_DIR": "Error: Overwriting file with dir", + "ERROR_OVERWRITING_DIR_WITH_FILE": "Error: Overwriting dir with file", + "ERROR_CANNOT_OPEN_DESTINATION_FILE": "Error: Cannot open destination file", + "ERROR_NOT_ENOUGH_SPACE_AVAILABLE": "Error: Not enough space available", + "ERROR_ONLY_FAT_FILES_CAN_BE_MOVED": "Error: Only FAT files can be moved", + "ERROR_DESTINATION_IS_PART_OF_ORIGIN": "Error: Destination is part of origin", + "ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME": "Destination equals origin\nChoose another name?", + "CHOOSE_NEW_NAME": "Choose new name", + "OVERWRITE_FILES": "Overwrite file(s)", + "SKIP_FILES": "Skip file(s)", + "OVERWRITE_ALL": "Overwrite all", + "SKIP_ALL": "Skip all", + "DESTINATION_ALREADY_EXISTS": "Destination already exists:\n%s", + "CHOOSE_NEW_DESTINATION_NAME": "Choose new destination name", + "COPY_OPERATION_IS_NOT_ALLOWED": "Copy operation is not allowed", + "DESTINATION_EQUALS_ORIGIN": "Destination equals origin", + "ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD": "Entry not found: %s\nInject into %s instead?", + "FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE": "File smaller than available space:\n%s (%s)\n%s (%s)\nContinue?", + "NO_USABLE_ENTRIES_FOUND": "No usable entries found.", + "BEAT_NO_ERROR": "No error", + "BEAT_END_OF_ACTION_LIST": "End of action list", + "BEAT_ABORTED_BY_USER": "Aborted by user", + "BEAT_FAILED_TO_READ_WRITE_FILE": "Failed to read/write file", + "BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF": "Attempted to write beyond end of file", + "BEAT_INVALID_PATCH_FILE": "Invalid patch file", + "BEAT_INVALID_INPUT_FILE": "Invalid input file", + "BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH": "Output file checksum mismatch", + "BEAT_FILE_CHECKSUM_FAILED": "File checksum failed", + "BEAT_EXPECTED_MORE_PATCH_DATA": "Expected more patch data", + "BEAT_OUT_OF_MEMORY": "Out of memory", + "BEAT_UNKNOWN_ERROR": "Unknown error", + "FAILED_TO_INITIALIZE_BPM_FILE": "Failed to initialize BPM file:\n%s", + "FAILED_TO_INITIALIZE_BPS_FILE": "Failed to initialize BPS file:\n%s", + "PATCH_SUCCESSFULLY_APPLIED": "Patch successfully applied", + "PATCHING_ABORTED_BY_USER": "Patching aborted by user", + "FAILED_TO_RUN_PATCH": "Failed to run patch:\n%s", + "DECOMPRESSING_DOT_CODE": "Decompressing .code...", + "DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Decompressing .code...\nB button detected. Cancel?", + "COMPRESSING_DOT_CODE": "Compressing .code...", + "COMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Compressing .code...\nB button detected. Cancel?", + "PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE": "The patch is most likely not intended for this file.", + "YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT": "You most likely applied the patch on the output file.", + "PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED": "The patch is technically valid,\nbut seems scrambled or malformed.", + "PATCH_IS_INVALID": "The patch is invalid.", + "FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT": "One or both files are bigger than 16MB.\nThe IPS format doesn't support that.", + "REQUESTED_FILE_PATH_WAS_INVALID": "The requested file path was invalid.", + "PATCHING_CANCELED": "Patching canceled.", + "NOT_ENOUGH_MEMORY": "Not enough memory.", + "REGION_AMERICAS": "Americas", + "REGION_AUSTRALIA": "Australia", + "REGION_BRAZIL": "Brazil", + "REGION_CHINA": "China", + "REGION_EUROPE": "Europe", + "REGION_FRANCE": "France", + "REGION_GERMANY": "Germany", + "REGION_ITALY": "Italy", + "REGION_JAPAN": "Japan", + "REGION_KOREA": "Korea", + "REGION_SPAIN": "Spain", + "REGION_TAIWAN": "Taiwan", + "REGION_UNKNOWN": "Unknown", + "REGION_UNITED_KINGDOM": "United Kingdom", + "REGION_MIDDLE_EAST": "Middle East", + "GENERATING_QR_CODE": "Generating QR code...", + "REINITIALIZING_SD_CARD": "Reinitializing SD card...", + "DUMPING_STATE_TO_SD_CARD": "Dumping state to SD card...", + "PRESS_POWER_TO_TURN_OFF": "Press POWER to turn off", + "CLEANING_UP_TITLES_PLEASE_WAIT": "Cleaning up titles, please wait...", + "ERROR_NOT_NCCH_FILE": "Error: Not an NCCH file", + "ERROR_FILE_IS_TOO_SMALL": "Error: File is too small", + "ATTEMPT_FIX_THIS_TIME": "Attempt fix this time", + "ATTEMPT_FIX_ALWAYS": "Attempt fix always", + "ABORT_VERIFICATION": "Abort verification", + "ERROR_BAD_CRYPTO_FLAGS": "Error: Bad crypto flags", + "ERROR_BAD_EXEFS_HEADER": "Error: Bad ExeFS header", + "ERROR_MISSING_EXTHEADER": "Error: Missing ExtHeader", + "ERROR_CRYPTO_NOT_SET_UP": "Error: Crypto not set up", + "PATH_NCCH_VERIFICATION_FAILED_INFO": "%s\nNCCH verification failed:\nExtHdr/ExeFS/RomFS: %s/%s/%s", + "OK": "ok", + "FAIL": "fail", + "ERROR_NOT_NCSD_FILE": "Error: Not an NCSD file", + "PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nContent%lu (%08lX@%08lX):\nVerification failed", + "ERROR_PROBABLY_NOT_CIA_FILE": "Error: Probably not a CIA file", + "ERROR_TMD_PROBABLY_CORRUPTED": "Error: TMD probably corrupted", + "PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nID %08lX (%08llX@%08llX)\nVerification failed", + "ERROR_CDN_TITLEKEY_NOT_FOUND": "Error: CDN titlekey not found", + "DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE": "DLC content is missing\n \nIgnore all and continue?", + "PATH_SECTION_N_HASH_MISMATCH": "%s\nSection %lu hash mismatch", + "ARM9_ENTRYPOINT_IS_MISSING": "ARM9 entrypoint is missing", + "WARNING_ARM11_ENTRYPOINT_IS_MISSING": "Warning: ARM11 entrypoint is missing", + "ERROR_NOT_A_BOSS_FILE": "Error: Not a BOSS file", + "BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT": "BOSS payload hash mismatch.\n \nTry to fix it?", + "GENERIC_TICKET_PIRATE_LEGIT": "Generic ticket (\"pirate legit\")", + "PERSONALIZED_TICKET_LEGIT": "Personalized ticket (legit)", + "ID_N_LEGIT_TICKET_IS_PERSONALIZED_USING_THIS_NOT_RECOMMENDED_CHOOSE_DEFAULT_ACTION": "ID %016llX\nLegit ticket is personalized.\nUsing this is not recommended.\nChoose default action:", + "ID_N_TITLEKEY_NOT_FOUND": "ID %016llX\nTitlekey not found.", + "ID_N_TMD_IN_TAD_NOT_LEGIT": "ID %016llX\nTMD in TAD is not legit.", + "ID_N_TMD_NOT_LEGIT": "ID %016llX\nTMD is not legit.", + "ID_N_DOT_N_STATUS": "ID %016llX.%08lX\n%s", + "CONTENT_IS_CORRUPT": "Content is corrupt", + "INSERT_CONTENT_FAILED": "Insert content failed", + "INSTALL_CONTENT_FAILED": "Install content failed", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_DB_FILES_MAYBE_SD_MISSING_OR_UNINITIALIZED": "Install error:\nThis system is missing one or\nmore .db files.\n \nMaybe the SD card is missing\nor uninitialized?", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB": "Install error:\nThis system is missing the\nticket.db file.", + "SKIPPED_TITLE_0004008C000CBD00_NEEDS_SPECIAL_COMPILE_FLAGS": "Skipped title:\nTitle with id 0004008C000CBD00\nneeds special compiler flags.", + "ERROR_FAKE_SIGNED_TICKET_ONLY_VALID_SIGNED_TICKETS_CAN_BE_INSTALLED": "Error: Fake-signed ticket\n \nOnly valid signed tickets can\nbe installed to the system.", + "PATH_ERROR_UNKNOWN_CID_N_THIS_TICKET_DOES_NOT_BELONG_TO_THIS_3DS": "%s\nError: Unknown cid %08lX\n \nThis ticket does not belong to\nthis 3DS console.", + "INSTALLING_TICKET": "Installing ticket...", + "POSSIBLY_BROKEN": "Possibly Broken", + "PERSONAL_LEGIT": "Personal Legit", + "PERSONAL_LEGIT_DLC": "Personal Legit DLC", + "PERSONAL_PIRATE_LEGIT": "Personal Pirate Legit", + "PERSONAL_PIRATE_LEGIT_DLC": "Personal Pirate Legit DLC", + "PERSONAL_CUSTOM": "Personal Custom", + "PERSONAL_CUSTOM_DLC": "Personal Custom DLC", + "UNIVERSAL_LEGIT": "Universal Legit", + "UNIVERSAL_LEGIT_DLC": "Universal Legit DLC", + "UNIVERSAL_PIRATE_LEGIT": "Universal Pirate Legit", + "UNIVERSAL_PIRATE_LEGIT_DLC": "Universal Pirate Legit DLC", + "UNIVERSAL_CUSTOM": "Universal Custom", + "UNIVERSAL_CUSTOM_DLC": "Universal Custom DLC", + "CONTENTS_IN_CIA_FOUND_TOTAL": "Contents in CIA: %lu/%lu", + "CONTENTS_IN_CIA_TOTAL": "Contents in TMD: %lu", + "CONSOLE_ID_N": "Console ID: %08lX\n", + "SHOW_GAME_INFO_DETAILS": "%s\n%s %s Title\n \nTitle ID: %016llX\nTitle version: %lu.%lu.%lu\nContents size: %s\n%s\n%s \nTicket/TMD: %s/%s\nVerification: %s", + "STATE_LEGIT": "legit", + "STATE_ILLEGIT": "illegit", + "STATE_UNKNOWN": "unknown", + "STATE_INVALID": "invalid", + "STATE_PENDING_PROCEED_WITH_VERIFICATION": "pending\n \nProceed with verification?", + "STATE_PASSED": "passed", + "STATE_FAILED": "failed", + "OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS": "Output file already exists.\nUpdate this?", + "DSI_ENHANCED": "DSi Enhanced", + "DSI_EXCLUSIVE": "DSi Exclusive", + "FIXING_CMACS_PLEASE_WAIT": "Fixing CMACs, please wait...", + "NCSD_HEADER_IS_NOT_VALID": "NCSD header is not valid", + "NAND_DUMP_MISSING_DATA": "NAND dump missing data", + "ERROR_CTR_MBR_IS_CORRUPT": "Error: CTR MBR is corrupt", + "ERROR_TWL_MBR_IS_CORRUPT": "Error: TWL MBR is corrupt", + "PATH_ERROR_CTR_PARTITION_N_IS_CORRUPT": "%s\nError: CTR partition%lu is corrupt", + "PATH_ERROR_TWL_PARTITION_N_IS_CORRUPT": "%s\nError: TWL partition%lu is corrupt", + "NO_VALID_FIRM_FOUND": "No valid FIRM found", + "ERROR_NAND_DUMP_IS_CORRUPT_STILL_CONTINUE": "Error: NAND dump is corrupt.\nStill continue?", + "ERROR_SYSTEM_IS_LOCKED": "Error: System is locked.", + "ESSENTIAL_FILES_BACKUP_IS_REQUIRED_CREATE_ONE_NOW": "Essential files backup is required.\nCreate one now?", + "WARNING_PROCEEDING_WILL_OVERWRITE_SYSNAND_WITH_DUMP": "!WARNING!\n \nProceeding will overwrite the\nSysNAND with the provided dump.\n \n(B9S/A9LH will be left intact.)", + "IMAGE_NCSD_CORRUPT_OR_CUSTOMIZED_SAFE_RESTORE_NOT_POSSIBLE": "Image NCSD corrupt or customized,\nsafe restore is not possible!", + "WARNING_NCSD_DIFFERS_BETWEEN_IMAGE_AND_LOCAL_ELEVATED_WRITE_PERMISSIONS_REQUIRED": "!WARNING!\n \nNCSD differs between image and local,\nelevated write permissions required\n \nProceed on your own risk?", + "NOT_AN_INSTALLABLE_FIRM": "Not a installable FIRM.", + "FIRM_LOAD_VERIFY_ERROR": "FIRM load/verify error.", + "PATH_FIRM_N_NOT_FOUND_OR_TOO_SMALL": "%s\nFIRM%lu not found or too small.", + "SECTOR_0X96_CRYPTO_FAIL": "Sector 0x96 crypto fail.", + "SECTOR_0X96_CORRUPTED_PROVIDE_SECRET_SECTOR_BIN_TO_FIX": "Sector 0x96 is corrupted.\n \nProvide \"secret_sector.bin\"\nto fix sector 0x96.", + "SECTOR_0X96_CORRUPTED_FIX_DURING_INSTALLATION": "Sector 0x96 is corrupted.\n \nFix sector 0x96 during\nthe installation?", + "WARNING_PROCEEDING_WILL_INSTALL_FIRM_TO_SYSNAND_AND_INJECT_SIGHAX_UNSUPPORTED_FIRM_WILL_BRICK": "!WARNING!\n \nProceeding will install the\nprovided FIRM to the SysNAND\nand inject sighax.\n \nInstalling an unsupported FIRM\nwill BRICK your console!", + "INSTALLING_FIRM_PLEASE_WAIT": "Installing FIRM, please wait...", + "THIS_IS_BAD_FAILED_WRITING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed writing sector 0x96.\nTry to fix before reboot!", + "THIS_IS_BAD_FAILED_WRITING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed writing FIRM%lu.\nTry to fix before reboot!", + "CHECKING_INSTALLATION_PLEASE_WAIT": "Checking installation, please wait...", + "THIS_IS_BAD_FAILED_VERIFYING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed verifying sector 0x96.\nTry to fix before reboot!", + "THIS_IS_BAD_FAILED_VERIFYING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed verifying FIRM%lu.\nTry to fix before reboot!", + "PERFECT_KEYDB_IS_ALREADY_INSTALLED": "Perfect %s is already installed!", + "PATH_NOT_PERFECT_KEYDB_IMAGE_CANNOT_INSTALL_TO_NAND": "%s\nNot a perfect %s image.\nCannot install to NAND!", + "PATH_FAILED_WRITING_KEYDB_TO_NAND": "%s\nFailed writing %s to NAND!", + "USE_L_R_TO_SAVE": "(gebruik L+R om op te slaan)" +} diff --git a/resources/languages/pl.json b/resources/languages/pl.json new file mode 100644 index 000000000..8124c34fe --- /dev/null +++ b/resources/languages/pl.json @@ -0,0 +1,127 @@ +{ + "GM9_LANGUAGE": "Polski", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%4$02lX.%3$02lX.%1$s%2$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ",", + "THOUSAND_SEPARATOR": " ", + "FIRM_TOO_BIG": "FIRM za duży, nie można uruchomić", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nOstrzeżenie: Nie uruchamiaj FIRM-ów\nz niezaufanych źródeł.\n \nUruchomić FIRM?", + "NOT_BOOTABLE_FIRM": "Nie bootowalny FIRM.", + "FIRM_ENCRYPTED": "FIRM jest zaszyfrowany.\n \nOdszyfrować przed uruchomieniem?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Zrób kopię w %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Spróbuj uruchomić mimo to", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Ostrzeżenie: Próba rozruchu z\nnieobsługiwanej lokalizacji.", + "ROOT": "[root]", + "LOADING": "ŁADOWANIE...", + "PANE_N": "SEKTOR #%lu", + "CURRENT": "BIEŻĄCY", + "DIR": "(dir)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAMdrive FAT)", + "GAME_VIRTUAL": "(Game Virtual)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND Virtual)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND Virtual)", + "IMAGE_FAT": "(Image FAT)", + "XORPAD_VIRTUAL": "(XORpad Virtual)", + "MEMORY_VIRTUAL": "(Memory Virtual)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Gamecart Virtual)", + "VRAM_VIRTUAL": "(VRAM Virtual)", + "SEARCH": "(Szukaj)", + "TITLEMANAGER_VIRTUAL": "(TitleManager Virtual)", + "LAB_SDCARD": "SDCARD", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUAL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUAL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "GAMECART", + "LAB_GAME_IMAGE": "GAME IMAGE", + "LAB_AESKEYDB_IMAGE": "AESKEYDB IMAGE", + "LAB_BDRI_IMAGE": "BDRI IMAGE", + "LAB_DISA_DIFF_IMAGE": "DISA/DIFF IMAGE", + "LAB_MEMORY_VIRTUAL": "MEMORY VIRTUAL", + "LAB_VRAM_VIRTUAL": "VRAM VIRTUAL", + "LAB_TITLE_MANAGER": "ZARZĄDZANIE TYTUŁAMI", + "LAB_LAST_SEARCH": "OSTATNIE WYSZUKIWANIE", + "LAB_FAT_IMAGE": "FAT IMAGE", + "LAB_BONUS_DRIVE": "BONUS DRIVE", + "LAB_RAMDRIVE": "RAMDRIVE", + "LAB_NOLABEL": "NOLABEL", + "N_BYTE": "%s Byte", + "BYTE": " Byte", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[CLIPBOARD]", + "PLUS_N_MORE": "+ %lu więcej", + "MARK_DELETE_COPY": "L - OZNACZ pliki (używaj z ↑↓→←)\nX - USUŃ / [+R] ZMIEŃ NAZWĘ pliku(ów)\nY - KOPIUJ pliki / [+R] STWÓRZ wpis\n", + "MARK_DELETE_PASTE": "L - OZNACZ pliki (używaj z ↑↓→←)\nX - USUŃ / [+R] ZMIEŃ NAZWĘ pliku(ów)\nY - WKLEJ pliki / [+R] STWÓRZ wpis\n", + "RELOCK_WRITE_PERMISSION": "R+Y - Zablokuj uprawnienia do zapisu\n", + "UNMOUNT_IMAGE": "R+X - Odmontuj obraz\n", + "UNMOUNT_SD": "R+B - Odmontuj kartę SD\n", + "REMOUNT_SD": "R+B - Zamontuj kartę SD\n", + "DIRECTORY_OPTIONS": "R+A - Opcje katalogu\n", + "DRIVE_OPTIONS": "R+A - Opcje napędu\n", + "MAKE_SCREENSHOT": "R+L - Zrób zrzut ekranu\n", + "PREV_NEXT_PANE": "R+←→ - Przełączanie do poprzedniego/kolejnego sektora\n", + "CLEAR_CLIPBOARD": "SELECT - Wyczyść schowek\n", + "RESTORE_CLIPBOARD": "SELECT - Przywróć schowek\n", + "REBOOT_POWEROFF_HOME": "START - Reboot / [+R] Poweroff\nHOME button for HOME menu", + "NO_EMUNAND": "No EmuNAND", + "REDNAND_SIZE_MIN": "RedNAND size (min)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNAND size (full)", + "MULTINAND_SIZE_2X": "MultiNAND size (2x)", + "MULTINAND_SIZE_3X": "MultiNAND size (3x)", + "MULTINAND_SIZE_4X": "MultiNAND size (4x)", + "USER_INPUT": "User input...", + "AUTO": "Auto", + "16KB_CLUSTERS": "16KB Clusters", + "32KB_CLUSTERS": "32KB Clusters", + "64KB_CLUSTERS": "64KB Clusters", + "SD_NOT_DETECTED": "Error: SD card not detected.", + "FORMAT_SD_CHOOSE_EMUNAND": "Format SD card (%lluMB)?\nChoose EmuNAND size:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "SD card size is %lluMB.\nEnter EmuNAND size (MB) below:", + "FORMAT_SD_CHOOSE_CLUSTER": "Format SD card (%lluMB)?\nChoose cluster size:", + "FORMAT_SD_ENTER_LABEL": "Format SD card (%lluMB)?\nEnter label:", + "FORMAT_SD_FAILED": "Format SD: failed!", + "REDNAND_TYPE": "RedNAND type", + "REDNAND_TYPE_MULTI": "RedNAND type (multi)", + "REDNAND_TYPE_SINGLE": "RedNAND type (single)", + "GW_EMUNAND_TYPE": "GW EmuNAND type", + "DONT_SET_UP": "Don't set up", + "CHOOSE_EMUNAND_TYPE": "Choose EmuNAND type to set up:", + "CLONE_SYSNAND_TO_REDNAND": "Clone SysNAND to RedNAND?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "Klonowanie SysNAND do EmuNAND: nie powiodło się!", + "PRESS_A_TO_CONTINUE": "Naciśnij aby kontynuować", + "HEXEDITOR_CONTROLS": "Sterowanie Hexeditor:\n \n↑↓→←(+R) - Przewijanie\nR+Y - Przełączanie widoku\nX - Wyszukiwanie / przejdź do...\nA - Wejście w tryb edycji\nA+↑↓→← - Edycja wartości\nB - Wyjście\n", + "NOT_FOUND": "Nie znaleziono!", + "GO_TO_OFFSET": "Przejdź do offsetu", + "SEARCH_FOR_STRING": "Wyszukaj ciąg znaków", + "SEARCH_FOR_DATA": "Szukaj danych", + "CURRENT_OFFSET_SELECT_ACTION": "Bieżący offset: %08lX\nWybierz akcję:", + "CURRENT_OFFSET_ENTER_NEW": "Bieżący offset: %08lX\nWpisz poniżej nowe przesunięcie.", + "ENTER_SEARCH_REPEAT_SEARCH": "Wprowadź tekst wyszukiwania poniżej.\n(R+X, aby powtórzyć wyszukiwanie)", + "MADE_EDITS_SAVE_CHANGES": "Dokonałeś edycji w %lu miejscach.\nZapisać zmiany do pliku?", + "FAILED_WRITING_TO_FILE": "Nieudany zapis do pliku!", + "CALCULATING_SHA_FAILED": "Obliczanie SHA-%s: nie udało się!", + "SHA_VERIFICATION_PASSED": "\nWeryfikacja SHA: zaliczona!", + "SHA_VERIFICATION_FAILED": "\nWeryfikacja SHA: nieudana", + "IDENTICAL_WITH_PREVIOUS": "\n \nIdentycznie jak w poprzednim pliku:\n", + "WRITE_SHA_FILE": "\n \nZapisać plik .SHA?", + "WRITE_SHA1_FILE": "\n \nZapisać plik .SHA1?", + "CALCULATING_CMAC_FAILED": "Obliczanie CMAC: nie udało się!", + "CMAC_VERIFICATION_PASSED": "Weryfikacja CMAC: zaliczona!", + "CMAC_VERIFICATION_FAILED": "Weryfikacja CMAC: nie powiodła się!" +} diff --git a/resources/languages/ru.json b/resources/languages/ru.json new file mode 100644 index 000000000..9ebc91ed1 --- /dev/null +++ b/resources/languages/ru.json @@ -0,0 +1,158 @@ +{ + "GM9_LANGUAGE": "Русский", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%4$02lX.%3$02lX.%1$s%2$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ",", + "THOUSAND_SEPARATOR": " ", + "FIRM_TOO_BIG": "FIRM слишком большой, невозможно загрузить", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dкб)\nПредупреждение: Не загружайте FIRM\nиз ненадежных источников.\n \nЗагрузить FIRM?", + "NOT_BOOTABLE_FIRM": "Не запускаемый FIRM.", + "FIRM_ENCRYPTED": "FIRM зашифрован.\n \nРасшифровать перед запуском?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Сделать копию в %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Все равно попытаться запустить", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Предупреждение: Попытка запуска с неподдерживаемого расположения.", + "ROOT": "[root]", + "LOADING": "ЗАГРУЗКА...", + "PANE_N": "ВКЛАДКА #%lu", + "CURRENT": "ТЕКУЩИЙ", + "DIR": "(папка)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAMdrive FAT)", + "GAME_VIRTUAL": "(Виртуальная Game)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(Виртуальный SysNAND)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(Виртуальный EmuNAND)", + "IMAGE_FAT": "(Image FAT)", + "XORPAD_VIRTUAL": "(Виртуальный XORpad)", + "MEMORY_VIRTUAL": "(Виртуальная Память)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Виртуальный Картридж)", + "VRAM_VIRTUAL": "(Виртуальная VRAM)", + "SEARCH": "(Поиск)", + "TITLEMANAGER_VIRTUAL": "(Виртуальный TitleManager)", + "LAB_SDCARD": "КАРТА ПАМЯТИ SD", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "ВИРТУАЛЬНЫЙ SYSNAND", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "ВИРТУАЛЬНЫЙ EMUNAND", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "ВИРТУАЛЬНЫЙ IMGNAND", + "LAB_GAMECART": "КАРТРИДЖ", + "LAB_GAME_IMAGE": "ИГРОВОЙ ДИСК", + "LAB_AESKEYDB_IMAGE": "ДИСК AESKEYDB", + "LAB_BDRI_IMAGE": "ДИСК BDRI", + "LAB_DISA_DIFF_IMAGE": "ДИСК DISA/DIFF", + "LAB_MEMORY_VIRTUAL": "ВИРТУАЛЬНАЯ ПАМЯТЬ", + "LAB_VRAM_VIRTUAL": "ВИРТУАЛЬНАЯ VRAM", + "LAB_TITLE_MANAGER": "TITLE MANAGER", + "LAB_LAST_SEARCH": "LAST SEARCH", + "LAB_FAT_IMAGE": "FAT IMAGE", + "LAB_BONUS_DRIVE": "BONUS DRIVE", + "LAB_RAMDRIVE": "RAMDRIVE", + "LAB_NOLABEL": "NOLABEL", + "N_BYTE": "%s Byte", + "BYTE": " Byte", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[CLIPBOARD]", + "PLUS_N_MORE": "+ %lu more", + "MARK_DELETE_COPY": "L - MARK files (use with ↑↓→←)\nX - DELETE / [+R] RENAME file(s)\nY - COPY files / [+R] CREATE entry\n", + "MARK_DELETE_PASTE": "L - MARK files (use with ↑↓→←)\nX - DELETE / [+R] RENAME file(s)\nY - PASTE files / [+R] CREATE entry\n", + "RELOCK_WRITE_PERMISSION": "R+Y - Relock write permissions\n", + "UNMOUNT_IMAGE": "R+X - Unmount image\n", + "UNMOUNT_SD": "R+B - Unmount SD card\n", + "REMOUNT_SD": "R+B - Remount SD card\n", + "DIRECTORY_OPTIONS": "R+A - Directory options\n", + "DRIVE_OPTIONS": "R+A - Drive options\n", + "MAKE_SCREENSHOT": "R+L - Make a Screenshot\n", + "PREV_NEXT_PANE": "R+←→ - Switch to prev/next pane\n", + "CLEAR_CLIPBOARD": "SELECT - Clear Clipboard\n", + "RESTORE_CLIPBOARD": "SELECT - Restore Clipboard\n", + "REBOOT_POWEROFF_HOME": "START - Reboot / [+R] Poweroff\nHOME button for HOME menu", + "NO_EMUNAND": "No EmuNAND", + "REDNAND_SIZE_MIN": "RedNAND size (min)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNAND size (full)", + "MULTINAND_SIZE_2X": "MultiNAND size (2x)", + "MULTINAND_SIZE_3X": "MultiNAND size (3x)", + "MULTINAND_SIZE_4X": "MultiNAND size (4x)", + "USER_INPUT": "User input...", + "AUTO": "Auto", + "16KB_CLUSTERS": "16KB Clusters", + "32KB_CLUSTERS": "32KB Clusters", + "64KB_CLUSTERS": "64KB Clusters", + "SD_NOT_DETECTED": "Error: SD card not detected.", + "FORMAT_SD_CHOOSE_EMUNAND": "Format SD card (%lluMB)?\nChoose EmuNAND size:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "SD card size is %lluMB.\nEnter EmuNAND size (MB) below:", + "FORMAT_SD_CHOOSE_CLUSTER": "Format SD card (%lluMB)?\nChoose cluster size:", + "FORMAT_SD_ENTER_LABEL": "Format SD card (%lluMB)?\nEnter label:", + "FORMAT_SD_FAILED": "Format SD: failed!", + "REDNAND_TYPE": "RedNAND type", + "REDNAND_TYPE_MULTI": "RedNAND type (multi)", + "REDNAND_TYPE_SINGLE": "RedNAND type (single)", + "GW_EMUNAND_TYPE": "GW EmuNAND type", + "DONT_SET_UP": "Don't set up", + "CHOOSE_EMUNAND_TYPE": "Choose EmuNAND type to set up:", + "CLONE_SYSNAND_TO_REDNAND": "Clone SysNAND to RedNAND?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "Клонирование SysNAND в EmuNAND: не удалось!", + "PRESS_A_TO_CONTINUE": "Нажмите чтобы продолжить", + "HEXEDITOR_CONTROLS": "Управление Hexeditor:\n \n↑↓→←(+R) - Прокрутка\nR+Y - Переключение вида\nX - Поиск / переход к...\nA - Войти в режим редактирования\nA+↑↓→← - Редактировать значение\nB - Выйти\n", + "NOT_FOUND": "Не найдено!", + "GO_TO_OFFSET": "Перейти к offset", + "SEARCH_FOR_STRING": "Поиск строки", + "SEARCH_FOR_DATA": "Поиск данных", + "CURRENT_OFFSET_SELECT_ACTION": "Текущий offset: %08lX\nВыберите действие:", + "CURRENT_OFFSET_ENTER_NEW": "Текущий offset: %08lX\nВведите новый offset ниже.", + "ENTER_SEARCH_REPEAT_SEARCH": "Введите искомую строку ниже.\n(R+X чтобы повторить поиск)", + "MADE_EDITS_SAVE_CHANGES": "Вы внесли правки в %lu месте(ах).\nЗаписать изменения в файл?", + "FAILED_WRITING_TO_FILE": "Ошибка записи в файл!", + "CALCULATING_SHA_FAILED": "Вычисление SHA-%s: ошибка!", + "SHA_VERIFICATION_PASSED": "\nПроверка SHA: пройдена!", + "SHA_VERIFICATION_FAILED": "\nПроверка SHA: ошибка", + "IDENTICAL_WITH_PREVIOUS": "\n \nИдентично предыдущему файлу:\n", + "WRITE_SHA_FILE": "\n \nЗаписать .SHA файл?", + "WRITE_SHA1_FILE": "\n \nЗаписать .SHA1 файл?", + "CALCULATING_CMAC_FAILED": "Вычисление CMAC: ошибка!", + "CMAC_VERIFICATION_PASSED": "Проверка CMAC: пройдена!", + "CMAC_VERIFICATION_FAILED": "Проверка CMAC: ошибка!", + "FIX_CMAC_IN_FILE": "\n \nИсправить CMAC в файле?", + "FIXING_CMAC_FAILED": "Исправление CMAC: ошибка!", + "COPY_ALL_SELECTED_ITEMS": "Копировать все %lu выбранный(х) элемент(а/ов)?", + "FAILED_COPYING_ITEM": "Ошибка копирования элемента", + "ITEMS_COPIED_TO_OUT": "%lu элементов скопировано в %s", + "PATH_COPIED_TO_OUT": "%s\nСкопировано в %s", + "CART_INIT_FAILED": "Ошибка инициализации карты!", + "CART_DETECTED_SIZE_INPUT_BELOW": "Картридж: %s\nОбнаруженный размер: %s\n \nВведите размер дампа ниже.", + "NDS_CART_DECRYPT_SECURE_AREA": "Картридж: %s\nКартридж NDS обнаружен\nРасшифровать защищенную область?", + "FAILED_DUMPING_CART": "%s\nНе удалось сдампить картридж", + "PATH_DUMPED_TO_OUT": "%s\nСдамплено в %s", + "CREATED": "создано", + "MODIFIED": "изменен", + "ANALYZING_DRIVE": "Анализ диска, пожалуйста, подождите...", + "ANALYZING_DIR": "Анализ папки, пожалуйста, подождите...", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu файлов и %lu подпапок\n%s общий размер\n \nсвободно места: %s\nместа используется: %s\nместа всего: %s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu файлов и %lu подпапок\n%s общий размер", + "FILESIZE_X": "размер файла: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %sread-only [%c] %shidden\n[%c] %ssystem [%c] %sarchive\n[%c] %svirtual\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→← чтобы изменить атрибуты)\n", + "A_TO_CONTINUE": "( чтобы продолжить)", + "A_APPLY_B_CANCEL": "( чтобы применить, чтобы отменить)", + "A_YES_B_NO": "( да, нет)", + "A_SELECT_B_CANCEL": "( выбрать, отмена)", + "HOLD_B_TO_CANCEL": "(удерживайте B для отмены)", + "FAILED_TO_SET_ATTRIBUTES": "Не удалось установить атрибуты!", + "NAND_IMAGE_OPTIONS": "Параметры NAND образа...", + "CTRNAND_OPTIONS": "Параметры CTRNAND...", + "MOUNT_FAT_IMAGE": "Смонтировать как FAT образ", + "CIA_IMAGE_OPTIONS": "Параметры CIA образа...", + "NCSD_IMAGE_OPTIONS": "Параметры NCSD образа..." +} diff --git a/resources/languages/ry.json b/resources/languages/ry.json new file mode 100644 index 000000000..15201a78b --- /dev/null +++ b/resources/languages/ry.json @@ -0,0 +1,253 @@ +{ + "GM9_LANGUAGE": "琉球諸語(うちなーぐちー)", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%1$s%2$02lXとぅし%3$02lXちち%4$02lX日 %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ".", + "THOUSAND_SEPARATOR": ",", + "FIRM_TOO_BIG": "FIRMがまぎしじーくとぅ、起動なやびらん。", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\n注意: 信頼ならんソースから\nFIRM起動さんぐーとぅーくぃみそーれー。\n \nFIRM起動さびーが?", + "NOT_BOOTABLE_FIRM": "%s\n起動ないるFIRMっしぇーあいびらん。", + "FIRM_ENCRYPTED": "FIRMが暗号化さりとーいびーん。\n \n起動めーに復号化さびーが?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "%s/temp.firmんかいコピー作成さびーが?", + "TRY_BOOT_ANYWAYS": "ぬーんでぃ起動しんーじゅん", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "警告: サポートさりてぃうぅらん\nばすからブートさんでぃそーいびーん。", + "ROOT": "[root]", + "LOADING": "読み込み中…", + "PANE_N": "ペイン %lu", + "CURRENT": "現在", + "DIR": "(dir)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAMドライブFAT)", + "GAME_VIRTUAL": "(ゲームバーチャル)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND Virtual)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND Virtual)", + "IMAGE_FAT": "(Image FAT)", + "XORPAD_VIRTUAL": "(XORpad Virtual)", + "MEMORY_VIRTUAL": "(Memory Virtual)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Gamecart Virtual)", + "VRAM_VIRTUAL": "(VRAM Virtual)", + "SEARCH": "(検索)", + "TITLEMANAGER_VIRTUAL": "(TitleManager Virtual)", + "LAB_SDCARD": "SDカード", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUAL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUAL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "ゲームカード", + "LAB_GAME_IMAGE": "ゲームイメージ", + "LAB_AESKEYDB_IMAGE": "AESKEYDBイメージ", + "LAB_BDRI_IMAGE": "BDRIイメージ", + "LAB_DISA_DIFF_IMAGE": "DISA/DIFFイメージ", + "LAB_MEMORY_VIRTUAL": "メモリバーチャル", + "LAB_VRAM_VIRTUAL": "VRAMバーチャル", + "LAB_TITLE_MANAGER": "タイトルマネージャー", + "LAB_LAST_SEARCH": "前検索", + "LAB_FAT_IMAGE": "FATイメージ", + "LAB_BONUS_DRIVE": "ボーナスドライブ", + "LAB_RAMDRIVE": "RAMドライブ", + "LAB_NOLABEL": "ラベルなし", + "N_BYTE": "%sバイト", + "BYTE": " バイト", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[クリップボード]", + "PLUS_N_MORE": "+ んでぃ%lu個", + "MARK_DELETE_COPY": "L - ファイルマーク (↑↓→←使用)\nX - ファイル削除 / [+R] なめー変更\nY - ファイルコピー / [+R] エントリ作成", + "MARK_DELETE_PASTE": "L - ファイルマーク (↑↓→←んでぃ使用)\nX - ファイル削除 / [+R] なめー変更\nY - ファイル貼いちきーん / [+R] エントリ作成", + "RELOCK_WRITE_PERMISSION": "R+Y - 書き込みぬ許可再ロック", + "UNMOUNT_IMAGE": "R+X - Unmount image\n", + "UNMOUNT_SD": "R+B - Unmount SD card\n", + "REMOUNT_SD": "R+B - Remount SD card\n", + "DIRECTORY_OPTIONS": "R+A - Directory options\n", + "DRIVE_OPTIONS": "R+A - Drive options\n", + "MAKE_SCREENSHOT": "R+L - Make a Screenshot\n", + "PREV_NEXT_PANE": "R+←→ - Switch to prev/next pane\n", + "CLEAR_CLIPBOARD": "SELECT - Clear Clipboard\n", + "RESTORE_CLIPBOARD": "SELECT - Restore Clipboard\n", + "REBOOT_POWEROFF_HOME": "START - Reboot / [+R] Poweroff\nHOME button for HOME menu", + "NO_EMUNAND": "No EmuNAND", + "REDNAND_SIZE_MIN": "RedNAND size (min)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNAND size (full)", + "MULTINAND_SIZE_2X": "MultiNAND size (2x)", + "MULTINAND_SIZE_3X": "MultiNAND size (3x)", + "MULTINAND_SIZE_4X": "MultiNAND size (4x)", + "USER_INPUT": "User input...", + "AUTO": "Auto", + "16KB_CLUSTERS": "16KB Clusters", + "32KB_CLUSTERS": "32KB Clusters", + "64KB_CLUSTERS": "64KB Clusters", + "SD_NOT_DETECTED": "Error: SD card not detected.", + "FORMAT_SD_CHOOSE_EMUNAND": "Format SD card (%lluMB)?\nChoose EmuNAND size:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "SD card size is %lluMB.\nEnter EmuNAND size (MB) below:", + "FORMAT_SD_CHOOSE_CLUSTER": "Format SD card (%lluMB)?\nChoose cluster size:", + "FORMAT_SD_ENTER_LABEL": "Format SD card (%lluMB)?\nEnter label:", + "FORMAT_SD_FAILED": "Format SD: failed!", + "REDNAND_TYPE": "RedNAND type", + "REDNAND_TYPE_MULTI": "RedNAND type (multi)", + "REDNAND_TYPE_SINGLE": "RedNAND type (single)", + "GW_EMUNAND_TYPE": "GW EmuNAND type", + "DONT_SET_UP": "設定さん", + "CHOOSE_EMUNAND_TYPE": "設定しーんEmuNANDタイプ選択しみそーれー。", + "CLONE_SYSNAND_TO_REDNAND": "RedNANDんかいSysNANDコピーさびーが?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "EmuNANDんかいシステムNANDコピー:  しーやんじゃびたん!", + "PRESS_A_TO_CONTINUE": "うち続きーん", + "HEXEDITOR_CONTROLS": "16進エディタぬコントロール:\n \n↑↓→←(+R) - スクロール\nR+Y - 表示切り替いーん\nX - 検索・移動…\nA - 編集モードなすん\nA+↑↓→← - 値編集\nB - 終了\n", + "NOT_FOUND": "あいびらん!", + "GO_TO_OFFSET": "オフセットんかい移動", + "SEARCH_FOR_STRING": "文字列っし検索", + "SEARCH_FOR_DATA": "データっし検索", + "CURRENT_OFFSET_SELECT_ACTION": "現在ぬオフセット: %08lX\nアクション選択:", + "CURRENT_OFFSET_ENTER_NEW": "現在ぬオフセット: %08lX\n以下にみーさるオフセット入力しみそーれー。", + "ENTER_SEARCH_REPEAT_SEARCH": "以下に検索する文字列入力しみそーれー。\n(R+Xっし検索繰いけーさびーる)", + "MADE_EDITS_SAVE_CHANGES": "%lu個ぬばすぬ変更さりやびたん。\n変更ファイルんかい書ちくまびーが?", + "FAILED_WRITING_TO_FILE": "ファイルんかいぬ書き込みんかいしーやんじゃびたん!", + "CALCULATING_SHA_FAILED": "SHA-%sぬさんみん: しーやんじゃびたん!", + "SHA_VERIFICATION_PASSED": "\nSHA検証: でぃかさびたん!", + "SHA_VERIFICATION_FAILED": "\nSHA検証: しーやんじゃびたん", + "IDENTICAL_WITH_PREVIOUS": "\n \n前ファイルとぅいぬやいびーん:\n", + "WRITE_SHA_FILE": "\n \n.SHAファイル作成さびーが?", + "WRITE_SHA1_FILE": "\n \n.SHA1ファイル作成さびーが?", + "CALCULATING_CMAC_FAILED": "CMACぬさんみん: しーやんじゃびたん!", + "CMAC_VERIFICATION_PASSED": "CMAC検証: でぃかさびたん!", + "CMAC_VERIFICATION_FAILED": "CMAC検証: しーやんじゃびたん!", + "FIX_CMAC_IN_FILE": "\n \nファイルんかいCMAC修正さびーが?", + "FIXING_CMAC_FAILED": "CMACぬ修正: しーやんじゃびたん!", + "COPY_ALL_SELECTED_ITEMS": "%lu個ぬ選択さったる項目まじりコピーさびーが?", + "FAILED_COPYING_ITEM": "項目ぬコピーんかいしーやんじゃびたん", + "ITEMS_COPIED_TO_OUT": "%lu個ぬ項目ー%sんかいコピーさびたん", + "PATH_COPIED_TO_OUT": "%s\n%sんかいコピーさびたん", + "CART_INIT_FAILED": "カードぬ初期化んかいしーやんじゃびたん!", + "CART_DETECTED_SIZE_INPUT_BELOW": "カード: %s\n検出さったるサイズ: %s\n \n以下にダンプサイズ入力しみそーれー。", + "NDS_CART_DECRYPT_SECURE_AREA": "カード: %s\nNDSカードぬ検出さりやびたん\nセキュアエリア復号化さびーが?", + "FAILED_DUMPING_CART": "%s\nカードぬダンプんかいしーやんじゃびたん", + "PATH_DUMPED_TO_OUT": "%s\n%sんかいダンプさびたん", + "CREATED": "作成日", + "MODIFIED": "更新日", + "ANALYZING_DRIVE": "ドライブ分析そーいびーん、いちゅた待っちくぃみそーれー。", + "ANALYZING_DIR": "フォルダ分析そーいびーん。いちゅた待っちくぃみそーれー。", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%luファイルとぅ%luフォルダ\n%s合計サイズ\n \n空き容量:%s\n使用容量:%s\n合計容量:%s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%luファイルとぅ%luフォルダ\n%s合計サイズ", + "FILESIZE_X": "ファイルサイズ: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %s読み取り専用 [%c] %s隠し\n[%c] %sシステム [%c] %sアーカイブ\n[%c] %sバーチャル\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→←っし属性変更すん)\n", + "A_TO_CONTINUE": "(っし続きーん)", + "A_APPLY_B_CANCEL": "(っし適用、っしキャンセル)", + "A_YES_B_NO": "(はい、うぅーうぅー)", + "A_SELECT_B_CANCEL": "(選択、キャンセル)", + "HOLD_B_TO_CANCEL": "(B長押しーしキャンセル)", + "FAILED_TO_SET_ATTRIBUTES": "属性ぬ設定んかいしーやんじゃびたん!", + "NAND_IMAGE_OPTIONS": "NAND image options...", + "CTRNAND_OPTIONS": "CTRNAND options...", + "MOUNT_FAT_IMAGE": "Mount as FAT image", + "CIA_IMAGE_OPTIONS": "CIA image options...", + "NCSD_IMAGE_OPTIONS": "NCSD image options...", + "NCCH_IMAGE_OPTIONS": "NCCH image options...", + "MOUNT_AS_EXEFS_IMAGE": "Mount as EXEFS image", + "MOUNT_AS_ROMFS_IMAGE": "Mount as ROMFS image", + "TMD_FILE_OPTIONS": "TMD file options...", + "TMD_CDN_OPTIONS": "TMD/CDN options...", + "TMD_TWL_OPTIONS": "TMD/TWL options...", + "MANAGE_TITLE": "Manage Title...", + "BOSS_FILE_OPTIONS": "BOSS file options...", + "DECRYPT_NUS_CDN_FILE": "Decrypt NUS/CDN file", + "SHOW_SMDH_TITLE_INFO": "Show SMDH title info", + "NDS_IMAGE_OPTIONS": "NDS image options...", + "GBA_IMAGE_OPTIONS": "GBA image options...", + "TICKET_OPTIONS": "Ticket options...", + "TAD_IMAGE_OPTIONS": "TAD image options...", + "SHOW_3DSX_TITLE_INFO": "Show 3DSX title info", + "FIRM_IMAGE_OPTIONS": "FIRM image options...", + "AGBSAVE_OPTIONS": "AGBSAVE options...", + "DUMP_GBA_VC_SAVE": "Dump GBA VC save", + "TICKET_DB_OPTIONS": "Ticket.db options...", + "MOUNT_AS_DIFF_IMAGE": "Mount as DIFF image", + "MOUNT_AS_DISA_IAMGE": "Mount as DISA image", + "INSTALL_CIFINISH_BIN": "Install cifinish.bin", + "TITLEKEY_OPTIONS": "Titlekey options...", + "AESKEYDB_OPTIONS": "AESkeydb options...", + "BUILD_X": "Build %s", + "NCCHINFO_OPTIONS": "NCCHinfo options...", + "EXECUTE_GM9_SCRIPT": "Execute GM9 script", + "FONT_OPTIONS": "Font options...", + "LANGUAGE_OPTIONS": "Language options...", + "VIEW_PNG_FILE": "View PNG file", + "REBUILD_NCSD_HEADER": "Rebuild NCSD header", + "SHOW_IN_HEXEDITOR": "Show in Hexeditor", + "CALCULATE_SHA256": "Calculate SHA-256", + "CALCULATE_SHA1": "Calculate SHA-1", + "SHOW_FILE_INFO": "Show file info", + "SHOW_IN_TEXTVIEWER": "Show in Textviewer", + "CALCULATE_CMAC": "Calculate CMAC", + "COPY_TO_OUT": "Copy to %s", + "DUMP_TO_OUT": "Dump to %s", + "INJECT_DATA_AT_OFFSET": "Inject data @offset", + "OPEN_THIS_FOLDER": "Open this folder", + "OPEN_CONTAINING_FOLDER": "Open containing folder", + "OPEN_TITLE_FOLDER": "Open title folder", + "PATH_N_FILES_SELECTED": "%s\n(%lu files selected)", + "CHECK_CURRENT_CMAC_ONLY": "Check current CMAC only", + "VERIFY_CMAC_FOR_ALL": "まじりぬCMAC確認すん", + "FIX_CMAC_FOR_ALL": "まじりぬCMAC修正すん", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%luファイルぬOK/修正/合計\n%lu/%luぬCMAC無し", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%luファイル検証済み\n%lu/%luファイル修正済み", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%luファイル検証済み\n%lu/%luファイルCMAC無し", + "N_OF_N_FILES_VERIFIED": "%lu/%luファイル検証済み", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "%sからデータ挿入さびーが?\n以下にオフセット入力しみそーれー。", + "FAILED_INJECTING_PATH": "%sぬ挿入んかいしーやんじゃびたん", + "MOUNT_CXI_NDS_TO_DRIVE": "CXI/NDSドライブんかいマウント", + "MOUNT_IMAGE_TO_DRIVE": "イメージドライブんかいマウント", + "RESTORE_SYSNAND_SAFE": "システムNAND復元 (安全)", + "UPDATE_EMBEDDED_BACKUP": "埋み込みバックアップ更新", + "SHOW_TITLE_INFO": "タイトル情報表示", + "DECRYPT_FILE": "ファイル復号化 (...)", + "DECRYPT_FILE_OUT": "ファイル復号化 (%sんかい)", + "ENCRYPT_FILE": "ファイル暗号化 (...)", + "ENCRYPT_FILE_OUT": "ファイル暗号化 (%sんかい)", + "BUILD_CIA_FROM_FILE": "ファイルからCIA作成", + "BUILD_CIA_STANDARD": "CIA作成 (標準)", + "BUILD_CIA_LEGIT": "CIA作成 (合法)", + "DUMP_CXI_NDS_FILE": "CXI/NDSファイルダンプ", + "INSTALL_GAME_IMAGE": "ゲームイメージをインストール", + "INSTALL_TICKET": "チケットインストール", + "DUMP_TICKET_FILE": "チケットファイルダンプ", + "UNINSTALL_TITLE": "タイトルアンインストール", + "VERIFY_FILE": "ファイル検証", + "TRANSFER_IMAGE_TO_CTRNAND": "CTRNANDんかいイメージ転送", + "INJECT_TO_H_AND_S": "がんじゅーんでぃ安全に挿入", + "TRIM_FILE": "ファイルトリミング", + "RENAME_FILE": "ファイルぬなめー変更", + "BUILD_XORPADS_SD": "XORパッド作成 (SDんかい出力)", + "BUILD_XORPADS_INPLACE": "XORパッド作成 (コピーさん)", + "EXTRACT_X": "%s解凍", + "INIT_X": "%s設定", + "INSTALL_X": "%sインストール", + "INSTALL_FIRM": "FIRMインストール", + "BOOT_FIRM": "FIRM起動", + "SET_AS_ACTIVE_FONT": "使用するフォントんかい設定", + "SET_AS_ACTIVE_LANGUAGE": "使用する言語んかい設定", + "DUMP_BA_VC_SAVE": "GBC VCセーブダンプ", + "INJECT_GBA_VC_SAVE": "GBA VCセーブ挿入", + "SET_AS_DEFAULT": "デフォルトとぅしてぃ設定", + "MOUNTING_IMAGE_FAILED": "イメージマウント: しーやんじゃびたん", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nドライブ%sとぅしてぃマウントさびたん\nなまちゃーきドライブんかい移動さびーが?", + "DECRYPT_TO_OUT": "%sんかい復号", + "DECRYPT_INPLACE": "コピーさんぐーとぅー復号", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "%lu個ぬ選択さるまじりぬファイル復号さびーが?", + "TRYING_TO_DECRYPT_N_FILES": "%lu個ぬファイル復号そーいびーん…", + "DECRYPTION_FAILED_CONTINUE": "復号化んかいしーやんじゃびたん\n \n続きやびーが?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%luファイル復号済み\n%lu/%luファイル暗号さりらん\n%lu/%luいぬ種類やあらん" +} diff --git a/resources/languages/source.json b/resources/languages/source.json new file mode 100644 index 000000000..1c6a1fd7b --- /dev/null +++ b/resources/languages/source.json @@ -0,0 +1,809 @@ +{ + "GM9_LANGUAGE": "[LANGUAGE NAME]", + "GM9_TRANS_VER": 1, + "DATE_TIME_FORMAT": "%1$s%2$02lX-%3$02lX-%4$02lX %5$02lX:%6$02lX", + "DECIMAL_SEPARATOR": ".", + "THOUSAND_SEPARATOR": ",", + "FIRM_TOO_BIG": "FIRM too big, can't boot", + "PATH_DO_NOT_BOOT_UNTRUSTED": "%s (%dkB)\nWarning: Do not boot FIRMs\nfrom untrusted sources.\n \nBoot FIRM?", + "NOT_BOOTABLE_FIRM": "Not a bootable FIRM.", + "FIRM_ENCRYPTED": "FIRM is encrypted.\n \nDecrypt before boot?", + "MAKE_COPY_AT_OUT_TEMP_FIRM": "Make a copy at %s/temp.firm", + "TRY_BOOT_ANYWAYS": "Try to boot anyways", + "WARNING_BOOT_UNSUPPORTED_LOCATION": "Warning: Trying to boot from an\nunsupported location.", + "ROOT": "[root]", + "LOADING": "LOADING...", + "PANE_N": "PANE #%lu", + "CURRENT": "CURRENT", + "DIR": "(dir)", + "SD_FAT": "(SD FAT)", + "RAMDRIVE_FAT": "(RAMdrive FAT)", + "GAME_VIRTUAL": "(Game Virtual)", + "SYSNAND_FAT": "(SysNAND FAT)", + "SYSNAND_VIRTUAL": "(SysNAND Virtual)", + "EMUNAND_FAT": "(EmuNAND FAT)", + "EMUNAND_VIRTUAL": "(EmuNAND Virtual)", + "IMAGE_FAT": "(Image FAT)", + "XORPAD_VIRTUAL": "(XORpad Virtual)", + "MEMORY_VIRTUAL": "(Memory Virtual)", + "ALIAS_FAT": "(Alias FAT)", + "GAMECART_VIRTUAL": "(Gamecart Virtual)", + "VRAM_VIRTUAL": "(VRAM Virtual)", + "SEARCH": "(Search)", + "TITLEMANAGER_VIRTUAL": "(TitleManager Virtual)", + "LAB_SDCARD": "SDCARD", + "LAB_SYSNAND_CTRNAND": "SYSNAND CTRNAND", + "LAB_SYSNAND_TWLN": "SYSNAND TWLN", + "LAB_SYSNAND_TWLP": "SYSNAND TWLP", + "LAB_SYSNAND_SD": "SYSNAND SD", + "LAB_SYSNAND_VIRTUAL": "SYSNAND VIRTUAL", + "LAB_EMUNAND_CTRNAND": "EMUNAND CTRNAND", + "LAB_EMUNAND_TWLN": "EMUNAND TWLN", + "LAB_EMUNAND_TWLP": "EMUNAND TWLP", + "LAB_EMUNAND_SD": "EMUNAND SD", + "LAB_EMUNAND_VIRTUAL": "EMUNAND VIRTUAL", + "LAB_IMGNAND_CTRNAND": "IMGNAND CTRNAND", + "LAB_IMGNAND_TWLN": "IMGNAND TWLN", + "LAB_IMGNAND_TWLP": "IMGNAND TWLP", + "LAB_IMGNAND_VIRTUAL": "IMGNAND VIRTUAL", + "LAB_GAMECART": "GAMECART", + "LAB_GAME_IMAGE": "GAME IMAGE", + "LAB_AESKEYDB_IMAGE": "AESKEYDB IMAGE", + "LAB_BDRI_IMAGE": "BDRI IMAGE", + "LAB_DISA_DIFF_IMAGE": "DISA/DIFF IMAGE", + "LAB_MEMORY_VIRTUAL": "MEMORY VIRTUAL", + "LAB_VRAM_VIRTUAL": "VRAM VIRTUAL", + "LAB_TITLE_MANAGER": "TITLE MANAGER", + "LAB_LAST_SEARCH": "LAST SEARCH", + "LAB_FAT_IMAGE": "FAT IMAGE", + "LAB_BONUS_DRIVE": "BONUS DRIVE", + "LAB_RAMDRIVE": "RAMDRIVE", + "LAB_NOLABEL": "NOLABEL", + "N_BYTE": "%s Byte", + "BYTE": " Byte", + "KB": " kB", + "MB": " MB", + "GB": " GB", + "CLIPBOARD": "[CLIPBOARD]", + "PLUS_N_MORE": "+ %lu more", + "MARK_DELETE_COPY": "L - MARK files (use with ↑↓→←)\nX - DELETE / [+R] RENAME file(s)\nY - COPY files / [+R] CREATE entry\n", + "MARK_DELETE_PASTE": "L - MARK files (use with ↑↓→←)\nX - DELETE / [+R] RENAME file(s)\nY - PASTE files / [+R] CREATE entry\n", + "RELOCK_WRITE_PERMISSION": "R+Y - Relock write permissions\n", + "UNMOUNT_IMAGE": "R+X - Unmount image\n", + "UNMOUNT_SD": "R+B - Unmount SD card\n", + "REMOUNT_SD": "R+B - Remount SD card\n", + "DIRECTORY_OPTIONS": "R+A - Directory options\n", + "DRIVE_OPTIONS": "R+A - Drive options\n", + "MAKE_SCREENSHOT": "R+L - Make a Screenshot\n", + "PREV_NEXT_PANE": "R+←→ - Switch to prev/next pane\n", + "CLEAR_CLIPBOARD": "SELECT - Clear Clipboard\n", + "RESTORE_CLIPBOARD": "SELECT - Restore Clipboard\n", + "REBOOT_POWEROFF_HOME": "START - Reboot / [+R] Poweroff\nHOME button for HOME menu", + "NO_EMUNAND": "No EmuNAND", + "REDNAND_SIZE_MIN": "RedNAND size (min)", + "GW_EMUNAND_SIZE_FULL": "GW EmuNAND size (full)", + "MULTINAND_SIZE_2X": "MultiNAND size (2x)", + "MULTINAND_SIZE_3X": "MultiNAND size (3x)", + "MULTINAND_SIZE_4X": "MultiNAND size (4x)", + "USER_INPUT": "User input...", + "AUTO": "Auto", + "16KB_CLUSTERS": "16KB Clusters", + "32KB_CLUSTERS": "32KB Clusters", + "64KB_CLUSTERS": "64KB Clusters", + "SD_NOT_DETECTED": "Error: SD card not detected.", + "FORMAT_SD_CHOOSE_EMUNAND": "Format SD card (%lluMB)?\nChoose EmuNAND size:", + "SD_SIZE_IS_ENTER_EMUNAND_SIZE": "SD card size is %lluMB.\nEnter EmuNAND size (MB) below:", + "FORMAT_SD_CHOOSE_CLUSTER": "Format SD card (%lluMB)?\nChoose cluster size:", + "FORMAT_SD_ENTER_LABEL": "Format SD card (%lluMB)?\nEnter label:", + "FORMAT_SD_FAILED": "Format SD: failed!", + "REDNAND_TYPE": "RedNAND type", + "REDNAND_TYPE_MULTI": "RedNAND type (multi)", + "REDNAND_TYPE_SINGLE": "RedNAND type (single)", + "GW_EMUNAND_TYPE": "GW EmuNAND type", + "DONT_SET_UP": "Don't set up", + "CHOOSE_EMUNAND_TYPE": "Choose EmuNAND type to set up:", + "CLONE_SYSNAND_TO_REDNAND": "Clone SysNAND to RedNAND?", + "CLONING_SYSNAND_TO_EMUNAND_FAILED": "Cloning SysNAND to EmuNAND: failed!", + "PRESS_A_TO_CONTINUE": "Press to continue", + "HEXEDITOR_CONTROLS": "Hexeditor Controls:\n \n↑↓→←(+R) - Scroll\nR+Y - Switch view\nX - Search / goto...\nA - Enter edit mode\nA+↑↓→← - Edit value\nB - Exit\n", + "NOT_FOUND": "Not found!", + "GO_TO_OFFSET": "Go to offset", + "SEARCH_FOR_STRING": "Search for string", + "SEARCH_FOR_DATA": "Search for data", + "CURRENT_OFFSET_SELECT_ACTION": "Current offset: %08lX\nSelect action:", + "CURRENT_OFFSET_ENTER_NEW": "Current offset: %08lX\nEnter new offset below.", + "ENTER_SEARCH_REPEAT_SEARCH": "Enter search string below.\n(R+X to repeat search)", + "MADE_EDITS_SAVE_CHANGES": "You made edits in %lu place(s).\nWrite changes to file?", + "FAILED_WRITING_TO_FILE": "Failed writing to file!", + "CALCULATING_SHA_FAILED": "Calculating SHA-%s: failed!", + "SHA_VERIFICATION_PASSED": "\nSHA verification: passed!", + "SHA_VERIFICATION_FAILED": "\nSHA verification: failed", + "IDENTICAL_WITH_PREVIOUS": "\n \nIdentical with previous file:\n", + "WRITE_SHA_FILE": "\n \nWrite .SHA file?", + "WRITE_SHA1_FILE": "\n \nWrite .SHA1 file?", + "CALCULATING_CMAC_FAILED": "Calculating CMAC: failed!", + "CMAC_VERIFICATION_PASSED": "CMAC verification: passed!", + "CMAC_VERIFICATION_FAILED": "CMAC verification: failed!", + "FIX_CMAC_IN_FILE": "\n \nFix CMAC in file?", + "FIXING_CMAC_FAILED": "Fixing CMAC: failed!", + "COPY_ALL_SELECTED_ITEMS": "Copy all %lu selected items?", + "FAILED_COPYING_ITEM": "Failed copying item", + "ITEMS_COPIED_TO_OUT": "%lu items copied to %s", + "PATH_COPIED_TO_OUT": "%s\nCopied to %s", + "CART_INIT_FAILED": "Cart init failed!", + "CART_DETECTED_SIZE_INPUT_BELOW": "Cart: %s\nDetected size: %s\n \nInput dump size below.", + "NDS_CART_DECRYPT_SECURE_AREA": "Cart: %s\nNDS cart detected\nDecrypt the secure area?", + "FAILED_DUMPING_CART": "%s\nFailed dumping cart", + "PATH_DUMPED_TO_OUT": "%s\nDumped to %s", + "CREATED": "created", + "MODIFIED": "modified", + "ANALYZING_DRIVE": "Analyzing drive, please wait...", + "ANALYZING_DIR": "Analyzing dir, please wait...", + "N_FILES_N_SUBDIRS_TOTAL_SIZE_FREE_USED_TOTAL": "%lu files & %lu subdirs\n%s total size\n \nspace free: %s\nspace used: %s\nspace total: %s", + "N_FILES_N_SUBDIRS_TOTAL_SIZE": "%lu files & %lu subdirs\n%s total size", + "FILESIZE_X": "filesize: %s", + "READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL": " \n[%c] %sread-only [%c] %shidden\n[%c] %ssystem [%c] %sarchive\n[%c] %svirtual\n%s", + "UDRL_CHANGE_ATTRIBUTES": " \n(↑↓→← to change attributes)\n", + "A_TO_CONTINUE": "( to continue)", + "A_APPLY_B_CANCEL": "( to apply, to cancel)", + "A_YES_B_NO": "( yes, no)", + "A_SELECT_B_CANCEL": "( select, cancel)", + "HOLD_B_TO_CANCEL": "(hold B to cancel)", + "FAILED_TO_SET_ATTRIBUTES": "Failed to set attributes!", + "NAND_IMAGE_OPTIONS": "NAND image options...", + "CTRNAND_OPTIONS": "CTRNAND options...", + "MOUNT_FAT_IMAGE": "Mount as FAT image", + "CIA_IMAGE_OPTIONS": "CIA image options...", + "NCSD_IMAGE_OPTIONS": "NCSD image options...", + "NCCH_IMAGE_OPTIONS": "NCCH image options...", + "MOUNT_AS_EXEFS_IMAGE": "Mount as EXEFS image", + "MOUNT_AS_ROMFS_IMAGE": "Mount as ROMFS image", + "TMD_FILE_OPTIONS": "TMD file options...", + "TMD_CDN_OPTIONS": "TMD/CDN options...", + "TMD_TWL_OPTIONS": "TMD/TWL options...", + "MANAGE_TITLE": "Manage Title...", + "BOSS_FILE_OPTIONS": "BOSS file options...", + "DECRYPT_NUS_CDN_FILE": "Decrypt NUS/CDN file", + "SHOW_SMDH_TITLE_INFO": "Show SMDH title info", + "NDS_IMAGE_OPTIONS": "NDS image options...", + "GBA_IMAGE_OPTIONS": "GBA image options...", + "TICKET_OPTIONS": "Ticket options...", + "TAD_IMAGE_OPTIONS": "TAD image options...", + "SHOW_3DSX_TITLE_INFO": "Show 3DSX title info", + "FIRM_IMAGE_OPTIONS": "FIRM image options...", + "AGBSAVE_OPTIONS": "AGBSAVE options...", + "DUMP_GBA_VC_SAVE": "Dump GBA VC save", + "TICKET_DB_OPTIONS": "Ticket.db options...", + "MOUNT_AS_DIFF_IMAGE": "Mount as DIFF image", + "MOUNT_AS_DISA_IAMGE": "Mount as DISA image", + "INSTALL_CIFINISH_BIN": "Install cifinish.bin", + "TITLEKEY_OPTIONS": "Titlekey options...", + "AESKEYDB_OPTIONS": "AESkeydb options...", + "BUILD_X": "Build %s", + "NCCHINFO_OPTIONS": "NCCHinfo options...", + "EXECUTE_GM9_SCRIPT": "Execute GM9 script", + "FONT_OPTIONS": "Font options...", + "LANGUAGE_OPTIONS": "Language options...", + "VIEW_PNG_FILE": "View PNG file", + "REBUILD_NCSD_HEADER": "Rebuild NCSD header", + "SHOW_IN_HEXEDITOR": "Show in Hexeditor", + "CALCULATE_SHA256": "Calculate SHA-256", + "CALCULATE_SHA1": "Calculate SHA-1", + "SHOW_FILE_INFO": "Show file info", + "SHOW_IN_TEXTVIEWER": "Show in Textviewer", + "CALCULATE_CMAC": "Calculate CMAC", + "COPY_TO_OUT": "Copy to %s", + "DUMP_TO_OUT": "Dump to %s", + "INJECT_DATA_AT_OFFSET": "Inject data @offset", + "OPEN_THIS_FOLDER": "Open this folder", + "OPEN_CONTAINING_FOLDER": "Open containing folder", + "OPEN_TITLE_FOLDER": "Open title folder", + "PATH_N_FILES_SELECTED": "%s\n(%lu files selected)", + "CHECK_CURRENT_CMAC_ONLY": "Check current CMAC only", + "VERIFY_CMAC_FOR_ALL": "Verify CMAC for all", + "FIX_CMAC_FOR_ALL": "Fix CMAC for all", + "N_N_N_FILES_OK_FIXED_TOTAL_N_OF_N_HAVE_NO_CMAC": "%lu/%lu/%lu files ok/fixed/total\n%lu/%lu have no CMAC", + "N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED": "%lu/%lu files verified ok\n%lu/%lu files fixed", + "N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC": "%lu/%lu files verified ok\n%lu/%lu have no CMAC", + "N_OF_N_FILES_VERIFIED": "%lu/%lu files verified ok", + "INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW": "Inject data from %s?\nSpecify offset below.", + "FAILED_INJECTING_PATH": "Failed injecting %s", + "MOUNT_CXI_NDS_TO_DRIVE": "Mount CXI/NDS to drive", + "MOUNT_IMAGE_TO_DRIVE": "Mount image to drive", + "RESTORE_SYSNAND_SAFE": "Restore SysNAND (safe)", + "UPDATE_EMBEDDED_BACKUP": "Update embedded backup", + "SHOW_TITLE_INFO": "Show title info", + "DECRYPT_FILE": "Decrypt file (...)", + "DECRYPT_FILE_OUT": "Decrypt file (%s)", + "ENCRYPT_FILE": "Encrypt file (...)", + "ENCRYPT_FILE_OUT": "Encrypt file (%s)", + "BUILD_CIA_FROM_FILE": "Build CIA from file", + "BUILD_CIA_STANDARD": "Build CIA (standard)", + "BUILD_CIA_LEGIT": "Build CIA (legit)", + "DUMP_CXI_NDS_FILE": "Dump CXI/NDS file", + "INSTALL_GAME_IMAGE": "Install game image", + "INSTALL_TICKET": "Install ticket", + "DUMP_TICKET_FILE": "Dump ticket file", + "UNINSTALL_TITLE": "Uninstall title", + "VERIFY_FILE": "Verify file", + "TRANSFER_IMAGE_TO_CTRNAND": "Transfer image to CTRNAND", + "INJECT_TO_H_AND_S": "Inject to H&S", + "TRIM_FILE": "Trim file", + "RENAME_FILE": "Rename file", + "BUILD_XORPADS_SD": "Build XORpads (SD output)", + "BUILD_XORPADS_INPLACE": "Build XORpads (inplace)", + "EXTRACT_X": "Extract %s", + "INIT_X": "Init %s", + "INSTALL_X": "Install %s", + "INSTALL_FIRM": "Install FIRM", + "BOOT_FIRM": "Boot FIRM", + "SET_AS_ACTIVE_FONT": "Set as active font", + "SET_AS_ACTIVE_LANGUAGE": "Set as active language", + "DUMP_BA_VC_SAVE": "Dump GBA VC save", + "INJECT_GBA_VC_SAVE": "Inject GBA VC save", + "SET_AS_DEFAULT": "Set as default", + "MOUNTING_IMAGE_FAILED": "Mounting image: failed", + "PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW": "%s\nMounted as drive %s\nEnter path now?", + "DECRYPT_TO_OUT": "Decrypt to %s", + "DECRYPT_INPLACE": "Decrypt inplace", + "TRY_TO_DECRYPT_ALL_N_SELECTED_FILES": "Try to decrypt all %lu selected files?", + "TRYING_TO_DECRYPT_N_FILES": "Trying to decrypt %lu files...", + "DECRYPTION_FAILED_CONTINUE": "Decryption failed\n \nContinue?", + "N_OF_N_FILES_DECRYPTED_N_OF_N_NOT_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files decrypted ok\n%lu/%lu not encrypted\n%lu/%lu not of same type", + "N_OF_N_FILES_DECRYPTED": "%lu/%lu files decrypted ok", + "N_FILES_WRITTEN_TO_OUT": "%lu files written to %s", + "FILE_NOT_ENCRYPTED": "File is not encrypted", + "DECRYPTION_SUCCESS": "Decryption success", + "DECRYPTION_FAILED": "Decryption failed", + "PATH_DECRYPTED_TO_OUT": "%s\nDecrypted to %s", + "ENCRYPT_TO_OUT": "Encrypt to %s", + "ENCRYPT_INPLACE": "Encrypt inplace", + "TRY_TO_ENCRYPT_N_SELECTED_FILES": "Try to encrypt all %lu selected files?", + "TRYING_TO_ENCRYPT_N_FILES": "Trying to encrypt %lu files...", + "ENCRYPTION_FAILED_CONTINUE": "Encryption failed\n \nContinue?", + "N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files encrypted ok\n%lu/%lu not of same type", + "N_OF_N_FILES_ENCRYPTED": "%lu/%lu files encrypted ok", + "ENCRYPTION_SUCCESS": "Encryption success", + "ENCRYPTION_FAILED": "Encryption failed", + "PATH_ENCRYPTED_TO_OUT": "%s\nEncrypted to %s", + "TRY_TO_PROCESS_N_SELECTED_FILES": "Try to process all %lu selected files?", + "PATH_BUILD_TYPE_FAILED_CONTINUE": "%s\nBuild %s failed\n \nContinue?", + "N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE": "%lu/%lu %ss built ok\n%lu/%lu not of same type", + "N_OF_N_TYPES_BUILT": "%lu/%lu %ss built ok", + "N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED": "%lu file(s) failed conversion.\nVerification is recommended.", + "PATH_TYPE_BUILT_TO_OUT": "%s\n%s built to %s", + "PATH_TYPE_BUILD_FAILED": "%s\n%s build failed", + "FILE_FAILED_CONVERSION_VERIFY_NOW": "file failed conversion.\n \nVerify now?", + "VERIFICATION_SUCCESS": "Verification success", + "VERIFICATION_FAILED": "Verification failed", + "CONTENT_IS_MISSING": "Content is missing", + "INSTALL_TO_SYSNAND": "Install to SysNAND", + "INSTALL_TO_EMUNAND": "Install to EmuNAND", + "TRY_TO_INSTALL_N_SELECTED_FILES": "Try to install all %lu selected files?", + "TRYING_TO_INSTALL_N_FILES": "Trying to install %lu files...", + "INSTALL_FAILED_CONTINUE": "Install failed\n \nContinue?", + "N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files installed ok\n%lu/%lu not of same type", + "N_OF_N_FILES_INSTALLED": "%lu/%lu files installed ok", + "INSTALL_SUCCESS": "Install success", + "INSTALL_FAILED": "Install failed", + "FILE_FAILED_INSTALL_VERIFY_NOW": "file failed install.\n \nVerify now?", + "KEEP_TICKET_AND_SAVEGAME": "Keep ticket & savegame", + "UNINSTALL_EVERYTHING": "Uninstall everything", + "ABORT_UNINSTALL": "Abort uninstall", + "UNINSTALL_N_SELECTED_TITLES": "Uninstall %lu selected titles?", + "UNINSTALL_SELECTED_TITLE": "Uninstall selected title?", + "N_OF_N_TITLES_UNINSTALLED": "%lu/%lu titles uninstalled", + "UNINSTALLING_PLEASE_WAIT": "Uninstalling, please wait...", + "UNINSTALL_FAILED": "Uninstall failed!", + "TRY_TO_VERIFY_N_SELECTED_FILES": "Try to verify all %lu selected files?", + "VERIFICATION_FAILED_CONTINUE": "Verification failed\n \nContinue?", + "N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files verified ok\n%lu/%lu not of same type", + "VERIFYING_FILE_PLEASE_WAIT": "Verifying file, please wait...", + "NAND_VALIDATION_SUCCESS": "NAND validation success", + "NAND_VALIDATION_FAILED": "NAND validation failed", + "DUMP_FOR_N_SELECTED_FILES": "Dump for all %lu selected files?", + "N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL": "%lu/%lu legit tickets dumped.\n \nAttempt to dump all tickets?", + "N_OF_N_TICKETS_DUMPED_TO_OUT": "%lu/%lu tickets dumped to %s", + "PATH_TICKET_DUMPED_TO_OUT": "%s\nTicket dumped to %s", + "LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS": "%s\nLegit ticket not found.\n \nDump anyways?", + "DUMP_TICKET_FAILED": "Dump ticket failed!", + "BUILDING_X": "Building %s...", + "BUILDING_X_SYSNAND": "Building %s (SysNAND)...", + "BUILDING_X_EMUNAND": "Building %s (EmuNAND)...", + "PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED": "%s\n%lu/%lu files processed\n%lu/%lu files ignored", + "PATH_N_OF_N_FILES_PROCESSED": "%s\n%lu/%lu files processed", + "BUILD_DATABASE_SUCCESS": "Build database success.", + "BUILD_DATABASE_FAILED": "Build database failed.", + "TRY_TO_TRIM_N_SELECTED_FILES": "Try to trim all %lu selected files?", + "TRIMMING_FAILED_CONTINUE": "Trimming failed\n \nContinue?", + "N_OF_N_FILES_TRIMMED_N_OF_N_NOT_OF_SAME_TYPE_X_SAVED": "%lu/%lu files trimmed ok\n%lu/%lu not of same type\n%s saved", + "N_OF_N_FILES_TRIMMED_X_SAVED": "%lu/%lu files trimmed ok\n%s saved", + "FILE_CANT_BE_TRIMMED": "File can't be trimmed.", + "FILE_ALREADY_TRIMMED": "File is already trimmed.", + "PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE": "%s\nCurrent size: %s\nTrimmed size: %s\nDifference: %s\n \nTrim this file?", + "TRIMMING_FAILED": "Trimming failed.", + "PATH_TRIMMED_BY_X": "%s\nTrimmed by %s.", + "TRY_TO_RENAME_N_SELECTED_FILES": "Try to rename all %lu selected files?", + "N_OF_N_RENAMED": "%lu/%lu renamed ok", + "COULD_NOT_RENAME_TO_GOOD_NAME": "Could not rename to good name", + "SYSNAND_H_AND_S_INJECT": "SysNAND H&S inject", + "EMUNAND_H_AND_S_INJECT": "EmuNAND H&S inject", + "H_AND_S_INJECT_SUCCESS": "H&S inject success", + "H_AND_S_INJECT_FAILURE": "H&S inject failure", + "TRY_EXTRACT_ALL_N_SELECTED_FILES": "Try to extract all %lu selected files?", + "N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE": "%lu/%lu files extracted ok\n%lu/%lu not of same type", + "N_OF_N_FILES_EXTRACTED": "%lu/%lu files extracted ok", + "EXTRACTING_DOT_CODE": "Extracting .code, please wait...", + "PATH_EXT_EXTRACTED_TO_OUT": "%s\n%s extracted to %s", + "DOT_CODE_EXTRACT_FAILED": ".code extract failed", + "TRANSFER_TO_SYSNAND": "Transfer to SysNAND", + "TRANSFER_TO_EMUNAND": "Transfer to EmuNAND", + "CTRNAND_TRANSFER_SUCCESS": "CTRNAND transfer success", + "CTRNAND_TRANSFER_FAILED": "CTRNAND transfer failed", + "NO_VALID_DESTINATION_FOUND": "No valid destination found", + "NAND_RESTORE_SUCCESS": "NAND restore success", + "NAND_RESTORE_FAILED": "NAND restore failed", + "REBUILD_NCSD_SUCCESS": "Rebuild NCSD success", + "REBUILD_NCSD_FAILED": "Rebuild NCSD failed", + "PATH_NCCHINFO_PADGEN_SUCCESS": "%s\nNCCHinfo padgen success%cOutput dir: %s", + "PATH_NCCHINFO_PADGEN_FAILED": "%s\nNCCHinfo padgen failed%c%0.0s", + "UPDATING_EMBEDDED_BACKUP": "Updating embedded backup...", + "BACKUP_UPDATE_NOT_REQUIRED": "Backup update: not required", + "BACKUP_UPDATE_COMPLETED": "Backup update: completed", + "BACKUP_UPDATE_FAILED": "Backup update: failed!", + "WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK": "Warning: Keys are not verified.\nContinue on your own risk?", + "AESKEYDB_INIT_SUCCESS": "AESkeydb init success", + "AESKEYDB_INIT_FAILED": "AESkeydb init failed", + "AESKEYDB_INSTALL_SUCCESS": "AESkeydb install success", + "AESKEYDB_INSTALL_FAILED": "AESkeydb install failed", + "INSTALL_TO_FIRM0": "Install to FIRM0", + "INSTALL_TO_FIRM1": "Install to FIRM1", + "INSTALL_TO_BOTH": "Install to both", + "PATH_N_KB_INSTALL_TO_SYSNAND": "%s (%dkB)\nInstall to SysNAND?", + "PATH_N_KB_INSTALL_SUCCESS": "%s (%dkB)\nInstall success", + "PATH_N_KB_INSTALL_FAILED": "%s (%dkB)\nInstall failed", + "WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS": "Warning: Do not run scripts\nfrom untrusted sources.\n \nExecute script?", + "SCRIPT_EXECUTE_SUCCESS": "Script execute success", + "SCRIPT_EXECUTE_FAILURE": "Script execute failure", + "ERROR_CANNOT_VIEW_FILE": "Error: Cannot view file\n(Hint: maybe it's too big)", + "SAVEGAME_DUMPED_TO_OUT": "Savegame dumped to %s.", + "SAVEGAME_DUMP_FAILED": "Savegame dump failed!", + "GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD": "GBA VC savegame has to\nbe in the clipboard.", + "SAVEGAME_INJECT_SUCCESS": "Savegame inject success.", + "SAVEGAME_INJECT_FAILED": "Savegame inject failed!", + "FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Font will be active on next boot", + "LANGUAGE_WILL_BE_ACTIVE_ON_NEXT_BOOT": "Language will be active on next boot", + "HOME_MORE_MENU_SELECT_ACTION": "HOME more... menu.\nSelect action:", + "SD_FORMAT_MENU": "SD format menu", + "BONUS_DRIVE_MENU": "Bonus drive setup", + "SWITCH_EMUNAND": "Switch EmuNAND", + "BUILD_SUPPORT_FILES": "Build support files", + "RESTORE_H_AND_S": "Restore H&S", + "SET_RTC_DATE_TIME": "Set RTC date&time", + "CONFGURE_BRIGHTNESS": "Configure brightness", + "CALIBRATE_TOUCHSCREEN": "Calibrate touchscreen", + "SYSTEM_INFO": "System info", + "SHOW_README": "Show ReadMe", + "INITIALIZING_SD_FAILED_RETRY": "Initializing SD card failed! Retry?", + "SETUP_FAILED": "Setup failed!", + "CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT": "Current EmuNAND offset is %06lX.\nSwitch to next offset?", + "BUILT_IN_OUT_STATUSES": "Built in %s:\n \n%-18.18s %s\n%-18.18s %s\n%-18.18s %s", + "OK_SYS_EMU": "OK (Sys&Emu)", + "OK_SYS": "OK (Sys)", + "FAILED": "Failed", + "RESTORE_H_AND_S_EMUNAND": "Restore H&S (EmuNAND)", + "RESTORE_H_AND_S_SYSNAND": "Restore H&S (SysNAND)", + "TITLE_SET_RTC_DATE_TIME": "Set RTC date&time:", + "NEW_RTC_DATE_TIME_IS_TIME": "New RTC date&time is:\n%s\n \nHint: HOMEMENU time needs\nmanual adjustment after\nsetting the RTC.", + "TOUCHSCREEN_CALIBRATION_SUCCESS": "Touchscreen calibration success!", + "TOUCHSCREEN_CALIBRATION_FAILED": "Touchscreen calibration failed!", + "GODMODE9_README_TOC": "GodMode9 ReadMe Table of Contents", + "ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW": "Essential files backup not found.\nCreate one now?", + "BACKUP_EMBEDDED_WRITTEN_TO_OUT": "Backup embedded in SysNAND\nand written to %s.", + "RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW": "RTC date&time seems to be\nwrong. Set it now?", + "RESUME_GODMODE9": "Resume GodMode9", + "RESUME_BOOTLOADER": "Resume bootloader", + "SELECT_PAYLOAD": "Select payload...", + "SELECT_SCRIPT": "Select script...", + "POWEROFF_SYSTEM": "Poweroff system", + "REBOOT_SYSTEM": "Reboot system", + "FLAVOR_BOOTLOADER_SELECT_OPTION": "%s bootloader menu.\nSelect action:", + "BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD": "Bootloader payloads menu.\nSelect payload:", + "BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT": "Bootloader scripts menu.\nSelect script:", + "NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9": "No bootable FIRM found.\nNow resuming GodMode9...", + "OUT_OF_MEMORY": "Out of memory.", + "INVALID_DIRECTORY_OBJECT": "Invalid directory object", + "INVALID_ROOT_DIRECTORY": "Invalid root directory.", + "WRITE_PERMISSIONS_WERE_CHANGED_RELOCK": "Write permissions were changed.\nRelock them?", + "OPEN_TITLE_MANAGER": "Open title manager", + "SEARCH_FOR_FILES": "Search for files...", + "FIX_CMACS_FOR_DRIVE": "Fix CMACs for drive", + "SHOW_DIRECTORY_INFO": "Show directory info", + "SHOW_DRIVE_INFO": "Show drive info", + "FAILED_SETTING_UP_TITLE_MANAGER": "Failed setting up title manager!", + "SEARCH_FILE_ENTER_SEARCH_BELOW": "Search %s?\nEnter search below.", + "FOUND_N_RESULTS": "Found %lu results.", + "FIX_CMACS_FOR_DRIVE_FINISHED": "Fix CMACs for drive finished.", + "FAILED_TO_ANALYZE_DRIVE": "Failed to analyze drive\n", + "FAILED_TO_ANALYZE_DIR": "Failed to analyze dir\n", + "NOT_ALLOWED_IN_VIRTUAL_PATH": "Not allowed in virtual path", + "DELETE_N_PATHS": "Delete %lu path(s)?", + "DELETING_FILES_PLEASE_WAIT": "Deleting files, please wait...", + "FAILED_DELETING_N_OF_N_PATHS": "Failed deleting %lu/%lu path(s)", + "DELETE_FILE": "Delete \"%s\"?", + "FAILED_DELETING_PATH": "Failed deleting:\n%s", + "NOT_ALLOWED_IN_SEARCH_DRIVE": "Not allowed in search drive", + "NOT_ALLOWED_IN_VIRTUAL_GAME_PATH": "Not allowed in virtual game path", + "NOT_ALLOWED_IN_XORPAD_DRIVE": "Not allowed in XORpad drive", + "NOT_ALLOWED_IN_GAMECART_DRIVE": "Not allowed in gamecart drive", + "NOT_ALLOWED_IN_ALIAS_PATH": "Not allowed in alias path", + "COPY_PATHS": "Copy path(s)", + "MOVE_PATHS": "Move path(s)", + "PASTE_FILE_HERE": "Paste \"%s\" here?", + "PASTE_N_PATHS_HERE": "Paste %lu paths here?", + "FAILED_COPYING_PATH_PROCESS_REMAINING": "Failed copying path:\n%s\nProcess remaining?", + "FAILED_COPYING_PATH": "Failed copying path:\n%s", + "FAILED_MOVING_PATH_PROCESS_REMAINING": "Failed moving path:\n%s\nProcess remaining?", + "FAILED_MOVING_PATH": "Failed moving path:\n%s", + "RENAME_FILE_ENTER_NEW_NAME_BELOW": "Rename %s?\nEnter new name below.", + "FAILED_RENAMING_PATH": "Failed renaming path:\n%s", + "CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE": "Create a new entry here?\nSelect type.", + "CREATE_A_FOLDER": "Create a folder", + "CREATE_A_DUMMY_FILE": "Create a dummy file", + "CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW": "Create a new folder here?\nEnter name below.", + "CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW": "Create a new file here?\nEnter name below.", + "CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW": "Create a new %s here?\nEnter file size below.", + "FAILED_CREATING_FOLDER_PATH": "Failed creating folder:\n%s", + "FAILED_CREATING_FILE_PATH": "Failed creating file:\n%s", + "TITLE_MANAGER": "Title manager", + "BRICK_MY_3DS": "Brick my 3DS", + "LANGUAGE": "Language...", + "SCRIPTS": "Scripts...", + "PAYLOADS": "Payloads...", + "MORE": "More...", + "BRACKET_MORE": "[more...]", + "HOME_BUTTON_PRESSED_SELECT_ACTION": "HOME button pressed.\nSelect action:", + "POWER_BUTTON_PRESSED_SELECT_ACTION": "POWER button pressed.\nSelect action:", + "1_DRIVE_NAND_TWL": "[1:] NAND / TWL", + "4_DRIVE_NAND_TWL": "[4:] NAND / TWL", + "A_DRIVE_SD_CARD": "[A:] SD CARD", + "B_DRIVE_SD_CARD": "[B:] SD CARD", + "TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE": "Title manager menu.\nSelect titles source:", + "LANGUAGES_DIRECTORY_NOT_FOUND": "Languages directory not found.\n(default path: 0:/gm9/%s)", + "SCRIPTS_DIRECTORY_NOT_FOUND": "Scripts directory not found.\n(default path: 0:/gm9/%s)", + "HOME_LANGUAGE_MENU_SELECT_LANGUAGE": "HOME language... menu.\nSelect language:", + "HOME_SCRIPTS_MENU_SELECT_SCRIPT": "HOME scripts... menu.\nSelect script:", + "PAYLOADS_DIRECTORY_NOT_FOUND": "Payloads directory not found.\n(default path: 0:/gm9/%s)", + "HOME_PAYLOADS_MENU_SELECT_PAYLOAD": "HOME payloads... menu.\nSelect payload:", + "UNEXPECTED_SD_CARD_REMOVAL_TO_PREVENT_DATA_LOSS_UNMOUNT_BEFORE_EJECT": "!Unexpected SD card removal!\n \nTo prevent data loss, unmount\nbefore ejecting the SD card.", + "FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT": "%s scripts menu.\nSelect script:", + "COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP": "Compiled as script autorunner\nbut no script provided.\n \nDerp!", + "KEYBOARD_CONTROLS_DETAILS": "Keyboard Controls:\n \n←/→ - Move cursor\nR - Caps / Capslock\nX - Delete char\nY - Insert char\nA - Submit\nB - Cancel\n \nSELECT switches to\nclassic prompt", + "TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS": "Touch the red crosshairs to\ncalibrate your touchscreen.\n \nUse the stylus for best\nresults!", + "INVALID": "INVALID", + "TO_PROCEED_ENTER_THIS": "To proceed, enter this:", + "TO_PROCEED_HOLD_X": "To proceed, hold :", + "N_MORE": " [%d more]", + "CANCEL": "cancel", + "R_FAST_SCROLL_L_CLEAR_DATA": "R - (↑↓) fast scroll\nL - clear data", + "X_REMOVE_CHAR_Y_INSERT_CHAR": "X - remove char\nY - insert char", + "ETA_N_MIN_N_SEC": "ETA %02llum%02llus", + "BRIGHTNESS_CONTROLS": "[←] Decrease brightness\n[→] Increase brightness\n \n[X] Use volume slider control\n[A] Set current brightness\n[B] Cancel", + "SEARCHING_PLEASE_WAIT": "Searching, please wait...", + "RENAME_TO_GOOD_NAME": "Rename to good name?", + "SD_WRITE_PROTECTED_CANT_CONTINUE": "SD card is write protected!\nCan't continue.", + "SYSNAND_LVL_N": "SysNAND (lvl%lu)", + "EMUNAND_LVL_N": "EmuNAND (lvl%lu)", + "GAME_IMAGES": "game images", + "GAMECART_SAVES": "gamecart saves", + "IMAGES": "images", + "MEMORY_AREAS": "memory areas", + "SD_SYSTEM_DATA": "SD system data", + "SD_CARD": "SD card", + "RAM_DRIVE": "RAM drive", + "WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW": "Writing to %s is locked!\nUnlock it now?", + "UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED": "Unlock write permission for\n%s is not allowed.", + "ENABLE_BASE_WRITE": "You want to enable base\nwriting permissions.", + "ENABLE_SD_WRITE": "You want to enable SD card\nwriting permissions.", + "ENABLE_IMAGE_WRITE": "You want to enable image\nwriting permissions.", + "ENABLE_RAM_DRIVE_WRITE": "You want to enable RAM drive\nwriting permissions.", + "ENABLE_EMUNAND_0_WRITE": "You want to enable EmuNAND\nlvl0 writing permissions.", + "ENABLE_SYSNAND_0_WRITE": "You want to enable SysNAND\nlvl0 writing permissions.", + "ENABLE_EMUNAND_1_WRITE": "You want to enable EmuNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nrecoverable system data,\nuser data & savegames.", + "ENABLE_SYSNAND_1_WRITE": "You want to enable SysNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nsystem data, installations,\nuser data & savegames.", + "ENABLE_GAMECART_SAVE_WRITE": "You want to enable gamecart\nsave writing permissions.", + "ENABLE_SYSNAND_2_WRITE": "!Better be careful!\n \nYou want to enable SysNAND\nlvl2 writing permissions.\n \nThis enables you to modify\nirrecoverable system data!", + "ENABLE_MEMORY_WRITE": "!Better be careful!\n \nYou want to enable memory\nwriting permissions.\n \nWriting to certain areas may\nlead to unexpected results.", + "ENABLE_SD_DATA_WRITE": "!THIS IS NOT RECOMMENDED!\n \nYou want to enable SD data\nwriting permissions.\n \nEverything here is encrypted.\nIt is recommended to use the\nA:/B: drives for modification\nof installations, user data &\nsavegames instead.", + "ENABLE_SYSNAND_3_WRITE": "!THIS IS YOUR ONLY WARNING!\n \nYou want to enable SysNAND\nlvl3 writing permissions.\n \nThis enables you to OVERWRITE\nyour bootloader installation,\nessential system files and/or\nBRICK your console!", + "UNLOCK_WRITE_NOT_ALLOWED": "Unlock write permission is not allowed.", + "CANT_UNLOCK_WRITE_TRY_GODMODE9": "Can't unlock write permission.\nTry GodMode9 instead!", + "ERROR_SD_TOO_SMALL": "Error: SD card is too small", + "WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA": "!WARNING!\n \nProceeding will format this SD.\nThis will irreversibly delete\nALL data on it.", + "FORMAT_BONUS_DRIVE_DELETE_ALL_DATA": "Format the bonus drive?\nThis will irreversibly delete\nALL data on it.", + "FORMATTING_SD_PLEASE_WAIT": "Formatting SD, please wait...", + "FORMATTING_DRIVE_PLEASE_WAIT": "Formatting drive, please wait...", + "ERROR_SD_CARD_IO_FAILURE": "Error: SD card i/o failure", + "FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK": "File is currently mounted.\nUnmount to unlock?", + "ERROR_CANT_INJECT_FILE_INTO_ITSELF": "Error: Can't inject file into itself", + "OPERATION_WOULD_WRITE_BEYOND_EOF": "Operation would write beyond end of file", + "NOT_ENOUGH_DATA_IN_FILE": "Not enough data in file", + "CANCEL_IS_NOT_ALLOWED_HERE": "Cancel is not allowed here", + "B_DETECTED_CANCEL": "B button detected. Cancel?", + "ERROR_CANNOT_APPEND_FOLDER": "Error: Cannot append a folder", + "ERROR_OVERWRITING_FILE_WITH_DIR": "Error: Overwriting file with dir", + "ERROR_OVERWRITING_DIR_WITH_FILE": "Error: Overwriting dir with file", + "ERROR_CANNOT_OPEN_DESTINATION_FILE": "Error: Cannot open destination file", + "ERROR_NOT_ENOUGH_SPACE_AVAILABLE": "Error: Not enough space available", + "ERROR_ONLY_FAT_FILES_CAN_BE_MOVED": "Error: Only FAT files can be moved", + "ERROR_DESTINATION_IS_PART_OF_ORIGIN": "Error: Destination is part of origin", + "ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME": "Destination equals origin\nChoose another name?", + "CHOOSE_NEW_NAME": "Choose new name", + "OVERWRITE_FILES": "Overwrite file(s)", + "SKIP_FILES": "Skip file(s)", + "OVERWRITE_ALL": "Overwrite all", + "SKIP_ALL": "Skip all", + "DESTINATION_ALREADY_EXISTS": "Destination already exists:\n%s", + "CHOOSE_NEW_DESTINATION_NAME": "Choose new destination name", + "COPY_OPERATION_IS_NOT_ALLOWED": "Copy operation is not allowed", + "DESTINATION_EQUALS_ORIGIN": "Destination equals origin", + "ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD": "Entry not found: %s\nInject into %s instead?", + "FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE": "File smaller than available space:\n%s (%s)\n%s (%s)\nContinue?", + "NO_USABLE_ENTRIES_FOUND": "No usable entries found.", + "BEAT_NO_ERROR": "No error", + "BEAT_END_OF_ACTION_LIST": "End of action list", + "BEAT_ABORTED_BY_USER": "Aborted by user", + "BEAT_FAILED_TO_READ_WRITE_FILE": "Failed to read/write file", + "BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF": "Attempted to write beyond end of file", + "BEAT_INVALID_PATCH_FILE": "Invalid patch file", + "BEAT_INVALID_INPUT_FILE": "Invalid input file", + "BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH": "Output file checksum mismatch", + "BEAT_FILE_CHECKSUM_FAILED": "File checksum failed", + "BEAT_EXPECTED_MORE_PATCH_DATA": "Expected more patch data", + "BEAT_OUT_OF_MEMORY": "Out of memory", + "BEAT_UNKNOWN_ERROR": "Unknown error", + "FAILED_TO_INITIALIZE_BPM_FILE": "Failed to initialize BPM file:\n%s", + "FAILED_TO_INITIALIZE_BPS_FILE": "Failed to initialize BPS file:\n%s", + "PATCH_SUCCESSFULLY_APPLIED": "Patch successfully applied", + "PATCHING_ABORTED_BY_USER": "Patching aborted by user", + "FAILED_TO_RUN_PATCH": "Failed to run patch:\n%s", + "DECOMPRESSING_DOT_CODE": "Decompressing .code...", + "DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Decompressing .code...\nB button detected. Cancel?", + "COMPRESSING_DOT_CODE": "Compressing .code...", + "COMPRESSING_DOT_CODE_B_DETECTED_CANCEL": "Compressing .code...\nB button detected. Cancel?", + "PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE": "The patch is most likely not intended for this file.", + "YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT": "You most likely applied the patch on the output file.", + "PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED": "The patch is technically valid,\nbut seems scrambled or malformed.", + "PATCH_IS_INVALID": "The patch is invalid.", + "FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT": "One or both files are bigger than 16MB.\nThe IPS format doesn't support that.", + "REQUESTED_FILE_PATH_WAS_INVALID": "The requested file path was invalid.", + "PATCHING_CANCELED": "Patching canceled.", + "NOT_ENOUGH_MEMORY": "Not enough memory.", + "REGION_AMERICAS": "Americas", + "REGION_AUSTRALIA": "Australia", + "REGION_BRAZIL": "Brazil", + "REGION_CHINA": "China", + "REGION_EUROPE": "Europe", + "REGION_FRANCE": "France", + "REGION_GERMANY": "Germany", + "REGION_ITALY": "Italy", + "REGION_JAPAN": "Japan", + "REGION_KOREA": "Korea", + "REGION_SPAIN": "Spain", + "REGION_TAIWAN": "Taiwan", + "REGION_UNKNOWN": "Unknown", + "REGION_UNITED_KINGDOM": "United Kingdom", + "REGION_MIDDLE_EAST": "Middle East", + "GENERATING_QR_CODE": "Generating QR code...", + "REINITIALIZING_SD_CARD": "Reinitializing SD card...", + "DUMPING_STATE_TO_SD_CARD": "Dumping state to SD card...", + "PRESS_POWER_TO_TURN_OFF": "Press POWER to turn off", + "CLEANING_UP_TITLES_PLEASE_WAIT": "Cleaning up titles, please wait...", + "ERROR_NOT_NCCH_FILE": "Error: Not an NCCH file", + "ERROR_FILE_IS_TOO_SMALL": "Error: File is too small", + "ATTEMPT_FIX_THIS_TIME": "Attempt fix this time", + "ATTEMPT_FIX_ALWAYS": "Attempt fix always", + "ABORT_VERIFICATION": "Abort verification", + "ERROR_BAD_CRYPTO_FLAGS": "Error: Bad crypto flags", + "ERROR_BAD_EXEFS_HEADER": "Error: Bad ExeFS header", + "ERROR_MISSING_EXTHEADER": "Error: Missing ExtHeader", + "ERROR_CRYPTO_NOT_SET_UP": "Error: Crypto not set up", + "PATH_NCCH_VERIFICATION_FAILED_INFO": "%s\nNCCH verification failed:\nExtHdr/ExeFS/RomFS: %s/%s/%s", + "OK": "ok", + "FAIL": "fail", + "ERROR_NOT_NCSD_FILE": "Error: Not an NCSD file", + "PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nContent%lu (%08lX@%08lX):\nVerification failed", + "ERROR_PROBABLY_NOT_CIA_FILE": "Error: Probably not a CIA file", + "ERROR_TMD_PROBABLY_CORRUPTED": "Error: TMD probably corrupted", + "PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED": "%s\nID %08lX (%08llX@%08llX)\nVerification failed", + "ERROR_CDN_TITLEKEY_NOT_FOUND": "Error: CDN titlekey not found", + "DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE": "DLC content is missing\n \nIgnore all and continue?", + "PATH_SECTION_N_HASH_MISMATCH": "%s\nSection %lu hash mismatch", + "ARM9_ENTRYPOINT_IS_MISSING": "ARM9 entrypoint is missing", + "WARNING_ARM11_ENTRYPOINT_IS_MISSING": "Warning: ARM11 entrypoint is missing", + "ERROR_NOT_A_BOSS_FILE": "Error: Not a BOSS file", + "BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT": "BOSS payload hash mismatch.\n \nTry to fix it?", + "GENERIC_TICKET_PIRATE_LEGIT": "Generic ticket (\"pirate legit\")", + "PERSONALIZED_TICKET_LEGIT": "Personalized ticket (legit)", + "ID_N_LEGIT_TICKET_IS_PERSONALIZED_USING_THIS_NOT_RECOMMENDED_CHOOSE_DEFAULT_ACTION": "ID %016llX\nLegit ticket is personalized.\nUsing this is not recommended.\nChoose default action:", + "ID_N_TITLEKEY_NOT_FOUND": "ID %016llX\nTitlekey not found.", + "ID_N_TMD_IN_TAD_NOT_LEGIT": "ID %016llX\nTMD in TAD is not legit.", + "ID_N_TMD_NOT_LEGIT": "ID %016llX\nTMD is not legit.", + "ID_N_DOT_N_STATUS": "ID %016llX.%08lX\n%s", + "CONTENT_IS_CORRUPT": "Content is corrupt", + "INSERT_CONTENT_FAILED": "Insert content failed", + "INSTALL_CONTENT_FAILED": "Install content failed", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_DB_FILES_MAYBE_SD_MISSING_OR_UNINITIALIZED": "Install error:\nThis system is missing one or\nmore .db files.\n \nMaybe the SD card is missing\nor uninitialized?", + "INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB": "Install error:\nThis system is missing the\nticket.db file.", + "SKIPPED_TITLE_0004008C000CBD00_NEEDS_SPECIAL_COMPILE_FLAGS": "Skipped title:\nTitle with id 0004008C000CBD00\nneeds special compiler flags.", + "ERROR_FAKE_SIGNED_TICKET_ONLY_VALID_SIGNED_TICKETS_CAN_BE_INSTALLED": "Error: Fake-signed ticket\n \nOnly valid signed tickets can\nbe installed to the system.", + "PATH_ERROR_UNKNOWN_CID_N_THIS_TICKET_DOES_NOT_BELONG_TO_THIS_3DS": "%s\nError: Unknown cid %08lX\n \nThis ticket does not belong to\nthis 3DS console.", + "INSTALLING_TICKET": "Installing ticket...", + "POSSIBLY_BROKEN": "Possibly Broken", + "PERSONAL_LEGIT": "Personal Legit", + "PERSONAL_LEGIT_DLC": "Personal Legit DLC", + "PERSONAL_PIRATE_LEGIT": "Personal Pirate Legit", + "PERSONAL_PIRATE_LEGIT_DLC": "Personal Pirate Legit DLC", + "PERSONAL_CUSTOM": "Personal Custom", + "PERSONAL_CUSTOM_DLC": "Personal Custom DLC", + "UNIVERSAL_LEGIT": "Universal Legit", + "UNIVERSAL_LEGIT_DLC": "Universal Legit DLC", + "UNIVERSAL_PIRATE_LEGIT": "Universal Pirate Legit", + "UNIVERSAL_PIRATE_LEGIT_DLC": "Universal Pirate Legit DLC", + "UNIVERSAL_CUSTOM": "Universal Custom", + "UNIVERSAL_CUSTOM_DLC": "Universal Custom DLC", + "CONTENTS_IN_CIA_FOUND_TOTAL": "Contents in CIA: %lu/%lu", + "CONTENTS_IN_CIA_TOTAL": "Contents in TMD: %lu", + "CONSOLE_ID_N": "Console ID: %08lX\n", + "SHOW_GAME_INFO_DETAILS": "%s\n%s %s Title\n \nTitle ID: %016llX\nTitle version: %lu.%lu.%lu\nContents size: %s\n%s\n%s \nTicket/TMD: %s/%s\nVerification: %s", + "STATE_LEGIT": "legit", + "STATE_ILLEGIT": "illegit", + "STATE_UNKNOWN": "unknown", + "STATE_INVALID": "invalid", + "STATE_PENDING_PROCEED_WITH_VERIFICATION": "pending\n \nProceed with verification?", + "STATE_PASSED": "passed", + "STATE_FAILED": "failed", + "OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS": "Output file already exists.\nUpdate this?", + "DSI_ENHANCED": "DSi Enhanced", + "DSI_EXCLUSIVE": "DSi Exclusive", + "FIXING_CMACS_PLEASE_WAIT": "Fixing CMACs, please wait...", + "NCSD_HEADER_IS_NOT_VALID": "NCSD header is not valid", + "NAND_DUMP_MISSING_DATA": "NAND dump missing data", + "ERROR_CTR_MBR_IS_CORRUPT": "Error: CTR MBR is corrupt", + "ERROR_TWL_MBR_IS_CORRUPT": "Error: TWL MBR is corrupt", + "PATH_ERROR_CTR_PARTITION_N_IS_CORRUPT": "%s\nError: CTR partition%lu is corrupt", + "PATH_ERROR_TWL_PARTITION_N_IS_CORRUPT": "%s\nError: TWL partition%lu is corrupt", + "NO_VALID_FIRM_FOUND": "No valid FIRM found", + "ERROR_NAND_DUMP_IS_CORRUPT_STILL_CONTINUE": "Error: NAND dump is corrupt.\nStill continue?", + "ERROR_SYSTEM_IS_LOCKED": "Error: System is locked.", + "ESSENTIAL_FILES_BACKUP_IS_REQUIRED_CREATE_ONE_NOW": "Essential files backup is required.\nCreate one now?", + "WARNING_PROCEEDING_WILL_OVERWRITE_SYSNAND_WITH_DUMP": "!WARNING!\n \nProceeding will overwrite the\nSysNAND with the provided dump.\n \n(B9S/A9LH will be left intact.)", + "IMAGE_NCSD_CORRUPT_OR_CUSTOMIZED_SAFE_RESTORE_NOT_POSSIBLE": "Image NCSD corrupt or customized,\nsafe restore is not possible!", + "WARNING_NCSD_DIFFERS_BETWEEN_IMAGE_AND_LOCAL_ELEVATED_WRITE_PERMISSIONS_REQUIRED": "!WARNING!\n \nNCSD differs between image and local,\nelevated write permissions required\n \nProceed on your own risk?", + "NOT_AN_INSTALLABLE_FIRM": "Not a installable FIRM.", + "FIRM_LOAD_VERIFY_ERROR": "FIRM load/verify error.", + "PATH_FIRM_N_NOT_FOUND_OR_TOO_SMALL": "%s\nFIRM%lu not found or too small.", + "SECTOR_0X96_CRYPTO_FAIL": "Sector 0x96 crypto fail.", + "SECTOR_0X96_CORRUPTED_PROVIDE_SECRET_SECTOR_BIN_TO_FIX": "Sector 0x96 is corrupted.\n \nProvide \"secret_sector.bin\"\nto fix sector 0x96.", + "SECTOR_0X96_CORRUPTED_FIX_DURING_INSTALLATION": "Sector 0x96 is corrupted.\n \nFix sector 0x96 during\nthe installation?", + "WARNING_PROCEEDING_WILL_INSTALL_FIRM_TO_SYSNAND_AND_INJECT_SIGHAX_UNSUPPORTED_FIRM_WILL_BRICK": "!WARNING!\n \nProceeding will install the\nprovided FIRM to the SysNAND\nand inject sighax.\n \nInstalling an unsupported FIRM\nwill BRICK your console!", + "INSTALLING_FIRM_PLEASE_WAIT": "Installing FIRM, please wait...", + "THIS_IS_BAD_FAILED_WRITING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed writing sector 0x96.\nTry to fix before reboot!", + "THIS_IS_BAD_FAILED_WRITING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed writing FIRM%lu.\nTry to fix before reboot!", + "CHECKING_INSTALLATION_PLEASE_WAIT": "Checking installation, please wait...", + "THIS_IS_BAD_FAILED_VERIFYING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed verifying sector 0x96.\nTry to fix before reboot!", + "THIS_IS_BAD_FAILED_VERIFYING_FIRM_N_TRY_FIX_BEFORE_REBOOT": "!THIS IS BAD!\n \nFailed verifying FIRM%lu.\nTry to fix before reboot!", + "PERFECT_KEYDB_IS_ALREADY_INSTALLED": "Perfect %s is already installed!", + "PATH_NOT_PERFECT_KEYDB_IMAGE_CANNOT_INSTALL_TO_NAND": "%s\nNot a perfect %s image.\nCannot install to NAND!", + "PATH_FAILED_WRITING_KEYDB_TO_NAND": "%s\nFailed writing %s to NAND!", + "USE_L_R_TO_SAVE": "(use L+R to save)", + "EASTER_NOT_FOUND": "(%s not found)", + "BUILDING_TO_OUT_ARG": "Building to %s:\n%s ...", + "EJECT_SD_CARD": "Eject SD card...", + "INSERT_SD_CARD": "Insert SD card...", + "SCRIPTERR_UNKNOWN_CMD": "unknown cmd", + "SCRIPTERR_BAD_NUMBER_OF_ARGS": "bad # of args", + "SCRIPTERR_UNRECOGNIZED_FLAGS": "unrecognized flags", + "SCRIPTERR_ILLEGAL_FLAG": "illegal flag", + "SCRIPTERR_UNRESOLVED_QUOTES": "unresolved quotes", + "SCRIPTERR_TOO_MANY_ARGUMENTS": "too many arguments", + "SCRIPTERR_ARGUMENT_EXPAND_FAILED": "argument expand failed", + "SCRIPTERR_QUOTE_NOT_AN_ERROR": "'not' an error", + "SCRIPTERR_SYNTAX_ERROR_AFTER_IF": "syntax error after 'if'", + "SCRIPTERR_ELIF_WITHOUT_IF": "'elif' without 'if'", + "SCRIPTERR_SYNTAX_ERROR_AFTER_ELIF": "syntax error after 'elif'", + "SCRIPTERR_ELSE_WITHOUT_IF": "'else' without 'if'", + "SCRIPTERR_END_WITHOUT_IF": "'end' without 'if'", + "SCRIPTERR_FOR_INSIDE_FOR": "'for' inside 'for'", + "SCRIPTERR_DIR_NOT_FOUND": "dir not found", + "SCRIPTERR_FOR_WITHOUT_NEXT": "'for' without 'next'", + "SCRIPTERR_NEXT_WITHOUT_FOR": "'next' without 'for'", + "SCRIPTERR_FORPATH_ERROR": "forpath error", + "SCRIPTERR_LABEL_NOT_FOUND": "label not found", + "SCRIPTERR_USER_ABORT": "user abort", + "SCRIPTERR_KEY_NOT_PRESSED": "key not pressed", + "SCRIPTERR_OUT_OF_MEMORY": "out of memory", + "SCRIPTERR_VAR_FAIL": "var fail", + "SCRIPTERR_FORBIDDEN_DRIVE": "forbidden drive", + "SCRIPTERR_INVALID_PATH": "invalid path", + "SCRIPTERR_FILESELECT_ABORT": "fileselect abort", + "SCRIPTERR_DIRSELECT_ABORT": "dirselect abort", + "SCRIPTERR_SET_FAIL": "set fail", + "SCRIPTERR_CHAR_NOT_FOUND": "char not found", + "SCRIPTERR_ARGV_2_IS_NOT_CHAR": "argv[2] is not a char", + "SCRIPTERR_ARGV_2_MUST_BE_2_CHARS": "argv[2] must be 2 chars", + "SCRIPTERR_ARG_MATCH": "arg match", + "SCRIPTERR_NO_ARG_MATCH": "no arg match", + "SCRIPTERR_PERMISSION_FAIL": "permission fail", + "SCRIPTERR_COPY_FAIL": "copy fail", + "SCRIPTERR_MOVE_FAIL": "move fail", + "SCRIPTERR_INJECT_FAIL": "inject fail", + "SCRIPTERR_FILLBYTE_FAIL": "fillbyte fail", + "SCRIPTERR_FILL_FAIL": "fill fail", + "SCRIPTERR_BAD_FILESIZE": "bad filesize", + "SCRIPTERR_CREATE_DUMMY_FILE": "create dummy fail", + "SCRIPTERR_REMOVE_FAIL": "remove fail", + "SCRIPTERR_MAKEDIR_FAIL": "makedir fail", + "SCRIPTERR_MOUNT_FAIL": "mount fail", + "SCRIPTERR_FIND_FAIL": "find fail", + "SCRIPTERR_FINDNOT_FAIL": "findnot fail", + "SCRIPTERR_NO_SIZE_GIVEN": "no size given", + "SCRIPTERR_SIZE_TOO_BIG": "size too big", + "SCRIPTERR_READ_FAIL": "read fail", + "SCRIPTERR_CONVERSION_FAIL": "conversion fail", + "SCRIPTERR_INVALID_DATA": "invalid data", + "SCRIPTERR_WRITE_FAIL": "write fail", + "SCRIPTERR_SHA_ARG0_FAIL": "sha arg0 fail", + "SCRIPTERR_SHA_ARG1_FAIL": "sha arg1 fail", + "SCRIPTERR_SHA_DOES_NOT_MATCH": "sha does not match", + "SCRIPTERR_SHA_WRITE_FAIL": "sha write fail", + "SCRIPTERR_FILE_WRITE_FAIL": "file write fail", + "SCRIPTERR_FIXCMAC_FAILED": "fixcmac failed", + "SCRIPTERR_VERIFICATION_FAILED": "verification failed", + "SCRIPTERR_DECRYPT_FAILED": "decrypt failed", + "SCRIPTERR_ENCRYPT_FAILED": "encrypt failed", + "SCRIPTERR_BUILD_CIA_FAILED": "build CIA failed", + "SCRIPTERR_INSTALL_GAME_FAILED": "install game failed", + "SCRIPTERR_DOES_NOT_CONTAIN_DOT_CODE": "does not contain .code", + "SCRIPTERR_EXTRACT_DOT_CODE_FAILED": "extract .code failed", + "SCRIPTERR_COMPRESS_DOT_CODE_FAILED": "compress .code failed", + "SCRIPTERR_BUILD_FAILED": "build failed", + "SCRIPTERR_UNKNOWN_FILE": "unknown file", + "SCRIPTERR_APPLY_IPS_FAILD": "apply IPS failed", + "SCRIPTERR_APPLY_BPS_FAILED": "apply BPS failed", + "SCRIPTERR_APPLY_BPM_FAILED": "apply BPM failed", + "SCRIPTERR_TEXTVIEWER_FAILED": "textviewer failed", + "SCRIPTERR_BAD_DUMPSIZE": "bad dumpsize", + "SCRIPTERR_CART_INIT_FAIL": "cart init fail", + "SCRIPTERR_CART_DUMP_FAILED": "cart dump failed", + "SCRIPTERR_NOT_A_DIR": "not a dir", + "SCRIPTERR_FILE_NOT_FOUND": "file not found", + "SCRIPTERR_NOT_A_BOOTABLE_FIRM": "not a bootable firm", + "SCRIPTERR_SD_NOT_MOUNTED": "SD not mounted", + "SCRIPTERR_UNKNOWN_ERROR": "unknown error", + "SCRIPTERR_COMMAND_SUCCESS": "command success", + "SCRIPTERR_CONTROL_FLOW_ERROR": "control flow error", + "SCRIPTERR_UNCLOSED_CONDITIONAL": "unclosed conditional", + "SCRIPTERR_ERROR_MESSAGE_FAIL": "error message fail", + "ERROR_INVALID_TEXT_DATA": "Error: Invalid text data", + "TEXTVIEWER_CONTROLS_DETAILS": "Textviewer Controls:\n \n↑↓→←(+R) - Scroll\nR+Y - Toggle wordwrap\nR+X - Goto line #\nB - Exit\n", + "CURRENT_LINE_N_ENTER_NEW_LINE_BELOW": "Current line: %i\nEnter new line below.", + "PREVIEW_DISABLED": "(preview disabled)", + "PATH_LINE_N_ERR_LINE": "%s\nline %lu: %s\n%s", + "END_OF_SCRIPT_UNRESOLVED_IF": "end of script: unresolved 'if'", + "END_OF_SCRIPT_UNRESOLVED_FOR": "end of script: unresolved 'for'", + "SYSINFO_MODEL": "Model: %s (%s)\r\n", + "SYSINFO_SERIAL": "Serial: %s\r\n", + "SYSINFO_REGION_SYSTEM": "Region (system): %s\r\n", + "SYSINFO_REGION_SALES": "Region (sales): %s\r\n", + "SYSINFO_SOC_MANUFACTURING_DATE": "SoC manufacturing date: %s\r\n", + "SYSINFO_SYSTEM_ASSEMBLY_DATE": "System assembly date: %s\r\n", + "SYSINFO_ORIGINAL_FIRMWARE": "Original firmware: %s\r\n", + "SYSINFO_FRIENDCODE_SEED": "Friendcode seed: %s\r\n", + "SYSINFO_SD_KEYY": "SD keyY: %s\r\n", + "SYSINFO_NAND_CID": "NAND CID: %s\r\n", + "SYSINFO_SD_CID": "SD CID: %s\r\n", + "SYSINFO_SYSTEM_ID0": "System ID0: %s\r\n", + "SYSINFO_SYSTEM_ID1": "System ID1: %s\r\n", + "SORTING_TICKETS_PLEASE_WAIT": "Sorting tickets, please wait ..." +} diff --git a/utils/transcp.py b/utils/transcp.py new file mode 100755 index 000000000..3b4cb2552 --- /dev/null +++ b/utils/transcp.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 + +from argparse import ArgumentParser, FileType +import json + +# Special keys +LANGUAGE_NAME = "GM9_LANGUAGE" +VERSION = "GM9_TRANS_VER" + +parser = ArgumentParser(description="Creates the language.inl file from source.json") +parser.add_argument("source", type=FileType("r"), help="source.json") +parser.add_argument("inl", type=FileType("w"), help="language.inl") +args = parser.parse_args() + +# Load the JSON and handle the meta values +source = json.load(args.source) +version = source[VERSION] +del source[VERSION] +del source[LANGUAGE_NAME] + +# Create the header file +args.inl.write("#define TRANSLATION_VER %d\n\n" % version) +for key in source: + # Escape \r, \n, and quotes + val = source[key].replace("\r", "\\r").replace("\n", "\\n").replace('"', '\\"') + args.inl.write('STRING(%s, "%s")\n' % (key, val)) diff --git a/utils/transriff.py b/utils/transriff.py new file mode 100755 index 000000000..5bde3176c --- /dev/null +++ b/utils/transriff.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python3 + +""" Create a TRF translation for GodMode9 from a translation JSON. """ + +import argparse +import json +import math +import pathlib +import struct +import sys + + +# Special keys +LANGUAGE_NAME = "GM9_LANGUAGE" +VERSION = "GM9_TRANS_VER" + + +def ceil_to_multiple(num: int, base: int) -> int: + """ + Return the ceiling of num which is a multiple of base. + + Args: + num: Number whose ceiling to return. + base: Value which num will become a multiple of. + + Returns: + Num rounded to the next multiple of base. + """ + return base * math.ceil(num / base) + + +def get_language(data: dict) -> bytes: + """ + Get language name from JSON data. + + Args: + data: JSON translation data. + + Returns: + The translation's language name. + + Raises: + ValueError: If no language name exists. + """ + try: + return data[LANGUAGE_NAME].encode("utf-8") + except KeyError as exception: + raise ValueError("missing language name") from exception + +def get_version(data: dict) -> int: + """ + Get translation version from JSON data. + + Args: + data: JSON translation data. + + Returns: + The translation's version. + + Raises: + ValueError: If no version exists. + """ + try: + return data[VERSION] + except KeyError as exception: + raise ValueError("missing verison number") from exception + + +def load_translations(data: dict) -> dict[str, bytearray]: + """ + Load translations from JSON data. + + Args: + data: JSON translation data. + + Returns: + The loaded strings. + """ + return { + key: bytearray(value, "utf-8") + b"\0" + for key, value in data.items() + if key not in (LANGUAGE_NAME, VERSION) + } + + +def strings_to_trf(mapping: dict[str, bytearray], version: int, language: str) -> bytearray: + """ + Create a TRF file from translated strings. + + Args: + mapping: Mapping between labels and translated strings. + version: Translation version. + language: Translation language. + + Returns: + The translation strings as TRF data. + """ + # File header. + trfdata = bytearray(b"RIFF\0\0\0\0") + + # Metadata section. + trfdata += ( + b"META" + + struct.pack(" None: + """ + Entrypoint of transriff. + + Args: + source: JSON to convert from. + dest: TRF file to write. + """ + data = json.loads(source.read_text()) + + try: + language = get_language(data) + version = get_version(data) + except ValueError as exception: + sys.exit(f"Fatal: {exception}.") + mapping = load_translations(data) + + trf_file = strings_to_trf(mapping, version, language) + + dest.write_bytes(trf_file) + print(f"Info: {dest.as_posix()} created with {len(mapping)} strings.") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Create a TRF translation for GodMode9 from a translation JSON." + ) + + parser.add_argument( + "source", + type=pathlib.Path, + help="JSON to convert from" + ) + parser.add_argument( + "dest", + type=pathlib.Path, + help="TRF file to write" + ) + + args = parser.parse_args() + + main(args.source, args.dest)