diff --git a/source/core/clipboard.c b/source/core/clipboard.c index 2f34809..75fcc0f 100644 --- a/source/core/clipboard.c +++ b/source/core/clipboard.c @@ -5,7 +5,6 @@ #include "clipboard.h" #include "util.h" -#include "../ui/section/task/task.h" static bool clipboard_has = false; static bool clipboard_contents_only; diff --git a/source/core/clipboard.h b/source/core/clipboard.h index 00a5eda..c33265a 100644 --- a/source/core/clipboard.h +++ b/source/core/clipboard.h @@ -1,7 +1,5 @@ #pragma once -typedef struct file_info_s file_info; - bool clipboard_has_contents(); FS_Archive clipboard_get_archive(); char* clipboard_get_path(); diff --git a/source/core/data/bnr.c b/source/core/data/bnr.c new file mode 100644 index 0000000..44e6ad9 --- /dev/null +++ b/source/core/data/bnr.c @@ -0,0 +1,34 @@ +#include <3ds.h> + +#include "bnr.h" +#include "../util.h" + +static CFG_Language region_default_language[] = { + CFG_LANGUAGE_JP, + CFG_LANGUAGE_EN, + CFG_LANGUAGE_EN, + CFG_LANGUAGE_EN, + CFG_LANGUAGE_ZH, + CFG_LANGUAGE_KO, + CFG_LANGUAGE_ZH +}; + +u16* bnr_select_title(BNR* bnr) { + char title[0x100] = {'\0'}; + + CFG_Language systemLanguage; + if(R_SUCCEEDED(CFGU_GetSystemLanguage((u8*) &systemLanguage))) { + utf16_to_utf8((uint8_t*) title, bnr->titles[systemLanguage], sizeof(title) - 1); + } + + if(util_is_string_empty(title)) { + CFG_Region systemRegion; + if(R_SUCCEEDED(CFGU_SecureInfoGetRegion((u8*) &systemRegion))) { + systemLanguage = region_default_language[systemRegion]; + } else { + systemLanguage = CFG_LANGUAGE_JP; + } + } + + return bnr->titles[systemLanguage]; +} \ No newline at end of file diff --git a/source/core/data/bnr.h b/source/core/data/bnr.h new file mode 100644 index 0000000..2425a02 --- /dev/null +++ b/source/core/data/bnr.h @@ -0,0 +1,16 @@ +#pragma once + +typedef struct BNR_s { + u8 version; + bool animated; + u16 crc16[4]; + u8 reserved[0x16]; + u8 mainIconBitmap[0x200]; + u16 mainIconPalette[0x10]; + u16 titles[16][0x80]; + u8 animatedFrameBitmaps[8][0x200]; + u16 animatedFramePalettes[8][0x10]; + u16 animationSequence[0x40]; +} BNR; + +u16* bnr_select_title(BNR* bnr); \ No newline at end of file diff --git a/source/core/data/cia.c b/source/core/data/cia.c new file mode 100644 index 0000000..0f71551 --- /dev/null +++ b/source/core/data/cia.c @@ -0,0 +1,44 @@ +#include <3ds.h> + +#include "cia.h" +#include "smdh.h" +#include "tmd.h" +#include "../util.h" + +u64 cia_get_title_id(u8* cia) { + u32 headerSize = ((*(u32*) &cia[0x00]) + 0x3F) & ~0x3F; + u32 certSize = ((*(u32*) &cia[0x08]) + 0x3F) & ~0x3F; + u32 ticketSize = ((*(u32*) &cia[0x0C]) + 0x3F) & ~0x3F; + + u8* tmd = &cia[headerSize + certSize + ticketSize]; + + return tmd_get_title_id(tmd); +} + +Result cia_file_get_smdh(SMDH* smdh, Handle handle) { + Result res = 0; + + if(smdh != NULL) { + u32 bytesRead = 0; + + u32 header[8]; + if(R_SUCCEEDED(res = FSFILE_Read(handle, &bytesRead, 0, header, sizeof(header))) && bytesRead == sizeof(header)) { + u32 headerSize = (header[0] + 0x3F) & ~0x3F; + u32 certSize = (header[2] + 0x3F) & ~0x3F; + u32 ticketSize = (header[3] + 0x3F) & ~0x3F; + u32 tmdSize = (header[4] + 0x3F) & ~0x3F; + u32 metaSize = (header[5] + 0x3F) & ~0x3F; + u64 contentSize = ((header[6] | ((u64) header[7] << 32)) + 0x3F) & ~0x3F; + + if(metaSize >= 0x3AC0) { + res = FSFILE_Read(handle, &bytesRead, headerSize + certSize + ticketSize + tmdSize + contentSize + 0x400, smdh, sizeof(SMDH)); + } else { + res = R_FBI_BAD_DATA; + } + } + } else { + res = R_FBI_INVALID_ARGUMENT; + } + + return res; +} \ No newline at end of file diff --git a/source/core/data/cia.h b/source/core/data/cia.h new file mode 100644 index 0000000..b1d08e4 --- /dev/null +++ b/source/core/data/cia.h @@ -0,0 +1,6 @@ +#pragma once + +typedef struct SMDH_s SMDH; + +u64 cia_get_title_id(u8* cia); +Result cia_file_get_smdh(SMDH* smdh, Handle handle); \ No newline at end of file diff --git a/source/core/data/smdh.c b/source/core/data/smdh.c new file mode 100644 index 0000000..f97ae93 --- /dev/null +++ b/source/core/data/smdh.c @@ -0,0 +1,73 @@ +#include + +#include <3ds.h> + +#include "smdh.h" +#include "../util.h" + +#define SMDH_NUM_REGIONS 7 +#define SMDH_ALL_REGIONS 0x7F + +static const char* smdh_region_strings[SMDH_NUM_REGIONS] = { + "Japan", + "North America", + "Europe", + "Australia", + "China", + "Korea", + "Taiwan" +}; + +void smdh_region_to_string(char* out, u32 region, size_t size) { + if(out == NULL) { + return; + } + + if(region == 0) { + snprintf(out, size, "Unknown"); + } else if((region & SMDH_ALL_REGIONS) == SMDH_ALL_REGIONS) { + snprintf(out, size, "Region Free"); + } else { + size_t pos = 0; + + for(u32 i = 0; i < SMDH_NUM_REGIONS; i++) { + if(region & (1 << i)) { + if(pos > 0) { + pos += snprintf(out + pos, size - pos, ", "); + } + + pos += snprintf(out + pos, size - pos, smdh_region_strings[i]); + } + } + } +} + +static CFG_Language region_default_language[] = { + CFG_LANGUAGE_JP, + CFG_LANGUAGE_EN, + CFG_LANGUAGE_EN, + CFG_LANGUAGE_EN, + CFG_LANGUAGE_ZH, + CFG_LANGUAGE_KO, + CFG_LANGUAGE_ZH +}; + +SMDH_title* smdh_select_title(SMDH* smdh) { + char shortDescription[0x100] = {'\0'}; + + CFG_Language systemLanguage; + if(R_SUCCEEDED(CFGU_GetSystemLanguage((u8*) &systemLanguage))) { + utf16_to_utf8((uint8_t*) shortDescription, smdh->titles[systemLanguage].shortDescription, sizeof(shortDescription) - 1); + } + + if(util_is_string_empty(shortDescription)) { + CFG_Region systemRegion; + if(R_SUCCEEDED(CFGU_SecureInfoGetRegion((u8*) &systemRegion))) { + systemLanguage = region_default_language[systemRegion]; + } else { + systemLanguage = CFG_LANGUAGE_JP; + } + } + + return &smdh->titles[systemLanguage]; +} \ No newline at end of file diff --git a/source/core/data/smdh.h b/source/core/data/smdh.h new file mode 100644 index 0000000..cb13651 --- /dev/null +++ b/source/core/data/smdh.h @@ -0,0 +1,29 @@ +#pragma once + +typedef struct SMDH_title_s { + u16 shortDescription[0x40]; + u16 longDescription[0x80]; + u16 publisher[0x40]; +} SMDH_title; + +typedef struct SMDH_s { + char magic[0x04]; + u16 version; + u16 reserved1; + SMDH_title titles[0x10]; + u8 ratings[0x10]; + u32 region; + u32 matchMakerId; + u64 matchMakerBitId; + u32 flags; + u16 eulaVersion; + u16 reserved; + u32 optimalBannerFrame; + u32 streetpassId; + u64 reserved2; + u8 smallIcon[0x480]; + u8 largeIcon[0x1200]; +} SMDH; + +void smdh_region_to_string(char* out, u32 region, size_t size); +SMDH_title* smdh_select_title(SMDH* smdh); \ No newline at end of file diff --git a/source/core/data/ticket.c b/source/core/data/ticket.c new file mode 100644 index 0000000..e538067 --- /dev/null +++ b/source/core/data/ticket.c @@ -0,0 +1,9 @@ +#include <3ds.h> + +#include "ticket.h" + +static u32 sigSizes[6] = {0x240, 0x140, 0x80, 0x240, 0x140, 0x80}; + +u64 ticket_get_title_id(u8* ticket) { + return __builtin_bswap64(*(u64*) &ticket[sigSizes[ticket[0x03]] + 0x9C]); +} \ No newline at end of file diff --git a/source/core/data/ticket.h b/source/core/data/ticket.h new file mode 100644 index 0000000..3bea836 --- /dev/null +++ b/source/core/data/ticket.h @@ -0,0 +1,3 @@ +#pragma once + +u64 ticket_get_title_id(u8* ticket); \ No newline at end of file diff --git a/source/core/data/tmd.c b/source/core/data/tmd.c new file mode 100644 index 0000000..dd53ef5 --- /dev/null +++ b/source/core/data/tmd.c @@ -0,0 +1,17 @@ +#include <3ds.h> + +#include "tmd.h" + +static u32 sigSizes[6] = {0x240, 0x140, 0x80, 0x240, 0x140, 0x80}; + +u64 tmd_get_title_id(u8* tmd) { + return __builtin_bswap64(*(u64*) &tmd[sigSizes[tmd[0x03]] + 0x4C]); +} + +u16 tmd_get_content_count(u8* tmd) { + return __builtin_bswap16(*(u16*) &tmd[sigSizes[tmd[0x03]] + 0x9E]); +} + +u8* tmd_get_content_chunk(u8* tmd, u32 index) { + return &tmd[sigSizes[tmd[0x03]] + 0x9C4 + (index * 0x30)]; +} \ No newline at end of file diff --git a/source/core/data/tmd.h b/source/core/data/tmd.h new file mode 100644 index 0000000..43c143f --- /dev/null +++ b/source/core/data/tmd.h @@ -0,0 +1,5 @@ +#pragma once + +u64 tmd_get_title_id(u8* tmd); +u16 tmd_get_content_count(u8* tmd); +u8* tmd_get_content_chunk(u8* tmd, u32 index); \ No newline at end of file diff --git a/source/core/screen.c b/source/core/screen.c index aaef762..b7080bd 100644 --- a/source/core/screen.c +++ b/source/core/screen.c @@ -37,22 +37,6 @@ static struct { u32 height; } textures[MAX_TEXTURES]; -static FILE* screen_open_resource(const char* path) { - u32 realPathSize = strlen(path) + 17; - char realPath[realPathSize]; - - snprintf(realPath, realPathSize, "sdmc:/fbi/theme/%s", path); - FILE* fd = fopen(realPath, "rb"); - - if(fd != NULL) { - return fd; - } else { - snprintf(realPath, realPathSize, "romfs:/%s", path); - - return fopen(realPath, "rb"); - } -} - static void screen_set_blend(u32 color, bool rgb, bool alpha) { C3D_TexEnv* env = C3D_GetTexEnv(0); if(env == NULL) { @@ -170,81 +154,6 @@ void screen_init() { } font_scale = 30.0f / glyphInfo->cellHeight; // 30 is cellHeight in J machines - - FILE* fd = screen_open_resource("textcolor.cfg"); - if(fd == NULL) { - util_panic("Failed to open text color config: %s\n", strerror(errno)); - return; - } - - char line[128]; - while(fgets(line, sizeof(line), fd) != NULL) { - char key[64]; - u32 color = 0; - - sscanf(line, "%63[^=]=%lx", key, &color); - - if(strcasecmp(key, "text") == 0) { - color_config[COLOR_TEXT] = color; - } else if(strcasecmp(key, "nand") == 0) { - color_config[COLOR_NAND] = color; - } else if(strcasecmp(key, "sd") == 0) { - color_config[COLOR_SD] = color; - } else if(strcasecmp(key, "gamecard") == 0) { - color_config[COLOR_GAME_CARD] = color; - } else if(strcasecmp(key, "dstitle") == 0) { - color_config[COLOR_DS_TITLE] = color; - } else if(strcasecmp(key, "file") == 0) { - color_config[COLOR_FILE] = color; - } else if(strcasecmp(key, "directory") == 0) { - color_config[COLOR_DIRECTORY] = color; - } else if(strcasecmp(key, "enabled") == 0) { - color_config[COLOR_ENABLED] = color; - } else if(strcasecmp(key, "disabled") == 0) { - color_config[COLOR_DISABLED] = color; - } else if(strcasecmp(key, "titledbinstalled") == 0) { - color_config[COLOR_TITLEDB_INSTALLED] = color; - } else if(strcasecmp(key, "titledbnotinstalled") == 0) { - color_config[COLOR_TITLEDB_NOT_INSTALLED] = color; - } else if(strcasecmp(key, "ticketinuse") == 0) { - color_config[COLOR_TICKET_IN_USE] = color; - } else if(strcasecmp(key, "ticketnotinuse") == 0) { - color_config[COLOR_TICKET_NOT_IN_USE] = color; - } - } - - fclose(fd); - - screen_load_texture_file(TEXTURE_BOTTOM_SCREEN_BG, "bottom_screen_bg.png", true); - screen_load_texture_file(TEXTURE_BOTTOM_SCREEN_TOP_BAR, "bottom_screen_top_bar.png", true); - screen_load_texture_file(TEXTURE_BOTTOM_SCREEN_TOP_BAR_SHADOW, "bottom_screen_top_bar_shadow.png", true); - screen_load_texture_file(TEXTURE_BOTTOM_SCREEN_BOTTOM_BAR, "bottom_screen_bottom_bar.png", true); - screen_load_texture_file(TEXTURE_BOTTOM_SCREEN_BOTTOM_BAR_SHADOW, "bottom_screen_bottom_bar_shadow.png", true); - screen_load_texture_file(TEXTURE_TOP_SCREEN_BG, "top_screen_bg.png", true); - screen_load_texture_file(TEXTURE_TOP_SCREEN_TOP_BAR, "top_screen_top_bar.png", true); - screen_load_texture_file(TEXTURE_TOP_SCREEN_TOP_BAR_SHADOW, "top_screen_top_bar_shadow.png", true); - screen_load_texture_file(TEXTURE_TOP_SCREEN_BOTTOM_BAR, "top_screen_bottom_bar.png", true); - screen_load_texture_file(TEXTURE_TOP_SCREEN_BOTTOM_BAR_SHADOW, "top_screen_bottom_bar_shadow.png", true); - screen_load_texture_file(TEXTURE_LOGO, "logo.png", true); - screen_load_texture_file(TEXTURE_SELECTION_OVERLAY, "selection_overlay.png", true); - screen_load_texture_file(TEXTURE_SCROLL_BAR, "scroll_bar.png", true); - screen_load_texture_file(TEXTURE_BUTTON, "button.png", true); - screen_load_texture_file(TEXTURE_PROGRESS_BAR_BG, "progress_bar_bg.png", true); - screen_load_texture_file(TEXTURE_PROGRESS_BAR_CONTENT, "progress_bar_content.png", true); - screen_load_texture_file(TEXTURE_META_INFO_BOX, "meta_info_box.png", true); - screen_load_texture_file(TEXTURE_META_INFO_BOX_SHADOW, "meta_info_box_shadow.png", true); - screen_load_texture_file(TEXTURE_BATTERY_CHARGING, "battery_charging.png", true); - screen_load_texture_file(TEXTURE_BATTERY_0, "battery0.png", true); - screen_load_texture_file(TEXTURE_BATTERY_1, "battery1.png", true); - screen_load_texture_file(TEXTURE_BATTERY_2, "battery2.png", true); - screen_load_texture_file(TEXTURE_BATTERY_3, "battery3.png", true); - screen_load_texture_file(TEXTURE_BATTERY_4, "battery4.png", true); - screen_load_texture_file(TEXTURE_BATTERY_5, "battery5.png", true); - screen_load_texture_file(TEXTURE_WIFI_DISCONNECTED, "wifi_disconnected.png", true); - screen_load_texture_file(TEXTURE_WIFI_0, "wifi0.png", true); - screen_load_texture_file(TEXTURE_WIFI_1, "wifi1.png", true); - screen_load_texture_file(TEXTURE_WIFI_2, "wifi2.png", true); - screen_load_texture_file(TEXTURE_WIFI_3, "wifi3.png", true); } void screen_exit() { @@ -287,6 +196,15 @@ void screen_set_base_alpha(u8 alpha) { base_alpha = alpha; } +void screen_set_color(u32 id, u32 color) { + if(id >= MAX_COLORS) { + util_panic("Attempted to draw string with invalid color ID \"%lu\".", id); + return; + } + + color_config[id] = color; +} + static u32 screen_next_pow_2(u32 i) { i--; i |= i >> 1; @@ -401,26 +319,36 @@ void screen_load_texture_untiled(u32 id, void* data, u32 size, u32 width, u32 he C3D_TexFlush(&textures[id].tex); } -void screen_load_texture_file(u32 id, const char* path, bool linearFilter) { +void screen_load_texture_path(u32 id, const char* path, bool linearFilter) { if(id >= MAX_TEXTURES) { util_panic("Attempted to load path \"%s\" to invalid texture ID \"%lu\".", path, id); return; } - FILE* fd = screen_open_resource(path); + FILE* fd = fopen(path, "rb"); if(fd == NULL) { util_panic("Failed to load PNG file \"%s\": %s", path, strerror(errno)); return; } + screen_load_texture_file(id, fd, linearFilter); + + fclose(fd); +} + +void screen_load_texture_file(u32 id, FILE* fd, bool linearFilter) { + if(id >= MAX_TEXTURES) { + util_panic("Attempted to load file to invalid texture ID \"%lu\".", id); + return; + } + int width; int height; int depth; u8* image = stbi_load_from_file(fd, &width, &height, &depth, STBI_rgb_alpha); - fclose(fd); if(image == NULL || depth != STBI_rgb_alpha) { - util_panic("Failed to load PNG file \"%s\".", path); + util_panic("Failed to load PNG file to texture ID \"%lu\".", id); return; } diff --git a/source/core/screen.h b/source/core/screen.h index 4181cc0..2d8078c 100644 --- a/source/core/screen.h +++ b/source/core/screen.h @@ -1,5 +1,7 @@ #pragma once +typedef struct __sFILE FILE; + #define TOP_SCREEN_WIDTH 400 #define TOP_SCREEN_HEIGHT 240 @@ -7,60 +9,16 @@ #define BOTTOM_SCREEN_HEIGHT 240 #define MAX_TEXTURES 1024 - -#define TEXTURE_BOTTOM_SCREEN_BG 1 -#define TEXTURE_BOTTOM_SCREEN_TOP_BAR 2 -#define TEXTURE_BOTTOM_SCREEN_TOP_BAR_SHADOW 3 -#define TEXTURE_BOTTOM_SCREEN_BOTTOM_BAR 4 -#define TEXTURE_BOTTOM_SCREEN_BOTTOM_BAR_SHADOW 5 -#define TEXTURE_TOP_SCREEN_BG 6 -#define TEXTURE_TOP_SCREEN_TOP_BAR 7 -#define TEXTURE_TOP_SCREEN_TOP_BAR_SHADOW 8 -#define TEXTURE_TOP_SCREEN_BOTTOM_BAR 9 -#define TEXTURE_TOP_SCREEN_BOTTOM_BAR_SHADOW 10 -#define TEXTURE_LOGO 11 -#define TEXTURE_SELECTION_OVERLAY 12 -#define TEXTURE_SCROLL_BAR 13 -#define TEXTURE_BUTTON 14 -#define TEXTURE_PROGRESS_BAR_BG 15 -#define TEXTURE_PROGRESS_BAR_CONTENT 16 -#define TEXTURE_META_INFO_BOX 17 -#define TEXTURE_META_INFO_BOX_SHADOW 18 -#define TEXTURE_BATTERY_CHARGING 19 -#define TEXTURE_BATTERY_0 20 -#define TEXTURE_BATTERY_1 21 -#define TEXTURE_BATTERY_2 22 -#define TEXTURE_BATTERY_3 23 -#define TEXTURE_BATTERY_4 24 -#define TEXTURE_BATTERY_5 25 -#define TEXTURE_WIFI_DISCONNECTED 26 -#define TEXTURE_WIFI_0 27 -#define TEXTURE_WIFI_1 28 -#define TEXTURE_WIFI_2 29 -#define TEXTURE_WIFI_3 30 - -#define MAX_COLORS 13 - -#define COLOR_TEXT 0 -#define COLOR_NAND 1 -#define COLOR_SD 2 -#define COLOR_GAME_CARD 3 -#define COLOR_DS_TITLE 4 -#define COLOR_FILE 5 -#define COLOR_DIRECTORY 6 -#define COLOR_ENABLED 7 -#define COLOR_DISABLED 8 -#define COLOR_TITLEDB_INSTALLED 9 -#define COLOR_TITLEDB_NOT_INSTALLED 10 -#define COLOR_TICKET_IN_USE 11 -#define COLOR_TICKET_NOT_IN_USE 12 +#define MAX_COLORS 32 void screen_init(); void screen_exit(); void screen_set_base_alpha(u8 alpha); +void screen_set_color(u32 id, u32 color); u32 screen_allocate_free_texture(); void screen_load_texture_untiled(u32 id, void* data, u32 size, u32 width, u32 height, GPU_TEXCOLOR format, bool linearFilter); -void screen_load_texture_file(u32 id, const char* path, bool linearFilter); +void screen_load_texture_path(u32 id, const char* path, bool linearFilter); +void screen_load_texture_file(u32 id, FILE* fd, bool linearFilter); void screen_load_texture_tiled(u32 id, void* data, u32 size, u32 width, u32 height, GPU_TEXCOLOR format, bool linearFilter); void screen_unload_texture(u32 id); void screen_get_texture_size(u32* width, u32* height, u32 id); diff --git a/source/ui/section/task/capturecam.c b/source/core/task/capturecam.c similarity index 97% rename from source/ui/section/task/capturecam.c rename to source/core/task/capturecam.c index cd2d974..b7a1e45 100644 --- a/source/ui/section/task/capturecam.c +++ b/source/core/task/capturecam.c @@ -3,9 +3,9 @@ #include <3ds.h> +#include "capturecam.h" #include "task.h" -#include "../../list.h" -#include "../../../core/util.h" +#include "../util.h" #define EVENT_CANCEL 0 #define EVENT_RECV 1 @@ -25,7 +25,7 @@ static void task_capture_cam_thread(void* arg) { u16* buffer = (u16*) calloc(1, bufferSize); if(buffer != NULL) { if(R_SUCCEEDED(res = camInit())) { - int cam = data->camera == CAMERA_OUTER ? SELECT_OUT1 : SELECT_IN1; + u32 cam = data->camera == CAMERA_OUTER ? SELECT_OUT1 : SELECT_IN1; if(R_SUCCEEDED(res = CAMU_SetSize(cam, SIZE_CTR_TOP_LCD, CONTEXT_A)) && R_SUCCEEDED(res = CAMU_SetOutputFormat(cam, OUTPUT_RGB_565, CONTEXT_A)) diff --git a/source/core/task/capturecam.h b/source/core/task/capturecam.h new file mode 100644 index 0000000..23e2a05 --- /dev/null +++ b/source/core/task/capturecam.h @@ -0,0 +1,21 @@ +#pragma once + +typedef enum capture_cam_camera_e { + CAMERA_OUTER, + CAMERA_INNER +} capture_cam_camera; + +typedef struct capture_cam_data_s { + u16* buffer; + s16 width; + s16 height; + capture_cam_camera camera; + + Handle mutex; + + volatile bool finished; + Result result; + Handle cancelEvent; +} capture_cam_data; + +Result task_capture_cam(capture_cam_data* data); \ No newline at end of file diff --git a/source/ui/section/task/task.c b/source/core/task/task.c similarity index 98% rename from source/ui/section/task/task.c rename to source/core/task/task.c index e397cec..d3ddc44 100644 --- a/source/ui/section/task/task.c +++ b/source/core/task/task.c @@ -1,7 +1,7 @@ #include <3ds.h> #include "task.h" -#include "../../../core/util.h" +#include "../util.h" static bool task_quit; diff --git a/source/core/task/task.h b/source/core/task/task.h new file mode 100644 index 0000000..301ff07 --- /dev/null +++ b/source/core/task/task.h @@ -0,0 +1,7 @@ +#pragma once + +void task_init(); +void task_exit(); +bool task_is_quit_all(); +Handle task_get_pause_event(); +Handle task_get_suspend_event(); \ No newline at end of file diff --git a/source/core/util.c b/source/core/util.c index ca857be..238597a 100644 --- a/source/core/util.c +++ b/source/core/util.c @@ -8,10 +8,9 @@ #include #include -#include "util.h" -#include "../ui/list.h" -#include "../ui/section/task/task.h" #include "linkedlist.h" +#include "util.h" +#include "task/task.h" extern void cleanup(); @@ -428,62 +427,6 @@ FS_MediaType util_get_title_destination(u64 titleId) { return platform == 0x0003 || (platform == 0x0004 && ((category & 0x8011) != 0 || (category == 0x0000 && variation == 0x02))) ? MEDIATYPE_NAND : MEDIATYPE_SD; } -static u32 sigSizes[6] = {0x240, 0x140, 0x80, 0x240, 0x140, 0x80}; - -u64 util_get_cia_title_id(u8* cia) { - u32 headerSize = ((*(u32*) &cia[0x00]) + 0x3F) & ~0x3F; - u32 certSize = ((*(u32*) &cia[0x08]) + 0x3F) & ~0x3F; - u32 ticketSize = ((*(u32*) &cia[0x0C]) + 0x3F) & ~0x3F; - - u8* tmd = &cia[headerSize + certSize + ticketSize]; - - return util_get_tmd_title_id(tmd); -} - -Result util_get_cia_file_smdh(SMDH* smdh, Handle handle) { - Result res = 0; - - if(smdh != NULL) { - u32 bytesRead = 0; - - u32 header[8]; - if(R_SUCCEEDED(res = FSFILE_Read(handle, &bytesRead, 0, header, sizeof(header))) && bytesRead == sizeof(header)) { - u32 headerSize = (header[0] + 0x3F) & ~0x3F; - u32 certSize = (header[2] + 0x3F) & ~0x3F; - u32 ticketSize = (header[3] + 0x3F) & ~0x3F; - u32 tmdSize = (header[4] + 0x3F) & ~0x3F; - u32 metaSize = (header[5] + 0x3F) & ~0x3F; - u64 contentSize = ((header[6] | ((u64) header[7] << 32)) + 0x3F) & ~0x3F; - - if(metaSize >= 0x3AC0) { - res = FSFILE_Read(handle, &bytesRead, headerSize + certSize + ticketSize + tmdSize + contentSize + 0x400, smdh, sizeof(SMDH)); - } else { - res = R_FBI_BAD_DATA; - } - } - } else { - res = R_FBI_INVALID_ARGUMENT; - } - - return res; -} - -u64 util_get_ticket_title_id(u8* ticket) { - return __builtin_bswap64(*(u64*) &ticket[sigSizes[ticket[0x03]] + 0x9C]); -} - -u64 util_get_tmd_title_id(u8* tmd) { - return __builtin_bswap64(*(u64*) &tmd[sigSizes[tmd[0x03]] + 0x4C]); -} - -u16 util_get_tmd_content_count(u8* tmd) { - return __builtin_bswap16(*(u16*) &tmd[sigSizes[tmd[0x03]] + 0x9E]); -} - -u8* util_get_tmd_content_chunk(u8* tmd, u32 index) { - return &tmd[sigSizes[tmd[0x03]] + 0x9C4 + (index * 0x30)]; -} - bool util_filter_cias(void* data, const char* name, u32 attributes) { if((attributes & FS_ATTRIBUTE_DIRECTORY) != 0) { return false; @@ -502,31 +445,6 @@ bool util_filter_tickets(void* data, const char* name, u32 attributes) { return (len >= 4 && strncasecmp(name + len - 4, ".tik", 4) == 0) || (len >= 5 && strncasecmp(name + len - 5, ".cetk", 5) == 0); } -int util_compare_file_infos(void* userData, const void* p1, const void* p2) { - list_item* info1 = (list_item*) p1; - list_item* info2 = (list_item*) p2; - - bool info1Base = strncmp(info1->name, "", LIST_ITEM_NAME_MAX) == 0 || strncmp(info1->name, "", LIST_ITEM_NAME_MAX) == 0; - bool info2Base = strncmp(info2->name, "", LIST_ITEM_NAME_MAX) == 0 || strncmp(info2->name, "", LIST_ITEM_NAME_MAX) == 0; - - if(info1Base && !info2Base) { - return -1; - } else if(!info1Base && info2Base) { - return 1; - } else { - file_info* f1 = (file_info*) info1->data; - file_info* f2 = (file_info*) info2->data; - - if((f1->attributes & FS_ATTRIBUTE_DIRECTORY) && !(f2->attributes & FS_ATTRIBUTE_DIRECTORY)) { - return -1; - } else if(!(f1->attributes & FS_ATTRIBUTE_DIRECTORY) && (f2->attributes & FS_ATTRIBUTE_DIRECTORY)) { - return 1; - } else { - return strncasecmp(f1->name, f2->name, FILE_NAME_MAX); - } - } -} - static char path_3dsx[FILE_PATH_MAX] = {'\0'}; const char* util_get_3dsx_path() { @@ -619,58 +537,13 @@ Result util_close_archive(FS_Archive archive) { return FSUSER_CloseArchive(archive); } -const char* util_get_display_eta(u32 seconds) { - static char disp[12]; - - u8 hours = seconds / 3600; - seconds -= hours * 3600; - u8 minutes = seconds / 60; - seconds -= minutes* 60; - - snprintf(disp, 12, "%02u:%02u:%02u", hours, minutes, (u8) seconds); - return disp; -} - -double util_get_display_size(u64 size) { - double s = size; - if(s > 1024) { - s /= 1024; - } - - if(s > 1024) { - s /= 1024; - } - - if(s > 1024) { - s /= 1024; - } - - return s; -} - -const char* util_get_display_size_units(u64 size) { - if(size > 1024 * 1024 * 1024) { - return "GiB"; - } - - if(size > 1024 * 1024) { - return "MiB"; - } - - if(size > 1024) { - return "KiB"; - } - - return "B"; -} - -void util_escape_file_name(char* out, const char* in, size_t size) { +void util_escape_file_name(char* out, const char* file, size_t size) { static const char reservedChars[] = {'<', '>', ':', '"', '/', '\\', '|', '?', '*'}; for(u32 i = 0; i < size; i++) { bool reserved = false; for(u32 j = 0; j < sizeof(reservedChars); j++) { - if(in[i] == reservedChars[j]) { + if(file[i] == reservedChars[j]) { reserved = true; break; } @@ -679,102 +552,15 @@ void util_escape_file_name(char* out, const char* in, size_t size) { if(reserved) { out[i] = '_'; } else { - out[i] = in[i]; + out[i] = file[i]; } - if(in[i] == '\0') { + if(file[i] == '\0') { break; } } } -#define SMDH_NUM_REGIONS 7 -#define SMDH_ALL_REGIONS 0x7F - -static const char* smdh_region_strings[SMDH_NUM_REGIONS] = { - "Japan", - "North America", - "Europe", - "Australia", - "China", - "Korea", - "Taiwan" -}; - -void util_smdh_region_to_string(char* out, u32 region, size_t size) { - if(out == NULL) { - return; - } - - if(region == 0) { - snprintf(out, size, "Unknown"); - } else if((region & SMDH_ALL_REGIONS) == SMDH_ALL_REGIONS) { - snprintf(out, size, "Region Free"); - } else { - size_t pos = 0; - - for(u32 i = 0; i < SMDH_NUM_REGIONS; i++) { - if(region & (1 << i)) { - if(pos > 0) { - pos += snprintf(out + pos, size - pos, ", "); - } - - pos += snprintf(out + pos, size - pos, smdh_region_strings[i]); - } - } - } -} - -static CFG_Language region_default_language[] = { - CFG_LANGUAGE_JP, - CFG_LANGUAGE_EN, - CFG_LANGUAGE_EN, - CFG_LANGUAGE_EN, - CFG_LANGUAGE_ZH, - CFG_LANGUAGE_KO, - CFG_LANGUAGE_ZH -}; - -SMDH_title* util_select_smdh_title(SMDH* smdh) { - char shortDescription[0x100] = {'\0'}; - - CFG_Language systemLanguage; - if(R_SUCCEEDED(CFGU_GetSystemLanguage((u8*) &systemLanguage))) { - utf16_to_utf8((uint8_t*) shortDescription, smdh->titles[systemLanguage].shortDescription, sizeof(shortDescription) - 1); - } - - if(util_is_string_empty(shortDescription)) { - CFG_Region systemRegion; - if(R_SUCCEEDED(CFGU_SecureInfoGetRegion((u8*) &systemRegion))) { - systemLanguage = region_default_language[systemRegion]; - } else { - systemLanguage = CFG_LANGUAGE_JP; - } - } - - return &smdh->titles[systemLanguage]; -} - -u16* util_select_bnr_title(BNR* bnr) { - char title[0x100] = {'\0'}; - - CFG_Language systemLanguage; - if(R_SUCCEEDED(CFGU_GetSystemLanguage((u8*) &systemLanguage))) { - utf16_to_utf8((uint8_t*) title, bnr->titles[systemLanguage], sizeof(title) - 1); - } - - if(util_is_string_empty(title)) { - CFG_Region systemRegion; - if(R_SUCCEEDED(CFGU_SecureInfoGetRegion((u8*) &systemRegion))) { - systemLanguage = region_default_language[systemRegion]; - } else { - systemLanguage = CFG_LANGUAGE_JP; - } - } - - return bnr->titles[systemLanguage]; -} - #define HTTPC_TIMEOUT 15000000000 Result util_http_open(httpcContext* context, u32* responseCode, const char* url, bool userAgent) { diff --git a/source/core/util.h b/source/core/util.h index 8afff39..2fea5c2 100644 --- a/source/core/util.h +++ b/source/core/util.h @@ -2,6 +2,7 @@ typedef struct json_t json_t; +// Errors #define R_FBI_CANCELLED MAKERESULT(RL_PERMANENT, RS_CANCELED, RM_APPLICATION, 1) #define R_FBI_HTTP_RESPONSE_CODE MAKERESULT(RL_PERMANENT, RS_INTERNAL, RM_APPLICATION, 2) #define R_FBI_WRONG_SYSTEM MAKERESULT(RL_PERMANENT, RS_NOTSUPPORTED, RM_APPLICATION, 3) @@ -18,104 +19,56 @@ typedef struct json_t json_t; #define R_FBI_OUT_OF_MEMORY MAKERESULT(RL_FATAL, RS_OUTOFRESOURCE, RM_APPLICATION, RD_OUT_OF_MEMORY) #define R_FBI_OUT_OF_RANGE MAKERESULT(RL_PERMANENT, RS_INVALIDARG, RM_APPLICATION, RD_OUT_OF_RANGE) +// HTTP constants #define MAKE_HTTP_USER_AGENT_(major, minor, micro) ("Mozilla/5.0 (Nintendo 3DS; Mobile; rv:10.0) Gecko/20100101 FBI/" #major "." #minor "." #micro) #define MAKE_HTTP_USER_AGENT(major, minor, micro) MAKE_HTTP_USER_AGENT_(major, minor, micro) #define HTTP_USER_AGENT MAKE_HTTP_USER_AGENT(VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO) #define HTTP_CONNECT_TIMEOUT 15 -typedef struct { - u16 shortDescription[0x40]; - u16 longDescription[0x80]; - u16 publisher[0x40]; -} SMDH_title; - -typedef struct { - char magic[0x04]; - u16 version; - u16 reserved1; - SMDH_title titles[0x10]; - u8 ratings[0x10]; - u32 region; - u32 matchMakerId; - u64 matchMakerBitId; - u32 flags; - u16 eulaVersion; - u16 reserved; - u32 optimalBannerFrame; - u32 streetpassId; - u64 reserved2; - u8 smallIcon[0x480]; - u8 largeIcon[0x1200]; -} SMDH; - -typedef struct { - u8 version; - bool animated; - u16 crc16[4]; - u8 reserved[0x16]; - u8 mainIconBitmap[0x200]; - u16 mainIconPalette[0x10]; - u16 titles[16][0x80]; - u8 animatedFrameBitmaps[8][0x200]; - u16 animatedFramePalettes[8][0x10]; - u16 animationSequence[0x40]; -} BNR; +// File constants +#define FILE_NAME_MAX 512 +#define FILE_PATH_MAX 512 +// Panic void util_panic(const char* s, ...); -FS_Path* util_make_path_utf8(const char* path); -void util_free_path_utf8(FS_Path* path); +// Strings +bool util_is_string_empty(const char* str); + +// Files +Result util_open_archive(FS_Archive* archive, FS_ArchiveID id, FS_Path path); +Result util_ref_archive(FS_Archive archive); +Result util_close_archive(FS_Archive archive); + +const char* util_get_3dsx_path(); +void util_set_3dsx_path(const char* path); FS_Path util_make_binary_path(const void* data, u32 size); +FS_Path* util_make_path_utf8(const char* path); +void util_free_path_utf8(FS_Path* path); bool util_is_dir(FS_Archive archive, const char* path); Result util_ensure_dir(FS_Archive archive, const char* path); void util_get_file_name(char* out, const char* file, u32 size); - +void util_escape_file_name(char* out, const char* file, size_t size); void util_get_path_file(char* out, const char* path, u32 size); void util_get_parent_path(char* out, const char* path, u32 size); -bool util_is_string_empty(const char* str); - -Result util_download(const char* url, u32* downloadedSize, void* buf, size_t size); -Result util_download_json(const char* url, json_t** json, size_t maxSize); - -Result util_import_seed(u32* responseCode, u64 titleId); - -FS_MediaType util_get_title_destination(u64 titleId); - -u64 util_get_cia_title_id(u8* cia); -Result util_get_cia_file_smdh(SMDH* smdh, Handle handle); -u64 util_get_ticket_title_id(u8* ticket); -u64 util_get_tmd_title_id(u8* tmd); -u16 util_get_tmd_content_count(u8* tmd); -u8* util_get_tmd_content_chunk(u8* tmd, u32 index); - bool util_filter_cias(void* data, const char* name, u32 attributes); bool util_filter_tickets(void* data, const char* name, u32 attributes); -int util_compare_file_infos(void* userData, const void* p1, const void* p2); +// Titles +Result util_import_seed(u32* responseCode, u64 titleId); -const char* util_get_3dsx_path(); -void util_set_3dsx_path(const char* path); +FS_MediaType util_get_title_destination(u64 titleId); -Result util_open_archive(FS_Archive* archive, FS_ArchiveID id, FS_Path path); -Result util_ref_archive(FS_Archive archive); -Result util_close_archive(FS_Archive archive); - -const char* util_get_display_eta(u32 seconds); -double util_get_display_size(u64 size); -const char* util_get_display_size_units(u64 size); - -void util_escape_file_name(char* out, const char* in, size_t size); - -void util_smdh_region_to_string(char* out, u32 region, size_t size); - -SMDH_title* util_select_smdh_title(SMDH* smdh); -u16* util_select_bnr_title(BNR* bnr); +// Download +Result util_download(const char* url, u32* downloadedSize, void* buf, size_t size); +Result util_download_json(const char* url, json_t** json, size_t maxSize); +// HTTP Result util_http_open(httpcContext* context, u32* responseCode, const char* url, bool userAgent); Result util_http_open_ranged(httpcContext* context, u32* responseCode, const char* url, bool userAgent, u32 rangeStart, u32 rangeEnd); Result util_http_get_size(httpcContext* context, u32* size); diff --git a/source/main.c b/source/main.c index edd1ec0..5661e03 100644 --- a/source/main.c +++ b/source/main.c @@ -7,10 +7,11 @@ #include "core/clipboard.h" #include "core/screen.h" #include "core/util.h" +#include "core/task/task.h" #include "ui/error.h" #include "ui/mainmenu.h" +#include "ui/resources.h" #include "ui/ui.h" -#include "ui/section/task/task.h" #define CURRENT_KPROCESS (*(void**) 0xFFFF9004) @@ -157,6 +158,7 @@ void init() { curl_global_init(CURL_GLOBAL_ALL); screen_init(); + resources_load(); ui_init(); task_init(); } diff --git a/source/ui/error.c b/source/ui/error.c index 0dc9bc1..ad61169 100644 --- a/source/ui/error.c +++ b/source/ui/error.c @@ -8,6 +8,7 @@ #include "error.h" #include "prompt.h" +#include "resources.h" #include "../core/screen.h" #include "../core/util.h" diff --git a/source/ui/info.c b/source/ui/info.c index d53bb9f..6d7b16b 100644 --- a/source/ui/info.c +++ b/source/ui/info.c @@ -5,6 +5,7 @@ #include "error.h" #include "info.h" +#include "resources.h" #include "ui.h" #include "../core/screen.h" diff --git a/source/ui/list.c b/source/ui/list.c index d69c218..8aee4db 100644 --- a/source/ui/list.c +++ b/source/ui/list.c @@ -4,6 +4,7 @@ #include "error.h" #include "list.h" +#include "resources.h" #include "ui.h" #include "../core/screen.h" #include "../core/linkedlist.h" diff --git a/source/ui/mainmenu.c b/source/ui/mainmenu.c index ff92d9d..50d1510 100644 --- a/source/ui/mainmenu.c +++ b/source/ui/mainmenu.c @@ -5,6 +5,7 @@ #include "list.h" #include "mainmenu.h" +#include "resources.h" #include "ui.h" #include "section/section.h" #include "../core/linkedlist.h" diff --git a/source/ui/prompt.c b/source/ui/prompt.c index 4e92e69..24bb192 100644 --- a/source/ui/prompt.c +++ b/source/ui/prompt.c @@ -6,6 +6,7 @@ #include "error.h" #include "prompt.h" +#include "resources.h" #include "ui.h" #include "../core/screen.h" diff --git a/source/ui/resources.c b/source/ui/resources.c new file mode 100644 index 0000000..5512bcf --- /dev/null +++ b/source/ui/resources.c @@ -0,0 +1,114 @@ +#include +#include +#include + +#include <3ds.h> + +#include "resources.h" +#include "../core/screen.h" +#include "../core/util.h" +#include "../core/task/task.h" + +static FILE* resources_open_file(const char* path) { + char realPath[FILE_PATH_MAX]; + snprintf(realPath, sizeof(realPath), "sdmc:/fbi/theme/%s", path); + + FILE* fd = fopen(realPath, "rb"); + + if(fd != NULL) { + return fd; + } else { + snprintf(realPath, sizeof(realPath), "romfs:/%s", path); + + return fopen(realPath, "rb"); + } +} + +static void resources_load_texture(u32 id, const char* name) { + FILE* fd = resources_open_file(name); + if(fd == NULL) { + util_panic("Failed to open texture \"%s\": %s\n", name, strerror(errno)); + return; + } + + screen_load_texture_file(id, fd, true); + + fclose(fd); +} + +void resources_load() { + FILE* fd = resources_open_file("textcolor.cfg"); + if(fd == NULL) { + util_panic("Failed to open text color config: %s\n", strerror(errno)); + return; + } + + char line[128]; + while(fgets(line, sizeof(line), fd) != NULL) { + char key[64]; + u32 color = 0; + + sscanf(line, "%63[^=]=%lx", key, &color); + + if(strcasecmp(key, "text") == 0) { + screen_set_color(COLOR_TEXT, color); + } else if(strcasecmp(key, "nand") == 0) { + screen_set_color(COLOR_NAND, color); + } else if(strcasecmp(key, "sd") == 0) { + screen_set_color(COLOR_SD, color); + } else if(strcasecmp(key, "gamecard") == 0) { + screen_set_color(COLOR_GAME_CARD, color); + } else if(strcasecmp(key, "dstitle") == 0) { + screen_set_color(COLOR_DS_TITLE, color); + } else if(strcasecmp(key, "file") == 0) { + screen_set_color(COLOR_FILE, color); + } else if(strcasecmp(key, "directory") == 0) { + screen_set_color(COLOR_DIRECTORY, color); + } else if(strcasecmp(key, "enabled") == 0) { + screen_set_color(COLOR_ENABLED, color); + } else if(strcasecmp(key, "disabled") == 0) { + screen_set_color(COLOR_DISABLED, color); + } else if(strcasecmp(key, "titledbinstalled") == 0) { + screen_set_color(COLOR_TITLEDB_INSTALLED, color); + } else if(strcasecmp(key, "titledbnotinstalled") == 0) { + screen_set_color(COLOR_TITLEDB_NOT_INSTALLED, color); + } else if(strcasecmp(key, "ticketinuse") == 0) { + screen_set_color(COLOR_TICKET_IN_USE, color); + } else if(strcasecmp(key, "ticketnotinuse") == 0) { + screen_set_color(COLOR_TICKET_NOT_IN_USE, color); + } + } + + fclose(fd); + + resources_load_texture(TEXTURE_BOTTOM_SCREEN_BG, "bottom_screen_bg.png"); + resources_load_texture(TEXTURE_BOTTOM_SCREEN_TOP_BAR, "bottom_screen_top_bar.png"); + resources_load_texture(TEXTURE_BOTTOM_SCREEN_TOP_BAR_SHADOW, "bottom_screen_top_bar_shadow.png"); + resources_load_texture(TEXTURE_BOTTOM_SCREEN_BOTTOM_BAR, "bottom_screen_bottom_bar.png"); + resources_load_texture(TEXTURE_BOTTOM_SCREEN_BOTTOM_BAR_SHADOW, "bottom_screen_bottom_bar_shadow.png"); + resources_load_texture(TEXTURE_TOP_SCREEN_BG, "top_screen_bg.png"); + resources_load_texture(TEXTURE_TOP_SCREEN_TOP_BAR, "top_screen_top_bar.png"); + resources_load_texture(TEXTURE_TOP_SCREEN_TOP_BAR_SHADOW, "top_screen_top_bar_shadow.png"); + resources_load_texture(TEXTURE_TOP_SCREEN_BOTTOM_BAR, "top_screen_bottom_bar.png"); + resources_load_texture(TEXTURE_TOP_SCREEN_BOTTOM_BAR_SHADOW, "top_screen_bottom_bar_shadow.png"); + resources_load_texture(TEXTURE_LOGO, "logo.png"); + resources_load_texture(TEXTURE_SELECTION_OVERLAY, "selection_overlay.png"); + resources_load_texture(TEXTURE_SCROLL_BAR, "scroll_bar.png"); + resources_load_texture(TEXTURE_BUTTON, "button.png"); + resources_load_texture(TEXTURE_PROGRESS_BAR_BG, "progress_bar_bg.png"); + resources_load_texture(TEXTURE_PROGRESS_BAR_CONTENT, "progress_bar_content.png"); + resources_load_texture(TEXTURE_META_INFO_BOX, "meta_info_box.png"); + resources_load_texture(TEXTURE_META_INFO_BOX_SHADOW, "meta_info_box_shadow.png"); + resources_load_texture(TEXTURE_BATTERY_CHARGING, "battery_charging.png"); + resources_load_texture(TEXTURE_BATTERY_0, "battery0.png"); + resources_load_texture(TEXTURE_BATTERY_1, "battery1.png"); + resources_load_texture(TEXTURE_BATTERY_2, "battery2.png"); + resources_load_texture(TEXTURE_BATTERY_3, "battery3.png"); + resources_load_texture(TEXTURE_BATTERY_4, "battery4.png"); + resources_load_texture(TEXTURE_BATTERY_5, "battery5.png"); + resources_load_texture(TEXTURE_WIFI_DISCONNECTED, "wifi_disconnected.png"); + resources_load_texture(TEXTURE_WIFI_0, "wifi0.png"); + resources_load_texture(TEXTURE_WIFI_1, "wifi1.png"); + resources_load_texture(TEXTURE_WIFI_2, "wifi2.png"); + resources_load_texture(TEXTURE_WIFI_3, "wifi3.png"); +} \ No newline at end of file diff --git a/source/ui/resources.h b/source/ui/resources.h new file mode 100644 index 0000000..5a1a6f5 --- /dev/null +++ b/source/ui/resources.h @@ -0,0 +1,48 @@ +#pragma once + +#define TEXTURE_BOTTOM_SCREEN_BG 1 +#define TEXTURE_BOTTOM_SCREEN_TOP_BAR 2 +#define TEXTURE_BOTTOM_SCREEN_TOP_BAR_SHADOW 3 +#define TEXTURE_BOTTOM_SCREEN_BOTTOM_BAR 4 +#define TEXTURE_BOTTOM_SCREEN_BOTTOM_BAR_SHADOW 5 +#define TEXTURE_TOP_SCREEN_BG 6 +#define TEXTURE_TOP_SCREEN_TOP_BAR 7 +#define TEXTURE_TOP_SCREEN_TOP_BAR_SHADOW 8 +#define TEXTURE_TOP_SCREEN_BOTTOM_BAR 9 +#define TEXTURE_TOP_SCREEN_BOTTOM_BAR_SHADOW 10 +#define TEXTURE_LOGO 11 +#define TEXTURE_SELECTION_OVERLAY 12 +#define TEXTURE_SCROLL_BAR 13 +#define TEXTURE_BUTTON 14 +#define TEXTURE_PROGRESS_BAR_BG 15 +#define TEXTURE_PROGRESS_BAR_CONTENT 16 +#define TEXTURE_META_INFO_BOX 17 +#define TEXTURE_META_INFO_BOX_SHADOW 18 +#define TEXTURE_BATTERY_CHARGING 19 +#define TEXTURE_BATTERY_0 20 +#define TEXTURE_BATTERY_1 21 +#define TEXTURE_BATTERY_2 22 +#define TEXTURE_BATTERY_3 23 +#define TEXTURE_BATTERY_4 24 +#define TEXTURE_BATTERY_5 25 +#define TEXTURE_WIFI_DISCONNECTED 26 +#define TEXTURE_WIFI_0 27 +#define TEXTURE_WIFI_1 28 +#define TEXTURE_WIFI_2 29 +#define TEXTURE_WIFI_3 30 + +#define COLOR_TEXT 0 +#define COLOR_NAND 1 +#define COLOR_SD 2 +#define COLOR_GAME_CARD 3 +#define COLOR_DS_TITLE 4 +#define COLOR_FILE 5 +#define COLOR_DIRECTORY 6 +#define COLOR_ENABLED 7 +#define COLOR_DISABLED 8 +#define COLOR_TITLEDB_INSTALLED 9 +#define COLOR_TITLEDB_NOT_INSTALLED 10 +#define COLOR_TICKET_IN_USE 11 +#define COLOR_TICKET_NOT_IN_USE 12 + +void resources_load(); \ No newline at end of file diff --git a/source/ui/section/action/browsebossextsavedata.c b/source/ui/section/action/browsebossextsavedata.c index a78e6aa..730ec5b 100644 --- a/source/ui/section/action/browsebossextsavedata.c +++ b/source/ui/section/action/browsebossextsavedata.c @@ -2,7 +2,7 @@ #include "action.h" #include "../section.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../list.h" #include "../../../core/util.h" diff --git a/source/ui/section/action/browsesystemsavedata.c b/source/ui/section/action/browsesystemsavedata.c index 4010f57..f18d6d6 100644 --- a/source/ui/section/action/browsesystemsavedata.c +++ b/source/ui/section/action/browsesystemsavedata.c @@ -2,7 +2,7 @@ #include "action.h" #include "../section.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../list.h" #include "../../../core/util.h" diff --git a/source/ui/section/action/browsetitlesavedata.c b/source/ui/section/action/browsetitlesavedata.c index c2cc7eb..0f42d75 100644 --- a/source/ui/section/action/browsetitlesavedata.c +++ b/source/ui/section/action/browsetitlesavedata.c @@ -2,7 +2,7 @@ #include "action.h" #include "../section.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../list.h" #include "../../../core/util.h" diff --git a/source/ui/section/action/browseuserextsavedata.c b/source/ui/section/action/browseuserextsavedata.c index 6e1d842..bf502ea 100644 --- a/source/ui/section/action/browseuserextsavedata.c +++ b/source/ui/section/action/browseuserextsavedata.c @@ -2,7 +2,7 @@ #include "action.h" #include "../section.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../list.h" #include "../../../core/util.h" diff --git a/source/ui/section/action/deletecontents.c b/source/ui/section/action/deletecontents.c index 74e45b1..4e3c6f2 100644 --- a/source/ui/section/action/deletecontents.c +++ b/source/ui/section/action/deletecontents.c @@ -5,11 +5,12 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" diff --git a/source/ui/section/action/deleteextsavedata.c b/source/ui/section/action/deleteextsavedata.c index 817651e..663584f 100644 --- a/source/ui/section/action/deleteextsavedata.c +++ b/source/ui/section/action/deleteextsavedata.c @@ -3,11 +3,12 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" diff --git a/source/ui/section/action/deletependingtitles.c b/source/ui/section/action/deletependingtitles.c index 1088c55..804b5f9 100644 --- a/source/ui/section/action/deletependingtitles.c +++ b/source/ui/section/action/deletependingtitles.c @@ -5,11 +5,12 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" diff --git a/source/ui/section/action/deletesecurevalue.c b/source/ui/section/action/deletesecurevalue.c index bd14fd9..f09cce1 100644 --- a/source/ui/section/action/deletesecurevalue.c +++ b/source/ui/section/action/deletesecurevalue.c @@ -3,11 +3,12 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" diff --git a/source/ui/section/action/deletesystemsavedata.c b/source/ui/section/action/deletesystemsavedata.c index 0fd327b..9920ace 100644 --- a/source/ui/section/action/deletesystemsavedata.c +++ b/source/ui/section/action/deletesystemsavedata.c @@ -3,11 +3,12 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" diff --git a/source/ui/section/action/deletetickets.c b/source/ui/section/action/deletetickets.c index 12886b7..cbacebd 100644 --- a/source/ui/section/action/deletetickets.c +++ b/source/ui/section/action/deletetickets.c @@ -4,11 +4,12 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" diff --git a/source/ui/section/action/deletetitle.c b/source/ui/section/action/deletetitle.c index da25bdb..e71d56a 100644 --- a/source/ui/section/action/deletetitle.c +++ b/source/ui/section/action/deletetitle.c @@ -3,11 +3,12 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" diff --git a/source/ui/section/action/erasetwlsave.c b/source/ui/section/action/erasetwlsave.c index 30db5ed..eb02a04 100644 --- a/source/ui/section/action/erasetwlsave.c +++ b/source/ui/section/action/erasetwlsave.c @@ -5,11 +5,12 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" @@ -115,7 +116,14 @@ static void action_erase_twl_save_update(ui_view* view, void* data, float* progr } *progress = eraseData->eraseInfo.currTotal != 0 ? (float) ((double) eraseData->eraseInfo.currProcessed / (double) eraseData->eraseInfo.currTotal) : 0; - snprintf(text, PROGRESS_TEXT_MAX, "%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", util_get_display_size(eraseData->eraseInfo.currProcessed), util_get_display_size_units(eraseData->eraseInfo.currProcessed), util_get_display_size(eraseData->eraseInfo.currTotal), util_get_display_size_units(eraseData->eraseInfo.currTotal), util_get_display_size(eraseData->eraseInfo.copyBytesPerSecond), util_get_display_size_units(eraseData->eraseInfo.copyBytesPerSecond), util_get_display_eta(eraseData->eraseInfo.estimatedRemainingSeconds)); + snprintf(text, PROGRESS_TEXT_MAX, "%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", + ui_get_display_size(eraseData->eraseInfo.currProcessed), + ui_get_display_size_units(eraseData->eraseInfo.currProcessed), + ui_get_display_size(eraseData->eraseInfo.currTotal), + ui_get_display_size_units(eraseData->eraseInfo.currTotal), + ui_get_display_size(eraseData->eraseInfo.copyBytesPerSecond), + ui_get_display_size_units(eraseData->eraseInfo.copyBytesPerSecond), + ui_get_display_eta(eraseData->eraseInfo.estimatedRemainingSeconds)); } static void action_erase_twl_save_onresponse(ui_view* view, void* data, u32 response) { diff --git a/source/ui/section/action/exportsecurevalue.c b/source/ui/section/action/exportsecurevalue.c index b9df840..942afcc 100644 --- a/source/ui/section/action/exportsecurevalue.c +++ b/source/ui/section/action/exportsecurevalue.c @@ -3,11 +3,12 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" diff --git a/source/ui/section/action/exporttwlsave.c b/source/ui/section/action/exporttwlsave.c index abbd5f9..c7c7ccd 100644 --- a/source/ui/section/action/exporttwlsave.c +++ b/source/ui/section/action/exporttwlsave.c @@ -4,11 +4,12 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" @@ -137,7 +138,14 @@ static void action_export_twl_save_update(ui_view* view, void* data, float* prog } *progress = exportData->exportInfo.currTotal != 0 ? (float) ((double) exportData->exportInfo.currProcessed / (double) exportData->exportInfo.currTotal) : 0; - snprintf(text, PROGRESS_TEXT_MAX, "%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", util_get_display_size(exportData->exportInfo.currProcessed), util_get_display_size_units(exportData->exportInfo.currProcessed), util_get_display_size(exportData->exportInfo.currTotal), util_get_display_size_units(exportData->exportInfo.currTotal), util_get_display_size(exportData->exportInfo.copyBytesPerSecond), util_get_display_size_units(exportData->exportInfo.copyBytesPerSecond), util_get_display_eta(exportData->exportInfo.estimatedRemainingSeconds)); + snprintf(text, PROGRESS_TEXT_MAX, "%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", + ui_get_display_size(exportData->exportInfo.currProcessed), + ui_get_display_size_units(exportData->exportInfo.currProcessed), + ui_get_display_size(exportData->exportInfo.currTotal), + ui_get_display_size_units(exportData->exportInfo.currTotal), + ui_get_display_size(exportData->exportInfo.copyBytesPerSecond), + ui_get_display_size_units(exportData->exportInfo.copyBytesPerSecond), + ui_get_display_eta(exportData->exportInfo.estimatedRemainingSeconds)); } static void action_export_twl_save_onresponse(ui_view* view, void* data, u32 response) { diff --git a/source/ui/section/action/extractsmdh.c b/source/ui/section/action/extractsmdh.c index 8ac846b..e16ecae 100644 --- a/source/ui/section/action/extractsmdh.c +++ b/source/ui/section/action/extractsmdh.c @@ -4,15 +4,17 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" #include "../../../core/util.h" +#include "../../../core/data/smdh.h" static void action_extract_smdh_update(ui_view* view, void* data, float* progress, char* text) { title_info* info = (title_info*) data; diff --git a/source/ui/section/action/importsecurevalue.c b/source/ui/section/action/importsecurevalue.c index 3d02423..7ca80ee 100644 --- a/source/ui/section/action/importsecurevalue.c +++ b/source/ui/section/action/importsecurevalue.c @@ -3,11 +3,12 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" diff --git a/source/ui/section/action/importseed.c b/source/ui/section/action/importseed.c index afa0231..0a3c95a 100644 --- a/source/ui/section/action/importseed.c +++ b/source/ui/section/action/importseed.c @@ -3,11 +3,12 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" diff --git a/source/ui/section/action/importtwlsave.c b/source/ui/section/action/importtwlsave.c index ba53d14..d051a07 100644 --- a/source/ui/section/action/importtwlsave.c +++ b/source/ui/section/action/importtwlsave.c @@ -4,11 +4,12 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" @@ -123,7 +124,14 @@ static void action_import_twl_save_update(ui_view* view, void* data, float* prog } *progress = importData->importInfo.currTotal != 0 ? (float) ((double) importData->importInfo.currProcessed / (double) importData->importInfo.currTotal) : 0; - snprintf(text, PROGRESS_TEXT_MAX, "%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", util_get_display_size(importData->importInfo.currProcessed), util_get_display_size_units(importData->importInfo.currProcessed), util_get_display_size(importData->importInfo.currTotal), util_get_display_size_units(importData->importInfo.currTotal), util_get_display_size(importData->importInfo.copyBytesPerSecond), util_get_display_size_units(importData->importInfo.copyBytesPerSecond), util_get_display_eta(importData->importInfo.estimatedRemainingSeconds)); + snprintf(text, PROGRESS_TEXT_MAX, "%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", + ui_get_display_size(importData->importInfo.currProcessed), + ui_get_display_size_units(importData->importInfo.currProcessed), + ui_get_display_size(importData->importInfo.currTotal), + ui_get_display_size_units(importData->importInfo.currTotal), + ui_get_display_size(importData->importInfo.copyBytesPerSecond), + ui_get_display_size_units(importData->importInfo.copyBytesPerSecond), + ui_get_display_eta(importData->importInfo.estimatedRemainingSeconds)); } static void action_import_twl_save_onresponse(ui_view* view, void* data, u32 response) { diff --git a/source/ui/section/action/installcdn.c b/source/ui/section/action/installcdn.c index 1a18a37..febfa83 100644 --- a/source/ui/section/action/installcdn.c +++ b/source/ui/section/action/installcdn.c @@ -5,16 +5,18 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../kbd.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" #include "../../../core/util.h" +#include "../../../core/data/tmd.h" #define CONTENTS_MAX 256 @@ -93,13 +95,13 @@ static Result action_install_cdn_open_dst(void* data, u32 index, void* initialRe install_cdn_data* installData = (install_cdn_data*) data; if(index == 0) { - installData->contentCount = util_get_tmd_content_count((u8*) initialReadBlock); + installData->contentCount = tmd_get_content_count((u8*) initialReadBlock); if(installData->contentCount > CONTENTS_MAX) { return R_FBI_OUT_OF_RANGE; } for(u32 i = 0; i < installData->contentCount; i++) { - u8* contentChunk = util_get_tmd_content_chunk((u8*) initialReadBlock, i); + u8* contentChunk = tmd_get_content_chunk((u8*) initialReadBlock, i); installData->contentIds[i] = __builtin_bswap32(*(u32*) &contentChunk[0x00]); installData->contentIndices[i] = __builtin_bswap16(*(u16*) &contentChunk[0x04]); @@ -244,7 +246,14 @@ static void action_install_cdn_update(ui_view* view, void* data, float* progress } *progress = installData->installInfo.currTotal != 0 ? (float) ((double) installData->installInfo.currProcessed / (double) installData->installInfo.currTotal) : 0; - snprintf(text, PROGRESS_TEXT_MAX, "%lu / %lu\n%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", installData->installInfo.processed, installData->installInfo.total, util_get_display_size(installData->installInfo.currProcessed), util_get_display_size_units(installData->installInfo.currProcessed), util_get_display_size(installData->installInfo.currTotal), util_get_display_size_units(installData->installInfo.currTotal), util_get_display_size(installData->installInfo.copyBytesPerSecond), util_get_display_size_units(installData->installInfo.copyBytesPerSecond), util_get_display_eta(installData->installInfo.estimatedRemainingSeconds)); + snprintf(text, PROGRESS_TEXT_MAX, "%lu / %lu\n%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", installData->installInfo.processed, installData->installInfo.total, + ui_get_display_size(installData->installInfo.currProcessed), + ui_get_display_size_units(installData->installInfo.currProcessed), + ui_get_display_size(installData->installInfo.currTotal), + ui_get_display_size_units(installData->installInfo.currTotal), + ui_get_display_size(installData->installInfo.copyBytesPerSecond), + ui_get_display_size_units(installData->installInfo.copyBytesPerSecond), + ui_get_display_eta(installData->installInfo.estimatedRemainingSeconds)); } static void action_install_cdn_n3ds_onresponse(ui_view* view, void* data, u32 response) { diff --git a/source/ui/section/action/installcias.c b/source/ui/section/action/installcias.c index dcd5824..8b4b4a2 100644 --- a/source/ui/section/action/installcias.c +++ b/source/ui/section/action/installcias.c @@ -5,11 +5,12 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" @@ -236,7 +237,14 @@ static void action_install_cias_update(ui_view* view, void* data, float* progres } *progress = installData->installInfo.currTotal != 0 ? (float) ((double) installData->installInfo.currProcessed / (double) installData->installInfo.currTotal) : 0; - snprintf(text, PROGRESS_TEXT_MAX, "%lu / %lu\n%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", installData->installInfo.processed, installData->installInfo.total, util_get_display_size(installData->installInfo.currProcessed), util_get_display_size_units(installData->installInfo.currProcessed), util_get_display_size(installData->installInfo.currTotal), util_get_display_size_units(installData->installInfo.currTotal), util_get_display_size(installData->installInfo.copyBytesPerSecond), util_get_display_size_units(installData->installInfo.copyBytesPerSecond), util_get_display_eta(installData->installInfo.estimatedRemainingSeconds)); + snprintf(text, PROGRESS_TEXT_MAX, "%lu / %lu\n%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", installData->installInfo.processed, installData->installInfo.total, + ui_get_display_size(installData->installInfo.currProcessed), + ui_get_display_size_units(installData->installInfo.currProcessed), + ui_get_display_size(installData->installInfo.currTotal), + ui_get_display_size_units(installData->installInfo.currTotal), + ui_get_display_size(installData->installInfo.copyBytesPerSecond), + ui_get_display_size_units(installData->installInfo.copyBytesPerSecond), + ui_get_display_eta(installData->installInfo.estimatedRemainingSeconds)); } static void action_install_cias_onresponse(ui_view* view, void* data, u32 response) { diff --git a/source/ui/section/action/installtickets.c b/source/ui/section/action/installtickets.c index cf156c4..a1770f1 100644 --- a/source/ui/section/action/installtickets.c +++ b/source/ui/section/action/installtickets.c @@ -5,11 +5,12 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" @@ -199,7 +200,14 @@ static void action_install_tickets_update(ui_view* view, void* data, float* prog } *progress = installData->installInfo.currTotal != 0 ? (float) ((double) installData->installInfo.currProcessed / (double) installData->installInfo.currTotal) : 0; - snprintf(text, PROGRESS_TEXT_MAX, "%lu / %lu\n%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", installData->installInfo.processed, installData->installInfo.total, util_get_display_size(installData->installInfo.currProcessed), util_get_display_size_units(installData->installInfo.currProcessed), util_get_display_size(installData->installInfo.currTotal), util_get_display_size_units(installData->installInfo.currTotal), util_get_display_size(installData->installInfo.copyBytesPerSecond), util_get_display_size_units(installData->installInfo.copyBytesPerSecond), util_get_display_eta(installData->installInfo.estimatedRemainingSeconds)); + snprintf(text, PROGRESS_TEXT_MAX, "%lu / %lu\n%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", installData->installInfo.processed, installData->installInfo.total, + ui_get_display_size(installData->installInfo.currProcessed), + ui_get_display_size_units(installData->installInfo.currProcessed), + ui_get_display_size(installData->installInfo.currTotal), + ui_get_display_size_units(installData->installInfo.currTotal), + ui_get_display_size(installData->installInfo.copyBytesPerSecond), + ui_get_display_size_units(installData->installInfo.copyBytesPerSecond), + ui_get_display_eta(installData->installInfo.estimatedRemainingSeconds)); } #define CDN_PROMPT_DEFAULT_VERSION 0 diff --git a/source/ui/section/action/installtitledb.c b/source/ui/section/action/installtitledb.c index 1fd9d6f..c1d1fad 100644 --- a/source/ui/section/action/installtitledb.c +++ b/source/ui/section/action/installtitledb.c @@ -4,7 +4,7 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../list.h" #include "../../ui.h" diff --git a/source/ui/section/action/installurl.c b/source/ui/section/action/installurl.c index 802bc81..4e52f74 100644 --- a/source/ui/section/action/installurl.c +++ b/source/ui/section/action/installurl.c @@ -5,13 +5,16 @@ #include <3ds.h> #include "../action/action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/screen.h" #include "../../../core/util.h" +#include "../../../core/data/cia.h" +#include "../../../core/data/ticket.h" typedef enum content_type_e { CONTENT_CIA, @@ -160,7 +163,7 @@ static Result action_install_url_open_dst(void* data, u32 index, void* initialRe if(*(u16*) initialReadBlock == 0x2020) { installData->contentType = CONTENT_CIA; - u64 titleId = util_get_cia_title_id((u8*) initialReadBlock); + u64 titleId = cia_get_title_id((u8*) initialReadBlock); FS_MediaType dest = util_get_title_destination(titleId); @@ -204,7 +207,7 @@ static Result action_install_url_open_dst(void* data, u32 index, void* initialRe } } - installData->ticketInfo.titleId = util_get_ticket_title_id((u8*) initialReadBlock); + installData->ticketInfo.titleId = ticket_get_title_id((u8*) initialReadBlock); installData->ticketInfo.inUse = false; AM_DeleteTicket(installData->ticketInfo.titleId); @@ -368,7 +371,14 @@ static void action_install_url_install_update(ui_view* view, void* data, float* } *progress = installData->installInfo.currTotal != 0 ? (float) ((double) installData->installInfo.currProcessed / (double) installData->installInfo.currTotal) : 0; - snprintf(text, PROGRESS_TEXT_MAX, "%lu / %lu\n%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", installData->installInfo.processed, installData->installInfo.total, util_get_display_size(installData->installInfo.currProcessed), util_get_display_size_units(installData->installInfo.currProcessed), util_get_display_size(installData->installInfo.currTotal), util_get_display_size_units(installData->installInfo.currTotal), util_get_display_size(installData->installInfo.copyBytesPerSecond), util_get_display_size_units(installData->installInfo.copyBytesPerSecond), util_get_display_eta(installData->installInfo.estimatedRemainingSeconds)); + snprintf(text, PROGRESS_TEXT_MAX, "%lu / %lu\n%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", installData->installInfo.processed, installData->installInfo.total, + ui_get_display_size(installData->installInfo.currProcessed), + ui_get_display_size_units(installData->installInfo.currProcessed), + ui_get_display_size(installData->installInfo.currTotal), + ui_get_display_size_units(installData->installInfo.currTotal), + ui_get_display_size(installData->installInfo.copyBytesPerSecond), + ui_get_display_size_units(installData->installInfo.copyBytesPerSecond), + ui_get_display_eta(installData->installInfo.estimatedRemainingSeconds)); } static void action_install_url_confirm_onresponse(ui_view* view, void* data, u32 response) { diff --git a/source/ui/section/action/launchtitle.c b/source/ui/section/action/launchtitle.c index bd59526..ec6fefa 100644 --- a/source/ui/section/action/launchtitle.c +++ b/source/ui/section/action/launchtitle.c @@ -1,11 +1,12 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/screen.h" diff --git a/source/ui/section/action/newfolder.c b/source/ui/section/action/newfolder.c index 6601343..7653538 100644 --- a/source/ui/section/action/newfolder.c +++ b/source/ui/section/action/newfolder.c @@ -4,12 +4,13 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../kbd.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" @@ -47,7 +48,7 @@ static void action_new_folder_onresponse(ui_view* view, void* data, SwkbdButton list_item* folderItem = NULL; if(R_SUCCEEDED(task_create_file_item(&folderItem, parentDir->archive, path, FS_ATTRIBUTE_DIRECTORY))) { linked_list_add(newFolderData->items, folderItem); - linked_list_sort(newFolderData->items, NULL, util_compare_file_infos); + linked_list_sort(newFolderData->items, NULL, task_compare_files); } prompt_display_notify("Success", "Folder created.", COLOR_TEXT, NULL, NULL, NULL); diff --git a/source/ui/section/action/pastecontents.c b/source/ui/section/action/pastecontents.c index 2b7886d..9370ee1 100644 --- a/source/ui/section/action/pastecontents.c +++ b/source/ui/section/action/pastecontents.c @@ -5,11 +5,12 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/clipboard.h" #include "../../../core/linkedlist.h" @@ -249,7 +250,7 @@ static void action_paste_contents_update(ui_view* view, void* data, float* progr if(pasteData->pasteInfo.finished) { FSUSER_ControlArchive(pasteData->target->archive, ARCHIVE_ACTION_COMMIT_SAVE_DATA, NULL, 0, NULL, 0); - linked_list_sort(pasteData->items, NULL, util_compare_file_infos); + linked_list_sort(pasteData->items, NULL, task_compare_files); ui_pop(); info_destroy(view); @@ -268,7 +269,14 @@ static void action_paste_contents_update(ui_view* view, void* data, float* progr } *progress = pasteData->pasteInfo.currTotal != 0 ? (float) ((double) pasteData->pasteInfo.currProcessed / (double) pasteData->pasteInfo.currTotal) : 0; - snprintf(text, PROGRESS_TEXT_MAX, "%lu / %lu\n%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", pasteData->pasteInfo.processed, pasteData->pasteInfo.total, util_get_display_size(pasteData->pasteInfo.currProcessed), util_get_display_size_units(pasteData->pasteInfo.currProcessed), util_get_display_size(pasteData->pasteInfo.currTotal), util_get_display_size_units(pasteData->pasteInfo.currTotal), util_get_display_size(pasteData->pasteInfo.copyBytesPerSecond), util_get_display_size_units(pasteData->pasteInfo.copyBytesPerSecond), util_get_display_eta(pasteData->pasteInfo.estimatedRemainingSeconds)); + snprintf(text, PROGRESS_TEXT_MAX, "%lu / %lu\n%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", pasteData->pasteInfo.processed, pasteData->pasteInfo.total, + ui_get_display_size(pasteData->pasteInfo.currProcessed), + ui_get_display_size_units(pasteData->pasteInfo.currProcessed), + ui_get_display_size(pasteData->pasteInfo.currTotal), + ui_get_display_size_units(pasteData->pasteInfo.currTotal), + ui_get_display_size(pasteData->pasteInfo.copyBytesPerSecond), + ui_get_display_size_units(pasteData->pasteInfo.copyBytesPerSecond), + ui_get_display_eta(pasteData->pasteInfo.estimatedRemainingSeconds)); } static void action_paste_contents_onresponse(ui_view* view, void* data, u32 response) { diff --git a/source/ui/section/action/rename.c b/source/ui/section/action/rename.c index 74f6855..4bc39e3 100644 --- a/source/ui/section/action/rename.c +++ b/source/ui/section/action/rename.c @@ -5,12 +5,13 @@ #include <3ds.h> #include "action.h" -#include "../task/task.h" +#include "../task/uitask.h" #include "../../error.h" #include "../../info.h" #include "../../kbd.h" #include "../../list.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" @@ -71,7 +72,7 @@ static void action_rename_onresponse(ui_view* view, void* data, SwkbdButton butt strncpy(targetInfo->name, fileName, FILE_NAME_MAX); strncpy(targetInfo->path, dstPath, FILE_PATH_MAX); - linked_list_sort(renameData->items, NULL, util_compare_file_infos); + linked_list_sort(renameData->items, NULL, task_compare_files); prompt_display_notify("Success", "Renamed.", COLOR_TEXT, NULL, NULL, NULL); } else { diff --git a/source/ui/section/dumpnand.c b/source/ui/section/dumpnand.c index 293df01..764ffcc 100644 --- a/source/ui/section/dumpnand.c +++ b/source/ui/section/dumpnand.c @@ -6,10 +6,11 @@ #include <3ds.h> #include "section.h" -#include "task/task.h" +#include "task/uitask.h" #include "../error.h" #include "../info.h" #include "../prompt.h" +#include "../resources.h" #include "../ui.h" #include "../../core/screen.h" #include "../../core/util.h" @@ -117,7 +118,11 @@ static void dumpnand_update(ui_view* view, void* data, float* progress, char* te } *progress = dumpData->currTotal != 0 ? (float) ((double) dumpData->currProcessed / (double) dumpData->currTotal) : 0; - snprintf(text, PROGRESS_TEXT_MAX, "%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", util_get_display_size(dumpData->currProcessed), util_get_display_size_units(dumpData->currProcessed), util_get_display_size(dumpData->currTotal), util_get_display_size_units(dumpData->currTotal), util_get_display_size(dumpData->copyBytesPerSecond), util_get_display_size_units(dumpData->copyBytesPerSecond), util_get_display_eta(dumpData->estimatedRemainingSeconds)); + snprintf(text, PROGRESS_TEXT_MAX, "%.2f %s / %.2f %s\n%.2f %s/s, ETA %s", + ui_get_display_size(dumpData->currProcessed), ui_get_display_size_units(dumpData->currProcessed), + ui_get_display_size(dumpData->currTotal), ui_get_display_size_units(dumpData->currTotal), + ui_get_display_size(dumpData->copyBytesPerSecond), ui_get_display_size_units(dumpData->copyBytesPerSecond), + ui_get_display_eta(dumpData->estimatedRemainingSeconds)); } static void dumpnand_onresponse(ui_view* view, void* data, u32 response) { diff --git a/source/ui/section/extsavedata.c b/source/ui/section/extsavedata.c index 290c255..7499cd1 100644 --- a/source/ui/section/extsavedata.c +++ b/source/ui/section/extsavedata.c @@ -6,9 +6,10 @@ #include "section.h" #include "action/action.h" -#include "task/task.h" +#include "task/uitask.h" #include "../error.h" #include "../list.h" +#include "../resources.h" #include "../ui.h" #include "../../core/linkedlist.h" #include "../../core/screen.h" diff --git a/source/ui/section/files.c b/source/ui/section/files.c index 0e3b613..d4a2e1e 100644 --- a/source/ui/section/files.c +++ b/source/ui/section/files.c @@ -6,10 +6,11 @@ #include "section.h" #include "action/action.h" -#include "task/task.h" +#include "task/uitask.h" #include "../error.h" #include "../list.h" #include "../prompt.h" +#include "../resources.h" #include "../ui.h" #include "../../core/clipboard.h" #include "../../core/linkedlist.h" diff --git a/source/ui/section/pendingtitles.c b/source/ui/section/pendingtitles.c index d72aca2..ce61bbd 100644 --- a/source/ui/section/pendingtitles.c +++ b/source/ui/section/pendingtitles.c @@ -5,9 +5,10 @@ #include "section.h" #include "action/action.h" -#include "task/task.h" +#include "task/uitask.h" #include "../error.h" #include "../list.h" +#include "../resources.h" #include "../ui.h" #include "../../core/linkedlist.h" #include "../../core/screen.h" diff --git a/source/ui/section/remoteinstall.c b/source/ui/section/remoteinstall.c index 9973c71..2915250 100644 --- a/source/ui/section/remoteinstall.c +++ b/source/ui/section/remoteinstall.c @@ -10,16 +10,17 @@ #include "section.h" #include "action/action.h" -#include "task/task.h" #include "../error.h" #include "../info.h" #include "../kbd.h" #include "../list.h" #include "../prompt.h" +#include "../resources.h" #include "../ui.h" #include "../../core/linkedlist.h" #include "../../core/screen.h" #include "../../core/util.h" +#include "../../core/task/capturecam.h" #include "../../libs/quirc/quirc_internal.h" static bool remoteinstall_get_last_urls(char* out, size_t size) { diff --git a/source/ui/section/systemsavedata.c b/source/ui/section/systemsavedata.c index ca34c70..b37d36b 100644 --- a/source/ui/section/systemsavedata.c +++ b/source/ui/section/systemsavedata.c @@ -5,9 +5,10 @@ #include "section.h" #include "action/action.h" -#include "task/task.h" +#include "task/uitask.h" #include "../error.h" #include "../list.h" +#include "../resources.h" #include "../ui.h" #include "../../core/linkedlist.h" #include "../../core/screen.h" diff --git a/source/ui/section/task/dataop.c b/source/ui/section/task/dataop.c index 711f627..2319587 100644 --- a/source/ui/section/task/dataop.c +++ b/source/ui/section/task/dataop.c @@ -3,11 +3,13 @@ #include <3ds.h> -#include "task.h" +#include "uitask.h" #include "../../prompt.h" +#include "../../resources.h" #include "../../ui.h" #include "../../../core/screen.h" #include "../../../core/util.h" +#include "../../../core/task/task.h" static Result task_data_op_check_running(data_op_data* data, u32 index, u32* srcHandle, u32* dstHandle) { Result res = 0; @@ -156,13 +158,7 @@ static void task_data_op_retry_onresponse(ui_view* view, void* data, u32 respons static void task_data_op_thread(void* arg) { data_op_data* data = (data_op_data*) arg; - bool reset = false; for(data->processed = 0; data->processed < data->total; data->processed++) { - if(reset) { - data->processed = 0; - reset = false; - } - Result res = 0; if(R_SUCCEEDED(res = task_data_op_check_running(data, data->processed, NULL, NULL))) { @@ -197,7 +193,7 @@ static void task_data_op_thread(void* arg) { if(proceed) { data->processed--; } else { - reset = true; + data->processed = 0; } } else if(!proceed) { break; diff --git a/source/ui/section/task/listextsavedata.c b/source/ui/section/task/listextsavedata.c index 896c91d..bb164f3 100644 --- a/source/ui/section/task/listextsavedata.c +++ b/source/ui/section/task/listextsavedata.c @@ -5,11 +5,14 @@ #include <3ds.h> -#include "task.h" +#include "uitask.h" #include "../../list.h" +#include "../../resources.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" #include "../../../core/util.h" +#include "../../../core/data/smdh.h" +#include "../../../core/task/task.h" #define MAX_EXT_SAVE_DATA 512 @@ -51,7 +54,7 @@ static Result task_populate_ext_save_data_from(populate_ext_save_data_data* data u32 smdhBytesRead = 0; if(R_SUCCEEDED(FSUSER_ReadExtSaveDataIcon(&smdhBytesRead, info, sizeof(SMDH), (u8*) smdh)) && smdhBytesRead == sizeof(SMDH)) { if(smdh->magic[0] == 'S' && smdh->magic[1] == 'M' && smdh->magic[2] == 'D' && smdh->magic[3] == 'H') { - SMDH_title* smdhTitle = util_select_smdh_title(smdh); + SMDH_title* smdhTitle = smdh_select_title(smdh); utf16_to_utf8((uint8_t*) item->name, smdhTitle->shortDescription, LIST_ITEM_NAME_MAX - 1); diff --git a/source/ui/section/task/listfiles.c b/source/ui/section/task/listfiles.c index d8d3b14..d5d1718 100644 --- a/source/ui/section/task/listfiles.c +++ b/source/ui/section/task/listfiles.c @@ -5,14 +5,43 @@ #include <3ds.h> -#include "task.h" +#include "uitask.h" #include "../../list.h" +#include "../../resources.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" #include "../../../core/util.h" +#include "../../../core/data/cia.h" +#include "../../../core/data/smdh.h" +#include "../../../core/task/task.h" #define MAX_FILES 1024 +int task_compare_files(void* userData, const void* p1, const void* p2) { + list_item* info1 = (list_item*) p1; + list_item* info2 = (list_item*) p2; + + bool info1Base = strncmp(info1->name, "", LIST_ITEM_NAME_MAX) == 0 || strncmp(info1->name, "", LIST_ITEM_NAME_MAX) == 0; + bool info2Base = strncmp(info2->name, "", LIST_ITEM_NAME_MAX) == 0 || strncmp(info2->name, "", LIST_ITEM_NAME_MAX) == 0; + + if(info1Base && !info2Base) { + return -1; + } else if(!info1Base && info2Base) { + return 1; + } else { + file_info* f1 = (file_info*) info1->data; + file_info* f2 = (file_info*) info2->data; + + if((f1->attributes & FS_ATTRIBUTE_DIRECTORY) && !(f2->attributes & FS_ATTRIBUTE_DIRECTORY)) { + return -1; + } else if(!(f1->attributes & FS_ATTRIBUTE_DIRECTORY) && (f2->attributes & FS_ATTRIBUTE_DIRECTORY)) { + return 1; + } else { + return strncasecmp(f1->name, f2->name, FILE_NAME_MAX); + } + } +} + Result task_create_file_item(list_item** out, FS_Archive archive, const char* path, u32 attributes) { Result res = 0; @@ -71,9 +100,9 @@ Result task_create_file_item(list_item** out, FS_Archive archive, const char* pa SMDH* smdh = (SMDH*) calloc(1, sizeof(SMDH)); if(smdh != NULL) { - if(R_SUCCEEDED(util_get_cia_file_smdh(smdh, fileHandle))) { + if(R_SUCCEEDED(cia_file_get_smdh(smdh, fileHandle))) { if(smdh->magic[0] == 'S' && smdh->magic[1] == 'M' && smdh->magic[2] == 'D' && smdh->magic[3] == 'H') { - SMDH_title* smdhTitle = util_select_smdh_title(smdh); + SMDH_title* smdhTitle = smdh_select_title(smdh); fileInfo->ciaInfo.hasMeta = true; utf16_to_utf8((uint8_t*) fileInfo->ciaInfo.meta.shortDescription, smdhTitle->shortDescription, sizeof(fileInfo->ciaInfo.meta.shortDescription) - 1); diff --git a/source/ui/section/task/listpendingtitles.c b/source/ui/section/task/listpendingtitles.c index 3492ede..5617ca2 100644 --- a/source/ui/section/task/listpendingtitles.c +++ b/source/ui/section/task/listpendingtitles.c @@ -4,11 +4,13 @@ #include <3ds.h> -#include "task.h" +#include "uitask.h" #include "../../list.h" +#include "../../resources.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" #include "../../../core/util.h" +#include "../../../core/task/task.h" static int task_populate_pending_titles_compare_ids(const void* e1, const void* e2) { u64 id1 = *(u64*) e1; diff --git a/source/ui/section/task/listsystemsavedata.c b/source/ui/section/task/listsystemsavedata.c index 59b3979..cfeec7f 100644 --- a/source/ui/section/task/listsystemsavedata.c +++ b/source/ui/section/task/listsystemsavedata.c @@ -4,11 +4,13 @@ #include <3ds.h> -#include "task.h" +#include "uitask.h" #include "../../list.h" +#include "../../resources.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" #include "../../../core/util.h" +#include "../../../core/task/task.h" #define MAX_SYSTEM_SAVE_DATA 512 diff --git a/source/ui/section/task/listtickets.c b/source/ui/section/task/listtickets.c index 026eb02..d1259f5 100644 --- a/source/ui/section/task/listtickets.c +++ b/source/ui/section/task/listtickets.c @@ -4,11 +4,13 @@ #include <3ds.h> -#include "task.h" +#include "uitask.h" #include "../../list.h" +#include "../../resources.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" #include "../../../core/util.h" +#include "../../../core/task/task.h" static int task_populate_tickets_compare_ids(const void* e1, const void* e2) { u64 id1 = *(u64*) e1; diff --git a/source/ui/section/task/listtitledb.c b/source/ui/section/task/listtitledb.c index 184725a..1a734c2 100644 --- a/source/ui/section/task/listtitledb.c +++ b/source/ui/section/task/listtitledb.c @@ -6,11 +6,13 @@ #include <3ds.h> #include -#include "task.h" +#include "uitask.h" #include "../../list.h" +#include "../../resources.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" #include "../../../core/util.h" +#include "../../../core/task/task.h" #include "../../../libs/stb_image/stb_image.h" #define json_object_get_string(obj, name, def) (json_is_string(json_object_get(obj, name)) ? json_string_value(json_object_get(obj, name)) : def) diff --git a/source/ui/section/task/listtitles.c b/source/ui/section/task/listtitles.c index f59665b..d0f692f 100644 --- a/source/ui/section/task/listtitles.c +++ b/source/ui/section/task/listtitles.c @@ -5,11 +5,15 @@ #include <3ds.h> -#include "task.h" +#include "uitask.h" #include "../../list.h" +#include "../../resources.h" #include "../../../core/linkedlist.h" #include "../../../core/screen.h" #include "../../../core/util.h" +#include "../../../core/data/bnr.h" +#include "../../../core/data/smdh.h" +#include "../../../core/task/task.h" static Result task_populate_titles_add_ctr(populate_titles_data* data, FS_MediaType mediaType, u64 titleId) { Result res = 0; @@ -40,7 +44,7 @@ static Result task_populate_titles_add_ctr(populate_titles_data* data, FS_MediaT if(smdh->magic[0] == 'S' && smdh->magic[1] == 'M' && smdh->magic[2] == 'D' && smdh->magic[3] == 'H') { titleInfo->hasMeta = true; - SMDH_title* smdhTitle = util_select_smdh_title(smdh); + SMDH_title* smdhTitle = smdh_select_title(smdh); utf16_to_utf8((uint8_t*) item->name, smdhTitle->shortDescription, LIST_ITEM_NAME_MAX - 1); @@ -138,7 +142,7 @@ static Result task_populate_titles_add_twl(populate_titles_data* data, FS_MediaT titleInfo->hasMeta = true; char title[0x100] = {'\0'}; - utf16_to_utf8((uint8_t*) title, util_select_bnr_title(bnr), sizeof(title) - 1); + utf16_to_utf8((uint8_t*) title, bnr_select_title(bnr), sizeof(title) - 1); if(strchr(title, '\n') == NULL) { size_t len = strlen(title); diff --git a/source/ui/section/task/task.h b/source/ui/section/task/uitask.h similarity index 89% rename from source/ui/section/task/task.h rename to source/ui/section/task/uitask.h index 668b6a0..d40d4a1 100644 --- a/source/ui/section/task/task.h +++ b/source/ui/section/task/uitask.h @@ -1,305 +1,283 @@ -#pragma once - -#define FILE_NAME_MAX 512 -#define FILE_PATH_MAX 512 - -typedef struct linked_list_s linked_list; -typedef struct list_item_s list_item; -typedef struct ui_view_s ui_view; - -typedef struct meta_info_s { - char shortDescription[0x100]; - char longDescription[0x200]; - char publisher[0x100]; - u32 region; - u32 texture; -} meta_info; - -typedef struct title_info_s { - FS_MediaType mediaType; - u64 titleId; - char productCode[0x10]; - u16 version; - u64 installedSize; - bool twl; - bool hasMeta; - meta_info meta; -} title_info; - -typedef struct pending_title_info_s { - FS_MediaType mediaType; - u64 titleId; - u16 version; -} pending_title_info; - -typedef struct ticket_info_s { - u64 titleId; - bool inUse; -} ticket_info; - -typedef struct ext_save_data_info_s { - FS_MediaType mediaType; - u64 extSaveDataId; - bool shared; - bool hasMeta; - meta_info meta; -} ext_save_data_info; - -typedef struct system_save_data_info_s { - u32 systemSaveDataId; -} system_save_data_info; - -typedef struct cia_info_s { - u64 titleId; - u16 version; - u64 installedSize; - bool hasMeta; - meta_info meta; -} cia_info; - -typedef struct file_info_s { - FS_Archive archive; - char name[FILE_NAME_MAX]; - char path[FILE_PATH_MAX]; - u32 attributes; - - // Files only - u64 size; - bool isCia; - cia_info ciaInfo; - bool isTicket; - ticket_info ticketInfo; -} file_info; - -typedef struct titledb_cia_info_s { - bool exists; - - u32 id; - char updatedAt[32]; - char version[32]; - u64 size; - u64 titleId; - - bool installed; - u16 installedVersion; -} titledb_cia_info; - -typedef struct titledb_smdh_info_s { - bool exists; - - u32 id; -} titledb_smdh_info; - -typedef struct titledb_tdsx_info_s { - bool exists; - - u32 id; - char updatedAt[32]; - char version[32]; - u64 size; - titledb_smdh_info smdh; - - bool installed; -} titledb_tdsx_info; - -typedef struct titledb_info_s { - u32 id; - char category[64]; - char headline[512]; - titledb_cia_info cia; - titledb_tdsx_info tdsx; - - meta_info meta; -} titledb_info; - -typedef enum capture_cam_camera_e { - CAMERA_OUTER, - CAMERA_INNER -} capture_cam_camera; - -typedef struct capture_cam_data_s { - u16* buffer; - s16 width; - s16 height; - capture_cam_camera camera; - - Handle mutex; - - volatile bool finished; - Result result; - Handle cancelEvent; -} capture_cam_data; - -typedef enum data_op_e { - DATAOP_COPY, - DATAOP_DELETE -} data_op; - -typedef struct data_op_data_s { - void* data; - - data_op op; - - // Copy - u32 copyBufferSize; - bool copyEmpty; - - u32 copyBytesPerSecond; - u32 estimatedRemainingSeconds; - - u32 processed; - u32 total; - - u64 currProcessed; - u64 currTotal; - - Result (*isSrcDirectory)(void* data, u32 index, bool* isDirectory); - Result (*makeDstDirectory)(void* data, u32 index); - - Result (*openSrc)(void* data, u32 index, u32* handle); - Result (*closeSrc)(void* data, u32 index, bool succeeded, u32 handle); - - Result (*getSrcSize)(void* data, u32 handle, u64* size); - Result (*readSrc)(void* data, u32 handle, u32* bytesRead, void* buffer, u64 offset, u32 size); - - Result (*openDst)(void* data, u32 index, void* initialReadBlock, u64 size, u32* handle); - Result (*closeDst)(void* data, u32 index, bool succeeded, u32 handle); - - Result (*writeDst)(void* data, u32 handle, u32* bytesWritten, void* buffer, u64 offset, u32 size); - - Result (*suspendCopy)(void* data, u32 index, u32* srcHandle, u32* dstHandle); - Result (*restoreCopy)(void* data, u32 index, u32* srcHandle, u32* dstHandle); - - // Delete - Result (*delete)(void* data, u32 index); - - // Suspend - Result (*suspend)(void* data, u32 index); - Result (*restore)(void* data, u32 index); - - // Errors - bool (*error)(void* data, u32 index, Result res, ui_view** errorView); - - // General - volatile bool finished; - Result result; - Handle cancelEvent; - - // Internal - volatile bool retryResponse; -} data_op_data; - -typedef struct populate_ext_save_data_data_s { - linked_list* items; - - void* userData; - bool (*filter)(void* data, u64 extSaveDataId, FS_MediaType mediaType); - int (*compare)(void* data, const void* p1, const void* p2); - - volatile bool finished; - Result result; - Handle cancelEvent; -} populate_ext_save_data_data; - -typedef struct populate_files_data_s { - linked_list* items; - - FS_Archive archive; - char path[FILE_PATH_MAX]; - - bool recursive; - bool includeBase; - - bool (*filter)(void* data, const char* name, u32 attributes); - void* filterData; - - volatile bool finished; - Result result; - Handle cancelEvent; -} populate_files_data; - -typedef struct populate_pending_titles_data_s { - linked_list* items; - - volatile bool finished; - Result result; - Handle cancelEvent; -} populate_pending_titles_data; - -typedef struct populate_system_save_data_data_s { - linked_list* items; - - volatile bool finished; - Result result; - Handle cancelEvent; -} populate_system_save_data_data; - -typedef struct populate_tickets_data_s { - linked_list* items; - - volatile bool finished; - Result result; - Handle cancelEvent; -} populate_tickets_data; - -typedef struct populate_titles_data_s { - linked_list* items; - - void* userData; - bool (*filter)(void* data, u64 titleId, FS_MediaType mediaType); - int (*compare)(void* data, const void* p1, const void* p2); - - volatile bool finished; - Result result; - Handle cancelEvent; -} populate_titles_data; - -typedef struct populate_titledb_data_s { - linked_list* items; - - volatile bool itemsListed; - volatile bool finished; - Result result; - Handle cancelEvent; -} populate_titledb_data; - -void task_init(); -void task_exit(); -bool task_is_quit_all(); -Handle task_get_pause_event(); -Handle task_get_suspend_event(); - -Result task_capture_cam(capture_cam_data* data); - -Result task_data_op(data_op_data* data); - -void task_free_ext_save_data(list_item* item); -void task_clear_ext_save_data(linked_list* items); -Result task_populate_ext_save_data(populate_ext_save_data_data* data); - -void task_free_file(list_item* item); -void task_clear_files(linked_list* items); -Result task_create_file_item(list_item** out, FS_Archive archive, const char* path, u32 attributes); -Result task_populate_files(populate_files_data* data); - -void task_free_pending_title(list_item* item); -void task_clear_pending_titles(linked_list* items); -Result task_populate_pending_titles(populate_pending_titles_data* data); - -void task_free_system_save_data(list_item* item); -void task_clear_system_save_data(linked_list* items); -Result task_populate_system_save_data(populate_system_save_data_data* data); - -void task_populate_tickets_update_use(list_item* item); -void task_free_ticket(list_item* item); -void task_clear_tickets(linked_list* items); -Result task_populate_tickets(populate_tickets_data* data); - -void task_free_title(list_item* item); -void task_clear_titles(linked_list* items); -Result task_populate_titles(populate_titles_data* data); - -void task_populate_titledb_update_status(list_item* item); -void task_free_titledb(list_item* item); -void task_clear_titledb(linked_list* items); +#pragma once + +// TODO: Find a way to get rid of this? +#ifndef FILE_NAME_MAX +#define FILE_NAME_MAX 512 +#define FILE_PATH_MAX 512 +#endif + +typedef struct linked_list_s linked_list; +typedef struct list_item_s list_item; +typedef struct ui_view_s ui_view; + +typedef struct meta_info_s { + char shortDescription[0x100]; + char longDescription[0x200]; + char publisher[0x100]; + u32 region; + u32 texture; +} meta_info; + +typedef struct title_info_s { + FS_MediaType mediaType; + u64 titleId; + char productCode[0x10]; + u16 version; + u64 installedSize; + bool twl; + bool hasMeta; + meta_info meta; +} title_info; + +typedef struct pending_title_info_s { + FS_MediaType mediaType; + u64 titleId; + u16 version; +} pending_title_info; + +typedef struct ticket_info_s { + u64 titleId; + bool inUse; +} ticket_info; + +typedef struct ext_save_data_info_s { + FS_MediaType mediaType; + u64 extSaveDataId; + bool shared; + bool hasMeta; + meta_info meta; +} ext_save_data_info; + +typedef struct system_save_data_info_s { + u32 systemSaveDataId; +} system_save_data_info; + +typedef struct cia_info_s { + u64 titleId; + u16 version; + u64 installedSize; + bool hasMeta; + meta_info meta; +} cia_info; + +typedef struct file_info_s { + FS_Archive archive; + char name[FILE_NAME_MAX]; + char path[FILE_PATH_MAX]; + u32 attributes; + + // Files only + u64 size; + bool isCia; + cia_info ciaInfo; + bool isTicket; + ticket_info ticketInfo; +} file_info; + +typedef struct titledb_cia_info_s { + bool exists; + + u32 id; + char updatedAt[32]; + char version[32]; + u64 size; + u64 titleId; + + bool installed; + u16 installedVersion; +} titledb_cia_info; + +typedef struct titledb_smdh_info_s { + bool exists; + + u32 id; +} titledb_smdh_info; + +typedef struct titledb_tdsx_info_s { + bool exists; + + u32 id; + char updatedAt[32]; + char version[32]; + u64 size; + titledb_smdh_info smdh; + + bool installed; +} titledb_tdsx_info; + +typedef struct titledb_info_s { + u32 id; + char category[64]; + char headline[512]; + titledb_cia_info cia; + titledb_tdsx_info tdsx; + + meta_info meta; +} titledb_info; + +typedef enum data_op_e { + DATAOP_COPY, + DATAOP_DELETE +} data_op; + +typedef struct data_op_data_s { + void* data; + + data_op op; + + // Copy + u32 copyBufferSize; + bool copyEmpty; + + u32 copyBytesPerSecond; + u32 estimatedRemainingSeconds; + + u32 processed; + u32 total; + + u64 currProcessed; + u64 currTotal; + + Result (*isSrcDirectory)(void* data, u32 index, bool* isDirectory); + Result (*makeDstDirectory)(void* data, u32 index); + + Result (*openSrc)(void* data, u32 index, u32* handle); + Result (*closeSrc)(void* data, u32 index, bool succeeded, u32 handle); + + Result (*getSrcSize)(void* data, u32 handle, u64* size); + Result (*readSrc)(void* data, u32 handle, u32* bytesRead, void* buffer, u64 offset, u32 size); + + Result (*openDst)(void* data, u32 index, void* initialReadBlock, u64 size, u32* handle); + Result (*closeDst)(void* data, u32 index, bool succeeded, u32 handle); + + Result (*writeDst)(void* data, u32 handle, u32* bytesWritten, void* buffer, u64 offset, u32 size); + + Result (*suspendCopy)(void* data, u32 index, u32* srcHandle, u32* dstHandle); + Result (*restoreCopy)(void* data, u32 index, u32* srcHandle, u32* dstHandle); + + // Delete + Result (*delete)(void* data, u32 index); + + // Suspend + Result (*suspend)(void* data, u32 index); + Result (*restore)(void* data, u32 index); + + // Errors + bool (*error)(void* data, u32 index, Result res, ui_view** errorView); + + // General + volatile bool finished; + Result result; + Handle cancelEvent; + + // Internal + volatile bool retryResponse; +} data_op_data; + +typedef struct populate_ext_save_data_data_s { + linked_list* items; + + void* userData; + bool (*filter)(void* data, u64 extSaveDataId, FS_MediaType mediaType); + int (*compare)(void* data, const void* p1, const void* p2); + + volatile bool finished; + Result result; + Handle cancelEvent; +} populate_ext_save_data_data; + +typedef struct populate_files_data_s { + linked_list* items; + + FS_Archive archive; + char path[FILE_PATH_MAX]; + + bool recursive; + bool includeBase; + + bool (*filter)(void* data, const char* name, u32 attributes); + void* filterData; + + volatile bool finished; + Result result; + Handle cancelEvent; +} populate_files_data; + +typedef struct populate_pending_titles_data_s { + linked_list* items; + + volatile bool finished; + Result result; + Handle cancelEvent; +} populate_pending_titles_data; + +typedef struct populate_system_save_data_data_s { + linked_list* items; + + volatile bool finished; + Result result; + Handle cancelEvent; +} populate_system_save_data_data; + +typedef struct populate_tickets_data_s { + linked_list* items; + + volatile bool finished; + Result result; + Handle cancelEvent; +} populate_tickets_data; + +typedef struct populate_titles_data_s { + linked_list* items; + + void* userData; + bool (*filter)(void* data, u64 titleId, FS_MediaType mediaType); + int (*compare)(void* data, const void* p1, const void* p2); + + volatile bool finished; + Result result; + Handle cancelEvent; +} populate_titles_data; + +typedef struct populate_titledb_data_s { + linked_list* items; + + volatile bool itemsListed; + volatile bool finished; + Result result; + Handle cancelEvent; +} populate_titledb_data; + +Result task_data_op(data_op_data* data); + +void task_free_ext_save_data(list_item* item); +void task_clear_ext_save_data(linked_list* items); +Result task_populate_ext_save_data(populate_ext_save_data_data* data); + +int task_compare_files(void* userData, const void* p1, const void* p2); +void task_free_file(list_item* item); +void task_clear_files(linked_list* items); +Result task_create_file_item(list_item** out, FS_Archive archive, const char* path, u32 attributes); +Result task_populate_files(populate_files_data* data); + +void task_free_pending_title(list_item* item); +void task_clear_pending_titles(linked_list* items); +Result task_populate_pending_titles(populate_pending_titles_data* data); + +void task_free_system_save_data(list_item* item); +void task_clear_system_save_data(linked_list* items); +Result task_populate_system_save_data(populate_system_save_data_data* data); + +void task_populate_tickets_update_use(list_item* item); +void task_free_ticket(list_item* item); +void task_clear_tickets(linked_list* items); +Result task_populate_tickets(populate_tickets_data* data); + +void task_free_title(list_item* item); +void task_clear_titles(linked_list* items); +Result task_populate_titles(populate_titles_data* data); + +void task_populate_titledb_update_status(list_item* item); +void task_free_titledb(list_item* item); +void task_clear_titledb(linked_list* items); Result task_populate_titledb(populate_titledb_data* data); \ No newline at end of file diff --git a/source/ui/section/tickets.c b/source/ui/section/tickets.c index 75df21e..0ef5fb7 100644 --- a/source/ui/section/tickets.c +++ b/source/ui/section/tickets.c @@ -5,9 +5,10 @@ #include "section.h" #include "action/action.h" -#include "task/task.h" +#include "task/uitask.h" #include "../error.h" #include "../list.h" +#include "../resources.h" #include "../ui.h" #include "../../core/linkedlist.h" #include "../../core/screen.h" diff --git a/source/ui/section/titledb.c b/source/ui/section/titledb.c index 4d11fc0..7e63ed9 100644 --- a/source/ui/section/titledb.c +++ b/source/ui/section/titledb.c @@ -6,9 +6,10 @@ #include "section.h" #include "action/action.h" -#include "task/task.h" +#include "task/uitask.h" #include "../error.h" #include "../list.h" +#include "../resources.h" #include "../ui.h" #include "../../core/linkedlist.h" #include "../../core/screen.h" diff --git a/source/ui/section/titles.c b/source/ui/section/titles.c index 869a682..8ede070 100644 --- a/source/ui/section/titles.c +++ b/source/ui/section/titles.c @@ -6,9 +6,10 @@ #include "section.h" #include "action/action.h" -#include "task/task.h" +#include "task/uitask.h" #include "../error.h" #include "../list.h" +#include "../resources.h" #include "../ui.h" #include "../../core/linkedlist.h" #include "../../core/screen.h" diff --git a/source/ui/section/update.c b/source/ui/section/update.c index 08995a2..d46ef46 100644 --- a/source/ui/section/update.c +++ b/source/ui/section/update.c @@ -10,6 +10,7 @@ #include "../error.h" #include "../info.h" #include "../prompt.h" +#include "../resources.h" #include "../ui.h" #include "../../core/screen.h" #include "../../core/util.h" diff --git a/source/ui/ui.c b/source/ui/ui.c index defa5e9..3bfa279 100644 --- a/source/ui/ui.c +++ b/source/ui/ui.c @@ -5,10 +5,12 @@ #include <3ds.h> #include +#include "resources.h" #include "ui.h" -#include "section/task/task.h" +#include "section/task/uitask.h" #include "../core/screen.h" #include "../core/util.h" +#include "../core/data/smdh.h" #define MAX_UI_VIEWS 16 @@ -211,7 +213,8 @@ static void ui_draw_top(ui_view* ui) { } u64 size = (u64) resource.freeClusters * (u64) resource.clusterSize; - snprintf(currBuffer, sizeof(ui_free_space_buffer) - (currBuffer - ui_free_space_buffer), "SD: %.1f %s", util_get_display_size(size), util_get_display_size_units(size)); + snprintf(currBuffer, sizeof(ui_free_space_buffer) - (currBuffer - ui_free_space_buffer), "SD: %.1f %s", + ui_get_display_size(size), ui_get_display_size_units(size)); currBuffer += strlen(currBuffer); } @@ -222,7 +225,8 @@ static void ui_draw_top(ui_view* ui) { } u64 size = (u64) resource.freeClusters * (u64) resource.clusterSize; - snprintf(currBuffer, sizeof(ui_free_space_buffer) - (currBuffer - ui_free_space_buffer), "CTR NAND: %.1f %s", util_get_display_size(size), util_get_display_size_units(size)); + snprintf(currBuffer, sizeof(ui_free_space_buffer) - (currBuffer - ui_free_space_buffer), "CTR NAND: %.1f %s", + ui_get_display_size(size), ui_get_display_size_units(size)); currBuffer += strlen(currBuffer); } @@ -233,7 +237,8 @@ static void ui_draw_top(ui_view* ui) { } u64 size = (u64) resource.freeClusters * (u64) resource.clusterSize; - snprintf(currBuffer, sizeof(ui_free_space_buffer) - (currBuffer - ui_free_space_buffer), "TWL NAND: %.1f %s", util_get_display_size(size), util_get_display_size_units(size)); + snprintf(currBuffer, sizeof(ui_free_space_buffer) - (currBuffer - ui_free_space_buffer), "TWL NAND: %.1f %s", + ui_get_display_size(size), ui_get_display_size_units(size)); currBuffer += strlen(currBuffer); } @@ -244,7 +249,8 @@ static void ui_draw_top(ui_view* ui) { } u64 size = (u64) resource.freeClusters * (u64) resource.clusterSize; - snprintf(currBuffer, sizeof(ui_free_space_buffer) - (currBuffer - ui_free_space_buffer), "TWL Photo: %.1f %s", util_get_display_size(size), util_get_display_size_units(size)); + snprintf(currBuffer, sizeof(ui_free_space_buffer) - (currBuffer - ui_free_space_buffer), "TWL Photo: %.1f %s", + ui_get_display_size(size), ui_get_display_size_units(size)); currBuffer += strlen(currBuffer); } @@ -355,6 +361,51 @@ bool ui_update() { return ui != NULL; } +const char* ui_get_display_eta(u32 seconds) { + static char disp[12]; + + u8 hours = seconds / 3600; + seconds -= hours * 3600; + u8 minutes = seconds / 60; + seconds -= minutes* 60; + + snprintf(disp, 12, "%02u:%02u:%02u", hours, minutes, (u8) seconds); + return disp; +} + +double ui_get_display_size(u64 size) { + double s = size; + if(s > 1024) { + s /= 1024; + } + + if(s > 1024) { + s /= 1024; + } + + if(s > 1024) { + s /= 1024; + } + + return s; +} + +const char* ui_get_display_size_units(u64 size) { + if(size > 1024 * 1024 * 1024) { + return "GiB"; + } + + if(size > 1024 * 1024) { + return "MiB"; + } + + if(size > 1024) { + return "KiB"; + } + + return "B"; +} + void ui_draw_meta_info(ui_view* view, void* data, float x1, float y1, float x2, float y2) { meta_info* info = (meta_info*) data; @@ -483,7 +534,8 @@ void ui_draw_file_info(ui_view* view, void* data, float x1, float y1, float x2, infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, "\n"); if(!(info->attributes & FS_ATTRIBUTE_DIRECTORY)) { - infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, "Size: %.2f %s\n", util_get_display_size(info->size), util_get_display_size_units(info->size)); + infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, "Size: %.2f %s\n", + ui_get_display_size(info->size), ui_get_display_size_units(info->size)); if(info->isCia) { char regionString[64]; @@ -491,7 +543,7 @@ void ui_draw_file_info(ui_view* view, void* data, float x1, float y1, float x2, if(info->ciaInfo.hasMeta) { ui_draw_meta_info(view, &info->ciaInfo.meta, x1, y1, x2, y2); - util_smdh_region_to_string(regionString, info->ciaInfo.meta.region, sizeof(regionString)); + smdh_region_to_string(regionString, info->ciaInfo.meta.region, sizeof(regionString)); } else { snprintf(regionString, sizeof(regionString), "Unknown"); } @@ -504,7 +556,8 @@ void ui_draw_file_info(ui_view* view, void* data, float x1, float y1, float x2, info->ciaInfo.titleId, info->ciaInfo.version, (info->ciaInfo.version >> 10) & 0x3F, (info->ciaInfo.version >> 4) & 0x3F, info->ciaInfo.version & 0xF, regionString, - util_get_display_size(info->ciaInfo.installedSize), util_get_display_size_units(info->ciaInfo.installedSize)); + ui_get_display_size(info->ciaInfo.installedSize), + ui_get_display_size_units(info->ciaInfo.installedSize)); } else if(info->isTicket) { infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, "Ticket ID: %016llX", info->ticketInfo.titleId); } @@ -577,7 +630,7 @@ void ui_draw_title_info(ui_view* view, void* data, float x1, float y1, float x2, if(info->hasMeta) { ui_draw_meta_info(view, &info->meta, x1, y1, x2, y2); - util_smdh_region_to_string(regionString, info->meta.region, sizeof(regionString)); + smdh_region_to_string(regionString, info->meta.region, sizeof(regionString)); } else { snprintf(regionString, sizeof(regionString), "Unknown"); } @@ -596,7 +649,7 @@ void ui_draw_title_info(ui_view* view, void* data, float x1, float y1, float x2, info->version, (info->version >> 10) & 0x3F, (info->version >> 4) & 0x3F, info->version & 0xF, info->productCode, regionString, - util_get_display_size(info->installedSize), util_get_display_size_units(info->installedSize)); + ui_get_display_size(info->installedSize), ui_get_display_size_units(info->installedSize)); float infoWidth; screen_get_string_size(&infoWidth, NULL, infoText, 0.5f, 0.5f); @@ -650,7 +703,7 @@ void ui_draw_titledb_info_cia(ui_view* view, void* data, float x1, float y1, flo info->cia.titleId, info->cia.version, info->cia.installedVersion, (info->cia.installedVersion >> 10) & 0x3F, (info->cia.installedVersion >> 4) & 0x3F, info->cia.installedVersion & 0xF, - util_get_display_size(info->cia.size), util_get_display_size_units(info->cia.size), + ui_get_display_size(info->cia.size), ui_get_display_size_units(info->cia.size), updatedDate, updatedTime); float infoWidth; @@ -678,7 +731,7 @@ void ui_draw_titledb_info_tdsx(ui_view* view, void* data, float x1, float y1, fl "Size: %.2f %s\n" "Updated At: %s %s", info->tdsx.version, - util_get_display_size(info->tdsx.size), util_get_display_size_units(info->tdsx.size), + ui_get_display_size(info->tdsx.size), ui_get_display_size_units(info->tdsx.size), updatedDate, updatedTime); float infoWidth; diff --git a/source/ui/ui.h b/source/ui/ui.h index 7543a87..826d97c 100644 --- a/source/ui/ui.h +++ b/source/ui/ui.h @@ -24,6 +24,10 @@ bool ui_push(ui_view* view); void ui_pop(); bool ui_update(); +const char* ui_get_display_eta(u32 seconds); +double ui_get_display_size(u64 size); +const char* ui_get_display_size_units(u64 size); + void ui_draw_meta_info(ui_view* view, void* data, float x1, float y1, float x2, float y2); void ui_draw_ext_save_data_info(ui_view* view, void* data, float x1, float y1, float x2, float y2); void ui_draw_file_info(ui_view* view, void* data, float x1, float y1, float x2, float y2);