Turn RequestBroker::RetrieveThumbnail into a request derived from Download
Also start moving RenderThumbnail out of RequestBroker into its own Task. Add mutex to SaveRenderer to guard Render().
This commit is contained in:
parent
53f2018c7e
commit
3a76a3a514
@ -4,8 +4,6 @@
|
|||||||
#include "ImageRequest.h"
|
#include "ImageRequest.h"
|
||||||
#include "common/String.h"
|
#include "common/String.h"
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace http
|
namespace http
|
||||||
{
|
{
|
||||||
class AvatarRequest : public ImageRequest
|
class AvatarRequest : public ImageRequest
|
||||||
|
@ -940,6 +940,14 @@ void Client::Shutdown()
|
|||||||
|
|
||||||
Client::~Client()
|
Client::~Client()
|
||||||
{
|
{
|
||||||
|
if (versionCheckRequest)
|
||||||
|
{
|
||||||
|
versionCheckRequest->Cancel();
|
||||||
|
}
|
||||||
|
if (alternateVersionCheckRequest)
|
||||||
|
{
|
||||||
|
alternateVersionCheckRequest->Cancel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
54
src/client/ThumbnailRenderer.cpp
Normal file
54
src/client/ThumbnailRenderer.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include "ThumbnailRenderer.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "graphics/Graphics.h"
|
||||||
|
#include "simulation/SaveRenderer.h"
|
||||||
|
#include "client/GameSave.h"
|
||||||
|
|
||||||
|
ThumbnailRendererTask::ThumbnailRendererTask(GameSave *save, int width, int height, bool autoRescale, bool decorations, bool fire) :
|
||||||
|
Save(new GameSave(*save)),
|
||||||
|
Width(width),
|
||||||
|
Height(height),
|
||||||
|
Decorations(decorations),
|
||||||
|
Fire(fire),
|
||||||
|
AutoRescale(autoRescale)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ThumbnailRendererTask::~ThumbnailRendererTask()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ThumbnailRendererTask::doWork()
|
||||||
|
{
|
||||||
|
thumbnail = std::unique_ptr<VideoBuffer>(SaveRenderer::Ref().Render(Save.get(), Decorations, Fire));
|
||||||
|
if (thumbnail)
|
||||||
|
{
|
||||||
|
if (AutoRescale)
|
||||||
|
{
|
||||||
|
int scaleX = (int)std::ceil((float)thumbnail->Width / Width);
|
||||||
|
int scaleY = (int)std::ceil((float)thumbnail->Height / Height);
|
||||||
|
int scale = scaleX > scaleY ? scaleX : scaleY;
|
||||||
|
int newWidth = thumbnail->Width / scale, newHeight = thumbnail->Height / scale;
|
||||||
|
thumbnail->Resize(newWidth, newHeight, true);
|
||||||
|
Width = newWidth;
|
||||||
|
Height = newHeight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thumbnail->Resize(Width, Height, true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<VideoBuffer> ThumbnailRendererTask::GetThumbnail()
|
||||||
|
{
|
||||||
|
return std::move(thumbnail);
|
||||||
|
}
|
||||||
|
|
28
src/client/ThumbnailRenderer.h
Normal file
28
src/client/ThumbnailRenderer.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef THUMBNAILRENDERER_H
|
||||||
|
#define THUMBNAILRENDERER_H
|
||||||
|
|
||||||
|
#include "tasks/Task.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class GameSave;
|
||||||
|
class VideoBuffer;
|
||||||
|
class ThumbnailRendererTask : public Task
|
||||||
|
{
|
||||||
|
std::unique_ptr<GameSave> Save;
|
||||||
|
int Width, Height;
|
||||||
|
bool Decorations;
|
||||||
|
bool Fire;
|
||||||
|
bool AutoRescale;
|
||||||
|
std::unique_ptr<VideoBuffer> thumbnail;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ThumbnailRendererTask(GameSave *save, int width, int height, bool autoRescale = false, bool decorations = true, bool fire = true);
|
||||||
|
virtual ~ThumbnailRendererTask();
|
||||||
|
|
||||||
|
virtual bool doWork() override;
|
||||||
|
std::unique_ptr<VideoBuffer> GetThumbnail();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // THUMBNAILRENDERER_H
|
||||||
|
|
15
src/client/ThumbnailRequest.cpp
Normal file
15
src/client/ThumbnailRequest.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include "ThumbnailRequest.h"
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
namespace http
|
||||||
|
{
|
||||||
|
ThumbnailRequest::ThumbnailRequest(int saveID, int saveDate, int width, int height) :
|
||||||
|
ImageRequest((
|
||||||
|
saveDate
|
||||||
|
? ByteString::Build("http://" STATICSERVER "/", saveID, "_", saveDate, "_small.pti")
|
||||||
|
: ByteString::Build("http://" STATICSERVER "/", saveID, "_small.pti")
|
||||||
|
), width, height)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
17
src/client/ThumbnailRequest.h
Normal file
17
src/client/ThumbnailRequest.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef THUMBNAILREQUEST2_H
|
||||||
|
#define THUMBNAILREQUEST2_H
|
||||||
|
|
||||||
|
#include "ImageRequest.h"
|
||||||
|
#include "common/String.h"
|
||||||
|
|
||||||
|
namespace http
|
||||||
|
{
|
||||||
|
class ThumbnailRequest : public ImageRequest
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ThumbnailRequest(int saveID, int saveDate, int width, int height);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // THUMBNAILREQUEST2_H
|
||||||
|
|
@ -6,7 +6,6 @@
|
|||||||
#include "Component.h"
|
#include "Component.h"
|
||||||
#include "graphics/Graphics.h"
|
#include "graphics/Graphics.h"
|
||||||
#include "gui/interface/Colour.h"
|
#include "gui/interface/Colour.h"
|
||||||
#include "client/requestbroker/RequestListener.h"
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -8,9 +8,11 @@
|
|||||||
#include "SaveButton.h"
|
#include "SaveButton.h"
|
||||||
#include "client/Client.h"
|
#include "client/Client.h"
|
||||||
#include "client/SaveInfo.h"
|
#include "client/SaveInfo.h"
|
||||||
|
#include "client/ThumbnailRequest.h"
|
||||||
|
#include "client/ThumbnailRenderer.h"
|
||||||
#include "graphics/Graphics.h"
|
#include "graphics/Graphics.h"
|
||||||
#include "simulation/SaveRenderer.h"
|
#include "simulation/SaveRenderer.h"
|
||||||
#include "client/requestbroker/RequestBroker.h"
|
#include "client/GameSave.h"
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
@ -18,11 +20,11 @@ SaveButton::SaveButton(Point position, Point size, SaveInfo * save):
|
|||||||
Component(position, size),
|
Component(position, size),
|
||||||
file(NULL),
|
file(NULL),
|
||||||
save(save),
|
save(save),
|
||||||
thumbnail(NULL),
|
triedThumbnail(false),
|
||||||
waitingForThumb(false),
|
|
||||||
isMouseInsideAuthor(false),
|
isMouseInsideAuthor(false),
|
||||||
isMouseInsideHistory(false),
|
isMouseInsideHistory(false),
|
||||||
showVotes(false),
|
showVotes(false),
|
||||||
|
thumbnailRequest(nullptr),
|
||||||
isButtonDown(false),
|
isButtonDown(false),
|
||||||
isMouseInside(false),
|
isMouseInside(false),
|
||||||
selected(false),
|
selected(false),
|
||||||
@ -91,12 +93,12 @@ SaveButton::SaveButton(Point position, Point size, SaveFile * file):
|
|||||||
Component(position, size),
|
Component(position, size),
|
||||||
file(file),
|
file(file),
|
||||||
save(NULL),
|
save(NULL),
|
||||||
thumbnail(NULL),
|
|
||||||
wantsDraw(false),
|
wantsDraw(false),
|
||||||
waitingForThumb(false),
|
triedThumbnail(false),
|
||||||
isMouseInsideAuthor(false),
|
isMouseInsideAuthor(false),
|
||||||
isMouseInsideHistory(false),
|
isMouseInsideHistory(false),
|
||||||
showVotes(false),
|
showVotes(false),
|
||||||
|
thumbnailRequest(nullptr),
|
||||||
isButtonDown(false),
|
isButtonDown(false),
|
||||||
isMouseInside(false),
|
isMouseInside(false),
|
||||||
selected(false),
|
selected(false),
|
||||||
@ -117,50 +119,66 @@ SaveButton::SaveButton(Point position, Point size, SaveFile * file):
|
|||||||
|
|
||||||
SaveButton::~SaveButton()
|
SaveButton::~SaveButton()
|
||||||
{
|
{
|
||||||
RequestBroker::Ref().DetachRequestListener(this);
|
if (thumbnailRequest)
|
||||||
|
{
|
||||||
|
thumbnailRequest->Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
delete thumbnail;
|
|
||||||
delete actionCallback;
|
delete actionCallback;
|
||||||
delete save;
|
delete save;
|
||||||
delete file;
|
delete file;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveButton::OnResponseReady(void * imagePtr, int identifier)
|
|
||||||
{
|
|
||||||
VideoBuffer * image = (VideoBuffer*)imagePtr;
|
|
||||||
if (image)
|
|
||||||
{
|
|
||||||
delete thumbnail;
|
|
||||||
thumbnail = image;
|
|
||||||
waitingForThumb = false;
|
|
||||||
if (file)
|
|
||||||
thumbSize = ui::Point(thumbnail->Width, thumbnail->Height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SaveButton::Tick(float dt)
|
void SaveButton::Tick(float dt)
|
||||||
{
|
{
|
||||||
if(!thumbnail && !waitingForThumb)
|
if (!thumbnail)
|
||||||
|
{
|
||||||
|
if (!triedThumbnail)
|
||||||
{
|
{
|
||||||
float scaleFactor = (Size.Y-25)/((float)YRES);
|
float scaleFactor = (Size.Y-25)/((float)YRES);
|
||||||
ui::Point thumbBoxSize = ui::Point(((float)XRES)*scaleFactor, ((float)YRES)*scaleFactor);
|
ui::Point thumbBoxSize = ui::Point(((float)XRES)*scaleFactor, ((float)YRES)*scaleFactor);
|
||||||
if(save)
|
if (save)
|
||||||
{
|
{
|
||||||
if(save->GetGameSave())
|
if(save->GetGameSave())
|
||||||
{
|
{
|
||||||
waitingForThumb = true;
|
thumbnailRenderer = std::unique_ptr<ThumbnailRendererTask>(new ThumbnailRendererTask(save->GetGameSave(), thumbBoxSize.X, thumbBoxSize.Y));
|
||||||
RequestBroker::Ref().RenderThumbnail(save->GetGameSave(), thumbBoxSize.X, thumbBoxSize.Y, this);
|
thumbnailRenderer->Start();
|
||||||
|
triedThumbnail = true;
|
||||||
}
|
}
|
||||||
else if(save->GetID())
|
else if (save->GetID())
|
||||||
{
|
{
|
||||||
waitingForThumb = true;
|
thumbnailRequest = new http::ThumbnailRequest(save->GetID(), save->GetVersion(), thumbBoxSize.X, thumbBoxSize.Y);
|
||||||
RequestBroker::Ref().RetrieveThumbnail(save->GetID(), save->GetVersion(), thumbBoxSize.X, thumbBoxSize.Y, this);
|
thumbnailRequest->Start();
|
||||||
|
triedThumbnail = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(file && file->GetGameSave())
|
else if (file && file->GetGameSave())
|
||||||
{
|
{
|
||||||
waitingForThumb = true;
|
thumbnailRenderer = std::unique_ptr<ThumbnailRendererTask>(new ThumbnailRendererTask(file->GetGameSave(), thumbBoxSize.X, thumbBoxSize.Y, true, true, false));
|
||||||
RequestBroker::Ref().RenderThumbnail(file->GetGameSave(), true, false, thumbBoxSize.X, thumbBoxSize.Y, true, this);
|
thumbnailRenderer->Start();
|
||||||
|
triedThumbnail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thumbnailRequest && thumbnailRequest->CheckDone())
|
||||||
|
{
|
||||||
|
thumbnail = thumbnailRequest->Finish();
|
||||||
|
thumbnailRequest = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thumbnailRenderer)
|
||||||
|
{
|
||||||
|
thumbnailRenderer->Poll();
|
||||||
|
if (thumbnailRenderer->GetDone())
|
||||||
|
{
|
||||||
|
thumbnail = thumbnailRenderer->GetThumbnail();
|
||||||
|
thumbnailRenderer.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thumbnail && file)
|
||||||
|
{
|
||||||
|
thumbSize = ui::Point(thumbnail->Width, thumbnail->Height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,9 +200,9 @@ void SaveButton::Draw(const Point& screenPos)
|
|||||||
{
|
{
|
||||||
//thumbBoxSize = ui::Point(thumbnail->Width, thumbnail->Height);
|
//thumbBoxSize = ui::Point(thumbnail->Width, thumbnail->Height);
|
||||||
if (save && save->id)
|
if (save && save->id)
|
||||||
g->draw_image(thumbnail, screenPos.X-3+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-21-thumbBoxSize.Y)/2, 255);
|
g->draw_image(thumbnail.get(), screenPos.X-3+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-21-thumbBoxSize.Y)/2, 255);
|
||||||
else
|
else
|
||||||
g->draw_image(thumbnail, screenPos.X+(Size.X-thumbSize.X)/2, screenPos.Y+(Size.Y-21-thumbSize.Y)/2, 255);
|
g->draw_image(thumbnail.get(), screenPos.X+(Size.X-thumbSize.X)/2, screenPos.Y+(Size.Y-21-thumbSize.Y)/2, 255);
|
||||||
}
|
}
|
||||||
else if (file && !file->GetGameSave())
|
else if (file && !file->GetGameSave())
|
||||||
g->drawtext(screenPos.X+(Size.X-Graphics::textwidth("Error loading save"))/2, screenPos.Y+(Size.Y-28)/2, "Error loading save", 180, 180, 180, 255);
|
g->drawtext(screenPos.X+(Size.X-Graphics::textwidth("Error loading save"))/2, screenPos.Y+(Size.Y-28)/2, "Error loading save", 180, 180, 180, 255);
|
||||||
|
@ -6,10 +6,16 @@
|
|||||||
#include "Component.h"
|
#include "Component.h"
|
||||||
#include "client/SaveFile.h"
|
#include "client/SaveFile.h"
|
||||||
#include "client/SaveInfo.h"
|
#include "client/SaveInfo.h"
|
||||||
#include "client/requestbroker/RequestListener.h"
|
|
||||||
#include "graphics/Graphics.h"
|
#include "graphics/Graphics.h"
|
||||||
#include "gui/interface/Colour.h"
|
#include "gui/interface/Colour.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class ThumbnailRendererTask;
|
||||||
|
namespace http
|
||||||
|
{
|
||||||
|
class ThumbnailRequest;
|
||||||
|
}
|
||||||
namespace ui
|
namespace ui
|
||||||
{
|
{
|
||||||
class SaveButton;
|
class SaveButton;
|
||||||
@ -23,11 +29,11 @@ public:
|
|||||||
virtual ~SaveButtonAction() {}
|
virtual ~SaveButtonAction() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SaveButton : public Component, public RequestListener
|
class SaveButton : public Component
|
||||||
{
|
{
|
||||||
SaveFile * file;
|
SaveFile * file;
|
||||||
SaveInfo * save;
|
SaveInfo * save;
|
||||||
VideoBuffer * thumbnail;
|
std::unique_ptr<VideoBuffer> thumbnail;
|
||||||
ui::Point thumbSize = ui::Point(0, 0);
|
ui::Point thumbSize = ui::Point(0, 0);
|
||||||
String name;
|
String name;
|
||||||
String votesString;
|
String votesString;
|
||||||
@ -36,10 +42,12 @@ class SaveButton : public Component, public RequestListener
|
|||||||
int voteBarHeightUp;
|
int voteBarHeightUp;
|
||||||
int voteBarHeightDown;
|
int voteBarHeightDown;
|
||||||
bool wantsDraw;
|
bool wantsDraw;
|
||||||
bool waitingForThumb;
|
bool triedThumbnail;
|
||||||
bool isMouseInsideAuthor;
|
bool isMouseInsideAuthor;
|
||||||
bool isMouseInsideHistory;
|
bool isMouseInsideHistory;
|
||||||
bool showVotes;
|
bool showVotes;
|
||||||
|
std::unique_ptr<ThumbnailRendererTask> thumbnailRenderer;
|
||||||
|
http::ThumbnailRequest *thumbnailRequest;
|
||||||
public:
|
public:
|
||||||
SaveButton(Point position, Point size, SaveInfo * save);
|
SaveButton(Point position, Point size, SaveInfo * save);
|
||||||
SaveButton(Point position, Point size, SaveFile * file);
|
SaveButton(Point position, Point size, SaveFile * file);
|
||||||
@ -59,8 +67,6 @@ public:
|
|||||||
void Draw(const Point& screenPos) override;
|
void Draw(const Point& screenPos) override;
|
||||||
void Tick(float dt) override;
|
void Tick(float dt) override;
|
||||||
|
|
||||||
void OnResponseReady(void * imagePtr, int identifier) override;
|
|
||||||
|
|
||||||
void SetSelected(bool selected_) { selected = selected_; }
|
void SetSelected(bool selected_) { selected = selected_; }
|
||||||
bool GetSelected() { return selected; }
|
bool GetSelected() { return selected; }
|
||||||
void SetSelectable(bool selectable_) { selectable = selectable_; }
|
void SetSelectable(bool selectable_) { selectable = selectable_; }
|
||||||
|
@ -29,10 +29,14 @@ SaveRenderer::SaveRenderer(){
|
|||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // Reset framebuffer binding
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // Reset framebuffer binding
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
pthread_mutex_init(&renderMutex, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoBuffer * SaveRenderer::Render(GameSave * save, bool decorations, bool fire)
|
VideoBuffer * SaveRenderer::Render(GameSave * save, bool decorations, bool fire)
|
||||||
{
|
{
|
||||||
|
pthread_mutex_lock(&renderMutex);
|
||||||
|
|
||||||
int width, height;
|
int width, height;
|
||||||
VideoBuffer * tempThumb = NULL;
|
VideoBuffer * tempThumb = NULL;
|
||||||
width = save->blockWidth;
|
width = save->blockWidth;
|
||||||
@ -145,11 +149,15 @@ VideoBuffer * SaveRenderer::Render(GameSave * save, bool decorations, bool fire)
|
|||||||
if(doCollapse)
|
if(doCollapse)
|
||||||
save->Collapse();
|
save->Collapse();
|
||||||
g->Release();
|
g->Release();
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&renderMutex);
|
||||||
return tempThumb;
|
return tempThumb;
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoBuffer * SaveRenderer::Render(unsigned char * saveData, int dataSize, bool decorations, bool fire)
|
VideoBuffer * SaveRenderer::Render(unsigned char * saveData, int dataSize, bool decorations, bool fire)
|
||||||
{
|
{
|
||||||
|
pthread_mutex_lock(&renderMutex);
|
||||||
|
|
||||||
GameSave * tempSave;
|
GameSave * tempSave;
|
||||||
try {
|
try {
|
||||||
tempSave = new GameSave((char*)saveData, dataSize);
|
tempSave = new GameSave((char*)saveData, dataSize);
|
||||||
@ -159,13 +167,17 @@ VideoBuffer * SaveRenderer::Render(unsigned char * saveData, int dataSize, bool
|
|||||||
VideoBuffer * buffer = new VideoBuffer(64, 64);
|
VideoBuffer * buffer = new VideoBuffer(64, 64);
|
||||||
buffer->BlendCharacter(32, 32, 'x', 255, 255, 255, 255);
|
buffer->BlendCharacter(32, 32, 'x', 255, 255, 255, 255);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&renderMutex);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
VideoBuffer * thumb = Render(tempSave, decorations, fire);
|
VideoBuffer * thumb = Render(tempSave, decorations, fire);
|
||||||
delete tempSave;
|
delete tempSave;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&renderMutex);
|
||||||
return thumb;
|
return thumb;
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveRenderer::~SaveRenderer() {
|
SaveRenderer::~SaveRenderer() {
|
||||||
|
pthread_mutex_destroy(&renderMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "graphics/OpenGLHeaders.h"
|
#include "graphics/OpenGLHeaders.h"
|
||||||
#endif
|
#endif
|
||||||
#include "common/Singleton.h"
|
#include "common/Singleton.h"
|
||||||
|
#include "common/tpt-thread.h"
|
||||||
|
|
||||||
class GameSave;
|
class GameSave;
|
||||||
class VideoBuffer;
|
class VideoBuffer;
|
||||||
@ -15,6 +16,7 @@ class SaveRenderer: public Singleton<SaveRenderer> {
|
|||||||
Graphics * g;
|
Graphics * g;
|
||||||
Simulation * sim;
|
Simulation * sim;
|
||||||
Renderer * ren;
|
Renderer * ren;
|
||||||
|
pthread_mutex_t renderMutex;
|
||||||
public:
|
public:
|
||||||
SaveRenderer();
|
SaveRenderer();
|
||||||
VideoBuffer * Render(GameSave * save, bool decorations = true, bool fire = true);
|
VideoBuffer * Render(GameSave * save, bool decorations = true, bool fire = true);
|
||||||
|
Reference in New Issue
Block a user