From 613e1d74c47cf3a756af9aff75575c7567699381 Mon Sep 17 00:00:00 2001 From: Mohamed Waheed Date: Tue, 24 Jun 2014 01:35:05 +0300 Subject: implemented savefile screenshot feature --- src/common/image.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ src/common/image.h | 6 ++++++ src/graphics/core/device.h | 3 +++ src/graphics/engine/engine.cpp | 17 ++++++++++++++--- src/graphics/opengl/gldevice.cpp | 17 +++++++++++++++++ src/graphics/opengl/gldevice.h | 2 ++ src/ui/maindialog.cpp | 7 ++++--- 7 files changed, 86 insertions(+), 6 deletions(-) diff --git a/src/common/image.cpp b/src/common/image.cpp index 8a876e3..ff5e42c 100644 --- a/src/common/image.cpp +++ b/src/common/image.cpp @@ -418,3 +418,43 @@ bool CImage::SavePNG(const std::string& fileName) return true; } +void CImage::SetDataPixels(void *pixels){ + + if (m_data != nullptr){ + + if (m_data->surface != nullptr) + { + if ( m_data->surface->pixels != nullptr ){ + unsigned int* pixels = static_cast(m_data->surface->pixels); + delete [] pixels; + m_data->surface->pixels = nullptr; + } + } + } + + m_data->surface->pixels = pixels; +} + +void CImage::flipVertical(){ + + 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 (m_data->surface->pixels); + Uint8* resultPixels = static_cast (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..afbebc2 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 flipVertical(); + + //! 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..9216fb0 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.flipVertical(); + + 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..57738a6 100644 --- a/src/graphics/opengl/gldevice.cpp +++ b/src/graphics/opengl/gldevice.cpp @@ -1791,6 +1791,23 @@ FillMode CGLDevice::GetFillMode() return FILL_POINT; } +void* CGLDevice::GetFrameBufferPixels()const{ + + SDL_Surface* surface = SDL_GetVideoSurface(); + + assert(surface != nullptr); + + GLubyte* pixels = new GLubyte [4 * surface->h * surface->w]; + + glReadPixels(0,0,surface->w,surface->h,GL_RGBA,GL_UNSIGNED_BYTE,pixels); + + unsigned int* p = static_cast ( static_cast(pixels) ); + + for (int i = 0; i < surface->h * surface->w; ++i) + p[i] |= 0xFF000000; + + return static_cast(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..784cd59 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 screenSize = m_app->GetVideoConfig().size; + + m_engine->WriteScreenShot(m_shotName, screenSize.x, screenSize.y); } } -- cgit v1.2.3-1-g7c22 From b7125a5b24bc6d2581bec0d3f792ba948e0e7edd Mon Sep 17 00:00:00 2001 From: Mohamed Waheed Date: Tue, 24 Jun 2014 20:27:31 +0300 Subject: formatting and enhancements for savefile screenshot feature --- src/common/image.cpp | 33 +++++++++++++++++---------------- src/common/image.h | 2 +- src/graphics/engine/engine.cpp | 2 +- src/graphics/opengl/gldevice.cpp | 10 +++------- src/ui/maindialog.cpp | 4 ++-- 5 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/common/image.cpp b/src/common/image.cpp index ff5e42c..e3d1ef7 100644 --- a/src/common/image.cpp +++ b/src/common/image.cpp @@ -420,26 +420,27 @@ bool CImage::SavePNG(const std::string& fileName) void CImage::SetDataPixels(void *pixels){ - if (m_data != nullptr){ - - if (m_data->surface != nullptr) - { - if ( m_data->surface->pixels != nullptr ){ - unsigned int* pixels = static_cast(m_data->surface->pixels); - delete [] pixels; - m_data->surface->pixels = nullptr; - } - } + Uint8* srcPixels = static_cast (pixels); + Uint8* resultPixels = static_cast (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); } - - m_data->surface->pixels = pixels; } -void CImage::flipVertical(){ +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); + 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); diff --git a/src/common/image.h b/src/common/image.h index afbebc2..b93f2f9 100644 --- a/src/common/image.h +++ b/src/common/image.h @@ -110,7 +110,7 @@ public: std::string GetError(); //! Flips the image vertically - void flipVertical(); + void flipVertically(); //! sets/replaces the pixels from the surface void SetDataPixels(void *pixels); diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 9216fb0..e0861d2 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -428,7 +428,7 @@ bool CEngine::WriteScreenShot(const std::string& fileName, int width, int height CImage img({width,height}); img.SetDataPixels(pixels); - img.flipVertical(); + img.flipVertically(); if ( img.SavePNG(fileName.c_str()) ){ GetLogger()->Info("Save SceenShot Saved Successfully!\n"); diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp index 57738a6..b42f29d 100644 --- a/src/graphics/opengl/gldevice.cpp +++ b/src/graphics/opengl/gldevice.cpp @@ -1793,17 +1793,13 @@ FillMode CGLDevice::GetFillMode() void* CGLDevice::GetFrameBufferPixels()const{ - SDL_Surface* surface = SDL_GetVideoSurface(); - - assert(surface != nullptr); - - GLubyte* pixels = new GLubyte [4 * surface->h * surface->w]; + GLubyte* pixels = new GLubyte [4 * m_config.size.x * m_config.size.y]; - glReadPixels(0,0,surface->w,surface->h,GL_RGBA,GL_UNSIGNED_BYTE,pixels); + glReadPixels(0, 0, m_config.size.x, m_config.size.y, GL_RGBA, GL_UNSIGNED_BYTE, pixels); unsigned int* p = static_cast ( static_cast(pixels) ); - for (int i = 0; i < surface->h * surface->w; ++i) + for (int i = 0; i < m_config.size.x * m_config.size.y; ++i) p[i] |= 0xFF000000; return static_cast(p); diff --git a/src/ui/maindialog.cpp b/src/ui/maindialog.cpp index 784cd59..fc5bb30 100644 --- a/src/ui/maindialog.cpp +++ b/src/ui/maindialog.cpp @@ -2076,9 +2076,9 @@ bool CMainDialog::EventProcess(const Event &event) m_shotDelay --; if ( m_shotDelay == 0 ) { - Math::IntPoint screenSize = m_app->GetVideoConfig().size; + Math::IntPoint windowSize = m_engine->GetWindowSize(); - m_engine->WriteScreenShot(m_shotName, screenSize.x, screenSize.y); + m_engine->WriteScreenShot(m_shotName, windowSize.x, windowSize.y); } } -- cgit v1.2.3-1-g7c22 From f5ba2a27d4422401317d814c60048121f9804429 Mon Sep 17 00:00:00 2001 From: Mohamed Waheed Date: Tue, 24 Jun 2014 20:31:17 +0300 Subject: fixed savefile screenshot loading bug --- src/app/gamedata.cpp | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 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::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) -- cgit v1.2.3-1-g7c22