clean up some shit. make framebuffer access less weird.
This commit is contained in:
parent
d81b68b16b
commit
64a447bb7c
|
@ -1702,7 +1702,7 @@ void ExecuteCommand()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x50: // flush
|
case 0x50: // flush
|
||||||
FlushRequest |= 0x1;
|
FlushRequest = 1;
|
||||||
FlushAttributes = ExecParams[0] & 0x3;
|
FlushAttributes = ExecParams[0] & 0x3;
|
||||||
CycleCount = 392;
|
CycleCount = 392;
|
||||||
break;
|
break;
|
||||||
|
@ -1743,7 +1743,7 @@ void ExecuteCommand()
|
||||||
|
|
||||||
void Run(s32 cycles)
|
void Run(s32 cycles)
|
||||||
{
|
{
|
||||||
if (FlushRequest & 0x1)
|
if (FlushRequest)
|
||||||
return;
|
return;
|
||||||
if (CycleCount <= 0 && CmdPIPE->IsEmpty())
|
if (CycleCount <= 0 && CmdPIPE->IsEmpty())
|
||||||
return;
|
return;
|
||||||
|
@ -1796,10 +1796,10 @@ void VCount144()
|
||||||
SoftRenderer::VCount144();
|
SoftRenderer::VCount144();
|
||||||
}
|
}
|
||||||
|
|
||||||
int frame=0;
|
|
||||||
void VBlank()
|
void VBlank()
|
||||||
{
|
{
|
||||||
if (FlushRequest & 0x1)
|
if (FlushRequest)
|
||||||
{
|
{
|
||||||
RenderVertexRAM = CurVertexRAM;
|
RenderVertexRAM = CurVertexRAM;
|
||||||
RenderPolygonRAM = CurPolygonRAM;
|
RenderPolygonRAM = CurPolygonRAM;
|
||||||
|
@ -1827,22 +1827,13 @@ void VBlank()
|
||||||
NumVertices = 0;
|
NumVertices = 0;
|
||||||
NumPolygons = 0;
|
NumPolygons = 0;
|
||||||
|
|
||||||
FlushRequest &= ~0x1;
|
FlushRequest = 0;
|
||||||
FlushRequest |= 0x2;frame=1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCount215()
|
void VCount215()
|
||||||
{
|
{
|
||||||
// TODO: detect other conditions that could require rerendering
|
SoftRenderer::RenderFrame();
|
||||||
// the DS is said to present new 3D frames all the time, even if no commands are sent
|
|
||||||
|
|
||||||
//if (FlushRequest & 0x2)
|
|
||||||
{
|
|
||||||
SoftRenderer::RenderFrame(RenderVertexRAM, RenderPolygonRAM, RenderNumPolygons);
|
|
||||||
|
|
||||||
FlushRequest &= ~0x2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequestLine(int line)
|
void RequestLine(int line)
|
||||||
|
|
|
@ -114,7 +114,7 @@ void DeInit();
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
void VCount144();
|
void VCount144();
|
||||||
void RenderFrame(Vertex* vertices, Polygon* polygons, int npolys);
|
void RenderFrame();
|
||||||
void RequestLine(int line);
|
void RequestLine(int line);
|
||||||
u32* GetLine(int line);
|
u32* GetLine(int line);
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,20 @@ namespace GPU3D
|
||||||
namespace SoftRenderer
|
namespace SoftRenderer
|
||||||
{
|
{
|
||||||
|
|
||||||
u32 ColorBuffer[258*3*194];
|
// buffer dimensions are 258x194 to add a offscreen 1px border
|
||||||
u32 DepthBuffer[258*3*194];
|
// which simplifies edge marking tests
|
||||||
u32 AttrBuffer[258*3*194];
|
// buffer is duplicated to keep track of the two topmost pixels
|
||||||
|
// TODO: check if the hardware can accidentally plot pixels
|
||||||
|
// offscreen in that border
|
||||||
|
|
||||||
|
const int ScanlineWidth = 258;
|
||||||
|
const int NumScanlines = 194;
|
||||||
|
const int BufferSize = ScanlineWidth * NumScanlines;
|
||||||
|
const int FirstPixelOffset = ScanlineWidth + 1;
|
||||||
|
|
||||||
|
u32 ColorBuffer[BufferSize * 2];
|
||||||
|
u32 DepthBuffer[BufferSize * 2];
|
||||||
|
u32 AttrBuffer[BufferSize * 2];
|
||||||
|
|
||||||
// attribute buffer:
|
// attribute buffer:
|
||||||
// bit0-3: edge flags (left/right/top/bottom)
|
// bit0-3: edge flags (left/right/top/bottom)
|
||||||
|
@ -993,7 +1004,7 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
|
||||||
edge = yedge | 0x1;
|
edge = yedge | 0x1;
|
||||||
for (; x < xstart+l_edgelen; x++)
|
for (; x < xstart+l_edgelen; x++)
|
||||||
{
|
{
|
||||||
u32 pixeladdr = 258*3 + 1 + (y*258*3) + x;
|
u32 pixeladdr = FirstPixelOffset + (y*ScanlineWidth) + x;
|
||||||
u32 attr = (polygon->Attr & 0x3F008000);
|
u32 attr = (polygon->Attr & 0x3F008000);
|
||||||
|
|
||||||
// check stencil buffer for shadows
|
// check stencil buffer for shadows
|
||||||
|
@ -1036,7 +1047,7 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
|
||||||
{
|
{
|
||||||
if (!(dstattr & 0x3)) continue;
|
if (!(dstattr & 0x3)) continue;
|
||||||
|
|
||||||
pixeladdr += 258;
|
pixeladdr += BufferSize;
|
||||||
if (!fnDepthTest(DepthBuffer[pixeladdr], z))
|
if (!fnDepthTest(DepthBuffer[pixeladdr], z))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1084,11 +1095,12 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
|
||||||
attr |= (cov << 8);
|
attr |= (cov << 8);
|
||||||
|
|
||||||
// push old pixel down if needed
|
// push old pixel down if needed
|
||||||
// we only need to do it for opaque edge pixels, since
|
if (pixeladdr < BufferSize)
|
||||||
// this only serves for antialiasing
|
{
|
||||||
ColorBuffer[pixeladdr+258] = ColorBuffer[pixeladdr];
|
ColorBuffer[pixeladdr+BufferSize] = ColorBuffer[pixeladdr];
|
||||||
DepthBuffer[pixeladdr+258] = DepthBuffer[pixeladdr];
|
DepthBuffer[pixeladdr+BufferSize] = DepthBuffer[pixeladdr];
|
||||||
AttrBuffer[pixeladdr+258] = AttrBuffer[pixeladdr];
|
AttrBuffer[pixeladdr+BufferSize] = AttrBuffer[pixeladdr];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1131,7 +1143,7 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
|
||||||
if (wireframe && !edge) x = xend-r_edgelen+1;
|
if (wireframe && !edge) x = xend-r_edgelen+1;
|
||||||
else for (; x <= xend-r_edgelen; x++)
|
else for (; x <= xend-r_edgelen; x++)
|
||||||
{
|
{
|
||||||
u32 pixeladdr = 258*3 + 1 + (y*258*3) + x;
|
u32 pixeladdr = FirstPixelOffset + (y*ScanlineWidth) + x;
|
||||||
u32 attr = (polygon->Attr & 0x3F008000);
|
u32 attr = (polygon->Attr & 0x3F008000);
|
||||||
|
|
||||||
// check stencil buffer for shadows
|
// check stencil buffer for shadows
|
||||||
|
@ -1164,7 +1176,7 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
|
||||||
{
|
{
|
||||||
if (!(dstattr & 0x3)) continue;
|
if (!(dstattr & 0x3)) continue;
|
||||||
|
|
||||||
pixeladdr += 258;
|
pixeladdr += BufferSize;
|
||||||
if (!fnDepthTest(DepthBuffer[pixeladdr], z))
|
if (!fnDepthTest(DepthBuffer[pixeladdr], z))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1222,7 +1234,7 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
|
||||||
edge = yedge | 0x2;
|
edge = yedge | 0x2;
|
||||||
for (; x <= xend; x++)
|
for (; x <= xend; x++)
|
||||||
{
|
{
|
||||||
u32 pixeladdr = 258*3 + 1 + (y*258*3) + x;
|
u32 pixeladdr = FirstPixelOffset + (y*ScanlineWidth) + x;
|
||||||
u32 attr = (polygon->Attr & 0x3F008000);
|
u32 attr = (polygon->Attr & 0x3F008000);
|
||||||
|
|
||||||
// check stencil buffer for shadows
|
// check stencil buffer for shadows
|
||||||
|
@ -1265,7 +1277,7 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
|
||||||
{
|
{
|
||||||
if (!(dstattr & 0x3)) continue;
|
if (!(dstattr & 0x3)) continue;
|
||||||
|
|
||||||
pixeladdr += 258;
|
pixeladdr += BufferSize;
|
||||||
if (!fnDepthTest(DepthBuffer[pixeladdr], z))
|
if (!fnDepthTest(DepthBuffer[pixeladdr], z))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1313,11 +1325,12 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
|
||||||
attr |= (cov << 8);
|
attr |= (cov << 8);
|
||||||
|
|
||||||
// push old pixel down if needed
|
// push old pixel down if needed
|
||||||
// we only need to do it for opaque edge pixels, since
|
if (pixeladdr < BufferSize)
|
||||||
// this only serves for antialiasing
|
{
|
||||||
ColorBuffer[pixeladdr+258] = ColorBuffer[pixeladdr];
|
ColorBuffer[pixeladdr+BufferSize] = ColorBuffer[pixeladdr];
|
||||||
DepthBuffer[pixeladdr+258] = DepthBuffer[pixeladdr];
|
DepthBuffer[pixeladdr+BufferSize] = DepthBuffer[pixeladdr];
|
||||||
AttrBuffer[pixeladdr+258] = AttrBuffer[pixeladdr];
|
AttrBuffer[pixeladdr+BufferSize] = AttrBuffer[pixeladdr];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1359,35 +1372,6 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
|
||||||
rp->XR = rp->SlopeR.Step();
|
rp->XR = rp->SlopeR.Step();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void RenderPolygon(RendererPolygon* rp)
|
|
||||||
{
|
|
||||||
Polygon* polygon = rp->PolyData;
|
|
||||||
int nverts = polygon->NumVertices;
|
|
||||||
bool isline = false;
|
|
||||||
|
|
||||||
int vtop = polygon->VTop, vbot = polygon->VBottom;
|
|
||||||
s32 ytop = polygon->YTop, ybot = polygon->YBottom;
|
|
||||||
s32 xtop = polygon->XTop, xbot = polygon->XBottom;
|
|
||||||
|
|
||||||
if (ytop > 191) return;
|
|
||||||
|
|
||||||
// draw, line per line
|
|
||||||
|
|
||||||
if (ybot > 192) ybot = 192;
|
|
||||||
|
|
||||||
/*if (polygon->ClearStencil)
|
|
||||||
{
|
|
||||||
memset(StencilBuffer, 0, 192*256);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
for (s32 y = ytop; y < ybot; y++)
|
|
||||||
{
|
|
||||||
RenderPolygonScanline(rp, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void RenderScanline(s32 y, int npolys)
|
void RenderScanline(s32 y, int npolys)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < npolys; i++)
|
for (int i = 0; i < npolys; i++)
|
||||||
|
@ -1422,11 +1406,11 @@ void ScanlineFinalPass(s32 y)
|
||||||
u32 fogB = (RenderFogColor >> 9) & 0x3E; if (fogB) fogB++;
|
u32 fogB = (RenderFogColor >> 9) & 0x3E; if (fogB) fogB++;
|
||||||
u32 fogA = (RenderFogColor >> 16) & 0x1F;
|
u32 fogA = (RenderFogColor >> 16) & 0x1F;
|
||||||
|
|
||||||
for (int i = 0; i < 258*2; i+=258)
|
//for (int i = 0; i < 258*2; i+=258)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < 256; x++)
|
for (int x = 0; x < 256; x++)
|
||||||
{
|
{
|
||||||
u32 pixeladdr = 258*3 + 1 + (y*258*3) + i + x;
|
u32 pixeladdr = FirstPixelOffset + (y*ScanlineWidth) + x;
|
||||||
|
|
||||||
u32 attr = AttrBuffer[pixeladdr];
|
u32 attr = AttrBuffer[pixeladdr];
|
||||||
if (!(attr & (1<<15))) continue;
|
if (!(attr & (1<<15))) continue;
|
||||||
|
@ -1539,14 +1523,14 @@ void ClearBuffers()
|
||||||
|
|
||||||
// fill screen borders for edge marking
|
// fill screen borders for edge marking
|
||||||
|
|
||||||
for (int x = 0; x < 258; x++)
|
for (int x = 0; x < ScanlineWidth; x++)
|
||||||
{
|
{
|
||||||
ColorBuffer[x] = 0;
|
ColorBuffer[x] = 0;
|
||||||
DepthBuffer[x] = clearz;
|
DepthBuffer[x] = clearz;
|
||||||
AttrBuffer[x] = polyid;
|
AttrBuffer[x] = polyid;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int x = 258*3; x < 258*3*193; x+=(258*3))
|
for (int x = ScanlineWidth; x < ScanlineWidth*193; x+=ScanlineWidth)
|
||||||
{
|
{
|
||||||
ColorBuffer[x] = 0;
|
ColorBuffer[x] = 0;
|
||||||
DepthBuffer[x] = clearz;
|
DepthBuffer[x] = clearz;
|
||||||
|
@ -1556,7 +1540,7 @@ void ClearBuffers()
|
||||||
AttrBuffer[x+257] = polyid;
|
AttrBuffer[x+257] = polyid;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int x = 258*3*193; x < 258*3*194; x++)
|
for (int x = ScanlineWidth*193; x < ScanlineWidth*194; x++)
|
||||||
{
|
{
|
||||||
ColorBuffer[x] = 0;
|
ColorBuffer[x] = 0;
|
||||||
DepthBuffer[x] = clearz;
|
DepthBuffer[x] = clearz;
|
||||||
|
@ -1570,7 +1554,7 @@ void ClearBuffers()
|
||||||
u8 xoff = (RenderClearAttr2 >> 16) & 0xFF;
|
u8 xoff = (RenderClearAttr2 >> 16) & 0xFF;
|
||||||
u8 yoff = (RenderClearAttr2 >> 24) & 0xFF;
|
u8 yoff = (RenderClearAttr2 >> 24) & 0xFF;
|
||||||
|
|
||||||
for (int y = 0; y < 258*3*192; y+=(258*3))
|
for (int y = 0; y < ScanlineWidth*192; y+=ScanlineWidth)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < 256; x++)
|
for (int x = 0; x < 256; x++)
|
||||||
{
|
{
|
||||||
|
@ -1586,7 +1570,7 @@ void ClearBuffers()
|
||||||
|
|
||||||
u32 z = ((val3 & 0x7FFF) * 0x200) + 0x1FF;
|
u32 z = ((val3 & 0x7FFF) * 0x200) + 0x1FF;
|
||||||
|
|
||||||
u32 pixeladdr = 258*3 + 1 + y + x;
|
u32 pixeladdr = FirstPixelOffset + y + x;
|
||||||
ColorBuffer[pixeladdr] = color;
|
ColorBuffer[pixeladdr] = color;
|
||||||
DepthBuffer[pixeladdr] = z;
|
DepthBuffer[pixeladdr] = z;
|
||||||
AttrBuffer[pixeladdr] = polyid | (val3 & 0x8000);
|
AttrBuffer[pixeladdr] = polyid | (val3 & 0x8000);
|
||||||
|
@ -1608,11 +1592,11 @@ void ClearBuffers()
|
||||||
|
|
||||||
polyid |= (RenderClearAttr1 & 0x8000);
|
polyid |= (RenderClearAttr1 & 0x8000);
|
||||||
|
|
||||||
for (int y = 0; y < 258*3*192; y+=(258*3))
|
for (int y = 0; y < ScanlineWidth*192; y+=ScanlineWidth)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < 256; x++)
|
for (int x = 0; x < 256; x++)
|
||||||
{
|
{
|
||||||
u32 pixeladdr = 258*3 + 1 + y + x;
|
u32 pixeladdr = FirstPixelOffset + y + x;
|
||||||
ColorBuffer[pixeladdr] = color;
|
ColorBuffer[pixeladdr] = color;
|
||||||
DepthBuffer[pixeladdr] = clearz;
|
DepthBuffer[pixeladdr] = clearz;
|
||||||
AttrBuffer[pixeladdr] = polyid;
|
AttrBuffer[pixeladdr] = polyid;
|
||||||
|
@ -1661,7 +1645,7 @@ void VCount144()
|
||||||
Platform::Semaphore_Wait(Sema_RenderDone);
|
Platform::Semaphore_Wait(Sema_RenderDone);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderFrame(Vertex* vertices, Polygon* polygons, int npolys)
|
void RenderFrame()
|
||||||
{
|
{
|
||||||
//ClearBuffers();
|
//ClearBuffers();
|
||||||
//RenderPolygons(false, polygons, npolys);
|
//RenderPolygons(false, polygons, npolys);
|
||||||
|
@ -1692,7 +1676,7 @@ void RequestLine(int line)
|
||||||
|
|
||||||
u32* GetLine(int line)
|
u32* GetLine(int line)
|
||||||
{
|
{
|
||||||
return &ColorBuffer[line * 258*3 + 258*3 + 1];
|
return &ColorBuffer[(line * ScanlineWidth) + FirstPixelOffset];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue