Add aglab2 lz4t

This commit is contained in:
a
2025-06-23 12:17:38 -04:00
parent a527dc78e8
commit 74cf4e1ad4
18 changed files with 7303 additions and 123 deletions

View File

@@ -2,8 +2,6 @@
#include "buffers.h"
ALIGNED8 u8 gDecompressionHeap[0xD000];
#if defined(VERSION_EU)
ALIGNED16 u8 gAudioHeap[DOUBLE_SIZE_ON_64_BIT(0x31200) - 0x3800];
#elif defined(VERSION_SH)

View File

@@ -7,8 +7,6 @@
#include "engine/game_init.h"
#include "config.h"
extern u8 gDecompressionHeap[];
extern u8 gAudioHeap[];
extern u8 gAudioSPTaskYieldBuffer[];

View File

@@ -297,7 +297,7 @@ static void level_cmd_load_mario_head(void) {
}
static void level_cmd_load_mio0_texture(void) {
load_segment_decompress_heap(CMD_GET(s16, 2), CMD_GET(void *, 4), CMD_GET(void *, 8));
load_segment_decompress(CMD_GET(s16, 2), CMD_GET(void *, 4), CMD_GET(void *, 8));
sCurrentCmd = CMD_NEXT;
}

View File

@@ -1,6 +1,7 @@
#ifndef DECOMPRESS_H
#define DECOMPRESS_H
void decompress(void *mio0, void *dest);
void lz4t_unpack_fast(const uint8_t* restrict inbuf, uint8_t* restrict dst, DMAAsyncCtx *ctx);
#define DMA_ASYNC_HEADER_SIZE 16
#endif // DECOMPRESS_H

42
src/game/dma_async.c Normal file
View File

@@ -0,0 +1,42 @@
#include "dma_async.h"
#include "game/main.h"
#define ALIGN16(val) (((val) + 0xF) & ~0xF)
void dma_async_ctx_init(DMAAsyncCtx* ctx, u8 *dest, u8 *srcStart, u8 *srcEnd) {
u32 size = ALIGN16(srcEnd - srcStart);
osInvalDCache(dest, size);
u32 copySize = (size >= 0x1000) ? 0x1000 : size;
osPiStartDma(&gDmaIoMesg, OS_MESG_PRI_NORMAL, OS_READ, (uintptr_t) srcStart, dest, copySize, &gDmaMesgQueue);
dest += copySize;
srcStart += copySize;
size -= copySize;
ctx->srcStart = srcStart;
ctx->dest = dest;
ctx->size = size;
}
void* dma_async_ctx_read(DMAAsyncCtx* ctx) {
// wait for the previous DMA issued
osRecvMesg(&gDmaMesgQueue, &gMainReceivedMesg, OS_MESG_BLOCK);
// start the new DMA transfer
u32 copySize = (ctx->size >= 0x1000) ? 0x1000 : ctx->size;
if (copySize == 0) {
// we are done, return a dummy address that is so gigantic that we will never be called again
return (void*) 0x80800000;
}
osPiStartDma(&gDmaIoMesg, OS_MESG_PRI_NORMAL, OS_READ, (uintptr_t) ctx->srcStart, ctx->dest, copySize, &gDmaMesgQueue);
const u32 margin = 16;
void* ret = ctx->dest - margin;
ctx->dest += copySize;
ctx->srcStart += copySize;
ctx->size -= copySize;
return ret;
}

15
src/game/dma_async.h Normal file
View File

@@ -0,0 +1,15 @@
#pragma once
#include "types.h"
typedef struct {
u8* srcStart;
u8* dest;
u32 size;
} DMAAsyncCtx;
// Starts to DMA the first block
void dma_async_ctx_init(DMAAsyncCtx* ctx, u8 *dest, u8 *srcStart, u8 *srcEnd);
// Starts to DMA the next block and waits for the previous block
void* dma_async_ctx_read(DMAAsyncCtx* ctx);

View File

@@ -183,6 +183,35 @@ int __ucmpdi2(unsigned long long a, unsigned long long b) {
return (a < b) ? 0 : 2;
}
// Taken from LLVM
typedef union {
u64 all;
struct {
u32 high;
u32 low;
} s;
} UdWords;
s64 __lshrdi3(s64 a, s32 b) {
const s32 bits_in_word = (s32)(sizeof(s32) * 8);
UdWords input;
UdWords result;
input.all = a;
if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */ {
result.s.high = 0;
result.s.low = input.s.high >> (b - bits_in_word);
} else /* 0 <= b < bits_in_word */ {
if (b == 0) {
return a;
}
result.s.high = input.s.high >> b;
result.s.low = (input.s.high << (bits_in_word - b)) | (input.s.low >> b);
}
return result.all;
}
// Compute division and modulo of 64-bit signed and unsigned integers
__asm__(" \n\

View File

@@ -6,6 +6,7 @@
#include "buffers/zbuffer.h"
#include "buffers/buffers.h"
#include "dma_async.h"
#include "decompress.h"
#include "engine/game_init.h"
#include "main.h"
@@ -342,7 +343,10 @@ void *load_segment_decompress(s32 segment, u8 *srcStart, u8 *srcEnd) {
dest = main_pool_alloc(*size, MEMORY_POOL_LEFT);
if (dest != NULL) {
CN_DEBUG_PRINTF(("start decompress\n"));
decompress(compressed, dest);
dma_read(compressed, srcStart, srcStart + DMA_ASYNC_HEADER_SIZE);
DMAAsyncCtx asyncCtx;
dma_async_ctx_init(&asyncCtx, compressed + DMA_ASYNC_HEADER_SIZE, srcStart + DMA_ASYNC_HEADER_SIZE, srcEnd);
lz4t_unpack_fast(compressed, dest, &asyncCtx);
CN_DEBUG_PRINTF(("end decompress\n"));
set_segment_base_addr(segment, dest);
@@ -354,22 +358,6 @@ void *load_segment_decompress(s32 segment, u8 *srcStart, u8 *srcEnd) {
return dest;
}
void *load_segment_decompress_heap(u32 segment, u8 *srcStart, u8 *srcEnd) {
UNUSED void *dest = NULL;
u32 compSize = ALIGN16(srcEnd - srcStart);
u8 *compressed = main_pool_alloc(compSize, MEMORY_POOL_RIGHT);
UNUSED u32 *pUncSize = (u32 *) (compressed + 4);
if (compressed != NULL) {
dma_read(compressed, srcStart, srcEnd);
decompress(compressed, gDecompressionHeap);
set_segment_base_addr(segment, gDecompressionHeap);
main_pool_free(compressed);
} else {
}
return gDecompressionHeap;
}
#ifndef LIBDRAGON_IPL3
void load_engine_code_segment(void) {
void *startAddr = (void *) _engineSegmentStart;