diff options
author | StapleButter <thetotalworm@gmail.com> | 2017-03-01 23:02:50 +0100 |
---|---|---|
committer | StapleButter <thetotalworm@gmail.com> | 2017-03-01 23:02:50 +0100 |
commit | f7c481b2a17d6bdd5ebeca1687a681ba8d2385e7 (patch) | |
tree | bc3ee567b2ee8e8668e8d97eadf54a44b1c6be7e | |
parent | 247558a35401e807770d162a5ed30602815d3dfb (diff) |
support for non-rotscaled bitmap sprites
-rw-r--r-- | GPU2D.cpp | 224 | ||||
-rw-r--r-- | melonDS.depend | 4 |
2 files changed, 143 insertions, 85 deletions
@@ -1081,6 +1081,8 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 { u32 prio = ((attrib[2] & 0x0C00) << 6) | 0x8000; u32 tilenum = attrib[2] & 0x03FF; + u32 spritemode = (attrib[0] >> 10) & 0x3; + u32 ytilefactor; if (DispCnt & 0x10) { @@ -1119,6 +1121,8 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 width <<= 8; height <<= 8; + //if (spritemode == 3) printf("BAKA"); + if (attrib[0] & 0x2000) { // 256-color @@ -1191,15 +1195,7 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, u32 ypos, u32* d { u32 prio = ((attrib[2] & 0x0C00) << 6) | 0x8000; u32 tilenum = attrib[2] & 0x03FF; - if (DispCnt & 0x10) - { - tilenum <<= ((DispCnt >> 20) & 0x3); - tilenum += ((ypos >> 3) * (width >> 3)) << ((attrib[0] & 0x2000) ? 1:0); - } - else - { - tilenum += ((ypos >> 3) * 0x20); - } + u32 spritemode = (attrib[0] >> 10) & 0x3; u32 wmask = width - 8; // really ((width - 1) & ~0x7) @@ -1216,116 +1212,178 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, u32 ypos, u32* d xpos = 0; } - if (attrib[0] & 0x2000) + if (spritemode == 3) { - // 256-color - tilenum <<= 5; - u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum; - pixelsaddr += ((ypos & 0x7) << 3); - - u32 extpal = (DispCnt & 0x80000000); + // bitmap sprite - u16* pal; - if (extpal) pal = GetOBJExtPal(attrib[2] >> 12); - else pal = (u16*)&GPU::Palette[Num ? 0x600 : 0x200]; - - if (attrib[1] & 0x1000) // xflip. TODO: do better? oh well for now this works + if (DispCnt & 0x40) { - pixelsaddr += (((width-1 - xoff) & wmask) << 3); - pixelsaddr += ((width-1 - xoff) & 0x7); - - for (; xoff < width;) + if (DispCnt & 0x20) { - u8 color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr); - pixelsaddr--; - - if (color) - dst[xpos] = pal[color] | prio; - - xoff++; - xpos++; - if (!(xoff & 0x7)) pixelsaddr -= 56; + // TODO ("reserved") + } + else + { + tilenum <<= (7 + ((DispCnt >> 22) & 0x1)); + tilenum += (ypos * width * 2); } } else { - pixelsaddr += ((xoff & wmask) << 3); - pixelsaddr += (xoff & 0x7); - - for (; xoff < width;) + if (DispCnt & 0x20) { - u8 color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr); - pixelsaddr++; + tilenum = ((tilenum & 0x01F) << 4) + ((tilenum & 0x3E0) << 7); + tilenum += (ypos * 256 * 2); + } + else + { + tilenum = ((tilenum & 0x00F) << 4) + ((tilenum & 0x3F0) << 7); + tilenum += (ypos * 128 * 2); + } + } - if (color) - dst[xpos] = pal[color] | prio; + u32 alpha = attrib[2] >> 12; + if (!alpha) return; + alpha++; - xoff++; - xpos++; - if (!(xoff & 0x7)) pixelsaddr += 56; - } + u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum; + pixelsaddr += (xoff << 1); + + for (; xoff < width;) + { + u16 color = GPU::ReadVRAM_OBJ<u16>(pixelsaddr); + pixelsaddr += 2; + + if (color & 0x8000) + dst[xpos] = color | prio; + + xoff++; + xpos++; } } else { - // 16-color - tilenum <<= 5; - u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum; - pixelsaddr += ((ypos & 0x7) << 2); - - u16* pal = (u16*)&GPU::Palette[Num ? 0x600 : 0x200]; - pal += (attrib[2] & 0xF000) >> 8; + if (DispCnt & 0x10) + { + tilenum <<= ((DispCnt >> 20) & 0x3); + tilenum += ((ypos >> 3) * (width >> 3)) << ((attrib[0] & 0x2000) ? 1:0); + } + else + { + tilenum += ((ypos >> 3) * 0x20); + } - if (attrib[1] & 0x1000) // xflip. TODO: do better? oh well for now this works + if (attrib[0] & 0x2000) { - pixelsaddr += (((width-1 - xoff) & wmask) << 2); - pixelsaddr += (((width-1 - xoff) & 0x7) >> 1); + // 256-color + tilenum <<= 5; + u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum; + pixelsaddr += ((ypos & 0x7) << 3); + + u32 extpal = (DispCnt & 0x80000000); + + u16* pal; + if (extpal) pal = GetOBJExtPal(attrib[2] >> 12); + else pal = (u16*)&GPU::Palette[Num ? 0x600 : 0x200]; - for (; xoff < width;) + if (attrib[1] & 0x1000) // xflip. TODO: do better? oh well for now this works { - u8 color; - if (xoff & 0x1) + pixelsaddr += (((width-1 - xoff) & wmask) << 3); + pixelsaddr += ((width-1 - xoff) & 0x7); + + for (; xoff < width;) { - color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) & 0x0F; + u8 color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr); pixelsaddr--; + + if (color) + dst[xpos] = pal[color] | prio; + + xoff++; + xpos++; + if (!(xoff & 0x7)) pixelsaddr -= 56; } - else + } + else + { + pixelsaddr += ((xoff & wmask) << 3); + pixelsaddr += (xoff & 0x7); + + for (; xoff < width;) { - color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) >> 4; - } + u8 color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr); + pixelsaddr++; - if (color) - dst[xpos] = pal[color] | prio; + if (color) + dst[xpos] = pal[color] | prio; - xoff++; - xpos++; - if (!(xoff & 0x7)) pixelsaddr -= 28; + xoff++; + xpos++; + if (!(xoff & 0x7)) pixelsaddr += 56; + } } } else { - pixelsaddr += ((xoff & wmask) << 2); - pixelsaddr += ((xoff & 0x7) >> 1); + // 16-color + tilenum <<= 5; + u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum; + pixelsaddr += ((ypos & 0x7) << 2); + + u16* pal = (u16*)&GPU::Palette[Num ? 0x600 : 0x200]; + pal += (attrib[2] & 0xF000) >> 8; - for (; xoff < width;) + if (attrib[1] & 0x1000) // xflip. TODO: do better? oh well for now this works { - u8 color; - if (xoff & 0x1) + pixelsaddr += (((width-1 - xoff) & wmask) << 2); + pixelsaddr += (((width-1 - xoff) & 0x7) >> 1); + + for (; xoff < width;) { - color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) >> 4; - pixelsaddr++; + u8 color; + if (xoff & 0x1) + { + color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) & 0x0F; + pixelsaddr--; + } + else + { + color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) >> 4; + } + + if (color) + dst[xpos] = pal[color] | prio; + + xoff++; + xpos++; + if (!(xoff & 0x7)) pixelsaddr -= 28; } - else + } + else + { + pixelsaddr += ((xoff & wmask) << 2); + pixelsaddr += ((xoff & 0x7) >> 1); + + for (; xoff < width;) { - color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) & 0x0F; - } + u8 color; + if (xoff & 0x1) + { + color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) >> 4; + pixelsaddr++; + } + else + { + color = GPU::ReadVRAM_OBJ<u8>(pixelsaddr) & 0x0F; + } - if (color) - dst[xpos] = pal[color] | prio; + if (color) + dst[xpos] = pal[color] | prio; - xoff++; - xpos++; - if (!(xoff & 0x7)) pixelsaddr += 28; + xoff++; + xpos++; + if (!(xoff & 0x7)) pixelsaddr += 28; + } } } } diff --git a/melonDS.depend b/melonDS.depend index 0aac391..6ca48b0 100644 --- a/melonDS.depend +++ b/melonDS.depend @@ -10,7 +10,7 @@ 1481161027 c:\documents\sources\melonds\types.h -1488396811 source:c:\documents\sources\melonds\nds.cpp +1488405583 source:c:\documents\sources\melonds\nds.cpp <stdio.h> <string.h> "NDS.h" @@ -87,7 +87,7 @@ "NDS.h" "SPI.h" -1488396037 source:c:\documents\sources\melonds\gpu2d.cpp +1488405475 source:c:\documents\sources\melonds\gpu2d.cpp <stdio.h> <string.h> "NDS.h" |