From e40cd00754c8baa730e0ff2e4671e1dc80e96ff0 Mon Sep 17 00:00:00 2001 From: Alex Taber Date: Mon, 10 Jun 2024 10:48:34 -0400 Subject: [PATCH] Avoid loading 15 MB files into RAM ever --- assets/back.png | Bin 696 -> 656 bytes include/fs.h | 1 + source/badges.c | 101 +++++++++++++++++++++++++++--------------------- source/fs.c | 23 ++++++++++- 4 files changed, 81 insertions(+), 44 deletions(-) diff --git a/assets/back.png b/assets/back.png index acb3d950aa4df8c34898ed1f2fbf0a7a118970ac..008ffab92688769e5841b2902eb99cd418d51362 100644 GIT binary patch delta 631 zcmV--0*L*%1&{@hB!7ZwLqkwWLqi}?a&Km7Y-IodD9@FVO(;ZB9L0Y#h^CQb7Rcf) zuwsK`$xxG`ra{eM;k`FzsCm!y-b^-@%2rwU*!Wu5ShKaTRZ96NSzA~U8|nGqH)V?+ zugcaGZj|^%an|Rc%8WSE ziBaK*u$HZ0qk_#P#}Xb8?o3;@AFbkV_x*8k8RA;T6vr4VSm?eV^#{MZbu;~arKE5a>YhCBtqbb6 z;A_+KJ`X+b>j-Kd;leKaR}Nt4UG&Ye*0~Q&>u`2i){Jd9-+g{Kr<2#s^t|qQvcMrO=l09GL-3^t!{eOAJ?~mv=MLcqpi_U>-00009 za7bBm000ic000ic0Tn1pfB*mhnn^@KR7gwhl|c%_Fbo7`=bt^~7x_$~`BYvLoLwOs z6M8At-ZCJBb(qCAPVC`tT5Ahxi)Ah$|DcW-dgt|{f z2huqtKY&2oLo@*-LNq^|2Q#w^mrd}AM80`Z0000EWmrjOO-%qQ00008000000002e RQ1q~8j=(jN5Qq=;KyRs!Nplu2UkH5`~Y!wa8h)U691PJ zTEuv8+>dwn9(V5mf3wO|vnK(lnq_2CNg6^ClDu?Zdk+{#50?g&Uv3W%F2>Ld`>)J&;^Mfxh}i>#<}FMpJzsm zY-XM~N-UJRSngt0HdNwi;+Udpl<&{EtZ?4qtXAu+eNXpF2XskIMF;2w3K2OR zmj6WQ0002BNklNLov}C{v>qCAmjLG>b@5j|)ki{!pVi`_3KM zwI0>T0t?{bNafRm6Y#PajF3PZkLP0000 0) { - DEBUG("Failed to write badgedatafile: 0x%08lx\n", res); - free(badgeMng); - free(badgeData); - return -1; + u32 read = 0; + res = FSFILE_Read(dataHandle, &read, cur, buf, min(0x10000, size)); + res = FSFILE_Write(sdHandle, NULL, cur, buf, read, FS_WRITE_FLUSH); + size -= read; + cur += read; } + free(badgeMng); - free(badgeData); + free(buf); + FSFILE_Close(dataHandle); + FSFILE_Close(sdHandle); return 0; } @@ -342,6 +360,7 @@ Result install_badges(void) Handle handle = 0; Handle folder = 0; Result res = 0; + draw_loading_bar(0, 1, INSTALL_BADGES); DEBUG("Backing up badges\n"); res = backup_badges(); @@ -377,7 +396,7 @@ Result install_badges(void) } badgeMngBuffer = NULL; - badgeDataBuffer = NULL; + badgeDataHandle = 0; rgb_buf_64x64 = NULL; rgb_buf_32x32 = NULL; alpha_buf_64x64 = NULL; @@ -399,13 +418,12 @@ Result install_badges(void) alpha_buf_64x64 = malloc(12*6*64*64/2); //Same thing, but 2 pixels of alpha data per byte rgb_buf_32x32 = malloc(12*6*32*32*2); //Same thing, but 32x32 alpha_buf_32x32 = malloc(12*6*32*32/2); - badgeDataBuffer = calloc(1, BADGE_DATA_SIZE); + res = FSUSER_OpenFile(&badgeDataHandle, ArchiveBadgeExt, fsMakePath(PATH_ASCII, "/BadgeData.dat"), FS_OPEN_WRITE, 0); badgeMngBuffer = calloc(1, BADGE_MNG_SIZE); if (!rgb_buf_64x64) { DEBUG("rgb_buf_64x64 alloc failed\n"); - res = -1; goto end; } @@ -427,9 +445,11 @@ Result install_badges(void) goto end; } - if (!badgeDataBuffer) + if (R_FAILED(res)) { - DEBUG("badgeDataBuffer alloc failed\n"); + badgeDataHandle = 0; + throw_error(language.badges.extdata_locked, ERROR_LEVEL_WARNING); + DEBUG("badgeDataHandle open failed\n"); goto end; } @@ -439,17 +459,19 @@ Result install_badges(void) goto end; } + zero_handle_memeasy(badgeDataHandle); + int badge_count = 0; int set_count = 0; int default_set = 0; int default_set_count = 0; int default_idx = 0; - draw_loading_bar(0, entries_read + 4, INSTALL_BADGES); + + draw_loading_bar(6, entries_read + 12, INSTALL_BADGES); for (u32 i = 0; i < entries_read && badge_count < 1000; ++i) { if (!strcmp(badge_files[i].shortExt, "PNG")) { - DEBUG("PNG discovered\n"); if (default_set == 0) { set_count += 1; @@ -462,7 +484,6 @@ Result install_badges(void) default_set_count += install_badge_png(fsMakePath(PATH_UTF16, path), badge_files[i], &badge_count, default_set); } else if (!strcmp(badge_files[i].shortExt, "ZIP")) { - DEBUG("ZIP discovered\n"); if (default_set == 0) { set_count += 1; @@ -475,13 +496,12 @@ Result install_badges(void) default_set_count += install_badge_zip(path, &badge_count, default_set); } else if (badge_files[i].attributes & FS_ATTRIBUTE_DIRECTORY) { - DEBUG("dir discovered\n"); set_count += 1; u32 count = install_badge_dir(badge_files[i], &badge_count, set_count); if (count == 0) set_count -= 1; } - draw_loading_bar(i, entries_read + 4, INSTALL_BADGES); + draw_loading_bar(i + 7, entries_read + 12, INSTALL_BADGES); } DEBUG("Badges installed - doing metadata\n"); @@ -493,7 +513,7 @@ Result install_badges(void) { u16 name[0x8A/2] = {0}; utf8_to_utf16(name, (u8 *) "Other Badges", 0x8A); - memcpy(badgeDataBuffer + default_index * 0x8A0 + i * 0x8A, &name, 0x8A); + FSFILE_Write(badgeDataHandle, NULL, default_index * 0x8A0 + i * 0x8A, &name, 0x8A, 0); } badgeMngBuffer[0x3D8 + default_index/8] |= 0 << (default_index % 8); @@ -516,16 +536,11 @@ Result install_badges(void) fclose(fp); pngToRGB565(icon_buf, size, rgb_buf_64x64, alpha_buf_64x64, rgb_buf_32x32, alpha_buf_32x32, true); free(icon_buf); - memcpy(badgeDataBuffer + 0x250F80 + default_index * 0x2000, rgb_buf_64x64, 64 * 64 * 2); + FSFILE_Write(badgeDataHandle, NULL, 0x250F80 + default_index * 0x2000, rgb_buf_64x64, 64 * 64 * 2, 0); } - res = buf_to_file(BADGE_DATA_SIZE, fsMakePath(PATH_ASCII, "/BadgeData.dat"), ArchiveBadgeExt, badgeDataBuffer); - if (res) - { - DEBUG("Error writing badge data! %lx\n", res); - throw_error(language.badges.extdata_locked, ERROR_LEVEL_WARNING); - goto end; - } + FSFILE_Flush(badgeDataHandle); + draw_loading_bar(entries_read + 9, entries_read + 12, INSTALL_BADGES); u32 total_badges = 0xFFFF * badge_count; // Quantity * unique badges? @@ -575,7 +590,7 @@ Result install_badges(void) if (alpha_buf_32x32) free(alpha_buf_32x32); if (handle) FSFILE_Close(handle); if (folder) FSDIR_Close(folder); - if (badgeDataBuffer) free(badgeDataBuffer); + if (badgeDataHandle) FSFILE_Close(badgeDataHandle); if (badgeMngBuffer) free(badgeMngBuffer); if (badge_files) free(badge_files); return res; diff --git a/source/fs.c b/source/fs.c index e731a4e..a414d8f 100644 --- a/source/fs.c +++ b/source/fs.c @@ -151,7 +151,11 @@ Result open_badge_extdata() createExtSaveData(0x000014d1); FSUSER_OpenArchive(&ArchiveBadgeExt, ARCHIVE_EXTDATA, badge); remake_file(fsMakePath(PATH_ASCII, "/BadgeMngFile.dat"), ArchiveBadgeExt, BADGE_MNG_SIZE); - remake_file(fsMakePath(PATH_ASCII, "/BadgeData.dat"), ArchiveBadgeExt, BADGE_DATA_SIZE); + FSUSER_CreateFile(ArchiveBadgeExt, fsMakePath(PATH_ASCII, "/BadgeData.dat"), 0, BADGE_DATA_SIZE); + FSUSER_OpenFile(&test_handle, ArchiveBadgeExt, fsMakePath(PATH_ASCII, "/BadgeData.dat"), FS_OPEN_WRITE, 0); + zero_handle_memeasy(test_handle); + FSFILE_Flush(test_handle); + FSFILE_Close(test_handle); } else { return res; @@ -488,6 +492,23 @@ void remake_file(FS_Path path, FS_Archive archive, u32 size) } } +Result zero_handle_memeasy(Handle handle) +{ + u64 size = 0; + u64 cur = 0; + FSFILE_GetSize(handle, &size); + char *zero_buf = calloc(1, 0x10000); + while (size > 0x10000) + { + FSFILE_Write(handle, NULL, cur, &zero_buf, 0x1000, 0); + cur += 0x10000; + size -= 0x10000; + } + FSFILE_Write(handle, NULL, cur, &zero_buf, size, 0); + free(zero_buf); + return 0; +} + static SwkbdCallbackResult fat32filter(void * user, const char ** ppMessage, const char * text, size_t textlen) { (void)textlen;