8 Commits

Author SHA1 Message Date
ash
116c846c9d Edit readme for gitea 2025-11-17 22:47:18 -05:00
Théo B.
69e0edffb4 fix build on new libctru and add lang fetch (#358)
removes ACT functions now in libctru
implement a single function to load a CFG_Language
2025-10-25 21:07:54 +01:00
cooolgamer
ba08ab9108 Added animated app splash 2024-06-24 22:22:18 -04:00
impeeza
ec91703bdf Update README.md
Add some system packages needed to successfully build the release.
2024-06-24 22:02:49 -04:00
1418c2bc8d Add all colors to config 2024-06-20 23:54:35 -04:00
b2c4afdc05 Properly dump badges without an associated set 2024-06-19 22:18:37 -04:00
79afaca01d Add paths to config file 2024-06-19 01:14:34 -04:00
Alex Taber
3ef2092dc2 3.0.1 hotfix backport (#328)
* Filter newline and carriage returns when dumping themes

* Backup badges if no badges found
2024-06-17 20:30:14 -04:00
16 changed files with 377 additions and 157 deletions

View File

@@ -1,8 +1,9 @@
![# Anemone3DS](https://github.com/astronautlevel2/Anemone3DS/blob/master/meta/banner.png)
![# Anemone3DS](https://git.ataber.pw/ash/Anemone3DS/raw/branch/master/meta/banner.png)
A Theme and Splashscreen Manager for the Nintendo 3DS, written in C.
# Dependencies
* Make, Git and PKG-Config
* devkitARM, which can be installed following the instructions [here](https://devkitpro.org/wiki/Getting_Started).
* jansson, libvorbisidec, libpng, and libarchive, which can be retrieved from [devkitPro pacman](https://devkitpro.org/viewtopic.php?f=13&t=8702).
* A recent build of [makerom](https://github.com/profi200/Project_CTR) and the latest release of [bannertool](https://github.com/Steveice10/bannertool). These must be added to your PATH.
@@ -10,8 +11,8 @@ A Theme and Splashscreen Manager for the Nintendo 3DS, written in C.
# Building
First of all, make sure devkitARM is properly installed - `$DEVKITPRO` and `$DEVKITARM` should be set to `/opt/devkitpro` and `$DEVKITPRO/devkitARM`, respectively.
After that, open the directory you want to clone the repo into, and execute
`git clone https://github.com/astronautlevel2/Anemone3DS` (or any other cloning method).
To install the prerequisite libraries, begin by ensuring devkitPro pacman (and the base install group, `3ds-dev`) is installed, and then install the dkP packages `3ds-jansson`, `3ds-libvorbisidec`, `3ds-libpng`, `3ds-lz4`, `3ds-libarchive` and `3ds-curl` using `[sudo] [dkp-]pacman -S <package-name>`.
`git clone https://git.ataber.pw.com/ash/Anemone3DS` (or any other cloning method).
To install the prerequisite libraries, begin by ensuring devkitPro pacman (and the base install group, `3ds-dev`) is installed, and then install the dkP packages `3ds-jansson`, `3ds-libvorbisidec`, `3ds-libpng`, `3ds-lz4`, `3ds-libarchive` and `3ds-curl` using `[sudo] [dkp-]pacman -S <package-name>`. System wide packages `make`, `git` and `pkg-config` are also needed.
After adding [makerom](https://github.com/profi200/Project_CTR) and [bannertool](https://github.com/Steveice10/buildtools) to your PATH, just enter your directory and run `make`. All built binaries will be in `/out/`.

View File

@@ -35,10 +35,12 @@ typedef u32 Color;
typedef enum {
COLOR_BACKGROUND, //silver-y black
COLOR_ACCENT,
COLOR_WHITE,
COLOR_WHITE_BACKGROUND,
COLOR_WHITE_ACCENT,
COLOR_CURSOR,
COLOR_BLACK,
COLOR_RED,
COLOR_RED_BACKGROUND,
COLOR_RED_ACCENT,
COLOR_YELLOW,
COLOR_AMOUNT,

View File

@@ -79,7 +79,7 @@ typedef enum {
REMOTE_MODE_AMOUNT,
} RemoteMode;
extern const char * main_paths[MODE_AMOUNT];
extern const char * main_paths[REMOTE_MODE_AMOUNT];
extern const int entries_per_screen_v[MODE_AMOUNT];
extern const int entries_per_screen_h[MODE_AMOUNT];
extern const int entry_size[MODE_AMOUNT];

View File

@@ -32,9 +32,14 @@
#include <jansson.h>
typedef struct {
u32 background_color;
u32 accent_color;
u32 red_color;
u32 background_color;
u32 white_color_background;
u32 white_color_accent;
u32 cursor_color;
u32 black_color;
u32 red_color_background;
u32 red_color_accent;
u32 yellow_color;
} Config_s;

View File

@@ -31,7 +31,7 @@
#include "badges.h"
#include "config.h"
#define ILLEGAL_CHARS "><\"?;:/\\+,.|[=]*"
#define ILLEGAL_CHARS "><\"?;:/\\+,.|[=]*\n\r"
extern FS_Archive ArchiveSD;
extern FS_Archive ArchiveHomeExt;

View File

@@ -193,4 +193,8 @@ typedef enum {
Language_s init_strings(CFG_Language lang);
extern Language_s language;
// fetches the system language through CFGU_GetSystemLanguage
// and returns the appropriate CFG_Language enum value
CFG_Language get_system_language(void);
#endif

Binary file not shown.

View File

@@ -32,7 +32,6 @@
#include "draw.h"
#include "ui_strings.h"
static Handle actHandle;
Handle badgeDataHandle;
char *badgeMngBuffer;
u16 *rgb_buf_64x64;
@@ -42,51 +41,6 @@ u8 *alpha_buf_32x32;
u64 progress_finish;
u64 progress_status;
Result actInit(void)
{
return srvGetServiceHandle(&actHandle, "act:u");
}
Result actExit(void)
{
return svcCloseHandle(actHandle);
}
Result ACTU_Initialize(u32 sdkVersion, u32 memSize, Handle handle)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00010084;
cmdbuf[1] = sdkVersion;
cmdbuf[2] = memSize;
cmdbuf[3] = 0x20;
cmdbuf[4] = 0x0;
cmdbuf[5] = 0x0;
cmdbuf[6] = handle;
if ((ret = svcSendSyncRequest(actHandle)) != 0) return ret;
return (Result) cmdbuf[1];
}
Result ACTU_GetAccountDataBlock(u32 slot, u32 size, u32 blockId, u32 *output)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x000600C2;
cmdbuf[1] = slot;
cmdbuf[2] = size;
cmdbuf[3] = blockId;
cmdbuf[4] = (size << 4) | 12;
cmdbuf[5] = (u32) output;
if ((ret = svcSendSyncRequest(actHandle)) != 0) return ret;
return (Result) cmdbuf[1];
}
void remove_exten(u16 *filename)
{
for (int i = 0; i < strulen(filename, 0x8A); ++i)
@@ -115,7 +69,7 @@ u64 getShortcut(char *filename)
if (sscanf(p1, "%08x", &lowpath) != 1) return shortcut;
shortcut = 0x0004001000000000 + lowpath;
DEBUG("Shortcut %08llx found for %s\n", shortcut, filename);
DEBUG("Shortcut %16llx found for %s\n", shortcut, filename);
return shortcut;
}
@@ -215,7 +169,7 @@ int install_badge_dir(FS_DirectoryEntry set_dir, int *badge_count, int set_id)
u16 path[512] = {0};
u16 set_icon[17] = {0};
utf8_to_utf16(set_icon, (u8 *) "_seticon.png", 16);
struacat(path, "/Badges/");
struacat(path, main_paths[REMOTE_MODE_BADGES]);
strucat(path, set_dir.name);
res = FSUSER_OpenDirectory(&folder, ArchiveSD, fsMakePath(PATH_UTF16, path));
if (R_FAILED(res))
@@ -231,7 +185,7 @@ int install_badge_dir(FS_DirectoryEntry set_dir, int *badge_count, int set_id)
if (!strcmp(badge_files[i].shortExt, "PNG"))
{
memset(path, 0, 512 * sizeof(u16));
struacat(path, "/Badges/");
struacat(path, main_paths[REMOTE_MODE_BADGES]);
strucat(path, set_dir.name);
struacat(path, "/");
strucat(path, badge_files[i].name);
@@ -245,7 +199,7 @@ int install_badge_dir(FS_DirectoryEntry set_dir, int *badge_count, int set_id)
} else if (!strcmp(badge_files[i].shortExt, "ZIP"))
{
memset(path, 0, 512 * sizeof(u16));
struacat(path, "/Badges/");
struacat(path, main_paths[REMOTE_MODE_BADGES]);
strucat(path, set_dir.name);
struacat(path, "/");
strucat(path, badge_files[i].name);
@@ -335,7 +289,14 @@ void free_list(SetNode *head)
SetNode * extract_sets(char *badgeMngBuffer, Handle backupDataHandle)
{
u32 setCount = *((u32 *) (badgeMngBuffer + 0x4));
if (setCount == 0) return NULL;
if (!setCount) // GYTB? make unknown set
{
u16 set_path[256] = {0};
struacat(set_path, "/3ds/" APP_TITLE "/BadgeBackups/Unknown Set");
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_UTF16, set_path), FS_ATTRIBUTE_DIRECTORY);
return NULL;
}
SetNode *head = calloc(1, sizeof(SetNode));
SetNode *cursor = head;
@@ -441,7 +402,7 @@ Result extract_badges(void)
{
u32 set_index = get_set_index(head, badgeSetId);
if (set_index == 0xFFFFFFFF) {
sprintf(dir, "/3ds" APP_TITLE "/BadgeBackups/Unknown Set");
sprintf(dir, "/3ds/" APP_TITLE "/BadgeBackups/Unknown Set");
} else
{
u16 utf16SetName[0x46] = {0};
@@ -454,6 +415,9 @@ Result extract_badges(void)
DEBUG("UTF-8 Set Name: %s; ID: %lx\n", utf8SetName, badgeSetId);
sprintf(dir, "/3ds/" APP_TITLE "/BadgeBackups/%s", utf8SetName);
}
} else
{
sprintf(dir, "/3ds/" APP_TITLE "/BadgeBackups/Unknown Set");
}
if (shortcut == 0xFFFFFFFF)
@@ -480,35 +444,112 @@ Result extract_badges(void)
return res;
}
Result backup_badges_fast(void)
{
char *badgeMng = NULL;
DEBUG("writing badge data: making files...\n");
char mng_path[128] = "/3ds/" APP_TITLE "/BadgeMngFile.dat";
char data_path[128] = "/3ds/" APP_TITLE "/BadgeData.dat";
DEBUG("mng_path: %s, data_path: %s\n", mng_path, data_path);
Handle dataHandle = 0;
Handle sdHandle = 0;
DEBUG("loading existing badge mng file...\n");
u32 mngRead = file_to_buf(fsMakePath(PATH_ASCII, "/BadgeMngFile.dat"), ArchiveBadgeExt, &badgeMng);
DEBUG("loading existing badge data file\n");
Result res = FSUSER_OpenFile(&dataHandle, ArchiveBadgeExt, fsMakePath(PATH_ASCII, "/BadgeData.dat"), FS_OPEN_READ, 0);
if (mngRead != BADGE_MNG_SIZE || R_FAILED(res))
{
char err_string[128] = {0};
sprintf(err_string, language.badges.extdata_locked, res);
throw_error(err_string, ERROR_LEVEL_WARNING);
if (badgeMng) free(badgeMng);
if (dataHandle) FSFILE_Close(dataHandle);
FSFILE_Close(sdHandle);
return -1;
}
remake_file(fsMakePath(PATH_ASCII, mng_path), ArchiveSD, BADGE_MNG_SIZE);
FSUSER_CreateFile(ArchiveSD, fsMakePath(PATH_ASCII, data_path), 0, BADGE_DATA_SIZE);
FSUSER_OpenFile(&sdHandle, ArchiveSD, fsMakePath(PATH_ASCII, data_path), FS_OPEN_WRITE, 0);
DEBUG("writing badge data: writing BadgeMngFile...\n");
res = buf_to_file(mngRead, fsMakePath(PATH_ASCII, mng_path), ArchiveSD, badgeMng);
if (R_FAILED(res))
{
DEBUG("Failed to write badgemngfile: 0x%08lx\n", res);
free(badgeMng);
FSFILE_Close(dataHandle);
FSFILE_Close(sdHandle);
return -1;
}
DEBUG("writing badge data: writing badgedata...\n");
char *buf = malloc(0x10000);
u64 size = BADGE_DATA_SIZE;
u64 cur = 0;
while (size > 0)
{
u32 read = 0;
res = FSFILE_Read(dataHandle, &read, cur, buf, min(0x10000, size));
res = FSFILE_Write(sdHandle, NULL, cur, buf, read, FS_WRITE_FLUSH);
size -= read;
cur += read;
}
free(badgeMng);
free(buf);
FSFILE_Close(dataHandle);
FSFILE_Close(sdHandle);
return 0;
}
Result install_badges(void)
{
Handle handle = 0;
Handle folder = 0;
Result res = 0;
draw_loading_bar(0, 1, INSTALL_BADGES);
{
char testpath[128] = "/3ds/" APP_TITLE "/BadgeData.dat";
if (R_FAILED(res = FSUSER_OpenFile(&handle, ArchiveSD, fsMakePath(PATH_ASCII, testpath), FS_OPEN_READ, 0)))
{
if (R_SUMMARY(res) == RS_NOTFOUND)
{
res = backup_badges_fast();
if (R_FAILED(res)) return res;
} else
{
DEBUG("????: 0x%08lx\n", res);
}
}
}
if (handle) FSFILE_Close(handle);
DEBUG("Initializing ACT\n");
res = actInit();
res = actInit(true);
if (R_FAILED(res))
{
DEBUG("actInit() failed!\n");
return res;
}
DEBUG("Initializing ACTU\n");
res = ACTU_Initialize(0xB0502C8, 0, 0);
DEBUG("Initializing ACT\n");
res = ACT_Initialize(0xB0502C8, 0, 0);
if (R_FAILED(res))
{
DEBUG("ACTU_Initialize failed! %08lx\n", res);
DEBUG("ACT_Initialize failed! %08lx\n", res);
return res;
}
DEBUG("Getting NNID\n");
u32 nnidNum = 0xFFFFFFFF;
res = ACTU_GetAccountDataBlock(0xFE, 4, 12, &nnidNum);
res = ACT_GetAccountInfo(&nnidNum, sizeof(nnidNum), ACT_DEFAULT_ACCOUNT, INFO_TYPE_PRINCIPAL_ID);
if (R_FAILED(res))
{
DEBUG("ACTU_GetAccountDataBlock failed! %08lx\n", res);
DEBUG("ACT_GetAccountInfo failed! %08lx\n", res);
return res;
}
DEBUG("NNID found: 0x%08lx\n", nnidNum);
@@ -522,7 +563,7 @@ Result install_badges(void)
DEBUG("Opening badge directory\n");
FS_DirectoryEntry *badge_files = calloc(1024, sizeof(FS_DirectoryEntry));
res = FSUSER_OpenDirectory(&folder, ArchiveSD, fsMakePath(PATH_ASCII, "/Badges/"));
res = FSUSER_OpenDirectory(&folder, ArchiveSD, fsMakePath(PATH_ASCII, main_paths[REMOTE_MODE_BADGES]));
if (R_FAILED(res))
{
DEBUG("Failed to open folder: %lx\n", res);
@@ -601,7 +642,7 @@ Result install_badges(void)
default_idx = badge_count;
}
u16 path[0x512] = {0};
struacat(path, "/Badges/");
struacat(path, main_paths[REMOTE_MODE_BADGES]);
strucat(path, badge_files[i].name);
default_set_count += install_badge_png(fsMakePath(PATH_UTF16, path), badge_files[i], &badge_count, default_set);
} else if (!strcmp(badge_files[i].shortExt, "ZIP"))
@@ -612,7 +653,7 @@ Result install_badges(void)
default_set = set_count;
}
u16 path[0x512] = {0};
struacat(path, "/Badges/");
struacat(path, main_paths[REMOTE_MODE_BADGES]);
strucat(path, badge_files[i].name);
default_set_count += install_badge_zip(path, &badge_count, default_set);

View File

@@ -201,7 +201,7 @@ static void update_ui(void * arg)
C2D_DrawImageAt((C2D_Image){ &tex, &subt3x }, 0.0f, 0.0f, 0.4f, NULL, 1.0f, 1.0f);
set_screen(bottom);
draw_text_center(GFX_BOTTOM, 4, 0.5, 0.5, 0.5, colors[COLOR_WHITE], language.camera.quit);
draw_text_center(GFX_BOTTOM, 4, 0.5, 0.5, 0.5, colors[COLOR_WHITE_ACCENT], language.camera.quit);
end_frame();
}

View File

@@ -32,9 +32,11 @@ void init_colors(void)
{
colors[COLOR_BACKGROUND] = config.background_color;
colors[COLOR_ACCENT] = config.accent_color;
colors[COLOR_WHITE] = C2D_Color32(255, 255, 255, 255);
colors[COLOR_CURSOR] = C2D_Color32(200, 200, 200, 255);
colors[COLOR_BLACK] = C2D_Color32(0, 0, 0, 255);
colors[COLOR_RED] = config.red_color;
colors[COLOR_WHITE_BACKGROUND] = config.white_color_background;
colors[COLOR_WHITE_ACCENT] = config.white_color_accent;
colors[COLOR_CURSOR] = config.cursor_color;
colors[COLOR_BLACK] = config.black_color;
colors[COLOR_RED_BACKGROUND] = config.red_color_background;
colors[COLOR_RED_ACCENT] = config.red_color_accent;
colors[COLOR_YELLOW] = config.yellow_color;
}

View File

@@ -30,6 +30,8 @@ Config_s config;
void load_config(void)
{
Handle test_handle;
Result res;
memset(&config, 0, sizeof(Config_s));
char *json_buf = NULL;
u32 json_len = file_to_buf(fsMakePath(PATH_ASCII, "/3ds/" APP_TITLE "/config.json"), ArchiveSD, &json_buf);
@@ -69,7 +71,7 @@ void load_config(void)
config.background_color = C2D_Color32(r, g, b, a);
}
}
else if (json_is_array(value) && !strcmp(key, "Red Color") && json_array_size(value) == 4)
else if (json_is_array(value) && !strcmp(key, "White Color Background") && json_array_size(value) == 4)
{
if (json_is_integer(json_array_get(value, 0)) && json_is_integer(json_array_get(value, 1))
&& json_is_integer(json_array_get(value, 2)) && json_is_integer(json_array_get(value, 3)))
@@ -79,7 +81,72 @@ void load_config(void)
u8 b = min(255, json_integer_value(json_array_get(value, 2)));
u8 a = min(255, json_integer_value(json_array_get(value, 3)));
config.red_color = C2D_Color32(r, g, b, a);
config.white_color_background = C2D_Color32(r, g, b, a);
}
}
else if (json_is_array(value) && !strcmp(key, "White Color Accent") && json_array_size(value) == 4)
{
if (json_is_integer(json_array_get(value, 0)) && json_is_integer(json_array_get(value, 1))
&& json_is_integer(json_array_get(value, 2)) && json_is_integer(json_array_get(value, 3)))
{
u8 r = min(255, json_integer_value(json_array_get(value, 0)));
u8 g = min(255, json_integer_value(json_array_get(value, 1)));
u8 b = min(255, json_integer_value(json_array_get(value, 2)));
u8 a = min(255, json_integer_value(json_array_get(value, 3)));
config.white_color_accent = C2D_Color32(r, g, b, a);
}
}
else if (json_is_array(value) && !strcmp(key, "Cursor Color") && json_array_size(value) == 4)
{
if (json_is_integer(json_array_get(value, 0)) && json_is_integer(json_array_get(value, 1))
&& json_is_integer(json_array_get(value, 2)) && json_is_integer(json_array_get(value, 3)))
{
u8 r = min(255, json_integer_value(json_array_get(value, 0)));
u8 g = min(255, json_integer_value(json_array_get(value, 1)));
u8 b = min(255, json_integer_value(json_array_get(value, 2)));
u8 a = min(255, json_integer_value(json_array_get(value, 3)));
config.cursor_color = C2D_Color32(r, g, b, a);
}
}
else if (json_is_array(value) && !strcmp(key, "Black Color") && json_array_size(value) == 4)
{
if (json_is_integer(json_array_get(value, 0)) && json_is_integer(json_array_get(value, 1))
&& json_is_integer(json_array_get(value, 2)) && json_is_integer(json_array_get(value, 3)))
{
u8 r = min(255, json_integer_value(json_array_get(value, 0)));
u8 g = min(255, json_integer_value(json_array_get(value, 1)));
u8 b = min(255, json_integer_value(json_array_get(value, 2)));
u8 a = min(255, json_integer_value(json_array_get(value, 3)));
config.black_color = C2D_Color32(r, g, b, a);
}
}
else if (json_is_array(value) && !strcmp(key, "Red Color Background") && json_array_size(value) == 4)
{
if (json_is_integer(json_array_get(value, 0)) && json_is_integer(json_array_get(value, 1))
&& json_is_integer(json_array_get(value, 2)) && json_is_integer(json_array_get(value, 3)))
{
u8 r = min(255, json_integer_value(json_array_get(value, 0)));
u8 g = min(255, json_integer_value(json_array_get(value, 1)));
u8 b = min(255, json_integer_value(json_array_get(value, 2)));
u8 a = min(255, json_integer_value(json_array_get(value, 3)));
config.red_color_background = C2D_Color32(r, g, b, a);
}
}
else if (json_is_array(value) && !strcmp(key, "Red Color Accent") && json_array_size(value) == 4)
{
if (json_is_integer(json_array_get(value, 0)) && json_is_integer(json_array_get(value, 1))
&& json_is_integer(json_array_get(value, 2)) && json_is_integer(json_array_get(value, 3)))
{
u8 r = min(255, json_integer_value(json_array_get(value, 0)));
u8 g = min(255, json_integer_value(json_array_get(value, 1)));
u8 b = min(255, json_integer_value(json_array_get(value, 2)));
u8 a = min(255, json_integer_value(json_array_get(value, 3)));
config.red_color_accent = C2D_Color32(r, g, b, a);
}
}
else if (json_is_array(value) && !strcmp(key, "Yellow Color") && json_array_size(value) == 4)
@@ -95,6 +162,54 @@ void load_config(void)
config.yellow_color = C2D_Color32(r, g, b, a);
}
}
else if (json_is_string(value) && !strcmp(key, "Themes Path"))
{
bool need_slash = json_string_value(value)[strlen(json_string_value(value)) - 1] != '/';
char *theme_path = calloc(1, strlen(json_string_value(value)) + 1 + (need_slash ? 1 : 0));
memcpy(theme_path, json_string_value(value), strlen(json_string_value(value)));
if (need_slash) theme_path[strlen(json_string_value(value))] = '/';
if (R_SUCCEEDED(res = FSUSER_OpenDirectory(&test_handle, ArchiveSD, fsMakePath(PATH_ASCII, theme_path))))
{
main_paths[REMOTE_MODE_THEMES] = theme_path;
FSDIR_Close(test_handle);
} else
{
DEBUG("Failed test - reverting to default. Err 0x%08lx\n", res);
free(theme_path);
}
}
else if (json_is_string(value) && !strcmp(key, "Splashes Path"))
{
bool need_slash = json_string_value(value)[strlen(json_string_value(value)) - 1] != '/';
char *splash_path = calloc(1, strlen(json_string_value(value)) + 1 + (need_slash ? 1 : 0));
memcpy(splash_path, json_string_value(value), strlen(json_string_value(value)));
if (need_slash) splash_path[strlen(json_string_value(value))] = '/';
if (R_SUCCEEDED(res = FSUSER_OpenDirectory(&test_handle, ArchiveSD, fsMakePath(PATH_ASCII, splash_path))))
{
main_paths[REMOTE_MODE_SPLASHES] = splash_path;
FSDIR_Close(test_handle);
} else
{
DEBUG("Failed test - reverting to default. Err 0x%08lx\n", res);
free(splash_path);
}
}
else if (json_is_string(value) && !strcmp(key, "Badges Path"))
{
bool need_slash = json_string_value(value)[strlen(json_string_value(value)) - 1] != '/';
char *badge_path = calloc(1, strlen(json_string_value(value)) + 1 + (need_slash ? 1 : 0));
memcpy(badge_path, json_string_value(value), strlen(json_string_value(value)));
if (need_slash) badge_path[strlen(json_string_value(value))] = '/';
if (R_SUCCEEDED(res = FSUSER_OpenDirectory(&test_handle, ArchiveSD, fsMakePath(PATH_ASCII, badge_path))))
{
main_paths[REMOTE_MODE_BADGES] = badge_path;
FSDIR_Close(test_handle);
} else
{
DEBUG("Failed test - reverting to default. Err 0x%08lx\n", res);
free(badge_path);
}
}
}
} else
{
@@ -107,9 +222,24 @@ void load_config(void)
if (config.background_color == 0)
config.background_color = C2D_Color32(35, 28, 32, 255); //silver-y black
if (config.red_color == 0)
config.red_color = C2D_Color32(229, 66, 66, 255);
if (config.white_color_background == 0)
config.white_color_background = C2D_Color32(255, 255, 255, 255);
if (config.white_color_accent == 0)
config.white_color_accent = C2D_Color32(255, 255, 255, 255);
if (config.cursor_color == 0)
config.cursor_color = C2D_Color32(200, 200, 200, 255);
if (config.black_color == 0)
config.black_color = C2D_Color32(0, 0, 0, 255);
if (config.red_color_background == 0)
config.red_color_background = C2D_Color32(229, 66, 66, 255);
if (config.red_color_accent == 0)
config.red_color_accent = C2D_Color32(229, 66, 66, 255);
if (config.yellow_color == 0)
config.yellow_color = C2D_Color32(239, 220, 11, 255);

View File

@@ -173,6 +173,11 @@ void end_frame(void)
C3D_FrameEnd(0);
}
static void draw_image_tint(int image_id, float x, float y, C2D_ImageTint tint)
{
C2D_DrawImageAt(C2D_SpriteSheetGetImage(spritesheet, image_id), x, y, 0.6f, &tint, 1.0f, 1.0f);
}
static void draw_image(int image_id, float x, float y)
{
C2D_DrawImageAt(C2D_SpriteSheetGetImage(spritesheet, image_id), x, y, 0.6f, NULL, 1.0f, 1.0f);
@@ -271,10 +276,10 @@ void draw_base_interface(void)
C2D_TextParse(&minutes, dynamicBuf, string_minutes);
C2D_TextOptimize(&minutes);
C2D_DrawText(&hours, C2D_WithColor, 7, 2, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE]);
C2D_DrawText(&hours, C2D_WithColor, 7, 2, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE_ACCENT]);
if(tm.tm_sec % 2 == 1)
C2D_DrawText(&separator, C2D_WithColor, 28, 1, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE]);
C2D_DrawText(&minutes, C2D_WithColor, 34, 2, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE]);
C2D_DrawText(&separator, C2D_WithColor, 28, 1, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE_ACCENT]);
C2D_DrawText(&minutes, C2D_WithColor, 34, 2, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE_ACCENT]);
#ifndef CITRA_MODE
u8 battery_charging = 0;
@@ -291,7 +296,7 @@ void draw_base_interface(void)
C2D_DrawRectSolid(0, 0, 0.5f, 320, 24, colors[COLOR_ACCENT]);
C2D_DrawRectSolid(0, 216, 0.5f, 320, 24, colors[COLOR_ACCENT]);
C2D_DrawText(&text[TEXT_VERSION], C2D_WithColor, 7, 219, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE]);
C2D_DrawText(&text[TEXT_VERSION], C2D_WithColor, 7, 219, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE_ACCENT]);
set_screen(top);
}
@@ -299,13 +304,13 @@ void draw_base_interface(void)
void throw_error(const char * error, ErrorLevel level)
{
Text bottom_text = TEXT_AMOUNT;
Color text_color = COLOR_WHITE;
Color text_color = COLOR_WHITE_BACKGROUND;
switch(level)
{
case ERROR_LEVEL_ERROR:
bottom_text = TEXT_ERROR_QUIT;
text_color = COLOR_RED;
text_color = COLOR_RED_BACKGROUND;
break;
case ERROR_LEVEL_WARNING:
bottom_text = TEXT_ERROR_CONTINUE;
@@ -322,7 +327,7 @@ void throw_error(const char * error, ErrorLevel level)
draw_base_interface();
draw_text_center(GFX_TOP, 100, 0.5f, 0.6f, 0.6f, colors[text_color], error);
draw_c2d_text_center(GFX_TOP, 170, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE], &text[bottom_text]);
draw_c2d_text_center(GFX_TOP, 170, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE_BACKGROUND], &text[bottom_text]);
end_frame();
if(kDown & KEY_A) break;
@@ -337,7 +342,7 @@ bool draw_confirm(const char * conf_msg, Entry_List_s * list, DrawMode draw_mode
draw_interface(list, instructions, draw_mode);
set_screen(top);
draw_text_center(GFX_TOP, BUTTONS_Y_LINE_1, 0.5f, 0.7f, 0.7f, colors[COLOR_YELLOW], conf_msg);
draw_c2d_text_center(GFX_TOP, BUTTONS_Y_LINE_3, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE], &text[TEXT_CONFIRM_YES_NO]);
draw_c2d_text_center(GFX_TOP, BUTTONS_Y_LINE_3, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE_BACKGROUND], &text[TEXT_CONFIRM_YES_NO]);
end_frame();
hidScanInput();
@@ -355,7 +360,7 @@ bool draw_confirm_no_interface(const char *conf_msg)
{
draw_base_interface();
draw_text_center(GFX_TOP, 100, 0.5f, 0.7f, 0.7f, colors[COLOR_YELLOW], conf_msg);
draw_c2d_text_center(GFX_TOP, 170, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE], &text[TEXT_CONFIRM_YES_NO]);
draw_c2d_text_center(GFX_TOP, 170, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE_BACKGROUND], &text[TEXT_CONFIRM_YES_NO]);
end_frame();
hidScanInput();
@@ -381,7 +386,7 @@ static void draw_install_handler(InstallType type)
if(type != INSTALL_NONE)
{
C2D_Text * install_text = &text[type];
draw_c2d_text_center(GFX_TOP, 120.0f, 0.5f, 0.8f, 0.8f, colors[COLOR_WHITE], install_text);
draw_c2d_text_center(GFX_TOP, 120.0f, 0.5f, 0.8f, 0.8f, colors[COLOR_WHITE_BACKGROUND], install_text);
}
}
@@ -408,7 +413,7 @@ void draw_loading_bar(u32 current, u32 max, InstallType type)
static void draw_instructions(Instructions_s instructions)
{
if(instructions.info_line != NULL)
draw_text_center(GFX_TOP, BUTTONS_Y_INFO, 0.5, 0.55, 0.55, colors[COLOR_WHITE], instructions.info_line);
draw_text_center(GFX_TOP, BUTTONS_Y_INFO, 0.5, 0.55, 0.55, colors[COLOR_WHITE_BACKGROUND], instructions.info_line);
const int y_lines[BUTTONS_INFO_LINES-1] = {
BUTTONS_Y_LINE_1,
@@ -419,20 +424,20 @@ static void draw_instructions(Instructions_s instructions)
for(int i = 0; i < BUTTONS_INFO_LINES-1; i++)
{
if(instructions.instructions[i][0] != NULL)
draw_text_wrap_scaled(BUTTONS_X_LEFT, y_lines[i], 0.5, colors[COLOR_WHITE], instructions.instructions[i][0], 0.6, 0, BUTTONS_X_RIGHT-2);
draw_text_wrap_scaled(BUTTONS_X_LEFT, y_lines[i], 0.5, colors[COLOR_WHITE_BACKGROUND], instructions.instructions[i][0], 0.6, 0, BUTTONS_X_RIGHT-2);
if(instructions.instructions[i][1] != NULL)
draw_text_wrap_scaled(BUTTONS_X_RIGHT, y_lines[i], 0.5, colors[COLOR_WHITE], instructions.instructions[i][1], 0.6, 0, BUTTONS_X_MAX-2);
draw_text_wrap_scaled(BUTTONS_X_RIGHT, y_lines[i], 0.5, colors[COLOR_WHITE_BACKGROUND], instructions.instructions[i][1], 0.6, 0, BUTTONS_X_MAX-2);
}
C2D_ImageTint white_tint;
C2D_PlainImageTint(&white_tint, colors[COLOR_WHITE], 1.0f);
C2D_PlainImageTint(&white_tint, colors[COLOR_WHITE_BACKGROUND], 1.0f);
const char * start_line = instructions.instructions[BUTTONS_INFO_LINES-1][0];
if(start_line != NULL)
{
C2D_SpriteSetPos(&sprite_start, BUTTONS_X_LEFT-10, BUTTONS_Y_LINE_4 + 3);
C2D_DrawSpriteTinted(&sprite_start, &white_tint);
draw_text_wrap_scaled(BUTTONS_X_LEFT+26, BUTTONS_Y_LINE_4, 0.5, colors[COLOR_WHITE], start_line, 0.6, 0, BUTTONS_X_RIGHT-2);
draw_text_wrap_scaled(BUTTONS_X_LEFT+26, BUTTONS_Y_LINE_4, 0.5, colors[COLOR_WHITE_BACKGROUND], start_line, 0.6, 0, BUTTONS_X_RIGHT-2);
}
const char * select_line = instructions.instructions[BUTTONS_INFO_LINES-1][1];
@@ -440,7 +445,7 @@ static void draw_instructions(Instructions_s instructions)
{
C2D_SpriteSetPos(&sprite_select, BUTTONS_X_RIGHT-10, BUTTONS_Y_LINE_4 + 3);
C2D_DrawSpriteTinted(&sprite_select, &white_tint);
draw_text_wrap_scaled(BUTTONS_X_RIGHT+26, BUTTONS_Y_LINE_4, 0.5, colors[COLOR_WHITE], select_line, 0.6, 0, BUTTONS_X_MAX-2);
draw_text_wrap_scaled(BUTTONS_X_RIGHT+26, BUTTONS_Y_LINE_4, 0.5, colors[COLOR_WHITE_BACKGROUND], select_line, 0.6, 0, BUTTONS_X_MAX-2);
}
}
@@ -528,18 +533,18 @@ static void draw_entry_info(Entry_s * entry)
{
char author[0x41] = {0};
utf16_to_utf8((u8 *)author, entry->author, 0x40);
draw_c2d_text(20, 35, 0.5, 0.5, 0.5, colors[COLOR_WHITE], &text[TEXT_BY_AUTHOR]);
draw_c2d_text(20, 35, 0.5, 0.5, 0.5, colors[COLOR_WHITE_BACKGROUND], &text[TEXT_BY_AUTHOR]);
float width = 0;
C2D_TextGetDimensions(&text[TEXT_BY_AUTHOR], 0.5, 0.5, &width, NULL);
draw_text(20+width, 35, 0.5, 0.5, 0.5, colors[COLOR_WHITE], author);
draw_text(20+width, 35, 0.5, 0.5, 0.5, colors[COLOR_WHITE_BACKGROUND], author);
char title[0x41] = {0};
utf16_to_utf8((u8 *)title, entry->name, 0x40);
draw_text(20, 50, 0.5, 0.7, 0.7, colors[COLOR_WHITE], title);
draw_text(20, 50, 0.5, 0.7, 0.7, colors[COLOR_WHITE_BACKGROUND], title);
char description[0x81] = {0};
utf16_to_utf8((u8 *)description, entry->desc, 0x80);
draw_text_wrap(20, 70, 0.5, 0.5, 0.5, colors[COLOR_WHITE], description, 363);
draw_text_wrap(20, 70, 0.5, 0.5, 0.5, colors[COLOR_WHITE_BACKGROUND], description, 363);
}
void draw_grid_interface(Entry_List_s * list, Instructions_s instructions, int extra_mode)
@@ -553,7 +558,7 @@ void draw_grid_interface(Entry_List_s * list, Instructions_s instructions, int e
&text[TEXT_THEMEPLAZA_BADGE_MODE],
};
draw_c2d_text_center(GFX_TOP, 4, 0.5f, 0.5f, 0.5f, colors[COLOR_WHITE], mode_string[current_mode]);
draw_c2d_text_center(GFX_TOP, 4, 0.5f, 0.5f, 0.5f, colors[COLOR_WHITE_ACCENT], mode_string[current_mode]);
draw_instructions(instructions);
@@ -563,16 +568,22 @@ void draw_grid_interface(Entry_List_s * list, Instructions_s instructions, int e
set_screen(bottom);
draw_c2d_text(7, 3, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE], &text[TEXT_SEARCH]);
draw_c2d_text(7, 3, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE_ACCENT], &text[TEXT_SEARCH]);
draw_image(sprites_back_idx, 320-96, 0);
draw_image(sprites_exit_idx, 320-72, 0);
draw_image(sprites_preview_idx, 320-48, 0);
C2D_ImageTint accent_tint;
C2D_PlainImageTint(&accent_tint, colors[COLOR_WHITE_ACCENT], 1.0f);
draw_text(320-24+2.5, -3, 0.6, 1.0f, 0.9f, colors[COLOR_WHITE], remote_mode_switch_char[current_mode]);
draw_image_tint(sprites_back_idx, 320-96, 0, accent_tint);
draw_image_tint(sprites_exit_idx, 320-72, 0, accent_tint);
draw_image_tint(sprites_preview_idx, 320-48, 0, accent_tint);
draw_image(sprites_arrow_left_idx, 3, 114);
draw_image(sprites_arrow_right_idx, 308, 114);
draw_text(320-24+2.5, -3, 0.6, 1.0f, 0.9f, colors[COLOR_WHITE_ACCENT], remote_mode_switch_char[current_mode]);
C2D_ImageTint background_tint;
C2D_PlainImageTint(&background_tint, colors[COLOR_WHITE_BACKGROUND], 1.0f);
draw_image_tint(sprites_arrow_left_idx, 3, 114, background_tint);
draw_image_tint(sprites_arrow_right_idx, 308, 114, background_tint);
for(int i = list->scroll; i < (list->entries_loaded + list->scroll); i++)
{
@@ -625,15 +636,15 @@ void draw_grid_interface(Entry_List_s * list, Instructions_s instructions, int e
float width = 0;
get_text_dimensions(entries_count_str, 0.6, 0.6, &width, NULL);
x -= width;
draw_text(x, 219, 0.5, 0.6, 0.6, colors[COLOR_WHITE], entries_count_str);
draw_text(x, 219, 0.5, 0.6, 0.6, colors[COLOR_WHITE_ACCENT], entries_count_str);
char selected_entry_str[0x20] = {0};
sprintf(selected_entry_str, "%" JSON_INTEGER_FORMAT, list->tp_current_page);
get_text_dimensions(selected_entry_str, 0.6, 0.6, &width, NULL);
x -= width;
draw_text(x, 219, 0.5, 0.6, 0.6, colors[COLOR_WHITE], selected_entry_str);
draw_text(x, 219, 0.5, 0.6, 0.6, colors[COLOR_WHITE_ACCENT], selected_entry_str);
draw_c2d_text(176, 219, 0.5, 0.6, 0.6, colors[COLOR_WHITE], &text[TEXT_PAGE]);
draw_c2d_text(176, 219, 0.5, 0.6, 0.6, colors[COLOR_WHITE_ACCENT], &text[TEXT_PAGE]);
}
void draw_interface(Entry_List_s * list, Instructions_s instructions, DrawMode draw_mode)
@@ -646,7 +657,10 @@ void draw_interface(Entry_List_s * list, Instructions_s instructions, DrawMode d
&text[TEXT_SPLASH_MODE],
};
draw_c2d_text_center(GFX_TOP, 4, 0.5f, 0.5f, 0.5f, colors[COLOR_WHITE], mode_string[current_mode]);
C2D_ImageTint accent_tint;
C2D_PlainImageTint(&accent_tint, colors[COLOR_WHITE_ACCENT], 1.0f);
draw_c2d_text_center(GFX_TOP, 4, 0.5f, 0.5f, 0.5f, colors[COLOR_WHITE_ACCENT], mode_string[current_mode]);
if(list->entries == NULL || list->entries_count == 0)
{
@@ -675,11 +689,11 @@ void draw_interface(Entry_List_s * list, Instructions_s instructions, DrawMode d
set_screen(bottom);
draw_image(sprites_qr_idx, 320-96, 0);
draw_image(sprites_browse_idx, 320-72, 0);
draw_image(sprites_exit_idx, 320-48, 0);
draw_image_tint(sprites_qr_idx, 320-96, 0, accent_tint);
draw_image_tint(sprites_browse_idx, 320-72, 0, accent_tint);
draw_image_tint(sprites_exit_idx, 320-48, 0, accent_tint);
draw_text(320-24+2.5, -3, 0.6, 1.0f, 0.9f, colors[COLOR_WHITE], mode_switch_char[!current_mode]);
draw_text(320-24+2.5, -3, 0.6, 1.0f, 0.9f, colors[COLOR_WHITE_ACCENT], mode_switch_char[!current_mode]);
return;
}
@@ -696,48 +710,48 @@ void draw_interface(Entry_List_s * list, Instructions_s instructions, DrawMode d
{
char * shuffle_count_string = NULL;
asprintf(&shuffle_count_string, language.draw.shuffle, list->shuffle_count);
draw_text(30, 3, 0.6, 0.6, 0.6f, list->shuffle_count <= 10 && list->shuffle_count >= 2 ? colors[COLOR_WHITE] : colors[COLOR_RED], shuffle_count_string);
draw_text(30, 3, 0.6, 0.6, 0.6f, list->shuffle_count <= 10 && list->shuffle_count >= 2 ? colors[COLOR_WHITE_ACCENT] : colors[COLOR_RED_ACCENT], shuffle_count_string);
free(shuffle_count_string);
}
if (draw_mode == DRAW_MODE_LIST)
{
draw_image(sprites_install_idx, 320-120, 0);
draw_image(sprites_qr_idx, 320-96, 0);
draw_image(sprites_exit_idx, 320-72, 0);
draw_image(sprites_preview_idx, 320-48, 0);
draw_text(320-24+2.5, -3, 0.6, 1.0f, 0.9f, colors[COLOR_WHITE], mode_switch_char[!current_mode]);
draw_image(sprites_menu_idx, 2, 0);
draw_image_tint(sprites_install_idx, 320-120, 0, accent_tint);
draw_image_tint(sprites_qr_idx, 320-96, 0, accent_tint);
draw_image_tint(sprites_exit_idx, 320-72, 0, accent_tint);
draw_image_tint(sprites_preview_idx, 320-48, 0, accent_tint);
draw_text(320-24+2.5, -3, 0.6, 1.0f, 0.9f, colors[COLOR_WHITE_ACCENT], mode_switch_char[!current_mode]);
draw_image_tint(sprites_menu_idx, 2, 0, accent_tint);
if (current_mode == MODE_THEMES)
{
draw_image(sprites_shuffle_idx, 320-144, 0);
draw_image_tint(sprites_shuffle_idx, 320-144, 0, accent_tint);
}
}
else
{
if (draw_mode == DRAW_MODE_INSTALL)
{
draw_image(sprites_install_idx, 320-24, 0);
draw_image(sprites_shuffle_idx, 320-48, 0);
draw_image(sprites_shuffle_no_bgm_idx, 320-72, 0);
draw_image(sprites_bgm_only_idx, 320-96, 0);
draw_image(sprites_back_idx, 2, 0);
draw_image_tint(sprites_install_idx, 320-24, 0, accent_tint);
draw_image_tint(sprites_shuffle_idx, 320-48, 0, accent_tint);
draw_image_tint(sprites_shuffle_no_bgm_idx, 320-72, 0, accent_tint);
draw_image_tint(sprites_bgm_only_idx, 320-96, 0, accent_tint);
draw_image_tint(sprites_back_idx, 2, 0, accent_tint);
} else if (draw_mode == DRAW_MODE_EXTRA)
{
draw_image(sprites_browse_idx, 320-24, 0);
draw_image(sprites_dump_idx, 320-48, 0);
draw_image(sprites_sort_idx, 320-72, 0);
draw_image(sprites_badge_idx, 320-96, 0);
draw_image(sprites_back_idx, 2, 0);
draw_image_tint(sprites_browse_idx, 320-24, 0, accent_tint);
draw_image_tint(sprites_dump_idx, 320-48, 0, accent_tint);
draw_image_tint(sprites_sort_idx, 320-72, 0, accent_tint);
draw_image_tint(sprites_badge_idx, 320-96, 0, accent_tint);
draw_image_tint(sprites_back_idx, 2, 0, accent_tint);
}
}
// Show arrows if there are themes out of bounds
//----------------------------------------------------------------
if(list->scroll > 0)
draw_image(sprites_arrow_up_idx, 141, 220);
draw_image_tint(sprites_arrow_up_idx, 141, 220, accent_tint);
if(list->scroll + list->entries_loaded < list->entries_count)
draw_image(sprites_arrow_down_idx, 157, 220);
draw_image_tint(sprites_arrow_down_idx, 157, 220, accent_tint);
for(int i = list->scroll; i < (list->entries_loaded + list->scroll); i++)
{
@@ -754,7 +768,7 @@ void draw_interface(Entry_List_s * list, Instructions_s instructions, DrawMode d
vertical_offset *= list->entry_size;
vertical_offset += 24;
u32 font_color = colors[COLOR_WHITE];
u32 font_color = colors[COLOR_WHITE_BACKGROUND];
if(i == selected_entry)
{
@@ -808,18 +822,18 @@ void draw_interface(Entry_List_s * list, Instructions_s instructions, DrawMode d
float width = 0;
get_text_dimensions(entries_count_str, 0.6, 0.6, &width, NULL);
x -= width;
draw_text(x, 219, 0.5, 0.6, 0.6, colors[COLOR_WHITE], entries_count_str);
draw_text(x, 219, 0.5, 0.6, 0.6, colors[COLOR_WHITE_ACCENT], entries_count_str);
char selected_entry_str[0x20] = {0};
sprintf(selected_entry_str, "%i", selected_entry + 1);
get_text_dimensions(selected_entry_str, 0.6, 0.6, &width, NULL);
x -= width;
draw_text(x, 219, 0.5, 0.6, 0.6, colors[COLOR_WHITE], selected_entry_str);
draw_text(x, 219, 0.5, 0.6, 0.6, colors[COLOR_WHITE_ACCENT], selected_entry_str);
if(list->entries_count < 10000)
draw_c2d_text(176, 219, 0.5, 0.6, 0.6, colors[COLOR_WHITE], &text[TEXT_SELECTED]);
draw_c2d_text(176, 219, 0.5, 0.6, 0.6, colors[COLOR_WHITE_ACCENT], &text[TEXT_SELECTED]);
else
draw_c2d_text(176, 219, 0.5, 0.6, 0.6, colors[COLOR_WHITE], &text[TEXT_SELECTED_SHORT]);
draw_c2d_text(176, 219, 0.5, 0.6, 0.6, colors[COLOR_WHITE_ACCENT], &text[TEXT_SELECTED_SHORT]);
if(draw_mode != DRAW_MODE_LIST)
{
C2D_DrawRectSolid(0, 24, 1.0f, 320, 240-48, C2D_Color32(0, 0, 0, 128));

View File

@@ -117,10 +117,9 @@ Result open_archives(void)
archive2 = 0x00;
}
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_ASCII, "/Themes"), FS_ATTRIBUTE_DIRECTORY);
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_ASCII, "/Splashes"), FS_ATTRIBUTE_DIRECTORY);
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_ASCII, "/Badges"), FS_ATTRIBUTE_DIRECTORY);
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_ASCII, "/Badges/ThemePlaza Badges"), FS_ATTRIBUTE_DIRECTORY);
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_ASCII, main_paths[REMOTE_MODE_THEMES]), FS_ATTRIBUTE_DIRECTORY);
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_ASCII, main_paths[REMOTE_MODE_SPLASHES]), FS_ATTRIBUTE_DIRECTORY);
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_ASCII, main_paths[REMOTE_MODE_BADGES]), FS_ATTRIBUTE_DIRECTORY);
u32 homeMenuPath[3] = {MEDIATYPE_SD, archive2, 0};
home.type = PATH_BINARY;
@@ -189,7 +188,12 @@ Result open_badge_extdata()
}
FSFILE_Close(test_handle);
if(R_FAILED(res = FSUSER_OpenFile(&test_handle, ArchiveSD, fsMakePath(PATH_ASCII, "/Badges/ThemePlaza Badges/_seticon.png"), FS_OPEN_READ, 0)))
char tp_path[0x106] = {0};
sprintf(tp_path, "%sThemePlaza Badges", main_paths[REMOTE_MODE_BADGES]);
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_ASCII, tp_path), FS_ATTRIBUTE_DIRECTORY);
strcat(tp_path, "/_seticon.png");
if(R_FAILED(res = FSUSER_OpenFile(&test_handle, ArchiveSD, fsMakePath(PATH_ASCII, tp_path), FS_OPEN_READ, 0)))
{
FILE *fp = fopen("romfs:/tp_set.png", "rb");
fseek(fp, 0L, SEEK_END);
@@ -198,8 +202,8 @@ Result open_badge_extdata()
fseek(fp, 0L, SEEK_SET);
fread(icon_buf, 1, size, fp);
fclose(fp);
remake_file(fsMakePath(PATH_ASCII, "/Badges/ThemePlaza Badges/_seticon.png"), ArchiveSD, size);
buf_to_file(size, fsMakePath(PATH_ASCII, "/Badges/ThemePlaza Badges/_seticon.png"), ArchiveSD, icon_buf);
remake_file(fsMakePath(PATH_ASCII, tp_path), ArchiveSD, size);
buf_to_file(size, fsMakePath(PATH_ASCII, tp_path), ArchiveSD, icon_buf);
DEBUG("res: 0x%08lx\n", res);
free(icon_buf);
}
@@ -271,6 +275,9 @@ s16 for_each_file_zip(u16 *zip_path, u32 (*zip_iter_callback)(char *filebuf, u64
if(r != ARCHIVE_OK)
{
DEBUG("Invalid zip being opened\n");
char path[0x128] = {0};
utf16_to_utf8((u8 *) path, zip_path, 0x128);
DEBUG("%s\n", path);
return -1;
}
@@ -346,6 +353,9 @@ u32 zip_file_to_buf(const char * file_name, const u16 * zip_path, char ** buf)
if(r != ARCHIVE_OK)
{
DEBUG("Invalid zip being opened\n");
char path[0x128] = {0};
utf16_to_utf8((u8 *) path, zip_path, 0x128);
DEBUG("%s\n", path);
return 0;
}
@@ -512,7 +522,8 @@ void remake_file(FS_Path path, FS_Archive archive, u32 size)
FSFILE_Close(handle);
FSUSER_DeleteFile(archive, path);
}
FSUSER_CreateFile(archive, path, 0, size);
Result res = FSUSER_CreateFile(archive, path, 0, size);
DEBUG("Remake file res: 0x%08lx\n", res);
char * buf = calloc(size, 1);
if (buf == NULL)
{
@@ -565,9 +576,9 @@ renamed:
char * curr_filename;
if (mode == REMOTE_MODE_BADGES)
{
DEBUG("Remote mode badges! Saving to /Badges/ThemePlaza Badges/\n");
sprintf(path_to_file, "%s%s", "/Badges/ThemePlaza Badges/", filename);
curr_filename = path_to_file + strlen("/Badges/ThemePlaza Badges/");
sprintf(path_to_file, "%sThemePlaza Badges/%s", main_paths[REMOTE_MODE_BADGES], filename);
DEBUG("Remote mode badges! Saving to %s/\n", path_to_file);
curr_filename = path_to_file + strlen(main_paths[REMOTE_MODE_BADGES]) + strlen("ThemePlaza Badges/");
} else
{
sprintf(path_to_file, "%s%s", main_paths[mode], filename);

View File

@@ -61,10 +61,12 @@ Result archive_result;
Result badge_archive_result;
u32 old_time_limit;
const char * main_paths[MODE_AMOUNT] = {
const char * main_paths[REMOTE_MODE_AMOUNT] = {
"/Themes/",
"/Splashes/",
"/Badges/"
};
const int entries_per_screen_v[MODE_AMOUNT] = {
4,
4,
@@ -379,8 +381,7 @@ int main(void)
{
srand(time(NULL));
init_services();
CFG_Language lang;
CFGU_GetSystemLanguage(&lang);
const CFG_Language lang = get_system_language();
language = init_strings(lang);
init_screens();
@@ -535,7 +536,7 @@ int main(void)
{
enable_qr:
draw_base_interface();
draw_text_center(GFX_TOP, 100, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE], language.main.loading_qr);
draw_text_center(GFX_TOP, 100, 0.5f, 0.6f, 0.6f, colors[COLOR_WHITE_BACKGROUND], language.main.loading_qr);
end_frame();
if(R_SUCCEEDED(camInit()))
{

View File

@@ -378,7 +378,7 @@ Result dump_current_theme(void)
}
u16 path[0x107] = { 0 };
struacat(path, "/themes/");
struacat(path, main_paths[REMOTE_MODE_THEMES]);
struacat(path, output_dir);
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_UTF16, path), FS_ATTRIBUTE_DIRECTORY);
@@ -614,7 +614,7 @@ Result dump_all_themes(void)
}
char path[0x107] = { 0 };
sprintf(path, "/Themes/Dump-%02lx-%ld-%s", dlc_index, extra_index, themename);
sprintf(path, "%sDump-%02lx-%ld-%s", main_paths[REMOTE_MODE_THEMES], dlc_index, extra_index, themename);
DEBUG("theme folder to create: %s\n", path);
FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_ASCII, path), FS_ATTRIBUTE_DIRECTORY);

View File

@@ -2086,3 +2086,12 @@ Language_s init_strings(CFG_Language lang)
return language_english;
}
}
CFG_Language get_system_language(void)
{
u8 lang = CFG_LANGUAGE_EN;
// can never fail, cfguInit is one of the very first thing that happens on start
// and if it does anyway, default to english
CFGU_GetSystemLanguage(&lang);
return (CFG_Language)lang;
}