GS: Properly loop when reading 32bit CLUT from offset

This commit is contained in:
refractionpcsx2 2021-10-31 01:11:58 +00:00
parent 3a91a07d51
commit 532d14611c
2 changed files with 11 additions and 5 deletions

View File

@ -315,8 +315,7 @@ void GSClut::Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
{
case PSM_PSMT8:
case PSM_PSMT8H:
clut += (TEX0.CSA & 15) << 4; // disney golf title screen
ReadCLUT_T32_I8(clut, m_buff32);
ReadCLUT_T32_I8(clut, m_buff32, (TEX0.CSA & 15) << 4);
break;
case PSM_PSMT4:
case PSM_PSMT4HL:
@ -508,11 +507,18 @@ __forceinline void GSClut::WriteCLUT_T16_I4_CSM1(const uint16* RESTRICT src, uin
}
}
void GSClut::ReadCLUT_T32_I8(const uint16* RESTRICT clut, uint32* RESTRICT dst)
void GSClut::ReadCLUT_T32_I8(const uint16* RESTRICT clut, uint32* RESTRICT dst, int offset)
{
// Okay this deserves a small explanation
// T32 I8 can address up to 256 colors however the offset can be "more than zero" when reading
// Previously I assumed that it would wrap around the end of the buffer to the beginning
// but it turns out this is incorrect, the address doesn't mirror, it clamps to to the last offset,
// probably though some sort of addressing mechanism then picks the color from the lower 0xF of the requested CLUT entry.
// if we don't do this, the dirt on GTA SA goes transparent and actually cleans the car driving through dirt.
for (int i = 0; i < 256; i += 16)
{
ReadCLUT_T32_I4(&clut[i], &dst[i]);
// Min value + offet or Last CSA * 16 (240)
ReadCLUT_T32_I4(&clut[std::min((i + offset), 240)], &dst[i]);
}
}

View File

@ -78,7 +78,7 @@ class alignas(32) GSClut : public GSAlignedClass<32>
static void WriteCLUT_T32_I4_CSM1(const uint32* RESTRICT src, uint16* RESTRICT clut);
static void WriteCLUT_T16_I8_CSM1(const uint16* RESTRICT src, uint16* RESTRICT clut);
static void WriteCLUT_T16_I4_CSM1(const uint16* RESTRICT src, uint16* RESTRICT clut);
static void ReadCLUT_T32_I8(const uint16* RESTRICT clut, uint32* RESTRICT dst);
static void ReadCLUT_T32_I8(const uint16* RESTRICT clut, uint32* RESTRICT dst, int offset);
static void ReadCLUT_T32_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst);
//static void ReadCLUT_T32_I4(const uint16* RESTRICT clut, uint32* RESTRICT dst32, uint64* RESTRICT dst64);
//static void ReadCLUT_T16_I8(const uint16* RESTRICT clut, uint32* RESTRICT dst);