aboutsummaryrefslogtreecommitdiff
path: root/sword2/driver/d_draw.h
blob: 8eda52e7f85e0836849bedb28d9af08929bf6ff4 (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
/* Copyright (C) 1994-2005 Revolution Software Ltd
 *
 * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header$
 */

#ifndef D_DRAW_H
#define D_DRAW_H

#include "common/rect.h"

namespace Sword2 {

// This is the maximum mouse cursor size in the SDL backend

#define MAX_MOUSE_W		80
#define MAX_MOUSE_H		80

#define RENDERAVERAGETOTAL	4

#define BLOCKWIDTH		64
#define BLOCKHEIGHT		64
#define MAXLAYERS		5

#define PALTABLESIZE		64 * 64 * 64

// Maximum scaled size of a sprite
#define SCALE_MAXWIDTH		512
#define SCALE_MAXHEIGHT		512

// Dirty grid cell size
#define CELLWIDE		10
#define CELLDEEP		20

#if !defined(__GNUC__)
	#pragma START_PACK_STRUCTS
#endif

struct MouseAnim {
	uint8 runTimeComp;	// type of runtime compression used for the
				// frame data
	uint8 noAnimFrames;	// number of frames in the anim
	int8 xHotSpot;		
	int8 yHotSpot;
	uint8 mousew;
	uint8 mouseh;
} GCC_PACK;

#if !defined(__GNUC__)
	#pragma END_PACK_STRUCTS
#endif

struct BlockSurface {
	byte data[BLOCKWIDTH * BLOCKHEIGHT];
	bool transparent;
};

class Graphics {
	friend class MoviePlayer;

private:
	Sword2Engine *_vm;

	byte *_buffer;
	byte *_dirtyGrid;

	uint16 _gridWide;
	uint16 _gridDeep;

	int32 _renderCaps;
	int8 _renderLevel;

	uint8 _menuStatus[2];
	byte *_icons[2][RDMENU_MAXPOCKETS];
	uint8 _pocketStatus[2][RDMENU_MAXPOCKETS];

	uint8 _iconCount;

	bool _needFullRedraw;

	byte _paletteMatch[PALTABLESIZE];

	uint8 _fadeStatus;

	int32 _fadeStartTime;
	int32 _fadeTotalTime;

	uint8 _mouseFrame;
	byte *_mouseSprite;
	struct MouseAnim *_mouseAnim;
	struct MouseAnim *_luggageAnim;
	int32 *_mouseOffsets;
	int32 *_luggageOffset;

	// Scroll variables.  _scrollX and _scrollY hold the current scroll
	// position, and _scrollXTarget and _scrollYTarget are the target
	// position for the end of the game cycle.

	int16 _scrollX;
	int16 _scrollY;

	int16 _scrollXTarget;
	int16 _scrollYTarget;
	int16 _scrollXOld;
	int16 _scrollYOld;

	int16 _parallaxScrollX;	// current x offset to link a sprite to the
				// parallax layer
	int16 _parallaxScrollY;	// current y offset to link a sprite to the
				// parallax layer
	int16 _locationWide;
	int16 _locationDeep;

	uint16 _layer;

	int32 _initialTime;
	int32 _startTime;
	int32 _totalTime;
	int32 _renderAverageTime;
	int32 _framesPerGameCycle;
	bool _renderTooSlow;

	uint8 _xBlocks[MAXLAYERS];
	uint8 _yBlocks[MAXLAYERS];

	// An array of sub-blocks, one for each of the parallax layers.

	BlockSurface **_blockSurfaces[MAXLAYERS];

	uint16 _xScale[SCALE_MAXWIDTH];
	uint16 _yScale[SCALE_MAXHEIGHT];

	byte *_lightMask;

	void clearIconArea(int menu, int pocket, Common::Rect *r);

	void decompressMouse(byte *decomp, byte *comp, int width, int height, int pitch, int xOff = 0, int yOff = 0);

	void fadeServer(void);

	void scaleImageFast(byte *dst, uint16 dstPitch, uint16 dstWidth,
		uint16 dstHeight, byte *src, uint16 srcPitch, uint16 srcWidth,
		uint16 srcHeight);
	void scaleImageGood(byte *dst, uint16 dstPitch, uint16 dstWidth,
		uint16 dstHeight, byte *src, uint16 srcPitch, uint16 srcWidth,
		uint16 srcHeight, byte *backbuf);

	void updateRect(Common::Rect *r);

	void blitBlockSurface(BlockSurface *s, Common::Rect *r, Common::Rect *clipRect);

	void mirrorSprite(byte *dst, byte *src, int16 w, int16 h);
	int32 decompressRLE256(byte *dest, byte *source, int32 decompSize);
	void unwindRaw16(byte *dest, byte *source, uint8 blockSize, byte *colTable);
	int32 decompressRLE16(byte *dest, byte *source, int32 decompSize, byte *colTable);


public:
	Graphics(Sword2Engine *vm, int16 width, int16 height);
	~Graphics();

	// Game screen metrics
	int16 _screenWide;
	int16 _screenDeep;

	byte _palette[256 * 4];

	byte *getScreen(void) { return _buffer; }

	int8 getRenderLevel(void);
	void setRenderLevel(int8 level);

	void clearScene(void);

	void processMenu(void);
	int32 showMenu(uint8 menu);
	int32 hideMenu(uint8 menu);
	int32 setMenuIcon(uint8 menu, uint8 pocket, byte *icon);
	void closeMenuImmediately(void);

	void markAsDirty(int16 x0, int16 y0, int16 x1, int16 y1);
	void updateDisplay(bool redrawScene = true);
	void setNeedFullRedraw(void);

	void setPalette(int16 startEntry, int16 noEntries, byte *palette, uint8 setNow);
	void updatePaletteMatchTable(byte *data);
	uint8 quickMatch(uint8 r, uint8 g, uint8 b);
	int32 fadeUp(float time = 0.75);
	int32 fadeDown(float time = 0.75);
	uint8 getFadeStatus(void);
	void dimPalette(void);
	void waitForFade(void);

	int32 setMouseAnim(byte *ma, int32 size, int32 mouseFlash);
	int32 setLuggageAnim(byte *la, int32 size);
	int32 animateMouse(void);

	void drawMouse(void);

	void resetRenderEngine(void);

	void setScrollTarget(int16 sx, int16 sy);
	void initialiseRenderCycle(void);
	void startRenderCycle(void);
	bool endRenderCycle(void);
	void renderParallax(Parallax *p, int16 layer);
	void setLocationMetrics(uint16 w, uint16 h);
	int32 initialiseBackgroundLayer(Parallax *p);
	void closeBackgroundLayer(void);

	void plotPoint(int16 x, int16 y, uint8 colour);
	void drawLine(int16 x1, int16 y1, int16 x2, int16 y2, uint8 colour);
#ifdef BACKEND_8BIT
	void plotYUV(byte *lut, int width, int height, byte *const *dat);
#endif


	int32 createSurface(SpriteInfo *s, byte **surface);
	void drawSurface(SpriteInfo *s, byte *surface, Common::Rect *clipRect = NULL);
	void deleteSurface(byte *surface);
	int32 drawSprite(SpriteInfo *s);
	int32 openLightMask(SpriteInfo *s);
	int32 closeLightMask(void);
};

} // End of namespace Sword2

#endif