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
|