1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "common/scummsys.h"
24 #include "backends/platform/psp/psppixelformat.h"
25 
26 //#define __PSP_DEBUG_FUNCS__	/* For debugging function calls */
27 //#define __PSP_DEBUG_PRINT__	/* For debug printouts */
28 
29 #include "backends/platform/psp/trace.h"
30 
31 // class PSPPixelFormat --------------------------------------
32 
set(Type type,bool swap)33 void PSPPixelFormat::set(Type type, bool swap /* = false */) {
34 	DEBUG_ENTER_FUNC();
35 	PSP_DEBUG_PRINT("type = %d\n", type);
36 
37 	format = type;
38 	swapRB = swap;
39 
40 	switch (type) {
41 	case Type_4444:
42 	case Type_5551:
43 	case Type_5650:
44 		bitsPerPixel = 16;
45 		break;
46 	case Type_8888:
47 		bitsPerPixel = 32;
48 		break;
49 	case Type_Palette_8bit:
50 		bitsPerPixel = 8;
51 		break;
52 	case Type_Palette_4bit:
53 		bitsPerPixel = 4;
54 		break;
55 	case Type_None:
56 		bitsPerPixel = 0;
57 		break;
58 	default:	// This is an error, but let's continue anyway
59 		PSP_ERROR("Unhandled value of pixel type[%d]\n", type);
60 		bitsPerPixel = 16;
61 		break;
62 	}
63 
64 	PSP_DEBUG_PRINT("bitsPerPixel[%u]\n", bitsPerPixel);
65 }
66 
67 // Convert from ScummVM general PixelFormat to our pixel format
68 // For buffer and palette.
convertFromScummvmPixelFormat(const Graphics::PixelFormat * pf,PSPPixelFormat::Type & bufferType,PSPPixelFormat::Type & paletteType,bool & swapRedBlue)69 void PSPPixelFormat::convertFromScummvmPixelFormat(const Graphics::PixelFormat *pf,
70 		PSPPixelFormat::Type &bufferType,
71 		PSPPixelFormat::Type &paletteType,
72 		bool &swapRedBlue) {
73 	swapRedBlue = false;	 // no red-blue swap by default
74 	PSPPixelFormat::Type *target = 0;	// which one we'll be filling
75 
76 	if (!pf) {	// Default, pf is NULL
77 		bufferType = Type_Palette_8bit;
78 		paletteType = Type_5551;
79 	} else {	// We have a pf
80 		if (pf->bytesPerPixel == 1) {
81 			bufferType = Type_Palette_8bit;
82 			target = &paletteType;	// The type describes the palette
83 		} else if (pf->bytesPerPixel == 2 || pf->bytesPerPixel == 4) {
84 			paletteType = Type_None;
85 			target = &bufferType;	// The type describes the buffer
86 		} else {
87 			PSP_ERROR("Unknown bpp[%u] in pixeltype. Reverting to 8bpp\n", pf->bytesPerPixel);
88 			bufferType = Type_Palette_8bit;
89 			target = &paletteType;	// The type describes the palette
90 		}
91 
92 		// Find out the exact type of the target
93 		if (pf->rLoss == 3 && pf->bLoss == 3) {
94 			if (pf->gLoss == 3)
95 				*target = Type_5551;
96 			else
97 				*target = Type_5650;
98 		} else if (pf->rLoss == 4 && pf->gLoss == 4 && pf->bLoss == 4) {
99 			*target = Type_4444;
100 		} else if (pf->gLoss == 0 && pf->gShift == 8) {
101 			*target = Type_8888;
102 		} else if ((pf->gLoss == 0 && pf->gShift == 0) ||
103 		           (pf->gLoss == 8 && pf->gShift == 0)) {	// Default CLUT8 can have weird values
104 			*target = Type_5551;
105 		} else {
106 			PSP_ERROR("Unknown Scummvm pixel format.\n");
107 			PSP_ERROR("\trLoss[%d], gLoss[%d], bLoss[%d], aLoss[%d]\n\trShift[%d], gShift[%d], bShift[%d], aShift[%d]\n",
108 			          pf->rLoss, pf->gLoss, pf->bLoss, pf->aLoss,
109 			          pf->rShift, pf->gShift, pf->bShift, pf->aShift);
110 			*target = Type_Unknown;
111 		}
112 
113 		if (pf->rShift != 0)	{// We allow backend swap of red and blue
114 			swapRedBlue = true;
115 			PSP_DEBUG_PRINT("detected red/blue swap\n");
116 		}
117 	}
118 }
119 
convertToScummvmPixelFormat(PSPPixelFormat::Type type)120 Graphics::PixelFormat PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type type) {
121 	Graphics::PixelFormat pf;
122 
123 	switch (type) {
124 	case Type_4444:
125 		pf.bytesPerPixel = 2;
126 		pf.aLoss = 4;
127 		pf.rLoss = 4;
128 		pf.gLoss = 4;
129 		pf.bLoss = 4;
130 		pf.aShift = 12;
131 		pf.rShift = 0;
132 		pf.gShift = 4;
133 		pf.bShift = 8;
134 		break;
135 	case Type_5551:
136 		pf.bytesPerPixel = 2;
137 		pf.aLoss = 7;
138 		pf.rLoss = 3;
139 		pf.gLoss = 3;
140 		pf.bLoss = 3;
141 		pf.aShift = 15;
142 		pf.rShift = 0;
143 		pf.gShift = 5;
144 		pf.bShift = 10;
145 		break;
146 	case Type_5650:
147 		pf.bytesPerPixel = 2;
148 		pf.aLoss = 8;
149 		pf.rLoss = 3;
150 		pf.gLoss = 2;
151 		pf.bLoss = 3;
152 		pf.aShift = 0;
153 		pf.rShift = 0;
154 		pf.gShift = 5;
155 		pf.bShift = 11;
156 		break;
157 	case Type_8888:
158 		pf.bytesPerPixel = 4;
159 		pf.aLoss = 0;
160 		pf.rLoss = 0;
161 		pf.gLoss = 0;
162 		pf.bLoss = 0;
163 		pf.aShift = 24;
164 		pf.rShift = 0;
165 		pf.gShift = 8;
166 		pf.bShift = 16;
167 		break;
168 	default:
169 		PSP_ERROR("Unhandled PSPPixelFormat[%u]\n", type);
170 		break;
171 	}
172 
173 	return pf;
174 }
175 
convertTo32BitColor(uint32 color) const176 uint32 PSPPixelFormat::convertTo32BitColor(uint32 color) const {
177 	DEBUG_ENTER_FUNC();
178 	uint32 r, g, b, a, output;
179 
180 	colorToRgba(color, r, g, b, a);
181 	output = ((b << 16) | (g << 8) | (r << 0) | (a << 24));
182 	PSP_DEBUG_PRINT_FUNC("input color[%x], output[%x]\n", color, output);
183 
184 	return output;
185 }
186