Add install badges from zip file

This commit is contained in:
2024-06-03 00:58:07 -04:00
parent df4c81c96d
commit 1a01ba502f
3 changed files with 92 additions and 15 deletions

View File

@@ -68,5 +68,6 @@ u32 compress_lz_file_fast(FS_Path path, FS_Archive archive, char * in_buf, u32 s
Result buf_to_file(u32 size, FS_Path path, FS_Archive archive, char * buf); Result buf_to_file(u32 size, FS_Path path, FS_Archive archive, char * buf);
void remake_file(FS_Path path, FS_Archive archive, u32 size); void remake_file(FS_Path path, FS_Archive archive, u32 size);
void save_zip_to_sd(char * filename, u32 size, char * buf, RemoteMode mode); void save_zip_to_sd(char * filename, u32 size, char * buf, RemoteMode mode);
s16 for_each_file_zip(u16 *zip_path, FS_Archive archive, u32 (*zip_iter_callback)(char *filebuf, u64 file_size, char *name, void *userdata), void *userdata);
#endif #endif

View File

@@ -113,28 +113,21 @@ u64 getShortcut(char *filename)
return shortcut; return shortcut;
} }
int install_badge_png(FS_Path badge_path, FS_DirectoryEntry badge_file, int *badge_count, int set_id) int install_badge_generic(char *file_buf, u64 file_size, u16 *name, int *badge_count, int set_id)
{ {
Result res; int badges_in_image = pngToRGB565(file_buf, file_size, rgb_buf_64x64, alpha_buf_64x64, rgb_buf_32x32, alpha_buf_32x32, false);
char *file_buf = NULL;
res = file_to_buf(badge_path, ArchiveSD, &file_buf);
if (res != badge_file.fileSize)
{
return -1;
}
int badges_in_image = pngToRGB565(file_buf, badge_file.fileSize, rgb_buf_64x64, alpha_buf_64x64, rgb_buf_32x32, alpha_buf_32x32, false);
char utf8_name[512] = {0}; char utf8_name[512] = {0};
utf16_to_utf8((u8 *) utf8_name, badge_file.name, 0x8A); utf16_to_utf8((u8 *) utf8_name, name, 0x8A);
u64 shortcut = getShortcut(utf8_name); u64 shortcut = getShortcut(utf8_name);
int badges_installed = 0; int badges_installed = 0;
for (int badge = 0; badge < badges_in_image && *badge_count < 1000; ++badge) for (int badge = 0; badge < badges_in_image && *badge_count < 1000; ++badge)
{ {
remove_exten(badge_file.name); remove_exten(name);
for (int j = 0; j < 16; ++j) // Copy name for all 16 languages for (int j = 0; j < 16; ++j) // Copy name for all 16 languages
{ {
memcpy(badgeDataBuffer + 0x35E80 + *badge_count * 16 * 0x8A + j * 0x8A, badge_file.name, 0x8A); memcpy(badgeDataBuffer + 0x35E80 + *badge_count * 16 * 0x8A + j * 0x8A, name, 0x8A);
} }
memcpy(badgeDataBuffer + 0x318F80 + *badge_count * 0x2800, rgb_buf_64x64 + badge * 64 * 64, 64 * 64 * 2); memcpy(badgeDataBuffer + 0x318F80 + *badge_count * 0x2800, rgb_buf_64x64 + badge * 64 * 64, 64 * 64 * 2);
memcpy(badgeDataBuffer + 0x31AF80 + *badge_count * 0x2800, alpha_buf_64x64 + badge * 64 * 64/2, 64 * 64/2); memcpy(badgeDataBuffer + 0x31AF80 + *badge_count * 0x2800, alpha_buf_64x64 + badge * 64 * 64/2, 64 * 64/2);
@@ -156,9 +149,51 @@ int install_badge_png(FS_Path badge_path, FS_DirectoryEntry badge_file, int *bad
*badge_count += 1; *badge_count += 1;
} }
return badges_installed; return badges_installed;
} }
int install_badge_png(FS_Path badge_path, FS_DirectoryEntry badge_file, int *badge_count, int set_id)
{
Result res;
char *file_buf = NULL;
res = file_to_buf(badge_path, ArchiveSD, &file_buf);
if (res != badge_file.fileSize)
{
return -1;
}
return install_badge_generic(file_buf, badge_file.fileSize, badge_file.name, badge_count, set_id);
}
typedef struct {
int *badge_count;
int set_id;
int installed;
} zip_userdata;
u32 zip_callback(char *file_buf, u64 file_size, char *name, void *userdata)
{
zip_userdata *data = (zip_userdata *) userdata;
u16 *utf16_name = calloc(strlen(name), sizeof(u16));
utf8_to_utf16(utf16_name, (u8 *) name, strlen(name));
data->installed += install_badge_generic(file_buf, file_size, utf16_name, data->badge_count, data->set_id);
free(utf16_name);
return 0;
}
int install_badge_zip(u16 *path, FS_DirectoryEntry zip, int *badge_count, int set_id)
{
Result res;
zip_userdata data = {0};
data.set_id = set_id;
data.badge_count = badge_count;
for_each_file_zip(path, ArchiveSD, zip_callback, &data);
return data.installed;
}
int install_badge_dir(FS_DirectoryEntry set_dir, int *badge_count, int set_id) int install_badge_dir(FS_DirectoryEntry set_dir, int *badge_count, int set_id)
{ {
Result res; Result res;
@@ -199,8 +234,12 @@ int install_badge_dir(FS_DirectoryEntry set_dir, int *badge_count, int set_id)
badges_in_set += install_badge_png(fsMakePath(PATH_UTF16, path), badge_files[i], badge_count, set_id); badges_in_set += install_badge_png(fsMakePath(PATH_UTF16, path), badge_files[i], badge_count, set_id);
} else if (!strcmp(badge_files[i].shortExt, "ZIP")) } else if (!strcmp(badge_files[i].shortExt, "ZIP"))
{ {
badges_in_set += 1; memset(path, 0, 512 * sizeof(u16));
// Zip install struacat(path, "/Badges/");
strucat(path, set_dir.name);
struacat(path, "/");
strucat(path, badge_files[i].name);
badges_in_set += install_badge_zip(path, badge_files[i], badge_count, set_id);
} }
} }
@@ -323,7 +362,11 @@ Result install_badges(void)
set_count += 1; set_count += 1;
default_set = set_count; default_set = set_count;
} }
// Zip install u16 path[0x512] = {0};
struacat(path, "/Badges/");
strucat(path, badge_files[i].name);
default_set_count += install_badge_zip(path, badge_files[i], &badge_count, default_set);
} else if (badge_files[i].attributes & FS_ATTRIBUTE_DIRECTORY) } else if (badge_files[i].attributes & FS_ATTRIBUTE_DIRECTORY)
{ {
set_count += 1; set_count += 1;

View File

@@ -216,6 +216,39 @@ u32 file_to_buf(FS_Path path, FS_Archive archive, char ** buf)
return (u32)size; return (u32)size;
} }
s16 for_each_file_zip(u16 *zip_path, FS_Archive archive, u32 (*zip_iter_callback)(char *filebuf, u64 file_size, char *name, void *userdata), void *userdata)
{
struct archive *a = archive_read_new();
archive_read_support_format_zip(a);
ssize_t len = strulen(zip_path, 0x106);
char * path = calloc(sizeof(char), len * sizeof(u16));
utf16_to_utf8((u8 *)path, zip_path, len * sizeof(u16));
DEBUG("Attempting to open zip %s\n", path);
int r = archive_read_open_filename(a, path, 0x4000);
free(path);
if(r != ARCHIVE_OK)
{
DEBUG("Invalid zip being opened\n");
return -1;
}
struct archive_entry *entry;
u64 file_size = 0;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK)
{
file_size = archive_entry_size(entry);
char *buf = calloc(file_size, sizeof(char));
archive_read_data(a, buf, file_size);
zip_iter_callback(buf, file_size, archive_entry_pathname(entry), userdata);
free(buf);
}
archive_read_free(a);
return 0;
}
static u32 zip_to_buf(struct archive * a, const char * file_name, char ** buf) static u32 zip_to_buf(struct archive * a, const char * file_name, char ** buf)
{ {
struct archive_entry * entry; struct archive_entry * entry;