mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
Revert "Be less dumb."
Revert "Actually, filename really does need to be a parameter because of some random debug thing." Revert "fix non-HAVE_WX case" Revert "Handle screenshot saving in RenderBase. Removes dependency on D3DX11 for screenshots (texture dumping is still broken)." This reverts commits00fe5057f1
,74b5fb3ab4
,cd46138d29
and5f72542e06
because taking screenshots in D3D still crashed for me so there was no point in the code changes (which I found ugly anyway).
This commit is contained in:
@ -11,6 +11,9 @@
|
||||
#include <cstdio>
|
||||
|
||||
#include "GLUtil.h"
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
#include "WxUtils.h"
|
||||
#endif
|
||||
|
||||
#include "FileUtil.h"
|
||||
|
||||
@ -22,6 +25,7 @@
|
||||
#include "DriverDetails.h"
|
||||
#include "VideoConfig.h"
|
||||
#include "Statistics.h"
|
||||
#include "ImageWrite.h"
|
||||
#include "PixelEngine.h"
|
||||
#include "Render.h"
|
||||
#include "BPStructs.h"
|
||||
@ -58,6 +62,10 @@
|
||||
#include "AVIDump.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
#include <wx/image.h>
|
||||
#endif
|
||||
|
||||
// glew1.8 doesn't define KHR_debug
|
||||
#ifndef GL_DEBUG_OUTPUT
|
||||
#define GL_DEBUG_OUTPUT 0x92E0
|
||||
@ -70,6 +78,17 @@ void VideoConfig::UpdateProjectionHack()
|
||||
}
|
||||
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
// Screenshot thread struct
|
||||
typedef struct
|
||||
{
|
||||
int W, H;
|
||||
std::string filename;
|
||||
wxImage *img;
|
||||
} ScrStrct;
|
||||
#endif
|
||||
|
||||
|
||||
int OSDInternalW, OSDInternalH;
|
||||
|
||||
namespace OGL
|
||||
@ -108,6 +127,10 @@ static u32 s_blendMode;
|
||||
|
||||
static bool s_vsync;
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
static std::thread scrshotThread;
|
||||
#endif
|
||||
|
||||
// EFB cache related
|
||||
static const u32 EFB_CACHE_RECT_SIZE = 64; // Cache 64x64 blocks.
|
||||
static const u32 EFB_CACHE_WIDTH = (EFB_WIDTH + EFB_CACHE_RECT_SIZE - 1) / EFB_CACHE_RECT_SIZE; // round up
|
||||
@ -616,6 +639,11 @@ Renderer::Renderer()
|
||||
|
||||
Renderer::~Renderer()
|
||||
{
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
if (scrshotThread.joinable())
|
||||
scrshotThread.join();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Renderer::Shutdown()
|
||||
@ -1391,9 +1419,11 @@ void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangle& r
|
||||
// Save screenshot
|
||||
if (s_bScreenshot)
|
||||
{
|
||||
TakeScreenshot(flipped_trc, s_sScreenshotName);
|
||||
s_bScreenshot = false;
|
||||
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
|
||||
SaveScreenshot(s_sScreenshotName, flipped_trc);
|
||||
// Reset settings
|
||||
s_sScreenshotName.clear();
|
||||
s_bScreenshot = false;
|
||||
}
|
||||
|
||||
// Frame dumps are handled a little differently in Windows
|
||||
@ -1771,22 +1801,71 @@ void Renderer::SetInterlacingMode()
|
||||
|
||||
void Renderer::FlipImageData(u8 *data, int w, int h)
|
||||
{
|
||||
// XXX make this faster
|
||||
u8* __restrict top = data;
|
||||
u8* bot = data + w * h * 3;
|
||||
// Flip image upside down. Damn OpenGL.
|
||||
for (int y = 0; y < h / 2; y++)
|
||||
{
|
||||
size_t stride = w * 3;
|
||||
bot -= stride;
|
||||
u8* __restrict brow = bot;
|
||||
for(size_t x = 0; x < stride; x++)
|
||||
for(int x = 0; x < w; x++)
|
||||
{
|
||||
std::swap(*top++, *brow++);
|
||||
std::swap(data[(y * w + x) * 3], data[((h - 1 - y) * w + x) * 3]);
|
||||
std::swap(data[(y * w + x) * 3 + 1], data[((h - 1 - y) * w + x) * 3 + 1]);
|
||||
std::swap(data[(y * w + x) * 3 + 2], data[((h - 1 - y) * w + x) * 3 + 2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::TakeScreenshot(const TargetRectangle &back_rc, std::string filename)
|
||||
}
|
||||
|
||||
// TODO: remove
|
||||
extern bool g_aspect_wide;
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
void TakeScreenshot(ScrStrct* threadStruct)
|
||||
{
|
||||
// These will contain the final image size
|
||||
float FloatW = (float)threadStruct->W;
|
||||
float FloatH = (float)threadStruct->H;
|
||||
|
||||
// Handle aspect ratio for the final ScrStrct to look exactly like what's on screen.
|
||||
if (g_ActiveConfig.iAspectRatio != ASPECT_STRETCH)
|
||||
{
|
||||
bool use16_9 = g_aspect_wide;
|
||||
|
||||
// Check for force-settings and override.
|
||||
if (g_ActiveConfig.iAspectRatio == ASPECT_FORCE_16_9)
|
||||
use16_9 = true;
|
||||
else if (g_ActiveConfig.iAspectRatio == ASPECT_FORCE_4_3)
|
||||
use16_9 = false;
|
||||
|
||||
float Ratio = (FloatW / FloatH) / (!use16_9 ? (4.0f / 3.0f) : (16.0f / 9.0f));
|
||||
|
||||
// If ratio > 1 the picture is too wide and we have to limit the width.
|
||||
if (Ratio > 1)
|
||||
FloatW /= Ratio;
|
||||
// ratio == 1 or the image is too high, we have to limit the height.
|
||||
else
|
||||
FloatH *= Ratio;
|
||||
|
||||
// This is a bit expensive on high resolutions
|
||||
threadStruct->img->Rescale((int)FloatW, (int)FloatH, wxIMAGE_QUALITY_HIGH);
|
||||
}
|
||||
|
||||
// Save the screenshot and finally kill the wxImage object
|
||||
// This is really expensive when saving to PNG, but not at all when using BMP
|
||||
threadStruct->img->SaveFile(StrToWxStr(threadStruct->filename),
|
||||
wxBITMAP_TYPE_PNG);
|
||||
threadStruct->img->Destroy();
|
||||
|
||||
// Show success messages
|
||||
OSD::AddMessage(StringFromFormat("Saved %i x %i %s", (int)FloatW, (int)FloatH,
|
||||
threadStruct->filename.c_str()), 2000);
|
||||
delete threadStruct;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace OGL
|
||||
{
|
||||
|
||||
bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle &back_rc)
|
||||
{
|
||||
u32 W = back_rc.GetWidth();
|
||||
u32 H = back_rc.GetHeight();
|
||||
@ -1800,13 +1879,38 @@ void Renderer::TakeScreenshot(const TargetRectangle &back_rc, std::string filena
|
||||
{
|
||||
free(data);
|
||||
OSD::AddMessage("Error capturing or saving screenshot.", 2000);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Turn image upside down
|
||||
FlipImageData(data, W, H);
|
||||
|
||||
SaveScreenshot(data, W, H, filename);
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
// Create wxImage
|
||||
wxImage *a = new wxImage(W, H, data);
|
||||
|
||||
if (scrshotThread.joinable())
|
||||
scrshotThread.join();
|
||||
|
||||
ScrStrct *threadStruct = new ScrStrct;
|
||||
threadStruct->filename = filename;
|
||||
threadStruct->img = a;
|
||||
threadStruct->H = H; threadStruct->W = W;
|
||||
|
||||
scrshotThread = std::thread(TakeScreenshot, threadStruct);
|
||||
#ifdef _WIN32
|
||||
SetThreadPriority(scrshotThread.native_handle(), THREAD_PRIORITY_BELOW_NORMAL);
|
||||
#endif
|
||||
bool result = true;
|
||||
|
||||
OSD::AddMessage("Saving Screenshot... ", 2000);
|
||||
|
||||
#else
|
||||
bool result = SaveTGA(filename.c_str(), W, H, data);
|
||||
free(data);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ public:
|
||||
|
||||
void RenderText(const char* pstr, int left, int top, u32 color) override;
|
||||
void DrawDebugInfo();
|
||||
static void FlipImageData(u8 *data, int w, int h);
|
||||
void FlipImageData(u8 *data, int w, int h);
|
||||
|
||||
u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override;
|
||||
|
||||
@ -80,7 +80,7 @@ public:
|
||||
|
||||
void UpdateViewport() override;
|
||||
|
||||
static void TakeScreenshot(const TargetRectangle &rc, std::string filename);
|
||||
bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc);
|
||||
|
||||
private:
|
||||
void UpdateEFBCache(EFBAccessType type, u32 cacheRectIdx, const EFBRectangle& efbPixelRc, const TargetRectangle& targetPixelRc, const u32* data);
|
||||
|
@ -341,7 +341,7 @@ void VertexManager::vFlush()
|
||||
tr.right = Renderer::GetTargetWidth();
|
||||
tr.top = 0;
|
||||
tr.bottom = Renderer::GetTargetHeight();
|
||||
Renderer::TakeScreenshot(tr, str);
|
||||
g_renderer->SaveScreenshot(str, tr);
|
||||
}
|
||||
#endif
|
||||
g_Config.iSaveTargetId++;
|
||||
|
Reference in New Issue
Block a user