aboutsummaryrefslogtreecommitdiff
path: root/engines/mohawk/riven_graphics.h
blob: 845fbf25a1326ae2e02fa804666bf9db529dc769 (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
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
/* 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 MOHAWK_RIVEN_GRAPHICS_H
#define MOHAWK_RIVEN_GRAPHICS_H

#include "mohawk/graphics.h"

#include "common/ustr.h"

namespace Graphics {
class Font;
}

namespace Mohawk {

class MohawkEngine_Riven;
class FliesEffect;
class WaterEffect;

enum RivenTransition {
	kRivenTransitionNone      = -1,
	kRivenTransitionWipeLeft  = 0,
	kRivenTransitionWipeRight = 1,
	kRivenTransitionWipeUp    = 2,
	kRivenTransitionWipeDown  = 3,
	kRivenTransitionPanLeft   = 12,
	kRivenTransitionPanRight  = 13,
	kRivenTransitionPanUp     = 14,
	kRivenTransitionPanDown   = 15,
	kRivenTransitionBlend     = 16,
	kRivenTransitionBlend2    = 17
};

enum RivenTransitionMode {
	kRivenTransitionModeDisabled = 5000,
	kRivenTransitionModeFastest  = 5001,
	kRivenTransitionModeNormal   = 5002,
	kRivenTransitionModeBest     = 5003
};

enum RivenCreditsImageNumber {
	kRivenCreditsZeroImage   = 302,
	kRivenCreditsFirstImage  = 303,
	kRivenCreditsSecondImage = 304,
	kRivenCreditsLastImage   = 320
};

class RivenGraphics : public GraphicsManager {
public:
	explicit RivenGraphics(MohawkEngine_Riven *vm);
	~RivenGraphics() override;

	// Screen updates
	void beginScreenUpdate();
	void applyScreenUpdate(bool force = false);
	void enableCardUpdateScript(bool enable);

	void copyImageToScreen(uint16 image, uint32 left, uint32 top, uint32 right, uint32 bottom);
	void drawRect(const Common::Rect &rect, bool active);
	void drawImageRect(uint16 id, const Common::Rect &srcRect, const Common::Rect &dstRect);
	void drawExtrasImage(uint16 id, const Common::Rect &dstRect);
	void drawExtrasImageToScreen(uint16 id, const Common::Rect &rect);

	/** Copy a rect from the system screen to the game screen */
	void copySystemRectToScreen(const Common::Rect &rect);

	Graphics::Surface *getEffectScreen();
	Graphics::Surface *getBackScreen();

	// Water Effect
	void scheduleWaterEffect(uint16);
	void clearWaterEffect();

	// Flies Effect
	void setFliesEffect(uint16 count, bool fireflies);
	void clearFliesEffect();

	/** Update the screen with the water and fly effects */
	void updateEffects();

	// Transitions
	void scheduleTransition(RivenTransition id, const Common::Rect &rect = Common::Rect(0, 0, 608, 392));
	void runScheduledTransition();
	void fadeToBlack();
	void setTransitionMode(RivenTransitionMode mode);

	// Main menu
	void drawText(const Common::U32String &text, const Common::Rect &dest, uint8 greyLevel);

	// Credits
	void beginCredits();
	void updateCredits();
	uint getCurCreditsImage() const { return _creditsImage; }

protected:
	MohawkSurface *decodeImage(uint16 id) override;
	MohawkEngine *getVM() override { return (MohawkEngine *)_vm; }

private:
	MohawkEngine_Riven *_vm;
	MohawkBitmap *_bitmapDecoder;
	int _screenUpdateNesting;
	bool _screenUpdateRunning;
	bool _enableCardUpdateScript;

	// Effects
	WaterEffect *_waterEffect;
	FliesEffect *_fliesEffect;

	// Transitions
	RivenTransition _scheduledTransition;
	Common::Rect _transitionRect;
	RivenTransitionMode _transitionMode;
	uint _transitionFrames;
	uint _transitionDuration;
	int16 _transitionOffset;

	// Screen Related
	Graphics::Surface *_mainScreen;
	Graphics::Surface *_effectScreen;
	bool _dirtyScreen;

	Graphics::PixelFormat _pixelFormat;
	void updateScreen();
	void clearMainScreen();

	// Main menu
	Graphics::Font *_menuFont;
	void loadMenuFont();
	const Graphics::Font *getMenuFont() const;

	// Credits
	uint _creditsImage, _creditsPos;
};

/**
 * Move slightly the water portions of a view to simulate waves
 */
class WaterEffect {
public:
	WaterEffect(MohawkEngine_Riven *vm, uint16 sfxeID);
	~WaterEffect();

	void update();

private:
	MohawkEngine_Riven *_vm;

	// Record values
	Common::Rect _rect;
	uint16 _speed;
	Common::Array<Common::SeekableReadStream *> _frameScripts;

	// Cur frame
	uint16 _curFrame;
	uint32 _lastFrameTime;
};

/**
 * The flies effect draws flies in the scene
 *
 * It can draw either regular flies or fireflies.
 * The flies' movement is simulated in 3 dimensions.
 */
class FliesEffect {
public:
	FliesEffect(MohawkEngine_Riven *vm, uint16 count, bool fireflies);
	~FliesEffect();

	/** Simulate the flies' movement and draw them to the screen */
	void update();

private:
	struct FliesEffectEntry	{
		bool light;
		int posX;
		int posY;
		int posZ;
		const uint16 *alphaMap;
		uint width;
		uint height;
		int framesTillLightSwitch;
		bool hasBlur;
		int blurPosX;
		int blurPosY;
		const uint16 *blurAlphaMap;
		uint blurWidth;
		uint blurHeight;
		float posXFloat;
		float posYFloat;
		float posZFloat;
		float directionAngleRad;
		float directionAngleRadZ;
		float speed;
	};

	struct FliesEffectData {
		bool lightable;
		bool unlightIfTooBright;
		bool isLarge;
		bool canBlur;
		float maxSpeed;
		float minSpeed;
		int maxAcceleration;
		float blurSpeedTreshold;
		float blurDistance;
		uint32 color32;
		int minFramesLit;
		int maxLightDuration;
	};

	MohawkEngine_Riven *_vm;

	uint _nextUpdateTime;
	int _updatePeriodMs;

	Common::Rect _gameRect;
	Graphics::Surface *_effectSurface;
	Graphics::Surface *_backSurface;
	Common::Array<Common::Rect> _screenSurfaceDirtyRects;
	Common::Array<Common::Rect> _effectsSurfaceDirtyRects;

	const FliesEffectData *_parameters;
	static const FliesEffectData _firefliesParameters;
	static const FliesEffectData _fliesParameters;

	Common::Array<FliesEffectEntry> _fly;

	void initFlies(uint16 count);
	void initFlyRandomPosition(uint index);
	void initFlyAtPosition(uint index, int posX, int posY, int posZ);

	void updateFlies();
	void updateFlyPosition(uint index);

	void draw();
	void updateScreen();

	void selectAlphaMap(bool horGridOffset, bool vertGridoffset, const uint16 **alphaMap, uint *width, uint *height);
	void colorBlending(uint32 flyColor, byte &r, byte &g, byte &b, int alpha);

	void addToScreenDirtyRects(const Common::Rect &rect);
	void addToEffectsDirtyRects(const Common::Rect &rect);
	void restoreEffectsSurface();

	int randomBetween(int min, int max);
};

} // End of namespace Mohawk

#endif