fog
This commit is contained in:
parent
a63ab24447
commit
6f4d835c7f
|
@ -179,7 +179,7 @@ u16 RenderToonTable[32];
|
|||
u16 RenderEdgeTable[8];
|
||||
|
||||
u32 RenderFogColor, RenderFogOffset;
|
||||
u8 RenderFogDensityTable[32];
|
||||
u8 RenderFogDensityTable[34];
|
||||
|
||||
u32 RenderClearAttr1, RenderClearAttr2;
|
||||
|
||||
|
@ -1815,7 +1815,9 @@ void VBlank()
|
|||
|
||||
RenderFogColor = FogColor;
|
||||
RenderFogOffset = FogOffset;
|
||||
memcpy(RenderFogDensityTable, FogDensityTable, 32);
|
||||
RenderFogDensityTable[0] = FogDensityTable[0];
|
||||
memcpy(&RenderFogDensityTable[1], FogDensityTable, 32);
|
||||
RenderFogDensityTable[33] = FogDensityTable[31];
|
||||
|
||||
RenderClearAttr1 = ClearAttr1;
|
||||
RenderClearAttr2 = ClearAttr2;
|
||||
|
@ -1988,7 +1990,7 @@ void Write8(u32 addr, u8 val)
|
|||
|
||||
if (addr >= 0x04000360 && addr < 0x04000380)
|
||||
{
|
||||
FogDensityTable[addr - 0x04000360] = val;
|
||||
FogDensityTable[addr - 0x04000360] = val & 0x7F;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2031,7 +2033,7 @@ void Write16(u32 addr, u16 val)
|
|||
FogColor = (FogColor & 0xFFFF) | (val << 16);
|
||||
return;
|
||||
case 0x0400035C:
|
||||
FogOffset = val;
|
||||
FogOffset = val & 0x7FFF;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2044,8 +2046,8 @@ void Write16(u32 addr, u16 val)
|
|||
if (addr >= 0x04000360 && addr < 0x04000380)
|
||||
{
|
||||
addr -= 0x04000360;
|
||||
FogDensityTable[addr] = val & 0xFF;
|
||||
FogDensityTable[addr+1] = val >> 8;
|
||||
FogDensityTable[addr] = val & 0x7F;
|
||||
FogDensityTable[addr+1] = (val >> 8) & 0x7F;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2085,7 +2087,7 @@ void Write32(u32 addr, u32 val)
|
|||
FogColor = val;
|
||||
return;
|
||||
case 0x0400035C:
|
||||
FogOffset = val;
|
||||
FogOffset = val & 0x7FFF;
|
||||
return;
|
||||
|
||||
case 0x04000600:
|
||||
|
@ -2129,10 +2131,10 @@ void Write32(u32 addr, u32 val)
|
|||
if (addr >= 0x04000360 && addr < 0x04000380)
|
||||
{
|
||||
addr -= 0x04000360;
|
||||
FogDensityTable[addr] = val & 0xFF;
|
||||
FogDensityTable[addr+1] = (val >> 8) & 0xFF;
|
||||
FogDensityTable[addr+2] = (val >> 16) & 0xFF;
|
||||
FogDensityTable[addr+3] = val >> 24;
|
||||
FogDensityTable[addr] = val & 0x7F;
|
||||
FogDensityTable[addr+1] = (val >> 8) & 0x7F;
|
||||
FogDensityTable[addr+2] = (val >> 16) & 0x7F;
|
||||
FogDensityTable[addr+3] = (val >> 24) & 0x7F;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ extern u16 RenderToonTable[32];
|
|||
extern u16 RenderEdgeTable[8];
|
||||
|
||||
extern u32 RenderFogColor, RenderFogOffset;
|
||||
extern u8 RenderFogDensityTable[32];
|
||||
extern u8 RenderFogDensityTable[34];
|
||||
|
||||
extern u32 RenderClearAttr1, RenderClearAttr2;
|
||||
|
||||
|
|
|
@ -1027,6 +1027,9 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
|
|||
if ((dstattr & 0x7F000000) == (attr & 0x7F000000))
|
||||
continue;
|
||||
|
||||
if (!(dstattr & (1<<15)))
|
||||
attr &= ~(1<<15);
|
||||
|
||||
u32 dstcolor = ColorBuffer[pixeladdr];
|
||||
u32 dstalpha = dstcolor >> 24;
|
||||
|
||||
|
@ -1106,6 +1109,78 @@ void RenderScanline(s32 y, int npolys)
|
|||
if (y >= polygon->YTop && (y < polygon->YBottom || (y == polygon->YTop && polygon->YBottom == polygon->YTop)))
|
||||
RenderPolygonScanline(rp, y);
|
||||
}
|
||||
|
||||
if (RenderDispCnt & (1<<7))
|
||||
{
|
||||
// fog
|
||||
|
||||
// hardware testing shows that the fog step is 0x80000>>SHIFT
|
||||
// basically, the depth values used in GBAtek need to be
|
||||
// multiplied by 0x200 to match Z-buffer values
|
||||
|
||||
bool fogcolor = !(RenderDispCnt & (1<<6));
|
||||
u32 fogshift = (RenderDispCnt >> 8) & 0xF;
|
||||
u32 fogoffset = RenderFogOffset * 0x200;
|
||||
|
||||
u32 fogR = (RenderFogColor << 1) & 0x3E; if (fogR) fogR++;
|
||||
u32 fogG = (RenderFogColor >> 4) & 0x3E; if (fogG) fogG++;
|
||||
u32 fogB = (RenderFogColor >> 9) & 0x3E; if (fogB) fogB++;
|
||||
u32 fogA = (RenderFogColor >> 16) & 0x1F;
|
||||
|
||||
for (int x = 0; x < 256; x++)
|
||||
{
|
||||
u32 pixeladdr = (y*256) + x;
|
||||
|
||||
u32 attr = AttrBuffer[pixeladdr];
|
||||
if (!(attr & (1<<15))) continue;
|
||||
|
||||
u32 z = DepthBuffer[pixeladdr];
|
||||
u32 densityid, densityfrac;
|
||||
if (z < fogoffset)
|
||||
{
|
||||
densityid = 0;
|
||||
densityfrac = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
z = (z - fogoffset) << fogshift;
|
||||
densityid = z >> 19;
|
||||
if (densityid >= 32)
|
||||
{
|
||||
densityid = 32;
|
||||
densityfrac = 0;
|
||||
}
|
||||
else
|
||||
densityfrac = z & 0x7FFFF;
|
||||
}
|
||||
|
||||
// checkme
|
||||
u32 density =
|
||||
((RenderFogDensityTable[densityid] * (0x80000-densityfrac)) +
|
||||
(RenderFogDensityTable[densityid+1] * densityfrac)) >> 19;
|
||||
if (density >= 127) density = 128;
|
||||
|
||||
u32 srccolor = ColorBuffer[pixeladdr];
|
||||
u32 srcR = srccolor & 0x3F;
|
||||
u32 srcG = (srccolor >> 8) & 0x3F;
|
||||
u32 srcB = (srccolor >> 16) & 0x3F;
|
||||
u32 srcA = (srccolor >> 24) & 0x1F;
|
||||
|
||||
if (fogcolor)
|
||||
{
|
||||
srcR = ((fogR * density) + (srcR * (128-density))) >> 7;
|
||||
srcG = ((fogG * density) + (srcG * (128-density))) >> 7;
|
||||
srcB = ((fogB * density) + (srcB * (128-density))) >> 7;
|
||||
}
|
||||
|
||||
if (densityid > 0)
|
||||
srcA = ((fogA * density) + (srcA * (128-density))) >> 7;
|
||||
else
|
||||
srcA = ((0x1F * density) + (srcA * (128-density))) >> 7; // checkme
|
||||
|
||||
ColorBuffer[pixeladdr] = srcR | (srcG << 8) | (srcB << 16) | (srcA << 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClearBuffers()
|
||||
|
|
Loading…
Reference in New Issue