mirror of https://github.com/zeldaret/tmc.git
205 lines
5.0 KiB
C
205 lines
5.0 KiB
C
#include "global.h"
|
|
#include "utils.h"
|
|
#include "structures.h"
|
|
#include "screen.h"
|
|
|
|
static void StoreKeyInput(Input* input, u32 keyInput);
|
|
|
|
typedef struct {
|
|
u16 paletteId;
|
|
u8 destPaletteNum;
|
|
u8 numPalettes;
|
|
} PaletteGroup;
|
|
|
|
typedef struct {
|
|
union {
|
|
int raw;
|
|
struct {
|
|
u8 filler0[0x3];
|
|
u8 unk3;
|
|
} bytes;
|
|
} unk0;
|
|
u32 dest;
|
|
u32 unk8;
|
|
} GfxItem;
|
|
|
|
extern const PaletteGroup* gPaletteGroups[];
|
|
extern const u8 gGlobalGfxAndPalettes[];
|
|
extern u32 gUsedPalettes;
|
|
extern u16 gPaletteBuffer[];
|
|
extern const GfxItem* gUnk_08100AA8[];
|
|
|
|
void MemFill16(u32 value, void* dest, u32 size) {
|
|
DmaFill16(3, value, dest, size);
|
|
}
|
|
|
|
void MemFill32(u32 value, void* dest, u32 size) {
|
|
DmaFill32(3, value, dest, size);
|
|
}
|
|
|
|
void MemClear(void* dest, u32 size) {
|
|
u32 zero = 0;
|
|
|
|
switch (((u32)dest | size) & 3) {
|
|
case 0:
|
|
MemFill32(0, dest, size);
|
|
break;
|
|
case 2:
|
|
MemFill16(0, dest, size);
|
|
break;
|
|
default:
|
|
do {
|
|
*(u8*)dest = zero;
|
|
dest++;
|
|
size--;
|
|
} while (size != 0);
|
|
}
|
|
}
|
|
|
|
void MemCopy(const void* src, void* dest, u32 size) {
|
|
switch (((u32)src | (u32)dest | size) & 3) {
|
|
case 0:
|
|
DmaCopy32(3, src, dest, size);
|
|
break;
|
|
case 2:
|
|
DmaCopy16(3, src, dest, size);
|
|
break;
|
|
default:
|
|
do {
|
|
*(u8*)dest = *(u8*)src;
|
|
src++;
|
|
dest++;
|
|
} while (--size);
|
|
}
|
|
}
|
|
|
|
void ReadKeyInput(void) {
|
|
u32 keyInput = ~REG_KEYINPUT & KEYS_MASK;
|
|
StoreKeyInput(&gInput, keyInput);
|
|
}
|
|
|
|
static void StoreKeyInput(Input* input, u32 keyInput) {
|
|
u32 heldKeys = input->heldKeys;
|
|
u32 difference = keyInput & ~heldKeys;
|
|
input->newKeys = difference;
|
|
if (keyInput == heldKeys) {
|
|
if (--input->unk7 == 0) {
|
|
input->unk7 = 4;
|
|
input->unk4 = keyInput;
|
|
} else {
|
|
input->unk4 = 0;
|
|
}
|
|
} else {
|
|
input->unk7 = 0x14;
|
|
input->unk4 = difference;
|
|
}
|
|
input->heldKeys = keyInput;
|
|
}
|
|
|
|
void LoadPaletteGroup(u32 group) {
|
|
const PaletteGroup* paletteGroup = gPaletteGroups[group];
|
|
while (1) {
|
|
u32 destPaletteNum = paletteGroup->destPaletteNum;
|
|
u32 numPalettes = paletteGroup->numPalettes & 0xF;
|
|
if (numPalettes == 0) {
|
|
numPalettes = 16;
|
|
}
|
|
LoadPalettes(&gGlobalGfxAndPalettes[paletteGroup->paletteId * 32], destPaletteNum, numPalettes);
|
|
if ((paletteGroup->numPalettes & 0x80) == 0) {
|
|
break;
|
|
}
|
|
paletteGroup++;
|
|
}
|
|
}
|
|
|
|
void LoadPalettes(const u8* src, int destPaletteNum, int numPalettes) {
|
|
u16* dest;
|
|
u32 size = numPalettes * 32;
|
|
u32 usedPalettesMask = 1 << destPaletteNum;
|
|
while (--numPalettes > 0) {
|
|
usedPalettesMask |= (usedPalettesMask << 1);
|
|
}
|
|
gUsedPalettes |= usedPalettesMask;
|
|
dest = &gPaletteBuffer[destPaletteNum * 16];
|
|
DmaCopy32(3, src, dest, size);
|
|
}
|
|
|
|
void sub_0801D79C(u32 colorIndex, u32 color) {
|
|
gPaletteBuffer[colorIndex] = color;
|
|
gUsedPalettes |= 1 << (colorIndex / 16);
|
|
}
|
|
|
|
void sub_0801D7BC(u32 color, u32 arg1) {
|
|
if (arg1) {
|
|
gScreen.lcd.unk6 = 0xE0FF;
|
|
} else {
|
|
gScreen.lcd.unk6 = 0xFFFF;
|
|
}
|
|
sub_0801D79C(0, color);
|
|
}
|
|
|
|
void LoadGfxGroup(u32 group) {
|
|
u32 terminator;
|
|
u32 dmaCtrl;
|
|
int gfxOffset;
|
|
const u8* src;
|
|
u32 dest;
|
|
int size;
|
|
const GfxItem* gfxItem = gUnk_08100AA8[group];
|
|
while (1) {
|
|
u32 loadGfx = FALSE;
|
|
u32 ctrl = gfxItem->unk0.bytes.unk3;
|
|
ctrl &= 0xF;
|
|
switch (ctrl) {
|
|
case 0x7:
|
|
loadGfx = TRUE;
|
|
break;
|
|
case 0xD:
|
|
return;
|
|
case 0xE:
|
|
if (gUnk_02000000->gameLanguage != 0 && gUnk_02000000->gameLanguage != 1) {
|
|
loadGfx = TRUE;
|
|
}
|
|
break;
|
|
case 0xF:
|
|
if (gUnk_02000000->gameLanguage != 0) {
|
|
loadGfx = TRUE;
|
|
}
|
|
break;
|
|
default:
|
|
if (ctrl == gUnk_02000000->gameLanguage) {
|
|
loadGfx = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (loadGfx) {
|
|
gfxOffset = gfxItem->unk0.raw & 0xFFFFFF;
|
|
src = &gGlobalGfxAndPalettes[gfxOffset];
|
|
dest = gfxItem->dest;
|
|
size = gfxItem->unk8;
|
|
dmaCtrl = 0x80000000;
|
|
if (size < 0) {
|
|
if (dest >= VRAM) {
|
|
LZ77UnCompVram(src, (void*)dest);
|
|
} else {
|
|
LZ77UnCompWram(src, (void*)dest);
|
|
}
|
|
} else {
|
|
DmaSet(3, src, dest, dmaCtrl | ((u32)size >> 1));
|
|
}
|
|
}
|
|
|
|
terminator = gfxItem->unk0.bytes.unk3;
|
|
terminator &= 0x80;
|
|
gfxItem++;
|
|
if (!terminator) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* TODO:
|
|
clear OAM, zMalloc, etc.
|
|
*/
|