This commit is contained in:
@@ -21,6 +21,15 @@ void * memoryAllocate(const size_t size) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void * memoryAlign(size_t alignment, size_t size) {
|
||||
assertTrue(alignment > 0, "Alignment must be greater than 0.");
|
||||
assertTrue(size > 0, "Cannot allocate 0 bytes of memory.");
|
||||
void *ptr = memalign(alignment, size);
|
||||
assertNotNull(ptr, "Aligned memory allocation failed.");
|
||||
MEMORY_POINTERS_IN_USE++;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void memoryFree(void *ptr) {
|
||||
assertNotNull(ptr, "Cannot free NULL memory.");
|
||||
free(ptr);
|
||||
|
||||
@@ -25,6 +25,15 @@ size_t memoryGetAllocatedCount(void);
|
||||
*/
|
||||
void * memoryAllocate(const size_t size);
|
||||
|
||||
/**
|
||||
* Allocates aligned memory.
|
||||
*
|
||||
* @param alignment The alignment of the memory to allocate.
|
||||
* @param size The size of the memory to allocate.
|
||||
* @return The allocated memory.
|
||||
*/
|
||||
void * memoryAlign(size_t alignment, size_t size);
|
||||
|
||||
/**
|
||||
* Frees memory.
|
||||
*
|
||||
|
||||
@@ -8,48 +8,26 @@
|
||||
#include "assetdolphindvd.h"
|
||||
#include "asset/asset.h"
|
||||
#include "util/string.h"
|
||||
#include <ogc/dvd.h>
|
||||
#include <ogc/cache.h>
|
||||
#include <malloc.h>
|
||||
#include "util/memory.h"
|
||||
#include "util/endian.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) {
|
||||
errorret_t assetInitDolphinDVD(void) {
|
||||
DVD_Init();
|
||||
DVD_Mount();
|
||||
|
||||
// Read disc header to find FST location
|
||||
u8 *hdr = (u8 *)dvdRead(0, 0x440);
|
||||
u8 *hdr = (u8 *)assetDolphinDVDRead(0, 0x440);
|
||||
if(!hdr) errorThrow("Failed to read DVD disc header.");
|
||||
u32 fstOff = dvdBe32(hdr + 0x424);
|
||||
u32 fstSize = dvdBe32(hdr + 0x428);
|
||||
u32 fstOff = assetDolphinDVDReadBigEndian32(hdr + 0x424);
|
||||
u32 fstSize = assetDolphinDVDReadBigEndian32(hdr + 0x428);
|
||||
free(hdr);
|
||||
|
||||
// Read the FST
|
||||
u8 *fst = (u8 *)dvdRead((s64)fstOff, fstSize);
|
||||
u8 *fst = (u8 *)assetDolphinDVDRead((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);
|
||||
u32 numEntries = assetDolphinDVDReadBigEndian32(fst + 8);
|
||||
u8 *strTable = fst + numEntries * 12u;
|
||||
|
||||
u32 fileOff = 0, fileLen = 0;
|
||||
@@ -60,22 +38,22 @@ errorret_t assetInitDolphin(void) {
|
||||
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);
|
||||
fileOff = assetDolphinDVDReadBigEndian32(e + 4);
|
||||
fileLen = assetDolphinDVDReadBigEndian32(e + 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(fst);
|
||||
memoryFree(fst);
|
||||
|
||||
if(!fileOff) errorThrow("Failed to find asset file on DVD.");
|
||||
|
||||
u8 *data = (u8 *)dvdRead((s64)fileOff, fileLen);
|
||||
u8 *data = (u8 *)assetDolphinDVDRead((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);
|
||||
memoryFree(data);
|
||||
errorThrow("Failed to create zip source from DVD buffer.");
|
||||
}
|
||||
|
||||
@@ -88,6 +66,23 @@ errorret_t assetInitDolphin(void) {
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t assetDisposeDolphin(void) {
|
||||
void *assetDolphinDVDRead(const s64 offset, const u32 size) {
|
||||
u32 padded = ASSET_DOLPHIN_DVD_ALIGN_UP(size);
|
||||
void *buf = memoryAlign(ASSET_DOLPHIN_DVD_ALIGN, padded);
|
||||
if(!buf) return NULL;
|
||||
DCInvalidateRange(buf, padded);
|
||||
dvdcmdblk block;
|
||||
if(DVD_ReadPrio(&block, buf, padded, offset, 0) <= 0) {
|
||||
memoryFree(buf);
|
||||
return NULL;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
u32 assetDolphinDVDReadBigEndian32(const u8 *p) {
|
||||
return ((u32)p[0] << 24) | ((u32)p[1] << 16) | ((u32)p[2] << 8) | (u32)p[3];
|
||||
}
|
||||
|
||||
errorret_t assetDisposeDolphinDVD(void) {
|
||||
errorOk();
|
||||
}
|
||||
|
||||
@@ -7,10 +7,61 @@
|
||||
|
||||
#pragma once
|
||||
#include "error/error.h"
|
||||
#include <ogc/dvd.h>
|
||||
#include <ogc/cache.h>
|
||||
|
||||
/** Alignment for Dolphin DVD asset reads. */
|
||||
#define ASSET_DOLPHIN_DVD_ALIGN 32u
|
||||
|
||||
/**
|
||||
* Gets the next multiple of ASSET_DOLPHIN_DVD_ALIGN greater than or equal to n.
|
||||
* This is used to ensure that DVD reads are properly aligned and padded.
|
||||
*
|
||||
* @param n The number to align.
|
||||
* @return The aligned number.
|
||||
*/
|
||||
#define ASSET_DOLPHIN_DVD_ALIGN_UP(n) \
|
||||
(((u32)(n) + ASSET_DOLPHIN_DVD_ALIGN - 1u) & ~(ASSET_DOLPHIN_DVD_ALIGN - 1u))
|
||||
|
||||
typedef struct {
|
||||
uint8_t nothing;
|
||||
} assetdolphin_t;
|
||||
} assetdolphindvd_t;
|
||||
|
||||
errorret_t assetInitDolphin(void);
|
||||
errorret_t assetDisposeDolphin(void);
|
||||
/**
|
||||
* Initializes the Dolphin DVD asset system.
|
||||
*
|
||||
* This will;
|
||||
* - Initialize the DVD subsystem and mount the disc.
|
||||
* - Read the disc header to find the FST location.
|
||||
* - Read the FST and find the offset and length of the "data" file.
|
||||
* - Store the offset and length for later use when loading assets.
|
||||
*
|
||||
* @return An errorret_t indicating success or failure.
|
||||
*/
|
||||
errorret_t assetInitDolphinDVD(void);
|
||||
|
||||
/**
|
||||
* Reads a block of data from the DVD at the specified offset and size.
|
||||
* The returned buffer is aligned to 32 bytes and padded. The caller is
|
||||
* responsible for freeing the buffer.
|
||||
*
|
||||
* @param offset The offset on the DVD to read from.
|
||||
* @param size The number of bytes to read.
|
||||
* @return A pointer to the buffer, or NULL on failure.
|
||||
*/
|
||||
void * assetDolphinDVDRead(const s64 offset, const u32 size);
|
||||
|
||||
/**
|
||||
* Reads a big-endian 32-bit integer from the given data.
|
||||
*
|
||||
* @param data The data to read from.
|
||||
* @return The big-endian 32-bit integer as a host-endian uint32_t.
|
||||
*/
|
||||
u32 assetDolphinDVDReadBigEndian32(const u8 *data);
|
||||
|
||||
/**
|
||||
* Disposes of the Dolphin DVD asset system.
|
||||
*
|
||||
* @return An errorret_t indicating success or failure.
|
||||
*/
|
||||
errorret_t assetDisposeDolphinDVD(void);
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
errorret_t assetInitDolphin(void) {
|
||||
errorret_t assetInitDolphinFAT(void) {
|
||||
if(!fatInitDefault()) errorThrow("Failed to initialize FAT filesystem.");
|
||||
|
||||
char_t **dolphinSearchPath = (char_t **)ASSET_DOLPHIN_PATHS;
|
||||
@@ -55,6 +55,6 @@ errorret_t assetInitDolphin(void) {
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t assetDisposeDolphin(void) {
|
||||
errorret_t assetDisposeDolphinFAT(void) {
|
||||
errorOk();
|
||||
}
|
||||
|
||||
@@ -31,7 +31,24 @@ static const char_t *ASSET_DOLPHIN_PATHS[] = {
|
||||
|
||||
typedef struct {
|
||||
uint8_t nothing;
|
||||
} assetdolphin_t;
|
||||
} assetdolphinfat_t;
|
||||
|
||||
errorret_t assetInitDolphin(void);
|
||||
errorret_t assetDisposeDolphin(void);
|
||||
/**
|
||||
* Initializes the Dolphin FAT asset system.
|
||||
*
|
||||
* FAT being the general term for the FAT filesystem, on Wii this would likely
|
||||
* be the SD Card, on Gamecube it can be something like the SD Gecko or the
|
||||
* Slot2 SD Card.
|
||||
*
|
||||
* As far as I know this doesn't (currently) work on the CUBEODE?
|
||||
*
|
||||
* @return An errorret_t indicating success or failure.
|
||||
*/
|
||||
errorret_t assetInitDolphinFAT(void);
|
||||
|
||||
/**
|
||||
* Disposes of the Dolphin FAT asset system.
|
||||
*
|
||||
* @return An errorret_t indicating success or failure.
|
||||
*/
|
||||
errorret_t assetDisposeDolphinFAT(void);
|
||||
@@ -9,11 +9,13 @@
|
||||
|
||||
#ifdef DUSK_DOLPHIN_BUILD_ISO
|
||||
#include "assetdolphindvd.h"
|
||||
#define assetInitPlatform assetInitDolphinDVD
|
||||
#define assetDisposePlatform assetDisposeDolphinDVD
|
||||
typedef assetdolphindvd_t assetplatform_t;
|
||||
#else
|
||||
#include "assetdolphinfat.h"
|
||||
#define assetInitPlatform assetInitDolphinFAT
|
||||
#define assetDisposePlatform assetDisposeDolphinFAT
|
||||
typedef assetdolphinfat_t assetplatform_t;
|
||||
#endif
|
||||
|
||||
#define assetInitPlatform assetInitDolphin
|
||||
#define assetDisposePlatform assetDisposeDolphin
|
||||
|
||||
typedef assetdolphin_t assetplatform_t;
|
||||
|
||||
Reference in New Issue
Block a user