Redesign dusk.dsk into a dual-archive DSK2 format

Splits the asset archive into a compressed (DEFLATE) zip and an
uncompressed (STORED) zip back to back behind a small header, instead of
one plain zip. DEFLATE-compressed zip entries aren't reliably seekable in
libzip, which caused locale string lookups (repeated rewind/reopen of the
same entry) to silently skip content on Dolphin specifically. Uncompressed
entries don't have that problem, so locale files now go in the stored
archive without needing to buffer the whole thing in memory.

Adds tools/asset/pack as the new packer (replacing the plain
`tar --format=zip`), a shared assetdsk.h/.c opener used by all platforms,
and a second ASSET.zipStored handle with fallback lookup in assetfile.c.

Confirmed working: Linux, PSP (PPSSPP), and Dolphin-FAT (Wii DOL under
-a LLE) - the original Dolphin locale lookup failure no longer reproduces.
This commit is contained in:
2026-08-31 15:33:45 -05:00
parent 9512c22e1f
commit e47a2c3e5c
17 changed files with 585 additions and 53 deletions
+11 -10
View File
@@ -7,6 +7,7 @@
#include "assetdolphindvd.h"
#include "asset/asset.h"
#include "asset/assetdsk.h"
#include "util/string.h"
#include "util/memory.h"
@@ -90,19 +91,15 @@ errorret_t assetInitDolphinDVD(void) {
);
if(!data) errorThrow("Failed to read asset file from ISO.");
zip_error_t zerr;
zip_source_t *src = zip_source_buffer_create(data, fileSize, 1, &zerr);
if(!src) {
errorret_t ret = assetDskOpenFromBuffer(
data, fileSize, &ASSET.zip, &ASSET.zipStored
);
if(errorIsNotOk(ret)) {
memoryFree(data);
errorThrow("Failed to create zip source from DVD buffer.");
}
ASSET.zip = zip_open_from_source(src, ZIP_RDONLY, &zerr);
if(!ASSET.zip) {
zip_source_free(src);
errorThrow("Failed to open asset zip from DVD.");
errorChain(ret);
}
ASSET.platform.dskData = data;
errorOk();
}
@@ -124,5 +121,9 @@ u32 assetDolphinDVDReadBigEndian32(const u8 *p) {
}
errorret_t assetDisposeDolphinDVD(void) {
if(ASSET.platform.dskData != NULL) {
memoryFree(ASSET.platform.dskData);
ASSET.platform.dskData = NULL;
}
errorOk();
}
+4 -1
View File
@@ -24,7 +24,10 @@
(((u32)(n) + ASSET_DOLPHIN_DVD_ALIGN - 1u) & ~(ASSET_DOLPHIN_DVD_ALIGN - 1u))
typedef struct {
uint8_t nothing;
// Whole dusk.dsk blob read from the ISO, kept alive for as long as
// ASSET.zip/ASSET.zipStored are open since they're non-owning windows
// into it (see assetDskOpenFromBuffer). Freed in assetDisposeDolphinDVD.
uint8_t *dskData;
} assetdolphindvd_t;
/**
+2 -4
View File
@@ -7,6 +7,7 @@
#include "assetdolphinfat.h"
#include "asset/asset.h"
#include "asset/assetdsk.h"
#include "util/string.h"
#include <fat.h>
#include <stdio.h>
@@ -50,10 +51,7 @@ errorret_t assetInitDolphinFAT(void) {
if(foundPath[0] == '\0')
errorThrow("Failed to find asset file on FAT filesystem.");
ASSET.zip = zip_open(foundPath, ZIP_RDONLY, NULL);
if(ASSET.zip == NULL)
errorThrow("Failed to open asset file on FAT filesystem.");
errorChain(assetDskOpenFromPath(foundPath, &ASSET.zip, &ASSET.zipStored));
errorOk();
}