Save screenshot image in a separate background thread (#546)

master
krzys-h 2015-08-03 21:40:30 +02:00
parent 5e4a423bf0
commit 04960035c1
4 changed files with 36 additions and 20 deletions

View File

@ -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()

View File

@ -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;

View File

@ -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)
{ {

View File

@ -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;