early-access version 2237

This commit is contained in:
pineappleEA 2021-11-22 07:17:44 +01:00
parent d8ed9646f4
commit e2e56152b0
10 changed files with 188 additions and 61 deletions

View File

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 2234. This is the source code for early-access 2237.
## Legal Notice ## Legal Notice

View File

@ -86,6 +86,26 @@ public:
num_instructions, MemoryReadCode(pc)); num_instructions, MemoryReadCode(pc));
} }
void InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation op,
VAddr value) override {
switch (op) {
case Dynarmic::A64::InstructionCacheOperation::InvalidateByVAToPoU: {
static constexpr u64 ICACHE_LINE_SIZE = 64;
const u64 cache_line_start = value & ~(ICACHE_LINE_SIZE - 1);
parent.InvalidateCacheRange(cache_line_start, ICACHE_LINE_SIZE);
break;
}
case Dynarmic::A64::InstructionCacheOperation::InvalidateAllToPoU:
parent.ClearInstructionCache();
break;
case Dynarmic::A64::InstructionCacheOperation::InvalidateAllToPoUInnerSharable:
default:
LOG_DEBUG(Core_ARM, "Unprocesseed instruction cache operation: {}", op);
break;
}
}
void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override { void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override {
switch (exception) { switch (exception) {
case Dynarmic::A64::Exception::WaitForInterrupt: case Dynarmic::A64::Exception::WaitForInterrupt:

View File

@ -175,6 +175,9 @@ Common::Input::ButtonNames Mouse::GetUIName(const Common::ParamPackage& params)
if (params.Has("button")) { if (params.Has("button")) {
return Common::Input::ButtonNames::Value; return Common::Input::ButtonNames::Value;
} }
if (params.Has("axis")) {
return Common::Input::ButtonNames::Value;
}
return Common::Input::ButtonNames::Invalid; return Common::Input::ButtonNames::Invalid;
} }

View File

@ -61,6 +61,7 @@ void MappingFactory::RegisterButton(const MappingData& data) {
} }
new_input.Set("port", static_cast<int>(data.pad.port)); new_input.Set("port", static_cast<int>(data.pad.port));
new_input.Set("pad", static_cast<int>(data.pad.pad)); new_input.Set("pad", static_cast<int>(data.pad.pad));
switch (data.type) { switch (data.type) {
case EngineInputType::Button: case EngineInputType::Button:
// Workaround for old compatibility // Workaround for old compatibility
@ -75,6 +76,10 @@ void MappingFactory::RegisterButton(const MappingData& data) {
new_input.Set("direction", data.hat_name); new_input.Set("direction", data.hat_name);
break; break;
case EngineInputType::Analog: case EngineInputType::Analog:
// Ignore mouse axis when mapping buttons
if (data.engine == "mouse") {
return;
}
new_input.Set("axis", data.index); new_input.Set("axis", data.index);
new_input.Set("threshold", 0.5f); new_input.Set("threshold", 0.5f);
break; break;

View File

@ -1155,11 +1155,13 @@ void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase*
if (src) { if (src) {
is_resolve = src->info.num_samples > 1; is_resolve = src->info.num_samples > 1;
src_info.num_samples = src->info.num_samples; src_info.num_samples = src->info.num_samples;
src_info.size = src->info.size; src_info.size.width = src->info.size.width;
src_info.size.height = src->info.size.height;
} }
if (dst) { if (dst) {
dst_info.num_samples = dst->info.num_samples; dst_info.num_samples = dst->info.num_samples;
dst_info.size = dst->info.size; dst_info.size.width = dst->info.size.width;
dst_info.size.height = dst->info.size.height;
} }
ASSERT(!is_resolve || dst_info.format == src_info.format); ASSERT(!is_resolve || dst_info.format == src_info.format);
} }

View File

@ -303,6 +303,7 @@ GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_,
connect(this, &GRenderWindow::ExecuteProgramSignal, parent, &GMainWindow::OnExecuteProgram, connect(this, &GRenderWindow::ExecuteProgramSignal, parent, &GMainWindow::OnExecuteProgram,
Qt::QueuedConnection); Qt::QueuedConnection);
connect(this, &GRenderWindow::ExitSignal, parent, &GMainWindow::OnExit, Qt::QueuedConnection); connect(this, &GRenderWindow::ExitSignal, parent, &GMainWindow::OnExit, Qt::QueuedConnection);
connect(this, &GRenderWindow::TasPlaybackStateChanged, parent, &GMainWindow::OnTasStateChanged);
} }
void GRenderWindow::ExecuteProgram(std::size_t program_index) { void GRenderWindow::ExecuteProgram(std::size_t program_index) {
@ -319,10 +320,19 @@ GRenderWindow::~GRenderWindow() {
void GRenderWindow::OnFrameDisplayed() { void GRenderWindow::OnFrameDisplayed() {
input_subsystem->GetTas()->UpdateThread(); input_subsystem->GetTas()->UpdateThread();
const InputCommon::TasInput::TasState new_tas_state =
std::get<0>(input_subsystem->GetTas()->GetStatus());
if (!first_frame) { if (!first_frame) {
last_tas_state = new_tas_state;
first_frame = true; first_frame = true;
emit FirstFrameDisplayed(); emit FirstFrameDisplayed();
} }
if (new_tas_state != last_tas_state) {
last_tas_state = new_tas_state;
emit TasPlaybackStateChanged();
}
} }
bool GRenderWindow::IsShown() const { bool GRenderWindow::IsShown() const {

View File

@ -33,6 +33,10 @@ class InputSubsystem;
enum class MouseButton; enum class MouseButton;
} // namespace InputCommon } // namespace InputCommon
namespace InputCommon::TasInput {
enum class TasState;
} // namespace InputCommon::TasInput
namespace VideoCore { namespace VideoCore {
enum class LoadCallbackStage; enum class LoadCallbackStage;
class RendererBase; class RendererBase;
@ -207,6 +211,7 @@ signals:
void ExecuteProgramSignal(std::size_t program_index); void ExecuteProgramSignal(std::size_t program_index);
void ExitSignal(); void ExitSignal();
void MouseActivity(); void MouseActivity();
void TasPlaybackStateChanged();
private: private:
void TouchBeginEvent(const QTouchEvent* event); void TouchBeginEvent(const QTouchEvent* event);
@ -240,6 +245,7 @@ private:
QWidget* child_widget = nullptr; QWidget* child_widget = nullptr;
bool first_frame = false; bool first_frame = false;
InputCommon::TasInput::TasState last_tas_state;
std::array<std::size_t, 16> touch_ids{}; std::array<std::size_t, 16> touch_ids{};

View File

@ -971,6 +971,9 @@ void GMainWindow::InitializeHotkeys() {
const QString toggle_status_bar = QStringLiteral("Toggle Status Bar"); const QString toggle_status_bar = QStringLiteral("Toggle Status Bar");
const QString fullscreen = QStringLiteral("Fullscreen"); const QString fullscreen = QStringLiteral("Fullscreen");
const QString capture_screenshot = QStringLiteral("Capture Screenshot"); const QString capture_screenshot = QStringLiteral("Capture Screenshot");
const QString tas_start_stop = QStringLiteral("TAS Start/Stop");
const QString tas_record = QStringLiteral("TAS Record");
const QString tas_reset = QStringLiteral("TAS Reset");
ui->action_Load_File->setShortcut(hotkey_registry.GetKeySequence(main_window, load_file)); ui->action_Load_File->setShortcut(hotkey_registry.GetKeySequence(main_window, load_file));
ui->action_Load_File->setShortcutContext( ui->action_Load_File->setShortcutContext(
@ -1011,6 +1014,18 @@ void GMainWindow::InitializeHotkeys() {
ui->action_Fullscreen->setShortcutContext( ui->action_Fullscreen->setShortcutContext(
hotkey_registry.GetShortcutContext(main_window, fullscreen)); hotkey_registry.GetShortcutContext(main_window, fullscreen));
ui->action_TAS_Start->setShortcut(hotkey_registry.GetKeySequence(main_window, tas_start_stop));
ui->action_TAS_Start->setShortcutContext(
hotkey_registry.GetShortcutContext(main_window, tas_start_stop));
ui->action_TAS_Record->setShortcut(hotkey_registry.GetKeySequence(main_window, tas_record));
ui->action_TAS_Record->setShortcutContext(
hotkey_registry.GetShortcutContext(main_window, tas_record));
ui->action_TAS_Reset->setShortcut(hotkey_registry.GetKeySequence(main_window, tas_reset));
ui->action_TAS_Reset->setShortcutContext(
hotkey_registry.GetShortcutContext(main_window, tas_reset));
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Load File"), this), connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Load File"), this),
&QShortcut::activated, this, &GMainWindow::OnMenuLoadFile); &QShortcut::activated, this, &GMainWindow::OnMenuLoadFile);
connect( connect(
@ -1101,28 +1116,6 @@ void GMainWindow::InitializeHotkeys() {
render_window->setAttribute(Qt::WA_Hover, true); render_window->setAttribute(Qt::WA_Hover, true);
} }
}); });
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("TAS Start/Stop"), this),
&QShortcut::activated, this, [&] {
if (!emulation_running) {
return;
}
input_subsystem->GetTas()->StartStop();
});
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("TAS Reset"), this),
&QShortcut::activated, this, [&] { input_subsystem->GetTas()->Reset(); });
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("TAS Record"), this),
&QShortcut::activated, this, [&] {
if (!emulation_running) {
return;
}
bool is_recording = input_subsystem->GetTas()->Record();
if (!is_recording) {
const auto res = QMessageBox::question(this, tr("TAS Recording"),
tr("Overwrite file of player 1?"),
QMessageBox::Yes | QMessageBox::No);
input_subsystem->GetTas()->SaveRecording(res == QMessageBox::Yes);
}
});
} }
void GMainWindow::SetDefaultUIGeometry() { void GMainWindow::SetDefaultUIGeometry() {
@ -1242,11 +1235,11 @@ void GMainWindow::ConnectMenuEvents() {
connect(ui->action_Restart, &QAction::triggered, this, connect(ui->action_Restart, &QAction::triggered, this,
[this] { BootGame(QString(game_path)); }); [this] { BootGame(QString(game_path)); });
connect(ui->action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure); connect(ui->action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure);
connect(ui->action_Configure_Tas, &QAction::triggered, this, &GMainWindow::OnConfigureTas);
connect(ui->action_Configure_Current_Game, &QAction::triggered, this, connect(ui->action_Configure_Current_Game, &QAction::triggered, this,
&GMainWindow::OnConfigurePerGame); &GMainWindow::OnConfigurePerGame);
// View // View
connect(ui->action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen);
connect(ui->action_Single_Window_Mode, &QAction::triggered, this, connect(ui->action_Single_Window_Mode, &QAction::triggered, this,
&GMainWindow::ToggleWindowMode); &GMainWindow::ToggleWindowMode);
connect(ui->action_Display_Dock_Widget_Headers, &QAction::triggered, this, connect(ui->action_Display_Dock_Widget_Headers, &QAction::triggered, this,
@ -1264,17 +1257,20 @@ void GMainWindow::ConnectMenuEvents() {
ui->menu_Reset_Window_Size->addAction(ui->action_Reset_Window_Size_900); ui->menu_Reset_Window_Size->addAction(ui->action_Reset_Window_Size_900);
ui->menu_Reset_Window_Size->addAction(ui->action_Reset_Window_Size_1080); ui->menu_Reset_Window_Size->addAction(ui->action_Reset_Window_Size_1080);
// Fullscreen // Tools
connect(ui->action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen); connect(ui->action_Rederive, &QAction::triggered, this,
std::bind(&GMainWindow::OnReinitializeKeys, this, ReinitializeKeyBehavior::Warning));
// Movie
connect(ui->action_Capture_Screenshot, &QAction::triggered, this, connect(ui->action_Capture_Screenshot, &QAction::triggered, this,
&GMainWindow::OnCaptureScreenshot); &GMainWindow::OnCaptureScreenshot);
// TAS
connect(ui->action_TAS_Start, &QAction::triggered, this, &GMainWindow::OnTasStartStop);
connect(ui->action_TAS_Record, &QAction::triggered, this, &GMainWindow::OnTasRecord);
connect(ui->action_TAS_Reset, &QAction::triggered, this, &GMainWindow::OnTasReset);
connect(ui->action_Configure_Tas, &QAction::triggered, this, &GMainWindow::OnConfigureTas);
// Help // Help
connect(ui->action_Open_yuzu_Folder, &QAction::triggered, this, &GMainWindow::OnOpenYuzuFolder); connect(ui->action_Open_yuzu_Folder, &QAction::triggered, this, &GMainWindow::OnOpenYuzuFolder);
connect(ui->action_Rederive, &QAction::triggered, this,
std::bind(&GMainWindow::OnReinitializeKeys, this, ReinitializeKeyBehavior::Warning));
connect(ui->action_About, &QAction::triggered, this, &GMainWindow::OnAbout); connect(ui->action_About, &QAction::triggered, this, &GMainWindow::OnAbout);
} }
@ -1588,6 +1584,7 @@ void GMainWindow::ShutdownGame() {
game_list->SetFilterFocus(); game_list->SetFilterFocus();
tas_label->clear(); tas_label->clear();
input_subsystem->GetTas()->Stop(); input_subsystem->GetTas()->Stop();
OnTasStateChanged();
render_window->removeEventFilter(render_window); render_window->removeEventFilter(render_window);
render_window->setAttribute(Qt::WA_Hover, false); render_window->setAttribute(Qt::WA_Hover, false);
@ -2515,6 +2512,7 @@ void GMainWindow::OnStartGame() {
ui->action_Restart->setEnabled(true); ui->action_Restart->setEnabled(true);
ui->action_Configure_Current_Game->setEnabled(true); ui->action_Configure_Current_Game->setEnabled(true);
ui->action_Report_Compatibility->setEnabled(true); ui->action_Report_Compatibility->setEnabled(true);
OnTasStateChanged();
discord_rpc->Update(); discord_rpc->Update();
ui->action_Load_Amiibo->setEnabled(true); ui->action_Load_Amiibo->setEnabled(true);
@ -2827,6 +2825,32 @@ void GMainWindow::OnConfigureTas() {
} }
} }
void GMainWindow::OnTasStartStop() {
if (!emulation_running) {
return;
}
input_subsystem->GetTas()->StartStop();
OnTasStateChanged();
}
void GMainWindow::OnTasRecord() {
if (!emulation_running) {
return;
}
const bool is_recording = input_subsystem->GetTas()->Record();
if (!is_recording) {
const auto res =
QMessageBox::question(this, tr("TAS Recording"), tr("Overwrite file of player 1?"),
QMessageBox::Yes | QMessageBox::No);
input_subsystem->GetTas()->SaveRecording(res == QMessageBox::Yes);
}
OnTasStateChanged();
}
void GMainWindow::OnTasReset() {
input_subsystem->GetTas()->Reset();
}
void GMainWindow::OnConfigurePerGame() { void GMainWindow::OnConfigurePerGame() {
const u64 title_id = system->GetCurrentProcessProgramID(); const u64 title_id = system->GetCurrentProcessProgramID();
OpenPerGameConfiguration(title_id, game_path.toStdString()); OpenPerGameConfiguration(title_id, game_path.toStdString());
@ -3020,6 +3044,24 @@ QString GMainWindow::GetTasStateDescription() const {
} }
} }
void GMainWindow::OnTasStateChanged() {
bool is_running = false;
bool is_recording = false;
if (emulation_running) {
const InputCommon::TasInput::TasState tas_status =
std::get<0>(input_subsystem->GetTas()->GetStatus());
is_running = tas_status == InputCommon::TasInput::TasState::Running;
is_recording = tas_status == InputCommon::TasInput::TasState::Recording;
}
ui->action_TAS_Start->setText(is_running ? tr("&Stop Running") : tr("&Start"));
ui->action_TAS_Record->setText(is_recording ? tr("Stop R&ecording") : tr("R&ecord"));
ui->action_TAS_Start->setEnabled(emulation_running);
ui->action_TAS_Record->setEnabled(emulation_running);
ui->action_TAS_Reset->setEnabled(emulation_running);
}
void GMainWindow::UpdateStatusBar() { void GMainWindow::UpdateStatusBar() {
if (emu_thread == nullptr) { if (emu_thread == nullptr) {
status_bar_update_timer.stop(); status_bar_update_timer.stop();

View File

@ -177,6 +177,7 @@ public slots:
void WebBrowserOpenWebPage(const std::string& main_url, const std::string& additional_args, void WebBrowserOpenWebPage(const std::string& main_url, const std::string& additional_args,
bool is_local); bool is_local);
void OnAppFocusStateChanged(Qt::ApplicationState state); void OnAppFocusStateChanged(Qt::ApplicationState state);
void OnTasStateChanged();
private: private:
void RegisterMetaTypes(); void RegisterMetaTypes();
@ -268,6 +269,9 @@ private slots:
void OnMenuRecentFile(); void OnMenuRecentFile();
void OnConfigure(); void OnConfigure();
void OnConfigureTas(); void OnConfigureTas();
void OnTasStartStop();
void OnTasRecord();
void OnTasReset();
void OnConfigurePerGame(); void OnConfigurePerGame();
void OnLoadAmiibo(); void OnLoadAmiibo();
void OnOpenYuzuFolder(); void OnOpenYuzuFolder();
@ -313,6 +317,7 @@ private:
void OpenURL(const QUrl& url); void OpenURL(const QUrl& url);
void LoadTranslation(); void LoadTranslation();
void OpenPerGameConfiguration(u64 title_id, const std::string& file_name); void OpenPerGameConfiguration(u64 title_id, const std::string& file_name);
QString GetTasStateDescription() const; QString GetTasStateDescription() const;
std::unique_ptr<Ui::MainWindow> ui; std::unique_ptr<Ui::MainWindow> ui;

View File

@ -79,39 +79,39 @@
<string>&amp;View</string> <string>&amp;View</string>
</property> </property>
<widget class="QMenu" name="menu_Reset_Window_Size"> <widget class="QMenu" name="menu_Reset_Window_Size">
<property name="title"> <property name="title">
<string>&amp;Reset Window Size</string> <string>&amp;Reset Window Size</string>
</property> </property>
</widget> </widget>
<action name="action_Reset_Window_Size_720">
<property name="text">
<string>Reset Window Size to &amp;720p</string>
</property>
<property name="iconText">
<string>Reset Window Size to 720p</string>
</property>
</action>
<action name="action_Reset_Window_Size_900">
<property name="text">
<string>Reset Window Size to &amp;900p</string>
</property>
<property name="iconText">
<string>Reset Window Size to 900p</string>
</property>
</action>
<action name="action_Reset_Window_Size_1080">
<property name="text">
<string>Reset Window Size to &amp;1080p</string>
</property>
<property name="iconText">
<string>Reset Window Size to 1080p</string>
</property>
</action>
<widget class="QMenu" name="menu_View_Debugging"> <widget class="QMenu" name="menu_View_Debugging">
<property name="title"> <property name="title">
<string>&amp;Debugging</string> <string>&amp;Debugging</string>
</property> </property>
</widget> </widget>
<action name="action_Reset_Window_Size_720">
<property name="text">
<string>Reset Window Size to &amp;720p</string>
</property>
<property name="iconText">
<string>Reset Window Size to 720p</string>
</property>
</action>
<action name="action_Reset_Window_Size_900">
<property name="text">
<string>Reset Window Size to &amp;900p</string>
</property>
<property name="iconText">
<string>Reset Window Size to 900p</string>
</property>
</action>
<action name="action_Reset_Window_Size_1080">
<property name="text">
<string>Reset Window Size to &amp;1080p</string>
</property>
<property name="iconText">
<string>Reset Window Size to 1080p</string>
</property>
</action>
<addaction name="action_Fullscreen"/> <addaction name="action_Fullscreen"/>
<addaction name="action_Single_Window_Mode"/> <addaction name="action_Single_Window_Mode"/>
<addaction name="action_Display_Dock_Widget_Headers"/> <addaction name="action_Display_Dock_Widget_Headers"/>
@ -125,10 +125,20 @@
<property name="title"> <property name="title">
<string>&amp;Tools</string> <string>&amp;Tools</string>
</property> </property>
<widget class="QMenu" name="menuTAS">
<property name="title">
<string>&amp;TAS</string>
</property>
<addaction name="action_TAS_Start"/>
<addaction name="action_TAS_Record"/>
<addaction name="action_TAS_Reset"/>
<addaction name="separator"/>
<addaction name="action_Configure_Tas"/>
</widget>
<addaction name="action_Rederive"/> <addaction name="action_Rederive"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="action_Capture_Screenshot"/> <addaction name="action_Capture_Screenshot"/>
<addaction name="action_Configure_Tas"/> <addaction name="menuTAS"/>
</widget> </widget>
<widget class="QMenu" name="menu_Help"> <widget class="QMenu" name="menu_Help">
<property name="title"> <property name="title">
@ -309,7 +319,7 @@
</action> </action>
<action name="action_Configure_Tas"> <action name="action_Configure_Tas">
<property name="text"> <property name="text">
<string>Configure &amp;TAS...</string> <string>&amp;Configure TAS...</string>
</property> </property>
</action> </action>
<action name="action_Configure_Current_Game"> <action name="action_Configure_Current_Game">
@ -320,6 +330,30 @@
<string>Configure C&amp;urrent Game...</string> <string>Configure C&amp;urrent Game...</string>
</property> </property>
</action> </action>
<action name="action_TAS_Start">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Start</string>
</property>
</action>
<action name="action_TAS_Reset">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Reset</string>
</property>
</action>
<action name="action_TAS_Record">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>R&amp;ecord</string>
</property>
</action>
</widget> </widget>
<resources> <resources>
<include location="yuzu.qrc"/> <include location="yuzu.qrc"/>