Compare commits

...

4 Commits

Author SHA1 Message Date
Rosalie Wanders e4868018f1 wip core compare 2024-04-08 10:51:44 +02:00
Rosalie Wanders f2af4a69d5 RMG-Core: introduce DebugApi.cpp 2024-04-07 23:34:33 +02:00
Rosalie Wanders b5b97b187a RMG: simplify on_Action_Audio_{Increase,Decrease}Volume() 2024-04-04 23:18:11 +02:00
Rosalie Wanders c6ec9c0686 3rdParty: update mupen64plus-rsp-parallel 2024-03-27 15:20:09 +01:00
15 changed files with 406 additions and 139 deletions
+1 -1
View File
@@ -72,7 +72,7 @@ ExternalProject_Add(mupen64plus-core
SRCDIR=${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-core/src
SUBDIR=${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-core/subprojects
OSD=0 NEW_DYNAREC=1 NO_ASM=$<BOOL:${NO_ASM}> KEYBINDINGS=0 ACCURATE_FPU=1
TARGET=${CORE_FILE} DEBUG=${MAKE_DEBUG}
TARGET=${CORE_FILE} DEBUG=${MAKE_DEBUG} DBG_COMPARE=1
CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
OPTFLAGS=${MAKE_OPTFLAGS}
BUILD_IN_SOURCE False
+2 -2
View File
@@ -6,7 +6,7 @@
[subrepo]
remote = git@github.com:/Rosalie241/parallel-rsp.git
branch = RMG
commit = 71f52c492ac5896a02725152a0e6c59036ee9576
parent = e8f10693c73eeed017f45cf8289a3763ae16c257
commit = f7c164cf0c4131f6cfbcaefba9af3c8eaf6df1b0
parent = eb6dd8068ef4d82e47807ebccca0444d2e3300e2
method = merge
cmdver = 0.4.6
+2
View File
@@ -40,6 +40,7 @@ extern "C"
}
#endif
#if 0 // FIXME: this is broken with upstream mupen64plus-core
if (rd == CP0_REGISTER_SP_SEMAPHORE)
{
if (*rsp->cp0.cr[CP0_REGISTER_SP_SEMAPHORE])
@@ -56,6 +57,7 @@ extern "C"
else
*rsp->cp0.cr[CP0_REGISTER_SP_SEMAPHORE] = 1;
}
#endif
//if (rd == 4) // SP_STATUS_REG
// fprintf(stderr, "READING STATUS REG!\n");
+2
View File
@@ -28,6 +28,7 @@ set(RMG_CORE_SOURCES
m64p/Api.cpp
m64p/CoreApi.cpp
m64p/ConfigApi.cpp
m64p/DebugApi.cpp
m64p/PluginApi.cpp
CachedRomHeaderAndSettings.cpp
ConvertStringEncoding.cpp
@@ -50,6 +51,7 @@ set(RMG_CORE_SOURCES
Video.cpp
Error.cpp
Unzip.cpp
Debug.cpp
Core.cpp
Key.cpp
Rom.cpp
+8
View File
@@ -120,6 +120,14 @@ bool CoreInit(void)
return false;
}
ret = m64p::Debug.Hook(l_CoreLibHandle);
if (!ret)
{
error = m64p::Debug.GetLastError();
CoreSetError(error);
return false;
}
m64p_ret = m64p::Core.Startup(FRONTEND_API_VERSION, CoreGetUserConfigDirectory().string().c_str(), CoreGetSharedDataDirectory().string().c_str(), (void*)l_CoreContextString, CoreDebugCallback, nullptr, CoreStateCallback);
if (m64p_ret != M64ERR_SUCCESS)
{
+1
View File
@@ -29,6 +29,7 @@
#include "Error.hpp"
#include "Unzip.hpp"
#include "Video.hpp"
#include "Debug.hpp"
#include "Key.hpp"
#include "Rom.hpp"
#ifdef CORE_PLUGIN
+117
View File
@@ -0,0 +1,117 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "Debug.hpp"
#include "Error.hpp"
#include "Emulation.hpp"
#include "SaveState.hpp"
#include "m64p/Api.hpp"
#include <fstream>
//
// Local Variables
//
static CoreCompareMode l_CoreCompareMode;
static std::fstream l_RecordingFileStream;
//
// Internal Functions
//
#include <iostream>
static void core_compare_check(uint32_t op)
{
}
static void core_compare_sync(int length, void* value)
{
if (l_CoreCompareMode == CoreCompareMode::Replay)
{
l_RecordingFileStream.read((char*)value, length);
if (l_RecordingFileStream.gcount() != length)
{
CoreCompareStop();
}
}
else
{
l_RecordingFileStream.write((char*)value, length);
}
}
//
// Exported Functions
//
bool CoreCompareStart(CoreCompareMode mode)
{
std::string error;
m64p_error ret;
l_CoreCompareMode = mode;
if (l_CoreCompareMode == CoreCompareMode::Replay)
{
if (!CoreLoadSaveState("rmg_recording.state"))
{
return false;
}
}
else
{
if (!CoreSaveState("rmg_recording.state"))
{
return false;
}
}
ret = m64p::Debug.SetCoreCompare(core_compare_check, core_compare_sync);
if (ret != M64ERR_SUCCESS)
{
error = "CoreCompareInit: m64p::Debug.SetCoreCompare() Failed: ";
error += m64p::Core.ErrorMessage(ret);
CoreSetError(error);
return false;
}
if (l_CoreCompareMode == CoreCompareMode::Replay)
{
l_RecordingFileStream.open("rmg_recording", std::ios_base::binary | std::ios_base::in);
}
else
{
l_RecordingFileStream.open("rmg_recording", std::ios_base::binary | std::ios_base::out);
}
return true;
}
bool CoreCompareStop(void)
{
std::string error;
m64p_error ret;
ret = m64p::Debug.SetCoreCompare(nullptr, nullptr);
if (ret != M64ERR_SUCCESS)
{
error = "CoreCompareInit: m64p::Debug.SetCoreCompare() Failed: ";
error += m64p::Core.ErrorMessage(ret);
CoreSetError(error);
}
l_RecordingFileStream.close();
return ret == M64ERR_SUCCESS;
}
+23
View File
@@ -0,0 +1,23 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef CORE_DEBUG_HPP
#define CORE_DEBUG_HPP
enum class CoreCompareMode
{
Record = 0,
Replay = 1
};
bool CoreCompareStart(CoreCompareMode mode);
bool CoreCompareStop(void);
#endif // CORE_DEBUG_HPP
+1
View File
@@ -13,4 +13,5 @@ namespace m64p
{
m64p::CoreApi Core;
m64p::ConfigApi Config;
m64p::DebugApi Debug;
} // namespace m64p
+2
View File
@@ -11,12 +11,14 @@
#define M64P_API_HPP
#include "ConfigApi.hpp"
#include "DebugApi.hpp"
#include "CoreApi.hpp"
namespace m64p
{
extern m64p::CoreApi Core;
extern m64p::ConfigApi Config;
extern m64p::DebugApi Debug;
} // namespace m64p
#endif // M64P_API_HPP
+52
View File
@@ -0,0 +1,52 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "DebugApi.hpp"
#include "Macros.hpp"
using namespace m64p;
DebugApi::DebugApi(void)
{
this->Unhook();
}
DebugApi::~DebugApi(void)
{
}
bool DebugApi::Hook(m64p_dynlib_handle handle)
{
this->errorMessage = "DebugApi::Hook Failed: ";
HOOK_FUNC(handle, Debug, SetCoreCompare);
HOOK_FUNC(handle, Debug, GetCPUDataPtr);
this->hooked = true;
return true;
}
bool DebugApi::Unhook(void)
{
UNHOOK_FUNC(Debug, SetCoreCompare);
UNHOOK_FUNC(Debug, GetCPUDataPtr);
this->hooked = false;
return true;
}
bool DebugApi::IsHooked(void)
{
return this->hooked;
}
std::string DebugApi::GetLastError(void)
{
return this->errorMessage;
}
+43
View File
@@ -0,0 +1,43 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef M64P_DEBUGAPI_HPP
#define M64P_DEBUGAPI_HPP
#include "api/m64p_common.h"
#include "api/m64p_debugger.h"
#include <string>
namespace m64p
{
class DebugApi
{
public:
DebugApi();
~DebugApi();
bool Hook(m64p_dynlib_handle handle);
bool Unhook(void);
bool IsHooked(void);
std::string GetLastError(void);
ptr_DebugSetCoreCompare SetCoreCompare;
ptr_DebugGetCPUDataPtr GetCPUDataPtr;
private:
bool hooked = false;
std::string errorMessage;
m64p_dynlib_handle handle;
};
} // namespace m64p
#endif // M64P_DEBUGAPI_HPP
+38 -14
View File
@@ -1054,6 +1054,9 @@ void MainWindow::connectActionSignals(void)
connect(this->action_View_ClearRomCache, &QAction::triggered, this, &MainWindow::on_Action_View_ClearRomCache);
connect(this->action_View_Log, &QAction::triggered, this, &MainWindow::on_Action_View_Log);
connect(this->action_Debug_CompareRecord, &QAction::triggered, this, &MainWindow::on_action_Debug_CompareRecord);
connect(this->action_Debug_CompareReplay, &QAction::triggered, this, &MainWindow::on_action_Debug_CompareReplay);
connect(this->action_Help_Github, &QAction::triggered, this, &MainWindow::on_Action_Help_Github);
connect(this->action_Help_About, &QAction::triggered, this, &MainWindow::on_Action_Help_About);
connect(this->action_Help_Update, &QAction::triggered, this, &MainWindow::on_Action_Help_Update);
@@ -1781,6 +1784,39 @@ void MainWindow::on_Action_View_Log(void)
this->logDialog.show();
}
#include <iostream>
void MainWindow::on_action_Debug_CompareRecord(void)
{
static bool recording = false;
if (!recording)
{
if (!CoreCompareStart(CoreCompareMode::Record))
{
this->showErrorMessage("CoreCompareStart() Failed", QString::fromStdString(CoreGetError()));
}
}
else
{
if (!CoreCompareStop())
{
this->showErrorMessage("CoreCompareStop() Failed", QString::fromStdString(CoreGetError()));
}
}
// toggle
recording = !recording;
}
void MainWindow::on_action_Debug_CompareReplay(void)
{
if (!CoreCompareStart(CoreCompareMode::Replay))
{
this->showErrorMessage("CoreCompareStart() Failed", QString::fromStdString(CoreGetError()));
}
}
void MainWindow::on_Action_Help_Github(void)
{
QDesktopServices::openUrl(QUrl("https://github.com/Rosalie241/RMG"));
@@ -1801,24 +1837,12 @@ void MainWindow::on_Action_Help_Update(void)
void MainWindow::on_Action_Audio_IncreaseVolume(void)
{
if (!CoreIncreaseVolume())
{
// It's rather annoying to have an error message pop-up everytime
// you use the increase volume hotkey when the volume is already
// at 100%, so we'll disable the error message
//this->showErrorMessage("CoreIncreaseVolume() Failed", QString::fromStdString(CoreGetError()));
}
CoreIncreaseVolume();
}
void MainWindow::on_Action_Audio_DecreaseVolume(void)
{
if (!CoreDecreaseVolume())
{
// It's rather annoying to have an error message pop-up everytime
// you use the decrease volume hotkey when the volume is already
// at 0%, so we'll disable the error message
//this->showErrorMessage("CoreDecreaseVolume() Failed", QString::fromStdString(CoreGetError()));
}
CoreDecreaseVolume();
}
void MainWindow::on_Action_Audio_ToggleVolumeMute(void)
+3
View File
@@ -201,6 +201,9 @@ class MainWindow : public QMainWindow, private Ui::MainWindow
void on_Action_View_ClearRomCache(void);
void on_Action_View_Log(void);
void on_action_Debug_CompareRecord(void);
void on_action_Debug_CompareReplay(void);
void on_Action_Help_Github(void);
void on_Action_Help_About(void);
void on_Action_Help_Update(void);
+111 -122
View File
@@ -31,26 +31,24 @@
</property>
<widget class="QMenu" name="menuSystem">
<property name="title">
<string>System</string>
<string>S&amp;ystem</string>
</property>
<widget class="QMenu" name="menuReset">
<property name="title">
<string>Reset</string>
<string>&amp;Reset</string>
</property>
<property name="icon">
<iconset theme="restart-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="restart-line"/>
</property>
<addaction name="action_System_SoftReset"/>
<addaction name="action_System_HardReset"/>
</widget>
<widget class="QMenu" name="menuCurrent_Save_State">
<property name="title">
<string>Current Save State</string>
<string>&amp;Current Save State</string>
</property>
<property name="icon">
<iconset theme="save-3-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="save-3-line"/>
</property>
<addaction name="actionSlot_0"/>
<addaction name="actionSlot_1"/>
@@ -68,11 +66,10 @@
<bool>true</bool>
</property>
<property name="title">
<string>Speed Factor</string>
<string>Speed &amp;Factor</string>
</property>
<property name="icon">
<iconset theme="speed-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="speed-line"/>
</property>
<addaction name="actionSpeed25"/>
<addaction name="actionSpeed50"/>
@@ -113,7 +110,7 @@
</widget>
<widget class="QMenu" name="menuSettings">
<property name="title">
<string>Settings</string>
<string>Setti&amp;ngs</string>
</property>
<addaction name="action_Settings_Graphics"/>
<addaction name="action_Settings_Audio"/>
@@ -143,7 +140,7 @@
</widget>
<widget class="QMenu" name="menuHelp">
<property name="title">
<string>Help</string>
<string>He&amp;lp</string>
</property>
<addaction name="action_Help_Github"/>
<addaction name="separator"/>
@@ -151,9 +148,23 @@
<addaction name="separator"/>
<addaction name="action_Help_About"/>
</widget>
<widget class="QMenu" name="menuDebug">
<property name="title">
<string>&amp;Debug</string>
</property>
<widget class="QMenu" name="menuCore_Compare">
<property name="title">
<string>&amp;Core Compare</string>
</property>
<addaction name="action_Debug_CompareRecord"/>
<addaction name="action_Debug_CompareReplay"/>
</widget>
<addaction name="menuCore_Compare"/>
</widget>
<addaction name="menuSystem"/>
<addaction name="menuSettings"/>
<addaction name="menuView"/>
<addaction name="menuDebug"/>
<addaction name="menuHelp"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
@@ -190,47 +201,42 @@
</widget>
<action name="action_System_StartRom">
<property name="icon">
<iconset theme="file-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="file-line"/>
</property>
<property name="text">
<string>Start ROM</string>
<string>&amp;Start ROM</string>
</property>
</action>
<action name="action_System_OpenCombo">
<property name="icon">
<iconset theme="file-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="file-line"/>
</property>
<property name="text">
<string>Start Combo</string>
<string>Start Co&amp;mbo</string>
</property>
</action>
<action name="action_System_Shutdown">
<property name="icon">
<iconset theme="shut-down-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="shut-down-line"/>
</property>
<property name="text">
<string>Shutdown</string>
<string>S&amp;hutdown</string>
</property>
</action>
<action name="action_System_SoftReset">
<property name="icon">
<iconset theme="restart-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="restart-line"/>
</property>
<property name="text">
<string>Soft Reset</string>
<string>&amp;Soft Reset</string>
</property>
</action>
<action name="action_System_HardReset">
<property name="icon">
<iconset theme="restart-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="restart-line"/>
</property>
<property name="text">
<string>Hard Reset</string>
<string>&amp;Hard Reset</string>
</property>
</action>
<action name="action_System_Pause">
@@ -238,20 +244,18 @@
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="pause-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="pause-line"/>
</property>
<property name="text">
<string>Pause</string>
<string>&amp;Pause</string>
</property>
</action>
<action name="action_System_Screenshot">
<property name="icon">
<iconset theme="screenshot-2-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="screenshot-2-line"/>
</property>
<property name="text">
<string>Screenshot</string>
<string>Scree&amp;nshot</string>
</property>
</action>
<action name="action_System_LimitFPS">
@@ -259,26 +263,23 @@
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="speed-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="speed-line"/>
</property>
<property name="text">
<string>Limit FPS</string>
<string>&amp;Limit FPS</string>
</property>
</action>
<action name="action_System_SaveState">
<property name="icon">
<iconset theme="save-3-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="save-3-line"/>
</property>
<property name="text">
<string>Save State</string>
<string>Sa&amp;ve State</string>
</property>
</action>
<action name="action_System_SaveAs">
<property name="icon">
<iconset theme="save-3-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="save-3-line"/>
</property>
<property name="text">
<string>Save As...</string>
@@ -286,20 +287,18 @@
</action>
<action name="action_System_LoadState">
<property name="icon">
<iconset theme="folder-open-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="folder-open-line"/>
</property>
<property name="text">
<string>Load State</string>
<string>L&amp;oad State</string>
</property>
</action>
<action name="action_System_Load">
<property name="icon">
<iconset theme="folder-open-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="folder-open-line"/>
</property>
<property name="text">
<string>Load...</string>
<string>Loa&amp;d...</string>
</property>
</action>
<action name="actionSlot_0">
@@ -307,7 +306,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Slot 0</string>
<string>&amp;Slot 0</string>
</property>
</action>
<action name="actionSlot_1">
@@ -315,7 +314,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Slot 1</string>
<string>Slot &amp;1</string>
</property>
</action>
<action name="actionSlot_2">
@@ -323,7 +322,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Slot 2</string>
<string>Slot &amp;2</string>
</property>
</action>
<action name="actionSlot_3">
@@ -331,7 +330,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Slot 3</string>
<string>Slot &amp;3</string>
</property>
</action>
<action name="actionSlot_4">
@@ -339,7 +338,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Slot 4</string>
<string>Slot &amp;4</string>
</property>
</action>
<action name="actionSlot_5">
@@ -347,7 +346,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Slot 5</string>
<string>Slot &amp;5</string>
</property>
</action>
<action name="actionSlot_6">
@@ -355,7 +354,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Slot 6</string>
<string>Slot &amp;6</string>
</property>
</action>
<action name="actionSlot_7">
@@ -363,7 +362,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Slot 7</string>
<string>Slot &amp;7</string>
</property>
</action>
<action name="actionSlot_8">
@@ -371,7 +370,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Slot 8</string>
<string>Slot &amp;8</string>
</property>
</action>
<action name="actionSlot_9">
@@ -379,13 +378,12 @@
<bool>true</bool>
</property>
<property name="text">
<string>Slot 9</string>
<string>Slot &amp;9</string>
</property>
</action>
<action name="action_System_Cheats">
<property name="icon">
<iconset theme="code-box-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="code-box-line"/>
</property>
<property name="text">
<string>Cheats...</string>
@@ -393,92 +391,82 @@
</action>
<action name="action_System_GSButton">
<property name="icon">
<iconset theme="checkbox-blank-circle-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="checkbox-blank-circle-line"/>
</property>
<property name="text">
<string>GS Button</string>
<string>&amp;GS Button</string>
</property>
</action>
<action name="action_System_Exit">
<property name="icon">
<iconset theme="door-open-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="door-open-line"/>
</property>
<property name="text">
<string>Exit</string>
<string>&amp;Exit</string>
</property>
</action>
<action name="action_Settings_Graphics">
<property name="icon">
<iconset theme="brush-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="brush-line"/>
</property>
<property name="text">
<string>Graphics</string>
<string>&amp;Graphics</string>
</property>
</action>
<action name="action_Settings_Input">
<property name="icon">
<iconset theme="gamepad-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="gamepad-line"/>
</property>
<property name="text">
<string>Input</string>
<string>&amp;Input</string>
</property>
</action>
<action name="action_Settings_Rsp">
<property name="icon">
<iconset theme="settings-3-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="settings-3-line"/>
</property>
<property name="text">
<string>RSP</string>
<string>&amp;RSP</string>
</property>
</action>
<action name="action_Settings_Audio">
<property name="icon">
<iconset theme="volume-up-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="volume-up-line"/>
</property>
<property name="text">
<string>Audio</string>
<string>&amp;Audio</string>
</property>
</action>
<action name="action_Settings_Settings">
<property name="icon">
<iconset theme="settings-3-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="settings-3-line"/>
</property>
<property name="text">
<string>Settings</string>
<string>&amp;Settings</string>
</property>
</action>
<action name="action_View_Fullscreen">
<property name="icon">
<iconset theme="fullscreen-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="fullscreen-line"/>
</property>
<property name="text">
<string>Fullscreen</string>
<string>&amp;Fullscreen</string>
</property>
</action>
<action name="action_Help_Github">
<property name="icon">
<iconset theme="github-fill">
<normaloff>.</normaloff>.</iconset>
<iconset theme="github-fill"/>
</property>
<property name="text">
<string>Github Repository</string>
<string>&amp;Github Repository</string>
</property>
</action>
<action name="action_Help_About">
<property name="icon">
<iconset theme="information-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="information-line"/>
</property>
<property name="text">
<string>About RMG</string>
<string>&amp;About RMG</string>
</property>
</action>
<action name="action_View_Toolbar">
@@ -486,11 +474,10 @@
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="tools-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="tools-line"/>
</property>
<property name="text">
<string>Toolbar</string>
<string>&amp;Toolbar</string>
</property>
</action>
<action name="action_View_StatusBar">
@@ -498,56 +485,50 @@
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="information-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="information-line"/>
</property>
<property name="text">
<string>Status Bar</string>
<string>&amp;Status Bar</string>
</property>
</action>
<action name="action_View_GameList">
<property name="icon">
<iconset theme="list-check">
<normaloff>.</normaloff>.</iconset>
<iconset theme="list-check"/>
</property>
<property name="text">
<string>Game List</string>
<string>&amp;Game List</string>
</property>
</action>
<action name="action_View_GameGrid">
<property name="icon">
<iconset theme="function-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="function-line"/>
</property>
<property name="text">
<string>Game Grid</string>
<string>Ga&amp;me Grid</string>
</property>
</action>
<action name="action_View_RefreshRoms">
<property name="icon">
<iconset theme="refresh-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="refresh-line"/>
</property>
<property name="text">
<string>Refresh ROMs</string>
<string>&amp;Refresh ROMs</string>
</property>
</action>
<action name="action_View_Log">
<property name="icon">
<iconset theme="file-list-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="file-list-line"/>
</property>
<property name="text">
<string>Log</string>
<string>&amp;Log</string>
</property>
</action>
<action name="action_View_ClearRomCache">
<property name="icon">
<iconset theme="delete-bin-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="delete-bin-line"/>
</property>
<property name="text">
<string>Clear ROM Cache</string>
<string>&amp;Clear ROM Cache</string>
</property>
</action>
<action name="action_View_UniformSize">
@@ -555,11 +536,10 @@
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="function-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="function-line"/>
</property>
<property name="text">
<string>Uniform Size (Grid View)</string>
<string>&amp;Uniform Size (Grid View)</string>
</property>
</action>
<action name="actionSpeed25">
@@ -567,17 +547,17 @@
<bool>false</bool>
</property>
<property name="text">
<string>25%</string>
<string>&amp;25%</string>
</property>
</action>
<action name="actionSpeed50">
<property name="text">
<string>50%</string>
<string>&amp;50%</string>
</property>
</action>
<action name="actionSpeed100">
<property name="text">
<string>100%</string>
<string>&amp;100%</string>
</property>
</action>
<action name="actionSpeed125">
@@ -592,12 +572,12 @@
</action>
<action name="actionSpeed200">
<property name="text">
<string>200%</string>
<string>2&amp;00%</string>
</property>
</action>
<action name="actionSpeed75">
<property name="text">
<string>75%</string>
<string>&amp;75%</string>
</property>
</action>
<action name="actionSpeed175">
@@ -622,16 +602,25 @@
</action>
<action name="actionSpeed300">
<property name="text">
<string>300%</string>
<string>&amp;300%</string>
</property>
</action>
<action name="action_Help_Update">
<property name="icon">
<iconset theme="download-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="download-line"/>
</property>
<property name="text">
<string>Check For Updates</string>
<string>&amp;Check For Updates</string>
</property>
</action>
<action name="action_Debug_CompareRecord">
<property name="text">
<string>&amp;Record</string>
</property>
</action>
<action name="action_Debug_CompareReplay">
<property name="text">
<string>R&amp;eplay</string>
</property>
</action>
</widget>