ISO build (partial)
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "assetdolphindvd.h"
|
||||
#include "asset/asset.h"
|
||||
#include "util/string.h"
|
||||
#include <ogc/dvd.h>
|
||||
#include <ogc/cache.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#define DUSK_DVD_ALIGN 32u
|
||||
#define DUSK_DVD_ALIGN_UP(n) \
|
||||
(((u32)(n) + DUSK_DVD_ALIGN - 1u) & ~(DUSK_DVD_ALIGN - 1u))
|
||||
|
||||
static u32 dvdBe32(const u8 *p) {
|
||||
return ((u32)p[0] << 24) | ((u32)p[1] << 16) | ((u32)p[2] << 8) | (u32)p[3];
|
||||
}
|
||||
|
||||
static void *dvdRead(s64 offset, u32 size) {
|
||||
u32 padded = DUSK_DVD_ALIGN_UP(size);
|
||||
void *buf = memalign(DUSK_DVD_ALIGN, padded);
|
||||
if(!buf) return NULL;
|
||||
DCInvalidateRange(buf, padded);
|
||||
dvdcmdblk block;
|
||||
if(DVD_ReadPrio(&block, buf, padded, offset, 0) <= 0) {
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
errorret_t assetInitDolphin(void) {
|
||||
DVD_Init();
|
||||
DVD_Mount();
|
||||
|
||||
// Read disc header to find FST location
|
||||
u8 *hdr = (u8 *)dvdRead(0, 0x440);
|
||||
if(!hdr) errorThrow("Failed to read DVD disc header.");
|
||||
u32 fstOff = dvdBe32(hdr + 0x424);
|
||||
u32 fstSize = dvdBe32(hdr + 0x428);
|
||||
free(hdr);
|
||||
|
||||
// Read the FST
|
||||
u8 *fst = (u8 *)dvdRead((s64)fstOff, fstSize);
|
||||
if(!fst) errorThrow("Failed to read DVD FST.");
|
||||
|
||||
// Root entry (index 0) bytes 8-11 = total entry count
|
||||
u32 numEntries = dvdBe32(fst + 8);
|
||||
u8 *strTable = fst + numEntries * 12u;
|
||||
|
||||
u32 fileOff = 0, fileLen = 0;
|
||||
for(u32 i = 1; i < numEntries; i++) {
|
||||
u8 *e = fst + i * 12u;
|
||||
if(e[0] != 0) continue;
|
||||
|
||||
u32 nameOff = ((u32)e[1] << 16) | ((u32)e[2] << 8) | (u32)e[3];
|
||||
const char_t *name = (const char_t *)(strTable + nameOff);
|
||||
if(stringCompareInsensitive(name, ASSET_FILE_NAME) == 0) {
|
||||
fileOff = dvdBe32(e + 4);
|
||||
fileLen = dvdBe32(e + 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(fst);
|
||||
|
||||
if(!fileOff) errorThrow("Failed to find asset file on DVD.");
|
||||
|
||||
u8 *data = (u8 *)dvdRead((s64)fileOff, fileLen);
|
||||
if(!data) errorThrow("Failed to read asset file from DVD.");
|
||||
|
||||
zip_error_t zerr;
|
||||
zip_source_t *src = zip_source_buffer_create(data, fileLen, 1, &zerr);
|
||||
if(!src) {
|
||||
free(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.");
|
||||
}
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t assetDisposeDolphin(void) {
|
||||
errorOk();
|
||||
}
|
||||
Reference in New Issue
Block a user