mirror of
https://github.com/yuzu-emu/yuzu-android.git
synced 2025-07-10 12:08:01 -05:00
Merge pull request #1886 from FearlessTobi/port-4164
Port citra-emu/citra#4164: "citra_qt, video_core: Screenshot functionality"
This commit is contained in:
@ -14,6 +14,8 @@
|
||||
#include "input_common/keyboard.h"
|
||||
#include "input_common/main.h"
|
||||
#include "input_common/motion_emu.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
#include "video_core/video_core.h"
|
||||
#include "yuzu/bootmanager.h"
|
||||
|
||||
EmuThread::EmuThread(GRenderWindow* render_window) : render_window(render_window) {}
|
||||
@ -333,6 +335,22 @@ void GRenderWindow::InitRenderTarget() {
|
||||
BackupGeometry();
|
||||
}
|
||||
|
||||
void GRenderWindow::CaptureScreenshot(u16 res_scale, const QString& screenshot_path) {
|
||||
auto& renderer = Core::System::GetInstance().Renderer();
|
||||
|
||||
if (!res_scale)
|
||||
res_scale = VideoCore::GetResolutionScaleFactor(renderer);
|
||||
|
||||
const Layout::FramebufferLayout layout{Layout::FrameLayoutFromResolutionScale(res_scale)};
|
||||
screenshot_image = QImage(QSize(layout.width, layout.height), QImage::Format_RGB32);
|
||||
renderer.RequestScreenshot(screenshot_image.bits(),
|
||||
[=] {
|
||||
screenshot_image.mirrored(false, true).save(screenshot_path);
|
||||
LOG_INFO(Frontend, "The screenshot is saved.");
|
||||
},
|
||||
layout);
|
||||
}
|
||||
|
||||
void GRenderWindow::OnMinimalClientAreaChangeRequest(
|
||||
const std::pair<unsigned, unsigned>& minimal_size) {
|
||||
setMinimumSize(minimal_size.first, minimal_size.second);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <QGLWidget>
|
||||
#include <QImage>
|
||||
#include <QThread>
|
||||
#include "common/thread.h"
|
||||
#include "core/core.h"
|
||||
@ -139,6 +140,8 @@ public:
|
||||
|
||||
void InitRenderTarget();
|
||||
|
||||
void CaptureScreenshot(u16 res_scale, const QString& screenshot_path);
|
||||
|
||||
public slots:
|
||||
void moveContext(); // overridden
|
||||
|
||||
@ -165,6 +168,9 @@ private:
|
||||
|
||||
EmuThread* emu_thread;
|
||||
|
||||
/// Temporary storage of the screenshot taken
|
||||
QImage screenshot_image;
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent* event) override;
|
||||
};
|
||||
|
@ -468,6 +468,8 @@ void Config::ReadValues() {
|
||||
UISettings::values.theme = qt_config->value("theme", UISettings::themes[0].second).toString();
|
||||
UISettings::values.enable_discord_presence =
|
||||
qt_config->value("enable_discord_presence", true).toBool();
|
||||
UISettings::values.screenshot_resolution_factor =
|
||||
static_cast<u16>(qt_config->value("screenshot_resolution_factor", 0).toUInt());
|
||||
|
||||
qt_config->beginGroup("UIGameList");
|
||||
UISettings::values.show_unknown = qt_config->value("show_unknown", true).toBool();
|
||||
@ -689,6 +691,8 @@ void Config::SaveValues() {
|
||||
qt_config->beginGroup("UI");
|
||||
qt_config->setValue("theme", UISettings::values.theme);
|
||||
qt_config->setValue("enable_discord_presence", UISettings::values.enable_discord_presence);
|
||||
qt_config->setValue("screenshot_resolution_factor",
|
||||
UISettings::values.screenshot_resolution_factor);
|
||||
|
||||
qt_config->beginGroup("UIGameList");
|
||||
qt_config->setValue("show_unknown", UISettings::values.show_unknown);
|
||||
@ -710,6 +714,7 @@ void Config::SaveValues() {
|
||||
qt_config->beginGroup("Paths");
|
||||
qt_config->setValue("romsPath", UISettings::values.roms_path);
|
||||
qt_config->setValue("symbolsPath", UISettings::values.symbols_path);
|
||||
qt_config->setValue("screenshotPath", UISettings::values.screenshot_path);
|
||||
qt_config->setValue("gameListRootDir", UISettings::values.gamedir);
|
||||
qt_config->setValue("gameListDeepScan", UISettings::values.gamedir_deepscan);
|
||||
qt_config->setValue("recentFiles", UISettings::values.recent_files);
|
||||
|
@ -358,6 +358,9 @@ void GMainWindow::InitializeHotkeys() {
|
||||
Qt::ApplicationShortcut);
|
||||
hotkey_registry.RegisterHotkey("Main Window", "Load Amiibo", QKeySequence(Qt::Key_F2),
|
||||
Qt::ApplicationShortcut);
|
||||
hotkey_registry.RegisterHotkey("Main Window", "Capture Screenshot",
|
||||
QKeySequence(QKeySequence::Print));
|
||||
|
||||
hotkey_registry.LoadHotkeys();
|
||||
|
||||
connect(hotkey_registry.GetHotkey("Main Window", "Load File", this), &QShortcut::activated,
|
||||
@ -417,6 +420,12 @@ void GMainWindow::InitializeHotkeys() {
|
||||
OnLoadAmiibo();
|
||||
}
|
||||
});
|
||||
connect(hotkey_registry.GetHotkey("Main Window", "Capture Screenshot", this),
|
||||
&QShortcut::activated, this, [&] {
|
||||
if (emu_thread->IsRunning()) {
|
||||
OnCaptureScreenshot();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void GMainWindow::SetDefaultUIGeometry() {
|
||||
@ -514,6 +523,10 @@ void GMainWindow::ConnectMenuEvents() {
|
||||
hotkey_registry.GetHotkey("Main Window", "Fullscreen", this)->key());
|
||||
connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen);
|
||||
|
||||
// Movie
|
||||
connect(ui.action_Capture_Screenshot, &QAction::triggered, this,
|
||||
&GMainWindow::OnCaptureScreenshot);
|
||||
|
||||
// Help
|
||||
connect(ui.action_Open_yuzu_Folder, &QAction::triggered, this, &GMainWindow::OnOpenYuzuFolder);
|
||||
connect(ui.action_Rederive, &QAction::triggered, this,
|
||||
@ -751,6 +764,7 @@ void GMainWindow::ShutdownGame() {
|
||||
ui.action_Restart->setEnabled(false);
|
||||
ui.action_Report_Compatibility->setEnabled(false);
|
||||
ui.action_Load_Amiibo->setEnabled(false);
|
||||
ui.action_Capture_Screenshot->setEnabled(false);
|
||||
render_window->hide();
|
||||
game_list->show();
|
||||
game_list->setFilterFocus();
|
||||
@ -1314,6 +1328,7 @@ void GMainWindow::OnStartGame() {
|
||||
|
||||
discord_rpc->Update();
|
||||
ui.action_Load_Amiibo->setEnabled(true);
|
||||
ui.action_Capture_Screenshot->setEnabled(true);
|
||||
}
|
||||
|
||||
void GMainWindow::OnPauseGame() {
|
||||
@ -1322,6 +1337,7 @@ void GMainWindow::OnPauseGame() {
|
||||
ui.action_Start->setEnabled(true);
|
||||
ui.action_Pause->setEnabled(false);
|
||||
ui.action_Stop->setEnabled(true);
|
||||
ui.action_Capture_Screenshot->setEnabled(false);
|
||||
}
|
||||
|
||||
void GMainWindow::OnStopGame() {
|
||||
@ -1484,6 +1500,18 @@ void GMainWindow::OnToggleFilterBar() {
|
||||
}
|
||||
}
|
||||
|
||||
void GMainWindow::OnCaptureScreenshot() {
|
||||
OnPauseGame();
|
||||
const QString path =
|
||||
QFileDialog::getSaveFileName(this, tr("Capture Screenshot"),
|
||||
UISettings::values.screenshot_path, tr("PNG Image (*.png)"));
|
||||
if (!path.isEmpty()) {
|
||||
UISettings::values.screenshot_path = QFileInfo(path).path();
|
||||
render_window->CaptureScreenshot(UISettings::values.screenshot_resolution_factor, path);
|
||||
}
|
||||
OnStartGame();
|
||||
}
|
||||
|
||||
void GMainWindow::UpdateStatusBar() {
|
||||
if (emu_thread == nullptr) {
|
||||
status_bar_update_timer.stop();
|
||||
|
@ -189,6 +189,7 @@ private slots:
|
||||
void ShowFullscreen();
|
||||
void HideFullscreen();
|
||||
void ToggleWindowMode();
|
||||
void OnCaptureScreenshot();
|
||||
void OnCoreError(Core::System::ResultStatus, std::string);
|
||||
void OnReinitializeKeys(ReinitializeKeyBehavior behavior);
|
||||
|
||||
|
@ -101,11 +101,13 @@
|
||||
<addaction name="action_Show_Status_Bar"/>
|
||||
<addaction name="menu_View_Debugging"/>
|
||||
</widget>
|
||||
<widget class ="QMenu" name="menu_Tools">
|
||||
<widget class="QMenu" name="menu_Tools">
|
||||
<property name="title">
|
||||
<string>Tools</string>
|
||||
</property>
|
||||
<addaction name="action_Rederive" />
|
||||
<addaction name="action_Rederive"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_Capture_Screenshot"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_Help">
|
||||
<property name="title">
|
||||
@ -118,7 +120,7 @@
|
||||
<addaction name="menu_File"/>
|
||||
<addaction name="menu_Emulation"/>
|
||||
<addaction name="menu_View"/>
|
||||
<addaction name="menu_Tools" />
|
||||
<addaction name="menu_Tools"/>
|
||||
<addaction name="menu_Help"/>
|
||||
</widget>
|
||||
<action name="action_Install_File_NAND">
|
||||
@ -173,11 +175,11 @@
|
||||
<string>&Stop</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Rederive">
|
||||
<property name="text">
|
||||
<string>Reinitialize keys...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Rederive">
|
||||
<property name="text">
|
||||
<string>Reinitialize keys...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_About">
|
||||
<property name="text">
|
||||
<string>About yuzu</string>
|
||||
@ -252,39 +254,47 @@
|
||||
<string>Fullscreen</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Restart">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Restart</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Load_Amiibo">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load Amiibo...</string>
|
||||
</property>
|
||||
<action name="action_Restart">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Restart</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Report_Compatibility">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Report Compatibility</string>
|
||||
</property>
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Open_yuzu_Folder">
|
||||
<property name="text">
|
||||
<string>Open yuzu Folder</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<action name="action_Load_Amiibo">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load Amiibo...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Report_Compatibility">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Report Compatibility</string>
|
||||
</property>
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Open_yuzu_Folder">
|
||||
<property name="text">
|
||||
<string>Open yuzu Folder</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Capture_Screenshot">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Capture Screenshot</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace UISettings {
|
||||
|
||||
@ -42,8 +43,11 @@ struct Values {
|
||||
// Discord RPC
|
||||
bool enable_discord_presence;
|
||||
|
||||
u16 screenshot_resolution_factor;
|
||||
|
||||
QString roms_path;
|
||||
QString symbols_path;
|
||||
QString screenshot_path;
|
||||
QString gamedir;
|
||||
bool gamedir_deepscan;
|
||||
QStringList recent_files;
|
||||
|
Reference in New Issue
Block a user