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 #ifndef PSP_GRAPHICS_H
24 #define PSP_GRAPHICS_H
25 
26 #include "common/singleton.h"
27 #include "graphics/surface.h"
28 #include "common/system.h"
29 #include "backends/platform/psp/memory.h"
30 #include "backends/platform/psp/psppixelformat.h"
31 
32 #define MAX_TEXTURE_SIZE 512
33 
34 class DisplayManager;
35 class GuRenderer;
36 
37 /**
38  *	Interface to inherit for all display clients
39  *	We deliberately avoid virtual functions for speed.
40  */
41 class DisplayClient {				// Abstract class
42 public:
DisplayClient()43 	DisplayClient() {}
isVisible()44 	bool isVisible() { return true; }
isDirty()45 	bool isDirty() { return true; }
setClean()46 	void setClean() {}
render()47 	void render() {}
~DisplayClient()48 	virtual ~DisplayClient() {}
49 };
50 
51 /**
52  * Vertex used for GU rendering
53  */
54 struct Vertex {
55 	float u, v;
56 	float x, y, z;
57 };
58 
59 struct Point {
60 	int x;
61 	int y;
PointPoint62 	Point() : x(0), y(0) {}
63 };
64 
65 /**
66  * Dimensions struct for simplification
67  */
68 struct Dimensions {
69 	uint32 width;
70 	uint32 height;
DimensionsDimensions71 	Dimensions() : width(0), height(0) {}
72 };
73 
74 /**
75  *	Universal PSP Palette class
76  *	Use this in any class that wishes to draw to the PSP screen.
77  *	Use together with GuRenderer
78  */
79 class Palette {
80 public:
Palette()81 	Palette() : _values(0), _numOfEntries(0) {}
~Palette()82 	virtual ~Palette() { deallocate(); }
83 	bool allocate();
84 	void deallocate();
85 	void clear();
86 	void setPixelFormats(PSPPixelFormat::Type paletteType, PSPPixelFormat::Type bufferType, bool swapRedBlue = false);
setNumOfEntries(uint32 num)87 	void setNumOfEntries(uint32 num) {	_numOfEntries = num; }
getNumOfEntries()88 	uint32 getNumOfEntries() const { return _numOfEntries; }
getSizeInBytes()89 	uint32 getSizeInBytes() const { return _pixelFormat.pixelsToBytes(_numOfEntries); }
set(byte * values)90 	void set(byte *values) { setPartial(values, 0, _numOfEntries); }
91 	void setPartial(const byte *colors, uint start, uint num, bool supportsAlpha = false);
92 	void getPartial(byte *colors, uint start, uint num) const;
93 	uint32 getRawColorAt(uint32 position) const;
94 	uint32 getRGBAColorAt(uint32 position) const;
95 	void setSingleColorRGBA(uint32 num, byte r, byte g, byte b, byte a);
96 	void setColorPositionAlpha(uint32 position, bool alpha);
getRawValues()97 	const byte *getRawValues() const { return _values; }
getRawValues()98 	byte *getRawValues() { return _values; }
isAllocated()99 	bool isAllocated() const { return (_values != 0); }
getPixelFormat()100 	PSPPixelFormat::Type getPixelFormat() const { return _pixelFormat.format; }
101 	void print(uint32 numToPrint = 0);					// print to screen
102 
103 protected:
104 	byte *_values;					///< array of palette data
105 	uint32 _numOfEntries;			///< number of palette entries
106 	PSPPixelFormat _pixelFormat;	///< pixel format of the palette data
107 };
108 
109 /**
110  *	Universal PSP buffer/texture object
111  *	Use this in any class that wishes to draw to the PSP screen.
112  *	Use together with GuRenderer
113  */
114 class Buffer {
115 public:
116 	enum HowToSize {
117 		kSizeByTextureSize,	// buffer size is determined by power of 2 roundup for texture
118 		kSizeBySourceSize	// buffer size is determined by source size
119 	};
120 
Buffer()121 	Buffer() : _pixels(0), _width(0), _height(0)  {}
~Buffer()122 	virtual ~Buffer() { deallocate(); }
123 
124 	// setters
125 	void setSize(uint32 width, uint32 height, HowToSize textureOrSource = kSizeByTextureSize);
setBitsPerPixel(uint32 bits)126 	void setBitsPerPixel(uint32 bits) { _pixelFormat.bitsPerPixel = bits; }
setBytesPerPixel(uint32 bytes)127 	void setBytesPerPixel(uint32 bytes) { setBitsPerPixel(bytes << 3); }
128 	void setPixelFormat(PSPPixelFormat::Type type, bool swapRedBlue = false);
129 
130 	// getters
getWidth()131 	uint32 getWidth() const { return _width; }
getWidthInBytes()132 	uint32 getWidthInBytes() const { return _pixelFormat.pixelsToBytes(getWidth()); }
getHeight()133 	uint32 getHeight() const { return _height; }
getSourceWidth()134 	uint32 getSourceWidth() const { return _sourceSize.width; }
getSourceWidthInBytes()135 	uint32 getSourceWidthInBytes() const { return _pixelFormat.pixelsToBytes(_sourceSize.width); }
getSourceHeight()136 	uint32 getSourceHeight() const { return _sourceSize.height; }
getTextureWidth()137 	uint32 getTextureWidth() const { return _textureSize.width; }
getTextureHeight()138 	uint32 getTextureHeight() const { return _textureSize.height; }
getPixelFormat()139 	PSPPixelFormat::Type getPixelFormat() const { return _pixelFormat.format; }
getBitsPerPixel()140 	uint32 getBitsPerPixel() const { return _pixelFormat.bitsPerPixel; }
getBytesPerPixel()141 	uint32 getBytesPerPixel() const { return getBitsPerPixel() >> 3; } /* won't work for 4-bit */
getPixels()142 	const byte *getPixels() const { return _pixels; }
getPixels()143 	byte *getPixels() { return _pixels; }
getSizeInBytes()144 	uint32 getSizeInBytes() const { return _pixelFormat.pixelsToBytes(_width * _height); }
145 
146 	bool hasPalette();
147 	void copyFromArray(const byte *buffer, int pitch);
148 	void copyFromRect(const byte *buf, uint32 pitch, int destX, int destY, uint32 recWidth, uint32 recHeight);
149 	void copyToArray(byte *dst, int pitch);
150 	bool allocate(bool inVram = false);
151 	void deallocate();
isAllocated()152 	bool isAllocated() const { return (_pixels != 0) ; }
153 	void clear();
154 	void flipNibbles();		// To handle peculiarities of PSP's 4 bit textures
155 	static uint32 scaleUpToPowerOfTwo(uint32 size);
156 	void print(uint32 mask, uint32 numToPrint = 0);
157 
158 protected:
159 	friend class GuRenderer;
160 	byte *_pixels;
161 	uint32 _width;					///< True allocated width
162 	uint32 _height;					///< True allocated height
163 	Dimensions _textureSize;		///< Size rounded up to power of 2. Used for drawing
164 	Dimensions _sourceSize;			///< Original size of the buffer
165 	PSPPixelFormat _pixelFormat;	///< Format of the buffer
166 };
167 
168 /**
169  *	Universal rendering class for PSP
170  *	Use this if you want to draw to the screen.
171  *	Needs to be supplied with a Buffer and a Palette
172  */
173 class GuRenderer {
174 public:
175 	// Constructors
GuRenderer()176 	GuRenderer() : _useGlobalScaler(false), _buffer(0), _palette(0),
177 					_blending(false), _alphaReverse(false), _colorTest(false),
178 					_keyColor(0), _fullScreen(false), _stretch(false), _stretchX(1.0f), _stretchY(1.0f) {}
GuRenderer(Buffer * buffer,Palette * palette)179 	GuRenderer(Buffer *buffer, Palette *palette) :
180 					_useGlobalScaler(false), _buffer(buffer), _palette(palette),
181 					_blending(false), _alphaReverse(false), _colorTest(false),
182 					_keyColor(0), _fullScreen(false), _stretch(false), _stretchX(1.0f), _stretchY(1.0f) {}
setDisplayManager(DisplayManager * dm)183 	static void setDisplayManager(DisplayManager *dm) { _displayManager = dm; } // Called by the Display Manager
184 
185 	// Setters
setDrawSize(uint32 width,uint32 height)186 	void setDrawSize(uint32 width, uint32 height) {	// How big of an area to draw
187 		_drawSize.width = width;
188 		_drawSize.height = height;
189 	}
setDrawWholeBuffer()190 	void setDrawWholeBuffer() {						// Draw the full size of the current buffer
191 		assert(_buffer);
192 		_drawSize.width = _buffer->getSourceWidth();
193 		_drawSize.height = _buffer->getSourceHeight();
194 	}
setBuffer(Buffer * buffer)195 	void setBuffer(Buffer *buffer) { _buffer = buffer; }
setPalette(Palette * palette)196 	void setPalette(Palette *palette) { _palette = palette; }
setOffsetOnScreen(int x,int y)197 	void setOffsetOnScreen(int x, int y) { _offsetOnScreen.x = x; _offsetOnScreen.y = y; }
setOffsetInBuffer(uint32 x,uint32 y)198 	void setOffsetInBuffer(uint32 x, uint32 y) { _offsetInBuffer.x = x; _offsetInBuffer.y = y; }
setColorTest(bool value)199 	void setColorTest(bool value) { _colorTest = value; }
setKeyColor(uint32 value)200 	void setKeyColor(uint32 value) { _keyColor = _buffer->_pixelFormat.convertTo32BitColor(value); }
setAlphaBlending(bool value)201 	void setAlphaBlending(bool value) { _blending = value; }
setAlphaReverse(bool value)202 	void setAlphaReverse(bool value) { _alphaReverse = value; }
setFullScreen(bool value)203 	void setFullScreen(bool value) { _fullScreen = value; }		// Shortcut for rendering
setUseGlobalScaler(bool value)204 	void setUseGlobalScaler(bool value) { _useGlobalScaler = value; }	// Scale to screen
setStretch(bool active)205 	void setStretch(bool active) { _stretch = active; }
setStretchXY(float x,float y)206 	void setStretchXY(float x, float y) { _stretchX = x; _stretchY = y; }
207 
208 	static void cacheInvalidate(void *pointer, uint32 size);
209 
210 	void render();							// Default rendering function. This should be good enough for most purposes
211 
212 protected:
213 	// Gu functions
214 	void fillVertices(Vertex *vertices);	// Fill in vertices with coordinates
215 	void guProgramDrawBehavior();
216 	Vertex *guGetVertices();
217 	void guLoadTexture();
218 	void guLoadPalette();
219 	void guProgramTextureFormat();
220 	void guProgramTextureBitDepth();
221 	void guDrawVertices(Vertex *vertices);
222 
223 	uint32 convertToGuPixelFormat(PSPPixelFormat::Type format);
224 	float scaleSourceToOutput(bool x, float offset);
225 	float stretch(bool x, float size);
226 
227 	friend class MasterGuRenderer;
228 	Point _textureLoadOffset;		///> For rendering textures > 512 pixels
229 	Point _offsetOnScreen;			///> Where on screen to draw
230 	Point _offsetInBuffer;			///> Where in the texture to draw
231 	bool _useGlobalScaler;			///> Scale to the output size on screen
232 	Buffer *_buffer;
233 	Palette *_palette;
234 	static DisplayManager *_displayManager;
235 	Dimensions _drawSize;			///> Actual size to draw out of the Buffer
236 	bool _blending;
237 	bool _alphaReverse;				///> 0 counts as full alpha
238 	bool _colorTest;
239 	uint32 _keyColor;				///> Color to test against for color test. in 32 bits.
240 	bool _fullScreen;				///> Speeds up for fullscreen rendering
241 	bool _stretch;					///> Whether zooming is activated
242 	float _stretchX, _stretchY;
243 };
244 
245 #endif /* PSP_SCREEN_H */
246