mm/src/code/sys_cmpdma.c

122 lines
3.4 KiB
C

#include "global.h"
#include "libc64/malloc.h"
#include "yaz0.h"
#include "yaz0.h"
#include "z64dma.h"
typedef struct {
/* 0x0 */ union {
u32 dmaWord[2];
u32 dataStart;
u32 dataSize;
struct {
u32 start;
u32 end;
} offset;
};
} CmpDmaBuffer; // size = 0x8
CmpDmaBuffer sDmaBuffer;
void func_80178AC0(u16* src, void* dst, size_t size) {
Color_RGBA8_u32 spC;
Color_RGBA16_2 tc;
Color_RGBA14 tc2;
u32* dstCur = dst;
u16* src16 = src;
while (((uintptr_t)dstCur) - size < ((uintptr_t)dst)) {
tc.rgba = *(src16++);
if (tc.a == 1) {
spC.r = (tc.r * 255) / 31;
spC.g = (tc.g * 255) / 31;
spC.b = (tc.b * 255) / 31;
spC.a = 255;
} else if (tc.rgba == 0) {
spC.rgba = 0;
} else {
tc2.rgba = tc.rgba;
tc.rgba = *(src16++);
spC.r = (tc.r << 3) | tc2.r;
spC.g = (tc.g << 3) | tc2.g;
spC.b = (tc.b << 3) | tc2.b;
spC.a = ((tc.rgba & 1) << 7) | ((tc2.a * 127) / 63);
}
*(dstCur++) = spC.rgba;
}
}
void CmpDma_GetFileInfo(uintptr_t segmentRom, s32 id, uintptr_t* outFileRom, size_t* size, s32* flag) {
uintptr_t dataStart;
uintptr_t refOff;
DmaMgr_DmaRomToRam(segmentRom, &sDmaBuffer.dataStart, sizeof(sDmaBuffer.dataStart));
dataStart = sDmaBuffer.dataStart;
refOff = id * sizeof(u32);
// if id is >= idMax
if (refOff > (dataStart - sizeof(u32))) {
*outFileRom = segmentRom;
*size = 0;
} else if (refOff == 0) {
// get offset start of next file, i.e. size of first file
DmaMgr_DmaRomToRam(segmentRom + sizeof(u32), &sDmaBuffer.dataSize, sizeof(sDmaBuffer.dataSize));
*outFileRom = segmentRom + dataStart;
*size = sDmaBuffer.dataSize;
} else {
// get offset start, end from dataStart
DmaMgr_DmaRomToRam(refOff + segmentRom, &sDmaBuffer.offset, sizeof(sDmaBuffer.offset));
*outFileRom = sDmaBuffer.offset.start + segmentRom + dataStart;
*size = sDmaBuffer.offset.end - sDmaBuffer.offset.start;
}
*flag = 0;
}
void CmpDma_Decompress(uintptr_t romStart, size_t size, void* dst) {
if (size != 0) {
Yaz0_Decompress(romStart, dst, size);
}
}
void CmpDma_LoadFileImpl(uintptr_t segmentRom, s32 id, void* dst, size_t size) {
uintptr_t romStart;
size_t compressedSize;
s32 flag;
CmpDma_GetFileInfo(segmentRom, id, &romStart, &compressedSize, &flag);
if (flag & 1) {
void* tempBuf = malloc(0x1000);
CmpDma_Decompress(romStart, compressedSize, tempBuf);
func_80178AC0(tempBuf, dst, size);
free(tempBuf);
} else {
CmpDma_Decompress(romStart, compressedSize, dst);
}
}
void CmpDma_LoadFile(uintptr_t segmentVrom, s32 id, void* dst, size_t size) {
CmpDma_LoadFileImpl(DmaMgr_TranslateVromToRom(segmentVrom), id, dst, size);
}
void CmpDma_LoadAllFiles(uintptr_t segmentVrom, void* dst, size_t size) {
uintptr_t rom = DmaMgr_TranslateVromToRom(segmentVrom);
u32 i;
u32 end;
void* nextDst;
u32 dataStart;
DmaMgr_DmaRomToRam(rom, &sDmaBuffer.dataStart, sizeof(sDmaBuffer.dataStart));
dataStart = sDmaBuffer.dataStart;
nextDst = dst;
end = (dataStart / sizeof(u32)) - 1;
for (i = 0; i < end; i++) {
CmpDma_LoadFileImpl(rom, i, nextDst, 0);
nextDst = gYaz0DecompressDstEnd;
}
}