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 //=============================================================================
24 //
25 // Software graphics factory, draws raw bitmaps onto a virtual screen,
26 // converts to SDL_Texture and finally presents with SDL_Renderer.
27 //
28 // TODO: replace nearest-neighbour software filter with SDL's own accelerated
29 // scaling, maybe add more filter types if SDL renderer supports them.
30 // Only keep Hqx filter as a software option (might need to change how the
31 // filter code works).
32 //
33 //=============================================================================
34 
35 #ifndef AGS_ENGINE_GFX_ALI_3D_SCUMMVM_H
36 #define AGS_ENGINE_GFX_ALI_3D_SCUMMVM_H
37 
38 #include "ags/lib/std/memory.h"
39 #include "ags/lib/std/vector.h"
40 #include "ags/shared/core/platform.h"
41 #include "ags/shared/gfx/bitmap.h"
42 #include "ags/engine/gfx/ddb.h"
43 #include "ags/engine/gfx/gfx_driver_factory_base.h"
44 #include "ags/engine/gfx/gfx_driver_base.h"
45 
46 namespace AGS3 {
47 namespace AGS {
48 namespace Engine {
49 namespace ALSW {
50 
51 class ScummVMRendererGraphicsDriver;
52 class ScummVMRendererGfxFilter;
53 using AGS::Shared::Bitmap;
54 
55 enum RendererFlip {
56 	FLIP_NONE = 0x00000000,       /**< Do not flip */
57 	FLIP_HORIZONTAL = 0x00000001, /**< flip horizontally */
58 	FLIP_VERTICAL = 0x00000002    /**< flip vertically */
59 };
60 
61 class ALSoftwareBitmap : public IDriverDependantBitmap {
62 public:
63 	// NOTE by CJ:
64 	// Transparency is a bit counter-intuitive
65 	// 0=not transparent, 255=invisible, 1..254 barely visible .. mostly visible
SetTransparency(int transparency)66 	void SetTransparency(int transparency) override {
67 		_transparency = transparency;
68 	}
SetFlippedLeftRight(bool isFlipped)69 	void SetFlippedLeftRight(bool isFlipped) override {
70 		_flipped = isFlipped;
71 	}
72 	void SetStretch(int width, int height, bool useResampler = true) override {
73 		_stretchToWidth = width;
74 		_stretchToHeight = height;
75 	}
GetWidth()76 	int GetWidth() override {
77 		return _width;
78 	}
GetHeight()79 	int GetHeight() override {
80 		return _height;
81 	}
GetColorDepth()82 	int GetColorDepth() override {
83 		return _colDepth;
84 	}
SetLightLevel(int lightLevel)85 	void SetLightLevel(int lightLevel) override {
86 	}
SetTint(int red,int green,int blue,int tintSaturation)87 	void SetTint(int red, int green, int blue, int tintSaturation) override {
88 	}
89 
90 	Bitmap *_bmp;
91 	int _width, _height;
92 	int _colDepth;
93 	bool _flipped;
94 	int _stretchToWidth, _stretchToHeight;
95 	bool _opaque; // no mask color
96 	bool _hasAlpha;
97 	int _transparency;
98 
ALSoftwareBitmap(Bitmap * bmp,bool opaque,bool hasAlpha)99 	ALSoftwareBitmap(Bitmap *bmp, bool opaque, bool hasAlpha) {
100 		_bmp = bmp;
101 		_width = bmp->GetWidth();
102 		_height = bmp->GetHeight();
103 		_colDepth = bmp->GetColorDepth();
104 		_flipped = false;
105 		_stretchToWidth = 0;
106 		_stretchToHeight = 0;
107 		_transparency = 0;
108 		_opaque = opaque;
109 		_hasAlpha = hasAlpha;
110 	}
111 
GetWidthToRender()112 	int GetWidthToRender() {
113 		return (_stretchToWidth > 0) ? _stretchToWidth : _width;
114 	}
GetHeightToRender()115 	int GetHeightToRender() {
116 		return (_stretchToHeight > 0) ? _stretchToHeight : _height;
117 	}
118 
Dispose()119 	void Dispose() {
120 		// do we want to free the bitmap?
121 	}
122 
~ALSoftwareBitmap()123 	~ALSoftwareBitmap() override {
124 		Dispose();
125 	}
126 };
127 
128 
129 class ScummVMRendererGfxModeList : public IGfxModeList {
130 public:
ScummVMRendererGfxModeList(const std::vector<DisplayMode> & modes)131 	ScummVMRendererGfxModeList(const std::vector<DisplayMode> &modes)
132 		: _modes(modes) {
133 	}
134 
GetModeCount()135 	int GetModeCount() const override {
136 		return _modes.size();
137 	}
138 
GetMode(int index,DisplayMode & mode)139 	bool GetMode(int index, DisplayMode &mode) const override {
140 		if (index >= 0 && (size_t)index < _modes.size()) {
141 			mode = _modes[index];
142 			return true;
143 		}
144 		return false;
145 	}
146 
147 private:
148 	std::vector<DisplayMode> _modes;
149 };
150 
151 
152 typedef SpriteDrawListEntry<ALSoftwareBitmap> ALDrawListEntry;
153 // Software renderer's sprite batch
154 struct ALSpriteBatch {
155 	// List of sprites to render
156 	std::vector<ALDrawListEntry> List;
157 	// Intermediate surface which will be drawn upon and transformed if necessary
158 	std::shared_ptr<Bitmap>      Surface;
159 	// Whether surface is a virtual screen's region
160 	bool                         IsVirtualScreen;
161 	// Tells whether the surface is treated as opaque or transparent
162 	bool                         Opaque;
163 };
164 typedef std::vector<ALSpriteBatch> ALSpriteBatches;
165 
166 
167 class ScummVMRendererGraphicsDriver : public GraphicsDriverBase {
168 public:
169 	ScummVMRendererGraphicsDriver();
170 	~ScummVMRendererGraphicsDriver() override;
171 
GetDriverName()172 	const char *GetDriverName() override {
173 		return "SDL 2D Software renderer";
174 	}
GetDriverID()175 	const char *GetDriverID() override {
176 		return "Software";
177 	}
178 	void SetTintMethod(TintMethod method) override;
179 	bool SetDisplayMode(const DisplayMode &mode) override;
180 	void UpdateDeviceScreen(const Size &screen_sz) override;
181 	bool SetNativeResolution(const GraphicResolution &native_res) override;
182 	bool SetRenderFrame(const Rect &dst_rect) override;
183 	bool IsModeSupported(const DisplayMode &mode) override;
184 	int  GetDisplayDepthForNativeDepth(int native_color_depth) const override;
185 	IGfxModeList *GetSupportedModeList(int color_depth) override;
186 	PGfxFilter GetGraphicsFilter() const override;
187 	void UnInit();
188 	// Clears the screen rectangle. The coordinates are expected in the **native game resolution**.
189 	void ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) override;
190 	int  GetCompatibleBitmapFormat(int color_depth) override;
191 	IDriverDependantBitmap *CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) override;
192 	void UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) override;
193 	void DestroyDDB(IDriverDependantBitmap *bitmap) override;
194 
195 	void DrawSprite(int x, int y, IDriverDependantBitmap *bitmap) override;
196 	void SetScreenFade(int red, int green, int blue) override;
197 	void SetScreenTint(int red, int green, int blue) override;
198 
199 	void RenderToBackBuffer() override;
200 	void Render() override;
201 	void Render(int xoff, int yoff, GlobalFlipType flip) override;
202 	bool GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) override;
203 	void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) override;
204 	void FadeIn(int speed, PALETTE pal, int targetColourRed, int targetColourGreen, int targetColourBlue) override;
205 	void BoxOutEffect(bool blackingOut, int speed, int delay) override;
206 	bool SupportsGammaControl() override;
207 	void SetGamma(int newGamma) override;
UseSmoothScaling(bool enabled)208 	void UseSmoothScaling(bool enabled) override {
209 	}
EnableVsyncBeforeRender(bool enabled)210 	void EnableVsyncBeforeRender(bool enabled) override {
211 	}
212 	void Vsync() override;
RenderSpritesAtScreenResolution(bool enabled,int supersampling)213 	void RenderSpritesAtScreenResolution(bool enabled, int supersampling) override {
214 	}
RequiresFullRedrawEachFrame()215 	bool RequiresFullRedrawEachFrame() override {
216 		return false;
217 	}
HasAcceleratedTransform()218 	bool HasAcceleratedTransform() override {
219 		return false;
220 	}
UsesMemoryBackBuffer()221 	bool UsesMemoryBackBuffer() override {
222 		return true;
223 	}
224 	Bitmap *GetMemoryBackBuffer() override;
225 	void SetMemoryBackBuffer(Bitmap *backBuffer) override;
226 	Bitmap *GetStageBackBuffer(bool mark_dirty) override;
GetStageMatrixes(RenderMatrixes & rm)227 	bool GetStageMatrixes(RenderMatrixes &rm) override {
228 		return false; /* not supported */
229 	}
230 
231 	typedef std::shared_ptr<ScummVMRendererGfxFilter> PSDLRenderFilter;
232 
233 	void SetGraphicsFilter(PSDLRenderFilter filter);
234 
235 private:
236 	Graphics::Screen *_screen = nullptr;
237 	PSDLRenderFilter _filter;
238 
239 	bool _hasGamma = false;
240 #ifdef TODO
241 	uint16 _defaultGammaRed[256] {};
242 	uint16 _defaultGammaGreen[256] {};
243 	uint16 _defaultGammaBlue[256] {};
244 #endif
245 
246 	RendererFlip _renderFlip = FLIP_NONE;
247 	/*  SDL_Renderer *_renderer = nullptr;
248 	    SDL_Texture *_screenTex = nullptr; */
249 	// BITMAP struct for wrapping screen texture locked pixels, so that we may use blit()
250 	BITMAP *_fakeTexBitmap = nullptr;
251 	unsigned char *_lastTexPixels = nullptr;
252 	int _lastTexPitch = -1;
253 
254 	// Original virtual screen created and managed by the renderer.
255 	std::unique_ptr<Bitmap> _origVirtualScreen;
256 	// Current virtual screen bitmap; may be either pointing to _origVirtualScreen,
257 	// or provided by external user (for example - plugin).
258 	// Its pixels are copied to the video texture to be presented by SDL_Renderer.
259 	Bitmap *virtualScreen;
260 	// Stage screen meant for particular rendering stages, may be referencing
261 	// actual virtual screen or separate bitmap of different size that is
262 	// blitted to virtual screen at the stage finalization.
263 	Bitmap *_stageVirtualScreen;
264 	int _tint_red, _tint_green, _tint_blue;
265 
266 	ALSpriteBatches _spriteBatches;
267 
268 	void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) override;
269 	void ResetAllBatches() override;
270 
271 	// Use gfx filter to create a new virtual screen
272 	void CreateVirtualScreen();
273 	void DestroyVirtualScreen();
274 	// Unset parameters and release resources related to the display mode
275 	void ReleaseDisplayMode();
276 	// Renders single sprite batch on the precreated surface
277 	void RenderSpriteBatch(const ALSpriteBatch &batch, Shared::Bitmap *surface, int surf_offx, int surf_offy);
278 
279 	void highcolor_fade_in(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue);
280 	void highcolor_fade_out(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue);
281 	void __fade_from_range(PALETTE source, PALETTE dest, int speed, int from, int to);
282 	void __fade_out_range(int speed, int from, int to, int targetColourRed, int targetColourGreen, int targetColourBlue);
283 	// Copy raw screen bitmap pixels to the screen
284 	void BlitToScreen();
285 	void copySurface(const Graphics::Surface &src, bool mode);
286 	// Render bitmap on screen
Present()287 	void Present() { BlitToScreen(); }
288 };
289 
290 
291 class ScummVMRendererGraphicsFactory : public GfxDriverFactoryBase<ScummVMRendererGraphicsDriver, ScummVMRendererGfxFilter> {
292 public:
293 	~ScummVMRendererGraphicsFactory() override;
294 
295 	size_t               GetFilterCount() const override;
296 	const GfxFilterInfo *GetFilterInfo(size_t index) const override;
297 	String               GetDefaultFilterID() const override;
298 
299 	static ScummVMRendererGraphicsFactory *GetFactory();
300 
301 private:
302 	ScummVMRendererGraphicsDriver *EnsureDriverCreated() override;
303 	ScummVMRendererGfxFilter *CreateFilter(const String &id) override;
304 
305 	static ScummVMRendererGraphicsFactory *_factory;
306 };
307 
308 } // namespace ALSW
309 } // namespace Engine
310 } // namespace AGS
311 } // namespace AGS3
312 
313 #endif
314