Make strings translatable

This commit is contained in:
Pk11 2022-03-22 18:13:18 -05:00 committed by d0k3
parent cae3d272d3
commit 93ee590cad
31 changed files with 1852 additions and 946 deletions

View File

@ -40,7 +40,7 @@ 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

View File

@ -1,5 +1,6 @@
#include <stdarg.h>
#include "language.h"
#include "swkbd.h"
#include "timer.h"
#include "hid.h"
@ -253,7 +254,7 @@ 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, "%s", instr);
show_instr = false;

View File

@ -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();

View File

@ -15,6 +15,7 @@
#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
@ -576,18 +577,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 +621,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]);
}
}
@ -720,7 +716,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) ? "(<A> yes, <B> no)" : "(<A> to continue)");
(ask) ? STR_A_YES_B_NO : STR_A_TO_CONTINUE);
while (true) {
u32 pad_state = InputWait(0);
@ -775,7 +771,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 +808,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 <X>:");
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++) {
@ -865,7 +861,7 @@ u32 ShowSelectPrompt(int n, const char** options, const char *format, ...) {
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, "(<A> select, <B> 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 (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",
@ -944,7 +940,7 @@ u32 ShowFileScrollPrompt(int 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, "(<A> select, <B> 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 (int i = scroll; i < scroll+n_show; i++) {
char bytestr[16];
@ -965,12 +961,12 @@ u32 ShowFileScrollPrompt(int n, const DirEntry** options, bool hide_ext, const c
DrawStringF(MAIN_SCREEN, x + item_width - font_width * 11, yopt + ((line_height+2)*(i-scroll)),
(sel == 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);
(options[i]->type == T_DIR) ? STR_DIR : (options[i]->type == T_DOTDOT) ? "(..)" : bytestr);
}
// show [n more]
if (n - n_show - scroll > 0) {
char more_str[UTF_BUFFER_BYTESIZE(item_width / font_width)], temp_str[64];
snprintf(temp_str, 64, " [%d more]", (n - (n_show-1) - scroll));
snprintf(temp_str, 64, 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);
}
@ -1025,7 +1021,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);
@ -1074,7 +1070,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);
@ -1423,12 +1419,12 @@ bool ShowProgress(u64 current, u64 total, const char* opstr)
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, 16, 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;
@ -1441,13 +1437,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
};

View File

@ -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)) {

View File

@ -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:", \

View File

@ -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
}

View File

@ -4,6 +4,7 @@
#include "image.h"
#include "unittype.h"
#include "essentials.h"
#include "language.h"
#include "ui.h"
#include "sdmmc.h"
@ -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, 16, 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,13 +74,13 @@ 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, 16, STR_EMUNAND_LVL_N, lvl);
} else if (drvtype & DRV_GAME) {
perm = PERM_GAME;
snprintf(area_name, 16, "game images");
snprintf(area_name, 16, "%s", STR_GAME_IMAGES);
} else if (drvtype & DRV_CART) {
perm = PERM_CART;
snprintf(area_name, 16, "gamecart saves");
snprintf(area_name, 16, "%s", STR_GAMECART_SAVES);
} else if (drvtype & DRV_VRAM) {
perm = PERM_VRAM;
snprintf(area_name, 16, "vram0");
@ -88,19 +89,19 @@ bool CheckWritePermissions(const char* path) {
snprintf(area_name, 16, "XORpads");
} else if (drvtype & DRV_IMAGE) {
perm = PERM_IMAGE;
snprintf(area_name, 16, "images");
snprintf(area_name, 16, "%s", STR_IMAGES);
} else if (drvtype & DRV_MEMORY) {
perm = PERM_MEMORY;
snprintf(area_name, 16, "memory areas");
snprintf(area_name, 16, "%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, 16, "%s", STR_SD_SYSTEM_DATA);
} else if (drvtype & DRV_SDCARD) {
perm = PERM_SDCARD;
snprintf(area_name, 16, "SD card");
snprintf(area_name, 16, "%s", STR_SD_CARD);
} else if (drvtype & DRV_RAMDRIVE) {
perm = PERM_RAMDRIVE;
snprintf(area_name, 16, "RAM drive");
snprintf(area_name, 16, "%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

View File

@ -11,6 +11,7 @@
#include "ff.h"
#include "ui.h"
#include "swkbd.h"
#include "language.h"
#define SKIP_CUR (1UL<<11)
#define OVERWRITE_CUR (1UL<<12)
@ -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);
}
@ -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;
}
@ -745,7 +745,7 @@ 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);
} else if (osize < dvfile.size) { // if origin is smaller than destination...
@ -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;
}
}
@ -832,7 +832,7 @@ 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;
}
@ -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;
}
}

View File

@ -18,6 +18,7 @@
#include <libgen.h>
#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;
}
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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);
@ -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);
}

View File

@ -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;
}
};

View File

@ -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);

File diff suppressed because it is too large Load Diff

5
arm9/source/language.c Normal file
View File

@ -0,0 +1,5 @@
#define STRING(what, def) const char *STR_##what = def;
#include "language.en.inl"
#undef STRING
// TODO read from file

799
arm9/source/language.en.inl Normal file
View File

@ -0,0 +1,799 @@
STRING(DATE_TIME_FORMAT, "%1$s%2$02lX-%3$02lX-%4$02lX %5$02lX:%6$02lX")
STRING(DECIMAL_SEPARATOR, ".")
STRING(THOUSAND_SEPARATOR, ",")
STRING(FIRM_TOO_BIG, "FIRM too big, can't boot")
STRING(PATH_DO_NOT_BOOT_UNTRUSTED, "%s (%dkB)\nWarning: Do not boot FIRMs\nfrom untrusted sources.\n \nBoot FIRM?")
STRING(NOT_BOOTABLE_FIRM, "Not a bootable FIRM.")
STRING(FIRM_ENCRYPTED, "FIRM is encrypted.\n \nDecrypt before boot?")
STRING(MAKE_COPY_AT_OUT_TEMP_FIRM, "Make a copy at %s/temp.firm")
STRING(TRY_BOOT_ANYWAYS, "Try to boot anyways")
STRING(WARNING_BOOT_UNSUPPORTED_LOCATION, "Warning: Trying to boot from an\nunsupported location.")
STRING(ROOT, "[root]")
STRING(LOADING, "LOADING...")
STRING(PANE_N, "PANE #%lu")
STRING(CURRENT, "CURRENT")
STRING(DIR, "(dir)")
STRING(SD_FAT, "(SD FAT)")
STRING(RAMDRIVE_FAT, "(RAMdrive FAT)")
STRING(GAME_VIRTUAL, "(Game Virtual)")
STRING(SYSNAND_FAT, "(SysNAND FAT)")
STRING(SYSNAND_VIRTUAL, "(SysNAND Virtual)")
STRING(EMUNAND_FAT, "(EmuNAND FAT)")
STRING(EMUNAND_VIRTUAL, "(EmuNAND Virtual)")
STRING(IMAGE_FAT, "(Image FAT)")
STRING(XORPAD_VIRTUAL, "(XORpad Virtual)")
STRING(MEMORY_VIRTUAL, "(Memory Virtual)")
STRING(ALIAS_FAT, "(Alias FAT)")
STRING(GAMECART_VIRTUAL, "(Gamecart Virtual)")
STRING(VRAM_VIRTUAL, "(VRAM Virtual)")
STRING(SEARCH, "(Search)")
STRING(TITLEMANAGER_VIRTUAL, "(TitleManager Virtual)")
STRING(LAB_SDCARD, "SDCARD")
STRING(LAB_SYSNAND_CTRNAND, "SYSNAND CTRNAND")
STRING(LAB_SYSNAND_TWLN, "SYSNAND TWLN")
STRING(LAB_SYSNAND_TWLP, "SYSNAND TWLP")
STRING(LAB_SYSNAND_SD, "SYSNAND SD")
STRING(LAB_SYSNAND_VIRTUAL, "SYSNAND VIRTUAL")
STRING(LAB_EMUNAND_CTRNAND, "EMUNAND CTRNAND")
STRING(LAB_EMUNAND_TWLN, "EMUNAND TWLN")
STRING(LAB_EMUNAND_TWLP, "EMUNAND TWLP")
STRING(LAB_EMUNAND_SD, "EMUNAND SD")
STRING(LAB_EMUNAND_VIRTUAL, "EMUNAND VIRTUAL")
STRING(LAB_IMGNAND_CTRNAND, "IMGNAND CTRNAND")
STRING(LAB_IMGNAND_TWLN, "IMGNAND TWLN")
STRING(LAB_IMGNAND_TWLP, "IMGNAND TWLP")
STRING(LAB_IMGNAND_VIRTUAL, "IMGNAND VIRTUAL")
STRING(LAB_GAMECART, "GAMECART")
STRING(LAB_GAME_IMAGE, "GAME IMAGE")
STRING(LAB_AESKEYDB_IMAGE, "AESKEYDB IMAGE")
STRING(LAB_BDRI_IMAGE, "BDRI IMAGE")
STRING(LAB_DISA_DIFF_IMAGE, "DISA/DIFF IMAGE")
STRING(LAB_MEMORY_VIRTUAL, "MEMORY VIRTUAL")
STRING(LAB_VRAM_VIRTUAL, "VRAM VIRTUAL")
STRING(LAB_TITLE_MANAGER, "TITLE MANAGER")
STRING(LAB_LAST_SEARCH, "LAST SEARCH")
STRING(LAB_FAT_IMAGE, "FAT IMAGE")
STRING(LAB_BONUS_DRIVE, "BONUS DRIVE")
STRING(LAB_RAMDRIVE, "RAMDRIVE")
STRING(LAB_NOLABEL, "NOLABEL")
STRING(N_BYTE, "%s Byte")
STRING(BYTE, " Byte")
STRING(KB, " kB")
STRING(MB, " MB")
STRING(GB, " GB")
STRING(CLIPBOARD, "[CLIPBOARD]")
STRING(PLUS_N_MORE, "+ %lu more")
STRING(MARK_DELETE_COPY, "L - MARK files (use with ↑↓→←)\nX - DELETE / [+R] RENAME file(s)\nY - COPY files / [+R] CREATE entry\n")
STRING(MARK_DELETE_PASTE, "L - MARK files (use with ↑↓→←)\nX - DELETE / [+R] RENAME file(s)\nY - PASTE files / [+R] CREATE entry\n")
STRING(RELOCK_WRITE_PERMISSION, "R+Y - Relock write permissions\n")
STRING(UNMOUNT_IMAGE, "R+X - Unmount image\n")
STRING(UNMOUNT_SD, "R+B - Unmount SD card\n")
STRING(REMOUNT_SD, "R+B - Remount SD card\n")
STRING(DIRECTORY_OPTIONS, "R+A - Directory options\n")
STRING(DRIVE_OPTIONS, "R+A - Drive options\n")
STRING(MAKE_SCREENSHOT, "R+L - Make a Screenshot\n")
STRING(PREV_NEXT_PANE, "R+←→ - Switch to prev/next pane\n")
STRING(CLEAR_CLIPBOARD, "SELECT - Clear Clipboard\n")
STRING(RESTORE_CLIPBOARD, "SELECT - Restore Clipboard\n")
STRING(REBOOT_POWEROFF_HOME, "START - Reboot / [+R] Poweroff\nHOME button for HOME menu")
STRING(NO_EMUNAND, "No EmuNAND")
STRING(REDNAND_SIZE_MIN, "RedNAND size (min)")
STRING(GW_EMUNAND_SIZE_FULL, "GW EmuNAND size (full)")
STRING(MULTINAND_SIZE_2X, "MultiNAND size (2x)")
STRING(MULTINAND_SIZE_3X, "MultiNAND size (3x)")
STRING(MULTINAND_SIZE_4X, "MultiNAND size (4x)")
STRING(USER_INPUT, "User input...")
STRING(AUTO, "Auto")
STRING(16KB_CLUSTERS, "16KB Clusters")
STRING(32KB_CLUSTERS, "32KB Clusters")
STRING(64KB_CLUSTERS, "64KB Clusters")
STRING(SD_NOT_DETECTED, "Error: SD card not detected.")
STRING(FORMAT_SD_CHOOSE_EMUNAND, "Format SD card (%lluMB)?\nChoose EmuNAND size:")
STRING(SD_SIZE_IS_ENTER_EMUNAND_SIZE, "SD card size is %lluMB.\nEnter EmuNAND size (MB) below:")
STRING(FORMAT_SD_CHOOSE_CLUSTER, "Format SD card (%lluMB)?\nChoose cluster size:")
STRING(FORMAT_SD_ENTER_LABEL, "Format SD card (%lluMB)?\nEnter label:")
STRING(FORMAT_SD_FAILED, "Format SD: failed!")
STRING(REDNAND_TYPE, "RedNAND type")
STRING(REDNAND_TYPE_MULTI, "RedNAND type (multi)")
STRING(REDNAND_TYPE_SINGLE, "RedNAND type (single)")
STRING(GW_EMUNAND_TYPE, "GW EmuNAND type")
STRING(DONT_SET_UP, "Don't set up")
STRING(CHOOSE_EMUNAND_TYPE, "Choose EmuNAND type to set up:")
STRING(CLONE_SYSNAND_TO_REDNAND, "Clone SysNAND to RedNAND?")
STRING(CLONING_SYSNAND_TO_EMUNAND_FAILED, "Cloning SysNAND to EmuNAND: failed!")
STRING(PRESS_A_TO_CONTINUE, "Press <A> to continue")
STRING(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")
STRING(NOT_FOUND, "Not found!")
STRING(GO_TO_OFFSET, "Go to offset")
STRING(SEARCH_FOR_STRING, "Search for string")
STRING(SEARCH_FOR_DATA, "Search for data")
STRING(CURRENT_OFFSET_SELECT_ACTION, "Current offset: %08lX\nSelect action:")
STRING(CURRENT_OFFSET_ENTER_NEW, "Current offset: %08lX\nEnter new offset below.")
STRING(ENTER_SEARCH_REPEAT_SEARCH, "Enter search string below.\n(R+X to repeat search)")
STRING(MADE_EDITS_SAVE_CHANGES, "You made edits in %lu place(s).\nWrite changes to file?")
STRING(FAILED_WRITING_TO_FILE, "Failed writing to file!")
STRING(CALCULATING_SHA_FAILED, "Calculating SHA-%s: failed!")
STRING(SHA_VERIFICATION_PASSED, "\nSHA verification: passed!")
STRING(SHA_VERIFICATION_FAILED, "\nSHA verification: failed")
STRING(IDENTICAL_WITH_PREVIOUS, "\n \nIdentical with previous file:\n")
STRING(WRITE_SHA_FILE, "\n \nWrite .SHA file?")
STRING(WRITE_SHA1_FILE, "\n \nWrite .SHA1 file?")
STRING(CALCULATING_CMAC_FAILED, "Calculating CMAC: failed!")
STRING(CMAC_VERIFICATION_PASSED, "CMAC verification: passed!")
STRING(CMAC_VERIFICATION_FAILED, "CMAC verification: failed!")
STRING(FIX_CMAC_IN_FILE, "\n \nFix CMAC in file?")
STRING(FIXING_CMAC_FAILED, "Fixing CMAC: failed!")
STRING(COPY_ALL_SELECTED_ITEMS, "Copy all %lu selected items?")
STRING(FAILED_COPYING_ITEM, "Failed copying item")
STRING(ITEMS_COPIED_TO_OUT, "%lu items copied to %s")
STRING(PATH_COPIED_TO_OUT, "%s\nCopied to %s")
STRING(CART_INIT_FAILED, "Cart init failed!")
STRING(CART_DETECTED_SIZE_INPUT_BELOW, "Cart: %s\nDetected size: %s\n \nInput dump size below.")
STRING(NDS_CART_DECRYPT_SECURE_AREA, "Cart: %s\nNDS cart detected\nDecrypt the secure area?")
STRING(FAILED_DUMPING_CART, "%s\nFailed dumping cart")
STRING(PATH_DUMPED_TO_OUT, "%s\nDumped to %s")
STRING(CREATED, "created")
STRING(MODIFIED, "modified")
STRING(ANALYZING_DRIVE, "Analyzing drive, please wait...")
STRING(ANALYZING_DIR, "Analyzing dir, please wait...")
STRING(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")
STRING(N_FILES_N_SUBDIRS_TOTAL_SIZE, "%lu files & %lu subdirs\n%s total size")
STRING(FILESIZE_X, "filesize: %s")
STRING(READONLY_HIDDEN_SYSTEM_ARCHIVE_VIRTUAL, " \n[%c] %sread-only [%c] %shidden\n[%c] %ssystem [%c] %sarchive\n[%c] %svirtual\n%s")
STRING(UDRL_CHANGE_ATTRIBUTES, " \n(↑↓→← to change attributes)\n")
STRING(A_TO_CONTINUE, "(<A> to continue)")
STRING(A_APPLY_B_CANCEL, "(<A> to apply, <B> to cancel)")
STRING(A_YES_B_NO, "(<A> yes, <B> no)")
STRING(A_SELECT_B_CANCEL, "(<A> select, <B> cancel)")
STRING(HOLD_B_TO_CANCEL, "(hold B to cancel)")
STRING(FAILED_TO_SET_ATTRIBUTES, "Failed to set attributes!")
STRING(NAND_IMAGE_OPTIONS, "NAND image options...")
STRING(CTRNAND_OPTIONS, "CTRNAND options...")
STRING(MOUNT_FAT_IMAGE, "Mount as FAT image")
STRING(CIA_IMAGE_OPTIONS, "CIA image options...")
STRING(NCSD_IMAGE_OPTIONS, "NCSD image options...")
STRING(NCCH_IMAGE_OPTIONS, "NCCH image options...")
STRING(MOUNT_AS_EXEFS_IMAGE, "Mount as EXEFS image")
STRING(MOUNT_AS_ROMFS_IMAGE, "Mount as ROMFS image")
STRING(TMD_FILE_OPTIONS, "TMD file options...")
STRING(TMD_CDN_OPTIONS, "TMD/CDN options...")
STRING(TMD_TWL_OPTIONS, "TMD/TWL options...")
STRING(MANAGE_TITLE, "Manage Title...")
STRING(BOSS_FILE_OPTIONS, "BOSS file options...")
STRING(DECRYPT_NUS_CDN_FILE, "Decrypt NUS/CDN file")
STRING(SHOW_SMDH_TITLE_INFO, "Show SMDH title info")
STRING(NDS_IMAGE_OPTIONS, "NDS image options...")
STRING(GBA_IMAGE_OPTIONS, "GBA image options...")
STRING(TICKET_OPTIONS, "Ticket options...")
STRING(TAD_IMAGE_OPTIONS, "TAD image options...")
STRING(SHOW_3DSX_TITLE_INFO, "Show 3DSX title info")
STRING(FIRM_IMAGE_OPTIONS, "FIRM image options...")
STRING(AGBSAVE_OPTIONS, "AGBSAVE options...")
STRING(DUMP_GBA_VC_SAVE, "Dump GBA VC save")
STRING(TICKET_DB_OPTIONS, "Ticket.db options...")
STRING(MOUNT_AS_DIFF_IMAGE, "Mount as DIFF image")
STRING(MOUNT_AS_DISA_IAMGE, "Mount as DISA image")
STRING(INSTALL_CIFINISH_BIN, "Install cifinish.bin")
STRING(TITLEKEY_OPTIONS, "Titlekey options...")
STRING(AESKEYDB_OPTIONS, "AESkeydb options...")
STRING(BUILD_X, "Build %s")
STRING(NCCHINFO_OPTIONS, "NCCHinfo options...")
STRING(EXECUTE_GM9_SCRIPT, "Execute GM9 script")
STRING(FONT_OPTIONS, "Font options...")
STRING(VIEW_PNG_FILE, "View PNG file")
STRING(REBUILD_NCSD_HEADER, "Rebuild NCSD header")
STRING(SHOW_IN_HEXEDITOR, "Show in Hexeditor")
STRING(CALCULATE_SHA256, "Calculate SHA-256")
STRING(CALCULATE_SHA1, "Calculate SHA-1")
STRING(SHOW_FILE_INFO, "Show file info")
STRING(SHOW_IN_TEXTVIEWER, "Show in Textviewer")
STRING(CALCULATE_CMAC, "Calculate CMAC")
STRING(COPY_TO_OUT, "Copy to %s")
STRING(DUMP_TO_OUT, "Dump to %s")
STRING(INJECT_DATA_AT_OFFSET, "Inject data @offset")
STRING(OPEN_THIS_FOLDER, "Open this folder")
STRING(OPEN_CONTAINING_FOLDER, "Open containing folder")
STRING(OPEN_TITLE_FOLDER, "Open title folder")
STRING(PATH_N_FILES_SELECTED, "%s\n(%lu files selected)")
STRING(CHECK_CURRENT_CMAC_ONLY, "Check current CMAC only")
STRING(VERIFY_CMAC_FOR_ALL, "Verify CMAC for all")
STRING(FIX_CMAC_FOR_ALL, "Fix CMAC for all")
STRING(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")
STRING(N_OF_N_FILES_VERIFIED_N_OF_N_FILES_FIXED, "%lu/%lu files verified ok\n%lu/%lu files fixed")
STRING(N_OF_N_FILES_VERIFIED_N_OF_N_HAVE_NO_CMAC, "%lu/%lu files verified ok\n%lu/%lu have no CMAC")
STRING(N_OF_N_FILES_VERIFIED, "%lu/%lu files verified ok")
STRING(INJECT_DATA_FROM_SPECIFY_OFFSET_BELOW, "Inject data from %s?\nSpecify offset below.")
STRING(FAILED_INJECTING_PATH, "Failed injecting %s")
STRING(MOUNT_CXI_NDS_TO_DRIVE, "Mount CXI/NDS to drive")
STRING(MOUNT_IMAGE_TO_DRIVE, "Mount image to drive")
STRING(RESTORE_SYSNAND_SAFE, "Restore SysNAND (safe)")
STRING(UPDATE_EMBEDDED_BACKUP, "Update embedded backup")
STRING(SHOW_TITLE_INFO, "Show title info")
STRING(DECRYPT_FILE, "Decrypt file (...)")
STRING(DECRYPT_FILE_OUT, "Decrypt file (%s)")
STRING(ENCRYPT_FILE, "Encrypt file (...)")
STRING(ENCRYPT_FILE_OUT, "Encrypt file (%s)")
STRING(BUILD_CIA_FROM_FILE, "Build CIA from file")
STRING(BUILD_CIA_STANDARD, "Build CIA (standard)")
STRING(BUILD_CIA_LEGIT, "Build CIA (legit)")
STRING(DUMP_CXI_NDS_FILE, "Dump CXI/NDS file")
STRING(INSTALL_GAME_IMAGE, "Install game image")
STRING(INSTALL_TICKET, "Install ticket")
STRING(DUMP_TICKET_FILE, "Dump ticket file")
STRING(UNINSTALL_TITLE, "Uninstall title")
STRING(VERIFY_FILE, "Verify file")
STRING(TRANSFER_IMAGE_TO_CTRNAND, "Transfer image to CTRNAND")
STRING(INJECT_TO_H_AND_S, "Inject to H&S")
STRING(TRIM_FILE, "Trim file")
STRING(RENAME_FILE, "Rename file")
STRING(BUILD_XORPADS_SD, "Build XORpads (SD output)")
STRING(BUILD_XORPADS_INPLACE, "Build XORpads (inplace)")
STRING(EXTRACT_X, "Extract %s")
STRING(INIT_X, "Init %s")
STRING(INSTALL_X, "Install %s")
STRING(INSTALL_FIRM, "Install FIRM")
STRING(BOOT_FIRM, "Boot FIRM")
STRING(SET_AS_ACTIVE_FONT, "Set as active font")
STRING(DUMP_BA_VC_SAVE, "Dump GBA VC save")
STRING(INJECT_GBA_VC_SAVE, "Inject GBA VC save")
STRING(SET_AS_DEFAULT, "Set as default")
STRING(MOUNTING_IMAGE_FAILED, "Mounting image: failed")
STRING(PATH_MOUNTED_AS_DRIVE_ENTER_PATH_NOW, "%s\nMounted as drive %s\nEnter path now?")
STRING(DECRYPT_TO_OUT, "Decrypt to %s")
STRING(DECRYPT_INPLACE, "Decrypt inplace")
STRING(TRY_TO_DECRYPT_ALL_N_SELECTED_FILES, "Try to decrypt all %lu selected files?")
STRING(TRYING_TO_DECRYPT_N_FILES, "Trying to decrypt %lu files...")
STRING(DECRYPTION_FAILED_CONTINUE, "Decryption failed\n \nContinue?")
STRING(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")
STRING(N_OF_N_FILES_DECRYPTED, "%lu/%lu files decrypted ok")
STRING(N_FILES_WRITTEN_TO_OUT, "%lu files written to %s")
STRING(FILE_NOT_ENCRYPTED, "File is not encrypted")
STRING(DECRYPTION_SUCCESS, "Decryption success")
STRING(DECRYPTION_FAILED, "Decryption failed")
STRING(PATH_DECRYPTED_TO_OUT, "%s\nDecrypted to %s")
STRING(ENCRYPT_TO_OUT, "Encrypt to %s")
STRING(ENCRYPT_INPLACE, "Encrypt inplace")
STRING(TRY_TO_ENCRYPT_N_SELECTED_FILES, "Try to encrypt all %lu selected files?")
STRING(TRYING_TO_ENCRYPT_N_FILES, "Trying to encrypt %lu files...")
STRING(ENCRYPTION_FAILED_CONTINUE, "Encryption failed\n \nContinue?")
STRING(N_OF_N_FILES_ENCRYPTED_N_OF_N_NOT_SAME_TYPE, "%lu/%lu files encrypted ok\n%lu/%lu not of same type")
STRING(N_OF_N_FILES_ENCRYPTED, "%lu/%lu files encrypted ok")
STRING(ENCRYPTION_SUCCESS, "Encryption success")
STRING(ENCRYPTION_FAILED, "Encryption failed")
STRING(PATH_ENCRYPTED_TO_OUT, "%s\nEncrypted to %s")
STRING(TRY_TO_PROCESS_N_SELECTED_FILES, "Try to process all %lu selected files?")
STRING(PATH_BUILD_TYPE_FAILED_CONTINUE, "%s\nBuild %s failed\n \nContinue?")
STRING(N_OF_N_TYPES_BUILT_N_OF_N_NOT_SAME_TYPE, "%lu/%lu %ss built ok\n%lu/%lu not of same type")
STRING(N_OF_N_TYPES_BUILT, "%lu/%lu %ss built ok")
STRING(N_FILES_FAILED_CONVERTION_VERIFICATION_RECOMMENDED, "%lu file(s) failed conversion.\nVerification is recommended.")
STRING(PATH_TYPE_BUILT_TO_OUT, "%s\n%s built to %s")
STRING(PATH_TYPE_BUILD_FAILED, "%s\n%s build failed")
STRING(FILE_FAILED_CONVERSION_VERIFY_NOW, "file failed conversion.\n \nVerify now?")
STRING(VERIFICATION_SUCCESS, "Verification success")
STRING(VERIFICATION_FAILED, "Verification failed")
STRING(CONTENT_IS_MISSING, "Content is missing")
STRING(INSTALL_TO_SYSNAND, "Install to SysNAND")
STRING(INSTALL_TO_EMUNAND, "Install to EmuNAND")
STRING(TRY_TO_INSTALL_N_SELECTED_FILES, "Try to install all %lu selected files?")
STRING(TRYING_TO_INSTALL_N_FILES, "Trying to install %lu files...")
STRING(INSTALL_FAILED_CONTINUE, "Install failed\n \nContinue?")
STRING(N_OF_N_FILES_INSTALLED_N_OF_N_NOT_SAME_TYPE, "%lu/%lu files installed ok\n%lu/%lu not of same type")
STRING(N_OF_N_FILES_INSTALLED, "%lu/%lu files installed ok")
STRING(INSTALL_SUCCESS, "Install success")
STRING(INSTALL_FAILED, "Install failed")
STRING(FILE_FAILED_INSTALL_VERIFY_NOW, "file failed install.\n \nVerify now?")
STRING(KEEP_TICKET_AND_SAVEGAME, "Keep ticket & savegame")
STRING(UNINSTALL_EVERYTHING, "Uninstall everything")
STRING(ABORT_UNINSTALL, "Abort uninstall")
STRING(UNINSTALL_N_SELECTED_TITLES, "Uninstall %lu selected titles?")
STRING(UNINSTALL_SELECTED_TITLE, "Uninstall selected title?")
STRING(N_OF_N_TITLES_UNINSTALLED, "%lu/%lu titles uninstalled")
STRING(UNINSTALLING_PLEASE_WAIT, "Uninstalling, please wait...")
STRING(UNINSTALL_FAILED, "Uninstall failed!")
STRING(TRY_TO_VERIFY_N_SELECTED_FILES, "Try to verify all %lu selected files?")
STRING(VERIFICATION_FAILED_CONTINUE, "Verification failed\n \nContinue?")
STRING(N_OF_N_FILES_VERIFIED_N_OF_N_NOT_SAME_TYPE, "%lu/%lu files verified ok\n%lu/%lu not of same type")
STRING(VERIFYING_FILE_PLEASE_WAIT, "Verifying file, please wait...")
STRING(NAND_VALIDATION_SUCCESS, "NAND validation success")
STRING(NAND_VALIDATION_FAILED, "NAND validation failed")
STRING(DUMP_FOR_N_SELECTED_FILES, "Dump for all %lu selected files?")
STRING(N_OF_N_LEGIT_TICKETS_DUMPED_ATTEMPT_DUMP_ALL, "%lu/%lu legit tickets dumped.\n \nAttempt to dump all tickets?")
STRING(N_OF_N_TICKETS_DUMPED_TO_OUT, "%lu/%lu tickets dumped to %s")
STRING(PATH_TICKET_DUMPED_TO_OUT, "%s\nTicket dumped to %s")
STRING(LEGIT_TICKET_NOT_FOUND_DUMP_ANYWAYS, "%s\nLegit ticket not found.\n \nDump anyways?")
STRING(DUMP_TICKET_FAILED, "Dump ticket failed!")
STRING(BUILDING_X, "Building %s...")
STRING(BUILDING_X_SYSNAND, "Building %s (SysNAND)...")
STRING(BUILDING_X_EMUNAND, "Building %s (EmuNAND)...")
STRING(PATH_N_OF_N_FILES_PROCESSED_N_OF_N_FILES_IGNORED, "%s\n%lu/%lu files processed\n%lu/%lu files ignored")
STRING(PATH_N_OF_N_FILES_PROCESSED, "%s\n%lu/%lu files processed")
STRING(BUILD_DATABASE_SUCCESS, "Build database success.")
STRING(BUILD_DATABASE_FAILED, "Build database failed.")
STRING(TRY_TO_TRIM_N_SELECTED_FILES, "Try to trim all %lu selected files?")
STRING(TRIMMING_FAILED_CONTINUE, "Trimming failed\n \nContinue?")
STRING(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")
STRING(N_OF_N_FILES_TRIMMED_X_SAVED, "%lu/%lu files trimmed ok\n%s saved")
STRING(FILE_CANT_BE_TRIMMED, "File can't be trimmed.")
STRING(FILE_ALREADY_TRIMMED, "File is already trimmed.")
STRING(PATH_CURRENT_SIZE_TRIMMED_SIZE_DIFFERENCE_TRIM_FILE, "%s\nCurrent size: %s\nTrimmed size: %s\nDifference: %s\n \nTrim this file?")
STRING(TRIMMING_FAILED, "Trimming failed.")
STRING(PATH_TRIMMED_BY_X, "%s\nTrimmed by %s.")
STRING(TRY_TO_RENAME_N_SELECTED_FILES, "Try to rename all %lu selected files?")
STRING(N_OF_N_RENAMED, "%lu/%lu renamed ok")
STRING(COULD_NOT_RENAME_TO_GOOD_NAME, "Could not rename to good name")
STRING(SYSNAND_H_AND_S_INJECT, "SysNAND H&S inject")
STRING(EMUNAND_H_AND_S_INJECT, "EmuNAND H&S inject")
STRING(H_AND_S_INJECT_SUCCESS, "H&S inject success")
STRING(H_AND_S_INJECT_FAILURE, "H&S inject failure")
STRING(TRY_EXTRACT_ALL_N_SELECTED_FILES, "Try to extract all %lu selected files?")
STRING(N_OF_N_FILES_EXTRACTED_N_OF_N_NOT_SAME_TYPE, "%lu/%lu files extracted ok\n%lu/%lu not of same type")
STRING(N_OF_N_FILES_EXTRACTED, "%lu/%lu files extracted ok")
STRING(EXTRACTING_DOT_CODE, "Extracting .code, please wait...")
STRING(PATH_EXT_EXTRACTED_TO_OUT, "%s\n%s extracted to %s")
STRING(DOT_CODE_EXTRACT_FAILED, ".code extract failed")
STRING(TRANSFER_TO_SYSNAND, "Transfer to SysNAND")
STRING(TRANSFER_TO_EMUNAND, "Transfer to EmuNAND")
STRING(CTRNAND_TRANSFER_SUCCESS, "CTRNAND transfer success")
STRING(CTRNAND_TRANSFER_FAILED, "CTRNAND transfer failed")
STRING(NO_VALID_DESTINATION_FOUND, "No valid destination found")
STRING(NAND_RESTORE_SUCCESS, "NAND restore success")
STRING(NAND_RESTORE_FAILED, "NAND restore failed")
STRING(REBUILD_NCSD_SUCCESS, "Rebuild NCSD success")
STRING(REBUILD_NCSD_FAILED, "Rebuild NCSD failed")
STRING(PATH_NCCHINFO_PADGEN_SUCCESS, "%s\nNCCHinfo padgen success%cOutput dir: %s")
STRING(PATH_NCCHINFO_PADGEN_FAILED, "%s\nNCCHinfo padgen failed%c%0.0s")
STRING(UPDATING_EMBEDDED_BACKUP, "Updating embedded backup...")
STRING(BACKUP_UPDATE_NOT_REQUIRED, "Backup update: not required")
STRING(BACKUP_UPDATE_COMPLETED, "Backup update: completed")
STRING(BACKUP_UPDATE_FAILED, "Backup update: failed!")
STRING(WARNING_KEYS_NOT_VERIFIED_CONTINUE_AT_YOUR_OWN_RISK, "Warning: Keys are not verified.\nContinue on your own risk?")
STRING(AESKEYDB_INIT_SUCCESS, "AESkeydb init success")
STRING(AESKEYDB_INIT_FAILED, "AESkeydb init failed")
STRING(AESKEYDB_INSTALL_SUCCESS, "AESkeydb install success")
STRING(AESKEYDB_INSTALL_FAILED, "AESkeydb install failed")
STRING(INSTALL_TO_FIRM0, "Install to FIRM0")
STRING(INSTALL_TO_FIRM1, "Install to FIRM1")
STRING(INSTALL_TO_BOTH, "Install to both")
STRING(PATH_N_KB_INSTALL_TO_SYSNAND, "%s (%dkB)\nInstall to SysNAND?")
STRING(PATH_N_KB_INSTALL_SUCCESS, "%s (%dkB)\nInstall success")
STRING(PATH_N_KB_INSTALL_FAILED, "%s (%dkB)\nInstall failed")
STRING(WARNING_DO_NOT_RUN_UNTRUSTED_SCRIPTS, "Warning: Do not run scripts\nfrom untrusted sources.\n \nExecute script?")
STRING(SCRIPT_EXECUTE_SUCCESS, "Script execute success")
STRING(SCRIPT_EXECUTE_FAILURE, "Script execute failure")
STRING(ERROR_CANNOT_VIEW_FILE, "Error: Cannot view file\n(Hint: maybe it's too big)")
STRING(SAVEGAME_DUMPED_TO_OUT, "Savegame dumped to %s.")
STRING(SAVEGAME_DUMP_FAILED, "Savegame dump failed!")
STRING(GBA_SAVEGAME_MUST_BE_IN_CLIPBOARD, "GBA VC savegame has to\nbe in the clipboard.")
STRING(SAVEGAME_INJECT_SUCCESS, "Savegame inject success.")
STRING(SAVEGAME_INJECT_FAILED, "Savegame inject failed!")
STRING(FONT_WILL_BE_ACTIVE_ON_NEXT_BOOT, "Font will be active on next boot")
STRING(HOME_MORE_MENU_SELECT_ACTION, "HOME more... menu.\nSelect action:")
STRING(SD_FORMAT_MENU, "SD format menu")
STRING(BONUS_DRIVE_MENU, "Bonus drive setup")
STRING(SWITCH_EMUNAND, "Switch EmuNAND")
STRING(BUILD_SUPPORT_FILES, "Build support files")
STRING(RESTORE_H_AND_S, "Restore H&S")
STRING(SET_RTC_DATE_TIME, "Set RTC date&time")
STRING(CONFGURE_BRIGHTNESS, "Configure brightness")
STRING(CALIBRATE_TOUCHSCREEN, "Calibrate touchscreen")
STRING(SYSTEM_INFO, "System info")
STRING(SHOW_README, "Show ReadMe")
STRING(INITIALIZING_SD_FAILED_RETRY, "Initializing SD card failed! Retry?")
STRING(SETUP_FAILED, "Setup failed!")
STRING(CURRENT_EMUNAND_OFFSET_IS_N_SWITCH_TO_NEXT, "Current EmuNAND offset is %06lX.\nSwitch to next offset?")
STRING(BUILT_IN_OUT_STATUSES, "Built in %s:\n \n%-18.18s %s\n%-18.18s %s\n%-18.18s %s")
STRING(OK_SYS_EMU, "OK (Sys&Emu)")
STRING(OK_SYS, "OK (Sys)")
STRING(FAILED, "Failed")
STRING(RESTORE_H_AND_S_EMUNAND, "Restore H&S (EmuNAND)")
STRING(RESTORE_H_AND_S_SYSNAND, "Restore H&S (SysNAND)")
STRING(TITLE_SET_RTC_DATE_TIME, "Set RTC date&time:")
STRING(NEW_RTC_DATE_TIME_IS_TIME, "New RTC date&time is:\n%s\n \nHint: HOMEMENU time needs\nmanual adjustment after\nsetting the RTC.")
STRING(TOUCHSCREEN_CALIBRATION_SUCCESS, "Touchscreen calibration success!")
STRING(TOUCHSCREEN_CALIBRATION_FAILED, "Touchscreen calibration failed!")
STRING(GODMODE9_README_TOC, "GodMode9 ReadMe Table of Contents")
STRING(ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW, "Essential files backup not found.\nCreate one now?")
STRING(BACKUP_EMBEDDED_WRITTEN_TO_OUT, "Backup embedded in SysNAND\nand written to %s.")
STRING(RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW, "RTC date&time seems to be\nwrong. Set it now?")
STRING(RESUME_GODMODE9, "Resume GodMode9")
STRING(RESUME_BOOTLOADER, "Resume bootloader")
STRING(SELECT_PAYLOAD, "Select payload...")
STRING(SELECT_SCRIPT, "Select script...")
STRING(POWEROFF_SYSTEM, "Poweroff system")
STRING(REBOOT_SYSTEM, "Reboot system")
STRING(FLAVOR_BOOTLOADER_SELECT_OPTION, "%s bootloader menu.\nSelect action:")
STRING(BOOTLOADER_PAYLOADS_MENU_SELECT_PAYLOAD, "Bootloader payloads menu.\nSelect payload:")
STRING(BOOTLOADER_SCRIPTS_MENU_SELECT_SCRIPT, "Bootloader scripts menu.\nSelect script:")
STRING(NO_BOOTABLE_FIRM_FOUND_RESUMING_GODMODE9, "No bootable FIRM found.\nNow resuming GodMode9...")
STRING(OUT_OF_MEMORY, "Out of memory.")
STRING(INVALID_DIRECTORY_OBJECT, "Invalid directory object")
STRING(INVALID_ROOT_DIRECTORY, "Invalid root directory.")
STRING(WRITE_PERMISSIONS_WERE_CHANGED_RELOCK, "Write permissions were changed.\nRelock them?")
STRING(OPEN_TITLE_MANAGER, "Open title manager")
STRING(SEARCH_FOR_FILES, "Search for files...")
STRING(FIX_CMACS_FOR_DRIVE, "Fix CMACs for drive")
STRING(SHOW_DIRECTORY_INFO, "Show directory info")
STRING(SHOW_DRIVE_INFO, "Show drive info")
STRING(FAILED_SETTING_UP_TITLE_MANAGER, "Failed setting up title manager!")
STRING(SEARCH_FILE_ENTER_SEARCH_BELOW, "Search %s?\nEnter search below.")
STRING(FOUND_N_RESULTS, "Found %lu results.")
STRING(FIX_CMACS_FOR_DRIVE_FINISHED, "Fix CMACs for drive finished.")
STRING(FAILED_TO_ANALYZE_DRIVE, "Failed to analyze drive\n")
STRING(FAILED_TO_ANALYZE_DIR, "Failed to analyze dir\n")
STRING(NOT_ALLOWED_IN_VIRTUAL_PATH, "Not allowed in virtual path")
STRING(DELETE_N_PATHS, "Delete %lu path(s)?")
STRING(DELETING_FILES_PLEASE_WAIT, "Deleting files, please wait...")
STRING(FAILED_DELETING_N_OF_N_PATHS, "Failed deleting %lu/%lu path(s)")
STRING(DELETE_FILE, "Delete \"%s\"?")
STRING(FAILED_DELETING_PATH, "Failed deleting:\n%s")
STRING(NOT_ALLOWED_IN_SEARCH_DRIVE, "Not allowed in search drive")
STRING(NOT_ALLOWED_IN_VIRTUAL_GAME_PATH, "Not allowed in virtual game path")
STRING(NOT_ALLOWED_IN_XORPAD_DRIVE, "Not allowed in XORpad drive")
STRING(NOT_ALLOWED_IN_GAMECART_DRIVE, "Not allowed in gamecart drive")
STRING(NOT_ALLOWED_IN_ALIAS_PATH, "Not allowed in alias path")
STRING(COPY_PATHS, "Copy path(s)")
STRING(MOVE_PATHS, "Move path(s)")
STRING(PASTE_FILE_HERE, "Paste \"%s\" here?")
STRING(PASTE_N_PATHS_HERE, "Paste %lu paths here?")
STRING(FAILED_COPYING_PATH_PROCESS_REMAINING, "Failed copying path:\n%s\nProcess remaining?")
STRING(FAILED_COPYING_PATH, "Failed copying path:\n%s")
STRING(FAILED_MOVING_PATH_PROCESS_REMAINING, "Failed moving path:\n%s\nProcess remaining?")
STRING(FAILED_MOVING_PATH, "Failed moving path:\n%s")
STRING(RENAME_FILE_ENTER_NEW_NAME_BELOW, "Rename %s?\nEnter new name below.")
STRING(FAILED_RENAMING_PATH, "Failed renaming path:\n%s")
STRING(CREATE_A_NEW_ENTRY_HERE_SELECT_TYPE, "Create a new entry here?\nSelect type.")
STRING(CREATE_A_FOLDER, "Create a folder")
STRING(CREATE_A_DUMMY_FILE, "Create a dummy file")
STRING(CREATE_NEW_FOLDER_HERE_ENTER_NAME_BELOW, "Create a new folder here?\nEnter name below.")
STRING(CREATE_NEW_FILE_HERE_ENTER_NAME_BELOW, "Create a new file here?\nEnter name below.")
STRING(CREATE_NEW_FILE_HERE_ENTER_SIZE_BELOW, "Create a new %s here?\nEnter file size below.")
STRING(FAILED_CREATING_FOLDER_PATH, "Failed creating folder:\n%s")
STRING(FAILED_CREATING_FILE_PATH, "Failed creating file:\n%s")
STRING(TITLE_MANAGER, "Title manager")
STRING(BRICK_MY_3DS, "Brick my 3DS")
STRING(SCRIPTS, "Scripts...")
STRING(PAYLOADS, "Payloads...")
STRING(MORE, "More...")
STRING(BRACKET_MORE, "[more...]")
STRING(HOME_BUTTON_PRESSED_SELECT_ACTION, "HOME button pressed.\nSelect action:")
STRING(POWER_BUTTON_PRESSED_SELECT_ACTION, "POWER button pressed.\nSelect action:")
STRING(1_DRIVE_NAND_TWL, "[1:] NAND / TWL")
STRING(4_DRIVE_NAND_TWL, "[4:] NAND / TWL")
STRING(A_DRIVE_SD_CARD, "[A:] SD CARD")
STRING(B_DRIVE_SD_CARD, "[B:] SD CARD")
STRING(TITLE_MANAGER_MENU_SELECT_TITLES_SOURCE, "Title manager menu.\nSelect titles source:")
STRING(SCRIPTS_DIRECTORY_NOT_FOUND, "Scripts directory not found.\n(default path: 0:/gm9/%s)")
STRING(HOME_SCRIPTS_MENU_SELECT_SCRIPT, "HOME scripts... menu.\nSelect script:")
STRING(PAYLOADS_DIRECTORY_NOT_FOUND, "Payloads directory not found.\n(default path: 0:/gm9/%s)")
STRING(HOME_PAYLOADS_MENU_SELECT_PAYLOAD, "HOME payloads... menu.\nSelect payload:")
STRING(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.")
STRING(FLAVOR_SCRIPTS_MENU_SELECT_SCRIPT, "%s scripts menu.\nSelect script:")
STRING(COMPILED_AS_SCRIPT_AUTORUNNER_BUT_NO_SCRIPT_DERP, "Compiled as script autorunner\nbut no script provided.\n \nDerp!")
STRING(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")
STRING(TOUCH_CROSSHAIRS_TO_CALIBRATE_TOUCHSCREEN_USE_STYLUS, "Touch the red crosshairs to\ncalibrate your touchscreen.\n \nUse the stylus for best\nresults!")
STRING(INVALID, "INVALID")
STRING(TO_PROCEED_ENTER_THIS, "To proceed, enter this:")
STRING(TO_PROCEED_HOLD_X, "To proceed, hold <X>:")
STRING(N_MORE, " [%d more]")
STRING(CANCEL, "cancel")
STRING(R_FAST_SCROLL_L_CLEAR_DATA, "R - (↑↓) fast scroll\nL - clear data")
STRING(X_REMOVE_CHAR_Y_INSERT_CHAR, "X - remove char\nY - insert char")
STRING(ETA_N_MIN_N_SEC, "ETA %02llum%02llus")
STRING(BRIGHTNESS_CONTROLS, "[←] Decrease brightness\n[→] Increase brightness\n \n[X] Use volume slider control\n[A] Set current brightness\n[B] Cancel")
STRING(SEARCHING_PLEASE_WAIT, "Searching, please wait...")
STRING(RENAME_TO_GOOD_NAME, "Rename to good name?")
STRING(SD_WRITE_PROTECTED_CANT_CONTINUE, "SD card is write protected!\nCan't continue.")
STRING(SYSNAND_LVL_N, "SysNAND (lvl%lu)")
STRING(EMUNAND_LVL_N, "EmuNAND (lvl%lu)")
STRING(GAME_IMAGES, "game images")
STRING(GAMECART_SAVES, "gamecart saves")
STRING(IMAGES, "images")
STRING(MEMORY_AREAS, "memory areas")
STRING(SD_SYSTEM_DATA, "SD system data")
STRING(SD_CARD, "SD card")
STRING(RAM_DRIVE, "RAM drive")
STRING(WRITING_TO_DRIVE_IS_LOCKED_UNLOCK_NOW, "Writing to %s is locked!\nUnlock it now?")
STRING(UNLOCK_WRITE_FOR_DRIVE_NOT_ALLOWED, "Unlock write permission for\n%s is not allowed.")
STRING(ENABLE_BASE_WRITE, "You want to enable base\nwriting permissions.")
STRING(ENABLE_SD_WRITE, "You want to enable SD card\nwriting permissions.")
STRING(ENABLE_IMAGE_WRITE, "You want to enable image\nwriting permissions.")
STRING(ENABLE_RAM_DRIVE_WRITE, "You want to enable RAM drive\nwriting permissions.")
STRING(ENABLE_EMUNAND_0_WRITE, "You want to enable EmuNAND\nlvl0 writing permissions.")
STRING(ENABLE_SYSNAND_0_WRITE, "You want to enable SysNAND\nlvl0 writing permissions.")
STRING(ENABLE_EMUNAND_1_WRITE, "You want to enable EmuNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nrecoverable system data,\nuser data & savegames.")
STRING(ENABLE_SYSNAND_1_WRITE, "You want to enable SysNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nsystem data, installations,\nuser data & savegames.")
STRING(ENABLE_GAMECART_SAVE_WRITE, "You want to enable gamecart\nsave writing permissions.")
STRING(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!")
STRING(ENABLE_MEMORY_WRITE, "!Better be careful!\n \nYou want to enable memory\nwriting permissions.\n \nWriting to certain areas may\nlead to unexpected results.")
STRING(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.")
STRING(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!")
STRING(UNLOCK_WRITE_NOT_ALLOWED, "Unlock write permission is not allowed.")
STRING(CANT_UNLOCK_WRITE_TRY_GODMODE9, "Can't unlock write permission.\nTry GodMode9 instead!")
STRING(ERROR_SD_TOO_SMALL, "Error: SD card is too small")
STRING(WARNING_PROCEEDING_WILL_FORMAT_SD_DELETE_ALL_DATA, "!WARNING!\n \nProceeding will format this SD.\nThis will irreversibly delete\nALL data on it.")
STRING(FORMAT_BONUS_DRIVE_DELETE_ALL_DATA, "Format the bonus drive?\nThis will irreversibly delete\nALL data on it.")
STRING(FORMATTING_SD_PLEASE_WAIT, "Formatting SD, please wait...")
STRING(FORMATTING_DRIVE_PLEASE_WAIT, "Formatting drive, please wait...")
STRING(ERROR_SD_CARD_IO_FAILURE, "Error: SD card i/o failure")
STRING(FILE_IS_MOUNTED_UNMOUNT_TO_UNLOCK, "File is currently mounted.\nUnmount to unlock?")
STRING(ERROR_CANT_INJECT_FILE_INTO_ITSELF, "Error: Can't inject file into itself")
STRING(OPERATION_WOULD_WRITE_BEYOND_EOF, "Operation would write beyond end of file")
STRING(NOT_ENOUGH_DATA_IN_FILE, "Not enough data in file")
STRING(CANCEL_IS_NOT_ALLOWED_HERE, "Cancel is not allowed here")
STRING(B_DETECTED_CANCEL, "B button detected. Cancel?")
STRING(ERROR_CANNOT_APPEND_FOLDER, "Error: Cannot append a folder")
STRING(ERROR_OVERWRITING_FILE_WITH_DIR, "Error: Overwriting file with dir")
STRING(ERROR_OVERWRITING_DIR_WITH_FILE, "Error: Overwriting dir with file")
STRING(ERROR_CANNOT_OPEN_DESTINATION_FILE, "Error: Cannot open destination file")
STRING(ERROR_NOT_ENOUGH_SPACE_AVAILABLE, "Error: Not enough space available")
STRING(ERROR_ONLY_FAT_FILES_CAN_BE_MOVED, "Error: Only FAT files can be moved")
STRING(ERROR_DESTINATION_IS_PART_OF_ORIGIN, "Error: Destination is part of origin")
STRING(ERROR_DESTINATION_EQUALS_ORIGIN_CHOOSE_ANOTHER_NAME, "Destination equals origin\nChoose another name?")
STRING(CHOOSE_NEW_NAME, "Choose new name")
STRING(OVERWRITE_FILES, "Overwrite file(s)")
STRING(SKIP_FILES, "Skip file(s)")
STRING(OVERWRITE_ALL, "Overwrite all")
STRING(SKIP_ALL, "Skip all")
STRING(DESTINATION_ALREADY_EXISTS, "Destination already exists:\n%s")
STRING(CHOOSE_NEW_DESTINATION_NAME, "Choose new destination name")
STRING(COPY_OPERATION_IS_NOT_ALLOWED, "Copy operation is not allowed")
STRING(DESTINATION_EQUALS_ORIGIN, "Destination equals origin")
STRING(ENTRY_NOT_FOUND_PATH_INJECT_INTO_PATH_INSTEAD, "Entry not found: %s\nInject into %s instead?")
STRING(FILE_SMALLER_THAN_SPACE_SIZES_CONTINUE, "File smaller than available space:\n%s (%s)\n%s (%s)\nContinue?")
STRING(NO_USABLE_ENTRIES_FOUND, "No usable entries found.")
STRING(BEAT_NO_ERROR, "No error")
STRING(BEAT_END_OF_ACTION_LIST, "End of action list")
STRING(BEAT_ABORTED_BY_USER, "Aborted by user")
STRING(BEAT_FAILED_TO_READ_WRITE_FILE, "Failed to read/write file")
STRING(BEAT_ATTEMPTED_TO_WRITE_BEYOND_EOF, "Attempted to write beyond end of file")
STRING(BEAT_INVALID_PATCH_FILE, "Invalid patch file")
STRING(BEAT_INVALID_INPUT_FILE, "Invalid input file")
STRING(BEAT_OUTPUT_FILE_CHECKSUM_MISMATCH, "Output file checksum mismatch")
STRING(BEAT_FILE_CHECKSUM_FAILED, "File checksum failed")
STRING(BEAT_EXPECTED_MORE_PATCH_DATA, "Expected more patch data")
STRING(BEAT_OUT_OF_MEMORY, "Out of memory")
STRING(BEAT_UNKNOWN_ERROR, "Unknown error")
STRING(FAILED_TO_INITIALIZE_BPM_FILE, "Failed to initialize BPM file:\n%s")
STRING(FAILED_TO_INITIALIZE_BPS_FILE, "Failed to initialize BPS file:\n%s")
STRING(PATCH_SUCCESSFULLY_APPLIED, "Patch successfully applied")
STRING(PATCHING_ABORTED_BY_USER, "Patching aborted by user")
STRING(FAILED_TO_RUN_PATCH, "Failed to run patch:\n%s")
STRING(DECOMPRESSING_DOT_CODE, "Decompressing .code...")
STRING(DECOMPRESSING_DOT_CODE_B_DETECTED_CANCEL, "Decompressing .code...\nB button detected. Cancel?")
STRING(COMPRESSING_DOT_CODE, "Compressing .code...")
STRING(COMPRESSING_DOT_CODE_B_DETECTED_CANCEL, "Compressing .code...\nB button detected. Cancel?")
STRING(PATCH_MOST_LIKELY_NOT_FOR_THIS_FILE, "The patch is most likely not intended for this file.")
STRING(YOU_MOST_LIKELY_APPLIED_PATCH_ON_OUTPUT, "You most likely applied the patch on the output file.")
STRING(PATCH_TECHNICALLY_VALID_BUT_SEEMS_SCRAMBLED, "The patch is technically valid,\nbut seems scrambled or malformed.")
STRING(PATCH_IS_INVALID, "The patch is invalid.")
STRING(FILES_BIGGER_THAN_16MB_IPS_DOESNT_SUPPORT_THAT, "One or both files are bigger than 16MB.\nThe IPS format doesn't support that.")
STRING(REQUESTED_FILE_PATH_WAS_INVALID, "The requested file path was invalid.")
STRING(PATCHING_CANCELED, "Patching canceled.")
STRING(NOT_ENOUGH_MEMORY, "Not enough memory.")
STRING(REGION_AMERICAS, "Americas")
STRING(REGION_AUSTRALIA, "Australia")
STRING(REGION_BRAZIL, "Brazil")
STRING(REGION_CHINA, "China")
STRING(REGION_EUROPE, "Europe")
STRING(REGION_FRANCE, "France")
STRING(REGION_GERMANY, "Germany")
STRING(REGION_ITALY, "Italy")
STRING(REGION_JAPAN, "Japan")
STRING(REGION_KOREA, "Korea")
STRING(REGION_SPAIN, "Spain")
STRING(REGION_TAIWAN, "Taiwan")
STRING(REGION_UNKNOWN, "Unknown")
STRING(REGION_UNITED_KINGDOM, "United Kingdom")
STRING(REGION_MIDDLE_EAST, "Middle East")
STRING(GENERATING_QR_CODE, "Generating QR code...")
STRING(REINITIALIZING_SD_CARD, "Reinitializing SD card...")
STRING(DUMPING_STATE_TO_SD_CARD, "Dumping state to SD card...")
STRING(PRESS_POWER_TO_TURN_OFF, "Press POWER to turn off")
STRING(CLEANING_UP_TITLES_PLEASE_WAIT, "Cleaning up titles, please wait...")
STRING(ERROR_NOT_NCCH_FILE, "Error: Not an NCCH file")
STRING(ERROR_FILE_IS_TOO_SMALL, "Error: File is too small")
STRING(ATTEMPT_FIX_THIS_TIME, "Attempt fix this time")
STRING(ATTEMPT_FIX_ALWAYS, "Attempt fix always")
STRING(ABORT_VERIFICATION, "Abort verification")
STRING(ERROR_BAD_CRYPTO_FLAGS, "Error: Bad crypto flags")
STRING(ERROR_BAD_EXEFS_HEADER, "Error: Bad ExeFS header")
STRING(ERROR_MISSING_EXTHEADER, "Error: Missing ExtHeader")
STRING(ERROR_CRYPTO_NOT_SET_UP, "Error: Crypto not set up")
STRING(PATH_NCCH_VERIFICATION_FAILED_INFO, "%s\nNCCH verification failed:\nExtHdr/ExeFS/RomFS: %s/%s/%s")
STRING(OK, "ok")
STRING(FAIL, "fail")
STRING(ERROR_NOT_NCSD_FILE, "Error: Not an NCSD file")
STRING(PATH_CONTENT_N_SIZE_AT_OFFSET_VERIFICATION_FAILED, "%s\nContent%lu (%08lX@%08lX):\nVerification failed")
STRING(ERROR_PROBABLY_NOT_CIA_FILE, "Error: Probably not a CIA file")
STRING(ERROR_TMD_PROBABLY_CORRUPTED, "Error: TMD probably corrupted")
STRING(PATH_ID_N_SIZE_AT_OFFSET_VERIFICATION_FAILED, "%s\nID %08lX (%08llX@%08llX)\nVerification failed")
STRING(ERROR_CDN_TITLEKEY_NOT_FOUND, "Error: CDN titlekey not found")
STRING(DLC_CONTENT_IS_MISSING_IGNORE_ALL_AND_CONTINUE, "DLC content is missing\n \nIgnore all and continue?")
STRING(PATH_SECTION_N_HASH_MISMATCH, "%s\nSection %lu hash mismatch")
STRING(ARM9_ENTRYPOINT_IS_MISSING, "ARM9 entrypoint is missing")
STRING(WARNING_ARM11_ENTRYPOINT_IS_MISSING, "Warning: ARM11 entrypoint is missing")
STRING(ERROR_NOT_A_BOSS_FILE, "Error: Not a BOSS file")
STRING(BOSS_PAYLOAD_HASH_MISMATCH_TRY_TO_FIX_IT, "BOSS payload hash mismatch.\n \nTry to fix it?")
STRING(GENERIC_TICKET_PIRATE_LEGIT, "Generic ticket (\"pirate legit\")")
STRING(PERSONALIZED_TICKET_LEGIT, "Personalized ticket (legit)")
STRING(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:")
STRING(ID_N_TITLEKEY_NOT_FOUND, "ID %016llX\nTitlekey not found.")
STRING(ID_N_TMD_IN_TAD_NOT_LEGIT, "ID %016llX\nTMD in TAD is not legit.")
STRING(ID_N_TMD_NOT_LEGIT, "ID %016llX\nTMD is not legit.")
STRING(ID_N_DOT_N_STATUS, "ID %016llX.%08lX\n%s")
STRING(CONTENT_IS_CORRUPT, "Content is corrupt")
STRING(INSERT_CONTENT_FAILED, "Insert content failed")
STRING(INSTALL_CONTENT_FAILED, "Install content failed")
STRING(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?")
STRING(INSTALL_ERROR_THIS_SYSTEM_IS_MISSING_TICKET_DB, "Install error:\nThis system is missing the\nticket.db file.")
STRING(SKIPPED_TITLE_0004008C000CBD00_NEEDS_SPECIAL_COMPILE_FLAGS, "Skipped title:\nTitle with id 0004008C000CBD00\nneeds special compiler flags.")
STRING(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.")
STRING(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.")
STRING(INSTALLING_TICKET, "Installing ticket...")
STRING(POSSIBLY_BROKEN, "Possibly Broken")
STRING(PERSONAL_LEGIT, "Personal Legit")
STRING(PERSONAL_LEGIT_DLC, "Personal Legit DLC")
STRING(PERSONAL_PIRATE_LEGIT, "Personal Pirate Legit")
STRING(PERSONAL_PIRATE_LEGIT_DLC, "Personal Pirate Legit DLC")
STRING(PERSONAL_CUSTOM, "Personal Custom")
STRING(PERSONAL_CUSTOM_DLC, "Personal Custom DLC")
STRING(UNIVERSAL_LEGIT, "Universal Legit")
STRING(UNIVERSAL_LEGIT_DLC, "Universal Legit DLC")
STRING(UNIVERSAL_PIRATE_LEGIT, "Universal Pirate Legit")
STRING(UNIVERSAL_PIRATE_LEGIT_DLC, "Universal Pirate Legit DLC")
STRING(UNIVERSAL_CUSTOM, "Universal Custom")
STRING(UNIVERSAL_CUSTOM_DLC, "Universal Custom DLC")
STRING(CONTENTS_IN_CIA_FOUND_TOTAL, "Contents in CIA: %lu/%lu")
STRING(CONTENTS_IN_CIA_TOTAL, "Contents in TMD: %lu")
STRING(CONSOLE_ID_N, "Console ID: %08lX\n")
STRING(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")
STRING(STATE_LEGIT, "legit")
STRING(STATE_ILLEGIT, "illegit")
STRING(STATE_UNKNOWN, "unknown")
STRING(STATE_INVALID, "invalid")
STRING(STATE_PENDING_PROCEED_WITH_VERIFICATION, "pending\n \nProceed with verification?")
STRING(STATE_PASSED, "passed")
STRING(STATE_FAILED, "failed")
STRING(OUTPUT_FILE_ALREADY_EXISTS_UPDATE_THIS, "Output file already exists.\nUpdate this?")
STRING(DSI_ENHANCED, "DSi Enhanced")
STRING(DSI_EXCLUSIVE, "DSi Exclusive")
STRING(FIXING_CMACS_PLEASE_WAIT, "Fixing CMACs, please wait...")
STRING(NCSD_HEADER_IS_NOT_VALID, "NCSD header is not valid")
STRING(NAND_DUMP_MISSING_DATA, "NAND dump missing data")
STRING(ERROR_CTR_MBR_IS_CORRUPT, "Error: CTR MBR is corrupt")
STRING(ERROR_TWL_MBR_IS_CORRUPT, "Error: TWL MBR is corrupt")
STRING(PATH_ERROR_CTR_PARTITION_N_IS_CORRUPT, "%s\nError: CTR partition%lu is corrupt")
STRING(PATH_ERROR_TWL_PARTITION_N_IS_CORRUPT, "%s\nError: TWL partition%lu is corrupt")
STRING(NO_VALID_FIRM_FOUND, "No valid FIRM found")
STRING(ERROR_NAND_DUMP_IS_CORRUPT_STILL_CONTINUE, "Error: NAND dump is corrupt.\nStill continue?")
STRING(ERROR_SYSTEM_IS_LOCKED, "Error: System is locked.")
STRING(ESSENTIAL_FILES_BACKUP_IS_REQUIRED_CREATE_ONE_NOW, "Essential files backup is required.\nCreate one now?")
STRING(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.)")
STRING(IMAGE_NCSD_CORRUPT_OR_CUSTOMIZED_SAFE_RESTORE_NOT_POSSIBLE, "Image NCSD corrupt or customized,\nsafe restore is not possible!")
STRING(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?")
STRING(NOT_AN_INSTALLABLE_FIRM, "Not a installable FIRM.")
STRING(FIRM_LOAD_VERIFY_ERROR, "FIRM load/verify error.")
STRING(PATH_FIRM_N_NOT_FOUND_OR_TOO_SMALL, "%s\nFIRM%lu not found or too small.")
STRING(SECTOR_0X96_CRYPTO_FAIL, "Sector 0x96 crypto fail.")
STRING(SECTOR_0X96_CORRUPTED_PROVIDE_SECRET_SECTOR_BIN_TO_FIX, "Sector 0x96 is corrupted.\n \nProvide \"secret_sector.bin\"\nto fix sector 0x96.")
STRING(SECTOR_0X96_CORRUPTED_FIX_DURING_INSTALLATION, "Sector 0x96 is corrupted.\n \nFix sector 0x96 during\nthe installation?")
STRING(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!")
STRING(INSTALLING_FIRM_PLEASE_WAIT, "Installing FIRM, please wait...")
STRING(THIS_IS_BAD_FAILED_WRITING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT, "!THIS IS BAD!\n \nFailed writing sector 0x96.\nTry to fix before reboot!")
STRING(THIS_IS_BAD_FAILED_WRITING_FIRM_N_TRY_FIX_BEFORE_REBOOT, "!THIS IS BAD!\n \nFailed writing FIRM%lu.\nTry to fix before reboot!")
STRING(CHECKING_INSTALLATION_PLEASE_WAIT, "Checking installation, please wait...")
STRING(THIS_IS_BAD_FAILED_VERIFYING_SECTOR_0X96_TRY_FIX_BEFORE_REBOOT, "!THIS IS BAD!\n \nFailed verifying sector 0x96.\nTry to fix before reboot!")
STRING(THIS_IS_BAD_FAILED_VERIFYING_FIRM_N_TRY_FIX_BEFORE_REBOOT, "!THIS IS BAD!\n \nFailed verifying FIRM%lu.\nTry to fix before reboot!")
STRING(PERFECT_KEYDB_IS_ALREADY_INSTALLED, "Perfect %s is already installed!")
STRING(PATH_NOT_PERFECT_KEYDB_IMAGE_CANNOT_INSTALL_TO_NAND, "%s\nNot a perfect %s image.\nCannot install to NAND!")
STRING(PATH_FAILED_WRITING_KEYDB_TO_NAND, "%s\nFailed writing %s to NAND!")
STRING(USE_L_R_TO_SAVE, "(use L+R to save)")
STRING(EASTER_NOT_FOUND, "(%s not found)")
STRING(BUILDING_TO_OUT_ARG, "Building to %s:\n%s ...")
STRING(EJECT_SD_CARD, "Eject SD card...")
STRING(INSERT_SD_CARD, "Insert SD card...")
STRING(SCRIPTERR_UNKNOWN_CMD, "unknown cmd")
STRING(SCRIPTERR_BAD_NUMBER_OF_ARGS, "bad # of args")
STRING(SCRIPTERR_UNRECOGNIZED_FLAGS, "unrecognized flags")
STRING(SCRIPTERR_ILLEGAL_FLAG, "illegal flag")
STRING(SCRIPTERR_UNRESOLVED_QUOTES, "unresolved quotes")
STRING(SCRIPTERR_TOO_MANY_ARGUMENTS, "too many arguments")
STRING(SCRIPTERR_ARGUMENT_EXPAND_FAILED, "argument expand failed")
STRING(SCRIPTERR_QUOTE_NOT_AN_ERROR, "'not' an error")
STRING(SCRIPTERR_SYNTAX_ERROR_AFTER_IF, "syntax error after 'if'")
STRING(SCRIPTERR_ELIF_WITHOUT_IF, "'elif' without 'if'")
STRING(SCRIPTERR_SYNTAX_ERROR_AFTER_ELIF, "syntax error after 'elif'")
STRING(SCRIPTERR_ELSE_WITHOUT_IF, "'else' without 'if'")
STRING(SCRIPTERR_END_WITHOUT_IF, "'end' without 'if'")
STRING(SCRIPTERR_FOR_INSIDE_FOR, "'for' inside 'for'")
STRING(SCRIPTERR_DIR_NOT_FOUND, "dir not found")
STRING(SCRIPTERR_FOR_WITHOUT_NEXT, "'for' without 'next'")
STRING(SCRIPTERR_NEXT_WITHOUT_FOR, "'next' without 'for'")
STRING(SCRIPTERR_FORPATH_ERROR, "forpath error")
STRING(SCRIPTERR_LABEL_NOT_FOUND, "label not found")
STRING(SCRIPTERR_USER_ABORT, "user abort")
STRING(SCRIPTERR_KEY_NOT_PRESSED, "key not pressed")
STRING(SCRIPTERR_OUT_OF_MEMORY, "out of memory")
STRING(SCRIPTERR_VAR_FAIL, "var fail")
STRING(SCRIPTERR_FORBIDDEN_DRIVE, "forbidden drive")
STRING(SCRIPTERR_INVALID_PATH, "invalid path")
STRING(SCRIPTERR_FILESELECT_ABORT, "fileselect abort")
STRING(SCRIPTERR_DIRSELECT_ABORT, "dirselect abort")
STRING(SCRIPTERR_SET_FAIL, "set fail")
STRING(SCRIPTERR_CHAR_NOT_FOUND, "char not found")
STRING(SCRIPTERR_ARGV_2_IS_NOT_CHAR, "argv[2] is not a char")
STRING(SCRIPTERR_ARGV_2_MUST_BE_2_CHARS, "argv[2] must be 2 chars")
STRING(SCRIPTERR_ARG_MATCH, "arg match")
STRING(SCRIPTERR_NO_ARG_MATCH, "no arg match")
STRING(SCRIPTERR_PERMISSION_FAIL, "permission fail")
STRING(SCRIPTERR_COPY_FAIL, "copy fail")
STRING(SCRIPTERR_MOVE_FAIL, "move fail")
STRING(SCRIPTERR_INJECT_FAIL, "inject fail")
STRING(SCRIPTERR_FILLBYTE_FAIL, "fillbyte fail")
STRING(SCRIPTERR_FILL_FAIL, "fill fail")
STRING(SCRIPTERR_BAD_FILESIZE, "bad filesize")
STRING(SCRIPTERR_CREATE_DUMMY_FILE, "create dummy fail")
STRING(SCRIPTERR_REMOVE_FAIL, "remove fail")
STRING(SCRIPTERR_MAKEDIR_FAIL, "makedir fail")
STRING(SCRIPTERR_MOUNT_FAIL, "mount fail")
STRING(SCRIPTERR_FIND_FAIL, "find fail")
STRING(SCRIPTERR_FINDNOT_FAIL, "findnot fail")
STRING(SCRIPTERR_NO_SIZE_GIVEN, "no size given")
STRING(SCRIPTERR_SIZE_TOO_BIG, "size too big")
STRING(SCRIPTERR_READ_FAIL, "read fail")
STRING(SCRIPTERR_CONVERSION_FAIL, "conversion fail")
STRING(SCRIPTERR_INVALID_DATA, "invalid data")
STRING(SCRIPTERR_WRITE_FAIL, "write fail")
STRING(SCRIPTERR_SHA_ARG0_FAIL, "sha arg0 fail")
STRING(SCRIPTERR_SHA_ARG1_FAIL, "sha arg1 fail")
STRING(SCRIPTERR_SHA_DOES_NOT_MATCH, "sha does not match")
STRING(SCRIPTERR_SHA_WRITE_FAIL, "sha write fail")
STRING(SCRIPTERR_FILE_WRITE_FAIL, "file write fail")
STRING(SCRIPTERR_FIXCMAC_FAILED, "fixcmac failed")
STRING(SCRIPTERR_VERIFICATION_FAILED, "verification failed")
STRING(SCRIPTERR_DECRYPT_FAILED, "decrypt failed")
STRING(SCRIPTERR_ENCRYPT_FAILED, "encrypt failed")
STRING(SCRIPTERR_BUILD_CIA_FAILED, "build CIA failed")
STRING(SCRIPTERR_INSTALL_GAME_FAILED, "install game failed")
STRING(SCRIPTERR_DOES_NOT_CONTAIN_DOT_CODE, "does not contain .code")
STRING(SCRIPTERR_EXTRACT_DOT_CODE_FAILED, "extract .code failed")
STRING(SCRIPTERR_COMPRESS_DOT_CODE_FAILED, "compress .code failed")
STRING(SCRIPTERR_BUILD_FAILED, "build failed")
STRING(SCRIPTERR_UNKNOWN_FILE, "unknown file")
STRING(SCRIPTERR_APPLY_IPS_FAILD, "apply IPS failed")
STRING(SCRIPTERR_APPLY_BPS_FAILED, "apply BPS failed")
STRING(SCRIPTERR_APPLY_BPM_FAILED, "apply BPM failed")
STRING(SCRIPTERR_TEXTVIEWER_FAILED, "textviewer failed")
STRING(SCRIPTERR_BAD_DUMPSIZE, "bad dumpsize")
STRING(SCRIPTERR_CART_INIT_FAIL, "cart init fail")
STRING(SCRIPTERR_CART_DUMP_FAILED, "cart dump failed")
STRING(SCRIPTERR_NOT_A_DIR, "not a dir")
STRING(SCRIPTERR_FILE_NOT_FOUND, "file not found")
STRING(SCRIPTERR_NOT_A_BOOTABLE_FIRM, "not a bootable firm")
STRING(SCRIPTERR_SD_NOT_MOUNTED, "SD not mounted")
STRING(SCRIPTERR_UNKNOWN_ERROR, "unknown error")
STRING(SCRIPTERR_COMMAND_SUCCESS, "command success")
STRING(SCRIPTERR_CONTROL_FLOW_ERROR, "control flow error")
STRING(SCRIPTERR_UNCLOSED_CONDITIONAL, "unclosed conditional")
STRING(SCRIPTERR_ERROR_MESSAGE_FAIL, "error message fail")
STRING(ERROR_INVALID_TEXT_DATA, "Error: Invalid text data")
STRING(TEXTVIEWER_CONTROLS_DETAILS, "Textviewer Controls:\n \n↑↓→←(+R) - Scroll\nR+Y - Toggle wordwrap\nR+X - Goto line #\nB - Exit\n")
STRING(CURRENT_LINE_N_ENTER_NEW_LINE_BELOW, "Current line: %i\nEnter new line below.")
STRING(PREVIEW_DISABLED, "(preview disabled)")
STRING(PATH_LINE_N_ERR_LINE, "%s\nline %lu: %s\n%s")
STRING(END_OF_SCRIPT_UNRESOLVED_IF, "end of script: unresolved 'if'")
STRING(END_OF_SCRIPT_UNRESOLVED_FOR, "end of script: unresolved 'for'")
STRING(SYSINFO_MODEL, "Model: %s (%s)\r\n")
STRING(SYSINFO_SERIAL, "Serial: %s\r\n")
STRING(SYSINFO_REGION_SYSTEM, "Region (system): %s\r\n")
STRING(SYSINFO_REGION_SALES, "Region (sales): %s\r\n")
STRING(SYSINFO_SOC_MANUFACTURING_DATE, "SoC manufacturing date: %s\r\n")
STRING(SYSINFO_SYSTEM_ASSEMBLY_DATE, "System assembly date: %s\r\n")
STRING(SYSINFO_ORIGINAL_FIRMWARE, "Original firmware: %s\r\n")
STRING(SYSINFO_FRIENDCODE_SEED, "Friendcode seed: %s\r\n")
STRING(SYSINFO_SD_KEYY, "SD keyY: %s\r\n")
STRING(SYSINFO_NAND_CID, "NAND CID: %s\r\n")
STRING(SYSINFO_SD_CID, "SD CID: %s\r\n")
STRING(SYSINFO_SYSTEM_ID0, "System ID0: %s\r\n")
STRING(SYSINFO_SYSTEM_ID1, "System ID1: %s\r\n")
STRING(SORTING_TICKETS_PLEASE_WAIT, "Sorting tickets, please wait ...")

5
arm9/source/language.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
#define STRING(what, def) extern const char *STR_##what;
#include "language.en.inl"
#undef STRING

View File

@ -0,0 +1,80 @@
STRING(PATH_FIRM_TOO_BIG, "%s\nFIRMは大きすぎる。 起動できません。")
STRING(PATH_DO_NOT_BOOT_UNTRUSTED, "%s (%dkB)\n注意: 信頼できないソースから\nFIRMを起動しないでください。\n \nFIRMを起動?")
STRING(NOT_BOOTABLE_FIRM, "%s\n起動できるFIRMではない。")
STRING(PATH_FIRM_ENCRYPTED, "%s\nFIRMは暗号化されている。\n \n起動前に復号化しますか?")
STRING(MAKE_COPY_AT_OUT_TEMP_FIRM, "%s/temp.firmにコピーを作成しますか")
STRING(TRY_BOOT_ANYWAYS, "とにかく起動してみる")
STRING(PATH_WARNING_BOOT_UNSUPPORTED_LOCATION, "%s\n注意: サポートされていない場所から起動を試みています。")
STRING(ROOT, "[ルート]")
STRING(LOADING, "ロード中……")
STRING(PANE_N, "ペイン第%luつ")
STRING(CURRENT, "現在")
STRING(DIR, "(dir)")
STRING(SD_FAT, "(SD FAT)")
STRING(RAMDRIVE_FAT, "(RAMドライブFAT)")
STRING(GAME_VIRTUAL, "(ゲームバーチャル)")
STRING(SYSNAND_FAT, "(システムNAND FAT)")
STRING(SYSNAND_VIRTUAL, "(システムNANDバーチャル)")
STRING(EMUNAND_FAT, "(エミュNAND FAT)")
STRING(EMUNAND_VIRTUAL, "(エミュNANDバーチャル)")
STRING(IMAGE_FAT, "(イメージFAT)")
STRING(XORPAD_VIRTUAL, "(XORパッドバーチャル)")
STRING(MEMORY_VIRTUAL, "(メモリバーチャル)")
STRING(ALIAS_FAT, "(エイリアスFAT)")
STRING(GAMECART_VIRTUAL, "(ゲームカートバーチャル)")
STRING(VRAM_VIRTUAL, "(VRAMバーチャル)")
STRING(SEARCH, "(検索))")
STRING(TITLEMANAGER_VIRTUAL, "(タイトルマネージャーバーチャル)")
STRING(N_BYTE, "%sバイト")
STRING(CLIPBOARD, "[クリップボード]")
STRING(PLUS_N_MORE, "+ と%lu個")
STRING(MARK_DELETE_COPY, "L - ファイルをマーク(↑↓→←と使用)\nX - ファイルを削除 / [+R] 名前を変更\nY - ファイルをコピー / [+R] エントリを作成\n")
STRING(MARK_DELETE_PASTE, "L - ファイルをマーク(↑↓→←と使用)\nX - ファイルを削除 / [+R] 名前を変更\nY - ファイルを貼り付ける / [+R] エントリを作成\n")
STRING(RELOCK_WRITE_PERMISSION, "R+Y - 書き込みの許可を再ロック\n")
STRING(UNMOUNT_IMAGE, "R+X - イメージをマウント解除\n")
STRING(UNMOUNT_SD, "R+B - SDカードをマウント解除\n")
STRING(REMOUNT_SD, "R+B - SDカードを再マウント\n")
STRING(DIRECTORY_OPTIONS, "R+A - ディレクトリオプション\n")
STRING(DRIVE_OPTIONS, "R+A - ドライブオプション\n")
STRING(MAKE_SCREENSHOT, "R+L - スクリーンショットを作成\n")
STRING(PREV_NEXT_PANE, "R+←→ - 前・次のペインに切り替える\n")
STRING(CLEAR_CLIPBOARD, "SELECT - クリップポードの消去\n")
STRING(RESTORE_CLIPBOARD, "SELECT - クリップボードの復元\n")
STRING(REBOOT_POWEROFF_HOME, "START - 再起動 / [+R] 電源オフ\nHOMEボタンでHOMEメニュー")
STRING(NO_EMUNAND, "EmuNANDなし")
STRING(REDNAND_SIZE_MIN, "RedNANDサイズ(最低)")
STRING(GW_EMUNAND_SIZE_FULL, "GWエミュNANDサイズ(フル)")
STRING(MULTINAND_SIZE_2X, "マルチNANDサイズ(2x)")
STRING(MULTINAND_SIZE_3X, "マルチNANDサイズ(3x)")
STRING(MULTINAND_SIZE_4X, "マルチNANDサイズ(4x)")
STRING(USER_INPUT, "ユーザー入力……")
STRING(AUTO, "自動")
STRING(16KB_CLUSTERS, "16KBクラスター")
STRING(32KB_CLUSTERS, "32KBクラスター")
STRING(64KB_CLUSTERS, "64KBクラスター")
STRING(SD_NOT_DETECTED, "エラー: SDカードを検出されない")
STRING(FORMAT_SD_CHOOSE_EMUNAND, "SDカード(%lluMB)をフォーマットしますか?\nエミュNANDサイズを選択さてください。")
STRING(SD_SIZE_IS_ENTER_EMUNAND_SIZE, "SDカードサイズは%lluMB。\nエミュNANDサイズ(MB)をいかに入力してください。")
STRING(FORMAT_SD_CHOOSE_CLUSTER, "SDカード(%lluMB)をフォーマットしますか?\nクラスターサイズを選択してください。")
STRING(FORMAT_SD_ENTER_LABEL, "SDカード(%lluMB)をフォーマットしますか?\nラベルを入力してください。")
STRING(FORMAT_SD_FAILED, "SDのフォーマット:失敗!")
STRING(REDNAND_TYPE, "RedNANDタイプ")
STRING(REDNAND_TYPE_MULTI, "RedNANDタイプ(マルチ)")
STRING(REDNAND_TYPE_SINGLE, "RedNAND type (シングル))")
STRING(GW_EMUNAND_TYPE, "GWエミュNANDタイプ")
STRING(DONT_SET_UP, "設定しない")
STRING(CHOOSE_EMUNAND_TYPE, "設定されるエミュNANDタイプを選択してください。")
STRING(CLONE_SYSNAND_TO_REDNAND, "RedNANDにSysNANDをコピーしますか?")
STRING(CLONING_SYSNAND_TO_EMUNAND_FAILED, "エミュNANDにSysNANDをコピー: 失敗!")
STRING(PRESS_A_TO_CONTINUE, "<A>を押して続ける")
STRING(HEXEDITOR_CONTROLS, "16進エディターのコントロール:\n \n↑↓→←(+R) - スクロール\nR+Y - 表示を切り替える\nX - 検索・移動……\nA - 編集モードにする\nA+↑↓→← - 値を編集\nB - 終了\n")
STRING(NOT_FOUND, "見つけない!")
STRING(GO_TO_OFFSET, "オフセットへ移動")
STRING(SEARCH_FOR_STRING, "文字列で検索")
STRING(SEARCH_FOR_DATA, "データで検索")
STRING(CURRENT_OFFSET_SELECT_ACTION, "現在のオフセット: %08lX\nアクションを選択:")
STRING(CURRENT_OFFSET_ENTER_NEW, "現在のオフセット: %08lX\n以下に新しいオフセットを入力してください。")
STRING(ENTER_SEARCH_REPEAT_SEARCH, "以下に検索する文字列を入力してください。\n(R+Xで検索を繰り返します)")
STRING(MADE_EDITS_SAVE_CHANGES, "%i個の場所で変更されました。\n変更をファイルに書き込みますか?")
STRING(FAILED_WRITING_TO_FILE, "ファイルに書き込みに失敗しました!")
STRING(CALCULATING_SHA_FAILED, "SHA-%sを計算する: 失敗!")

View File

@ -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"
@ -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();
@ -139,16 +141,16 @@ void XRQ_DumpRegisters(u32 xrq, u32 *regs)
snprintf(path, 64, "%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();

View File

@ -2,6 +2,7 @@
#include "nandcmac.h"
#include "fs.h"
#include "essentials.h"
#include "language.h"
#include "ui.h"
#include "sha.h"
@ -110,7 +111,7 @@ u32 TransferCtrNandImage(const char* path_img, const char* drv) {
PathCopy(path_dbs, path_from, &flags);
FixFileCmac(path_to, true);
}
ShowString("Cleaning up titles, please wait...");
ShowString("%s", STR_CLEANING_UP_TITLES_PLEASE_WAIT);
snprintf(path_to, 32, "%s/title", drv);
snprintf(path_from, 32, "7:/title");
PathDelete(path_to);

View File

@ -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,7 +743,7 @@ 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",
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,7 +788,7 @@ 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",
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 %lu 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);
@ -2192,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) {
@ -2222,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 {
@ -2279,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;
}
@ -2363,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;
}
@ -2418,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;
}
}
@ -2867,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;
}
@ -2911,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;
}
@ -2944,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;
}
@ -2985,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;
}
@ -2994,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;
}
@ -3002,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;
}
@ -3014,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
@ -3170,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;
}
@ -3223,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;
}
@ -3427,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;
}
@ -3515,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;
@ -3572,15 +3572,23 @@ 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, sizeof(typestr), "Possibly Broken");
else snprintf(typestr, sizeof(typestr), "%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, sizeof(srcstr), "%s",
@ -3591,30 +3599,23 @@ u32 ShowGameCheckerInfo(const char* path) {
(type & GAME_TWLTMD) ? "TWL" : "UNK");
char contents_str[64];
if (type & GAME_CIA) snprintf(contents_str, sizeof(contents_str), "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, sizeof(conid_str), "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: %lu.%lu.%lu\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);
}
@ -3819,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;
}
@ -3912,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;
@ -4142,7 +4143,7 @@ u32 GetGoodName(char* name, const char* path, bool quick) {
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

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}
@ -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" : "TWL";
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%lu 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("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("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;
}

View File

@ -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,7 +115,7 @@ 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, "%s", snapstr);

View File

@ -571,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;
@ -608,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;
}
@ -628,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;
@ -650,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;
}
@ -693,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;
}
@ -738,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
}
@ -847,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
}
}
@ -881,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
@ -890,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;
}
@ -907,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;
}
@ -926,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;
}
@ -941,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 {
@ -958,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';
@ -980,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) {
@ -1021,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]);
@ -1043,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 };
@ -1057,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)) {
@ -1074,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];
@ -1110,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];
@ -1127,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;
@ -1161,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;
@ -1170,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], '@');
@ -1182,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;
@ -1190,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) {
@ -1212,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);
@ -1229,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++) {
@ -1269,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);
}
}
}
@ -1286,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) {
@ -1301,20 +1301,20 @@ 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'))
@ -1324,9 +1324,9 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) {
snprintf(hash_str, 64+1, "%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) {
@ -1335,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))
@ -1402,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));
@ -1434,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]);
@ -1464,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;
}
}
@ -1472,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;
}
}
@ -1480,7 +1480,7 @@ 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);
@ -1496,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();
@ -1543,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;
}
@ -1574,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;
}
@ -1693,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;
}
@ -1701,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("%s", instr);
ShowString("%s", STR_TEXTVIEWER_CONTROLS_DETAILS);
// set script colors
if (as_script) {
@ -1741,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("%s", 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);
@ -1779,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;
}
@ -1886,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;
}
@ -1930,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;
@ -1946,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);
}
@ -1986,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;
}
@ -2001,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;
}
@ -2017,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];
@ -2027,7 +2026,7 @@ bool ExecuteGM9Script(const char* path_script) {
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);
ShowPrompt(false, STR_PATH_LINE_N_ERR_LINE, path_str, lno, err_str, line_str);
}
}
if (!(flags & _FLG('o'))) { // failed if not optional
@ -2056,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;
}

View File

@ -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,24 +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[] = {
// Sales regions.
const char* salesRegion(char serial_char) {
switch(serial_char) {
// Typical regions.
{ 'J', "Japan" },
{ 'W', "Americas" }, // "W" = worldwide?
{ 'E', "Europe" },
{ 'C', "China" },
{ 'K', "Korea" },
{ 'T', "Taiwan" },
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.
{ 'U', "United Kingdom" },
{ 'S', "Middle East" }, // "S" = Saudi Arabia? Singapore? (Southeast Asia included.)
{ 'A', "Australia" },
{ 'B', "Brazil" },
};
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 {
@ -60,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];
@ -165,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';
}
@ -233,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));
strncpy(info->sales_region, salesRegion(second_letter), countof(info->sales_region));
info->sales_region[countof(info->sales_region) - 1] = '\0';
break;
}
}
}
// Determine the sub-model from the first two digits of the digit part.
@ -599,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);
}

View File

@ -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;