fix handling of invalid viewports. solves homie rollerz character select. only implemented in softrasterizer. re #27
This commit is contained in:
parent
8dd7c9b924
commit
e02d134482
|
@ -1749,10 +1749,21 @@ static void gfx3d_glVecTest(u32 v)
|
|||
|
||||
void VIEWPORT::decode(const u32 v)
|
||||
{
|
||||
this->x = (v & 0xFF);
|
||||
this->y = std::min<u8>(191, (v >> 8) & 0xFF);
|
||||
this->width = ((v >> 16) & 0xFF) + 1 - this->x;
|
||||
this->height = std::min<u8>(191, (v >> 24) & 0xFF) + 1 - this->y;
|
||||
//test: homie rollerz character select chooses nonsense for Y. they did the math backwards. their goal was a fullscreen viewport, they just messed up.
|
||||
//they also messed up the width...
|
||||
|
||||
u8 x1 = (v>> 0)&0xFF;
|
||||
u8 y1 = (v>> 8)&0xFF;
|
||||
u8 x2 = (v>>16)&0xFF;
|
||||
u8 y2 = (v>>24)&0xFF;
|
||||
|
||||
//I'm 100% sure this is basically 99% correct
|
||||
//the modular math is right. the details of how the +1 is handled may be wrong (this might should be dealt with in the viewport transformation instead)
|
||||
//Its an off by one error in any event so we may never know
|
||||
width = (u8)(x2-x1)+1;
|
||||
height = (u8)(y2-y1)+1;
|
||||
x = x1;
|
||||
y = y1;
|
||||
}
|
||||
|
||||
void gfx3d_glFogColor(u32 v)
|
||||
|
|
|
@ -1519,11 +1519,22 @@ template<bool CUSTOM> void SoftRasterizerRenderer::performViewportTransforms()
|
|||
vert.coord[1] *= viewport.height * yfactor;
|
||||
vert.coord[1] += viewport.y * yfactor;
|
||||
vert.coord[1] = ymax - vert.coord[1];
|
||||
|
||||
//this is required to fix Homie Rollerz character select.
|
||||
//this was also a better fix for Princess Debut's giant out of range polys.
|
||||
//Basically, invalid viewports are blithely used here, and the math overflows and wraps around
|
||||
//NOTE: this is a crude approximation of the correct fixed point modular arithmetic
|
||||
if(vert.coord[0] >= 256) vert.coord[0] -= 256;
|
||||
if(vert.coord[1] >= 256) vert.coord[1] -= 256;
|
||||
if(vert.coord[0] < 0) vert.coord[0] += 256;
|
||||
if(vert.coord[1] < 0) vert.coord[1] += 256;
|
||||
|
||||
//well, i guess we need to do this to keep Princess Debut from rendering huge polys.
|
||||
//there must be something strange going on
|
||||
vert.coord[0] = max(0.0f,min(xmax,vert.coord[0]));
|
||||
vert.coord[1] = max(0.0f,min(ymax,vert.coord[1]));
|
||||
//now, this is really lame. probably the rasterizer should be dealing with this, but
|
||||
//1. its easier here
|
||||
//2. its more likely reusable in opengl this way (well, this is a bunch more calculations that should be earlier in the pipeline and obligatorily shared)
|
||||
//I do have some evidence that this wrecks the hardware extremely, but nothing's likely to use that effect.
|
||||
//This is a sanity check only.
|
||||
if(vert.coord[1] >= 192) vert.coord[1] = 192;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue