Skip to content

Instantly share code, notes, and snippets.

@ITotalJustice
Created January 24, 2023 06:44
Show Gist options
  • Save ITotalJustice/a9c5876f0b2d3e294901f4af6cadaa89 to your computer and use it in GitHub Desktop.
Save ITotalJustice/a9c5876f0b2d3e294901f4af6cadaa89 to your computer and use it in GitHub Desktop.
auto LZ77UnCompReadNormalWrite(Gba& gba, auto fetch_and_write, auto calc_offset) -> bool
{
auto src = arm7tdmi::get_reg(gba, 0);
auto dst = arm7tdmi::get_reg(gba, 1);
const auto header = mem::read32(gba, src);
auto len = bit::get_range<8, 31>(header);
src += 4; // skip over header
if (!IsValidRange(gba, len, src))
{
return true;
}
for (;;)
{
const auto flag = mem::read8(gba, src++);
for (int bit = 7; bit >= 0; bit--)
{
if (bit::is_set(flag, bit)) // compressed
{
u16 meta = 0;
meta |= mem::read8(gba, src++) << 8;
meta |= mem::read8(gba, src++) << 0;
const auto size = bit::get_range<12, 15>(meta) + 3;
const auto disp = bit::get_range<0, 11>(meta);
auto offset = calc_offset(dst, disp);
for (int i = 0; i < size; i++)
{
fetch_and_write(dst, len, offset++);
if (!len)
{
return true;
}
}
}
else // uncompressed
{
fetch_and_write(dst, len, src++);
if (!len)
{
return true;
}
}
}
}
}
// 0x11
auto LZ77UnCompReadNormalWrite8bit(Gba& gba) -> bool
{
const auto calc_offset = [](u32 dst, u32 disp)
{
return dst - disp - 1;
};
const auto fetch_and_write = [&gba](u32& dst, u32& len, u32 src_addr)
{
const auto data = mem::read8(gba, src_addr);
mem::write8(gba, dst++, data);
len--;
};
return LZ77UnCompReadNormalWrite(gba, fetch_and_write, calc_offset);
}
// 0x12
auto LZ77UnCompReadNormalWrite16bit(Gba& gba) -> bool
{
u16 vram_data = 0;
bool flipflop = false;
const auto calc_offset = [&flipflop](u32 dst, u32 disp)
{
return dst - disp - 1 + flipflop;
};
const auto fetch_and_write = [&gba, &vram_data, &flipflop](u32& dst, u32& len, u32 src_addr)
{
const auto data = mem::read8(gba, src_addr);
vram_data >>= 8;
vram_data |= data << 8;
if (flipflop)
{
mem::write16(gba, dst, vram_data);
dst += 2;
}
flipflop ^= 1;
len--;
};
return LZ77UnCompReadNormalWrite(gba, fetch_and_write, calc_offset);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment