This commit is contained in:
asrael 2025-09-28 13:10:29 -05:00
parent 9f96626ea7
commit 6a02b24ae6
29 changed files with 653 additions and 583 deletions

View file

@ -8,17 +8,38 @@
#include <unistd.h>
#include "../lib/miniz/miniz.h"
static pxl8_cart* s_current_cart = NULL;
static char* s_original_cwd = NULL;
static pxl8_cart* __pxl8_current_cart = NULL;
static char* __pxl8_original_cwd = NULL;
static bool is_directory(const char* path) {
struct stat st;
return stat(path, &st) == 0 && S_ISDIR(st.st_mode);
}
static void pxl8_add_file_recursive(mz_zip_archive* zip, const char* dir_path, const char* prefix) {
DIR* dir = opendir(dir_path);
if (!dir) return;
static bool is_pxc_file(const char* path) {
size_t len = strlen(path);
return len > 4 && strcmp(path + len - 4, ".pxc") == 0;
struct dirent* entry;
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
char full_path[1024];
char zip_path[1024];
snprintf(full_path, sizeof(full_path), "%s/%s", dir_path, entry->d_name);
snprintf(zip_path, sizeof(zip_path), "%s%s", prefix, entry->d_name);
struct stat st;
if (stat(full_path, &st) == 0) {
if (S_ISDIR(st.st_mode)) {
char new_prefix[1025];
snprintf(new_prefix, sizeof(new_prefix), "%s/", zip_path);
pxl8_add_file_recursive(zip, full_path, new_prefix);
} else {
pxl8_info("Adding: %s", zip_path);
if (!mz_zip_writer_add_file(zip, zip_path, full_path, NULL, 0, MZ_BEST_COMPRESSION)) {
pxl8_warn("Failed to add file: %s", zip_path);
}
}
}
}
closedir(dir);
}
static char* get_cart_name(const char* path) {
@ -39,19 +60,18 @@ static char* get_cart_name(const char* path) {
return name;
}
pxl8_cart* pxl8_cart_new(void) {
pxl8_cart* cart = calloc(1, sizeof(pxl8_cart));
if (!cart) {
pxl8_error("Failed to allocate cart");
return NULL;
}
return cart;
static bool is_directory(const char* path) {
struct stat st;
return stat(path, &st) == 0 && S_ISDIR(st.st_mode);
}
void pxl8_cart_destroy(pxl8_cart* cart) {
if (!cart) return;
pxl8_cart_unload(cart);
free(cart);
static bool is_pxc_file(const char* path) {
size_t len = strlen(path);
return len > 4 && strcmp(path + len - 4, ".pxc") == 0;
}
pxl8_cart* pxl8_cart_current(void) {
return __pxl8_current_cart;
}
pxl8_result pxl8_cart_load(pxl8_cart* cart, const char* path) {
@ -128,7 +148,7 @@ pxl8_result pxl8_cart_load(pxl8_cart* cart, const char* path) {
mz_zip_archive_file_stat file_stat;
if (!mz_zip_reader_file_stat(&zip, i, &file_stat)) continue;
char extract_path[512];
char extract_path[1024];
snprintf(extract_path, sizeof(extract_path), "%s/%s", temp_dir, file_stat.m_filename);
if (file_stat.m_is_directory) {
@ -171,6 +191,8 @@ void pxl8_cart_unload(pxl8_cart* cart) {
system(cmd);
}
char* cart_name = cart->name ? strdup(cart->name) : NULL;
if (cart->base_path) {
free(cart->base_path);
cart->base_path = NULL;
@ -189,26 +211,31 @@ void pxl8_cart_unload(pxl8_cart* cart) {
cart->archive_size = 0;
cart->is_folder = false;
cart->is_mounted = false;
if (cart_name) {
pxl8_info("Unloaded cart: %s", cart_name);
free(cart_name);
}
}
pxl8_result pxl8_cart_mount(pxl8_cart* cart) {
if (!cart || !cart->base_path) return PXL8_ERROR_NULL_POINTER;
if (cart->is_mounted) return PXL8_OK;
if (s_current_cart) {
pxl8_cart_unmount(s_current_cart);
if (__pxl8_current_cart) {
pxl8_cart_unmount(__pxl8_current_cart);
}
s_original_cwd = getcwd(NULL, 0);
__pxl8_original_cwd = getcwd(NULL, 0);
if (chdir(cart->base_path) != 0) {
pxl8_error("Failed to change to cart directory: %s", cart->base_path);
free(s_original_cwd);
s_original_cwd = NULL;
free(__pxl8_original_cwd);
__pxl8_original_cwd = NULL;
return PXL8_ERROR_FILE_NOT_FOUND;
}
cart->is_mounted = true;
s_current_cart = cart;
__pxl8_current_cart = cart;
pxl8_info("Mounted cart: %s", cart->name);
return PXL8_OK;
@ -217,15 +244,15 @@ pxl8_result pxl8_cart_mount(pxl8_cart* cart) {
void pxl8_cart_unmount(pxl8_cart* cart) {
if (!cart || !cart->is_mounted) return;
if (s_original_cwd) {
chdir(s_original_cwd);
free(s_original_cwd);
s_original_cwd = NULL;
if (__pxl8_original_cwd) {
chdir(__pxl8_original_cwd);
free(__pxl8_original_cwd);
__pxl8_original_cwd = NULL;
}
cart->is_mounted = false;
if (s_current_cart == cart) {
s_current_cart = NULL;
if (__pxl8_current_cart == cart) {
__pxl8_current_cart = NULL;
}
pxl8_info("Unmounted cart: %s", cart->name);
@ -252,37 +279,6 @@ bool pxl8_cart_file_exists(const pxl8_cart* cart, const char* path) {
return exists;
}
static void pxl8_add_files_recursive(mz_zip_archive* zip, const char* dir_path, const char* prefix) {
DIR* dir = opendir(dir_path);
if (!dir) return;
struct dirent* entry;
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
char full_path[512];
char zip_path[512];
snprintf(full_path, sizeof(full_path), "%s/%s", dir_path, entry->d_name);
snprintf(zip_path, sizeof(zip_path), "%s%s", prefix, entry->d_name);
struct stat st;
if (stat(full_path, &st) == 0) {
if (S_ISDIR(st.st_mode)) {
char new_prefix[512];
snprintf(new_prefix, sizeof(new_prefix), "%s/", zip_path);
pxl8_add_files_recursive(zip, full_path, new_prefix);
} else {
pxl8_info("Adding: %s", zip_path);
if (!mz_zip_writer_add_file(zip, zip_path, full_path, NULL, 0, MZ_BEST_COMPRESSION)) {
pxl8_warn("Failed to add file: %s", zip_path);
}
}
}
}
closedir(dir);
}
pxl8_result pxl8_cart_pack(const char* folder_path, const char* output_path) {
if (!folder_path || !output_path) return PXL8_ERROR_NULL_POINTER;
@ -308,7 +304,7 @@ pxl8_result pxl8_cart_pack(const char* folder_path, const char* output_path) {
}
pxl8_info("Packing cart: %s -> %s", folder_path, output_path);
pxl8_add_files_recursive(&zip, folder_path, "");
pxl8_add_file_recursive(&zip, folder_path, "");
if (!mz_zip_writer_finalize_archive(&zip)) {
pxl8_error("Failed to finalize archive");
@ -320,7 +316,3 @@ pxl8_result pxl8_cart_pack(const char* folder_path, const char* output_path) {
pxl8_info("Cart packed successfully!");
return PXL8_OK;
}
pxl8_cart* pxl8_cart_current(void) {
return s_current_cart;
}