mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
Allow taking screenshots in the app menu
This commit is contained in:
parent
e0e96200b9
commit
d21fef52ae
@ -1056,7 +1056,7 @@ namespace SaveState
|
|||||||
case SAVESTATE_SAVE_SCREENSHOT:
|
case SAVESTATE_SAVE_SCREENSHOT:
|
||||||
{
|
{
|
||||||
int maxResMultiplier = 2;
|
int maxResMultiplier = 2;
|
||||||
tempResult = TakeGameScreenshot(op.filename, ScreenshotFormat::JPG, SCREENSHOT_DISPLAY, nullptr, nullptr, maxResMultiplier);
|
tempResult = TakeGameScreenshot(nullptr, op.filename, ScreenshotFormat::JPG, SCREENSHOT_DISPLAY, nullptr, nullptr, maxResMultiplier);
|
||||||
callbackResult = tempResult ? Status::SUCCESS : Status::FAILURE;
|
callbackResult = tempResult ? Status::SUCCESS : Status::FAILURE;
|
||||||
if (!tempResult) {
|
if (!tempResult) {
|
||||||
ERROR_LOG(SAVESTATE, "Failed to take a screenshot for the savestate! %s", op.filename.c_str());
|
ERROR_LOG(SAVESTATE, "Failed to take a screenshot for the savestate! %s", op.filename.c_str());
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "Core/Screenshot.h"
|
#include "Core/Screenshot.h"
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "GPU/Common/GPUDebugInterface.h"
|
#include "GPU/Common/GPUDebugInterface.h"
|
||||||
|
#include "GPU/Common/FramebufferManagerCommon.h"
|
||||||
#include "GPU/GPUInterface.h"
|
#include "GPU/GPUInterface.h"
|
||||||
#include "GPU/GPUState.h"
|
#include "GPU/GPUState.h"
|
||||||
|
|
||||||
@ -328,28 +329,30 @@ static GPUDebugBuffer ApplyRotation(const GPUDebugBuffer &buf, DisplayRotation r
|
|||||||
return rotated;
|
return rotated;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TakeGameScreenshot(const Path &filename, ScreenshotFormat fmt, ScreenshotType type, int *width, int *height, int maxRes) {
|
bool TakeGameScreenshot(Draw::DrawContext *draw, const Path &filename, ScreenshotFormat fmt, ScreenshotType type, int *width, int *height, int maxRes) {
|
||||||
if (!gpuDebug) {
|
|
||||||
ERROR_LOG(SYSTEM, "Can't take screenshots when GPU not running");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
GPUDebugBuffer buf;
|
GPUDebugBuffer buf;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
u32 w = (u32)-1;
|
u32 w = (u32)-1;
|
||||||
u32 h = (u32)-1;
|
u32 h = (u32)-1;
|
||||||
|
|
||||||
if (type == SCREENSHOT_DISPLAY || type == SCREENSHOT_RENDER) {
|
if (type == SCREENSHOT_DISPLAY || type == SCREENSHOT_RENDER) {
|
||||||
|
if (!gpuDebug) {
|
||||||
|
ERROR_LOG(SYSTEM, "Can't take screenshots when GPU not running");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
success = gpuDebug->GetCurrentFramebuffer(buf, type == SCREENSHOT_RENDER ? GPU_DBG_FRAMEBUF_RENDER : GPU_DBG_FRAMEBUF_DISPLAY, maxRes);
|
success = gpuDebug->GetCurrentFramebuffer(buf, type == SCREENSHOT_RENDER ? GPU_DBG_FRAMEBUF_RENDER : GPU_DBG_FRAMEBUF_DISPLAY, maxRes);
|
||||||
w = maxRes > 0 ? 480 * maxRes : PSP_CoreParameter().renderWidth;
|
w = maxRes > 0 ? 480 * maxRes : PSP_CoreParameter().renderWidth;
|
||||||
h = maxRes > 0 ? 272 * maxRes : PSP_CoreParameter().renderHeight;
|
h = maxRes > 0 ? 272 * maxRes : PSP_CoreParameter().renderHeight;
|
||||||
} else if (g_display.rotation != DisplayRotation::ROTATE_0) {
|
} else if (g_display.rotation != DisplayRotation::ROTATE_0) {
|
||||||
|
_dbg_assert_(draw);
|
||||||
GPUDebugBuffer temp;
|
GPUDebugBuffer temp;
|
||||||
success = gpuDebug->GetOutputFramebuffer(temp);
|
success = ::GetOutputFramebuffer(draw, buf);
|
||||||
if (success) {
|
if (success) {
|
||||||
buf = ApplyRotation(temp, g_display.rotation);
|
buf = ApplyRotation(temp, g_display.rotation);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
success = gpuDebug->GetOutputFramebuffer(buf);
|
_dbg_assert_(draw);
|
||||||
|
success = ::GetOutputFramebuffer(draw, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
@ -20,6 +20,9 @@
|
|||||||
#include "Common/File/Path.h"
|
#include "Common/File/Path.h"
|
||||||
|
|
||||||
struct GPUDebugBuffer;
|
struct GPUDebugBuffer;
|
||||||
|
namespace Draw {
|
||||||
|
class DrawContext;
|
||||||
|
}
|
||||||
|
|
||||||
enum class ScreenshotFormat {
|
enum class ScreenshotFormat {
|
||||||
PNG,
|
PNG,
|
||||||
@ -38,7 +41,7 @@ enum ScreenshotType {
|
|||||||
const u8 *ConvertBufferToScreenshot(const GPUDebugBuffer &buf, bool alpha, u8 *&temp, u32 &w, u32 &h);
|
const u8 *ConvertBufferToScreenshot(const GPUDebugBuffer &buf, bool alpha, u8 *&temp, u32 &w, u32 &h);
|
||||||
|
|
||||||
// Can only be used while in game.
|
// Can only be used while in game.
|
||||||
bool TakeGameScreenshot(const Path &filename, ScreenshotFormat fmt, ScreenshotType type, int *width = nullptr, int *height = nullptr, int maxRes = -1);
|
bool TakeGameScreenshot(Draw::DrawContext *draw, const Path &filename, ScreenshotFormat fmt, ScreenshotType type, int *width = nullptr, int *height = nullptr, int maxRes = -1);
|
||||||
|
|
||||||
bool Save888RGBScreenshot(const Path &filename, ScreenshotFormat fmt, const u8 *bufferRGB888, int w, int h);
|
bool Save888RGBScreenshot(const Path &filename, ScreenshotFormat fmt, const u8 *bufferRGB888, int w, int h);
|
||||||
bool Save8888RGBAScreenshot(const Path &filename, const u8 *bufferRGBA8888, int w, int h);
|
bool Save8888RGBAScreenshot(const Path &filename, const u8 *bufferRGBA8888, int w, int h);
|
||||||
|
@ -3076,15 +3076,22 @@ bool FramebufferManagerCommon::GetStencilbuffer(u32 fb_address, int fb_stride, G
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FramebufferManagerCommon::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
|
bool GetOutputFramebuffer(Draw::DrawContext *draw, GPUDebugBuffer &buffer) {
|
||||||
int w, h;
|
int w, h;
|
||||||
draw_->GetFramebufferDimensions(nullptr, &w, &h);
|
draw->GetFramebufferDimensions(nullptr, &w, &h);
|
||||||
Draw::DataFormat fmt = draw_->PreferredFramebufferReadbackFormat(nullptr);
|
Draw::DataFormat fmt = draw->PreferredFramebufferReadbackFormat(nullptr);
|
||||||
// Ignore preferred formats other than BGRA.
|
// Ignore preferred formats other than BGRA.
|
||||||
if (fmt != Draw::DataFormat::B8G8R8A8_UNORM)
|
if (fmt != Draw::DataFormat::B8G8R8A8_UNORM)
|
||||||
fmt = Draw::DataFormat::R8G8B8A8_UNORM;
|
fmt = Draw::DataFormat::R8G8B8A8_UNORM;
|
||||||
buffer.Allocate(w, h, fmt == Draw::DataFormat::R8G8B8A8_UNORM ? GPU_DBG_FORMAT_8888 : GPU_DBG_FORMAT_8888_BGRA, false);
|
|
||||||
bool retval = draw_->CopyFramebufferToMemory(nullptr, Draw::FB_COLOR_BIT, 0, 0, w, h, fmt, buffer.GetData(), w, Draw::ReadbackMode::BLOCK, "GetOutputFramebuffer");
|
bool flipped = g_Config.iGPUBackend == (int)GPUBackend::OPENGL;
|
||||||
|
|
||||||
|
buffer.Allocate(w, h, fmt == Draw::DataFormat::R8G8B8A8_UNORM ? GPU_DBG_FORMAT_8888 : GPU_DBG_FORMAT_8888_BGRA, flipped);
|
||||||
|
return draw->CopyFramebufferToMemory(nullptr, Draw::FB_COLOR_BIT, 0, 0, w, h, fmt, buffer.GetData(), w, Draw::ReadbackMode::BLOCK, "GetOutputFramebuffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FramebufferManagerCommon::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
|
||||||
|
bool retval = ::GetOutputFramebuffer(draw_, buffer);
|
||||||
// That may have unbound the framebuffer, rebind to avoid crashes when debugging.
|
// That may have unbound the framebuffer, rebind to avoid crashes when debugging.
|
||||||
RebindFramebuffer("RebindFramebuffer - GetOutputFramebuffer");
|
RebindFramebuffer("RebindFramebuffer - GetOutputFramebuffer");
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -647,3 +647,6 @@ protected:
|
|||||||
u8 *convBuf_ = nullptr;
|
u8 *convBuf_ = nullptr;
|
||||||
u32 convBufSize_ = 0;
|
u32 convBufSize_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Should probably live elsewhere.
|
||||||
|
bool GetOutputFramebuffer(Draw::DrawContext *draw, GPUDebugBuffer &buffer);
|
||||||
|
@ -968,7 +968,7 @@ void NativeShutdownGraphics() {
|
|||||||
INFO_LOG(SYSTEM, "NativeShutdownGraphics done");
|
INFO_LOG(SYSTEM, "NativeShutdownGraphics done");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TakeScreenshot() {
|
static void TakeScreenshot(Draw::DrawContext *draw) {
|
||||||
Path path = GetSysDirectory(DIRECTORY_SCREENSHOT);
|
Path path = GetSysDirectory(DIRECTORY_SCREENSHOT);
|
||||||
if (!File::Exists(path)) {
|
if (!File::Exists(path)) {
|
||||||
File::CreateDir(path);
|
File::CreateDir(path);
|
||||||
@ -991,7 +991,7 @@ static void TakeScreenshot() {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = TakeGameScreenshot(filename, g_Config.bScreenshotsAsPNG ? ScreenshotFormat::PNG : ScreenshotFormat::JPG, SCREENSHOT_OUTPUT);
|
bool success = TakeGameScreenshot(draw, filename, g_Config.bScreenshotsAsPNG ? ScreenshotFormat::PNG : ScreenshotFormat::JPG, SCREENSHOT_OUTPUT);
|
||||||
if (success) {
|
if (success) {
|
||||||
g_OSD.Show(OSDType::MESSAGE_FILE_LINK, filename.ToString(), 0.0f, "screenshot_link");
|
g_OSD.Show(OSDType::MESSAGE_FILE_LINK, filename.ToString(), 0.0f, "screenshot_link");
|
||||||
if (System_GetPropertyBool(SYSPROP_CAN_SHOW_FILE)) {
|
if (System_GetPropertyBool(SYSPROP_CAN_SHOW_FILE)) {
|
||||||
@ -1012,7 +1012,7 @@ static void TakeScreenshot() {
|
|||||||
|
|
||||||
void CallbackPostRender(UIContext *dc, void *userdata) {
|
void CallbackPostRender(UIContext *dc, void *userdata) {
|
||||||
if (g_TakeScreenshot) {
|
if (g_TakeScreenshot) {
|
||||||
TakeScreenshot();
|
TakeScreenshot(dc->GetDrawContext());
|
||||||
g_TakeScreenshot = false;
|
g_TakeScreenshot = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ ScreenRenderFlags ReportScreen::render(ScreenRenderMode mode) {
|
|||||||
File::CreateDir(path);
|
File::CreateDir(path);
|
||||||
}
|
}
|
||||||
screenshotFilename_ = path / ".reporting.jpg";
|
screenshotFilename_ = path / ".reporting.jpg";
|
||||||
if (TakeGameScreenshot(screenshotFilename_, ScreenshotFormat::JPG, SCREENSHOT_DISPLAY, nullptr, nullptr, 4)) {
|
if (TakeGameScreenshot(screenManager()->getDrawContext(), screenshotFilename_, ScreenshotFormat::JPG, SCREENSHOT_DISPLAY, nullptr, nullptr, 4)) {
|
||||||
// Redo the views already, now with a screenshot included.
|
// Redo the views already, now with a screenshot included.
|
||||||
RecreateViews();
|
RecreateViews();
|
||||||
} else {
|
} else {
|
||||||
|
@ -107,7 +107,6 @@ namespace MainWindow {
|
|||||||
EnableMenuItem(menu, ID_DEBUG_LOADSYMFILE, menuEnable);
|
EnableMenuItem(menu, ID_DEBUG_LOADSYMFILE, menuEnable);
|
||||||
EnableMenuItem(menu, ID_DEBUG_SAVESYMFILE, menuEnable);
|
EnableMenuItem(menu, ID_DEBUG_SAVESYMFILE, menuEnable);
|
||||||
EnableMenuItem(menu, ID_DEBUG_RESETSYMBOLTABLE, menuEnable);
|
EnableMenuItem(menu, ID_DEBUG_RESETSYMBOLTABLE, menuEnable);
|
||||||
EnableMenuItem(menu, ID_DEBUG_TAKESCREENSHOT, menuEnable);
|
|
||||||
EnableMenuItem(menu, ID_DEBUG_SHOWDEBUGSTATISTICS, menuInGameEnable);
|
EnableMenuItem(menu, ID_DEBUG_SHOWDEBUGSTATISTICS, menuInGameEnable);
|
||||||
EnableMenuItem(menu, ID_DEBUG_EXTRACTFILE, menuEnable);
|
EnableMenuItem(menu, ID_DEBUG_EXTRACTFILE, menuEnable);
|
||||||
EnableMenuItem(menu, ID_DEBUG_MEMORYBASE, menuInGameEnable);
|
EnableMenuItem(menu, ID_DEBUG_MEMORYBASE, menuInGameEnable);
|
||||||
|
Loading…
Reference in New Issue
Block a user