Fix case where we could write off the end of a buffer if texture width == 1 and 4-bit color.

This commit is contained in:
Henrik Rydgård 2022-12-09 23:00:52 +01:00
parent 03433c42ce
commit e59b734b27
3 changed files with 32 additions and 11 deletions

View File

@ -282,7 +282,7 @@ public:
UI::Event OnChoice;
protected:
bool HasTitleBar() const { return false; }
bool HasTitleBar() const override { return false; }
private:
const ContextMenuItem *items_;

View File

@ -1673,7 +1673,9 @@ CheckAlphaResult TextureCacheCommon::DecodeTextureLevel(u8 *out, int outPitch, G
case GE_CMODE_16BIT_ABGR5551:
case GE_CMODE_16BIT_ABGR4444:
{
if (clutAlphaLinear_ && mipmapShareClut && !expandTo32bit) {
// The w > 1 check is to not need a case that handles a single pixel
// in DeIndexTexture4Optimal<u16>.
if (clutAlphaLinear_ && mipmapShareClut && !expandTo32bit && w >= 4) {
// We don't bother with fullalpha here (clutAlphaLinear_)
// Here, reverseColors means the CLUT is already reversed.
if (reverseColors) {

View File

@ -163,22 +163,36 @@ inline void DeIndexTexture4(/*WRITEONLY*/ ClutT *dest, const u8 *indexed, int le
ClutT alphaSum = (ClutT)(-1);
if (nakedIndex) {
for (int i = 0; i < length; i += 2) {
while (length >= 2) {
u8 index = *indexed++;
ClutT color0 = clut[index & 0xf];
ClutT color1 = clut[index >> 4];
dest[i + 0] = color0;
dest[i + 1] = color1;
*dest++ = color0;
*dest++ = color1;
alphaSum &= color0 & color1;
length -= 2;
}
if (length) { // Last pixel. Can really only happen in 1xY textures, but making this work generically.
u8 index = *indexed++;
ClutT color0 = clut[index & 0xf];
*dest = color0;
alphaSum &= color0;
}
} else {
for (int i = 0; i < length; i += 2) {
while (length >= 2) {
u8 index = *indexed++;
ClutT color0 = clut[gstate.transformClutIndex((index >> 0) & 0xf)];
ClutT color1 = clut[gstate.transformClutIndex((index >> 4) & 0xf)];
dest[i + 0] = color0;
dest[i + 1] = color1;
*dest++ = color0;
*dest++ = color1;
alphaSum &= color0 & color1;
length -= 2;
}
if (length) {
u8 index = *indexed++;
ClutT color0 = clut[gstate.transformClutIndex((index >> 0) & 0xf)];
*dest = color0;
alphaSum &= color0;
}
}
@ -187,10 +201,15 @@ inline void DeIndexTexture4(/*WRITEONLY*/ ClutT *dest, const u8 *indexed, int le
template <typename ClutT>
inline void DeIndexTexture4Optimal(ClutT *dest, const u8 *indexed, int length, ClutT color) {
for (int i = 0; i < length; i += 2) {
while (length >= 2) {
u8 index = *indexed++;
dest[i + 0] = color | ((index >> 0) & 0xf);
dest[i + 1] = color | ((index >> 4) & 0xf);
*dest++ = color | ((index >> 0) & 0xf);
*dest++ = color | ((index >> 4) & 0xf);
length -= 2;
}
if (length) {
u8 index = *indexed++;
*dest++ = color | ((index >> 0) & 0xf);
}
}