[Scummvm-git-logs] scummvm master -> 71a581288edaa803cd6f63441e43d38f2f564584

sev- noreply at scummvm.org
Sat May 9 21:55:28 UTC 2026


This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .

Summary:
adc8f111af PSP: Remove old pixel format conversion code for now
4549a485b1 PSP: Use Graphics::crossBlit for converting the cursor
90a0bdefd0 PSP: Use Graphics::crossBlit for converting the game screen
fe1bc90297 PSP: List more formats in DisplayManager::getSupportedPixelFormats()
71a581288e GRAPHICS Add a fast path for RGB565<->BGR565 conversion


Commit: adc8f111afff47055235b4d00c0a47c56b567bd1
    https://github.com/scummvm/scummvm/commit/adc8f111afff47055235b4d00c0a47c56b567bd1
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2026-05-09T23:55:23+02:00

Commit Message:
PSP: Remove old pixel format conversion code for now

Changed paths:
    backends/platform/psp/cursor.cpp
    backends/platform/psp/default_display_client.cpp
    backends/platform/psp/display_client.cpp
    backends/platform/psp/display_client.h
    backends/platform/psp/memory.cpp
    backends/platform/psp/memory.h
    backends/platform/psp/psppixelformat.cpp
    backends/platform/psp/psppixelformat.h
    backends/platform/psp/tests.cpp


diff --git a/backends/platform/psp/cursor.cpp b/backends/platform/psp/cursor.cpp
index 8cc4104d1e3..b74a7177338 100644
--- a/backends/platform/psp/cursor.cpp
+++ b/backends/platform/psp/cursor.cpp
@@ -221,10 +221,9 @@ void Cursor::setScreenPaletteScummvmPixelFormat(const Graphics::PixelFormat *for
 
 	PSPPixelFormat::Type bufferType = PSPPixelFormat::Type_Unknown;
 	PSPPixelFormat::Type paletteType = PSPPixelFormat::Type_Unknown;
-	bool swapRedBlue = false;
 
 	// Convert Scummvm Pixel Format to PSPPixelFormat
-	PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferType, paletteType, swapRedBlue);
+	PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferType, paletteType);
 
 	if (paletteType == PSPPixelFormat::Type_None) {
 		//_screenPalette.deallocate();		// leave palette for default CLUT8
@@ -251,9 +250,8 @@ void Cursor::setSizeAndScummvmPixelFormat(uint32 width, uint32 height, const Gra
 
 	PSPPixelFormat::Type bufferType = PSPPixelFormat::Type_Unknown;
 	PSPPixelFormat::Type paletteType = PSPPixelFormat::Type_Unknown;
-	bool swapRedBlue = false;
 
-	PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferType, paletteType, swapRedBlue);
+	PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferType, paletteType);
 	PSP_DEBUG_PRINT("bufferType[%u], paletteType[%u]\n", bufferType, paletteType);
 
 	// Check if we need to set new pixel format
diff --git a/backends/platform/psp/default_display_client.cpp b/backends/platform/psp/default_display_client.cpp
index 81b05804314..656a416da50 100644
--- a/backends/platform/psp/default_display_client.cpp
+++ b/backends/platform/psp/default_display_client.cpp
@@ -182,11 +182,10 @@ void Screen::setScummvmPixelFormat(const Graphics::PixelFormat *format) {
 	}
 
 	PSPPixelFormat::Type bufferFormat, paletteFormat;
-	bool swapRedBlue = false;
 
-	PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferFormat, paletteFormat, swapRedBlue);
-	_buffer.setPixelFormat(bufferFormat, swapRedBlue);
-	_palette.setPixelFormats(paletteFormat, bufferFormat, swapRedBlue);
+	PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferFormat, paletteFormat);
+	_buffer.setPixelFormat(bufferFormat);
+	_palette.setPixelFormats(paletteFormat, bufferFormat);
 }
 
 Graphics::Surface *Screen::lockAndGetForEditing() {
diff --git a/backends/platform/psp/display_client.cpp b/backends/platform/psp/display_client.cpp
index d52d3eace34..d4ef07fa610 100644
--- a/backends/platform/psp/display_client.cpp
+++ b/backends/platform/psp/display_client.cpp
@@ -42,7 +42,6 @@
 #include "backends/platform/psp/psppixelformat.h"
 #include "backends/platform/psp/display_client.h"
 #include "backends/platform/psp/display_manager.h"
-#define PSP_INCLUDE_SWAP
 #include "backends/platform/psp/memory.h"
 
 //#define __PSP_DEBUG_FUNCS__	/* For debugging the stack */
@@ -137,7 +136,7 @@ void Palette::setPartial(const byte *colors, uint start, uint num, bool supports
 }
 
 // Sets pixel format and number of entries by the buffer's pixel format */
-void Palette::setPixelFormats(PSPPixelFormat::Type paletteType, PSPPixelFormat::Type bufferType, bool swapRedBlue /* = false */) {
+void Palette::setPixelFormats(PSPPixelFormat::Type paletteType, PSPPixelFormat::Type bufferType) {
 	DEBUG_ENTER_FUNC();
 
 	if (paletteType == PSPPixelFormat::Type_Unknown)
@@ -159,7 +158,7 @@ void Palette::setPixelFormats(PSPPixelFormat::Type paletteType, PSPPixelFormat::
 		break;
 	}
 
-	_pixelFormat.set(paletteType, swapRedBlue);
+	_pixelFormat.set(paletteType);
 }
 
 bool Palette::allocate() {
@@ -300,12 +299,12 @@ uint32 Palette::getRGBAColorAt(uint32 position) const {
 
 // class Buffer ---------------------------------------------------
 
-void Buffer::setPixelFormat(PSPPixelFormat::Type type, bool swapRedBlue) {
+void Buffer::setPixelFormat(PSPPixelFormat::Type type) {
 	if (type == PSPPixelFormat::Type_None ||
 	        type == PSPPixelFormat::Type_Unknown)
 		PSP_ERROR("Unhandled buffer format[%u]\n", type);
 
-	_pixelFormat.set(type, swapRedBlue);
+	_pixelFormat.set(type);
 }
 
 bool Buffer::hasPalette() {
@@ -349,16 +348,10 @@ void Buffer::copyFromRect(const byte *buf, uint32 pitch, int destX, int destY, u
 
 	if (pitch == realWidthInBytes && pitch == recWidthInBytes) {
 		//memcpy(dst, buf, _pixelFormat.pixelsToBytes(recHeight * recWidth));
-		if (_pixelFormat.swapRB)
-			PspMemorySwap::fastSwap(dst, buf, _pixelFormat.pixelsToBytes(recHeight * recWidth), _pixelFormat);
-		else
-			PspMemory::fastCopy(dst, buf, _pixelFormat.pixelsToBytes(recHeight * recWidth));
+		PspMemory::fastCopy(dst, buf, _pixelFormat.pixelsToBytes(recHeight * recWidth));
 	} else {
 		do {
-			if (_pixelFormat.swapRB)
-				PspMemorySwap::fastSwap(dst, buf, recWidthInBytes, _pixelFormat);
-			else
-				PspMemory::fastCopy(dst, buf, recWidthInBytes);
+			PspMemory::fastCopy(dst, buf, recWidthInBytes);
 			buf += pitch;
 			dst += realWidthInBytes;
 		} while (--recHeight);
@@ -377,10 +370,7 @@ void Buffer::copyToArray(byte *dst, int pitch) {
 
 	do {
 		//memcpy(dst, src, sourceWidthInBytes);
-		if (_pixelFormat.swapRB)
-			PspMemorySwap::fastSwap(dst, src, sourceWidthInBytes, _pixelFormat);
-		else
-			PspMemory::fastCopy(dst, src, sourceWidthInBytes);
+		PspMemory::fastCopy(dst, src, sourceWidthInBytes);
 		src += realWidthInBytes;
 		dst += pitch;
 	} while (--h);
@@ -639,7 +629,6 @@ inline uint32 GuRenderer::convertToGuPixelFormat(PSPPixelFormat::Type format) {
 		guFormat = GU_PSM_5650;
 		break;
 	case PSPPixelFormat::Type_8888:
-	case PSPPixelFormat::Type_8888_RGBA:
 		guFormat = GU_PSM_8888;
 		break;
 	case PSPPixelFormat::Type_Palette_8bit:
diff --git a/backends/platform/psp/display_client.h b/backends/platform/psp/display_client.h
index 87a87ca5c1b..2b17ed0044b 100644
--- a/backends/platform/psp/display_client.h
+++ b/backends/platform/psp/display_client.h
@@ -82,7 +82,7 @@ public:
 	bool allocate();
 	void deallocate();
 	void clear();
-	void setPixelFormats(PSPPixelFormat::Type paletteType, PSPPixelFormat::Type bufferType, bool swapRedBlue = false);
+	void setPixelFormats(PSPPixelFormat::Type paletteType, PSPPixelFormat::Type bufferType);
 	void setNumOfEntries(uint32 num) {	_numOfEntries = num; }
 	uint32 getNumOfEntries() const { return _numOfEntries; }
 	uint32 getSizeInBytes() const { return _pixelFormat.pixelsToBytes(_numOfEntries); }
@@ -124,7 +124,7 @@ public:
 	void setSize(uint32 width, uint32 height, HowToSize textureOrSource = kSizeByTextureSize);
 	void setBitsPerPixel(uint32 bits) { _pixelFormat.bitsPerPixel = bits; }
 	void setBytesPerPixel(uint32 bytes) { setBitsPerPixel(bytes << 3); }
-	void setPixelFormat(PSPPixelFormat::Type type, bool swapRedBlue = false);
+	void setPixelFormat(PSPPixelFormat::Type type);
 
 	// getters
 	uint32 getWidth() const { return _width; }
diff --git a/backends/platform/psp/memory.cpp b/backends/platform/psp/memory.cpp
index 273390793c5..e43b5719198 100644
--- a/backends/platform/psp/memory.cpp
+++ b/backends/platform/psp/memory.cpp
@@ -22,7 +22,6 @@
 #include "common/scummsys.h"
 #include "common/singleton.h"
 #include "backends/platform/psp/psppixelformat.h"
-#define PSP_INCLUDE_SWAP
 #include "backends/platform/psp/memory.h"
 
 // Class Copier --------------------------------------------------------------------------
@@ -245,159 +244,3 @@ void PspMemory::testCopy(const byte *debugDst, const byte *debugSrc, uint32 debu
 	}
 }
 
-//
-// used to swap red and blue
-void PspMemorySwap::swap(uint16 *dst16, const uint16 *src16, uint32 bytes, PSPPixelFormat &format) {
-	DEBUG_ENTER_FUNC();
-
-#ifdef TEST_MEMORY_COPY
-	uint32 debugBytes = bytes;
-	const uint16 *debugDst = dst16, *debugSrc = src16;
-#endif
-
-	// align the destination pointer first
-	uint32 prefixDst = (((uint32)dst16) & 0x3);	// for swap, we can only have 2 or 0 as our prefix
-
-	if (prefixDst) {
-		bytes -= prefixDst;						// remember we assume bytes > 4
-		*dst16++ = format.swapRedBlue16(*src16++);
-
-		if (bytes < MIN_AMOUNT_FOR_COMPLEX_COPY) { // check if it's worthwhile to continue
-			swap16(dst16, src16, bytes, format);
-
-#ifdef TEST_MEMORY_COPY
-			testSwap(debugDst, debugSrc, debugBytes, format);
-#endif
-			return;
-		}
-	}
-
-	// check the source pointer alignment now
-	uint32 alignSrc = (((uint32)src16) & 0x3);
-
-	if (alignSrc) {						// we'll need to realign our reads
-		PSP_DEBUG_PRINT("misaligned copy of %u bytes from %p to %p\n", bytes, src16, dst16);
-		swap32Misaligned((uint32 *)dst16, src16, bytes, format);
-	} else {
-		swap32Aligned((uint32 *)dst16, (const uint32 *)src16, bytes, format);
-	}
-
-#ifdef TEST_MEMORY_COPY
-	testSwap(debugDst, debugSrc, debugBytes, format);
-#endif
-
-}
-
-void PspMemorySwap::testSwap(const uint16 *debugDst, const uint16 *debugSrc, uint32 debugBytes, PSPPixelFormat &format) {
-
-	bool mismatch = false;
-	PSP_INFO_PRINT("testing fastSwap...");
-
-	uint32 shorts = debugBytes >> 1;
-
-	for (uint32 i = 0; i < shorts; i++) {
-		if (debugDst[i] != format.swapRedBlue16(debugSrc[i])) {
-			if (!mismatch) {
-				PSP_INFO_PRINT("**** mismatch in swap! ****\n");
-				PSP_INFO_PRINT("dst[%p], src[%p], bytes[%u]\n", debugDst, debugSrc, debugBytes);
-				mismatch = true;
-			}
-			PSP_INFO_PRINT("[%d]%x!=%x ", i<<1, format.swapRedBlue16(debugSrc[i]), debugDst[i]);
-		}
-	}
-	if (mismatch) {
-		PSP_INFO_PRINT("\n");
-	} else {
-		PSP_INFO_PRINT("ok\n");
-	}
-}
-
-void PspMemorySwap::swap32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes, PSPPixelFormat &format) {
-	DEBUG_ENTER_FUNC();
-	int words4 = bytes >> 4;
-
-	// try blocks of 4 words at a time
-	while (words4--) {
-		uint32 a, b, c, d;
-		a = format.swapRedBlue32(src32[0]);
-		b = format.swapRedBlue32(src32[1]);
-		c = format.swapRedBlue32(src32[2]);
-		d = format.swapRedBlue32(src32[3]);
-		dst32[0] = a;
-		dst32[1] = b;
-		dst32[2] = c;
-		dst32[3] = d;
-		dst32 += 4;
-		src32 += 4;
-	}
-
-	uint32 bytesLeft = bytes & 0xF;
-	uint32 words = bytesLeft >> 2;
-
-	// now just do words
-	while (words--) {
-		*dst32++ = format.swapRedBlue32(*src32++);
-	}
-
-	bytesLeft = bytes & 0x3;
-
-	if (bytesLeft) {	// for swap, can only be 1 short left
-		*((uint16 *)dst32) = format.swapRedBlue16(*((const uint16 *)src32));
-	}
-}
-
-// More challenging -- need to shift
-// We assume dst is aligned
-void PspMemorySwap::swap32Misaligned(uint32 *dst32, const uint16 *src16, uint32 bytes, PSPPixelFormat &format) {
-	DEBUG_ENTER_FUNC();
-
-	const uint32 shiftValue = 16;
-	uint32 *src32 = (uint32 *)(((uint32)src16) & 0xFFFFFFFC);	// remove misalignment
-
-	// Try to do groups of 4 words
-	uint32 words4 = bytes >> 4;
-	uint32 srcWord = src32[0];	// preload
-
-	while (words4--) {
-		uint32 dstWord = srcWord >> shiftValue;
-		srcWord = src32[1];
-		dstWord |= srcWord << shiftValue;
-		dst32[0] = format.swapRedBlue32(dstWord);
-		dstWord = srcWord >> shiftValue;
-		srcWord = src32[2];
-		dstWord |= srcWord << shiftValue;
-		dst32[1] = format.swapRedBlue32(dstWord);
-		dstWord = srcWord >> shiftValue;
-		srcWord = src32[3];
-		dstWord |= srcWord << shiftValue;
-		dst32[2] = format.swapRedBlue32(dstWord);
-		dstWord = srcWord >> shiftValue;
-		srcWord = src32[4];
-		dstWord |= srcWord << shiftValue;
-		dst32[3] = format.swapRedBlue32(dstWord);
-		src32 += 4;
-		dst32 += 4;
-	}
-
-	uint32 words = (bytes & 0xF) >> 2;
-
-	// we read one word ahead of what we write
-	// setup the first read
-	if (words) {
-		//srcWord = *src32++;	// don't need this. already loaded
-		src32++;	// we already have the value loaded in
-
-		while (words--) {
-			uint32 dstWord = srcWord >> shiftValue;
-			srcWord = *src32++;
-			dstWord |= srcWord << shiftValue;
-			*dst32++ = format.swapRedBlue32(dstWord);
-		}
-	}
-
-	uint32 bytesLeft = bytes & 3;
-
-	if (bytesLeft) {	// for swap, can only be 1 short left
-		*((uint16 *)dst32) = format.swapRedBlue16((uint16)(srcWord >> shiftValue));
-	}
-}
diff --git a/backends/platform/psp/memory.h b/backends/platform/psp/memory.h
index ed851461db7..5c7da4558f4 100644
--- a/backends/platform/psp/memory.h
+++ b/backends/platform/psp/memory.h
@@ -88,36 +88,3 @@ inline void *psp_memcpy(void *dst, const void *src, int32 bytes) {
 }
 
 #endif /* PSP_MEMORY_H */
-
-#if defined(PSP_INCLUDE_SWAP) && !defined(PSP_MEMORY_SWAP_H)
-#define PSP_MEMORY_SWAP_H
-
-//#include "backends/platform/psp/psppixelformat.h"
-
-class PspMemorySwap {
-private:
-	static void testSwap(const uint16 *debugDst, const uint16 *debugSrc, uint32 debugBytes, PSPPixelFormat &format);
-	static void swap(uint16 *dst16, const uint16 *src16, uint32 bytes, PSPPixelFormat &format);
-	static void swap32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes, PSPPixelFormat &format);
-	static void swap32Misaligned(uint32 *dst32, const uint16 *src16, uint32 bytes, PSPPixelFormat &format);
-	// For swapping, we know that we have multiples of 16 bits
-	static void swap16(uint16 *dst16, const uint16 *src16, uint32 bytes, PSPPixelFormat &format) {
-		PSP_DEBUG_PRINT("swap16 called with dst16[%p], src16[%p], bytes[%d]\n", dst16, src16, bytes);
-		uint32 shorts = bytes >> 1;
-
-		while (shorts--) {
-			*dst16++ = format.swapRedBlue16(*src16++);
-		}
-	}
-
-public:
-	static void fastSwap(byte *dst, const byte *src, uint32 bytes, PSPPixelFormat &format) {
-		if (bytes < MIN_AMOUNT_FOR_COMPLEX_COPY * 2) {
-			swap16((uint16 *)dst, (const uint16 *)src, bytes, format);
-		} else {	// go to more powerful copy
-			swap((uint16 *)dst, (const uint16 *)src, bytes, format);
-		}
-	}
-};
-
-#endif /* PSP_INCLUDE_SWAP */
diff --git a/backends/platform/psp/psppixelformat.cpp b/backends/platform/psp/psppixelformat.cpp
index 777c04decf9..8c6c48f6366 100644
--- a/backends/platform/psp/psppixelformat.cpp
+++ b/backends/platform/psp/psppixelformat.cpp
@@ -29,12 +29,11 @@
 
 // class PSPPixelFormat --------------------------------------
 
-void PSPPixelFormat::set(Type type, bool swap /* = false */) {
+void PSPPixelFormat::set(Type type) {
 	DEBUG_ENTER_FUNC();
 	PSP_DEBUG_PRINT("type = %d\n", type);
 
 	format = type;
-	swapRB = swap;
 
 	switch (type) {
 	case Type_4444:
@@ -43,7 +42,6 @@ void PSPPixelFormat::set(Type type, bool swap /* = false */) {
 		bitsPerPixel = 16;
 		break;
 	case Type_8888:
-	case Type_8888_RGBA:
 		bitsPerPixel = 32;
 		break;
 	case Type_Palette_8bit:
@@ -68,9 +66,7 @@ void PSPPixelFormat::set(Type type, bool swap /* = false */) {
 // For buffer and palette.
 void PSPPixelFormat::convertFromScummvmPixelFormat(const Graphics::PixelFormat *pf,
 		PSPPixelFormat::Type &bufferType,
-		PSPPixelFormat::Type &paletteType,
-		bool &swapRedBlue) {
-	swapRedBlue = false;	 // no red-blue swap by default
+		PSPPixelFormat::Type &paletteType) {
 	PSPPixelFormat::Type *target = nullptr;	// which one we'll be filling
 
 	if (!pf) {	// Default, pf is NULL
@@ -97,10 +93,8 @@ void PSPPixelFormat::convertFromScummvmPixelFormat(const Graphics::PixelFormat *
 				*target = Type_5650;
 		} else if (pf->rLoss == 4 && pf->gLoss == 4 && pf->bLoss == 4) {
 			*target = Type_4444;
-		} else if (pf->gLoss == 0 && pf->gShift == 8) {
+		} else if (pf->rLoss == 0 && pf->gLoss == 0 && pf->bLoss == 0) {
 			*target = Type_8888;
-		} else if (pf->gLoss == 0 && pf->gShift == 16) {
-			*target = Type_8888_RGBA;
 		} else if ((pf->gLoss == 0 && pf->gShift == 0) ||
 		           (pf->gLoss == 8 && pf->gShift == 0)) {	// Default CLUT8 can have weird values
 			*target = Type_5551;
@@ -111,11 +105,6 @@ void PSPPixelFormat::convertFromScummvmPixelFormat(const Graphics::PixelFormat *
 			          pf->rShift, pf->gShift, pf->bShift, pf->aShift);
 			*target = Type_Unknown;
 		}
-
-		if (pf->rShift != 0)	{// We allow backend swap of red and blue
-			swapRedBlue = true;
-			PSP_DEBUG_PRINT("detected red/blue swap\n");
-		}
 	}
 }
 
@@ -157,7 +146,6 @@ Graphics::PixelFormat PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat
 		pf.bShift = 11;
 		break;
 	case Type_8888:
-	case Type_8888_RGBA:
 		pf.bytesPerPixel = 4;
 		pf.aLoss = 0;
 		pf.rLoss = 0;
diff --git a/backends/platform/psp/psppixelformat.h b/backends/platform/psp/psppixelformat.h
index 83cd8f681c2..96ccccbaa19 100644
--- a/backends/platform/psp/psppixelformat.h
+++ b/backends/platform/psp/psppixelformat.h
@@ -38,7 +38,6 @@ struct PSPPixelFormat {
 		Type_5551,
 		Type_5650,
 		Type_8888,
-		Type_8888_RGBA,
 		Type_Palette_8bit,
 		Type_Palette_4bit,
 		Type_Unknown
@@ -46,14 +45,12 @@ struct PSPPixelFormat {
 
 	Type format;
 	uint32 bitsPerPixel;					///< Must match bpp of selected type
-	bool swapRB;							///< Swap red and blue values when reading and writing
 
-	PSPPixelFormat() : format(Type_Unknown), bitsPerPixel(0), swapRB(false) {}
-	void set(Type type, bool swap = false);
+	PSPPixelFormat() : format(Type_Unknown), bitsPerPixel(0) {}
+	void set(Type type);
 	static void convertFromScummvmPixelFormat(const Graphics::PixelFormat *pf,
 	        PSPPixelFormat::Type &bufferType,
-	        PSPPixelFormat::Type &paletteType,
-	        bool &swapRedBlue);
+	        PSPPixelFormat::Type &paletteType);
 	static Graphics::PixelFormat convertToScummvmPixelFormat(PSPPixelFormat::Type type);
 	uint32 convertTo32BitColor(uint32 color) const;
 
@@ -71,7 +68,6 @@ struct PSPPixelFormat {
 			color = (((b >> 3) << 11) | ((g >> 2) << 5) | ((r >> 3) << 0));
 			break;
 		case Type_8888:
-		case Type_8888_RGBA:
 			color = (((b >> 0) << 16) | ((g >> 0) << 8) | ((r >> 0) << 0) | ((a >> 0) << 24));
 			break;
 		default:
@@ -112,7 +108,6 @@ struct PSPPixelFormat {
 			r = r << 3 | r >> 2;
 			break;
 		case Type_8888:
-		case Type_8888_RGBA:
 			a = (color >> 24) & 0xFF;
 			b = (color >> 16) & 0xFF;
 			g = (color >> 8)  & 0xFF;
@@ -133,7 +128,6 @@ struct PSPPixelFormat {
 			color = (color & 0x7FFF) | (((uint32)alpha >> 7) << 15);
 			break;
 		case Type_8888:
-		case Type_8888_RGBA:
 			color = (color & 0x00FFFFFF) | ((uint32)alpha << 24);
 			break;
 		case Type_5650:
@@ -163,60 +157,6 @@ struct PSPPixelFormat {
 		return pixels;
 	}
 
-	inline uint16 swapRedBlue16(uint16 color) const {
-		uint16 output;
-
-		switch (format) {
-		case Type_4444:
-			output = (color & 0xf0f0) | ((color & 0x000f) << 8)  | ((color & 0x0f00) >> 8);
-			break;
-		case Type_5551:
-			output = (color & 0x83e0) | ((color & 0x001f) << 10) | ((color & 0x7c00) >> 10);
-			break;
-		case Type_5650:
-			output = (color & 0x07e0) | ((color & 0x001f) << 11) | ((color & 0xf800) >> 11);
-			break;
-		default:
-			PSP_ERROR("invalid format[%u] for swapping\n", format);
-			output = 0;
-			break;
-		}
-		return output;
-	}
-
-	inline uint32 swapRedBlue32(uint32 color) const {
-		uint32 output;
-
-		switch (format) {
-		case Type_4444:
-			output = (color & 0xf0f0f0f0) |
-			         ((color & 0x000f000f) << 8)  | ((color & 0x0f000f00) >> 8);
-			break;
-		case Type_5551:
-			output = (color & 0x83e083e0) |
-			         ((color & 0x001f001f) << 10) | ((color & 0x7c007c00) >> 10);
-			break;
-		case Type_5650:
-			output = (color & 0x07e007e0) |
-			         ((color & 0x001f001f) << 11) | ((color & 0xf800f800) >> 11);
-			break;
-		case Type_8888:
-			output = (color & 0xff00ff00) |
-			         ((color & 0x000000ff) << 16) | ((color & 0x00ff0000) >> 16);
-			break;
-		case Type_8888_RGBA:
-			output = ((color & 0x000000ff) << 24) | ((color & 0x0000ff00) << 8) |
-			         ((color & 0x00ff0000) >> 8) | ((color & 0xff000000) >> 24);
-			break;
-		default:
-			PSP_ERROR("invalid format[%u] for swapping\n", format);
-			output = 0;
-			break;
-		}
-
-		return output;
-	}
-
 	// Return whatever color we point at
 	inline uint32 getColorValueAt(byte *pointer) const {
 		uint32 result;
diff --git a/backends/platform/psp/tests.cpp b/backends/platform/psp/tests.cpp
index 5d49108a233..71334ec79f3 100644
--- a/backends/platform/psp/tests.cpp
+++ b/backends/platform/psp/tests.cpp
@@ -450,8 +450,8 @@ private:
 		MEMCPY_BUFFER_SIZE = 8192
 	};
 
-	void fastCopySpecificSize(byte *dst, byte *src, uint32 bytes, bool swap = false);
-	void fastCopyDifferentSizes(byte *dst, byte *src, bool swap = false);
+	void fastCopySpecificSize(byte *dst, byte *src, uint32 bytes);
+	void fastCopyDifferentSizes(byte *dst, byte *src);
 
 };
 
@@ -474,13 +474,13 @@ void PspUnitTests::testFastCopy() {
 	byte *bufferSrc = ((byte *)bufferSrc32);
 	byte *bufferDst = ((byte *)bufferDst32);
 
-	fastCopyDifferentSizes(bufferDst, bufferSrc, true);
+	fastCopyDifferentSizes(bufferDst, bufferSrc);
 	fastCopyDifferentSizes(bufferDst+1, bufferSrc+1);
-	fastCopyDifferentSizes(bufferDst+2, bufferSrc+2, true);
+	fastCopyDifferentSizes(bufferDst+2, bufferSrc+2);
 	fastCopyDifferentSizes(bufferDst+3, bufferSrc+3);
 	fastCopyDifferentSizes(bufferDst, bufferSrc+1);
-	fastCopyDifferentSizes(bufferDst, bufferSrc+2, true);
-	fastCopyDifferentSizes(bufferDst+2, bufferSrc, true);
+	fastCopyDifferentSizes(bufferDst, bufferSrc+2);
+	fastCopyDifferentSizes(bufferDst+2, bufferSrc);
 	fastCopyDifferentSizes(bufferDst, bufferSrc+3);
 	fastCopyDifferentSizes(bufferDst+1, bufferSrc+2);
 	fastCopyDifferentSizes(bufferDst+1, bufferSrc+3);
@@ -495,46 +495,36 @@ void PspUnitTests::testFastCopy() {
 
 void PspUnitTests::fastCopyDifferentSizes(byte *dst, byte *src, bool swap) {
 	fastCopySpecificSize(dst, src, 1);
-	fastCopySpecificSize(dst, src, 2, swap);
-	fastCopySpecificSize(dst, src, 4, swap);
-	fastCopySpecificSize(dst, src, 6, swap);
-	fastCopySpecificSize(dst, src, 8, swap);
+	fastCopySpecificSize(dst, src, 2);
+	fastCopySpecificSize(dst, src, 4);
+	fastCopySpecificSize(dst, src, 6);
+	fastCopySpecificSize(dst, src, 8);
 	fastCopySpecificSize(dst, src, 9);
-	fastCopySpecificSize(dst, src, 10, swap);
+	fastCopySpecificSize(dst, src, 10);
 	fastCopySpecificSize(dst, src, 11);
-	fastCopySpecificSize(dst, src, 12, swap);
+	fastCopySpecificSize(dst, src, 12);
 	fastCopySpecificSize(dst, src, 13);
-	fastCopySpecificSize(dst, src, 14, swap);
+	fastCopySpecificSize(dst, src, 14);
 	fastCopySpecificSize(dst, src, 15);
-	fastCopySpecificSize(dst, src, 16, swap);
+	fastCopySpecificSize(dst, src, 16);
 	fastCopySpecificSize(dst, src, 17);
-	fastCopySpecificSize(dst, src, 18, swap);
+	fastCopySpecificSize(dst, src, 18);
 	fastCopySpecificSize(dst, src, 19);
-	fastCopySpecificSize(dst, src, 20, swap);
-	fastCopySpecificSize(dst, src, 32, swap);
+	fastCopySpecificSize(dst, src, 20);
+	fastCopySpecificSize(dst, src, 32);
 	fastCopySpecificSize(dst, src, 33);
-	fastCopySpecificSize(dst, src, 34, swap);
+	fastCopySpecificSize(dst, src, 34);
 	fastCopySpecificSize(dst, src, 35);
-	fastCopySpecificSize(dst, src, 36, swap);
-	fastCopySpecificSize(dst, src, 50, swap);
-	fastCopySpecificSize(dst, src, 100, swap);
-	fastCopySpecificSize(dst, src, 500, swap);
-	fastCopySpecificSize(dst, src, 1000, swap);
+	fastCopySpecificSize(dst, src, 36);
+	fastCopySpecificSize(dst, src, 50);
+	fastCopySpecificSize(dst, src, 100);
+	fastCopySpecificSize(dst, src, 500);
+	fastCopySpecificSize(dst, src, 1000);
 }
 
-void PspUnitTests::fastCopySpecificSize(byte *dst, byte *src, uint32 bytes, bool swap) {
+void PspUnitTests::fastCopySpecificSize(byte *dst, byte *src, uint32 bytes) {
 	memset(dst, 0, bytes);
 	PspMemory::fastCopy(dst, src, bytes);
-
-	if (swap) {	// test swap also
-		memset(dst, 0, bytes);
-
-		// pixelformat for swap
-		PSPPixelFormat format;
-		format.set(PSPPixelFormat::Type_4444, true);
-
-		PspMemory::fastSwap(dst, src, bytes, format);
-	}
 }
 
 // This function leaks. For now I don't care


Commit: 4549a485b14bd8f8d489bd89c7a2e345bc5d1853
    https://github.com/scummvm/scummvm/commit/4549a485b14bd8f8d489bd89c7a2e345bc5d1853
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2026-05-09T23:55:23+02:00

Commit Message:
PSP: Use Graphics::crossBlit for converting the cursor

Changed paths:
    backends/platform/psp/cursor.cpp
    backends/platform/psp/cursor.h
    backends/platform/psp/default_display_client.cpp
    backends/platform/psp/display_client.h
    backends/platform/psp/psppixelformat.cpp
    backends/platform/psp/psppixelformat.h


diff --git a/backends/platform/psp/cursor.cpp b/backends/platform/psp/cursor.cpp
index b74a7177338..e91c701ee2c 100644
--- a/backends/platform/psp/cursor.cpp
+++ b/backends/platform/psp/cursor.cpp
@@ -105,7 +105,9 @@ void Cursor::clearKeyColor() {
 		if (_palette.isAllocated())
 			_palette.setColorPositionAlpha(_keyColor, false);
 	} else {	// 16bit
-		_renderer.setKeyColor(_keyColor);
+		byte a, r, g, b;
+		_srcFormat.colorToARGB(_keyColor, a, r, g, b);
+		_renderer.setKeyColor((b << 16) | (g << 8) | (r << 0) | (a << 24));
 	}
 	setDirty();
 }
@@ -138,7 +140,15 @@ void Cursor::copyFromArray(const byte *array) {
 		_buffer.allocate();
 	}
 
-	_buffer.copyFromArray(array, _buffer.getSourceWidthInBytes());	// pitch is source width
+	if (_blitFunc) {
+		_blitFunc(_buffer.getPixels(), array,
+		          _buffer.getWidthInBytes(), _buffer.getSourceWidthInBytes(),
+		          _buffer.getWidth(), _buffer.getHeight());
+	} else {
+		Graphics::crossBlit(_buffer.getPixels(), array,
+		                    _buffer.getWidthInBytes(), _buffer.getSourceWidthInBytes(),
+		                    _buffer.getWidth(), _buffer.getHeight(), _dstFormat, _srcFormat);
+	}
 	setDirty();
 
 	// debug
@@ -221,9 +231,10 @@ void Cursor::setScreenPaletteScummvmPixelFormat(const Graphics::PixelFormat *for
 
 	PSPPixelFormat::Type bufferType = PSPPixelFormat::Type_Unknown;
 	PSPPixelFormat::Type paletteType = PSPPixelFormat::Type_Unknown;
+	bool fakeAlpha = false;
 
 	// Convert Scummvm Pixel Format to PSPPixelFormat
-	PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferType, paletteType);
+	PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferType, paletteType, fakeAlpha);
 
 	if (paletteType == PSPPixelFormat::Type_None) {
 		//_screenPalette.deallocate();		// leave palette for default CLUT8
@@ -250,10 +261,13 @@ void Cursor::setSizeAndScummvmPixelFormat(uint32 width, uint32 height, const Gra
 
 	PSPPixelFormat::Type bufferType = PSPPixelFormat::Type_Unknown;
 	PSPPixelFormat::Type paletteType = PSPPixelFormat::Type_Unknown;
+	bool fakeAlpha = false;
 
-	PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferType, paletteType);
+	PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferType, paletteType, fakeAlpha);
 	PSP_DEBUG_PRINT("bufferType[%u], paletteType[%u]\n", bufferType, paletteType);
 
+	_srcFormat = format ? *format : Graphics::PixelFormat::createFormatCLUT8();
+
 	// Check if we need to set new pixel format
 	if (_buffer.getPixelFormat() != bufferType) {
 		PSP_DEBUG_PRINT("new buffer pixel format[%u] is different from [%u]. Setting it.\n", bufferType, _buffer.getPixelFormat());
@@ -269,15 +283,15 @@ void Cursor::setSizeAndScummvmPixelFormat(uint32 width, uint32 height, const Gra
 	PSP_DEBUG_PRINT("palette pixel format[%u]\n", paletteType);
 
 	if (paletteType == PSPPixelFormat::Type_None) {
+		_dstFormat = PSPPixelFormat::convertToScummvmPixelFormat(bufferType, fakeAlpha);
+		_blitFunc = Graphics::getFastBlitFunc(_dstFormat, _srcFormat);
+		_fakeAlpha = fakeAlpha;
 		setRendererModePalettized(false);	// use non-palettized mechanism
-		if (format) {
-			if (format->aBits() == 0)
-				_fakeAlpha = true;		// we are treating e.g. 555 as 5551
-			else
-				_fakeAlpha = false;		// we have a genuine alpha channel
-		}
 	} else {	// We have a palette
 		_palette.setPixelFormats(paletteType, bufferType);
+		_dstFormat = Graphics::PixelFormat::createFormatCLUT8();
+		_blitFunc = nullptr;
+		_fakeAlpha = false;
 		setRendererModePalettized(true);	// use palettized mechanism
 	}
 
@@ -317,9 +331,6 @@ inline void Cursor::setRendererModePalettized(bool palettized) {
 		// Pixel formats without alpha (5650) are considered to have their alpha set.
 		// Since pixel formats like 555 are treated as 5551 on PSP, we reverse
 		// the alpha format for them so that 0 alpha is 1.
-		if (_buffer.getPixelFormat() != PSPPixelFormat::Type_5650 && _fakeAlpha)
-			_renderer.setAlphaReverse(true);
-		else
-			_renderer.setAlphaReverse(false);
+		_renderer.setAlphaReverse(_fakeAlpha);
 	}
 }
diff --git a/backends/platform/psp/cursor.h b/backends/platform/psp/cursor.h
index 85d1814b07f..61b4413e634 100644
--- a/backends/platform/psp/cursor.h
+++ b/backends/platform/psp/cursor.h
@@ -23,6 +23,7 @@
 #define MOUSE_H
 
 #include "backends/platform/psp/default_display_client.h"
+#include "graphics/blit.h"
 
 class Cursor : public DefaultDisplayClient {
 private:
@@ -36,6 +37,9 @@ private:
 	int32	_x, _y;
 	Palette _screenPalette;			// separate palette for screen. default 'palette' is cursor palette.
 	bool _fakeAlpha;			// true if treating e.g. 555 as 5551, false if there's a genuine alpha channel
+	Graphics::PixelFormat _srcFormat;
+	Graphics::PixelFormat _dstFormat;
+	Graphics::FastBlitFunc _blitFunc;
 
 	void updateRendererOffset();
 
diff --git a/backends/platform/psp/default_display_client.cpp b/backends/platform/psp/default_display_client.cpp
index 656a416da50..fe9c7719738 100644
--- a/backends/platform/psp/default_display_client.cpp
+++ b/backends/platform/psp/default_display_client.cpp
@@ -182,8 +182,9 @@ void Screen::setScummvmPixelFormat(const Graphics::PixelFormat *format) {
 	}
 
 	PSPPixelFormat::Type bufferFormat, paletteFormat;
+	bool fakeAlpha = false;
 
-	PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferFormat, paletteFormat);
+	PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferFormat, paletteFormat, fakeAlpha);
 	_buffer.setPixelFormat(bufferFormat);
 	_palette.setPixelFormats(paletteFormat, bufferFormat);
 }
diff --git a/backends/platform/psp/display_client.h b/backends/platform/psp/display_client.h
index 2b17ed0044b..79beb28f50b 100644
--- a/backends/platform/psp/display_client.h
+++ b/backends/platform/psp/display_client.h
@@ -196,7 +196,7 @@ public:
 	void setOffsetOnScreen(int x, int y) { _offsetOnScreen.x = x; _offsetOnScreen.y = y; }
 	void setOffsetInBuffer(uint32 x, uint32 y) { _offsetInBuffer.x = x; _offsetInBuffer.y = y; }
 	void setColorTest(bool value) { _colorTest = value; }
-	void setKeyColor(uint32 value) { _keyColor = _buffer->_pixelFormat.convertTo32BitColor(value); }
+	void setKeyColor(uint32 value) { _keyColor = value; }
 	void setAlphaBlending(bool value) { _blending = value; }
 	void setAlphaReverse(bool value) { _alphaReverse = value; }
 	void setFullScreen(bool value) { _fullScreen = value; }		// Shortcut for rendering
diff --git a/backends/platform/psp/psppixelformat.cpp b/backends/platform/psp/psppixelformat.cpp
index 8c6c48f6366..4c66099b3d6 100644
--- a/backends/platform/psp/psppixelformat.cpp
+++ b/backends/platform/psp/psppixelformat.cpp
@@ -66,7 +66,9 @@ void PSPPixelFormat::set(Type type) {
 // For buffer and palette.
 void PSPPixelFormat::convertFromScummvmPixelFormat(const Graphics::PixelFormat *pf,
 		PSPPixelFormat::Type &bufferType,
-		PSPPixelFormat::Type &paletteType) {
+		PSPPixelFormat::Type &paletteType,
+		bool &fakeAlpha) {
+	fakeAlpha = false;	 // no fake alpha by default
 	PSPPixelFormat::Type *target = nullptr;	// which one we'll be filling
 
 	if (!pf) {	// Default, pf is NULL
@@ -87,14 +89,20 @@ void PSPPixelFormat::convertFromScummvmPixelFormat(const Graphics::PixelFormat *
 
 		// Find out the exact type of the target
 		if (pf->rLoss == 3 && pf->bLoss == 3) {
-			if (pf->gLoss == 3)
+			if (pf->gLoss == 3) {
 				*target = Type_5551;
-			else
+				if (pf->aLoss == 8)
+					fakeAlpha = true;
+			} else
 				*target = Type_5650;
 		} else if (pf->rLoss == 4 && pf->gLoss == 4 && pf->bLoss == 4) {
 			*target = Type_4444;
+			if (pf->aLoss == 8)
+				fakeAlpha = true;
 		} else if (pf->rLoss == 0 && pf->gLoss == 0 && pf->bLoss == 0) {
 			*target = Type_8888;
+			if (pf->aLoss == 8)
+				fakeAlpha = true;
 		} else if ((pf->gLoss == 0 && pf->gShift == 0) ||
 		           (pf->gLoss == 8 && pf->gShift == 0)) {	// Default CLUT8 can have weird values
 			*target = Type_5551;
@@ -108,7 +116,7 @@ void PSPPixelFormat::convertFromScummvmPixelFormat(const Graphics::PixelFormat *
 	}
 }
 
-Graphics::PixelFormat PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type type) {
+Graphics::PixelFormat PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type type, bool fakeAlpha) {
 	Graphics::PixelFormat pf;
 
 	switch (type) {
@@ -158,19 +166,13 @@ Graphics::PixelFormat PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat
 		break;
 	default:
 		PSP_ERROR("Unhandled PSPPixelFormat[%u]\n", type);
-		break;
+		return pf;
 	}
 
-	return pf;
-}
-
-uint32 PSPPixelFormat::convertTo32BitColor(uint32 color) const {
-	DEBUG_ENTER_FUNC();
-	uint32 r, g, b, a, output;
-
-	colorToRgba(color, r, g, b, a);
-	output = ((b << 16) | (g << 8) | (r << 0) | (a << 24));
-	PSP_DEBUG_PRINT_FUNC("input color[%x], output[%x]\n", color, output);
+	if (fakeAlpha) {
+		pf.aLoss = 8;
+		pf.aShift = 0;
+	}
 
-	return output;
+	return pf;
 }
diff --git a/backends/platform/psp/psppixelformat.h b/backends/platform/psp/psppixelformat.h
index 96ccccbaa19..ae9b5793684 100644
--- a/backends/platform/psp/psppixelformat.h
+++ b/backends/platform/psp/psppixelformat.h
@@ -50,9 +50,9 @@ struct PSPPixelFormat {
 	void set(Type type);
 	static void convertFromScummvmPixelFormat(const Graphics::PixelFormat *pf,
 	        PSPPixelFormat::Type &bufferType,
-	        PSPPixelFormat::Type &paletteType);
-	static Graphics::PixelFormat convertToScummvmPixelFormat(PSPPixelFormat::Type type);
-	uint32 convertTo32BitColor(uint32 color) const;
+	        PSPPixelFormat::Type &paletteType,
+		bool &fakeAlpha);
+	static Graphics::PixelFormat convertToScummvmPixelFormat(PSPPixelFormat::Type type, bool fakeAlpha = false);
 
 	inline uint32 rgbaToColor(uint32 r, uint32 g, uint32 b, uint32 a) const {
 		uint32 color;


Commit: 90a0bdefd0a66ad729904bfd44ecf4f550d894a6
    https://github.com/scummvm/scummvm/commit/90a0bdefd0a66ad729904bfd44ecf4f550d894a6
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2026-05-09T23:55:23+02:00

Commit Message:
PSP: Use Graphics::crossBlit for converting the game screen

Changed paths:
    backends/platform/psp/default_display_client.cpp
    backends/platform/psp/default_display_client.h
    backends/platform/psp/display_client.h


diff --git a/backends/platform/psp/default_display_client.cpp b/backends/platform/psp/default_display_client.cpp
index fe9c7719738..5a60c944838 100644
--- a/backends/platform/psp/default_display_client.cpp
+++ b/backends/platform/psp/default_display_client.cpp
@@ -175,10 +175,9 @@ void Screen::setScummvmPixelFormat(const Graphics::PixelFormat *format) {
 	PSP_DEBUG_PRINT("format[%p], _buffer[%p], _palette[%p]\n", format, &_buffer, &_palette);
 
 	if (!format) {
-		memset(&_pixelFormat, 0, sizeof(_pixelFormat));
-		_pixelFormat.bytesPerPixel = 1;	// default
+		_srcFormat = Graphics::PixelFormat::createFormatCLUT8();
 	} else {
-		_pixelFormat = *format;
+		_srcFormat = *format;
 	}
 
 	PSPPixelFormat::Type bufferFormat, paletteFormat;
@@ -187,20 +186,84 @@ void Screen::setScummvmPixelFormat(const Graphics::PixelFormat *format) {
 	PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferFormat, paletteFormat, fakeAlpha);
 	_buffer.setPixelFormat(bufferFormat);
 	_palette.setPixelFormats(paletteFormat, bufferFormat);
+
+	if (paletteFormat == PSPPixelFormat::Type_None) {
+		_dstFormat = PSPPixelFormat::convertToScummvmPixelFormat(bufferFormat, fakeAlpha);
+		_blitFunc = Graphics::getFastBlitFunc(_dstFormat, _srcFormat);
+		_convert = (_srcFormat != _dstFormat);
+	} else {
+		_dstFormat = Graphics::PixelFormat::createFormatCLUT8();
+		_blitFunc = nullptr;
+		_convert = false;
+	}
 }
 
 Graphics::Surface *Screen::lockAndGetForEditing() {
 	DEBUG_ENTER_FUNC();
 
-	_frameBuffer.init(_buffer.getSourceWidth(), _buffer.getSourceHeight(), _buffer.getBytesPerPixel() * _buffer.getWidth(),
-	                  _buffer.getPixels(), _pixelFormat);
 	// We'll set to dirty once we unlock the screen
 
 	return &_frameBuffer;
 }
 
+void Screen::unlock() {
+
+	// set dirty here because of changes
+
+	_dirtyRects.emplace_back(getWidth(), getHeight());
+	setDirty();
+}
+
+void Screen::copyFromRect(const byte *buf, int pitch, int destX, int destY, int recWidth, int recHeight) {
+	DEBUG_ENTER_FUNC();
+	_frameBuffer.copyRectToSurface(buf, pitch, destX, destY, recWidth, recHeight);
+	_dirtyRects.emplace_back(destX, destY, destX + recWidth, destY + recHeight);
+	setDirty();
+}
+
 bool Screen::allocate() {
 	DEBUG_ENTER_FUNC();
 
-	return DefaultDisplayClient::allocate(true, false);	// buffer in VRAM
+	if (!DefaultDisplayClient::allocate(true, false))	// buffer in VRAM
+		return false;
+
+	if (_convert) {
+		_frameBuffer.create(_buffer.getSourceWidth(), _buffer.getSourceHeight(), _srcFormat);
+	} else {
+		_frameBuffer.init(_buffer.getSourceWidth(), _buffer.getSourceHeight(), _buffer.getWidthInBytes(),
+		                  _buffer.getPixels(), _srcFormat);
+	}
+
+	return true;
+}
+
+void Screen::deallocate() {
+	if (_convert)
+		_frameBuffer.free();
+	else
+		_frameBuffer.setPixels(nullptr);
+	DefaultDisplayClient::deallocate();
+}
+
+void Screen::render() {
+	if (_convert && !_dirtyRects.empty()) {
+		_dirtyRects.merge();
+
+		for (const Common::Rect &r : _dirtyRects) {
+			const byte *src = (const byte *)_frameBuffer.getBasePtr(r.left, r.top);
+			byte *dst = (byte *)_buffer.getBasePtr(r.left, r.top);
+
+			if (_blitFunc) {
+				_blitFunc(dst, src, _buffer.getWidthInBytes(),
+				          _frameBuffer.pitch, r.width(), r.height());
+			} else {
+				Graphics::crossBlit(dst, src, _buffer.getWidthInBytes(),
+				                    _frameBuffer.pitch, r.width(), r.height(),
+				                    _dstFormat, _srcFormat);
+			}
+		}
+	}
+	_dirtyRects.clear();
+
+	DefaultDisplayClient::render();
 }
diff --git a/backends/platform/psp/default_display_client.h b/backends/platform/psp/default_display_client.h
index f4b96156142..6c5da70048d 100644
--- a/backends/platform/psp/default_display_client.h
+++ b/backends/platform/psp/default_display_client.h
@@ -22,6 +22,9 @@
 #ifndef PSP_DEF_DISPLAY_CLIENT_H
 #define PSP_DEF_DISPLAY_CLIENT_H
 
+#include "graphics/blit.h"
+#include "graphics/dirtyrects.h"
+
 /**
  *	Default display client that is useful for most purposes.
  */
@@ -77,25 +80,30 @@ public:
  */
 class Screen : public DefaultDisplayClient {
 public:
-	Screen() : _shakeXOffset(0), _shakeYOffset(0) {
-		memset(&_pixelFormat, 0, sizeof(_pixelFormat));
-		memset(&_frameBuffer, 0, sizeof(_frameBuffer));
-	}
+	Screen() : _shakeXOffset(0), _shakeYOffset(0), _convert(false), _blitFunc(nullptr) {}
+	~Screen() { deallocate(); }
 
 	void init();
 	bool allocate();
+	void deallocate();
 	void setShakePos(int shakeXOffset, int shakeYOffset);
 	void setScummvmPixelFormat(const Graphics::PixelFormat *format);
-	const Graphics::PixelFormat &getScummvmPixelFormat() const { return _pixelFormat; }
+	const Graphics::PixelFormat &getScummvmPixelFormat() const { return _srcFormat; }
 	Graphics::Surface *lockAndGetForEditing();
-	void unlock() { setDirty(); } // set dirty here because of changes
+	void unlock();
+	void copyFromRect(const byte *buf, int pitch, int destX, int destY, int recWidth, int recHeight);
 	void setSize(uint32 width, uint32 height);
+	void render();
 
 private:
 	uint32 _shakeXOffset;
 	uint32 _shakeYOffset;
-	Graphics::PixelFormat _pixelFormat;
+	bool _convert;
+	Graphics::PixelFormat _srcFormat;
+	Graphics::PixelFormat _dstFormat;
 	Graphics::Surface _frameBuffer;
+	Graphics::FastBlitFunc _blitFunc;
+	Graphics::DirtyRectList _dirtyRects;
 };
 
 #endif /* PSP_DEF_DISPLAY_CLIENT_H */
diff --git a/backends/platform/psp/display_client.h b/backends/platform/psp/display_client.h
index 79beb28f50b..85afc18a0f5 100644
--- a/backends/platform/psp/display_client.h
+++ b/backends/platform/psp/display_client.h
@@ -140,6 +140,8 @@ public:
 	uint32 getBytesPerPixel() const { return getBitsPerPixel() >> 3; } /* won't work for 4-bit */
 	const byte *getPixels() const { return _pixels; }
 	byte *getPixels() { return _pixels; }
+	const byte *getBasePtr(int x, int y) const { return _pixels + _pixelFormat.pixelsToBytes((y * _width) + x); }
+	byte *getBasePtr(int x, int y) { return _pixels + _pixelFormat.pixelsToBytes((y * _width) + x); }
 	uint32 getSizeInBytes() const { return _pixelFormat.pixelsToBytes(_width * _height); }
 
 	bool hasPalette();


Commit: fe1bc9029788a643e2ade276e0e4e2d580fb091d
    https://github.com/scummvm/scummvm/commit/fe1bc9029788a643e2ade276e0e4e2d580fb091d
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2026-05-09T23:55:23+02:00

Commit Message:
PSP: List more formats in DisplayManager::getSupportedPixelFormats()

Changed paths:
    backends/platform/psp/display_manager.cpp


diff --git a/backends/platform/psp/display_manager.cpp b/backends/platform/psp/display_manager.cpp
index d6f94932e9e..16b2e193eb9 100644
--- a/backends/platform/psp/display_manager.cpp
+++ b/backends/platform/psp/display_manager.cpp
@@ -463,9 +463,16 @@ Common::List<Graphics::PixelFormat> DisplayManager::getSupportedPixelFormats() c
 	Common::List<Graphics::PixelFormat> list;
 
 	// In order of preference
+	// Note that the OSystem documentation suggests that the format with the highest
+	// depth should come first, but for PSP BGR565 is listed first instead to reduce
+	// memory usage
 	list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_5650));
-	list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_5551));
-	list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_4444));
+	list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_5551, false));
+	list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_5551, true));
+	list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_4444, false));
+	list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_4444, true));
+	list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_8888, false));
+	list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_8888, true));
 	list.push_back(Graphics::PixelFormat::createFormatCLUT8());
 
 	return list;


Commit: 71a581288edaa803cd6f63441e43d38f2f564584
    https://github.com/scummvm/scummvm/commit/71a581288edaa803cd6f63441e43d38f2f564584
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2026-05-09T23:55:23+02:00

Commit Message:
GRAPHICS Add a fast path for RGB565<->BGR565 conversion

Changed paths:
    graphics/blit/blit-fast.cpp


diff --git a/graphics/blit/blit-fast.cpp b/graphics/blit/blit-fast.cpp
index 4fe69a1d29f..0a2d2fc28bb 100644
--- a/graphics/blit/blit-fast.cpp
+++ b/graphics/blit/blit-fast.cpp
@@ -103,10 +103,35 @@ static void fastBlit_XRGB1555_RGBA5551(byte *dst, const byte *src,
 	}
 }
 
+static void fastBlit_RGB565_BGR565(byte *dst, const byte *src,
+                                   const uint dstPitch, const uint srcPitch,
+                                   const uint w, const uint h) {
+	// Faster, but larger, to provide optimized handling for each case.
+	const uint srcDelta = (srcPitch - w * sizeof(uint16));
+	const uint dstDelta = (dstPitch - w * sizeof(uint16));
+
+	for (uint y = 0; y < h; ++y) {
+		for (uint x = 0; x < w; ++x) {
+			uint16 col = *(const uint16 *)src;
+
+			col =   ((col & 0xF800) >> 11)  // R
+			      |  (col & 0x07E0)         // G
+			      | ((col & 0x001F) << 11); // B
+
+			*(uint16 *)dst = col;
+
+			src += sizeof(uint16);
+			dst += sizeof(uint16);
+		}
+		src += srcDelta;
+		dst += dstDelta;
+	}
+}
+
 } // End of anonymous namespace
 
 // TODO: Add fast 24<->32bpp conversion
-// TODO: Add fast 16bpp RGB <-> 16bpp BGR conversion
+// TODO: Add more fast 16bpp RGB <-> 16bpp BGR conversion
 struct FastBlitLookup {
 	FastBlitFunc func;
 	Graphics::PixelFormat srcFmt, dstFmt;
@@ -145,6 +170,9 @@ static const FastBlitLookup fastBlitFuncs_2to2[] = {
 
 	{ fastBlit_XRGB1555_RGBA5551, Graphics::PixelFormat(2, 5, 5, 5, 0, 10,  5,  0,  0), Graphics::PixelFormat(2, 5, 5, 5, 1, 11,  6,  1,  0) }, // XRGB1555 -> RGBA5551
 	{ fastBlit_XRGB1555_RGBA5551, Graphics::PixelFormat(2, 5, 5, 5, 0,  0,  5, 10,  0), Graphics::PixelFormat(2, 5, 5, 5, 1,  1,  6, 11,  0) }, // XBGR1555 -> BGRA5551
+
+	{ fastBlit_RGB565_BGR565, Graphics::PixelFormat(2, 5, 5, 5, 0, 11,  5,  0,  0), Graphics::PixelFormat(2, 5, 6, 5, 0,  0,  5, 11,  0) }, // RGB565 -> BGR565
+	{ fastBlit_RGB565_BGR565, Graphics::PixelFormat(2, 5, 5, 5, 0,  0,  5, 11,  0), Graphics::PixelFormat(2, 5, 6, 5, 0, 11,  5,  0,  0) }, // BGR565 -> RGB565
 };
 
 #ifdef SCUMMVM_NEON




More information about the Scummvm-git-logs mailing list