Cores/Nds/GPU.Flat.cs
namespace Emulotl.Nds;
public sealed partial class GPU
{
private const int FlatPad = 8;
public byte[] VRAMFlat_ABG = new byte[0x80000 + FlatPad];
public byte[] VRAMFlat_BBG = new byte[0x20000 + FlatPad];
public byte[] VRAMFlat_AOBJ = new byte[0x40000 + FlatPad];
public byte[] VRAMFlat_BOBJ = new byte[0x20000 + FlatPad];
public byte[] VRAMFlat_ABGExtPal = new byte[0x8000 + FlatPad];
public byte[] VRAMFlat_BBGExtPal = new byte[0x8000 + FlatPad];
public byte[] VRAMFlat_AOBJExtPal = new byte[0x2000 + FlatPad];
public byte[] VRAMFlat_BOBJExtPal = new byte[0x2000 + FlatPad];
public void RebuildVRAMFlat()
{
UpdateTexVRAMTracking();
FlattenRegion( VRAMFlat_ABG, VRAMMap_ABG, 14 );
FlattenRegion( VRAMFlat_BBG, VRAMMap_BBG, 14 );
FlattenRegion( VRAMFlat_AOBJ, VRAMMap_AOBJ, 14 );
FlattenRegion( VRAMFlat_BOBJ, VRAMMap_BOBJ, 14 );
FlattenRegion( VRAMFlat_ABGExtPal, VRAMMap_ABGExtPal, 13 );
FlattenRegion( VRAMFlat_BBGExtPal, VRAMMap_BBGExtPal, 13 );
FlattenSlot( VRAMFlat_AOBJExtPal, VRAMMap_AOBJExtPal, 0x2000 );
FlattenSlot( VRAMFlat_BOBJExtPal, VRAMMap_BOBJExtPal, 0x2000 );
}
private void UpdateTexVRAMTracking()
{
uint mask = 0;
ulong sig = 1469598103934665603UL;
for ( int s = 0; s < VRAMMap_Texture.Length; s++ )
{
mask |= VRAMMap_Texture[s];
sig = (sig ^ VRAMMap_Texture[s]) * 1099511628211UL;
}
for ( int s = 0; s < VRAMMap_TexPal.Length; s++ )
{
mask |= VRAMMap_TexPal[s];
sig = (sig ^ VRAMMap_TexPal[s]) * 1099511628211UL;
}
TexBankMask = mask;
if ( sig != _lastTexMapSig )
{
_lastTexMapSig = sig;
TexVRAMVersion++;
}
}
private void FlattenRegion( byte[] flat, uint[] map, int slotShift )
{
int slotSize = 1 << slotShift;
for ( int s = 0; s < map.Length; s++ )
FlattenSlotAt( flat, s << slotShift, map[s], slotSize );
}
private void FlattenSlot( byte[] flat, uint mask, int slotSize )
{
FlattenSlotAt( flat, 0, mask, slotSize );
}
private void FlattenSlotAt( byte[] flat, int dst, uint mask, int slotSize )
{
if ( mask == 0 )
{
Array.Clear( flat, dst, slotSize );
return;
}
bool first = true;
for ( int b = 0; b < 9; b++ )
{
if ( (mask & (1u << b)) == 0 )
continue;
byte[] bank = VRAM[b];
int src = (int)((uint)dst & VRAMMask[b]);
if ( first )
{
Array.Copy( bank, src, flat, dst, slotSize );
first = false;
}
else
{
for ( int i = 0; i < slotSize; i++ )
flat[dst + i] |= bank[src + i];
}
}
}
}