Refactor things referencing VideoBuffer internals
This commit is contained in:
parent
b56d3cf611
commit
7f84887f6d
@ -94,26 +94,22 @@ String format::CleanString(String dirtyString, bool ascii, bool color, bool newl
|
||||
return dirtyString;
|
||||
}
|
||||
|
||||
std::vector<char> format::VideoBufferToPPM(const VideoBuffer & vidBuf)
|
||||
std::vector<char> format::VideoBufferToPPM(VideoBuffer const &vidBuf)
|
||||
{
|
||||
std::vector<char> data;
|
||||
char buffer[256];
|
||||
sprintf(buffer, "P6\n%d %d\n255\n", vidBuf.Width, vidBuf.Height);
|
||||
data.insert(data.end(), buffer, buffer+strlen(buffer));
|
||||
sprintf(buffer, "P6\n%d %d\n255\n", vidBuf.Size().X, vidBuf.Size().Y);
|
||||
data.insert(data.end(), buffer, buffer + strlen(buffer));
|
||||
|
||||
unsigned char * currentRow = new unsigned char[vidBuf.Width*3];
|
||||
for(int y = 0; y < vidBuf.Height; y++)
|
||||
data.reserve(data.size() + vidBuf.Size().X * vidBuf.Size().Y * 3);
|
||||
|
||||
for (int i = 0; i < vidBuf.Size().X * vidBuf.Size().Y; i++)
|
||||
{
|
||||
int rowPos = 0;
|
||||
for(int x = 0; x < vidBuf.Width; x++)
|
||||
{
|
||||
currentRow[rowPos++] = PIXR(vidBuf.Buffer[(y*vidBuf.Width)+x]);
|
||||
currentRow[rowPos++] = PIXG(vidBuf.Buffer[(y*vidBuf.Width)+x]);
|
||||
currentRow[rowPos++] = PIXB(vidBuf.Buffer[(y*vidBuf.Width)+x]);
|
||||
}
|
||||
data.insert(data.end(), currentRow, currentRow+(vidBuf.Width*3));
|
||||
auto colour = RGB<uint8_t>::Unpack(vidBuf.Data()[i]);
|
||||
data.push_back(colour.Red);
|
||||
data.push_back(colour.Green);
|
||||
data.push_back(colour.Blue);
|
||||
}
|
||||
delete [] currentRow;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -13,20 +13,15 @@ int ThumbnailRendererTask::QueueSize()
|
||||
return queueSize;
|
||||
}
|
||||
|
||||
ThumbnailRendererTask::ThumbnailRendererTask(GameSave const &save, Vec2<int> size, bool autoRescale, bool decorations, bool fire):
|
||||
ThumbnailRendererTask::ThumbnailRendererTask(GameSave const &save, Vec2<int> size, bool decorations, bool fire):
|
||||
save(std::make_unique<GameSave>(save)),
|
||||
size(size),
|
||||
decorations(decorations),
|
||||
fire(fire),
|
||||
autoRescale(autoRescale)
|
||||
fire(fire)
|
||||
{
|
||||
queueSize += 1;
|
||||
}
|
||||
|
||||
ThumbnailRendererTask::ThumbnailRendererTask(GameSave *save, int width, int height, bool autoRescale, bool decorations, bool fire):
|
||||
ThumbnailRendererTask(*save, Vec2(width, height), autoRescale, decorations, fire)
|
||||
{}
|
||||
|
||||
ThumbnailRendererTask::~ThumbnailRendererTask()
|
||||
{
|
||||
queueSize -= 1;
|
||||
@ -37,15 +32,8 @@ bool ThumbnailRendererTask::doWork()
|
||||
thumbnail = std::unique_ptr<VideoBuffer>(SaveRenderer::Ref().Render(save.get(), decorations, fire));
|
||||
if (thumbnail)
|
||||
{
|
||||
if (autoRescale)
|
||||
{
|
||||
thumbnail->ResizeToFit(size, true);
|
||||
size = thumbnail->Size();
|
||||
}
|
||||
else
|
||||
{
|
||||
thumbnail->Resize(size);
|
||||
}
|
||||
thumbnail->ResizeToFit(size, true);
|
||||
size = thumbnail->Size();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -12,15 +12,12 @@ class ThumbnailRendererTask : public AbandonableTask
|
||||
Vec2<int> size;
|
||||
bool decorations;
|
||||
bool fire;
|
||||
bool autoRescale;
|
||||
std::unique_ptr<VideoBuffer> thumbnail;
|
||||
|
||||
static int queueSize;
|
||||
|
||||
public:
|
||||
ThumbnailRendererTask(GameSave const &, Vec2<int> size, bool autoRescale, bool decorations, bool fire);
|
||||
[[deprecated("Use ThumbnailRendererTask(GameSave const &, Vec2<int>, bool, bool, bool)")]]
|
||||
ThumbnailRendererTask(GameSave *save, int width, int height, bool autoRescale = false, bool decorations = true, bool fire = true);
|
||||
ThumbnailRendererTask(GameSave const &, Vec2<int> size, bool decorations, bool fire);
|
||||
virtual ~ThumbnailRendererTask();
|
||||
|
||||
virtual bool doWork() override;
|
||||
|
@ -59,8 +59,6 @@ struct yExtent: extentStorage<Extent>
|
||||
template<typename T, size_t Width = DynamicExtent, size_t Height = DynamicExtent>
|
||||
class PlaneAdapter: xExtent<Width>, yExtent<Height>
|
||||
{
|
||||
friend class VideoBuffer; // TODO: remove
|
||||
|
||||
using value_type = std::remove_reference_t<decltype(std::declval<T>()[0])>;
|
||||
using iterator = decltype(std::begin(std::declval<T &>()));
|
||||
using const_iterator = decltype(std::begin(std::declval<T const &>()));
|
||||
|
@ -118,6 +118,14 @@ struct Vec2
|
||||
return (*this + Vec2<T>(0.5, 0.5)).Floor();
|
||||
}
|
||||
|
||||
Vec2<T> Clamp(Rect<T> rect) const
|
||||
{
|
||||
return Vec2<T>(
|
||||
std::clamp(X, rect.TopLeft.X, rect.BottomRight.X),
|
||||
std::clamp(Y, rect.TopLeft.Y, rect.BottomRight.Y)
|
||||
);
|
||||
}
|
||||
|
||||
// Return a rectangle starting at origin, whose dimensions match this vector
|
||||
template<typename S = T, typename = std::enable_if_t<std::is_integral_v<S>>>
|
||||
constexpr inline Rect<T> OriginRect() const
|
||||
@ -382,6 +390,12 @@ public:
|
||||
return BottomRight - TopLeft + Vec2<T>(1, 1);
|
||||
}
|
||||
|
||||
template<typename S>
|
||||
Rect<decltype(std::declval<T>() + std::declval<S>())> Inset(S delta) const
|
||||
{
|
||||
return Rect<decltype(std::declval<T>() + std::declval<S>())>(TopLeft + Vec2(delta, delta), BottomRight - Vec2(delta, delta));
|
||||
}
|
||||
|
||||
template<IterationDirection D1, IterationDirection D2, typename S = T, typename = std::enable_if_t<std::is_integral_v<T>>>
|
||||
constexpr auto Range() const
|
||||
{
|
||||
|
@ -555,8 +555,8 @@ void Graphics::draw_rgba_image(const pixel *data, int w, int h, int x, int y, fl
|
||||
|
||||
VideoBuffer Graphics::DumpFrame()
|
||||
{
|
||||
VideoBuffer newBuffer(WINDOW);
|
||||
std::copy_n(video.data(), WINDOW.X * WINDOW.Y, newBuffer.Data());
|
||||
VideoBuffer newBuffer(video.Size());
|
||||
std::copy_n(video.data(), video.Size().X * video.Size().Y, newBuffer.Data());
|
||||
return newBuffer;
|
||||
}
|
||||
|
||||
@ -578,10 +578,10 @@ void Graphics::SetClipRect(int &x, int &y, int &w, int &h)
|
||||
|
||||
bool VideoBuffer::WritePNG(const ByteString &path) const
|
||||
{
|
||||
std::vector<png_const_bytep> rowPointers(Height);
|
||||
for (auto y = 0; y < Height; ++y)
|
||||
std::vector<png_const_bytep> rowPointers(Size().Y);
|
||||
for (auto y = 0; y < Size().Y; ++y)
|
||||
{
|
||||
rowPointers[y] = (png_const_bytep)&Buffer[y * Width];
|
||||
rowPointers[y] = (png_const_bytep)&*video.RowIterator(Vec2(0, y));
|
||||
}
|
||||
png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!png)
|
||||
@ -612,7 +612,7 @@ bool VideoBuffer::WritePNG(const ByteString &path) const
|
||||
auto &imf = *(InMemoryFile *)ud;
|
||||
imf.data.insert(imf.data.end(), data, data + length);
|
||||
}, NULL);
|
||||
png_set_IHDR(png, info, Width, Height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
png_set_IHDR(png, info, Size().X, Size().Y, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
png_write_info(png, info);
|
||||
png_set_filler(png, 0, PNG_FILLER_AFTER);
|
||||
png_set_bgr(png);
|
||||
|
@ -21,13 +21,6 @@ class VideoBuffer: public RasterDrawMethods<VideoBuffer>
|
||||
friend struct RasterDrawMethods<VideoBuffer>;
|
||||
|
||||
public:
|
||||
[[deprecated("Use video")]]
|
||||
std::vector<pixel> &Buffer = video.Base;
|
||||
[[deprecated("Use Size()")]]
|
||||
size_t &Width = video.xExtent<DynamicExtent>::extent; // See TODO in common/Plane.h
|
||||
[[deprecated("Use Size()")]]
|
||||
size_t &Height = video.yExtent<DynamicExtent>::extent;
|
||||
|
||||
VideoBuffer(VideoBuffer const &) = default;
|
||||
VideoBuffer(pixel const *data, Vec2<int> size);
|
||||
VideoBuffer(pixel const *data, Vec2<int> size, size_t rowStride);
|
||||
|
@ -427,7 +427,7 @@ void RasterDrawMethods<Derived>::draw_image(const pixel *img, int x, int y, int
|
||||
template<typename Derived>
|
||||
void RasterDrawMethods<Derived>::draw_image(const VideoBuffer * vidBuf, int x, int y, int a)
|
||||
{
|
||||
draw_image(vidBuf->Buffer.data(), x, y, vidBuf->Width, vidBuf->Height, a);
|
||||
BlendImage(vidBuf->Data(), a, RectSized(Vec2(x, y), vidBuf->Size()));
|
||||
}
|
||||
|
||||
#undef video
|
||||
|
@ -502,7 +502,7 @@ VideoBuffer Renderer::DumpFrame()
|
||||
VideoBuffer newBuffer(XRES, YRES);
|
||||
for(int y = 0; y < YRES; y++)
|
||||
{
|
||||
std::copy(vid+(y*WINDOWW), vid+(y*WINDOWW)+XRES, newBuffer.Buffer.data()+(y*XRES));
|
||||
std::copy(vid+(y*WINDOWW), vid+(y*WINDOWW)+XRES, newBuffer.Data()+(y*XRES));
|
||||
}
|
||||
return newBuffer;
|
||||
}
|
||||
|
@ -958,7 +958,7 @@ ByteString GameView::TakeScreenshot(int captureUI, int fileType)
|
||||
// We should be able to simply use SDL_PIXELFORMAT_XRGB8888 here with a bit depth of 32 to convert RGBA data to RGB data,
|
||||
// and save the resulting surface directly. However, ubuntu-18.04 ships SDL2 so old that it doesn't have
|
||||
// SDL_PIXELFORMAT_XRGB8888, so we first create an RGBA surface and then convert it.
|
||||
auto *rgbaSurface = SDL_CreateRGBSurfaceWithFormatFrom(screenshot->Buffer.data(), screenshot->Width, screenshot->Height, 32, screenshot->Width * sizeof(pixel), SDL_PIXELFORMAT_ARGB8888);
|
||||
auto *rgbaSurface = SDL_CreateRGBSurfaceWithFormatFrom(screenshot->Data(), screenshot->Size().X, screenshot->Size().Y, 32, screenshot->Size().X * sizeof(pixel), SDL_PIXELFORMAT_ARGB8888);
|
||||
auto *rgbSurface = SDL_ConvertSurfaceFormat(rgbaSurface, SDL_PIXELFORMAT_RGB888, 0);
|
||||
if (!rgbSurface || SDL_SaveBMP(rgbSurface, filename.c_str()))
|
||||
{
|
||||
@ -1200,20 +1200,9 @@ void GameView::OnMouseUp(int x, int y, unsigned button)
|
||||
{
|
||||
if (placeSaveThumb && y <= WINDOWH-BARSIZE)
|
||||
{
|
||||
int thumbX = selectPoint2.X - ((placeSaveThumb->Width-placeSaveOffset.X)/2);
|
||||
int thumbY = selectPoint2.Y - ((placeSaveThumb->Height-placeSaveOffset.Y)/2);
|
||||
|
||||
if (thumbX < 0)
|
||||
thumbX = 0;
|
||||
if (thumbX+(placeSaveThumb->Width) >= XRES)
|
||||
thumbX = XRES-placeSaveThumb->Width;
|
||||
|
||||
if (thumbY < 0)
|
||||
thumbY = 0;
|
||||
if (thumbY+(placeSaveThumb->Height) >= YRES)
|
||||
thumbY = YRES-placeSaveThumb->Height;
|
||||
|
||||
c->PlaceSave(ui::Point(thumbX, thumbY));
|
||||
auto thumb = selectPoint2 - (placeSaveThumb->Size() - placeSaveOffset) / 2;
|
||||
thumb = thumb.Clamp(RectBetween(Vec2<int>::Zero, RES - placeSaveThumb->Size()));
|
||||
c->PlaceSave(thumb);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -2145,24 +2134,11 @@ void GameView::OnDraw()
|
||||
{
|
||||
if(placeSaveThumb && selectPoint2.X!=-1)
|
||||
{
|
||||
int thumbX = selectPoint2.X - ((placeSaveThumb->Width-placeSaveOffset.X)/2) + CELL/2;
|
||||
int thumbY = selectPoint2.Y - ((placeSaveThumb->Height-placeSaveOffset.Y)/2) + CELL/2;
|
||||
|
||||
ui::Point thumbPos = c->NormaliseBlockCoord(ui::Point(thumbX, thumbY));
|
||||
|
||||
if(thumbPos.X<0)
|
||||
thumbPos.X = 0;
|
||||
if(thumbPos.X+(placeSaveThumb->Width)>=XRES)
|
||||
thumbPos.X = XRES-placeSaveThumb->Width;
|
||||
|
||||
if(thumbPos.Y<0)
|
||||
thumbPos.Y = 0;
|
||||
if(thumbPos.Y+(placeSaveThumb->Height)>=YRES)
|
||||
thumbPos.Y = YRES-placeSaveThumb->Height;
|
||||
|
||||
ren->draw_image(placeSaveThumb, thumbPos.X, thumbPos.Y, 128);
|
||||
|
||||
ren->xor_rect(thumbPos.X, thumbPos.Y, placeSaveThumb->Width, placeSaveThumb->Height);
|
||||
auto thumb = selectPoint2 - (placeSaveThumb->Size() - placeSaveOffset) / 2 + Vec2(1, 1) * CELL / 2;
|
||||
thumb = c->NormaliseBlockCoord(thumb).Clamp(RectBetween(Vec2<int>::Zero, RES - placeSaveThumb->Size()));
|
||||
auto rect = RectSized(thumb, placeSaveThumb->Size());
|
||||
ren->BlendImage(placeSaveThumb->Data(), 0x80, rect);
|
||||
ren->XorDottedRect(rect);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -131,7 +131,7 @@ void SaveButton::Tick(float dt)
|
||||
{
|
||||
if(save->GetGameSave())
|
||||
{
|
||||
thumbnailRenderer = new ThumbnailRendererTask(save->GetGameSave(), thumbBoxSize.X, thumbBoxSize.Y);
|
||||
thumbnailRenderer = new ThumbnailRendererTask(*save->GetGameSave(), thumbBoxSize, true, true);
|
||||
thumbnailRenderer->Start();
|
||||
triedThumbnail = true;
|
||||
}
|
||||
@ -144,7 +144,7 @@ void SaveButton::Tick(float dt)
|
||||
}
|
||||
else if (file && file->GetGameSave())
|
||||
{
|
||||
thumbnailRenderer = new ThumbnailRendererTask(file->GetGameSave(), thumbBoxSize.X, thumbBoxSize.Y, true, true, false);
|
||||
thumbnailRenderer = new ThumbnailRendererTask(*file->GetGameSave(), thumbBoxSize, true, false);
|
||||
thumbnailRenderer->Start();
|
||||
triedThumbnail = true;
|
||||
}
|
||||
@ -168,7 +168,7 @@ void SaveButton::Tick(float dt)
|
||||
|
||||
if (thumbnail && file)
|
||||
{
|
||||
thumbSize = ui::Point(thumbnail->Width, thumbnail->Height);
|
||||
thumbSize = thumbnail->Size();
|
||||
}
|
||||
}
|
||||
if (file && !wantsDraw && !thumbnailRenderer)
|
||||
|
@ -285,9 +285,9 @@ void PreviewView::OnDraw()
|
||||
g->clearrect(Position.X-2, Position.Y-2, Size.X+4, Size.Y+4);
|
||||
|
||||
//Save preview (top-left)
|
||||
if(savePreview)
|
||||
if (savePreview)
|
||||
{
|
||||
g->draw_image(savePreview, (Position.X+1)+(((XRES/2)-savePreview->Width)/2), (Position.Y+1)+(((YRES/2)-savePreview->Height)/2), 255);
|
||||
g->BlendImage(savePreview->Data(), 0xFF, RectSized(Position + Vec2(1, 1) + (RES / 2 - savePreview->Size()) / 2, savePreview->Size()));
|
||||
}
|
||||
g->drawrect(Position.X, Position.Y, (XRES/2)+1, (YRES/2)+1, 255, 255, 255, 100);
|
||||
g->draw_line(Position.X+XRES/2, Position.Y+1, Position.X+XRES/2, Position.Y+Size.Y-2, 200, 200, 200, 255);
|
||||
|
@ -58,7 +58,7 @@ LocalSaveActivity::LocalSaveActivity(SaveFile save, OnSaved onSaved_) :
|
||||
|
||||
if(save.GetGameSave())
|
||||
{
|
||||
thumbnailRenderer = new ThumbnailRendererTask(save.GetGameSave(), Size.X-16, -1, false, true, false);
|
||||
thumbnailRenderer = new ThumbnailRendererTask(*save.GetGameSave(), Size - Vec2(16, 16), true, false);
|
||||
thumbnailRenderer->Start();
|
||||
}
|
||||
}
|
||||
@ -135,13 +135,14 @@ void LocalSaveActivity::OnDraw()
|
||||
{
|
||||
Graphics * g = GetGraphics();
|
||||
g->draw_rgba_image(&save_to_disk_image[0], save_to_disk_imageW, save_to_disk_imageH, 0, 0, 0.7f);
|
||||
g->clearrect(Position.X-2, Position.Y-2, Size.X+3, Size.Y+3);
|
||||
g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 255, 255, 255, 255);
|
||||
g->DrawFilledRect(RectSized(Position, Size).Inset(-1), 0x000000_rgb);
|
||||
g->DrawRect(RectSized(Position, Size), 0xFFFFFF_rgb);
|
||||
|
||||
if(thumbnail)
|
||||
if (thumbnail)
|
||||
{
|
||||
g->draw_image(thumbnail.get(), Position.X+(Size.X-thumbnail->Width)/2, Position.Y+45, 255);
|
||||
g->drawrect(Position.X+(Size.X-thumbnail->Width)/2, Position.Y+45, thumbnail->Width, thumbnail->Height, 180, 180, 180, 255);
|
||||
auto rect = RectSized(Position + Vec2((Size.X - thumbnail->Size().X) / 2, 45), thumbnail->Size());
|
||||
g->BlendImage(thumbnail->Data(), 0xFF, rect);
|
||||
g->DrawRect(rect, 0xB4B4B4_rgb);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,7 @@ ServerSaveActivity::ServerSaveActivity(SaveInfo save, OnUploaded onUploaded_) :
|
||||
|
||||
if (save.GetGameSave())
|
||||
{
|
||||
thumbnailRenderer = new ThumbnailRendererTask(save.GetGameSave(), (Size.X/2)-16, -1, false, false, true);
|
||||
thumbnailRenderer = new ThumbnailRendererTask(*save.GetGameSave(), Size / 2 - Vec2(16, 16), false, true);
|
||||
thumbnailRenderer->Start();
|
||||
}
|
||||
}
|
||||
@ -375,16 +375,17 @@ void ServerSaveActivity::OnDraw()
|
||||
{
|
||||
Graphics * g = GetGraphics();
|
||||
g->draw_rgba_image(&save_to_server_image[0], save_to_server_imageW, save_to_server_imageH, -10, 0, 0.7f);
|
||||
g->clearrect(Position.X-2, Position.Y-2, Size.X+3, Size.Y+3);
|
||||
g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 255, 255, 255, 255);
|
||||
g->DrawFilledRect(RectSized(Position, Size).Inset(-1), 0x000000_rgb);
|
||||
g->DrawRect(RectSized(Position, Size), 0xFFFFFF_rgb);
|
||||
|
||||
if(Size.X>220)
|
||||
g->draw_line(Position.X+(Size.X/2)-1, Position.Y, Position.X+(Size.X/2)-1, Position.Y+Size.Y-1, 255, 255, 255, 255);
|
||||
if (Size.X > 220)
|
||||
g->DrawLine(Position + Vec2(Size.X / 2 - 1, 0), Position + Vec2(Size.X / 2 - 1, Size.Y - 1), 0xFFFFFF_rgb);
|
||||
|
||||
if(thumbnail)
|
||||
if (thumbnail)
|
||||
{
|
||||
g->draw_image(thumbnail.get(), Position.X+(Size.X/2)+((Size.X/2)-thumbnail->Width)/2, Position.Y+25, 255);
|
||||
g->drawrect(Position.X+(Size.X/2)+((Size.X/2)-thumbnail->Width)/2, Position.Y+25, thumbnail->Width, thumbnail->Height, 180, 180, 180, 255);
|
||||
auto rect = RectSized(Position + Vec2(Size.X / 2 + (Size.X / 2 - thumbnail->Size().X) / 2, 25), thumbnail->Size());
|
||||
g->BlendImage(thumbnail->Data(), 0xFF, rect);
|
||||
g->DrawRect(rect, 0xB4B4B4_rgb);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user