diff options
-rw-r--r-- | GPU.cpp | 4 | ||||
-rw-r--r-- | GPU.h | 2 | ||||
-rw-r--r-- | GPU2D.cpp | 94 | ||||
-rw-r--r-- | GPU2D.h | 20 | ||||
-rw-r--r-- | main.cpp | 8 | ||||
-rw-r--r-- | melonDS.depend | 12 |
6 files changed, 91 insertions, 49 deletions
@@ -62,7 +62,7 @@ u8* VRAM_AOBJExtPal; u8* VRAM_BBGExtPal[4]; u8* VRAM_BOBJExtPal; -u16 Framebuffer[256*192*2]; +u32 Framebuffer[256*192*2]; GPU2D* GPU2D_A; GPU2D* GPU2D_B; @@ -123,7 +123,7 @@ void Reset() for (int i = 0; i < 256*192*2; i++) { - Framebuffer[i] = 0x7FFF; + Framebuffer[i] = 0xFFFFFFFF; } GPU2D_A->Reset(); @@ -48,7 +48,7 @@ extern u8* VRAM_AOBJExtPal; extern u8* VRAM_BBGExtPal[4]; extern u8* VRAM_BOBJExtPal; -extern u16 Framebuffer[256*192*2]; +extern u32 Framebuffer[256*192*2]; extern GPU2D* GPU2D_A; extern GPU2D* GPU2D_B; @@ -82,11 +82,8 @@ void GPU2D::Reset() memset(BGRotD, 0, 2*2); } -void GPU2D::SetFramebuffer(u16* buf) +void GPU2D::SetFramebuffer(u32* buf) { - // framebuffer is 256x192 16bit. - // might eventually support other framebuffer types/sizes - // TODO: change this. the DS uses 18bit color Framebuffer = buf; } @@ -205,7 +202,7 @@ void GPU2D::Write32(u32 addr, u32 val) void GPU2D::DrawScanline(u32 line) { - u16* dst = &Framebuffer[256*line]; + u32* dst = &Framebuffer[256*line]; u32 dispmode = DispCnt >> 16; dispmode &= (Num ? 0x1 : 0x3); @@ -214,8 +211,8 @@ void GPU2D::DrawScanline(u32 line) { case 0: // screen off { - for (int i = 0; i < 256>>1; i++) - ((u32*)dst)[i] = 0x7FFF7FFF; + for (int i = 0; i < 256; i++) + dst[i] = 0xFF3F3F3F; } break; @@ -230,8 +227,15 @@ void GPU2D::DrawScanline(u32 line) u32* vram = (u32*)GPU::VRAM[(DispCnt >> 18) & 0x3]; vram = &vram[line << 7]; - for (int i = 0; i < 256>>1; i++) - ((u32*)dst)[i] = vram[i]; + for (int i = 0; i < 256; i++) + { + u16 color = vram[i]; + u8 r = (color & 0x001F) << 1; + u8 g = (color & 0x03E0) >> 4; + u8 b = (color & 0x7C00) >> 9; + + dst[i] = r | (g << 8) | (b << 16); + } } break; @@ -241,6 +245,12 @@ void GPU2D::DrawScanline(u32 line) } break; } + + // convert to 32-bit RGBA + for (int i = 0; i < 256; i++) + dst[i] = ((dst[i] & 0x003F3F3F) << 2) | + ((dst[i] & 0x00303030) >> 4) | + 0xFF000000; } void GPU2D::VBlank() @@ -250,7 +260,7 @@ void GPU2D::VBlank() template<u32 bgmode> -void GPU2D::DrawScanlineBGMode(u32 line, u32* spritebuf, u16* dst) +void GPU2D::DrawScanlineBGMode(u32 line, u32* spritebuf, u32* dst) { for (int i = 3; i >= 0; i--) { @@ -300,17 +310,24 @@ void GPU2D::DrawScanlineBGMode(u32 line, u32* spritebuf, u16* dst) } } -void GPU2D::DrawScanline_Mode1(u32 line, u16* dst) +void GPU2D::DrawScanline_Mode1(u32 line, u32* dst) { u32 backdrop; if (Num) backdrop = *(u16*)&GPU::Palette[0x400]; else backdrop = *(u16*)&GPU::Palette[0]; - // TODO: color effect for backdrop + { + u8 r = (backdrop & 0x001F) << 1; + u8 g = (backdrop & 0x03E0) >> 4; + u8 b = (backdrop & 0x7C00) >> 9; + + // TODO: color effect for backdrop - backdrop |= (backdrop<<16); - for (int i = 0; i < 256>>1; i++) - ((u32*)dst)[i] = backdrop; + backdrop = r | (g << 8) | (b << 16) | 0x20000000; + + for (int i = 0; i < 256; i++) + dst[i] = backdrop; + } // prerender sprites u32 spritebuf[256]; @@ -333,26 +350,38 @@ void GPU2D::DrawScanline_Mode1(u32 line, u16* dst) } -void GPU2D::DrawBG_3D(u32 line, u16* dst) +typedef void (*DrawPixelFunc)(u32 bgnum, u32* dst, u16 color, u32 blendfunc); + +void GPU2D::DrawPixel_Normal(u32 bgnum, u32* dst, u16 color, u32 blendfunc) +{ + u8 r = (color & 0x001F) << 1; + u8 g = (color & 0x03E0) >> 4; + u8 b = (color & 0x7C00) >> 9; + + *dst = r | (g << 8) | (b << 16) | (0x01000000 << bgnum); +} + +void GPU2D::DrawBG_3D(u32 line, u32* dst) { // TODO: scroll, etc u8* src = GPU3D::GetLine(line); for (int i = 0; i < 256; i++) { - // TODO: color buffer should be 18bit!! - u8 r = *src++; u8 g = *src++; u8 b = *src++; u8 a = *src++; if (a == 0) continue; - dst[i] = (r >> 1) | ((g >> 1) << 5) | ((b >> 1) << 10); + // TODO: blending + // alpha is 6bit too....? + + dst[i] = r | (g << 8) | (b << 16); } } -void GPU2D::DrawBG_Text(u32 line, u16* dst, u32 bgnum) +void GPU2D::DrawBG_Text(u32 line, u32* dst, u32 bgnum) { u16 bgcnt = BGCnt[bgnum]; @@ -366,6 +395,8 @@ void GPU2D::DrawBG_Text(u32 line, u16* dst, u32 bgnum) u32 widexmask = (bgcnt & 0x4000) ? 0x100 : 0; + DrawPixelFunc drawpixelfn = DrawPixel_Normal; + extpal = (bgcnt & 0x0080) && (DispCnt & 0x40000000); if (Num) @@ -456,7 +487,7 @@ void GPU2D::DrawBG_Text(u32 line, u16* dst, u32 bgnum) color = pixels[tilexoff]; if (color) - dst[i] = curpal[color]; + drawpixelfn(bgnum, &dst[i], curpal[color], BlendFunc); xoff++; } @@ -499,14 +530,14 @@ void GPU2D::DrawBG_Text(u32 line, u16* dst, u32 bgnum) } if (color) - dst[i] = curpal[color]; + drawpixelfn(bgnum, &dst[i], curpal[color], BlendFunc); xoff++; } } } -void GPU2D::DrawBG_Extended(u32 line, u16* dst, u32 bgnum) +void GPU2D::DrawBG_Extended(u32 line, u32* dst, u32 bgnum) { u16 bgcnt = BGCnt[bgnum]; @@ -529,6 +560,8 @@ void GPU2D::DrawBG_Extended(u32 line, u16* dst, u32 bgnum) if (bgcnt & 0x2000) overflowmask = 0; else overflowmask = ~(coordmask | 0x7FF); + DrawPixelFunc drawpixelfn = DrawPixel_Normal; + extpal = (DispCnt & 0x40000000); s16 rotA = BGRotA[bgnum-2]; @@ -566,7 +599,7 @@ void GPU2D::DrawBG_Extended(u32 line, u16* dst, u32 bgnum) u16 color = bitmap[(((rotY & coordmask) >> 8) << yshift) + ((rotX & coordmask) >> 8)]; if (color & 0x8000) - dst[i] = color; + drawpixelfn(bgnum, &dst[i], color, BlendFunc); } rotX += rotA; @@ -587,7 +620,7 @@ void GPU2D::DrawBG_Extended(u32 line, u16* dst, u32 bgnum) u8 color = tileset[(((rotY & coordmask) >> 8) << yshift) + ((rotX & coordmask) >> 8)]; if (color) - dst[i] = pal[color]; + drawpixelfn(bgnum, &dst[i], pal[color], BlendFunc); } rotX += rotA; @@ -660,7 +693,7 @@ void GPU2D::DrawBG_Extended(u32 line, u16* dst, u32 bgnum) color = pixels[(tileyoff << 3) + tilexoff]; if (color) - dst[i] = curpal[color]; + drawpixelfn(bgnum, &dst[i], curpal[color], BlendFunc); } rotX += rotA; @@ -672,12 +705,17 @@ void GPU2D::DrawBG_Extended(u32 line, u16* dst, u32 bgnum) //BGYCenter[bgnum-2] += rotD; } -void GPU2D::InterleaveSprites(u32* buf, u32 prio, u16* dst) +void GPU2D::InterleaveSprites(u32* buf, u32 prio, u32* dst) { + DrawPixelFunc drawpixelfn = DrawPixel_Normal; + for (u32 i = 0; i < 256; i++) { if ((buf[i] & 0xF8000) == prio) - dst[i] = buf[i] & 0x7FFF; + { + u32 blendfunc = 0; + drawpixelfn(4, &dst[i], buf[i], blendfunc); + } } } @@ -27,7 +27,7 @@ public: void Reset(); - void SetFramebuffer(u16* buf); + void SetFramebuffer(u32* buf); u8 Read8(u32 addr); u16 Read16(u32 addr); @@ -41,7 +41,7 @@ public: private: u32 Num; - u16* Framebuffer; + u32* Framebuffer; u32 DispCnt; u16 BGCnt[4]; @@ -56,14 +56,18 @@ private: s16 BGRotC[2]; s16 BGRotD[2]; - template<u32 bgmode> void DrawScanlineBGMode(u32 line, u32* spritebuf, u16* dst); - void DrawScanline_Mode1(u32 line, u16* dst); + u32 BlendFunc; - void DrawBG_3D(u32 line, u16* dst); - void DrawBG_Text(u32 line, u16* dst, u32 num); - void DrawBG_Extended(u32 line, u16* dst, u32 bgnum); + template<u32 bgmode> void DrawScanlineBGMode(u32 line, u32* spritebuf, u32* dst); + void DrawScanline_Mode1(u32 line, u32* dst); - void InterleaveSprites(u32* buf, u32 prio, u16* dst); + static void DrawPixel_Normal(u32 bgnum, u32* dst, u16 color, u32 blendfunc); + + void DrawBG_3D(u32 line, u32* dst); + void DrawBG_Text(u32 line, u32* dst, u32 num); + void DrawBG_Extended(u32 line, u32* dst, u32 bgnum); + + void InterleaveSprites(u32* buf, u32 prio, u32* dst); void DrawSprites(u32 line, u32* dst); void DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, u32 ypos, u32* dst); void DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, u32 ypos, u32* dst); @@ -216,11 +216,11 @@ int main() bmp.bV4Width = 256; bmp.bV4Height = -384; bmp.bV4Planes = 1; - bmp.bV4BitCount = 16; + bmp.bV4BitCount = 32; bmp.bV4V4Compression = BI_RGB|BI_BITFIELDS; - bmp.bV4RedMask = 0x001F; - bmp.bV4GreenMask = 0x03E0; - bmp.bV4BlueMask = 0x7C00; + bmp.bV4RedMask = 0x000000FF; + bmp.bV4GreenMask = 0x0000FF00; + bmp.bV4BlueMask = 0x00FF0000; NDS::Init(); diff --git a/melonDS.depend b/melonDS.depend index db3140c..5553a14 100644 --- a/melonDS.depend +++ b/melonDS.depend @@ -1,5 +1,5 @@ # depslib dependency file v1.0 -1487028720 source:c:\documents\sources\melonds\main.cpp +1487105574 source:c:\documents\sources\melonds\main.cpp <stdio.h> <windows.h> "NDS.h" @@ -10,7 +10,7 @@ 1481161027 c:\documents\sources\melonds\types.h -1487039174 source:c:\documents\sources\melonds\nds.cpp +1487101361 source:c:\documents\sources\melonds\nds.cpp <stdio.h> <string.h> "NDS.h" @@ -87,13 +87,13 @@ "NDS.h" "SPI.h" -1486778220 source:c:\documents\sources\melonds\gpu2d.cpp +1487105611 source:c:\documents\sources\melonds\gpu2d.cpp <stdio.h> <string.h> "NDS.h" "GPU.h" -1486777351 c:\documents\sources\melonds\gpu2d.h +1487105228 c:\documents\sources\melonds\gpu2d.h 1481040524 c:\documents\sources\melonds\wifi.h @@ -119,13 +119,13 @@ 1484698068 c:\documents\sources\melonds\dma.h "types.h" -1486736549 source:c:\documents\sources\melonds\gpu.cpp +1487102235 source:c:\documents\sources\melonds\gpu.cpp <stdio.h> <string.h> "NDS.h" "GPU.h" -1486501976 c:\documents\sources\melonds\gpu.h +1487102203 c:\documents\sources\melonds\gpu.h "GPU2D.h" "GPU3D.h" |