aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/psp/display_client.h
blob: e384bfb82b083649346e96c7b186fef9ff2839e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#ifndef PSP_GRAPHICS_H
#define PSP_GRAPHICS_H

#include "common/singleton.h"
#include "graphics/surface.h"
#include "common/system.h"
#include "backends/platform/psp/memory.h"
#include "backends/platform/psp/psppixelformat.h"

#define MAX_TEXTURE_SIZE 512

class DisplayManager;
class GuRenderer;

/**
 *	Interface to inherit for all display clients
 *	We deliberately avoid virtual functions for speed.
 */
class DisplayClient {				// Abstract class
public:
	DisplayClient() {}
	bool isVisible() { return true; }
	bool isDirty() { return true; }
	void setClean() {}
	void render() {}
	virtual ~DisplayClient() {}
};

/**
 * Vertex used for GU rendering
 */
struct Vertex {
	float u, v;
	float x, y, z;
};

struct Point {
	int x;
	int y;
	Point() : x(0), y(0) {}
};

/**
 * Dimensions struct for simplification
 */
struct Dimensions {
	uint32 width;
	uint32 height;
	Dimensions() : width(0), height(0) {}
};

/**
 *	Universal PSP Palette class
 *	Use this in any class that wishes to draw to the PSP screen.
 *	Use together with GuRenderer
 */
class Palette {
public:
	Palette() : _values(0), _numOfEntries(0) {}
	virtual ~Palette() { deallocate(); }
	bool allocate();
	void deallocate();
	void clear();
	void setPixelFormats(PSPPixelFormat::Type paletteType, PSPPixelFormat::Type bufferType, bool swapRedBlue = false);
	void setNumOfEntries(uint32 num) {	_numOfEntries = num; }
	uint32 getNumOfEntries() { return _numOfEntries; }
	uint32 getSizeInBytes() { return _pixelFormat.pixelsToBytes(_numOfEntries); }
	void set(byte *values) { setPartial(values, 0, _numOfEntries); }
	void setPartial(const byte *colors, uint start, uint num, bool supportsAlpha = false);
	void getPartial(byte *colors, uint start, uint num);
	uint32 getRawColorAt(uint32 position);
	uint32 getRGBAColorAt(uint32 position);
	void setSingleColorRGBA(uint32 num, byte r, byte g, byte b, byte a);
	void setColorPositionAlpha(uint32 position, bool alpha);
	byte *getRawValues() { return _values; }
	bool isAllocated() { return (_values != 0); }
	PSPPixelFormat::Type getPixelFormat() { return _pixelFormat.format; }
	void print(uint32 numToPrint = 0);					// print to screen

protected:
	byte *_values;					///< array of palette data
	uint32 _numOfEntries;			///< number of palette entries
	PSPPixelFormat _pixelFormat;	///< pixel format of the palette data
};

/**
 *	Universal PSP buffer/texture object
 *	Use this in any class that wishes to draw to the PSP screen.
 *	Use together with GuRenderer
 */
class Buffer {
public:
	enum HowToSize {
		kSizeByTextureSize,	// buffer size is determined by power of 2 roundup for texture
		kSizeBySourceSize	// buffer size is determined by source size
	};

	Buffer() : _pixels(0), _width(0), _height(0)  {}
	virtual ~Buffer() { deallocate(); }

	// setters
	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);

	// getters
	uint32 getWidth() { return _width; }
	uint32 getWidthInBytes() { return _pixelFormat.pixelsToBytes(getWidth()); }
	uint32 getHeight() { return _height; }
	uint32 getSourceWidth() { return _sourceSize.width; }
	uint32 getSourceWidthInBytes() { return _pixelFormat.pixelsToBytes(_sourceSize.width); }
	uint32 getSourceHeight() { return _sourceSize.height; }
	uint32 getTextureWidth() { return _textureSize.width; }
	uint32 getTextureHeight() { return _textureSize.height; }
	PSPPixelFormat::Type getPixelFormat() { return _pixelFormat.format; }
	uint32 getBitsPerPixel() { return _pixelFormat.bitsPerPixel; }
	uint32 getBytesPerPixel() { return getBitsPerPixel() >> 3; } /* won't work for 4-bit */
	byte *getPixels() { return _pixels; }
	uint32 getSizeInBytes() { return _pixelFormat.pixelsToBytes(_width * _height); }

	bool hasPalette();
	void copyFromArray(const byte *buffer, int pitch);
	void copyFromRect(const byte *buf, uint32 pitch, int destX, int destY, uint32 recWidth, uint32 recHeight);
	void copyToArray(byte *dst, int pitch);
	bool allocate(bool inVram = false);
	void deallocate();
	bool isAllocated() { return (_pixels != 0) ; }
	void clear();
	void flipNibbles();		// To handle peculiarities of PSP's 4 bit textures
	static uint32 scaleUpToPowerOfTwo(uint32 size);
	void print(uint32 mask, uint32 numToPrint = 0);

protected:
	friend class GuRenderer;
	byte *_pixels;
	uint32 _width;					///< True allocated width
	uint32 _height;					///< True allocated height
	Dimensions _textureSize;		///< Size rounded up to power of 2. Used for drawing
	Dimensions _sourceSize;			///< Original size of the buffer
	PSPPixelFormat _pixelFormat;	///< Format of the buffer
};

/**
 *	Universal rendering class for PSP
 *	Use this if you want to draw to the screen.
 *	Needs to be supplied with a Buffer and a Palette
 */
class GuRenderer {
public:
	// Constructors
	GuRenderer() : _useGlobalScaler(false), _buffer(0), _palette(0),
					_blending(false), _alphaReverse(false), _colorTest(false),
					_keyColor(0), _fullScreen(false), _stretch(false), _stretchX(1.0f), _stretchY(1.0f) {}
	GuRenderer(Buffer *buffer, Palette *palette) :
					_useGlobalScaler(false), _buffer(buffer), _palette(palette),
					_blending(false), _alphaReverse(false), _colorTest(false),
					_keyColor(0), _fullScreen(false), _stretch(false), _stretchX(1.0f), _stretchY(1.0f) {}
	static void setDisplayManager(DisplayManager *dm) { _displayManager = dm; } // Called by the Display Manager

	// Setters
	void setDrawSize(uint32 width, uint32 height) {	// How big of an area to draw
		_drawSize.width = width;
		_drawSize.height = height;
	}
	void setDrawWholeBuffer() {						// Draw the full size of the current buffer
		assert(_buffer);
		_drawSize.width = _buffer->getSourceWidth();
		_drawSize.height = _buffer->getSourceHeight();
	}
	void setBuffer(Buffer *buffer) { _buffer = buffer; }
	void setPalette(Palette *palette) { _palette = palette; }
	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 setAlphaBlending(bool value) { _blending = value; }
	void setAlphaReverse(bool value) { _alphaReverse = value; }
	void setFullScreen(bool value) { _fullScreen = value; }		// Shortcut for rendering
	void setUseGlobalScaler(bool value) { _useGlobalScaler = value; }	// Scale to screen
	void setStretch(bool active) { _stretch = active; }
	void setStretchXY(float x, float y) { _stretchX = x; _stretchY = y; }

	static void cacheInvalidate(void *pointer, uint32 size);

	void render();							// Default rendering function. This should be good enough for most purposes

protected:
	// Gu functions
	void fillVertices(Vertex *vertices);	// Fill in vertices with coordinates
	void guProgramDrawBehavior();
	Vertex *guGetVertices();
	void guLoadTexture();
	void guLoadPalette();
	void guProgramTextureFormat();
	void guProgramTextureBitDepth();
	void guDrawVertices(Vertex *vertices);

	uint32 convertToGuPixelFormat(PSPPixelFormat::Type format);
	float scaleSourceToOutput(bool x, float offset);
	float stretch(bool x, float size);

	friend class MasterGuRenderer;
	Point _textureLoadOffset;		///> For rendering textures > 512 pixels
	Point _offsetOnScreen;			///> Where on screen to draw
	Point _offsetInBuffer;			///> Where in the texture to draw
	bool _useGlobalScaler;			///> Scale to the output size on screen
	Buffer *_buffer;
	Palette *_palette;
	static DisplayManager *_displayManager;
	Dimensions _drawSize;			///> Actual size to draw out of the Buffer
	bool _blending;
	bool _alphaReverse;				///> 0 counts as full alpha
	bool _colorTest;
	uint32 _keyColor;				///> Color to test against for color test. in 32 bits.
	bool _fullScreen;				///> Speeds up for fullscreen rendering
	bool _stretch;					///> Whether zooming is activated
	float _stretchX, _stretchY;
};

#endif /* PSP_SCREEN_H */