* Broke the "prepare" methods up into smaller methods * Removed the usage of linked lists and replaced them with arrays. Given that themes won't be added/removed throughout the execution of the program, we don't need to be able to dynamically add or remove elements to the list. In addition, once you got to ~50 themes, it took about .2 seconds to iterate through the entire list, which, while it may not sound like much, is a huge time sink when you're going through a list. Being able to randomly access any element in the list at the same speed is hugely beneficial. The downside to this is we need to keep track of the number of themes/splashes at all times, and, for splashes, have to do some weird type magic in order to properly iterate over it. However, these negatives are outweighed by the speed improvements.
147 lines
5.5 KiB
C
147 lines
5.5 KiB
C
#include <3ds.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "theme.h"
|
|
#include "unicode.h"
|
|
#include "splashes.h"
|
|
|
|
Result unzip_splashes()
|
|
{
|
|
Handle splashes_dir;
|
|
FSUSER_OpenDirectory(&splashes_dir, ArchiveSD, fsMakePath(PATH_ASCII, "/Splashes"));; // Open up splashes directory
|
|
while (true) // Honestly this repeated code triggers me but I'm too lazy to refactor (now at least)
|
|
{
|
|
FS_DirectoryEntry *entry = malloc(sizeof(FS_DirectoryEntry));
|
|
u32 entries_read;
|
|
FSDIR_Read(splashes_dir, &entries_read, 1, entry);
|
|
if (entries_read) // If there is a new entry
|
|
{
|
|
if (!strcmp(entry->shortExt, "ZIP")) // if that entry is a zip
|
|
{
|
|
u16 sanitized_zip[sizeof(entry->name)] = {0};
|
|
bool changed = strip_unicode(sanitized_zip, entry->name, sizeof(entry->name)); // Here we strip out the non-ASCII characters in the zip name, as minizip doesn't like them
|
|
if (changed) // If there were any non-ascii characters
|
|
{
|
|
u16 zip_path[550] = {0};
|
|
ssize_t len = atow(zip_path, "/Splashes/"); // Copy the unicode equivalent of "/Splashes/" into zip_path
|
|
memcpy(&zip_path[len], entry->name, sizeof(entry->name)); // Copy the name of the zip (with unicode chars) into zip_path
|
|
u16 sanitized_zip_path[550] = {0}; // Same thing as above, this time with sanitized names
|
|
atow(sanitized_zip_path, "/Splashes/");
|
|
memcpy(&sanitized_zip_path[len], sanitized_zip, sizeof(entry->name));
|
|
FSUSER_RenameFile(ArchiveSD, fsMakePath(PATH_UTF16, zip_path), ArchiveSD, fsMakePath(PATH_UTF16, sanitized_zip_path)); // Rename the zip to the sanitized one
|
|
unzip_file("/Splashes/", entry, sanitized_zip); // And unzip it
|
|
} else unzip_file("/Splashes/", entry, entry->name); // If it's the same, unzip it anyway
|
|
}
|
|
free(entry);
|
|
} else {
|
|
free(entry);
|
|
break;
|
|
}
|
|
}
|
|
FSDIR_Close(splashes_dir);
|
|
}
|
|
|
|
Result prepare_splashes(u16* splash_list)
|
|
{
|
|
Handle splashes_dir;
|
|
FSUSER_OpenDirectory(&splashes_dir, ArchiveSD, fsMakePath(PATH_ASCII, "/Splashes"));
|
|
int iter = 0;
|
|
while (true)
|
|
{
|
|
FS_DirectoryEntry *entry = malloc(sizeof(FS_DirectoryEntry));
|
|
u32 entries_read;
|
|
FSDIR_Read(splashes_dir, &entries_read, 1, entry);
|
|
if (entries_read)
|
|
{
|
|
if (entry->attributes == 1)
|
|
{
|
|
atow(&splash_list[iter * PATH_LENGTH/sizeof(u16)], "/Splashes/");
|
|
strucat(&splash_list[iter * PATH_LENGTH/sizeof(u16)], entry->name);
|
|
iter++;
|
|
}
|
|
free(entry);
|
|
} else {
|
|
free(entry);
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
Result install_splash(u16 *path)
|
|
{
|
|
printu(path);
|
|
int splashes_installed = 0;
|
|
u16 file_path[0x106] = {0};
|
|
strucpy(file_path, path);
|
|
struacat(file_path, "/splash.bin");
|
|
|
|
Handle file_handle;
|
|
Result res = FSUSER_OpenFile(&file_handle, ArchiveSD, fsMakePath(PATH_UTF16, file_path), FS_OPEN_READ, 0);
|
|
if (R_FAILED(res) && R_SUMMARY(res) != RS_NOTFOUND) return res;
|
|
else if (R_SUCCEEDED(res))
|
|
{
|
|
u64 file_size;
|
|
u32 bytes;
|
|
FSFILE_GetSize(file_handle, &file_size);
|
|
char *splash_data = malloc(file_size);
|
|
memset(splash_data, 0, file_size);
|
|
FSFILE_Read(file_handle, &bytes, 0, splash_data, file_size);
|
|
FSFILE_Close(file_handle);
|
|
FSUSER_DeleteFile(ArchiveSD, fsMakePath(PATH_ASCII, "/Luma/splash.bin"));
|
|
FSUSER_CreateFile(ArchiveSD, fsMakePath(PATH_ASCII, "/Luma/splash.bin"), 0, file_size);
|
|
FSUSER_OpenFile(&file_handle, ArchiveSD, fsMakePath(PATH_ASCII, "/Luma/splash.bin"), FS_OPEN_WRITE, 0);
|
|
Result res = FSFILE_Write(file_handle, &bytes, 0, splash_data, file_size, FS_WRITE_FLUSH);
|
|
if (R_FAILED(res)) printf("Write: %lX\n", res);
|
|
free(splash_data);
|
|
FSFILE_Close(file_handle);
|
|
splashes_installed++;
|
|
}
|
|
|
|
memset(file_path, 0, 0x106);
|
|
strucpy(file_path, path);
|
|
struacat(file_path, "/splashbottom.bin");
|
|
|
|
res = FSUSER_OpenFile(&file_handle, ArchiveSD, fsMakePath(PATH_UTF16, file_path), FS_OPEN_READ, 0);
|
|
if (R_FAILED(res) && R_SUMMARY(res) != RS_NOTFOUND) return res;
|
|
else if (R_SUCCEEDED(res))
|
|
{
|
|
u64 file_size;
|
|
u32 bytes;
|
|
FSFILE_GetSize(file_handle, &file_size);
|
|
char *splash_data = malloc(file_size);
|
|
memset(splash_data, 0, file_size);
|
|
FSFILE_Read(file_handle, &bytes, 0, splash_data, file_size);
|
|
FSFILE_Close(file_handle);
|
|
FSUSER_DeleteFile(ArchiveSD, fsMakePath(PATH_ASCII, "/Luma/splashbottom.bin"));
|
|
FSUSER_CreateFile(ArchiveSD, fsMakePath(PATH_ASCII, "/Luma/splashbottom.bin"), 0, file_size);
|
|
FSUSER_OpenFile(&file_handle, ArchiveSD, fsMakePath(PATH_ASCII, "/Luma/splashbottom.bin"), FS_OPEN_WRITE, 0);
|
|
FSFILE_Write(file_handle, &bytes, 0, splash_data, file_size, FS_WRITE_FLUSH);
|
|
FSFILE_Close(file_handle);
|
|
free(splash_data);
|
|
splashes_installed += 2;
|
|
}
|
|
|
|
switch(splashes_installed)
|
|
{
|
|
case 0:
|
|
printf("No splashes installed\n");
|
|
break;
|
|
|
|
case 1:
|
|
printf("Top splash installed\n");
|
|
break;
|
|
|
|
case 2:
|
|
printf("Bottom splash installed\n");
|
|
break;
|
|
|
|
case 3:
|
|
printf("Both splashes installed\n");
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
} |