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