Skip to content

Commit 80d1bb1

Browse files
GS: Add special case CSM2 read for Breath of Fire Dragon Quarter
1 parent eb5e3fc commit 80d1bb1

2 files changed

Lines changed: 31 additions & 1 deletion

File tree

pcsx2/GS/GSClut.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,9 +383,16 @@ void GSClut::Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
383383
case PSMT4:
384384
case PSMT4HL:
385385
case PSMT4HH:
386+
386387
clut += (TEX0.CSA & 15) << 4;
387388
// TODO: merge these functions
388-
ReadCLUT_T32_I4(clut, m_buff32);
389+
390+
// This is for a situation with Breath of Fire Dragon Quarter where it reinterprets the buffer under CSM2 after reading as CSM1.
391+
if (TEX0.CSM == 1 && m_write.TEX0.CSM == 0)
392+
ReadCLUT_T32_I4_Swizzled(clut, m_buff32);
393+
else
394+
ReadCLUT_T32_I4(clut, m_buff32);
395+
389396
ExpandCLUT64_T32_I8(m_buff32, (u64*)m_buff64); // sw renderer does not need m_buff64 anymore
390397
break;
391398
}
@@ -632,6 +639,28 @@ __forceinline void GSClut::WriteCLUT_T16_I4_CSM1(const u16* RESTRICT src, u16* R
632639
}
633640
}
634641

642+
// These functions are only used if the CLUT is in 32bit mode and it swaps to CSM2, a very obscure setup used by Breath of Fire Dragon Quarter.
643+
// This doesn't handle offsetting the CLUT or anything crazy, that would be a lot more work
644+
void GSClut::ReadCLUT_T32_I4_Swizzled(const u16* RESTRICT clut, u32* RESTRICT dst)
645+
{
646+
// Point to the base of the palette block
647+
GSVector4i* s = (GSVector4i*)clut;
648+
GSVector4i* d = (GSVector4i*)dst;
649+
650+
GSVector4i v0 = s[0];
651+
GSVector4i v1 = s[2];
652+
GSVector4i v2 = s[32];
653+
GSVector4i v3 = s[34];
654+
655+
GSVector4i::sw16(v0, v2, v1, v3);
656+
657+
d[0] = v0;
658+
d[1] = v1;
659+
d[2] = v2;
660+
d[3] = v3;
661+
}
662+
663+
635664
void GSClut::ReadCLUT_T32_I8(const u16* RESTRICT clut, u32* RESTRICT dst, int offset)
636665
{
637666
// Okay this deserves a small explanation

pcsx2/GS/GSClut.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class alignas(32) GSClut final : public GSAlignedClass<32>
7878
static void WriteCLUT_T32_I4_CSM1(const u32* RESTRICT src, u16* RESTRICT clut);
7979
static void WriteCLUT_T16_I8_CSM1(const u16* RESTRICT src, u16* RESTRICT clut);
8080
static void WriteCLUT_T16_I4_CSM1(const u16* RESTRICT src, u16* RESTRICT clut);
81+
static void ReadCLUT_T32_I4_Swizzled(const u16* RESTRICT clut, u32* RESTRICT dst);
8182
static void ReadCLUT_T32_I8(const u16* RESTRICT clut, u32* RESTRICT dst, int offset);
8283
static void ReadCLUT_T32_I4(const u16* RESTRICT clut, u32* RESTRICT dst);
8384
//static void ReadCLUT_T32_I4(const u16* RESTRICT clut, u32* RESTRICT dst32, u64* RESTRICT dst64);

0 commit comments

Comments
 (0)