Initial commit
This commit is contained in:
330
engines/ags/engine/gfx/ali_3d_scummvm.h
Normal file
330
engines/ags/engine/gfx/ali_3d_scummvm.h
Normal file
@@ -0,0 +1,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
|
||||
Reference in New Issue
Block a user