summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiotr Dziwiński <piotrdz@gmail.com>2014-06-24 19:42:25 +0200
committerPiotr Dziwiński <piotrdz@gmail.com>2014-06-24 19:42:25 +0200
commitae13e0a62121d7fc8fa5ec5769ea5e7125443146 (patch)
treee2d5883e04bd01342f51d6457a130d663fc5eafd
parent52cf9e2815688481f689e03e67c5fc983ed1351b (diff)
parentf5ba2a27d4422401317d814c60048121f9804429 (diff)
downloadcolobot-ae13e0a62121d7fc8fa5ec5769ea5e7125443146.tar.gz
colobot-ae13e0a62121d7fc8fa5ec5769ea5e7125443146.tar.bz2
colobot-ae13e0a62121d7fc8fa5ec5769ea5e7125443146.zip
Merge pull request #304 from MohamedWaheed/dev
Savefile screenshot implementation and screenshot loading bug fix
-rw-r--r--src/app/gamedata.cpp35
-rw-r--r--src/common/image.cpp41
-rw-r--r--src/common/image.h6
-rw-r--r--src/graphics/core/device.h3
-rw-r--r--src/graphics/engine/engine.cpp17
-rw-r--r--src/graphics/opengl/gldevice.cpp13
-rw-r--r--src/graphics/opengl/gldevice.h2
-rw-r--r--src/ui/maindialog.cpp7
8 files changed, 99 insertions, 25 deletions
diff --git a/src/app/gamedata.cpp b/src/app/gamedata.cpp
index 1bf3f36..05c0242 100644
--- a/src/app/gamedata.cpp
+++ b/src/app/gamedata.cpp
@@ -78,16 +78,22 @@ std::string CGameData::GetFilePath(DataDir dir, const std::string& subpath)
for(std::vector<std::string>::reverse_iterator rit = m_dataDirs.rbegin(); rit != m_dataDirs.rend(); ++rit) {
std::stringstream str;
- str << *rit;
- str << "/";
- str << m_standardDataDirs[index];
- if (dir == DIR_HELP)
- {
+
+ if ( subpath.find("save") == std::string::npos ){ // if its NOT a path to a savefile screenshot
+ str << *rit;
+ str << "/";
+ str << m_standardDataDirs[index];
+
+ if (dir == DIR_HELP)
+ {
+ str << "/";
+ str << CApplication::GetInstancePointer()->GetLanguageChar();
+ }
str << "/";
- str << CApplication::GetInstancePointer()->GetLanguageChar();
}
- str << "/";
+
str << subpath;
+
boost::filesystem::path path(str.str());
if(boost::filesystem::exists(path))
{
@@ -95,18 +101,9 @@ std::string CGameData::GetFilePath(DataDir dir, const std::string& subpath)
}
}
- std::stringstream str;
- str << m_dataDirs[0];
- str << "/";
- str << m_standardDataDirs[index];
- if (dir == DIR_HELP)
- {
- str << "/";
- str << CApplication::GetInstancePointer()->GetLanguageChar();
- }
- str << "/";
- str << subpath;
- return str.str();
+ GetLogger()->Error("file subpath error\n");
+
+ return "";
}
std::string CGameData::GetDataPath(const std::string &subpath)
diff --git a/src/common/image.cpp b/src/common/image.cpp
index 8a876e3..e3d1ef7 100644
--- a/src/common/image.cpp
+++ b/src/common/image.cpp
@@ -418,3 +418,44 @@ bool CImage::SavePNG(const std::string& fileName)
return true;
}
+void CImage::SetDataPixels(void *pixels){
+
+ Uint8* srcPixels = static_cast<Uint8*> (pixels);
+ Uint8* resultPixels = static_cast<Uint8*> (m_data->surface->pixels);
+
+ Uint32 pitch = m_data->surface->pitch;
+
+ for(int line = 0; line < m_data->surface->h; ++line) {
+ Uint32 pos = line * pitch;
+ memcpy(&resultPixels[pos], &srcPixels[pos], pitch);
+ }
+}
+
+void CImage::flipVertically(){
+
+ SDL_Surface* result = SDL_CreateRGBSurface( m_data->surface->flags,
+ m_data->surface->w,
+ m_data->surface->h,
+ m_data->surface->format->BytesPerPixel * 8,
+ m_data->surface->format->Rmask,
+ m_data->surface->format->Gmask,
+ m_data->surface->format->Bmask,
+ m_data->surface->format->Amask);
+
+ assert(result != nullptr);
+
+ Uint8* srcPixels = static_cast<Uint8*> (m_data->surface->pixels);
+ Uint8* resultPixels = static_cast<Uint8*> (result->pixels);
+
+ Uint32 pitch = m_data->surface->pitch;
+ Uint32 pxLength = pitch*m_data->surface->h;
+
+ for(int line = 0; line < m_data->surface->h; ++line) {
+ Uint32 pos = line * pitch;
+ memcpy(&resultPixels[pos], &srcPixels[(pxLength-pos)-pitch], pitch);
+ }
+
+ SDL_FreeSurface(m_data->surface);
+
+ m_data->surface = result;
+} \ No newline at end of file
diff --git a/src/common/image.h b/src/common/image.h
index 31dab2d..b93f2f9 100644
--- a/src/common/image.h
+++ b/src/common/image.h
@@ -109,6 +109,12 @@ public:
//! Returns the last error
std::string GetError();
+ //! Flips the image vertically
+ void flipVertically();
+
+ //! sets/replaces the pixels from the surface
+ void SetDataPixels(void *pixels);
+
private:
//! Blit to new RGBA surface with given size
void BlitToNewRGBASurface(int width, int height);
diff --git a/src/graphics/core/device.h b/src/graphics/core/device.h
index 4c1189c..a896104 100644
--- a/src/graphics/core/device.h
+++ b/src/graphics/core/device.h
@@ -400,6 +400,9 @@ public:
virtual void SetFillMode(FillMode mode) = 0;
//! Returns the current fill mode
virtual FillMode GetFillMode() = 0;
+
+ //! Returns the pixels of the entire screen
+ virtual void* GetFrameBufferPixels()const = 0;
};
diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp
index d6e4415..e0861d2 100644
--- a/src/graphics/engine/engine.cpp
+++ b/src/graphics/engine/engine.cpp
@@ -424,9 +424,20 @@ void CEngine::FrameUpdate()
bool CEngine::WriteScreenShot(const std::string& fileName, int width, int height)
{
- // TODO write screenshot: not very important for now
- GetLogger()->Debug("CEngine::WriteSceenShot(): stub!\n");
- return true;
+ void *pixels = m_device->GetFrameBufferPixels();
+ CImage img({width,height});
+
+ img.SetDataPixels(pixels);
+ img.flipVertically();
+
+ if ( img.SavePNG(fileName.c_str()) ){
+ GetLogger()->Info("Save SceenShot Saved Successfully!\n");
+ return true;
+ }
+ else{
+ GetLogger()->Error("%s!\n",img.GetError().c_str());
+ return false;
+ }
}
bool CEngine::GetPause()
diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp
index 9f64fab..b42f29d 100644
--- a/src/graphics/opengl/gldevice.cpp
+++ b/src/graphics/opengl/gldevice.cpp
@@ -1791,6 +1791,19 @@ FillMode CGLDevice::GetFillMode()
return FILL_POINT;
}
+void* CGLDevice::GetFrameBufferPixels()const{
+
+ GLubyte* pixels = new GLubyte [4 * m_config.size.x * m_config.size.y];
+
+ glReadPixels(0, 0, m_config.size.x, m_config.size.y, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ unsigned int* p = static_cast<unsigned int*> ( static_cast<void*>(pixels) );
+
+ for (int i = 0; i < m_config.size.x * m_config.size.y; ++i)
+ p[i] |= 0xFF000000;
+
+ return static_cast<void*>(p);
+}
} // namespace Gfx
diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h
index c648161..267ee73 100644
--- a/src/graphics/opengl/gldevice.h
+++ b/src/graphics/opengl/gldevice.h
@@ -188,6 +188,8 @@ public:
virtual void SetFillMode(FillMode mode) ;
virtual FillMode GetFillMode();
+ virtual void* GetFrameBufferPixels()const;
+
private:
//! Updates internal modelview matrix
void UpdateModelviewMatrix();
diff --git a/src/ui/maindialog.cpp b/src/ui/maindialog.cpp
index 1964531..fc5bb30 100644
--- a/src/ui/maindialog.cpp
+++ b/src/ui/maindialog.cpp
@@ -2075,9 +2075,10 @@ bool CMainDialog::EventProcess(const Event &event)
{
m_shotDelay --;
if ( m_shotDelay == 0 )
- {
- m_engine->WriteScreenShot(m_shotName, 320, 240);
- //? m_engine->WriteScreenShot(m_shotName, 160, 120);
+ {
+ Math::IntPoint windowSize = m_engine->GetWindowSize();
+
+ m_engine->WriteScreenShot(m_shotName, windowSize.x, windowSize.y);
}
}