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