mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-12 22:51:11 +00:00
AGS: Separate sprite lists and batch lists in renderers
From upstream ccbf3d16788720e94e5362ff8aeae1e32b4febe5
This commit is contained in:
parent
a476850123
commit
9fff1dc1fa
@ -234,7 +234,7 @@ void ScummVMRendererGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBa
|
||||
if (_spriteBatches.size() <= index)
|
||||
_spriteBatches.resize(index + 1);
|
||||
ALSpriteBatch &batch = _spriteBatches[index];
|
||||
batch.List.clear();
|
||||
batch.ID = index;
|
||||
// TODO: correct offsets to have pre-scale (source) and post-scale (dest) offsets!
|
||||
const int src_w = desc.Viewport.GetWidth() / desc.Transform.ScaleX;
|
||||
const int src_h = desc.Viewport.GetHeight() / desc.Transform.ScaleY;
|
||||
@ -271,12 +271,12 @@ void ScummVMRendererGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBa
|
||||
}
|
||||
|
||||
void ScummVMRendererGraphicsDriver::ResetAllBatches() {
|
||||
for (ALSpriteBatches::iterator it = _spriteBatches.begin(); it != _spriteBatches.end(); ++it)
|
||||
it->List.clear();
|
||||
_spriteBatches.clear();
|
||||
_spriteList.clear();
|
||||
}
|
||||
|
||||
void ScummVMRendererGraphicsDriver::DrawSprite(int x, int y, IDriverDependantBitmap *bitmap) {
|
||||
_spriteBatches[_actSpriteBatch].List.push_back(ALDrawListEntry((ALSoftwareBitmap *)bitmap, x, y));
|
||||
_spriteList.push_back(ALDrawListEntry((ALSoftwareBitmap *)bitmap, _actSpriteBatch, x, y));
|
||||
}
|
||||
|
||||
void ScummVMRendererGraphicsDriver::SetScreenFade(int /*red*/, int /*green*/, int /*blue*/) {
|
||||
@ -289,7 +289,8 @@ void ScummVMRendererGraphicsDriver::SetScreenTint(int red, int green, int blue)
|
||||
_tint_green = green;
|
||||
_tint_blue = blue;
|
||||
if (((_tint_red > 0) || (_tint_green > 0) || (_tint_blue > 0)) && (_srcColorDepth > 8)) {
|
||||
_spriteBatches[_actSpriteBatch].List.push_back(ALDrawListEntry((ALSoftwareBitmap *)0x1, 0, 0));
|
||||
_spriteList.push_back(
|
||||
ALDrawListEntry(reinterpret_cast<ALSoftwareBitmap *>(DRAWENTRY_TINT), _actSpriteBatch, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,10 +306,11 @@ void ScummVMRendererGraphicsDriver::RenderToBackBuffer() {
|
||||
// that here would slow things down significantly, so if we ever go that way sprite caching will
|
||||
// be required (similarily to how AGS caches flipped/scaled object sprites now for).
|
||||
//
|
||||
for (size_t i = 0; i <= _actSpriteBatch; ++i) {
|
||||
const Rect &viewport = _spriteBatchDesc[i].Viewport;
|
||||
const SpriteTransform &transform = _spriteBatchDesc[i].Transform;
|
||||
const ALSpriteBatch &batch = _spriteBatches[i];
|
||||
for (size_t cur_spr = 0; cur_spr < _spriteList.size();) {
|
||||
const auto &batch_desc = _spriteBatchDesc[_spriteList[cur_spr].node];
|
||||
const ALSpriteBatch &batch = _spriteBatches[_spriteList[cur_spr].node];
|
||||
const Rect &viewport = batch_desc.Viewport;
|
||||
const SpriteTransform &transform = batch_desc.Transform;
|
||||
|
||||
virtualScreen->SetClip(viewport);
|
||||
Bitmap *surface = batch.Surface.get();
|
||||
@ -318,38 +320,38 @@ void ScummVMRendererGraphicsDriver::RenderToBackBuffer() {
|
||||
if (!batch.Opaque)
|
||||
surface->ClearTransparent();
|
||||
_stageVirtualScreen = surface;
|
||||
RenderSpriteBatch(batch, surface, transform.X, transform.Y);
|
||||
cur_spr = RenderSpriteBatch(batch, cur_spr, surface, transform.X, transform.Y);
|
||||
if (!batch.IsVirtualScreen)
|
||||
virtualScreen->StretchBlt(surface, RectWH(view_offx, view_offy, viewport.GetWidth(), viewport.GetHeight()),
|
||||
batch.Opaque ? kBitmap_Copy : kBitmap_Transparency);
|
||||
batch.Opaque ? kBitmap_Copy : kBitmap_Transparency);
|
||||
} else {
|
||||
RenderSpriteBatch(batch, virtualScreen, view_offx + transform.X, view_offy + transform.Y);
|
||||
cur_spr = RenderSpriteBatch(batch, cur_spr, virtualScreen, view_offx + transform.X, view_offy + transform.Y);
|
||||
}
|
||||
_stageVirtualScreen = virtualScreen;
|
||||
}
|
||||
ClearDrawLists();
|
||||
}
|
||||
|
||||
void ScummVMRendererGraphicsDriver::RenderSpriteBatch(const ALSpriteBatch &batch, Shared::Bitmap *surface, int surf_offx, int surf_offy) {
|
||||
const std::vector<ALDrawListEntry> &drawlist = batch.List;
|
||||
for (size_t i = 0; i < drawlist.size(); i++) {
|
||||
if (drawlist[i].bitmap == nullptr) {
|
||||
size_t ScummVMRendererGraphicsDriver::RenderSpriteBatch(const ALSpriteBatch &batch, size_t from, Bitmap *surface, int surf_offx, int surf_offy) {
|
||||
for (; (from < _spriteList.size()) && (_spriteList[from].node == batch.ID); ++from) {
|
||||
const auto &sprite = _spriteList[from];
|
||||
if (sprite.ddb == nullptr) {
|
||||
if (_nullSpriteCallback)
|
||||
_nullSpriteCallback(drawlist[i].x, drawlist[i].y);
|
||||
_nullSpriteCallback(sprite.x, sprite.y);
|
||||
else
|
||||
error("Unhandled attempt to draw null sprite");
|
||||
|
||||
continue;
|
||||
} else if (drawlist[i].bitmap == (ALSoftwareBitmap *)0x1) {
|
||||
} else if (sprite.ddb == reinterpret_cast<ALSoftwareBitmap *>(DRAWENTRY_TINT)) {
|
||||
// draw screen tint fx
|
||||
set_trans_blender(_tint_red, _tint_green, _tint_blue, 0);
|
||||
surface->LitBlendBlt(surface, 0, 0, 128);
|
||||
continue;
|
||||
}
|
||||
|
||||
ALSoftwareBitmap *bitmap = drawlist[i].bitmap;
|
||||
int drawAtX = drawlist[i].x + surf_offx;
|
||||
int drawAtY = drawlist[i].y + surf_offy;
|
||||
ALSoftwareBitmap *bitmap = sprite.ddb;
|
||||
int drawAtX = sprite.x + surf_offx;
|
||||
int drawAtY = sprite.y + surf_offy;
|
||||
|
||||
if (bitmap->_transparency >= 255) {
|
||||
} // fully transparent, do nothing
|
||||
@ -370,9 +372,10 @@ void ScummVMRendererGraphicsDriver::RenderSpriteBatch(const ALSpriteBatch &batch
|
||||
} else {
|
||||
// here _transparency is used as alpha (between 1 and 254), but 0 means opaque!
|
||||
GfxUtil::DrawSpriteWithTransparency(surface, bitmap->_bmp, drawAtX, drawAtY,
|
||||
bitmap->_transparency ? bitmap->_transparency : 255);
|
||||
bitmap->_transparency ? bitmap->_transparency : 255);
|
||||
}
|
||||
}
|
||||
return from;
|
||||
}
|
||||
|
||||
void ScummVMRendererGraphicsDriver::copySurface(const Graphics::Surface &src, bool mode) {
|
||||
|
@ -143,14 +143,13 @@ private:
|
||||
typedef SpriteDrawListEntry<ALSoftwareBitmap> ALDrawListEntry;
|
||||
// Software renderer's sprite batch
|
||||
struct ALSpriteBatch {
|
||||
// List of sprites to render
|
||||
std::vector<ALDrawListEntry> List;
|
||||
uint32_t ID = 0;
|
||||
// Intermediate surface which will be drawn upon and transformed if necessary
|
||||
std::shared_ptr<Bitmap> Surface;
|
||||
std::shared_ptr<Bitmap> Surface;
|
||||
// Whether surface is a virtual screen's region
|
||||
bool IsVirtualScreen;
|
||||
bool IsVirtualScreen = false;
|
||||
// Tells whether the surface is treated as opaque or transparent
|
||||
bool Opaque;
|
||||
bool Opaque = false;
|
||||
};
|
||||
typedef std::vector<ALSpriteBatch> ALSpriteBatches;
|
||||
|
||||
@ -181,10 +180,10 @@ public:
|
||||
int GetCompatibleBitmapFormat(int color_depth) override;
|
||||
IDriverDependantBitmap *CreateDDB(int width, int height, int color_depth, bool opaque) override;
|
||||
IDriverDependantBitmap *CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) override;
|
||||
void UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) override;
|
||||
void DestroyDDB(IDriverDependantBitmap *bitmap) override;
|
||||
void UpdateDDBFromBitmap(IDriverDependantBitmap *ddb, Bitmap *bitmap, bool hasAlpha) override;
|
||||
void DestroyDDB(IDriverDependantBitmap *ddb) override;
|
||||
|
||||
void DrawSprite(int x, int y, IDriverDependantBitmap *bitmap) override;
|
||||
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;
|
||||
|
||||
@ -252,7 +251,10 @@ private:
|
||||
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;
|
||||
@ -263,7 +265,7 @@ private:
|
||||
// Unset parameters and release resources related to the display mode
|
||||
void ReleaseDisplayMode();
|
||||
// Renders single sprite batch on the precreated surface
|
||||
void RenderSpriteBatch(const ALSpriteBatch &batch, Shared::Bitmap *surface, int surf_offx, int surf_offy);
|
||||
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 offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue);
|
||||
void highcolor_fade_out(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue);
|
||||
|
@ -71,19 +71,15 @@ typedef std::vector<SpriteBatchDesc> SpriteBatchDescs;
|
||||
// The single sprite entry in the render list
|
||||
template<class T_DDB>
|
||||
struct SpriteDrawListEntry {
|
||||
T_DDB *bitmap; // TODO: use shared pointer?
|
||||
int x, y; // sprite position, in camera coordinates
|
||||
bool skip;
|
||||
T_DDB *ddb = nullptr; // TODO: use shared pointer?
|
||||
uint32_t node = 0; // sprite batch / scene node index
|
||||
int x = 0, y = 0; // sprite position, in local batch / node coordinates
|
||||
bool skip = false;
|
||||
|
||||
SpriteDrawListEntry()
|
||||
: bitmap(nullptr)
|
||||
, x(0)
|
||||
, y(0)
|
||||
, skip(false) {
|
||||
}
|
||||
|
||||
SpriteDrawListEntry(T_DDB *ddb, int x_ = 0, int y_ = 0)
|
||||
: bitmap(ddb)
|
||||
SpriteDrawListEntry() = default;
|
||||
SpriteDrawListEntry(T_DDB * ddb_, uint32_t node_, int x_, int y_)
|
||||
: ddb(ddb_)
|
||||
, node(node_)
|
||||
, x(x_)
|
||||
, y(y_)
|
||||
, skip(false) {
|
||||
@ -123,6 +119,11 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
// Special internal values, applied to DrawListEntry
|
||||
static const intptr_t DRAWENTRY_STAGECALLBACK = 0x0;
|
||||
static const intptr_t DRAWENTRY_FADE = 0x1;
|
||||
static const intptr_t DRAWENTRY_TINT = 0x2;
|
||||
|
||||
// Called after graphics driver was initialized for use for the first time
|
||||
virtual void OnInit();
|
||||
// Called just before graphics mode is going to be uninitialized and its
|
||||
|
Loading…
x
Reference in New Issue
Block a user