File: ali_3d_scummvm.h

package info (click to toggle)
scummvm 2.9.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 450,268 kB
  • sloc: cpp: 4,297,604; asm: 28,322; python: 12,901; sh: 11,219; java: 8,477; xml: 7,843; perl: 2,633; ansic: 2,465; yacc: 1,670; javascript: 1,020; makefile: 933; lex: 578; awk: 275; objc: 82; sed: 11; php: 1
file content (330 lines) | stat: -rw-r--r-- 12,039 bytes parent folder | download | duplicates (2)
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
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
/* 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 3 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, see <http://www.gnu.org/licenses/>.
 *
 */

//=============================================================================
//
// Software graphics factory, draws raw bitmaps onto a virtual screen,
// converts to SDL_Texture and finally presents with SDL_Renderer.
//
// TODO: replace nearest-neighbour software filter with SDL's own accelerated
// scaling, maybe add more filter types if SDL renderer supports them.
// Only keep Hqx filter as a software option (might need to change how the
// filter code works).
//
//=============================================================================

#ifndef AGS_ENGINE_GFX_ALI_3D_SCUMMVM_H
#define AGS_ENGINE_GFX_ALI_3D_SCUMMVM_H

#include "common/std/memory.h"
#include "common/std/vector.h"
#include "ags/shared/core/platform.h"
#include "ags/shared/gfx/bitmap.h"
#include "ags/engine/gfx/ddb.h"
#include "ags/engine/gfx/gfx_driver_factory_base.h"
#include "ags/engine/gfx/gfx_driver_base.h"

namespace AGS3 {
namespace AGS {
namespace Engine {
namespace ALSW {

class ScummVMRendererGraphicsDriver;
class ScummVMRendererGfxFilter;
using AGS::Shared::Bitmap;

enum RendererFlip {
	FLIP_NONE = 0x00000000,       /**< Do not flip */
	FLIP_HORIZONTAL = 0x00000001, /**< flip horizontally */
	FLIP_VERTICAL = 0x00000002    /**< flip vertically */
};

class ALSoftwareBitmap : public BaseDDB {
public:
	uint32_t GetRefID() const override { return UINT32_MAX /* not supported */; }

	int  GetAlpha() const override {
		return _alpha;
	}
	void SetAlpha(int alpha) override {
		_alpha = alpha;
	}
	void SetFlippedLeftRight(bool isFlipped) override {
		_flipped = isFlipped;
	}
	void SetStretch(int width, int height, bool /*useResampler*/) override {
		_stretchToWidth = width;
		_stretchToHeight = height;
	}
	void SetLightLevel(int /*lightLevel*/) override {}
	void SetTint(int /*red*/, int /*green*/, int /*blue*/, int /*tintSaturation*/) override {}

	Bitmap *_bmp = nullptr;
	bool _flipped = false;
	int _stretchToWidth = 0, _stretchToHeight = 0;
	int _alpha = 255;

	ALSoftwareBitmap(int width, int height, int color_depth, bool opaque) {
		_width = width;
		_height = height;
		_colDepth = color_depth;
		_opaque = opaque;
		_stretchToWidth = _width;
		_stretchToHeight = _height;
	}

	ALSoftwareBitmap(Bitmap *bmp, bool has_alpha, bool opaque) {
		_bmp = bmp;
		_width = bmp->GetWidth();
		_height = bmp->GetHeight();
		_colDepth = bmp->GetColorDepth();
		_opaque = opaque;
		_hasAlpha = has_alpha;
		_stretchToWidth = _width;
		_stretchToHeight = _height;
	}

	int GetWidthToRender() {
		return _stretchToWidth;
	}
	int GetHeightToRender() {
		return _stretchToHeight;
	}

	~ALSoftwareBitmap() override = default;
};


class ScummVMRendererGfxModeList : public IGfxModeList {
public:
	ScummVMRendererGfxModeList(const std::vector<DisplayMode> &modes)
		: _modes(modes) {
	}

	int GetModeCount() const override {
		return _modes.size();
	}

	bool GetMode(int index, DisplayMode &mode) const override {
		if (index >= 0 && (size_t)index < _modes.size()) {
			mode = _modes[index];
			return true;
		}
		return false;
	}

private:
	std::vector<DisplayMode> _modes;
};


typedef SpriteDrawListEntry<ALSoftwareBitmap> ALDrawListEntry;
// Software renderer's sprite batch
struct ALSpriteBatch {
	uint32_t ID = 0u;
	// Clipping viewport, also used as a destination for blitting optional Surface;
	// in *relative* coordinates to parent surface.
	Rect Viewport;
	// Optional model transformation, to be applied to each sprite
	SpriteTransform Transform;
	// Intermediate surface which will be drawn upon and transformed if necessary
	std::shared_ptr<Bitmap> Surface;
	// Whether surface is a parent surface's region (e.g. virtual screen)
	bool IsParentRegion = false;
	// Tells whether the surface is treated as opaque or transparent
	bool Opaque = false;
};
typedef std::vector<ALSpriteBatch> ALSpriteBatches;


class ScummVMRendererGraphicsDriver : public GraphicsDriverBase {
public:
	ScummVMRendererGraphicsDriver();
	~ScummVMRendererGraphicsDriver() override;

	const char *GetDriverID() override {
		return "Software";
	}

	bool RequiresFullRedrawEachFrame() override { return false; }
	bool HasAcceleratedTransform() override { return false; }
	bool UsesMemoryBackBuffer() override { return true; }
	bool ShouldReleaseRenderTargets() override { return false; }

	const char *GetDriverName() override {
		return "ScummVM 2D renderer";
	}

	void SetTintMethod(TintMethod /*method*/) override;
	bool SetDisplayMode(const DisplayMode &mode) override;
	void UpdateDeviceScreen(const Size &screen_sz) override;
	bool SetNativeResolution(const GraphicResolution &native_res) override;
	bool SetRenderFrame(const Rect &dst_rect) override;
	bool IsModeSupported(const DisplayMode &mode) override;
	int  GetDisplayDepthForNativeDepth(int native_color_depth) const override;
	IGfxModeList *GetSupportedModeList(int color_depth) override;
	PGfxFilter GetGraphicsFilter() const override;
	void UnInit();
	// Clears the screen rectangle. The coordinates are expected in the **native game resolution**.
	void ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) override;
	int  GetCompatibleBitmapFormat(int color_depth) override;
	size_t GetAvailableTextureMemory() override {
		// not using textures for sprites anyway
		return 0;
	}
	IDriverDependantBitmap *CreateDDB(int width, int height, int color_depth, bool opaque) override;
	IDriverDependantBitmap *CreateDDBFromBitmap(Bitmap *bitmap, bool has_alpha, bool opaque) override;
	IDriverDependantBitmap *CreateRenderTargetDDB(int width, int height, int color_depth, bool opaque) override;
	void UpdateDDBFromBitmap(IDriverDependantBitmap *ddb, Bitmap *bitmap, bool has_alpha) override;
	void DestroyDDB(IDriverDependantBitmap *ddb) override;

	IDriverDependantBitmap *GetSharedDDB(uint32_t /*sprite_id*/,
		Bitmap *bitmap, bool has_alpha, bool opaque) override {
		// Software renderer does not require a texture cache, because it uses bitmaps directly
		return CreateDDBFromBitmap(bitmap, has_alpha, opaque);
	}

	void UpdateSharedDDB(uint32_t /*sprite_id*/, Bitmap */*bitmap*/, bool /*has_alpha*/, bool /*opaque*/) override {
		/* do nothing */
	}
	void ClearSharedDDB(uint32_t /*sprite_id*/) override {
		/* do nothing */
	}

	void DrawSprite(int x, int y, IDriverDependantBitmap *ddb) override;
	void SetScreenFade(int red, int green, int blue) override;
	void SetScreenTint(int red, int green, int blue) override;
	void SetStageScreen(const Size &sz, int x = 0, int y = 0) override;

	void RenderToBackBuffer() override;
	void Render() override;
	void Render(int xoff, int yoff, Shared::GraphicFlip flip) override;
	bool GetCopyOfScreenIntoBitmap(Bitmap *destination, const Rect *src_rect, bool at_native_res, GraphicResolution *want_fmt,
								   uint32_t batch_skip_filter = 0u) override;
	void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue,
				 uint32_t batch_skip_filter = 0u) override;
	void FadeIn(int speed, PALETTE pal, int targetColourRed, int targetColourGreen, int targetColourBlue,
				uint32_t batch_skip_filter = 0u) override;
	void BoxOutEffect(bool blackingOut, int speed, int delay, uint32_t batch_skip_filter = 0u) override;
	bool SupportsGammaControl() override;
	void SetGamma(int newGamma) override;
	void UseSmoothScaling(bool /*enabled*/) override {}
	bool DoesSupportVsyncToggle() override;
	void RenderSpritesAtScreenResolution(bool /*enabled*/) override {}
	Bitmap *GetMemoryBackBuffer() override;
	void SetMemoryBackBuffer(Bitmap *backBuffer) override;
	Bitmap *GetStageBackBuffer(bool mark_dirty) override;
	void SetStageBackBuffer(Bitmap *backBuffer) override;
	bool GetStageMatrixes(RenderMatrixes & /*rm*/) override {
		return false; /* not supported */
	}

	typedef std::shared_ptr<ScummVMRendererGfxFilter> PSDLRenderFilter;

	void SetGraphicsFilter(PSDLRenderFilter filter);

protected:
	bool SetVsyncImpl(bool vsync, bool &vsync_res) override;
	size_t GetLastDrawEntryIndex() override {
		return _spriteList.size();
	}

private:
	Graphics::Screen *_screen = nullptr;
	PSDLRenderFilter _filter;

	bool _hasGamma = false;
#ifdef TODO
	uint16 _defaultGammaRed[256] {};
	uint16 _defaultGammaGreen[256] {};
	uint16 _defaultGammaBlue[256] {};
	int _gamma = 100;
#endif

	/*  SDL_Renderer *_renderer = nullptr;
	    SDL_Texture *_screenTex = nullptr; */
	// BITMAP struct for wrapping screen texture locked pixels, so that we may use blit()
	BITMAP *_fakeTexBitmap = nullptr;
	unsigned char *_lastTexPixels = nullptr;
	int _lastTexPitch = -1;

	// Original virtual screen created and managed by the renderer.
	std::unique_ptr<Bitmap> _origVirtualScreen;
	// Current virtual screen bitmap; may be either pointing to _origVirtualScreen,
	// or provided by external user (for example - plugin).
	// Its pixels are copied to the video texture to be presented by SDL_Renderer.
	Bitmap *virtualScreen;
	// Stage screen meant for particular rendering stages, may be referencing
	// actual virtual screen or separate bitmap of different size that is
	// blitted to virtual screen at the stage finalization.
	Bitmap *_stageVirtualScreen;
	int _tint_red, _tint_green, _tint_blue;

	// Sprite batches (parent scene nodes)
	ALSpriteBatches _spriteBatches;
	// List of sprites to render
	std::vector<ALDrawListEntry> _spriteList;

	void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) override;
	void ResetAllBatches() override;

	// Use gfx filter to create a new virtual screen
	void CreateVirtualScreen();
	void DestroyVirtualScreen();
	// Unset parameters and release resources related to the display mode
	void ReleaseDisplayMode();
	// Renders single sprite batch on the precreated surface
	size_t RenderSpriteBatch(const ALSpriteBatch &batch, size_t from, Shared::Bitmap *surface, int surf_offx, int surf_offy);

	void highcolor_fade_in(Bitmap *vs, void(*draw_callback)(), int speed, int targetColourRed, int targetColourGreen, int targetColourBlue);
	void highcolor_fade_out(Bitmap *vs, void(*draw_callback)(), int speed, int targetColourRed, int targetColourGreen, int targetColourBlue);
	void __fade_from_range(PALETTE source, PALETTE dest, int speed, int from, int to);
	void __fade_out_range(int speed, int from, int to, int targetColourRed, int targetColourGreen, int targetColourBlue);
	// Copy raw screen bitmap pixels to the screen
	void copySurface(const Graphics::Surface &src, bool mode);
	// Render bitmap on screen
	void Present(int xoff = 0, int yoff = 0, Shared::GraphicFlip flip = Shared::kFlip_None);
};


class ScummVMRendererGraphicsFactory : public GfxDriverFactoryBase<ScummVMRendererGraphicsDriver, ScummVMRendererGfxFilter> {
public:
	~ScummVMRendererGraphicsFactory() override;

	size_t               GetFilterCount() const override;
	const GfxFilterInfo *GetFilterInfo(size_t index) const override;
	String               GetDefaultFilterID() const override;

	static ScummVMRendererGraphicsFactory *GetFactory();

private:
	ScummVMRendererGraphicsDriver *EnsureDriverCreated() override;
	ScummVMRendererGfxFilter *CreateFilter(const String &id) override;

	static ScummVMRendererGraphicsFactory *_factory;
};

} // namespace ALSW
} // namespace Engine
} // namespace AGS
} // namespace AGS3

#endif