mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Compare stencil correctly based on bitdepth.
All sorts of funny rules. See comments here: https://github.com/hrydgard/ppsspp/pull/4150
This commit is contained in:
parent
82c56dccff
commit
c1897b9e54
1 changed files with 43 additions and 7 deletions
|
@ -317,7 +317,7 @@ static inline void SetPixelDepth(int x, int y, u16 value)
|
|||
static inline u8 GetPixelStencil(int x, int y)
|
||||
{
|
||||
if (gstate.FrameBufFormat() == GE_FORMAT_565) {
|
||||
// TODO: Should we return 0xFF instead here?
|
||||
// Always treated as 0 for comparison purposes.
|
||||
return 0;
|
||||
} else if (gstate.FrameBufFormat() == GE_FORMAT_5551) {
|
||||
return ((fb.Get16(x, y, gstate.FrameBufStride()) & 0x8000) != 0) ? 0xFF : 0;
|
||||
|
@ -399,6 +399,17 @@ static inline bool IsRightSideOrFlatBottomLine(const Vec2<u10>& vertex, const Ve
|
|||
|
||||
static inline bool StencilTestPassed(u8 stencil)
|
||||
{
|
||||
switch (gstate.FrameBufFormat()) {
|
||||
case GE_FORMAT_4444:
|
||||
// For comparison purposes, 0x1 is treated as 0x11 (0x10 is less, 0x12 is more.)
|
||||
// This is not true for updates to the value, e.g. GE_STENCILOP_INCR.
|
||||
stencil = Convert4To8(stencil);
|
||||
break;
|
||||
default:
|
||||
// Every other case is already okay (5551 is 0 or 0xff.)
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: Does the masking logic make any sense?
|
||||
stencil &= gstate.getStencilTestMask();
|
||||
u8 ref = gstate.getStencilTestRef() & gstate.getStencilTestMask();
|
||||
|
@ -444,7 +455,21 @@ static inline void ApplyStencilOp(int op, int x, int y)
|
|||
return;
|
||||
|
||||
case GE_STENCILOP_REPLACE:
|
||||
SetPixelStencil(x, y, reference_stencil);
|
||||
switch (gstate.FrameBufFormat()) {
|
||||
case GE_FORMAT_8888:
|
||||
SetPixelStencil(x, y, reference_stencil);
|
||||
break;
|
||||
case GE_FORMAT_4444:
|
||||
// Replace with the top 4 bits only.
|
||||
SetPixelStencil(x, y, reference_stencil >> 4);
|
||||
break;
|
||||
case GE_FORMAT_5551:
|
||||
// Replace with the value of the top bit only.
|
||||
SetPixelStencil(x, y, reference_stencil >> 7);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case GE_STENCILOP_INVERT:
|
||||
|
@ -452,15 +477,26 @@ static inline void ApplyStencilOp(int op, int x, int y)
|
|||
break;
|
||||
|
||||
case GE_STENCILOP_INCR:
|
||||
// TODO: Does this overflow?
|
||||
if (old_stencil != 0xFF)
|
||||
SetPixelStencil(x, y, old_stencil+1);
|
||||
switch (gstate.FrameBufFormat()) {
|
||||
case GE_FORMAT_8888:
|
||||
case GE_FORMAT_5551:
|
||||
if (old_stencil != 0xFF) {
|
||||
SetPixelStencil(x, y, old_stencil + 1);
|
||||
}
|
||||
break;
|
||||
case GE_FORMAT_4444:
|
||||
if (old_stencil != 0xF) {
|
||||
SetPixelStencil(x, y, old_stencil + 1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case GE_STENCILOP_DECR:
|
||||
// TODO: Does this underflow?
|
||||
if (old_stencil != 0)
|
||||
SetPixelStencil(x, y, old_stencil-1);
|
||||
SetPixelStencil(x, y, old_stencil - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue