From a266203a9287358ece5f76e6c32fc0c4790ba8e6 Mon Sep 17 00:00:00 2001 From: Alex Taber Date: Thu, 24 Dec 2020 14:34:56 -0500 Subject: [PATCH] Add theme dump functionality --- include/draw.h | 4 ++ include/instructions.h | 4 +- include/themes.h | 4 +- source/draw.c | 1 + source/main.c | 7 ++++ source/themes.c | 93 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 110 insertions(+), 3 deletions(-) diff --git a/include/draw.h b/include/draw.h index ea6d08c..b35dd6f 100644 --- a/include/draw.h +++ b/include/draw.h @@ -55,6 +55,8 @@ typedef enum { INSTALL_LOADING_REMOTE_PREVIEW, INSTALL_LOADING_REMOTE_BGM, + INSTALL_DUMPING_THEME, + INSTALL_NONE, } InstallType; @@ -81,6 +83,8 @@ typedef enum { TEXT_INSTALL_LOADING_REMOTE_PREVIEW, TEXT_INSTALL_LOADING_REMOTE_BGM, + TEXT_INSTALL_DUMPING_THEME, + // Other text TEXT_VERSION, diff --git a/include/instructions.h b/include/instructions.h index 7cb0490..d37ed99 100644 --- a/include/instructions.h +++ b/include/instructions.h @@ -128,7 +128,7 @@ Instructions_s extra_instructions[3] = { }, { "\uE07B Browse ThemePlaza", - NULL, + "\uE07C Dump Current Theme" }, { "\uE004 Sorting menu", @@ -142,4 +142,4 @@ Instructions_s extra_instructions[3] = { }, }; -#endif \ No newline at end of file +#endif diff --git a/include/themes.h b/include/themes.h index 1e85811..48790d8 100644 --- a/include/themes.h +++ b/include/themes.h @@ -75,6 +75,8 @@ Result bgm_install(Entry_s theme); Result shuffle_install(Entry_List_s themes); +Result dump_theme(void); + void themes_check_installed(void * void_arg); -#endif \ No newline at end of file +#endif diff --git a/source/draw.c b/source/draw.c index ee81dbb..e42d3cd 100644 --- a/source/draw.c +++ b/source/draw.c @@ -125,6 +125,7 @@ void init_screens(void) C2D_TextParse(&text[TEXT_INSTALL_LOADING_REMOTE_SPLASHES], staticBuf, "Downloading splash list, please wait..."); C2D_TextParse(&text[TEXT_INSTALL_LOADING_REMOTE_PREVIEW], staticBuf, "Downloading preview, please wait..."); C2D_TextParse(&text[TEXT_INSTALL_LOADING_REMOTE_BGM], staticBuf, "Downloading BGM, please wait..."); + C2D_TextParse(&text[TEXT_INSTALL_DUMPING_THEME], staticBuf, "Dumping theme, please wait..."); for(int i = 0; i < TEXT_AMOUNT; i++) C2D_TextOptimize(&text[i]); diff --git a/source/main.c b/source/main.c index 57a2911..6667194 100644 --- a/source/main.c +++ b/source/main.c @@ -647,6 +647,13 @@ int main(void) { load_icons_first(current_list, false); } + else if((kDown | kHeld) & KEY_DRIGHT) + { + draw_install(INSTALL_DUMPING_THEME); + Result res = dump_theme(); + if (R_FAILED(res)) DEBUG("Dump theme result: %lx\n", res); + else load_lists(lists); + } } else if(key_l) { diff --git a/source/themes.c b/source/themes.c index 828bbca..9110375 100644 --- a/source/themes.c +++ b/source/themes.c @@ -315,6 +315,99 @@ inline Result shuffle_install(Entry_List_s themes) return install_theme_internal(themes, THEME_INSTALL_SHUFFLE | THEME_INSTALL_BODY | THEME_INSTALL_BGM); } +static SwkbdCallbackResult +dir_name_callback(void *data, const char ** ppMessage, const char * text, size_t textlen) +{ + (void)textlen; + (void)data; + if(strpbrk(text, "><\"?;:/\\+,.|[=]")) + { + *ppMessage = "Illegal character used."; + return SWKBD_CALLBACK_CONTINUE; + } + return SWKBD_CALLBACK_OK; +} + +Result dump_theme(void) +{ + const int max_chars = 255; + char * output_dir = calloc(max_chars + 1, sizeof(char)); + + SwkbdState swkbd; + + swkbdInit(&swkbd, SWKBD_TYPE_WESTERN, 2, max_chars); + swkbdSetHintText(&swkbd, "Name of output folder"); + + swkbdSetButton(&swkbd, SWKBD_BUTTON_LEFT, "Cancel", false); + swkbdSetButton(&swkbd, SWKBD_BUTTON_RIGHT, "Done", true); + swkbdSetValidation(&swkbd, SWKBD_NOTEMPTY_NOTBLANK, 0, max_chars); + swkbdSetFilterCallback(&swkbd, dir_name_callback, NULL); + + SwkbdButton button = swkbdInputText(&swkbd, output_dir, max_chars); + + if (button != SWKBD_BUTTON_CONFIRM) + { + DEBUG(" Something went wrong with getting swkbd\n"); + return MAKERESULT(RL_FATAL, RS_CANCELED, RM_UTIL, RD_CANCEL_REQUESTED); + } + + u16 path[0x107] = { 0 }; + struacat(path, "/themes/"); + struacat(path, output_dir); + FSUSER_CreateDirectory(ArchiveSD, fsMakePath(PATH_UTF16, path), FS_ATTRIBUTE_DIRECTORY); + + char *thememanage_buf = NULL; + file_to_buf(fsMakePath(PATH_ASCII, "/ThemeManage.bin"), ArchiveThemeExt, &thememanage_buf); + ThemeManage_bin_s * theme_manage = (ThemeManage_bin_s *)thememanage_buf; + u32 theme_size = theme_manage->body_size; + u32 bgm_size = theme_manage->music_size; + free(thememanage_buf); + + char *temp_buf = NULL; + file_to_buf(fsMakePath(PATH_ASCII, "/BodyCache.bin"), ArchiveThemeExt, &temp_buf); + u16 path_output[0x107] = { 0 }; + memcpy(path_output, path, 0x107); + struacat(path_output, "/body_LZ.bin"); + remake_file(fsMakePath(PATH_UTF16, path_output), ArchiveSD, theme_size); + buf_to_file(theme_size, fsMakePath(PATH_UTF16, path_output), ArchiveSD, temp_buf); + free(temp_buf); + temp_buf = NULL; + + file_to_buf(fsMakePath(PATH_ASCII, "/BgmCache.bin"), ArchiveThemeExt, &temp_buf); + memcpy(path_output, path, 0x107); + struacat(path_output, "/bgm.bcstm"); + remake_file(fsMakePath(PATH_UTF16, path_output), ArchiveSD, bgm_size); + buf_to_file(bgm_size, fsMakePath(PATH_UTF16, path_output), ArchiveSD, temp_buf); + free(temp_buf); + temp_buf = NULL; + + char *smdh_file = calloc(1, 0x36c0); + smdh_file[0] = 0x53; // SMDH magic + smdh_file[1] = 0x4d; + smdh_file[2] = 0x44; + smdh_file[3] = 0x48; + + struacat((u16 *) (smdh_file + 0x8), output_dir); + struacat((u16 *) (smdh_file + 0x88), "No description"); + struacat((u16 *) (smdh_file + 0x188), "Unknown Author"); + + free(output_dir); + + u16 color = rand() % 65535; + + for (int i = 0x2040; i < 0x36c0; i += 2) + *(smdh_file + i) = color; + + memcpy(path_output, path, 0x107); + struacat(path_output, "/info.smdh"); + remake_file(fsMakePath(PATH_UTF16, path_output), ArchiveSD, 0x36c0); + buf_to_file(0x36c0, fsMakePath(PATH_UTF16, path_output), ArchiveSD, smdh_file); + + free(smdh_file); + + return 0; +} + void themes_check_installed(void * void_arg) { Thread_Arg_s * arg = (Thread_Arg_s *)void_arg;