diff options
author | StapleButter <thetotalworm@gmail.com> | 2017-03-07 01:13:00 +0100 |
---|---|---|
committer | StapleButter <thetotalworm@gmail.com> | 2017-03-07 01:13:00 +0100 |
commit | d95d22837bf01188a851904eb346c9a4577aa25e (patch) | |
tree | 76acce93e49a80fa661043041363d954ab5214ad | |
parent | 72209c51f9db6e1cb7d8f0909d7317454e8b5771 (diff) |
proper clear-plane support, including bitmap mode
-rw-r--r-- | GPU3D.cpp | 52 | ||||
-rw-r--r-- | GPU3D.h | 2 | ||||
-rw-r--r-- | GPU3D_Soft.cpp | 53 | ||||
-rw-r--r-- | NDS.cpp | 7 |
4 files changed, 105 insertions, 9 deletions
@@ -143,6 +143,7 @@ FIFO<CmdFIFOEntry>* CmdPIPE; u32 NumCommands, CurCommand, ParamCount, TotalParams; +u32 DispCnt; u32 GXStat; u32 ExecParams[32]; @@ -196,6 +197,8 @@ Polygon* CurPolygonRAM; u32 NumVertices, NumPolygons; u32 CurRAMBank; +u32 ClearAttr1, ClearAttr2; + u32 FlushRequest; u32 FlushAttributes, CurFlushAttributes; @@ -229,6 +232,7 @@ void Reset() ParamCount = 0; TotalParams = 0; + DispCnt = 0; GXStat = 0; memset(ExecParams, 0, 32*4); @@ -262,7 +266,12 @@ void Reset() NumVertices = 0; NumPolygons = 0; + ClearAttr1 = 0; + ClearAttr2 = 0; + FlushRequest = 0; + FlushAttributes = 0; + CurFlushAttributes = 0; SoftRenderer::Reset(); } @@ -544,6 +553,8 @@ void SubmitPolygon() // if it's outside, check if the previous and next vertices are inside // if so, place a new vertex at the edge of the view volume + // TODO: optional culling of polygons that clip through the far plane + // X clipping c = clipstart; @@ -1414,6 +1425,12 @@ u8 Read8(u32 addr) u16 Read16(u32 addr) { + switch (addr) + { + case 0x04000060: + return DispCnt; + } + return 0; } @@ -1421,6 +1438,9 @@ u32 Read32(u32 addr) { switch (addr) { + case 0x04000060: + return DispCnt; + case 0x04000320: return 46; // TODO, eventually @@ -1453,18 +1473,46 @@ u32 Read32(u32 addr) void Write8(u32 addr, u8 val) { - // } void Write16(u32 addr, u16 val) { - // + switch (addr) + { + case 0x04000060: + DispCnt = val; + return; + + case 0x04000350: + ClearAttr1 = (ClearAttr1 & 0xFFFF0000) | val; + return; + case 0x04000352: + ClearAttr1 = (ClearAttr1 & 0xFFFF) | (val << 16); + return; + case 0x04000354: + ClearAttr2 = (ClearAttr2 & 0xFFFF0000) | val; + return; + case 0x04000356: + ClearAttr2 = (ClearAttr2 & 0xFFFF) | (val << 16); + return; + } } void Write32(u32 addr, u32 val) { switch (addr) { + case 0x04000060: + DispCnt = val & 0xFFFF; + return; + + case 0x04000350: + ClearAttr1 = val; + return; + case 0x04000354: + ClearAttr2 = val; + return; + case 0x04000600: if (val & 0x8000) GXStat &= ~0x8000; val &= 0xC0000000; @@ -53,7 +53,9 @@ typedef struct } Polygon; +extern u32 DispCnt; extern s32 Viewport[4]; +extern u32 ClearAttr1, ClearAttr2; bool Init(); void DeInit(); diff --git a/GPU3D_Soft.cpp b/GPU3D_Soft.cpp index b1919f5..8551aa5 100644 --- a/GPU3D_Soft.cpp +++ b/GPU3D_Soft.cpp @@ -582,11 +582,56 @@ void RenderFrame(u32 attr, Vertex* vertices, Polygon* polygons, int npolys) { // TODO: render translucent polygons last - // TODO proper clear color/depth support! - for (int i = 0; i < 256*192; i++) + // TODO: fog, poly ID, other attributes + + if (DispCnt & (1<<14)) + { + u8 xoff = (ClearAttr2 >> 16) & 0xFF; + u8 yoff = (ClearAttr2 >> 24) & 0xFF; + + for (int y = 0; y < 256*192; y += 256) + { + for (int x = 0; x < 256; x++) + { + u16 val2 = GPU::ReadVRAM_Texture<u16>(0x40000 + (yoff << 9) + (xoff << 1)); + u16 val3 = GPU::ReadVRAM_Texture<u16>(0x60000 + (yoff << 9) + (xoff << 1)); + + // TODO: confirm color conversion + u32 r = (val2 << 1) & 0x3E; if (r) r++; + u32 g = (val2 >> 4) & 0x3E; if (g) g++; + u32 b = (val2 >> 9) & 0x3E; if (b) b++; + u32 a = (val2 & 0x8000) ? 0x1F000000 : 0; + u32 color = r | (g << 8) | (b << 16) | a; + + u32 z = ((val3 & 0x7FFF) * 0x200) + 0x1FF; + if (z >= 0x10000 && z < 0xFFFFFF) z++; + + ColorBuffer[y+x] = color; + DepthBuffer[y+x] = z; + + xoff++; + } + + yoff++; + } + } + else { - ColorBuffer[i] = 0x00000000; - DepthBuffer[i] = 0xFFFFFF; + // TODO: confirm color conversion + u32 r = (ClearAttr1 << 1) & 0x3E; if (r) r++; + u32 g = (ClearAttr1 >> 4) & 0x3E; if (g) g++; + u32 b = (ClearAttr1 >> 9) & 0x3E; if (b) b++; + u32 a = (ClearAttr1 >> 16) & 0x1F; + u32 color = r | (g << 8) | (b << 16) | (a << 24); + + u32 z = ((ClearAttr2 & 0x7FFF) * 0x200) + 0x1FF; + if (z >= 0x10000 && z < 0xFFFFFF) z++; + + for (int i = 0; i < 256*192; i++) + { + ColorBuffer[i] = color; + DepthBuffer[i] = z; + } } for (int i = 0; i < npolys; i++) @@ -1295,7 +1295,7 @@ u16 ARM9IORead16(u32 addr) case 0x04000004: return GPU::DispStat[0]; case 0x04000006: return GPU::VCount; - case 0x04000060: return 0; + case 0x04000060: return GPU3D::Read16(addr); case 0x04000064: case 0x04000066: return GPU::GPU2D_A->Read16(addr); @@ -1382,6 +1382,7 @@ u32 ARM9IORead32(u32 addr) { case 0x04000004: return GPU::DispStat[0] | (GPU::VCount << 16); + case 0x04000060: return GPU3D::Read32(addr); case 0x04000064: return GPU::GPU2D_A->Read32(addr); case 0x040000B0: return DMAs[0]->SrcAddr; @@ -1547,7 +1548,7 @@ void ARM9IOWrite16(u32 addr, u16 val) { case 0x04000004: GPU::SetDispStat(0, val); return; - case 0x04000060: return; + case 0x04000060: GPU3D::Write16(addr, val); return; case 0x040000B8: DMAs[0]->WriteCnt((DMAs[0]->Cnt & 0xFFFF0000) | val); return; case 0x040000BA: DMAs[0]->WriteCnt((DMAs[0]->Cnt & 0x0000FFFF) | (val << 16)); return; @@ -1667,7 +1668,7 @@ void ARM9IOWrite32(u32 addr, u32 val) { switch (addr) { - case 0x04000060: return; + case 0x04000060: GPU3D::Write32(addr, val); return; case 0x04000064: GPU::GPU2D_A->Write32(addr, val); return; case 0x040000B0: DMAs[0]->SrcAddr = val; return; |