Save screenshot image in a separate background thread (#546)
parent
5e4a423bf0
commit
04960035c1
|
@ -52,6 +52,7 @@
|
|||
#include "ui/interface.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <SDL_thread.h>
|
||||
|
||||
template<> Gfx::CEngine* CSingleton<Gfx::CEngine>::m_instance = nullptr;
|
||||
|
||||
|
@ -483,24 +484,42 @@ void CEngine::FrameUpdate()
|
|||
}
|
||||
}
|
||||
|
||||
struct WriteScreenShotData
|
||||
{
|
||||
std::unique_ptr<CImage> img;
|
||||
std::string fileName;
|
||||
};
|
||||
|
||||
bool CEngine::WriteScreenShot(const std::string& fileName, int width, int height)
|
||||
{
|
||||
void *pixels = m_device->GetFrameBufferPixels();
|
||||
CImage img({width, height});
|
||||
WriteScreenShotData* data = new WriteScreenShotData();
|
||||
data->img = MakeUnique<CImage>(Math::IntPoint(width, height));
|
||||
|
||||
img.SetDataPixels(pixels);
|
||||
img.FlipVertically();
|
||||
data->img->SetDataPixels(m_device->GetFrameBufferPixels());
|
||||
data->img->FlipVertically();
|
||||
|
||||
if ( img.SavePNG(fileName.c_str()) )
|
||||
data->fileName = fileName;
|
||||
SDL_CreateThread(CEngine::WriteScreenShotThread, data);
|
||||
return true;
|
||||
}
|
||||
|
||||
int CEngine::WriteScreenShotThread(void* data_ptr)
|
||||
{
|
||||
WriteScreenShotData* data = static_cast<WriteScreenShotData*>(data_ptr);
|
||||
|
||||
if ( data->img->SavePNG(data->fileName.c_str()) )
|
||||
{
|
||||
GetLogger()->Debug("Save screenshot saved successfully\n");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
GetLogger()->Error("%s!\n", img.GetError().c_str());
|
||||
return false;
|
||||
GetLogger()->Error("%s!\n", data->img->GetError().c_str());
|
||||
}
|
||||
|
||||
delete data;
|
||||
|
||||
CRobotMain::GetInstancePointer()->IOWriteSceneFinished();
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CEngine::GetPause()
|
||||
|
|
|
@ -1348,6 +1348,8 @@ protected:
|
|||
|
||||
int GetEngineState(const ModelTriangle& triangle);
|
||||
|
||||
static int WriteScreenShotThread(void* data_ptr);
|
||||
|
||||
protected:
|
||||
CApplication* m_app;
|
||||
CSoundInterface* m_sound;
|
||||
|
|
|
@ -179,7 +179,6 @@ CRobotMain::CRobotMain(CController* controller)
|
|||
m_satcomRepeat = true;
|
||||
m_editorTrack = "";
|
||||
m_editorRepeat = true;
|
||||
m_delayWriteMessage = 0;
|
||||
m_selectObject = 0;
|
||||
m_infoUsed = 0;
|
||||
|
||||
|
@ -2754,15 +2753,6 @@ bool CRobotMain::EventFrame(const Event &event)
|
|||
}
|
||||
}
|
||||
|
||||
if (m_delayWriteMessage > 0)
|
||||
{
|
||||
m_delayWriteMessage --;
|
||||
if (m_delayWriteMessage == 0)
|
||||
{
|
||||
m_displayText->DisplayError(INFO_WRITEOK, Math::Vector(0.0f,0.0f,0.0f));
|
||||
}
|
||||
}
|
||||
|
||||
if (GetMissionType() == MISSION_CODE_BATTLE)
|
||||
{
|
||||
if (!m_codeBattleInit)
|
||||
|
@ -5128,10 +5118,15 @@ bool CRobotMain::IOWriteScene(const char *filename, const char *filecbot, char *
|
|||
CBotClass::SaveStaticState(file);
|
||||
fClose(file);
|
||||
|
||||
m_delayWriteMessage = 4; // displays message in 3 frames
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Notifies the user that scene write is finished
|
||||
void CRobotMain::IOWriteSceneFinished()
|
||||
{
|
||||
m_displayText->DisplayError(INFO_WRITEOK, Math::Vector(0.0f,0.0f,0.0f));
|
||||
}
|
||||
|
||||
//! Resumes the game
|
||||
CObject* CRobotMain::IOReadObject(CLevelParserLine *line, const char* filename, int objRank)
|
||||
{
|
||||
|
|
|
@ -299,6 +299,7 @@ public:
|
|||
|
||||
bool IsBusy();
|
||||
bool IOWriteScene(const char *filename, const char *filecbot, char *info);
|
||||
void IOWriteSceneFinished();
|
||||
CObject* IOReadScene(const char *filename, const char *filecbot);
|
||||
void IOWriteObject(CLevelParserLine *line, CObject* obj);
|
||||
CObject* IOReadObject(CLevelParserLine *line, const char* filename, int objRank);
|
||||
|
@ -479,7 +480,6 @@ protected:
|
|||
bool m_satcomRepeat;
|
||||
std::string m_editorTrack;
|
||||
bool m_editorRepeat;
|
||||
int m_delayWriteMessage;
|
||||
int m_movieInfoIndex;
|
||||
|
||||
CObject* m_controller;
|
||||
|
|
Loading…
Reference in New Issue