scummvm/engines/ags/engine/gfx/ali_3d_scummvm.h
Walter Agazzi 5d58384af2 AGS: remove "supersampling" setting, as not entirely supported
This setting comes from the original mobile port of AGS, but it's not clear whether it was
useful. More importantly, there are issues with this:
1. It was never implemented in another hardware accelerated driver (Direct3D), being
exclusive to OpenGL.
2. It was never added to standard setup, so not very visible.
3. It's not clear whether it was working properly all this time. There were multiple changes to graphic renderers, and some of them may assume that rendering at "native resolution" is done at exactly, well, native resolution.
2024-10-30 18:07:42 +02:00

330 lines
12 KiB
C++

/* 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