Compare commits

...

131 Commits

Author SHA1 Message Date
Rosalie Wanders 32a39afc75 Package: v0.2.9 2023-01-03 19:09:35 +01:00
Rosalie Wanders fd967cc2a3 RMG: correct commonInterfaceStyleSettings() in SettingsDialog 2023-01-03 18:39:51 +01:00
Rosalie Wanders 8c0bb09667 RMG: improve behavior of Hotkeys tab in SettingsDialog 2023-01-03 18:28:38 +01:00
Rosalie Wanders 8c753d6cfe RMG: add 'Current Save State' tab to Hotkeys tab in SettingsDialog 2023-01-03 18:02:40 +01:00
Rosalie Wanders 276e681f29 RMG-Core: add save state slot keybinding settings 2023-01-03 18:00:48 +01:00
Rosalie Wanders f23b17e1b8 RMG: "Choose ROM Directory" -> "Change ROM Directory" 2023-01-03 17:39:47 +01:00
Rosalie Wanders f1e10fa4b1 RMG: add icon for 'Current Save State' & 'GS Button' 2023-01-03 17:39:20 +01:00
Rosalie Wanders be67cd03cb RMG-Core: correct CORE_INSTALL_PREFIX name 2023-01-03 16:37:42 +01:00
Rosalie Wanders d7dfe12fb4 RMG: don't use setCurrentIndex() in MainWindow.cpp 2023-01-03 16:25:53 +01:00
Rosalie Wanders be437afd2f RMG: save geomtry in closeEvent() when emulation isn't running 2023-01-03 16:10:26 +01:00
Rosalie Wanders f72688773a RMG: don't switch back to ROM browser in closeEvent() 2023-01-03 15:07:44 +01:00
Rosalie Wanders fb328d8d92 RMG: install qt message handler 2023-01-03 14:40:51 +01:00
Rosalie Wanders 36e6d2fcc7 RMG: add -q/--quit-after-emulation commandline option 2023-01-03 13:57:08 +01:00
Rosalie Wanders 7b3293341b RMG: check visibility of OGLWidget in VidExt_OglSetup() 2023-01-03 13:50:57 +01:00
Rosalie Wanders 0a7b72a51b RMG: only set current directory in when PORTABLE_INSTALL is defined 2023-01-03 13:10:19 +01:00
Rosalie Wanders 6265973cc6 RMG-Core: use std::filesystem::path in osal_dynlib functions 2023-01-03 13:06:48 +01:00
Rosalie Wanders f1edc47a80 RMG-Core: correct osal_files_get_file_time for Windows 2023-01-03 12:53:06 +01:00
Rosalie Wanders 8f60d5c80f RMG-Core: only free buffer when opening a cartridge 2023-01-02 12:54:19 +01:00
Rosalie Wanders c42489fa81 RMG: correct 64DD disk file extension in RomBrowserEmptyWidget 2023-01-02 00:07:39 +01:00
Rosalie Wanders 66b60c988a RMG: update copyright year in AboutDialog 2023-01-02 00:04:22 +01:00
Rosalie Wanders 5d20e98aba Package: v0.2.8 2023-01-01 13:55:11 +01:00
Rosalie Wanders 617ee3f96c RMG: only call on_VidExt_ResizeWindow when not returning from fullscreen 2023-01-01 13:36:48 +01:00
Rosalie Wanders 083f7c2e4f RMG: simplify vidext function implementation 2023-01-01 13:14:07 +01:00
Rosalie Wanders a8ea1795bf Script: simplify BundleDependencies.sh 2023-01-01 12:43:49 +01:00
Rosalie Wanders 8a6cb4b5a8 RMG: configure toolbar & statusbar visibility in configureUI 2022-12-31 14:17:52 +01:00
Rosalie Wanders 53edf065a5 RMG: don't return when over the item limit in RomSearcherThread 2022-12-31 14:17:52 +01:00
Rosalie Wanders bf65be483d RMG: set current view widget in RomBrowserWidget constructor 2022-12-31 13:22:02 +01:00
Rosalie Wanders 1e90047368 3rdParty: use CMAKE_CONFIGURE_ARGS for mupen64plus-rsp-parallel 2022-12-30 14:24:07 +01:00
Rosalie Wanders abd1160f87 RMG: disable 'Uniform Size (Grid View)' during emulation 2022-12-29 01:34:49 +01:00
Rosalie Wanders 55d7dd9d89 RMG-Core: improve error message in read_raw_file 2022-12-29 01:18:58 +01:00
Rosalie Wanders b7eb1afb86 Package: v0.2.7 2022-12-29 00:28:43 +01:00
Rosalie Wanders 25ddb4a531 RMG: only refresh ROM list in SetGridViewUniformSizes when in grid view 2022-12-29 00:17:44 +01:00
Rosalie Wanders 79f7c2224b RMG: enable smooth scrolling in RomBrowserWidget 2022-12-29 00:14:58 +01:00
Rosalie Wanders 8adda4fc7d RMG: add more icons to the View menu 2022-12-29 00:14:38 +01:00
Rosalie Wanders 5d23743133 RMG: add 'Uniform Size (Grid View)' to View menu 2022-12-29 00:14:03 +01:00
Rosalie Wanders 2558e5d6a6 RMG-Core: add RomBrowser_GridViewUniformItemSizes setting 2022-12-29 00:08:49 +01:00
Rosalie Wanders 859b81b7e0 RMG: fixup cover filename in RomBrowserWidget 2022-12-28 23:09:46 +01:00
Rosalie Wanders 30369f58a9 3rdParty: update mupen64plus-core 2022-12-28 17:47:04 +01:00
Rosalie Wanders 30afc80a64 3rdParty: update mupen64plus-core 2022-12-28 17:23:32 +01:00
Rosalie Wanders 949eee8d08 RMG: improve updater script on windows 2022-12-28 16:34:40 +01:00
Rosalie Wanders 1fae30bd33 Script: also bundle libjpeg-8.dll for windows in BundleDependencies.sh 2022-12-28 16:18:59 +01:00
Rosalie Wanders d8817bf0f3 RMG: add disk files to RomBrowserEmptyWidget 2022-12-28 01:00:31 +01:00
Rosalie Wanders 5279b10b67 RMG: show core error even when statusbar is disabled 2022-12-28 00:36:21 +01:00
Rosalie Wanders 391f46be22 Package: update screenshots 2022-12-28 00:16:21 +01:00
Rosalie Wanders 44809bf28f Package: v0.2.6 2022-12-28 00:12:09 +01:00
Rosalie Wanders 3cd113c46f RMG: show context menu even when not having a selection 2022-12-28 00:10:56 +01:00
Rosalie Wanders 3d195c6a4d RMG: overhaul UI 2022-12-27 23:54:54 +01:00
Rosalie Wanders 423d30ac29 RMG-Core: introduce CoreClearRomHeaderAndSettingsCache() 2022-12-27 23:26:42 +01:00
Rosalie Wanders b07b73e005 RMG-Core: implement support for M64CMD_DISK_OPEN & M64CMD_DISK_CLOSE 2022-12-27 23:26:40 +01:00
Rosalie Wanders 418d9c4684 3rdParty: update mupen64plus-core 2022-12-27 23:26:38 +01:00
Rosalie Wanders 1801a48eaa 3rdParty: update GLideN64 2022-12-27 23:26:36 +01:00
Rosalie Wanders 8e8fbcdd2e Package: update archlinux PKGBUILD 2022-12-27 23:26:19 +01:00
Rosalie Wanders d5834de5e7 RMG-Input: disable Input_RemoveDuplicateMappings on linux 2022-12-27 23:25:53 +01:00
Rosalie Wanders a52e3fe1e5 RMG-Core: add more GUI settings 2022-12-19 21:07:45 +01:00
Rosalie Wanders eb261bc2bf RMG-Core: fix default save state/game directory being wrong 2022-12-19 21:07:45 +01:00
Rosalie Wanders 7b5f735714 RMG-Core: move over cheat settings in CoreUpdateCheat() 2022-12-19 13:27:10 +01:00
Rosalie Wanders 404c2c4f43 RMG: return M64ERR_UNSUPPORTED in VidExt_List{Modes,Rates} 2022-12-19 13:27:07 +01:00
Rosalie Wanders 57f1a33e51 3rdParty: update GLideN64 2022-12-19 13:27:05 +01:00
Rosalie Wanders fa277352b0 3rdParty: update angrylion-rdp-plus 2022-12-19 13:27:02 +01:00
Rosalie Wanders f502984e05 3rdParty: use $(MAKE) instead of make 2022-12-19 13:26:56 +01:00
Rosalie Wanders c205b5bfd3 3rdParty: update mupen64plus-video-parallel 2022-12-15 18:35:38 +01:00
Rosalie Wanders c6625e137d Package: v0.2.5 2022-12-14 20:46:09 +01:00
Rosalie Wanders 0ad7e1d715 Package: update & add screenshots 2022-12-14 20:38:45 +01:00
Rosalie Wanders 1f8d5be9a7 Package: update ArchLinux PKGBUILD 2022-12-14 20:30:12 +01:00
Rosalie Wanders 21673affbb RMG-Core: include Config.hpp in Directories.cpp 2022-12-14 20:28:11 +01:00
Rosalie Wanders a0a1255ef3 3rdParty: update mupen64plus-video-parallel 2022-12-14 20:16:26 +01:00
Rosalie Wanders 206a5ec7f6 3rdParty: update mupen64plus-video-angrylion-plus 2022-12-14 20:16:18 +01:00
Rosalie Wanders 8661273568 Script: update DownloadStyles.sh 2022-12-14 19:49:16 +01:00
Rosalie Wanders 6aed340831 RMG: call CoreGetVersion() in main.cpp 2022-12-14 19:13:38 +01:00
Rosalie Wanders f7bfb6aea1 RMG: remove Config.hpp include from main.cpp 2022-12-14 19:10:22 +01:00
Rosalie Wanders c5ae117cf8 RMG: remove Config.hpp include in RomBrowserWidget 2022-12-14 18:56:26 +01:00
Rosalie Wanders a1c9dc3f12 RMG: slightly redesign RomInfoDialog 2022-12-14 18:54:59 +01:00
Rosalie Wanders 0f3e70706d RMG-Input: allow removing/resetting the main profile 2022-12-14 18:50:55 +01:00
Rosalie Wanders 722ca67b87 RMG-Input: enable close button on all dialogs 2022-12-14 18:41:34 +01:00
Rosalie Wanders 981897df8c RMG-Audio: enable close button on all dialogs 2022-12-14 18:41:28 +01:00
Rosalie Wanders 3a066dfc03 RMG: enable close button on all dialogs 2022-12-14 18:41:06 +01:00
Rosalie Wanders 870481e34e Data: remove stylesheet.qss 2022-12-14 18:27:23 +01:00
Rosalie Wanders 9f5f2334d7 RMG: remove Config.hpp & use CoreGetVersion() 2022-12-14 18:26:30 +01:00
Rosalie Wanders 330a66c81c RMG-Core: introduce & use CoreGetVersion() 2022-12-14 18:26:01 +01:00
Rosalie Wanders 92b4d4dc32 RMG: remove 'About' button in plugins tab in SettingsDialog 2022-12-14 18:15:31 +01:00
Rosalie Wanders 531fab51be RMG: add correct info layouts to User Interface tab in SettingsDialog 2022-12-14 00:21:14 +01:00
Rosalie Wanders 3f027fad63 RMG-Input: force call on_controllerPluggedCheckBox_toggled() 2022-12-14 00:13:35 +01:00
Rosalie Wanders 6eb46dd63c RMG: also load misc settings tab in SettingsDialog 2022-12-13 23:53:58 +01:00
Rosalie Wanders 70830ae016 RMG-Input: do nothing in CheckInputDeviceSettings() when combobox is empty 2022-12-13 23:31:56 +01:00
Rosalie Wanders 8a88a736ad RMG-Input: actually add required svg resource 2022-12-13 23:02:39 +01:00
Rosalie Wanders d580d2be9a RMG-Input: add Z-Trigger to the svg & hook it up to ControllerImageWidget 2022-12-13 22:53:03 +01:00
Rosalie Wanders 0e3fc0e981 RMG: fix empty style setting 2022-12-13 21:57:47 +01:00
Rosalie Wanders 4907b2dd32 RMG: use fallback stylesheet 2022-12-13 21:57:44 +01:00
Rosalie Wanders 3ad2a5760e RMG: make ui_Stylesheet_Setup windows exclusive 2022-12-13 21:42:53 +01:00
Rosalie Wanders e474a09642 ci: execute DownloadStyles.sh on windows 2022-12-13 21:38:07 +01:00
Rosalie Wanders f5296c9f79 RMG: add style setting to SettingsDialog 2022-12-13 21:37:52 +01:00
Rosalie Wanders f8e1ed3920 RMG-Core: add GUI_Style setting 2022-12-13 21:33:01 +01:00
Rosalie Wanders 9aeca88946 Script: add DownloadStyles.sh 2022-12-13 21:32:43 +01:00
Rosalie Wanders 3961c066be ci: specify key for ccache-action 2022-12-13 16:11:32 +01:00
Rosalie Wanders 4aeb3da6eb cmake: respect C/C++ compiler in 3rdParty projects 2022-12-13 15:40:50 +01:00
Rosalie Wanders bf9e370ddd ci: use ccache 2022-12-13 15:26:29 +01:00
Rosalie Wanders 7c72fa98fd cmake: add USE_CCACHE option 2022-12-13 15:25:25 +01:00
Rosalie Wanders 0824586db9 RMG: remove Debugger checkbox from SettingsDialog 2022-12-13 14:51:56 +01:00
Rosalie Wanders 8a22c6d929 RMG: rename Interface tab to User Interface in SettingsDialog 2022-12-13 14:50:58 +01:00
Rosalie Wanders 8f76619d7d cmake: add USE_QT5 option 2022-12-13 13:48:15 +01:00
Rosalie Wanders d94d9fc5d7 3rdParty: update GLideN64 2022-12-12 21:58:27 +01:00
Rosalie Wanders 38312f8add Script: use windeployqt-qt6 in BundleDependencies.sh 2022-12-12 21:58:27 +01:00
Rosalie Wanders d52b1e1b5a RMG: don't link to sdl 2022-12-12 21:58:27 +01:00
Rosalie Wanders 06c9d9b826 3rdParty: update parallel-rdp-standalone 2022-12-12 21:58:27 +01:00
Rosalie Wanders 20a669dbbb 3rdParty: update angrylion-rdp-plus 2022-12-12 21:58:27 +01:00
Rosalie Wanders 68c8c431a2 3rdParty: update GLideN64 2022-12-12 21:58:27 +01:00
Rosalie Wanders d6b1fdfa7b ci: use Qt6 packages 2022-12-12 21:58:27 +01:00
Rosalie Wanders 6ac9208c7f RMG-Input: use Qt6 2022-12-12 21:58:27 +01:00
Rosalie Wanders fdcfaf3fad RMG-Audio: use Qt6 2022-12-12 21:58:27 +01:00
Rosalie Wanders dd08dfafc8 RMG: use Qt6 2022-12-12 21:58:27 +01:00
Rosalie Wanders 22a019abb1 RMG: remove unused included header 2022-12-12 21:58:27 +01:00
Rosalie Wanders e112ae75eb RMG-Input: prepare for Qt6 2022-12-11 22:35:18 +01:00
Rosalie Wanders 0de1073094 RMG: prepare for Qt6 2022-12-11 22:35:06 +01:00
Rosalie Wanders 18a1a6afe6 RMG-Input: fix 'full match' not being correct in ControllerWidget 2022-12-10 22:17:16 +01:00
Rosalie Wanders 149bd86a89 Package: v0.2.4 2022-12-08 15:41:11 +01:00
Rosalie Wanders dbe67853dc RMG-Core: disable Audio_Synchronize by default 2022-12-08 15:23:21 +01:00
Rosalie Wanders 4f30be19b1 3rdParty: update GLideN64 2022-12-08 15:08:47 +01:00
Rosalie Wanders 0347033d89 3rdParty: update mupen64plus-core 2022-12-08 15:08:22 +01:00
Rosalie Wanders 5fc36d5743 RMG: fix InstallUpdateDialog not showing 2022-12-08 15:07:45 +01:00
Rosalie Wanders c745ec18bb cheats: add more cheats from Gent 2022-12-08 14:57:49 +01:00
Rosalie Wanders 0e84317fbc RMG-Core: use dynamic size in CachedRomHeaderAndSettings.cpp 2022-12-08 13:43:03 +01:00
Rosalie Wanders b7df075dec RMG-Core: introduce & use ConvertStringEncoding 2022-12-08 13:42:53 +01:00
Rosalie Wanders da3e30f735 RMG: don't re-initialize Discord Rpc in settings dialog
after CoreDiscordRpcShutdown(), CoreDiscordRpcInit() seems to do nothing.
2022-12-05 22:17:57 +01:00
Rosalie Wanders 9bd0ea0ba6 RMG-Core: properly depend on discord-rpc 2022-12-05 18:43:54 +01:00
Rosalie Wanders 91df63c660 Package: v0.2.3 2022-12-05 17:21:54 +01:00
Rosalie Wanders bea8abd60d 3rdParty: update mupen64plus-core & GLideN64 2022-12-05 17:20:49 +01:00
Rosalie Wanders 86bb226db4 3rdParty: correct discord-rpc BUILD_BYPRODUCTS 2022-12-05 16:40:00 +01:00
Rosalie Wanders 5bbdc7f821 RMG: add check for updates & discord rpc to settings dialog 2022-12-05 16:21:18 +01:00
Rosalie Wanders f23b0ca493 RMG-Core: implement & use DiscordRpc functions 2022-12-05 16:20:35 +01:00
Rosalie Wanders 538b503bcb 3rdParty: add discord-rpc 2022-12-05 16:19:13 +01:00
Rosalie Wanders cabc56550b RMG: introduce an updater 2022-12-04 20:43:33 +01:00
179 changed files with 9712 additions and 2106 deletions
+12 -2
View File
@@ -9,11 +9,14 @@ jobs:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: hendrikmuhs/ccache-action@v1.2.5
with:
key: Linux
- name: Install Packages
run: |
sudo apt-get -qq update
sudo apt-get upgrade
sudo apt-get -y install cmake libhidapi-dev libsamplerate0-dev libspeex-dev libminizip-dev libsdl2-dev libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev pkg-config zlib1g-dev binutils-dev libspeexdsp-dev qtbase5-dev libqt5svg5-dev build-essential nasm git zip
sudo apt-get -y install cmake libhidapi-dev libsamplerate0-dev libspeex-dev libminizip-dev libsdl2-dev libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev pkg-config zlib1g-dev binutils-dev libspeexdsp-dev qt6-base-dev libqt6svg6-dev build-essential nasm git zip
- name: Prepare Environment
run: |
echo "GIT_REVISION=$(git describe --tags --always)" >> $GITHUB_ENV
@@ -32,6 +35,9 @@ jobs:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: hendrikmuhs/ccache-action@v1.2.5
with:
key: Windows
- uses: msys2/setup-msys2@v2
with:
path-type: inherit
@@ -45,7 +51,7 @@ jobs:
mingw-w64-x86_64-libpng
mingw-w64-x86_64-SDL2
mingw-w64-x86_64-jasper
mingw-w64-x86_64-qt5
mingw-w64-x86_64-qt6
mingw-w64-x86_64-SDL2
mingw-w64-x86_64-hidapi
mingw-w64-x86_64-speexdsp
@@ -53,6 +59,7 @@ jobs:
mingw-w64-x86_64-python3-pip
mingw-w64-x86_64-python3-pyopenssl
mingw-w64-x86_64-nasm
mingw-w64-x86_64-minizip
git
- name: Prepare Environment
run: |
@@ -62,6 +69,9 @@ jobs:
- name: Build RMG (Portable)
run: ./Source/Script/Build.sh Release
shell: msys2 {0}
- name: Download Styles
run: ./Source/Script/DownloadStyles.sh
shell: msys2 {0}
- name: Create Installer
run: .\Build\Release\Source\Installer\CreateInstaller.bat
- name: Upload RMG (Portable)
+29 -2
View File
@@ -5,6 +5,10 @@ cmake_minimum_required(VERSION 3.15)
option(PORTABLE_INSTALL "Portable Installation" ON)
option(NO_GIT_CLONE "Disables git clone usage for 3rdParty dependencies" OFF)
option(UPDATER "Enables updater" ${PORTABLE_INSTALL})
option(DISCORD_RPC "Enables Discord Rich Presence" ON)
option(USE_QT5 "Enables Qt5 instead of Qt6 (will be removed in the future)" OFF)
option(USE_CCACHE "Enables usage of ccache when ccache has been found" ON)
project(RMG)
@@ -17,11 +21,25 @@ execute_process(
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if (USE_CCACHE)
find_program(CCACHE_FOUND ccache)
if (CCACHE_FOUND)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
else(CCACHE_FOUND)
set(USE_CCACHE OFF)
endif(CCACHE_FOUND)
endif(USE_CCACHE)
if (NOT PORTABLE_INSTALL AND (WIN32 OR MSYS))
message(WARNING "Not-Portable build not supported on windows, re-enabling PORTABLE_INSTALL!")
set(PORTABLE_INSTALL ON)
endif()
if (NOT PORTABLE_INSTALL AND UPDATER)
message(WARNING "Not-Portable builds don't support the updater, disabling UPDATER")
set(UPDATER OFF)
endif()
if (PORTABLE_INSTALL)
set(CMAKE_INSTALL_PREFIX "")
set(INSTALL_PATH "Bin/${CMAKE_BUILD_TYPE}")
@@ -41,6 +59,16 @@ else()
set(ICON_INSTALL_PATH "share/icons/hicolor/scalable/apps/")
endif()
if (USE_QT5)
set(QT_VERSION "Qt5")
set(USE_QT6 OFF)
else(USE_QT5)
set(QT_VERSION "Qt6")
set(USE_QT6 ON)
endif(USE_QT5)
add_subdirectory(Source/3rdParty)
add_subdirectory(Source/RMG-Core)
add_subdirectory(Source/RMG)
add_subdirectory(Source/RMG-Audio)
@@ -63,11 +91,10 @@ if (WIN32)
)
endif()
add_subdirectory(Source/3rdParty)
install(FILES ${MUPEN64PLUSCORE_LIB}
DESTINATION ${CORE_INSTALL_PATH}
)
install(FILES ${MUPEN64PLUSCORE_INI} Data/font.ttf Data/stylesheet.qss
install(FILES ${MUPEN64PLUSCORE_INI} Data/font.ttf
DESTINATION ${DATA_INSTALL_PATH}
)
file(GLOB GENERATED_CHEAT_FILES ${CMAKE_SOURCE_DIR}/Data/Cheats/Generated/*.cht)
@@ -0,0 +1,56 @@
[0CA6AEDA-BB9CFDD9-C:45]
Name=Carnivale - Cenzo's Adventure (USA) (Prototype)
$Infinite Max Silver & Gold Coins
Note=This seems to act as Health?
810A2E7E 001E
810A2E80 001E
810A2E82 001E
$Infinite Max Peas
Note=Max Pea Shooter Ammo
810A2E7A 001E
$Unlock Everything
Note=This Unlocks All Items in Single & All Multi Player Characters and Tracks.(Thanks Retroben!)
810A2E90 0003
810A2E92 87F9
810A2E94 87F9
$Press L for Warp Select (Single Mode)
Note=Press the L-Button as you go through a door (Thanks SubDrag!)
D00A3359 0020
800CA85B 00??
01 Blue Background Race
02 Dark Mountains Race
03 Purple/Yellow Mountains Race
04 Cloud Floor Race (from the locked main area)
05 Main Area
06 Maze
07 King Race Super Rat Ride
08 Mallet Game
09 Duck Game
0A Puppet Show (Come back later)
0B Rock Paper Scissors Game
0C Create Password
0D Main Menu
0E Select New Game
0F Boss Intro Guy with hammer
10 Options Menu
11 Boss Intro Meet Strongman
12 Main Menu
$Max Strength in Mallet Game
811B08A6 0162
$Perfect Aim In Mallet Game (Line up and Shoot)
Note=Use with Max Strength in Mallet Game. Wait until the Eyeball is past the 2 Red Lines (centre) and then press A
811B0BD4 FFF2
811B0B28 FDD2
811605C8 FDD2
81153148 FDD2
$1 Lap to Race (All Characters & Races)
Note=For Single and Multi Player Modes. This will display 1 of 3, but on the first checkpoint you will get the message "You win" 1 Lap to race will also make you come in 1st and win. a big thanks to Parasyte for working with me on this! You are "Magic" lol
81060020 2400
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,33 @@
[7BD65F9E-76B6A083-C:45]
Name=007 - The World is Not Enough (U) (Prototype - 2020 release)
$Enable Cheats Menu
800811F0 0005
$Invincible
80130ACD 00??
01 On
00 Off
$All Weapons
80130AE0 00??
01 On
00 Off
$All Gadgets
80130AE1 00??
01 On
00 Off
$All Missions
80130AE2 00??
01 On
00 Off
$Infinite Health (All Levels)
81045D68 2400
$Infinite Ammo (All Guns for all Levels)
Note=The Clip will count down but you will never run out of Ammo.
81040730 2400
@@ -0,0 +1,36 @@
[8825E18B-3297746B-C:50]
Name=Aidyn Chronicles - The First Mage (Europe) (Prototype) (2)
$Infinite\Max Health
80279308 001E
$Infinite\99 Health Potions
Note=Do Not put this cheat on until you have collected your 1st Health Potion from the 1st Cheat or you will not be able to get into the Sub menu and Continue the game.
80278D3B 0063
$Have\Max Gold
50000401 0000
80277AA5 00FF
$Have\Max Total XP
50000401 0000
8027931D 00FF
$Have\Max Total XP Remaning to Start
Note=This will give you 16777215 Total XP Remaning to start with and after your 1st batle will allow you to buy your Max Stats
50000401 0000
80279321 00FF
$Play As Character
Note=Enable this at the start of a Game, before a next Level, or before a Cutscene to become your chosen option.
810E108E ????
25F9 Alaron
2A43 Marari Female
2C17 Spirit
2CC0 Marari Male
2D4A GiantBat
2E82 Chaos Trooper
3094 Gryphon
324D Ogre
32CC GiantRat
@@ -0,0 +1,36 @@
[8EAA1A2C-61C09930-C:00]
Name=Aidyn Chronicles - The First Mage (USA) (Prototype)
$Infinite\Max Health
80275AA1 001E
$Infinite\99 Health Potions
Note=Do Not put this cheat on until you have collected your 1st Health Potion from the 1st Cheat or you will not be able to get into the Sub menu and Continue the game.
8027540F 0063
$Have\Max Gold
50000401 0000
8027423E 00FF
$Have\Max Total XP
50000401 0000
80275AB6 00FF
$Have\Max Total XP Remaning to Start
Note=This will give you 16777215 Total XP Remaning to start with and after your 1st batle will allow you to buy your Max Stats
50000401 0000
80275ABA 00FF
$Play As Character
Note=Enable this at the start of a Game, before a next Level, or before a Cutscene to become your chosen option.
810E0D6E ????
25F9 Alaron
2A43 Marari Female
2C17 Spirit
2CC0 Marari Male
2D4A GiantBat
2E82 Chaos Trooper
3094 Gryphon
324D Ogre
32CC GiantRat
@@ -0,0 +1,29 @@
[A92E0966-341C3912-C:45]
Name=007 - The World is Not Enough (U) (Beta) [!]
$Invincible
8011E157 00??
01 On
00 Off
$Have All Gadgets
8011E159 00??
01 On
00 Off
$Enable All Missions
8011E15A 00??
01 On
00 Off
$Have All Weapons
8011E158 00??
01 On
00 Off
$Infinite Health (All Levels)
8106AC88 2400
$Infinite Ammo (All Guns for all Levels)
8106246C 2400
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,36 @@
[D0E29F11-E029063F-C:50]
Name=Aidyn Chronicles - The First Mage (Europe) (Prototype) (1)
$Infinite\Max Health
80279208 001E
$Infinite\99 Health Potions
Note=Do Not put this cheat on until you have collected your 1st Health Potion from the 1st Cheat or you will not be able to get into the Sub menu and Continue the game.
80278C3B 0063
$Have\Max Gold
50000401 0000
802779A5 00FF
$Have\Max Total XP
50000401 0000
8027921D 00FF
$Have\Max Total XP Remaning to Start
Note=This will give you 16777215 Total XP Remaning to start with and after your 1st batle will allow you to buy your Max Stats
50000401 0000
80279221 00FF
$Play As Character
Note=Enable this at the start of a Game, before a next Level, or before a Cutscene to become your chosen option.
810E0F9E ????
25F9 Alaron
2A43 Marari Female
2C17 Spirit
2CC0 Marari Male
2D4A GiantBat
2E82 Chaos Trooper
3094 Gryphon
324D Ogre
32CC GiantRat
@@ -0,0 +1,74 @@
[E48E01F5-E6E51F9B-C:59]
Name=Carmageddon 64 (E) (M4) (Eng-Spa-Fre-Ita) [!]
$Have Everything Unlocked
Note=This will unlock Cars, Races, Missions and the in-built Cheat Menu. This will also replace all the Zombies with Dinosaurs. To access Cheat menu options: Pause Game: Use Control Stick, to scroll the Cheat Menu. Press A, to activate Cheats
801BE43D 000F
$Have Infinite\Invunerability
81097EAC ????
0BBB On
0000 Off
$Have Infinite\Free Repairs
81097EC4 ????
0BBB On
0000 Off
$Have Infinite\Underwater Ability
81097EF4 ????
0BBB On
0000 Off
$Have Infinite\Turbo
81097E34 ????
0BBB On
0000 Off
$Have Infinite\Mega Turbo
81097E4C ????
0BBB On
0000 Off
$Have Infinite\Hot Rod
81097E64 ????
0BBB On
0000 Off
$Have Infinite\Turbo Nitrous
81097E7C ????
0BBB On
0000 Off
$Have Infinite\Frozen Opponents
81097F24 ????
0BBB On
0000 Off
$Have Infinite\Grip-O-Matic Tires
8109805C ????
0BBB On
0000 Off
$Have Infinite\Mine Dropping Ability
81098118 ????
0064 On
0000 Off
$Freeze Timer at 04:59
Note=Do not enable until count down to race is finished
811BE21E 3A70
$Max Credits
Note=This is also Infinite until disabled
811BE29A FFFF
$Max Kills
Note=This will automatically Clear the stage if enabled and go back to the stage menu
81094BEE 01F4
$Have All Groups Completed
Note=This gives you all Cups for all Groups.
50002801 0000
801BE35C 0002
@@ -0,0 +1,74 @@
[F1642508-BEE60CF6-C:45]
Name=Bust-A-Move 3 DX (USA) (Prototype)
$Always Have\guide line on
800558CC 0082
$Pointer always active
D0055BA0 0002
80055BA0 0082
$Play As Select\Player 1
800E1E50 00??
00 Bubbloon
01 Twinkie
02 Prettio
03 Marina
04 Musashi
05 Luna
06 Jack
07 SSB
08 Dragoon
09 Gnome
10 Monkey
11 furby? (looks like 2 balloons)
12 Blue Gnome
13 1 of the two Ballons
14 Water under ballons
$Play As Select\Player 2
800E1E58 00??
00 Bubbloon
01 Twinkie
02 Prettio
03 Marina
04 Musashi
05 Luna
06 Jack
07 SSB
08 Dragoon
09 Gnome
10 Monkey
11 furby? (looks like 2 balloons)
12 Blue Gnome
13 1 of the two Ballons
14 Water under ballons
$Next Bubble Select\Player 1
800EBA19 00??
00 No Bubble
01 Red
02 Green
03 Blue
04 Yellow
05 Orange
06 Purple
07 White
08 Black
$Next Bubble Select\Player 2
800EBB09 00??
00 No Bubble
01 Red
02 Green
03 Blue
04 Yellow
05 Orange
06 Purple
07 White
08 Black
$Press GS Button to Reset Player 2 score to 0
8809C5C0 0000
8809C5C2 0000
@@ -0,0 +1,25 @@
[F7AA4F819F41CB4236792A8145684627]
Name=Yoshi's Story (CHN) (iQue)
$Infinite\Health
Note=This is for All Yoshis All levels
50000804 0000
8012FD1F 00??
08 Infinite Health
09 Infinite Max Health
$Infinite\Eggs (Once You Get One)
Note=This is for All Yoshis All levels
8103E52C 2400
$Infinite\Lives
Note=This is for All Yoshis All levels
8012FD5F 00FF
$Press GS Button To Have All Fruit
8812F93B 001E
$Enable All Levels (Trial Mode)
8112FDC4 FFFF
8112FDC6 FFFF
+2 -2
View File
@@ -11,8 +11,8 @@ license=('GPLv3')
provides=("$_pkgname")
conflicts=("$_pkgname")
depends=("hidapi" "libsamplerate" "minizip" "sdl2" "zlib" "freetype2" "qt5-base" "qt5-svg")
makedepends=("git" "pkg-config" "nasm" "cmake" "rustup")
depends=("hidapi" "libsamplerate" "minizip" "sdl2" "zlib" "freetype2" "qt6-base" "qt6-svg" "xdg-user-dirs")
makedepends=("git" "pkg-config" "nasm" "cmake" "cargo")
source=("git+https://github.com/Rosalie241/${_pkgname}.git")
sha256sums=('SKIP')
Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 KiB

After

Width:  |  Height:  |  Size: 445 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 47 KiB

@@ -18,13 +18,126 @@
<caption>During A Game</caption>
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/InGame.png</image>
</screenshot>
<screenshot type="default">
<caption>Cheats</caption>
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/Cheats.png</image>
</screenshot>
<screenshot type="default">
<caption>Settings</caption>
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/Settings.png</image>
</screenshot>
<screenshot type="default">
<caption>Input Settings</caption>
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/InputSettings.png</image>
</screenshot>
</screenshots>
<description/>
<releases>
<release version="v0.2.9" date="2023-01-03" type="stable">
<description>
<p>Changes:</p>
<ul>
<li>Fix wrong 64DD Disk extension being listed in empty ROM browser</li>
<li>Fix memory corruption when having 64DD Disk files</li>
<li>Fix possible crash when render window wasn't visible yet</li>
<li>Fix RMG changing the current directory on non-portable installs</li>
<li>Remove Qt warning messages (you can view them by setting RMG_SHOW_DEBUG_QT_MESSAGES to 1)</li>
<li>Change "Choose ROM Directory" to "Change ROM Directory"</li>
<li>Add -q/--quit-after-emulation commandline option</li>
<li>Add 2 more icons to menubar menus/items</li>
<li>Add "Current Save State" tab to Hotkeys tab in settings dialog (this allows you to use a hotkey to change save state slots)</li>
<li>Improve behavior of Hotkeys tab in settings dialog</li>
<li>Improve behavior of window when exiting RMG while in-game</li>
</ul>
</description>
</release>
<release version="v0.2.8" date="2023-01-01" type="stable">
<description>
<p>Changes:</p>
<ul>
<li>Fix 'Uniform Size (Grid View)' not being disabled during emulation</li>
<li>Fix toolbar not respecting the view setting</li>
<li>Fix being stuck at the loading screen when having more ROMs than the ROM search limit</li>
<li>Improve error message when opening a ROM fails</li>
</ul>
</description>
</release>
<release version="v0.2.7" date="2022-12-29" type="stable">
<description>
<p>Changes:</p>
<ul>
<li>Fix core error not showing when the statusbar was hidden</li>
<li>Fix .ndd/.64d not being in the empty ROM Browser widget</li>
<li>Fix .jpg/.jpeg files not working on covers on Windows</li>
<li>Fix updater script not copying subdirectories on Windows (for portable installs)</li>
<li>Fix 64DD Disks which required the development IPL not working</li>
<li>Fix 64DD Disks showing the wrong internal ROM name (this fix requires clearing the ROM cache)</li>
<li>Fix cover filenames allowing invalid characters (they will now be replaced by _)</li>
<li>Add more icons to View menu in the menu bar</li>
<li>Add 'Uniform Size (Grid View)' to View menu in the menu bar</li>
<li>Add smooth scrolling to List View and Grid View</li>
</ul>
</description>
</release>
<release version="v0.2.6" date="2022-12-28" type="stable">
<description>
<p>Changes:</p>
<ul>
<li>Fix default save state/game directory being incorrect on first run (on non-portable installs)</li>
<li>Fix angrylion-rdp-plus not loading settings correctly</li>
<li>Fix cheat settings not moving over when renaming a cheat</li>
<li>Remove fullscreen resolution combobox from GLideN64 because it did nothing</li>
<li>Remove File menu from menu bar</li>
<li>Implement disk support without requiring a cartridge</li>
<li>Add toolbar</li>
<li>Add View menu to menu bar</li>
<li>Add Grid view to ROM browser</li>
<li>Add icons to all menu bar items</li>
<li>Add log dialog</li>
</ul>
</description>
</release>
<release version="v0.2.5" date="2022-12-14" type="stable">
<description>
<p>Changes:</p>
<ul>
<li>Fix incorrect controller being selected in RMG-Input when having 2 controllers with the same name</li>
<li>Fix some UI elements being enabled while the 'Controller Is Plugged In' checkbox is disabled in RMG-Input</li>
<li>Fix extra padding being added when having a controller selected and opening RMG-Input</li>
<li>Fix creating a new profile in GLideN64</li>
<li>Add Z-Trigger visualization in RMG-Input</li>
<li>Remove Debugger checkbox in the settings dialog because it did nothing</li>
<li>Remove About buttons in the plugin tab of the settings dialog because it did nothing</li>
<li>Implement close button on all dialogs</li>
<li>Implement custom style support (for Windows only)</li>
<li>Implement the ability to remove/reset the main profile in RMG-Input</li>
<li>Rename Interface tab in settings dialog to User Interface</li>
<li>Migrate to Qt6 (currently the flatpak will remain Qt5)</li>
</ul>
</description>
</release>
<release version="v0.2.4" date="2022-12-08" type="stable">
<description>
<p>Changes:</p>
<ul>
<li>Fix Discord Rich Presence breaking when opening the settings dialog</li>
<li>Fix install update window not showing</li>
<li>Fix 'Limit FPS' not working with new RMG-Audio (this disables the 'synchronize audio' option)</li>
<li>Implement support for Japanese characters in the ROM header</li>
<li>Implement dynamic buffer sizes in the ROM browser cache (this reduces the ROM browser cache size)</li>
<li>Add more cheats from Gent</li>
</ul>
</description>
</release>
<release version="v0.2.3" date="2022-12-05" type="stable">
<description>
<p>Changes:</p>
<ul>
<li>Add updater for portable installations</li>
<li>Add Discord Rich Presence</li>
</ul>
</description>
</release>
<release version="v0.2.2" date="2022-12-03" type="stable">
<description>
<p>Changes:</p>
+54 -19
View File
@@ -8,9 +8,9 @@ set(THIRDPARTY_DIR ${CMAKE_BINARY_DIR}/Source/3rdParty)
find_program(RUST_CARGO cargo)
if(${RUST_CARGO} STREQUAL "RUST_CARGO-NOTFOUND")
message(WARNING "mupen64plus-input-gca will not be built due to not having cargo installed")
set(BUILD_INPUT_GCA "0")
set(BUILD_INPUT_GCA OFF)
else()
set(BUILD_INPUT_GCA "1")
set(BUILD_INPUT_GCA ON)
endif()
set(M64P_CORE_DIR ${THIRDPARTY_DIR}/mupen64plus-core)
@@ -24,9 +24,20 @@ else(WIN32)
set(CORE_FILE "libmupen64plus.so")
endif(WIN32)
set(BASE_CMAKE_CONFIGURE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER})
if (USE_CCACHE)
set(CMAKE_CONFIGURE_ARGS ${BASE_CMAKE_CONFIGURE_ARGS} -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache)
set(MAKE_CC_COMPILER "ccache ${CMAKE_C_COMPILER}")
set(MAKE_CXX_COMPILER "ccache ${CMAKE_CXX_COMPILER}")
else(USE_CCACHE)
set(CMAKE_CONFIGURE_ARGS ${BASE_CMAKE_CONFIGURE_ARGS})
set(MAKE_CC_COMPILER "${CMAKE_C_COMPILER}")
set(MAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER}")
endif(USE_CCACHE)
if(NOT NO_GIT_CLONE)
set(MUPEN64PLUSCORE_URL "https://github.com/mupen64plus/mupen64plus-core")
set(MUPEN64PLUSCORE_TAG "f63e1b35063241738d848f73311496b76c8aa918")
set(MUPEN64PLUSCORE_URL "https://github.com/Rosalie241/mupen64plus-core")
set(MUPEN64PLUSCORE_TAG "3b6523edd467eb9224310e0862005c7e5ae9c290")
set(MUPEN64PLUS_RSP_CXD4_URL "https://github.com/mupen64plus/mupen64plus-rsp-cxd4")
set(MUPEN64PLUS_RSP_CXD4_TAG "39f79201baa15890c4cbae92f2215a634cc3ee6d")
@@ -44,13 +55,16 @@ if(NOT NO_GIT_CLONE)
set(MUPEN64PLUS_INPUT_GCA_TAG "21639fb13dfa797a7c0949ffd9bbda9a3456fc69")
set(MUPEN64PLUS_GFX_ANGRYLION_URL "https://github.com/Rosalie241/angrylion-rdp-plus")
set(MUPEN64PLUS_GFX_ANGRYLION_TAG "9d71074f6b71750e99ad06a713f28a9c32ad15cb")
set(MUPEN64PLUS_GFX_ANGRYLION_TAG "158e74d4ec1c818289cd19c3a05e498c3ceff758")
set(MUPEN64PLUS_GFX_GLIDEN64_URL "https://github.com/gonetz/GLideN64")
set(MUPEN64PLUS_GFX_GLIDEN64_TAG "a2ecb92e954fdc1dd1130b331935f04381b29e28")
set(MUPEN64PLUS_GFX_GLIDEN64_TAG "7bbde56cf08ff96108efb592848e5b6eaac293c9")
set(MUPEN64PLUS_GFX_PARALLEL_URL "https://github.com/Rosalie241/parallel-rdp-standalone")
set(MUPEN64PLUS_GFX_PARALLEL_TAG "693f607728aca78d94ba5d45b0ce119b4ccbcd8c")
set(MUPEN64PLUS_GFX_PARALLEL_TAG "88d3626362e41aa9b011fca1f65e1c1237ddb3b2")
set(DISCORD_RPC_URL "https://github.com/discord/discord-rpc")
set(DISCORD_RPC_TAG "963aa9f3e5ce81a4682c6ca3d136cddda614db33")
endif(NOT NO_GIT_CLONE)
ExternalProject_Add(mupen64plus-core
@@ -62,7 +76,7 @@ ExternalProject_Add(mupen64plus-core
GIT_REPOSITORY ${MUPEN64PLUSCORE_URL}
GIT_TAG ${MUPEN64PLUSCORE_TAG}
BUILD_COMMAND make all OSD=0 NEW_DYNAREC=1 TARGET=${CORE_FILE} DEBUG=$<CONFIG:Debug> KEYBINDINGS=0
BUILD_COMMAND $(MAKE) all OSD=0 NEW_DYNAREC=1 TARGET=${CORE_FILE} DEBUG=$<CONFIG:Debug> KEYBINDINGS=0 CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
BUILD_IN_SOURCE False
BINARY_DIR ${M64P_CORE_DIR}/projects/unix
@@ -81,7 +95,7 @@ ExternalProject_Add(mupen64plus-rsp-cxd4
GIT_REPOSITORY ${MUPEN64PLUS_RSP_CXD4_URL}
GIT_TAG ${MUPEN64PLUS_RSP_CXD4_TAG}
BUILD_COMMAND make all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug> POSTFIX=
BUILD_COMMAND $(MAKE) all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug> POSTFIX= CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
BUILD_IN_SOURCE False
BINARY_DIR ${THIRDPARTY_DIR}/mupen64plus-rsp-cxd4/projects/unix
@@ -99,7 +113,7 @@ ExternalProject_Add(mupen64plus-rsp-hle
GIT_REPOSITORY ${MUPEN64PLUS_RSP_HLE_URL}
GIT_TAG ${MUPEN64PLUS_RSP_HLE_TAG}
BUILD_COMMAND make all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug>
BUILD_COMMAND $(MAKE) all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug> CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
BUILD_IN_SOURCE False
BINARY_DIR ${THIRDPARTY_DIR}/mupen64plus-rsp-hle/projects/unix
@@ -117,7 +131,7 @@ ExternalProject_Add(mupen64plus-rsp-parallel
INSTALL_COMMAND ""
BUILD_IN_SOURCE True
CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
CMAKE_ARGS ${CMAKE_CONFIGURE_ARGS}
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-rsp-parallel/mupen64plus-rsp-parallel.${SO_EXT}
DEPENDS mupen64plus-core
@@ -132,7 +146,7 @@ ExternalProject_Add(mupen64plus-input-raphnetraw
GIT_REPOSITORY ${MUPEN64PLUS_INPUT_RAPHNET_URL}
GIT_TAG ${MUPEN64PLUS_INPUT_RAPHNET_TAG}
BUILD_COMMAND make all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug>
BUILD_COMMAND $(MAKE) all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug> CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
BUILD_IN_SOURCE False
BINARY_DIR ${THIRDPARTY_DIR}/mupen64plus-input-raphnetraw/projects/unix
@@ -141,7 +155,7 @@ ExternalProject_Add(mupen64plus-input-raphnetraw
DEPENDS mupen64plus-core
)
if (${BUILD_INPUT_GCA} STREQUAL "1")
if (BUILD_INPUT_GCA)
ExternalProject_Add(mupen64plus-input-gca
SOURCE_DIR mupen64plus-input-gca/
@@ -157,7 +171,7 @@ if (${BUILD_INPUT_GCA} STREQUAL "1")
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-input-gca/target/release/${GCA_LIB}
DEPENDS mupen64plus-core
)
endif()
endif(BUILD_INPUT_GCA)
set(GLIDEN64_DIR "${THIRDPARTY_DIR}/mupen64plus-video-GLideN64")
set(GLIDEN64_BUILD_DIR "${GLIDEN64_DIR}/projects/cmake")
@@ -181,7 +195,7 @@ ExternalProject_Add(mupen64plus-video-angrylion-plus
INSTALL_COMMAND ""
BUILD_IN_SOURCE True
CMAKE_ARGS -DBUILD_MUPEN64PLUS=ON -DBUILD_PROJECT64=OFF -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
CMAKE_ARGS -DBUILD_MUPEN64PLUS=ON -DBUILD_PROJECT64=OFF -DUSE_QT5=${USE_QT5} ${CMAKE_CONFIGURE_ARGS}
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-video-angrylion-plus/mupen64plus-video-angrylion-plus.${SO_EXT}
DEPENDS mupen64plus-core
@@ -196,7 +210,7 @@ ExternalProject_Add(mupen64plus-video-GLideN64
INSTALL_COMMAND ""
BUILD_IN_SOURCE False
CMAKE_ARGS -DMUPENPLUSAPI=ON -DMUPENPLUSAPI_GLIDENUI=ON -DUSE_SYSTEM_LIBS=ON -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
CMAKE_ARGS -DMUPENPLUSAPI=ON -DMUPENPLUSAPI_GLIDENUI=ON -DGLIDENUI_QT6=${USE_QT6} -DUSE_SYSTEM_LIBS=ON ${CMAKE_CONFIGURE_ARGS}
SOURCE_SUBDIR ./src/
BINARY_DIR ${GLIDEN64_BUILD_DIR}
@@ -215,12 +229,28 @@ ExternalProject_Add(mupen64plus-video-parallel
INSTALL_COMMAND ""
BUILD_IN_SOURCE True
CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
CMAKE_ARGS -DUSE_QT5=${USE_QT5} ${CMAKE_CONFIGURE_ARGS}
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-video-parallel/mupen64plus-video-parallel.${SO_EXT}
DEPENDS mupen64plus-core
)
if (DISCORD_RPC)
ExternalProject_Add(discord-rpc
SOURCE_DIR discord-rpc
GIT_REPOSITORY ${DISCORD_RPC_URL}
GIT_TAG ${DISCORD_RPC_TAG}
INSTALL_COMMAND ""
BUILD_IN_SOURCE True
CMAKE_ARGS -DBUILD_EXAMPLES=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON ${CMAKE_CONFIGURE_ARGS}
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/discord-rpc/src/libdiscord-rpc.a
)
endif(DISCORD_RPC)
ExternalProject_Get_property(mupen64plus-core BUILD_BYPRODUCTS)
set(MUPEN64PLUSCORE_LIB ${BUILD_BYPRODUCTS} PARENT_SCOPE)
set(MUPEN64PLUSCORE_INI ${M64P_CORE_DIR}/data/mupen64plus.ini PARENT_SCOPE)
@@ -237,10 +267,10 @@ set(MUPEN64PLUS_PLUGIN_RSP_PARALLEL ${BUILD_BYPRODUCTS} PARENT_SCOPE)
ExternalProject_Get_property(mupen64plus-input-raphnetraw BUILD_BYPRODUCTS)
set(MUPEN64PLUS_PLUGIN_INPUT_RAPHNET ${BUILD_BYPRODUCTS} PARENT_SCOPE)
if (${BUILD_INPUT_GCA} STREQUAL "1")
if (BUILD_INPUT_GCA)
ExternalProject_Get_property(mupen64plus-input-gca BUILD_BYPRODUCTS)
set(MUPEN64PLUS_PLUGIN_INPUT_GCA ${BUILD_BYPRODUCTS} PARENT_SCOPE)
endif()
endif(BUILD_INPUT_GCA)
ExternalProject_Get_property(mupen64plus-video-angrylion-plus BUILD_BYPRODUCTS)
set(MUPEN64PLUS_PLUGIN_GFX_ANGRYLION ${BUILD_BYPRODUCTS} PARENT_SCOPE)
@@ -250,3 +280,8 @@ set(MUPEN64PLUS_PLUGIN_GFX_GLIDEN64 ${BUILD_BYPRODUCTS} PARENT_SCOPE)
ExternalProject_Get_property(mupen64plus-video-parallel BUILD_BYPRODUCTS)
set(MUPEN64PLUS_PLUGIN_GFX_PARALLEL ${BUILD_BYPRODUCTS} PARENT_SCOPE)
if (DISCORD_RPC)
ExternalProject_Get_property(discord-rpc BUILD_BYPRODUCTS)
set(DISCORD_RPC_LIB ${BUILD_BYPRODUCTS} PARENT_SCOPE)
endif(DISCORD_RPC)
+2 -2
View File
@@ -7,7 +7,7 @@ set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt5 COMPONENTS Gui Widgets Core REQUIRED)
find_package(${QT_VERSION} COMPONENTS Gui Widgets Core REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2)
@@ -36,7 +36,7 @@ target_link_libraries(RMG-Audio
${SDL2_LIBRARIES}
${SPEEX_LIBRARIES}
${SAMPLERATE_LIBRARIES}
Qt5::Gui Qt5::Widgets
${QT_VERSION}::Gui ${QT_VERSION}::Widgets
)
target_include_directories(RMG-Audio PRIVATE
+18 -1
View File
@@ -12,11 +12,13 @@
using namespace UserInterface;
MainDialog::MainDialog(QWidget* parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
MainDialog::MainDialog(QWidget* parent) : QDialog(parent)
{
this->setupUi(this);
this->setWindowIcon(QIcon(":Resource/RMG.png"));
this->setIconsForEmulationInfoText();
this->volumeSlider->setValue(CoreSettingsGetIntValue(SettingsID::Audio_Volume));
this->muteCheckBox->setChecked(CoreSettingsGetBoolValue(SettingsID::Audio_Muted));
@@ -38,6 +40,21 @@ MainDialog::~MainDialog()
{
}
void MainDialog::setIconsForEmulationInfoText(void)
{
QLabel* labels[] = {
this->infoIconLabel_0
};
QIcon infoIcon = QIcon::fromTheme("information-line");
QPixmap infoIconPixmap = infoIcon.pixmap(16, 16);
for (QLabel* label : labels)
{
label->setPixmap(infoIconPixmap);
}
}
void MainDialog::hideEmulationInfoText(void)
{
QHBoxLayout *layouts[] = {this->emulationInfoLayout};
@@ -25,6 +25,7 @@ public:
~MainDialog(void);
private:
void setIconsForEmulationInfoText(void);
void hideEmulationInfoText(void);
private slots:
+2 -2
View File
@@ -324,7 +324,7 @@
<item>
<layout class="QHBoxLayout" name="emulationInfoLayout">
<item>
<widget class="QLabel" name="label_6">
<widget class="QLabel" name="infoIconLabel_0">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
@@ -335,7 +335,7 @@
<string/>
</property>
<property name="pixmap">
<pixmap resource="UIResources.qrc">:/Resource/Info.ico</pixmap>
<pixmap>:/Resource/Info.ico</pixmap>
</property>
<property name="scaledContents">
<bool>false</bool>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,6 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>Resource/RMG.png</file>
<file>Resource/Info.ico</file>
</qresource>
</RCC>
+22 -2
View File
@@ -9,6 +9,9 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2)
pkg_check_modules(MINIZIP REQUIRED minizip)
if (WIN32)
pkg_check_modules(ICONV REQUIRED iconv)
endif(WIN32)
configure_file(Config.hpp.in Config.hpp)
@@ -18,6 +21,7 @@ set(RMG_CORE_SOURCES
m64p/ConfigApi.cpp
m64p/PluginApi.cpp
CachedRomHeaderAndSettings.cpp
ConvertStringEncoding.cpp
Settings/Settings.cpp
SpeedLimiter.cpp
RomSettings.cpp
@@ -29,10 +33,12 @@ set(RMG_CORE_SOURCES
SaveState.cpp
Callback.cpp
Plugins.cpp
Version.cpp
Cheats.cpp
VidExt.cpp
Video.cpp
Error.cpp
Unzip.cpp
Core.cpp
Key.cpp
Rom.cpp
@@ -50,8 +56,15 @@ else()
)
endif()
if (DISCORD_RPC)
list(APPEND RMG_CORE_SOURCES
DiscordRpc.cpp
)
add_definitions(-DDISCORD_RPC)
endif(DISCORD_RPC)
if (PORTABLE_INSTALL)
add_definitions(-DPORTABLE_INSTALL)
add_definitions(-DPORTABLE_INSTALL)
endif(PORTABLE_INSTALL)
add_library(RMG-Core STATIC ${RMG_CORE_SOURCES})
@@ -61,13 +74,20 @@ if(UNIX)
endif(UNIX)
if(WIN32)
target_link_libraries(RMG-Core wsock32 ws2_32)
target_link_libraries(RMG-Core wsock32 ws2_32 ${ICONV_LIBRARIES})
endif(WIN32)
target_link_libraries(RMG-Core
${MINIZIP_LIBRARIES}
)
if (DISCORD_RPC)
target_link_libraries(RMG-Core
${DISCORD_RPC_LIB}
)
add_dependencies(RMG-Core discord-rpc)
endif(DISCORD_RPC)
target_include_directories(RMG-Core PRIVATE
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
+50 -13
View File
@@ -18,16 +18,30 @@
#include <fstream>
#include <algorithm>
#ifdef _WIN32
#include <Windows.h>
#else // Linux
#include <linux/limits.h>
#endif // _WIN32
//
// Local Defines
//
#define MAX_FILENAME_LEN 4096
#define ROMHEADER_NAME_LEN 21
#ifdef _WIN32
#define MAX_FILENAME_LEN MAX_PATH
#else // Linux
#define MAX_FILENAME_LEN PATH_MAX
#endif // _WIN32
#define ROMHEADER_NAME_LEN 256
#define GOODNAME_LEN 256
#define MD5_LEN 33
#define CACHE_FILE_MAGIC "RMGCoreHeaderAndSettingsCache_03"
#ifdef _WIN32
#define CACHE_FILE_MAGIC "RMGCoreHeaderAndSettingsCacheWindows_04"
#else // Linux
#define CACHE_FILE_MAGIC "RMGCoreHeaderAndSettingsCacheLinux_04"
#endif // _WIN32
#define CACHE_FILE_ITEMS_MAX 10000
//
@@ -90,6 +104,7 @@ void CoreReadRomHeaderAndSettingsCache(void)
char headerNameBuf[ROMHEADER_NAME_LEN];
char goodNameBuf[GOODNAME_LEN];
char md5Buf[MD5_LEN];
uint32_t size;
l_CacheEntry cacheEntry;
inputStream.open(get_cache_file_name(), std::ios::binary);
@@ -108,27 +123,32 @@ void CoreReadRomHeaderAndSettingsCache(void)
// read all file entries
#define FREAD(x) inputStream.read((char*)&x, sizeof(x))
#define FREAD_STR(x) inputStream.read((char*)x, sizeof(x))
#define FREAD_STR(x, y) inputStream.read((char*)x, y)
while (!inputStream.eof())
{
// reset buffers
size = 0;
memset(fileNameBuf, 0, sizeof(fileNameBuf));
memset(headerNameBuf, 0, sizeof(headerNameBuf));
memset(goodNameBuf, 0, sizeof(goodNameBuf));
memset(md5Buf, 0, sizeof(md5Buf));
// file info
FREAD_STR(fileNameBuf);
FREAD(size);
FREAD_STR(fileNameBuf, size);
cacheEntry.fileName = std::filesystem::path(fileNameBuf);
FREAD(cacheEntry.fileTime);
// header
FREAD_STR(headerNameBuf);
FREAD(size);
FREAD_STR(headerNameBuf, size);
cacheEntry.header.Name = std::string(headerNameBuf);
FREAD(cacheEntry.header.CRC1);
FREAD(cacheEntry.header.CRC2);
// (partial) settings
FREAD_STR(goodNameBuf);
FREAD_STR(md5Buf);
FREAD(size);
FREAD_STR(goodNameBuf, size);
FREAD(size);
FREAD_STR(md5Buf, size);
cacheEntry.settings.GoodName = std::string(goodNameBuf);
cacheEntry.settings.MD5 = std::string(md5Buf);
@@ -148,6 +168,7 @@ bool CoreSaveRomHeaderAndSettingsCache(void)
char headerNameBuf[ROMHEADER_NAME_LEN];
char goodNameBuf[GOODNAME_LEN];
char md5Buf[MD5_LEN];
uint32_t size;
l_CacheEntry cacheEntry;
// only save cache when the entries have changed
@@ -167,12 +188,13 @@ bool CoreSaveRomHeaderAndSettingsCache(void)
// write each entry in the file
#define FWRITE(x) outputStream.write((char*)&x, sizeof(x))
#define FWRITE_STR(x) outputStream.write((char*)x, sizeof(x))
#define FWRITE_STR(x, y) outputStream.write((char*)x, y)
for (auto iter = l_CacheEntries.cbegin(); iter != l_CacheEntries.end(); iter++)
{
cacheEntry = (*iter);
// reset buffers
size = 0;
memset(fileNameBuf, 0, sizeof(fileNameBuf));
memset(headerNameBuf, 0, sizeof(headerNameBuf));
memset(goodNameBuf, 0, sizeof(goodNameBuf));
@@ -185,15 +207,23 @@ bool CoreSaveRomHeaderAndSettingsCache(void)
strncpy(md5Buf, cacheEntry.settings.MD5.c_str(), sizeof(md5Buf));
// file info
FWRITE_STR(fileNameBuf);
size = cacheEntry.fileName.wstring().size() * sizeof(wchar_t);
FWRITE(size);
FWRITE_STR(fileNameBuf, size);
FWRITE(cacheEntry.fileTime);
// header
FWRITE_STR(headerNameBuf);
size = cacheEntry.header.Name.size();
FWRITE(size);
FWRITE_STR(headerNameBuf, size);
FWRITE(cacheEntry.header.CRC1);
FWRITE(cacheEntry.header.CRC2);
// (partial) settings
FWRITE_STR(goodNameBuf);
FWRITE_STR(md5Buf);
size = cacheEntry.settings.GoodName.size();
FWRITE(size);
FWRITE_STR(goodNameBuf, size);
size = cacheEntry.settings.MD5.size();
FWRITE(size);
FWRITE_STR(md5Buf, size);
}
#undef FWRITE
#undef FWRITE_STR
@@ -245,3 +275,10 @@ bool CoreAddCachedRomHeaderAndSettings(std::filesystem::path file, CoreRomHeader
l_CacheEntriesChanged = true;
return true;
}
bool CoreClearRomHeaderAndSettingsCache(void)
{
l_CacheEntries.clear();
l_CacheEntriesChanged = true;
return true;
}
@@ -36,4 +36,8 @@ bool CoreGetCachedRomHeaderAndSettings(std::filesystem::path file, CoreRomHeader
// for given filename succeeds
bool CoreAddCachedRomHeaderAndSettings(std::filesystem::path file, CoreRomHeader header, CoreRomSettings settings);
// returns whether clearing rom header & settings cache
// succeeds
bool CoreClearRomHeaderAndSettingsCache(void);
#endif // CORE_CACHEDROMHEADERANDSETTINGS_HPP
+17 -3
View File
@@ -9,13 +9,14 @@
*/
#define CORE_INTERNAL
#include "Core.hpp"
#include "ConvertStringEncoding.hpp"
//
// Local Variables
//
static bool l_SetupCallbacks = false;
static std::function<void(enum CoreDebugMessageType, std::string)> l_DebugCallbackFunc;
static std::function<void(enum CoreDebugMessageType, std::string, std::string)> l_DebugCallbackFunc;
//
// Internal Functions
@@ -28,7 +29,20 @@ void CoreDebugCallback(void* context, int level, const char* message)
return;
}
l_DebugCallbackFunc((CoreDebugMessageType)level, std::string(message));
std::string contextString((const char*)context);
std::string messageString(message);
// convert string encoding accordingly
if (messageString.starts_with("IS64:"))
{
messageString = CoreConvertStringEncoding(message, CoreStringEncoding::EUC_JP);
}
else
{
messageString = CoreConvertStringEncoding(message, CoreStringEncoding::Shift_JIS);
}
l_DebugCallbackFunc((CoreDebugMessageType)level, contextString, messageString);
}
void CoreStateCallback(void* context, m64p_core_param param, int value)
@@ -40,7 +54,7 @@ void CoreStateCallback(void* context, m64p_core_param param, int value)
// Exported Functions
//
bool CoreSetupCallbacks(std::function<void(enum CoreDebugMessageType, std::string)> debugCallbackFunc)
bool CoreSetupCallbacks(std::function<void(enum CoreDebugMessageType, std::string, std::string)> debugCallbackFunc)
{
l_DebugCallbackFunc = debugCallbackFunc;
l_SetupCallbacks = true;
+1 -1
View File
@@ -32,6 +32,6 @@ enum class CoreDebugMessageType
Verbose = 5
};
bool CoreSetupCallbacks(std::function<void(enum CoreDebugMessageType, std::string)> debugCallbackFunc);
bool CoreSetupCallbacks(std::function<void(enum CoreDebugMessageType, std::string, std::string)> debugCallbackFunc);
#endif // CORE_CALLBACK_HPP
+41
View File
@@ -717,6 +717,7 @@ bool CoreUpdateCheat(CoreCheat oldCheat, CoreCheat newCheat)
CoreRomHeader romHeader;
CoreRomSettings romSettings;
std::filesystem::path cheatFilePath;
CoreCheatOption cheatOption;
if (!CoreGetCurrentRomHeader(romHeader) ||
!CoreGetCurrentRomSettings(romSettings))
@@ -726,6 +727,23 @@ bool CoreUpdateCheat(CoreCheat oldCheat, CoreCheat newCheat)
cheatFilePath = get_user_cheat_file_path(romHeader, romSettings);
// copy over cheat settings when name has changed
if (oldCheat.Name != newCheat.Name)
{
CoreEnableCheat(newCheat, CoreIsCheatEnabled(oldCheat));
// only set option to new cheat when
// retrieving from old one succeeds
if (CoreGetCheatOption(oldCheat, cheatOption))
{
CoreSetCheatOption(newCheat, cheatOption);
}
// reset old cheat settings
CoreEnableCheat(oldCheat, false);
CoreResetCheatOption(oldCheat);
}
// try to find old cheat in user cheats,
// when it isnt found, it's most likely a system cheat
auto iter = find_user_cheat_using_name(oldCheat.Name);
@@ -892,6 +910,29 @@ bool CoreGetCheatOption(CoreCheat cheat, CoreCheatOption& option)
return false;
}
bool CoreResetCheatOption(CoreCheat cheat)
{
CoreRomSettings romSettings;
std::string settingSection;
std::string settingKey;
if (!cheat.HasOptions)
{
return false;
}
if (!CoreGetCurrentRomSettings(romSettings))
{
return false;
}
settingSection = romSettings.MD5 + " Cheats";
settingKey = "Cheat \"" + cheat.Name + "\" Option";
CoreSettingsSetValue(settingSection, settingKey, -1);
return true;
}
bool CoreApplyCheats(void)
{
std::string error;
+3
View File
@@ -136,6 +136,9 @@ bool CoreSetCheatOption(CoreCheat cheat, CoreCheatOption option);
// attempts to retrieve the currently's set cheat's option
bool CoreGetCheatOption(CoreCheat cheat, CoreCheatOption& option);
// attempts to reset the cheat option
bool CoreResetCheatOption(CoreCheat cheat);
// attempts to apply the enabled cheats to the currently opened ROM
bool CoreApplyCheats(void);
+1 -1
View File
@@ -13,7 +13,7 @@
#define CORE_VERSION "${GIT_VERSION}"
#ifndef PORTABLE_INSTALL
#define CORE_INSTAlL_PREFIX "${CMAKE_INSTALL_PREFIX}"
#define CORE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}"
#endif // PORTABLE_INSTALL
#endif // CORE_CONFIG_HPP
+78
View File
@@ -0,0 +1,78 @@
/*
* 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/>.
*/
#define CORE_INTERNAL
#include "ConvertStringEncoding.hpp"
#include "Error.hpp"
#include <string.h>
#include <string>
#include <iconv.h>
//
// Exported Functions
//
std::string CoreConvertStringEncoding(std::string str, CoreStringEncoding encoding)
{
std::string error;
std::string encodingString;
iconv_t cd;
char inputBuf[256] = {0};
char outputBuf[256] = {0};
char* inputBufPtr = (char*)str.c_str();
char* outputBufPtr = outputBuf;
size_t inputBufSize = str.size();
size_t outputBufSize = sizeof(outputBuf);
if (encoding == CoreStringEncoding::EUC_JP)
{
encodingString = "EUC-JP";
}
else
{
encodingString = "Shift_JIS";
}
cd = iconv_open("UTF-8//TRANSLIT//IGNORE", encodingString.c_str());
if (cd == (iconv_t)-1)
{
error = "CoreConvertStringEncoding Failed: ";
error += "iconv_open Failed: ";
error += errno;
CoreSetError(error);
return str;
}
size_t ret = iconv(cd, &inputBufPtr, &inputBufSize, &outputBufPtr, &outputBufSize);
if (ret == -1)
{
error = "CoreConvertStringEncoding Failed: ";
error += "iconv Failed: ";
error += errno;
CoreSetError(error);
// reset iconv
iconv(cd, nullptr, nullptr, nullptr, nullptr);
iconv_close(cd);
return str;
}
// reset iconv
iconv(cd, nullptr, nullptr, nullptr, nullptr);
iconv_close(cd);
return std::string(outputBuf);
}
+27
View File
@@ -0,0 +1,27 @@
/*
* 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_CONVERTSTRINGENCODING_HPP
#define CORE_CONVERTSTRINGENCODING_HPP
#ifdef CORE_INTERNAL
#include <string>
enum class CoreStringEncoding : int
{
EUC_JP = 0,
Shift_JIS = 1
};
// attempts to convert the string (which uses encoding) to UTF-8,
// on failure, returns original string
std::string CoreConvertStringEncoding(std::string str, CoreStringEncoding encoding);
#endif // CORE_INTERNAL
#endif // CORE_CONVERTSTRINGENCODING_HPP
+27 -10
View File
@@ -9,35 +9,40 @@
*/
#define CORE_INTERNAL
#include "Core.hpp"
#ifdef DISCORD_RPC
#include "DiscordRpc.hpp"
#endif // DISCORD_RPC
#include "osal/osal_dynlib.hpp"
#include "m64p/Api.hpp"
#include "m64p/api/version.h"
#include <filesystem>
#include <string>
#include <cstring>
//
// Local Variables
//
static osal_dynlib_lib_handle l_CoreLibHandle;
static char l_CoreContextString[20];
//
// Local Functions
//
std::string find_core_lib(void)
std::filesystem::path find_core_lib(void)
{
for (const auto& entry : std::filesystem::recursive_directory_iterator(CoreGetCoreDirectory()))
{
std::string path = entry.path().string();
if (path.ends_with(OSAL_DYNLIB_LIB_EXT_STR))
std::filesystem::path path = entry.path();
if (path.has_extension() &&
path.extension() == OSAL_DYNLIB_LIB_EXT_STR)
{
return path;
}
}
return std::string();
return std::filesystem::path();
}
bool config_override_user_dirs(void)
@@ -74,11 +79,14 @@ bool config_override_user_dirs(void)
bool CoreInit(void)
{
std::string error;
std::string core_file;
m64p_error m64p_ret;
std::string error;
std::filesystem::path core_file;
m64p_error m64p_ret;
bool ret = false;
// initialize context string
std::strcpy(l_CoreContextString, "[CORE] ");
core_file = find_core_lib();
if (core_file.empty())
{
@@ -87,7 +95,7 @@ bool CoreInit(void)
return false;
}
l_CoreLibHandle = osal_dynlib_open(core_file.c_str());
l_CoreLibHandle = osal_dynlib_open(core_file);
if (l_CoreLibHandle == nullptr)
{
error = "osal_dynlib_open Failed: ";
@@ -112,7 +120,7 @@ bool CoreInit(void)
return false;
}
m64p_ret = m64p::Core.Startup(FRONTEND_API_VERSION, CoreGetUserConfigDirectory().string().c_str(), CoreGetSharedDataDirectory().string().c_str(), nullptr, CoreDebugCallback, nullptr, CoreStateCallback);
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)
{
error = "CoreInit M64P::Core.Startup() Failed: ";
@@ -153,6 +161,11 @@ bool CoreInit(void)
CoreReadRomHeaderAndSettingsCache();
#ifdef DISCORD_RPC
CoreDiscordRpcInit();
CoreDiscordRpcUpdate(false);
#endif // DISCORD_RPC
return true;
}
@@ -186,6 +199,10 @@ void CoreShutdown(void)
CoreSaveRomHeaderAndSettingsCache();
#ifdef DISCORD_RPC
CoreDiscordRpcShutdown();
#endif // DISCORD_RPC
m64p::Core.Unhook();
m64p::Config.Unhook();
+2
View File
@@ -22,8 +22,10 @@
#include "RomHeader.hpp"
#include "Callback.hpp"
#include "Plugins.hpp"
#include "Version.hpp"
#include "Cheats.hpp"
#include "Error.hpp"
#include "Unzip.hpp"
#include "Video.hpp"
#include "Key.hpp"
#include "Rom.hpp"
+6 -6
View File
@@ -8,9 +8,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "Directories.hpp"
#include "Config.hpp"
#include "Error.hpp"
#include "Core.hpp"
#include "Config.hpp"
#include "m64p/Api.hpp"
#include <cstdio>
@@ -123,7 +123,7 @@ std::filesystem::path CoreGetCoreDirectory(void)
#ifdef PORTABLE_INSTALL
directory = "Core";
#else // Not Portable
directory = CORE_INSTAlL_PREFIX;
directory = CORE_INSTALL_PREFIX;
directory += "/lib/RMG/Core";
#endif // PORTABLE_INSTALL
return directory;
@@ -135,7 +135,7 @@ std::filesystem::path CoreGetPluginDirectory(void)
#ifdef PORTABLE_INSTALL
directory = "Plugin";
#else // Not Portable
directory = CORE_INSTAlL_PREFIX;
directory = CORE_INSTALL_PREFIX;
directory += "/lib/RMG/Plugin";
#endif // PORTABLE_INSTALL
return directory;
@@ -180,7 +180,7 @@ std::filesystem::path CoreGetDefaultSaveDirectory(void)
#ifdef PORTABLE_INSTALL
directory = "Save/Game";
#else // Not Portable
directory = CoreGetUserDataDirectory();
directory = CoreGetDefaultUserDataDirectory();
directory += "/Save/Game";
#endif // PORTABLE_INSTALL
return directory;
@@ -192,7 +192,7 @@ std::filesystem::path CoreGetDefaultSaveStateDirectory(void)
#ifdef PORTABLE_INSTALL
directory = "Save/State";
#else // Not Portable
directory = CoreGetUserDataDirectory();
directory = CoreGetDefaultUserDataDirectory();
directory += "/Save/State";
#endif // PORTABLE_INSTALL
return directory;
@@ -233,7 +233,7 @@ std::filesystem::path CoreGetSharedDataDirectory(void)
#ifdef PORTABLE_INSTALL
directory = "Data";
#else // Not Portable
directory = CORE_INSTAlL_PREFIX;
directory = CORE_INSTALL_PREFIX;
directory += "/share/RMG";
#endif // PORTABLE_INSTALL
return directory;
+87
View File
@@ -0,0 +1,87 @@
/*
* 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 "Settings/Settings.hpp"
#include "DiscordRpc.hpp"
#include "RomSettings.hpp"
#include "RomHeader.hpp"
#include <../3rdParty/discord-rpc/include/discord_rpc.h>
#include <cstring>
#include <ctime>
#include <algorithm>
//
// Exported Functions
//
void CoreDiscordRpcInit(void)
{
if (!CoreSettingsGetBoolValue(SettingsID::GUI_DiscordRpc))
{
return;
}
Discord_Initialize("801450412280119356", nullptr, 0, "");
}
void CoreDiscordRpcShutdown(void)
{
Discord_Shutdown();
}
void CoreDiscordRpcUpdate(bool inGame)
{
std::string smallImageKey;
std::string largeImageKey;
std::string details;
if (!CoreSettingsGetBoolValue(SettingsID::GUI_DiscordRpc))
{
return;
}
if (inGame)
{
CoreRomSettings romSettings;
CoreRomHeader romHeader;
// make sure we retrieve the rom settings & header
if (!CoreGetCurrentRomSettings(romSettings) ||
!CoreGetCurrentRomHeader(romHeader))
{
return;
}
smallImageKey = "rmg-icon";
largeImageKey = romHeader.Name;
details = romSettings.GoodName;
// replace ' ' with '_' and replace '&' with '_'
// also tolower the entire string
std::replace(largeImageKey.begin(),largeImageKey.end(),' ','_');
std::replace(largeImageKey.begin(),largeImageKey.end(),'&','_');
std::transform(largeImageKey.begin(), largeImageKey.end(), largeImageKey.begin(), ::tolower);
}
else
{
largeImageKey = "rmg-icon";
details = "Not in-game";
}
DiscordRichPresence discordPresence;
memset(&discordPresence, 0, sizeof(discordPresence));
discordPresence.smallImageKey = smallImageKey.c_str();
discordPresence.largeImageKey = largeImageKey.c_str();
discordPresence.largeImageText = "Rosalie's Mupen GUI";
discordPresence.details = details.c_str();
discordPresence.startTimestamp = time(nullptr);
Discord_UpdatePresence(&discordPresence);
}
+22
View File
@@ -0,0 +1,22 @@
/*
* 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_DISCORDRPC_HPP
#define CORE_DISCORDRPC_HPP
// initializes the discord rpc library
void CoreDiscordRpcInit(void);
// shuts down the discord rpc library
void CoreDiscordRpcShutdown(void);
// updates the state of the discord rpc library
void CoreDiscordRpcUpdate(bool inGame);
#endif // CORE_DISCORDRPC_HPP
+16 -2
View File
@@ -16,6 +16,9 @@
#include "Cheats.hpp"
#include "Error.hpp"
#include "Rom.hpp"
#ifdef DISCORD_RPC
#include "DiscordRpc.hpp"
#endif // DISCORD_RPC
//
// Local Functions
@@ -123,8 +126,11 @@ bool CoreStartEmulation(std::filesystem::path n64rom, std::filesystem::path n64d
return false;
}
// set disk file in media loader
CoreMediaLoaderSetDiskFile(n64ddrom);
// set disk file in media loader when ROM is a cartridge
if (CoreGetRomType() == CoreRomType::Cartridge)
{
CoreMediaLoaderSetDiskFile(n64ddrom);
}
// apply core settings overlay
apply_coresettings_overlay();
@@ -132,6 +138,10 @@ bool CoreStartEmulation(std::filesystem::path n64rom, std::filesystem::path n64d
// apply game core settings overrides
apply_game_coresettings_overlay();
#ifdef DISCORD_RPC
CoreDiscordRpcUpdate(true);
#endif // DISCORD_RPC
ret = m64p::Core.DoCommand(M64CMD_EXECUTE, 0, nullptr);
if (ret != M64ERR_SUCCESS)
{
@@ -147,6 +157,10 @@ bool CoreStartEmulation(std::filesystem::path n64rom, std::filesystem::path n64d
// restore plugin settings
CoreApplyPluginSettings();
#ifdef DISCORD_RPC
CoreDiscordRpcUpdate(false);
#endif // DISCORD_RPC
return ret == M64ERR_SUCCESS;
}
+34 -1
View File
@@ -7,7 +7,9 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#define CORE_INTERNAL
#include "Plugins.hpp"
#include "Callback.hpp"
#include "Directories.hpp"
#include "Error.hpp"
#include "Emulation.hpp"
@@ -21,6 +23,7 @@
#include "m64p/Api.hpp"
#include <filesystem>
#include <cstring>
//
// Local Variables
@@ -28,6 +31,7 @@
static m64p::PluginApi l_Plugins[(int)CorePluginType::Input];
static std::string l_PluginFiles[(int)CorePluginType::Input];
static char l_PluginContext[(int)CorePluginType::Input][20];
//
// Local Functions
@@ -101,6 +105,32 @@ std::string get_plugin_type_name(CorePluginType type)
return name + " Plugin";
}
std::string get_plugin_context_name(CorePluginType type)
{
std::string name;
switch (type)
{
default:
name = "[UNKNOWN]";
break;
case CorePluginType::Rsp:
name = "[RSP] ";
break;
case CorePluginType::Gfx:
name = "[GFX] ";
break;
case CorePluginType::Audio:
name = "[AUDIO] ";
break;
case CorePluginType::Input:
name = "[INPUT] ";
break;
}
return name;
}
bool apply_plugin_settings(std::string pluginSettings[4])
{
std::string error;
@@ -121,6 +151,9 @@ bool apply_plugin_settings(std::string pluginSettings[4])
pluginType = (CorePluginType)(i + 1);
// copy context string to a c string using strcpy
std::strcpy(l_PluginContext[(int)pluginType], get_plugin_context_name(pluginType).c_str());
if (settingValue != l_PluginFiles[i])
{
plugin = &l_Plugins[i];
@@ -179,7 +212,7 @@ bool apply_plugin_settings(std::string pluginSettings[4])
}
// attempt to start plugin
ret = plugin->Startup(m64p::Core.GetHandle(), nullptr, nullptr);
ret = plugin->Startup(m64p::Core.GetHandle(), (void*)l_PluginContext[(int)pluginType], CoreDebugCallback);
if (ret != M64ERR_SUCCESS)
{
error = "apply_plugin_settings (";
+72 -12
View File
@@ -9,6 +9,7 @@
*/
#include "Rom.hpp"
#include "Error.hpp"
#include "MediaLoader.hpp"
#include "m64p/Api.hpp"
#include "RomSettings.hpp"
#include "Cheats.hpp"
@@ -17,6 +18,7 @@
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
//
// Local Defines
@@ -29,11 +31,26 @@
//
static bool l_HasRomOpen = false;
static bool l_HasDisk = false;
//
// Local Functions
//
static std::string to_lower_str(std::string str)
{
std::string resultString = str;
std::transform(resultString.begin(), resultString.end(), resultString.begin(),
[](unsigned char c)
{
return std::tolower(c);
}
);
return resultString;
}
static bool read_zip_file(std::filesystem::path file, char** buf, int* size)
{
std::string error;
@@ -74,9 +91,11 @@ static bool read_zip_file(std::filesystem::path file, char** buf, int* size)
// make sure file has supported file format,
// if it does, read it in memory
std::filesystem::path fileNamePath(fileName);
if (fileNamePath.extension() == ".z64" ||
fileNamePath.extension() == ".v64" ||
fileNamePath.extension() == ".n64")
std::string fileExtension = fileNamePath.has_extension() ? fileNamePath.extension().string() : "";
fileExtension = to_lower_str(fileExtension);
if (fileExtension == ".z64" ||
fileExtension == ".v64" ||
fileExtension == ".n64")
{
char* buffer;
char* outBuffer;
@@ -190,7 +209,11 @@ static bool read_raw_file(std::filesystem::path file, char** buf, int* size)
if (!fileStream.is_open())
{
error = "read_raw_file Failed: ";
error += "failed to open file!";
error += "failed to open file: ";
error += strerror(errno);
error += " (";
error += std::to_string(errno);
error += ")";
CoreSetError(error);
return false;
}
@@ -230,8 +253,9 @@ bool CoreOpenRom(std::filesystem::path file)
{
std::string error;
m64p_error ret;
char* buf;
int buf_size;
char* buf = nullptr;
int buf_size = 0;
std::string file_extension;
if (!m64p::Core.IsHooked())
{
@@ -246,12 +270,23 @@ bool CoreOpenRom(std::filesystem::path file)
return false;
}
if (file.has_extension() && file.extension() == ".zip")
file_extension = file.has_extension() ? file.extension().string() : "";
file_extension = to_lower_str(file_extension);
if (file_extension == ".zip")
{
if (!read_zip_file(file, &buf, &buf_size))
{
return false;
}
l_HasDisk = false;
}
else if (file_extension == ".d64" ||
file_extension == ".ndd")
{
CoreMediaLoaderSetDiskFile(file);
l_HasDisk = true;
}
else
{
@@ -259,17 +294,28 @@ bool CoreOpenRom(std::filesystem::path file)
{
return false;
}
l_HasDisk = false;
}
if (l_HasDisk)
{
ret = m64p::Core.DoCommand(M64CMD_DISK_OPEN, 0, nullptr);
error = "CoreOpenRom: m64p::Core.DoCommand(M64CMD_DISK_OPEN) Failed: ";
}
else
{
ret = m64p::Core.DoCommand(M64CMD_ROM_OPEN, buf_size, buf);
error = "CoreOpenRom: m64p::Core.DoCommand(M64CMD_ROM_OPEN) Failed: ";
free(buf);
}
ret = m64p::Core.DoCommand(M64CMD_ROM_OPEN, buf_size, buf);
if (ret != M64ERR_SUCCESS)
{
error = "CoreOpenRom: m64p::Core.DoCommand(M64CMD_ROM_OPEN) Failed: ";
error += m64p::Core.ErrorMessage(ret);
CoreSetError(error);
}
free(buf);
l_HasRomOpen = (ret == M64ERR_SUCCESS);
if (l_HasRomOpen)
@@ -288,6 +334,11 @@ bool CoreHasRomOpen(void)
return l_HasRomOpen;
}
CoreRomType CoreGetRomType(void)
{
return l_HasDisk ? CoreRomType::Disk : CoreRomType::Cartridge;
}
bool CoreCloseRom(void)
{
std::string error;
@@ -311,10 +362,19 @@ bool CoreCloseRom(void)
return false;
}
ret = m64p::Core.DoCommand(M64CMD_ROM_CLOSE, 0, nullptr);
if (l_HasDisk)
{
ret = m64p::Core.DoCommand(M64CMD_DISK_CLOSE, 0, nullptr);
error = "CoreCloseRom: m64p::Core.DoCommand(M64CMD_DISK_CLOSE) Failed: ";
}
else
{
ret = m64p::Core.DoCommand(M64CMD_ROM_CLOSE, 0, nullptr);
error = "CoreCloseRom: m64p::Core.DoCommand(M64CMD_ROM_CLOSE) Failed: ";
}
if (ret != M64ERR_SUCCESS)
{
error = "CoreCloseRom: m64p::Core.DoCommand(M64CMD_ROM_CLOSE) Failed: ";
error += m64p::Core.ErrorMessage(ret);
CoreSetError(error);
return false;
+9
View File
@@ -12,12 +12,21 @@
#include <filesystem>
enum class CoreRomType
{
Cartridge,
Disk
};
// opens the given file as ROM
bool CoreOpenRom(std::filesystem::path file);
// returns whether core has a ROM opened
bool CoreHasRomOpen(void);
// returns the opened ROM's type
CoreRomType CoreGetRomType(void);
// closes ROM
bool CoreCloseRom(void);
+4 -1
View File
@@ -13,7 +13,9 @@
#include <arpa/inet.h>
#endif // _WIN32
#define CORE_INTERNAL
#include "RomHeader.hpp"
#include "ConvertStringEncoding.hpp"
#include "Emulation.hpp"
#include "m64p/Api.hpp"
#include "Error.hpp"
@@ -46,6 +48,7 @@ bool CoreGetCurrentRomHeader(CoreRomHeader& header)
header.CRC1 = ntohl(m64p_header.CRC1);
header.CRC2 = ntohl(m64p_header.CRC2);
header.CountryCode = m64p_header.Country_code;
header.Name = std::string((char*)m64p_header.Name);
header.Name = CoreConvertStringEncoding((char*)m64p_header.Name, CoreStringEncoding::Shift_JIS);
return true;
}
+4 -1
View File
@@ -7,13 +7,16 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#define CORE_INTERNAL
#include "RomSettings.hpp"
#include "Emulation.hpp"
#include "RomHeader.hpp"
#include "m64p/Api.hpp"
#include "Error.hpp"
#include "Rom.hpp"
#include "Settings/Settings.hpp"
#include "ConvertStringEncoding.hpp"
//
// Local Variables
@@ -46,7 +49,7 @@ bool CoreGetCurrentRomSettings(CoreRomSettings& settings)
return false;
}
settings.GoodName = std::string(m64p_settings.goodname);
settings.GoodName = CoreConvertStringEncoding(m64p_settings.goodname, CoreStringEncoding::Shift_JIS);
settings.MD5 = std::string(m64p_settings.MD5);
settings.SaveType = m64p_settings.savetype;
settings.DisableExtraMem = m64p_settings.disableextramem;
+99 -20
View File
@@ -10,7 +10,7 @@
#include "Settings.hpp"
#include "Directories.hpp"
#include "Config.hpp"
#include "Version.hpp"
#include "m64p/Api.hpp"
#include "Error.hpp"
#include "m64p/api/m64p_types.h"
@@ -161,8 +161,29 @@ static l_Setting get_setting(SettingsID settingId)
case SettingsID::GUI_AutomaticFullscreen:
setting = {SETTING_SECTION_GUI, "AutomaticFullscreen", false};
break;
case SettingsID::GUI_ShowVerboseLogMessages:
setting = {SETTING_SECTION_GUI, "ShowVerboseLogMessages", false};
break;
case SettingsID::GUI_Toolbar:
setting = {SETTING_SECTION_GUI, "Toolbar", true};
break;
case SettingsID::GUI_StatusBar:
setting = {SETTING_SECTION_GUI, "StatusBar", true};
break;
case SettingsID::GUI_Style:
setting = {SETTING_SECTION_GUI, "Style", ""};
break;
case SettingsID::GUI_IconTheme:
setting = {SETTING_SECTION_GUI, "IconTheme", "black"};
break;
case SettingsID::GUI_CheckForUpdates:
setting = {SETTING_SECTION_GUI, "CheckForUpdates", true};
break;
case SettingsID::GUI_DiscordRpc:
setting = {SETTING_SECTION_GUI, "DiscordRpc", true};
break;
case SettingsID::GUI_Version:
setting = {SETTING_SECTION_GUI, "Version", CORE_VERSION};
setting = {SETTING_SECTION_GUI, "Version", CoreGetVersion()};
break;
case SettingsID::Core_GFX_Plugin:
@@ -353,17 +374,14 @@ static l_Setting get_setting(SettingsID settingId)
case SettingsID::KeyBinding_RemoveDuplicates:
setting = {SETTING_SECTION_KEYBIND, "RemoveDuplicates", true};
break;
case SettingsID::KeyBinding_OpenROM:
setting = {SETTING_SECTION_KEYBIND, "OpenROM", "Ctrl+O"};
case SettingsID::KeyBinding_StartROM:
setting = {SETTING_SECTION_KEYBIND, "StartROM", "Ctrl+O"};
break;
case SettingsID::KeyBinding_OpenCombo:
setting = {SETTING_SECTION_KEYBIND, "OpenCombo", "Ctrl+Shift+O"};
case SettingsID::KeyBinding_StartCombo:
setting = {SETTING_SECTION_KEYBIND, "StartCombo", "Ctrl+Shift+O"};
break;
case SettingsID::KeyBinding_StartEmulation:
setting = {SETTING_SECTION_KEYBIND, "StartEmulation", "F11"};
break;
case SettingsID::KeyBinding_EndEmulation:
setting = {SETTING_SECTION_KEYBIND, "EndEmulation", "F12"};
case SettingsID::KeyBinding_Shutdown:
setting = {SETTING_SECTION_KEYBIND, "Shutdown", "F12"};
break;
case SettingsID::KeyBinding_RefreshROMList:
setting = {SETTING_SECTION_KEYBIND, "RefreshROMList", "F5"};
@@ -380,15 +398,12 @@ static l_Setting get_setting(SettingsID settingId)
case SettingsID::KeyBinding_Resume:
setting = {SETTING_SECTION_KEYBIND, "Resume", "F2"};
break;
case SettingsID::KeyBinding_GenerateBitmap:
setting = {SETTING_SECTION_KEYBIND, "GenerateBitmap", "F3"};
case SettingsID::KeyBinding_Screenshot:
setting = {SETTING_SECTION_KEYBIND, "Screenshot", "F3"};
break;
case SettingsID::KeyBinding_LimitFPS:
setting = {SETTING_SECTION_KEYBIND, "LimitFPS", "F4"};
break;
case SettingsID::KeyBinding_SwapDisk:
setting = {SETTING_SECTION_KEYBIND, "SwapDisk", "Ctrl+D"};
break;
case SettingsID::KeyBinding_SaveState:
setting = {SETTING_SECTION_KEYBIND, "SaveState", "F5"};
break;
@@ -407,6 +422,36 @@ static l_Setting get_setting(SettingsID settingId)
case SettingsID::KeyBinding_GSButton:
setting = {SETTING_SECTION_KEYBIND, "GSButton", "F9"};
break;
case SettingsID::KeyBinding_SaveStateSlot0:
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot0", "Ctrl+0"};
break;
case SettingsID::KeyBinding_SaveStateSlot1:
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot1", "Ctrl+1"};
break;
case SettingsID::KeyBinding_SaveStateSlot2:
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot2", "Ctrl+2"};
break;
case SettingsID::KeyBinding_SaveStateSlot3:
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot3", "Ctrl+3"};
break;
case SettingsID::KeyBinding_SaveStateSlot4:
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot4", "Ctrl+4"};
break;
case SettingsID::KeyBinding_SaveStateSlot5:
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot5", "Ctrl+5"};
break;
case SettingsID::KeyBinding_SaveStateSlot6:
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot6", "Ctrl+6"};
break;
case SettingsID::KeyBinding_SaveStateSlot7:
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot7", "Ctrl+7"};
break;
case SettingsID::KeyBinding_SaveStateSlot8:
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot8", "Ctrl+8"};
break;
case SettingsID::KeyBinding_SaveStateSlot9:
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot9", "Ctrl+9"};
break;
case SettingsID::KeyBinding_Fullscreen:
setting = {SETTING_SECTION_KEYBIND, "Fullscreen", "Alt+Return"};
break;
@@ -430,7 +475,25 @@ static l_Setting get_setting(SettingsID settingId)
setting = {SETTING_SECTION_ROMBROWSER, "Columns", std::vector<int>({0, 1, 2})};
break;
case SettingsID::RomBrowser_ColumnSizes:
setting = {SETTING_SECTION_ROMBROWSER, "ColumnSizes", std::vector<int>({0, 250, 1, 100, 2, 100})};
setting = {SETTING_SECTION_ROMBROWSER, "ColumnSizes", std::vector<int>({-1, -1, -1})};
break;
case SettingsID::RomBrowser_ViewMode:
setting = {SETTING_SECTION_ROMBROWSER, "ViewMode", 0};
break;
case SettingsID::RomBrowser_ListViewSortSection:
setting = {SETTING_SECTION_ROMBROWSER, "ListViewSortSection", 0};
break;
case SettingsID::RomBrowser_ListViewSortOrder:
setting = {SETTING_SECTION_ROMBROWSER, "ListViewSortOrder", 0};
break;
case SettingsID::RomBrowser_GridViewIconWidth:
setting = {SETTING_SECTION_ROMBROWSER, "GridViewIconWidth", 180};
break;
case SettingsID::RomBrowser_GridViewIconHeight:
setting = {SETTING_SECTION_ROMBROWSER, "GridViewIconHeight", 126};
break;
case SettingsID::RomBrowser_GridViewUniformItemSizes:
setting = {SETTING_SECTION_ROMBROWSER, "GridViewUniformItemSizes", true};
break;
case SettingsID::Settings_HasForceUsedSetOnce:
@@ -462,7 +525,7 @@ static l_Setting get_setting(SettingsID settingId)
setting = {SETTING_SECTION_AUDIO, "Muted", false};
break;
case SettingsID::Audio_Synchronize:
setting = {SETTING_SECTION_AUDIO, "Synchronize", true};
setting = {SETTING_SECTION_AUDIO, "Synchronize", false};
break;
case SettingsID::Input_PluggedIn:
@@ -951,7 +1014,7 @@ bool CoreSettingsUpgrade(void)
// we don't need to do anything
// when the core version and the settings version match
if (settingsVersion == CORE_VERSION)
if (settingsVersion == CoreGetVersion())
{
return true;
}
@@ -972,11 +1035,27 @@ bool CoreSettingsUpgrade(void)
CoreSettingsSetValue(SettingsID::Core_ScreenshotPath, CoreGetDefaultScreenshotDirectory());
}
#endif
}
if (settingsVersion == "v0.2.1" ||
settingsVersion == "v0.2.2" ||
settingsVersion == "v0.2.3")
{
// sadly when introducing the new RMG-Audio based on mupen64plus-audio-sdl
// 1) sync audio seems to cause crackling for some users
// 2) sync audio breaks the 'Limit FPS' option
// so to fix those issues, we'll disable the sync audio option
// if it's enabled
if (CoreSettingsGetBoolValue(SettingsID::Audio_Synchronize))
{
CoreSettingsSetValue(SettingsID::Audio_Synchronize, false);
}
}
// save core version
return CoreSettingsSetValue(SettingsID::GUI_Version, std::string(CORE_VERSION));
CoreSettingsSetValue(SettingsID::GUI_Version, CoreGetVersion());
CoreSettingsSave();
return true;
}
bool CoreSettingsSetupDefaults(void)
+28 -7
View File
@@ -13,6 +13,13 @@ enum class SettingsID
GUI_PauseEmulationOnFocusLoss,
GUI_ResumeEmulationOnFocus,
GUI_AutomaticFullscreen,
GUI_ShowVerboseLogMessages,
GUI_Toolbar,
GUI_StatusBar,
GUI_Style,
GUI_IconTheme,
GUI_CheckForUpdates,
GUI_DiscordRpc,
GUI_Version,
// Core Plugin Settings
@@ -87,24 +94,32 @@ enum class SettingsID
// GUI KeyBindings
KeyBinding_RemoveDuplicates,
KeyBinding_OpenROM,
KeyBinding_OpenCombo,
KeyBinding_StartEmulation,
KeyBinding_EndEmulation,
KeyBinding_StartROM,
KeyBinding_StartCombo,
KeyBinding_Shutdown,
KeyBinding_RefreshROMList,
KeyBinding_Exit,
KeyBinding_SoftReset,
KeyBinding_HardReset,
KeyBinding_Resume,
KeyBinding_GenerateBitmap,
KeyBinding_Screenshot,
KeyBinding_LimitFPS,
KeyBinding_SwapDisk,
KeyBinding_SaveState,
KeyBinding_SaveAs,
KeyBinding_LoadState,
KeyBinding_Load,
KeyBinding_Cheats,
KeyBinding_GSButton,
KeyBinding_SaveStateSlot0,
KeyBinding_SaveStateSlot1,
KeyBinding_SaveStateSlot2,
KeyBinding_SaveStateSlot3,
KeyBinding_SaveStateSlot4,
KeyBinding_SaveStateSlot5,
KeyBinding_SaveStateSlot6,
KeyBinding_SaveStateSlot7,
KeyBinding_SaveStateSlot8,
KeyBinding_SaveStateSlot9,
KeyBinding_Fullscreen,
KeyBinding_Settings,
@@ -115,7 +130,13 @@ enum class SettingsID
RomBrowser_MaxItems,
RomBrowser_Columns,
RomBrowser_ColumnSizes,
RomBrowser_ViewMode,
RomBrowser_ListViewSortSection,
RomBrowser_ListViewSortOrder,
RomBrowser_GridViewIconWidth,
RomBrowser_GridViewIconHeight,
RomBrowser_GridViewUniformItemSizes,
// Settings Settings
Settings_HasForceUsedSetOnce,
+169
View File
@@ -0,0 +1,169 @@
/*
* 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 "Unzip.hpp"
#include "Error.hpp"
#include <exception>
#include <filesystem>
#include <fstream>
#include <unzip.h>
//
// Local Defines
//
#define UNZIP_READ_SIZE 67108860 /* 64 MiB */
//
// Exported Functions
//
bool CoreUnzip(std::filesystem::path file, std::filesystem::path path)
{
std::string error;
unzFile zipFile;
unz_global_info zipInfo;
std::ofstream outputStream;
char* read_buffer = (char*)malloc(UNZIP_READ_SIZE);
size_t bytes_read = 0;
if (read_buffer == nullptr)
{
error = "CoreUnzip: malloc Failed!";
CoreSetError(error);
return false;
}
zipFile = unzOpen(file.string().c_str());
if (zipFile == nullptr)
{
free(read_buffer);
error = "CoreUnzip: unzOpen Failed!";
CoreSetError(error);
return false;
}
if (unzGetGlobalInfo(zipFile, &zipInfo) != UNZ_OK)
{
free(read_buffer);
error = "CoreUnzip: unzGetGlobalInfo Failed!";
CoreSetError(error);
return false;
}
for (int i = 0; i < zipInfo.number_entry; i++)
{
unz_file_info fileInfo;
char fileName[PATH_MAX];
std::filesystem::path targetPath;
// ensure we can retrieve the current file info
if (unzGetCurrentFileInfo(zipFile, &fileInfo, fileName, PATH_MAX, nullptr, 0, nullptr, 0) != UNZ_OK)
{
free(read_buffer);
unzClose(zipFile);
error = "CoreUnzip: unzGetCurrentFileInfo Failed!";
CoreSetError(error);
return false;
}
targetPath = path;
targetPath += "/";
targetPath += fileName;
if (targetPath.string().ends_with("/"))
{ // directory
try
{
if (!std::filesystem::is_directory(targetPath) &&
!std::filesystem::create_directory(targetPath))
{
throw std::exception();
}
}
catch (...)
{
free(read_buffer);
unzClose(zipFile);
error = "CoreUnzip: std::filesystem::create_directory(";
error += targetPath.string();
error += ") Failed!";
CoreSetError(error);
return false;
}
}
else
{ // file
if (unzOpenCurrentFile(zipFile) != UNZ_OK)
{
free(read_buffer);
unzClose(zipFile);
error = "CoreUnzip: unzOpenCurrentFile Failed!";
CoreSetError(error);
return false;
}
outputStream.open(targetPath, std::ios::trunc | std::ios::binary);
if (!outputStream.is_open())
{
free(read_buffer);
unzCloseCurrentFile(zipFile);
unzClose(zipFile);
error = "CoreUnzip: failed to open file!";
error += targetPath.string();
CoreSetError(error);
return false;
}
do
{
bytes_read = unzReadCurrentFile(zipFile, read_buffer, UNZIP_READ_SIZE);
if (bytes_read < 0)
{
free(read_buffer);
unzCloseCurrentFile(zipFile);
unzClose(zipFile);
error = "CoreUnzip: unzReadCurrentFile Failed!";
CoreSetError(error);
return false;
}
else
{ // write data to file
outputStream.write(read_buffer, bytes_read);
}
} while (bytes_read > 0);
outputStream.close();
unzCloseCurrentFile(zipFile);
}
// break when we've iterated over all entries
if ((i + 1) >= zipInfo.number_entry)
{
break;
}
// move to next file
if (unzGoToNextFile(zipFile) != UNZ_OK)
{
free(read_buffer);
unzClose(zipFile);
error = "CoreUnzip: unzGoToNextFile Failed!";
CoreSetError(error);
return false;
}
}
unzClose(zipFile);
free(read_buffer);
return true;
}
+18
View File
@@ -0,0 +1,18 @@
/*
* 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_UNZIP_HPP
#define CORE_UNZIP_HPP
#include <filesystem>
// attempts to unzip the file to path
bool CoreUnzip(std::filesystem::path file, std::filesystem::path path);
#endif // CORE_UNZIP_HPP
@@ -7,10 +7,14 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
QTableView
#include "Version.hpp"
#include "Config.hpp"
//
// Exported Functions
//
std::string CoreGetVersion(void)
{
border: none;
color: #0096d3;
selection-color: #FFFFFF;
selection-background-color: #0096d3;
return std::string(CORE_VERSION);
}
+18
View File
@@ -0,0 +1,18 @@
/*
* 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_VERSION_HPP
#define CORE_VERSION_HPP
#include <string>
// returns the current RMG-Core version (as string)
std::string CoreGetVersion(void);
#endif // CORE_VERSION_HPP
+3 -1
View File
@@ -168,7 +168,9 @@ typedef enum {
M64CMD_NETPLAY_GET_VERSION,
M64CMD_NETPLAY_CLOSE,
M64CMD_PIF_OPEN,
M64CMD_ROM_SET_SETTINGS
M64CMD_ROM_SET_SETTINGS,
M64CMD_DISK_OPEN,
M64CMD_DISK_CLOSE
} m64p_command;
typedef struct {
+3 -2
View File
@@ -11,6 +11,7 @@
#define OSAL_DYNLIB_HPP
#include <string>
#include <filesystem>
#ifdef _WIN32
#include <windows.h>
@@ -25,11 +26,11 @@ typedef void* osal_dynlib_lib_sym;
// returns library handle for given filename,
// return nullptr when invalid library
osal_dynlib_lib_handle osal_dynlib_open(const char *);
osal_dynlib_lib_handle osal_dynlib_open(std::filesystem::path path);
// retrieves symbol handle for given library
// handle, returns nullptr when not found
osal_dynlib_lib_sym osal_dynlib_sym(osal_dynlib_lib_handle, const char *);
osal_dynlib_lib_sym osal_dynlib_sym(osal_dynlib_lib_handle, const char* symbol);
// closes library handle
void osal_dynlib_close(osal_dynlib_lib_handle);
+4 -4
View File
@@ -11,14 +11,14 @@
#include <dlfcn.h>
osal_dynlib_lib_handle osal_dynlib_open(const char* file)
osal_dynlib_lib_handle osal_dynlib_open(std::filesystem::path path)
{
return dlopen(file, RTLD_LAZY);
return dlopen(path.string().c_str(), RTLD_LAZY);
}
osal_dynlib_lib_sym osal_dynlib_sym(osal_dynlib_lib_handle handle, const char *sym)
osal_dynlib_lib_sym osal_dynlib_sym(osal_dynlib_lib_handle handle, const char* symbol)
{
return dlsym(handle, sym);
return dlsym(handle, symbol);
}
void osal_dynlib_close(osal_dynlib_lib_handle handle)
+4 -4
View File
@@ -9,14 +9,14 @@
*/
#include "osal_dynlib.hpp"
osal_dynlib_lib_handle osal_dynlib_open(const char* file)
osal_dynlib_lib_handle osal_dynlib_open(std::filesystem::path path)
{
return LoadLibrary(file);
return LoadLibraryW(path.wstring().c_str());
}
osal_dynlib_lib_sym osal_dynlib_sym(osal_dynlib_lib_handle handle, const char *sym)
osal_dynlib_lib_sym osal_dynlib_sym(osal_dynlib_lib_handle handle, const char* symbol)
{
return GetProcAddress(handle, sym);
return GetProcAddress(handle, symbol);
}
void osal_dynlib_close(osal_dynlib_lib_handle handle)
+6 -4
View File
@@ -17,8 +17,9 @@ osal_files_file_time osal_files_get_file_time(std::filesystem::path file)
BOOL ret;
HANDLE file_handle;
FILETIME file_time;
ULARGE_INTEGER ularge_int;
file_handle = CreateFileA(file.string().c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
file_handle = CreateFileW(file.wstring().c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (file_handle == INVALID_HANDLE_VALUE)
{
return -1;
@@ -36,7 +37,8 @@ osal_files_file_time osal_files_get_file_time(std::filesystem::path file)
return -1;
}
// this is probably incorrect but it doesn't matter
// for our use-case
return file_time.dwLowDateTime + file_time.dwHighDateTime;
ularge_int.LowPart = file_time.dwLowDateTime;
ularge_int.HighPart = file_time.dwHighDateTime;
return ularge_int.QuadPart;
}
+2 -2
View File
@@ -8,7 +8,7 @@ set(CMAKE_AUTOUIC ON)
# disable lib prefix
set(CMAKE_SHARED_LIBRARY_PREFIX "")
find_package(Qt5 COMPONENTS Gui Widgets Core Svg REQUIRED)
find_package(${QT_VERSION} COMPONENTS Gui Widgets Core Svg REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2)
@@ -41,4 +41,4 @@ target_include_directories(RMG-Input PRIVATE
${SDL2_INCLUDE_DIRS}
)
target_link_libraries(RMG-Input Qt5::Gui Qt5::Widgets Qt5::Svg)
target_link_libraries(RMG-Input ${QT_VERSION}::Gui ${QT_VERSION}::Widgets ${QT_VERSION}::Svg)
@@ -18,7 +18,7 @@
using namespace UserInterface;
MainDialog::MainDialog(QWidget* parent, Thread::SDLThread* sdlThread) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
MainDialog::MainDialog(QWidget* parent, Thread::SDLThread* sdlThread) : QDialog(parent)
{
this->setupUi(this);
this->setWindowIcon(QIcon(":Resource/RMG.png"));
@@ -28,7 +28,7 @@ private:
QString deviceName;
int deviceNum;
bool operator== (inputDevice_t other)
bool operator== (inputDevice_t other) const
{
return other.deviceNum == deviceNum &&
other.deviceName == deviceName;
@@ -18,11 +18,14 @@ OptionsDialog::OptionsDialog(QWidget* parent, OptionsDialogSettings settings) :
{
this->setupUi(this);
this->setIconsForEmulationInfoText();
this->controllerPakComboBox->setCurrentIndex(settings.ControllerPak);
this->gameboyRomLineEdit->setText(QString::fromStdString(settings.GameboyRom));
this->gameboySaveLineEdit->setText(QString::fromStdString(settings.GameboySave));
this->removeDuplicateMappingsCheckbox->setChecked(settings.RemoveDuplicateMappings);
this->invertAxisCheckBox->setChecked(settings.InvertAxis);
if (!CoreIsEmulationRunning() && !CoreIsEmulationPaused())
{
this->hideEmulationInfoText();
@@ -39,6 +42,21 @@ OptionsDialogSettings OptionsDialog::GetSettings()
return this->settings;
}
void OptionsDialog::setIconsForEmulationInfoText(void)
{
QLabel* labels[] = {
this->infoIconLabel_0
};
QIcon infoIcon = QIcon::fromTheme("information-line");
QPixmap infoIconPixmap = infoIcon.pixmap(16, 16);
for (QLabel* label : labels)
{
label->setPixmap(infoIconPixmap);
}
}
void OptionsDialog::hideEmulationInfoText(void)
{
QHBoxLayout *layouts[] = {this->emulationInfoLayout_1};
@@ -43,6 +43,7 @@ private:
bool hasSaved = false;
OptionsDialogSettings settings;
void setIconsForEmulationInfoText(void);
void hideEmulationInfoText(void);
private slots:
@@ -151,7 +151,7 @@
<item>
<layout class="QHBoxLayout" name="emulationInfoLayout_1">
<item>
<widget class="QLabel" name="label_2">
<widget class="QLabel" name="infoIconLabel_0">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
@@ -162,7 +162,7 @@
<string/>
</property>
<property name="pixmap">
<pixmap resource="UIResources.qrc">:/Resource/Info.ico</pixmap>
<pixmap>:/Resource/Info.ico</pixmap>
</property>
<property name="scaledContents">
<bool>false</bool>
@@ -8,7 +8,7 @@
style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"
id="svg21"
sodipodi:docname="Controller.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
@@ -23,15 +23,17 @@
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="0.28240146"
inkscape:cx="-426.69751"
inkscape:cy="3454.3023"
inkscape:zoom="0.070600365"
inkscape:cx="6019.7989"
inkscape:cy="1600.5583"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg21" />
inkscape:current-layer="layer2"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1" />
<path
id="Dark-Grey-Background"
serif:id="Dark Grey Background"
@@ -111,4 +113,39 @@
style="fill:#ec3f21"
id="circle18" />
</g>
</svg>
<g
id="layer2"
inkscape:label="Z-Button"
style="display:inline;opacity:1;stroke-width:1;stroke-dasharray:none;paint-order:markers stroke fill"
transform="matrix(50.366966,0,0,50.366966,3240.0678,-579.56452)"><g
id="layer2-0"
inkscape:label="Z-Button"
style="clip-rule:evenodd;display:inline;fill-rule:evenodd;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:2;stroke-dasharray:none;paint-order:markers stroke fill"><rect
style="clip-rule:evenodd;display:inline;opacity:1;fill:#5c5c5c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill;image-rendering:auto"
id="rect1917-0-4"
width="11.478539"
height="16.72587"
x="-32.517441"
y="86.256668"
ry="3.4675589"
inkscape:label="btnZ-outline"
class="theme-button"
ojd-button="Z" /><rect
style="display:inline;opacity:1;fill:#bcbdbf;fill-opacity:1;stroke:none;stroke-width:0.960842;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill;image-rendering:auto"
id="rect1917-8"
width="10.956328"
height="16.177647"
x="-32.225891"
y="86.523468"
ry="3.3539019"
inkscape:label="btnZ"
class="theme-button"
ojd-button="Z" /><g
aria-label="Z"
style="font-style:normal;font-weight:normal;font-size:5.73478px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;clip-rule:evenodd;display:inline;opacity:1;fill:#56575b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.751267;stroke-linejoin:round;stroke-miterlimit:2;stroke-dasharray:none;paint-order:markers stroke fill"
id="text1921-7"
transform="matrix(1.3310888,0,0,1.3310888,-67.459296,-40.853038)"><path
d="m 28.805176,99.685474 h 3.514231 v 0.652446 l -2.242948,2.71338 h 2.307352 v 0.81485 h -3.64304 v -0.65244 l 2.242948,-2.71338 h -2.178543 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#56575b;fill-opacity:1;stroke-width:0.751267;stroke-dasharray:none;paint-order:markers stroke fill"
id="path2008-2"
inkscape:connector-curvature="0" /></g></g></g></svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

@@ -8,7 +8,7 @@
style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"
id="svg21"
sodipodi:docname="Controller_NoAnalogStick.svg"
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
@@ -23,15 +23,17 @@
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="0.14120073"
inkscape:cx="2549.5619"
inkscape:cy="3325.0536"
inkscape:zoom="0.099843994"
inkscape:cx="2829.4141"
inkscape:cy="3475.4219"
inkscape:window-width="1920"
inkscape:window-height="1007"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg21" />
inkscape:current-layer="svg21"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1" />
<path
id="Dark-Grey-Background"
serif:id="Dark Grey Background"
@@ -101,4 +103,36 @@
style="fill:#ec3f21"
id="circle18" />
</g>
</svg>
<g
id="layer2"
inkscape:label="Z-Button"
style="display:inline;opacity:1;stroke-width:1;stroke-dasharray:none;paint-order:markers stroke fill"
transform="matrix(50.366966,0,0,50.366966,3240.0678,-579.56452)"><rect
style="clip-rule:evenodd;display:inline;opacity:1;fill:#5c5c5c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill;image-rendering:auto"
id="rect1917-0"
width="11.478539"
height="16.72587"
x="-32.517441"
y="86.256668"
ry="3.4675589"
inkscape:label="btnZ-outline"
class="theme-button"
ojd-button="Z" /><rect
style="display:inline;opacity:1;fill:#bcbdbf;fill-opacity:1;stroke:none;stroke-width:0.960842;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill;image-rendering:auto"
id="rect1917"
width="10.956328"
height="16.177647"
x="-32.225891"
y="86.523468"
ry="3.3539019"
inkscape:label="btnZ"
class="theme-button"
ojd-button="Z" /><g
aria-label="Z"
style="font-style:normal;font-weight:normal;font-size:5.73478px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;clip-rule:evenodd;display:inline;opacity:1;fill:#56575b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.751267;stroke-linejoin:round;stroke-miterlimit:2;stroke-dasharray:none;paint-order:markers stroke fill"
id="text1921"
transform="matrix(1.3310888,0,0,1.3310888,-67.459296,-40.853038)"><path
d="m 28.805176,99.685474 h 3.514231 v 0.652446 l -2.242948,2.71338 h 2.307352 v 0.81485 h -3.64304 v -0.65244 l 2.242948,-2.71338 h -2.178543 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#56575b;fill-opacity:1;stroke-width:0.751267;stroke-dasharray:none;paint-order:markers stroke fill"
id="path2008"
inkscape:connector-curvature="0" /></g></g></svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="6939.9795"
height="6772.564"
viewBox="0 0 6939.9795 6772.564"
version="1.1"
xml:space="preserve"
style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"
id="svg21"
sodipodi:docname="Controller_Pressed_ZTrigger.svg"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs25" /><sodipodi:namedview
id="namedview23"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="0.099843994"
inkscape:cx="2468.8516"
inkscape:cy="3856.0156"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg21"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1" />
<g
style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"
id="g5916"
transform="matrix(1.0882331,0,0,1.0882331,512.32815,1416.6572)"><circle
style="opacity:0.62;fill:#ececec;fill-rule:evenodd;stroke-width:0.280377"
id="path42"
cx="1267.6501"
cy="2546.3296"
r="180.5985" /></g></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

@@ -15,7 +15,7 @@
<file>Resource/Controller_Pressed_Start.svg</file>
<file>Resource/Controller_Pressed_LeftTrigger.svg</file>
<file>Resource/Controller_Pressed_RightTrigger.svg</file>
<file>Resource/Controller_Pressed_ZTrigger.svg</file>
<file>Resource/RMG.png</file>
<file>Resource/Info.ico</file>
</qresource>
</RCC>
@@ -125,6 +125,7 @@ void ControllerImageWidget::paintEvent(QPaintEvent *event)
{ N64ControllerButton::CButtonRight, ":Resource/Controller_Pressed_CButtonRight.svg" },
{ N64ControllerButton::LeftTrigger, ":Resource/Controller_Pressed_LeftTrigger.svg" },
{ N64ControllerButton::RightTrigger, ":Resource/Controller_Pressed_RightTrigger.svg" },
{ N64ControllerButton::ZTrigger, ":Resource/Controller_Pressed_ZTrigger.svg" }
};
static const QString baseImageUri = ":Resource/Controller_NoAnalogStick.svg";
@@ -58,6 +58,7 @@ ControllerWidget::ControllerWidget(QWidget* parent, EventFilter* eventFilter) :
{ N64ControllerButton::CButtonRight, this->cbuttonRightButton },
{ N64ControllerButton::LeftTrigger, this->leftTriggerButton },
{ N64ControllerButton::RightTrigger, this->rightTriggerButton },
{ N64ControllerButton::ZTrigger, this->zTriggerButton }
});
this->joystickWidgetMappings.append(
@@ -121,7 +122,7 @@ ControllerWidget::ControllerWidget(QWidget* parent, EventFilter* eventFilter) :
this->setupButtonWidgets.append(button);
}
this->on_controllerPluggedCheckBox_toggled(false);
this->initializeButtons();
}
@@ -292,6 +293,13 @@ void ControllerWidget::CheckInputDeviceSettings()
std::string deviceName = CoreSettingsGetStringValue(SettingsID::Input_DeviceName, section);
int deviceNum = CoreSettingsGetIntValue(SettingsID::Input_DeviceNum, section);
// do nothing when input device combobox
// is empty
if (this->inputDeviceComboBox->count() == 0)
{
return;
}
// clear (not found) devices first
int notFoundIndex = this->inputDeviceComboBox->findText("(not found)", Qt::MatchFlag::MatchEndsWith);
if (notFoundIndex != -1)
@@ -302,11 +310,11 @@ void ControllerWidget::CheckInputDeviceSettings()
int deviceNameIndex = this->inputDeviceComboBox->findText(QString::fromStdString(deviceName), Qt::MatchFlag::MatchStartsWith);
int deviceNumIndex = this->inputDeviceComboBox->findData(deviceNum);
if ((deviceNameIndex == deviceNumIndex) &&
(deviceNameIndex != -1))
if ((deviceNumIndex != -1) &&
(this->inputDeviceComboBox->itemText(deviceNumIndex).startsWith(QString::fromStdString(deviceName))))
{ // full match
this->inputDeviceComboBox->setCurrentIndex(deviceNameIndex);
this->inputDeviceComboBox->setCurrentIndex(deviceNumIndex);
}
else if (deviceNameIndex != -1)
{ // name only match
@@ -363,7 +371,7 @@ void ControllerWidget::on_profileComboBox_currentIndexChanged(int value)
// reload settings from section
this->LoadSettings(this->getCurrentSettingsSection());
// reload input device settings
CheckInputDeviceSettings();
this->CheckInputDeviceSettings();
}
void ControllerWidget::on_inputDeviceComboBox_currentIndexChanged(int value)
@@ -446,11 +454,15 @@ void ControllerWidget::on_removeProfileButton_clicked()
if (this->profileComboBox->currentIndex() == 0)
{
QMessageBox messageBox(this);
messageBox.setIcon(QMessageBox::Icon::Critical);
messageBox.setWindowTitle("Error");
messageBox.setText("Cannot remove main profile!");
messageBox.addButton(QMessageBox::Ok);
messageBox.exec();
messageBox.setIcon(QMessageBox::Icon::Warning);
messageBox.setText("Are you sure you want to reset the main profile?");
messageBox.addButton(QMessageBox::Yes);
messageBox.addButton(QMessageBox::No);
if (messageBox.exec() == QMessageBox::Yes)
{
this->SaveDefaultSettings();
this->LoadSettings(this->getCurrentSettingsSection());
}
return;
}
@@ -911,6 +923,8 @@ void ControllerWidget::LoadSettings(QString sectionQString)
buttonSetting.button->SetInputData(type, data, extraData, QString::fromStdString(name));
}
this->on_controllerPluggedCheckBox_toggled(this->IsPluggedIn());
}
void ControllerWidget::SaveDefaultSettings()
@@ -927,7 +941,11 @@ void ControllerWidget::SaveDefaultSettings()
CoreSettingsSetValue(SettingsID::Input_DeviceNum, section, -1);
CoreSettingsSetValue(SettingsID::Input_Deadzone, section, 9);
CoreSettingsSetValue(SettingsID::Input_Pak, section, 0);
#ifdef _WIN32
CoreSettingsSetValue(SettingsID::Input_RemoveDuplicateMappings, section, true);
#else
CoreSettingsSetValue(SettingsID::Input_RemoveDuplicateMappings, section, false);
#endif // _WIN32
CoreSettingsSetValue(SettingsID::Input_InvertAxis, section, true);
for (auto& buttonSetting : this->buttonSettingMappings)
+39 -6
View File
@@ -5,21 +5,37 @@ set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt5 COMPONENTS Gui Widgets Core REQUIRED)
find_package(${QT_VERSION} COMPONENTS Gui Widgets Core OpenGL REQUIRED)
if (PORTABLE_INSTALL)
add_definitions(-DPORTABLE_INSTALL)
endif(PORTABLE_INSTALL)
if (UPDATER)
find_package(${QT_VERSION} COMPONENTS Network REQUIRED)
add_definitions(-DUPDATER)
endif(UPDATER)
if (DISCORD_RPC)
add_definitions(-DDISCORD_RPC)
endif(DISCORD_RPC)
find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2)
configure_file(Config.hpp.in Config.hpp)
set(RMG_SOURCES
UserInterface/MainWindow.cpp
UserInterface/MainWindow.ui
UserInterface/Widget/RomBrowserWidget.cpp
UserInterface/Widget/RomBrowserListViewWidget.cpp
UserInterface/Widget/RomBrowserGridViewWidget.cpp
UserInterface/Widget/RomBrowserLoadingWidget.cpp
UserInterface/Widget/RomBrowserEmptyWidget.cpp
UserInterface/Widget/RomBrowserEmptyWidget.ui
UserInterface/Widget/OGLWidget.cpp
UserInterface/Widget/KeybindButton.cpp
UserInterface/Dialog/SettingsDialog.cpp
UserInterface/Dialog/SettingsDialog.ui
UserInterface/Dialog/SettingsDialog.qrc
UserInterface/Dialog/CheatsDialog.cpp
UserInterface/Dialog/CheatsDialog.ui
UserInterface/Dialog/AddCheatDialog.cpp
@@ -30,6 +46,8 @@ set(RMG_SOURCES
UserInterface/Dialog/RomInfoDialog.ui
UserInterface/Dialog/AboutDialog.cpp
UserInterface/Dialog/AboutDialog.ui
UserInterface/Dialog/LogDialog.cpp
UserInterface/Dialog/LogDialog.ui
UserInterface/NoFocusDelegate.cpp
UserInterface/EventFilter.cpp
UserInterface/UIResources.rc
@@ -42,6 +60,17 @@ set(RMG_SOURCES
main.cpp
)
if (UPDATER)
list(APPEND RMG_SOURCES
UserInterface/Dialog/UpdateDialog.cpp
UserInterface/Dialog/UpdateDialog.ui
UserInterface/Dialog/DownloadUpdateDialog.cpp
UserInterface/Dialog/DownloadUpdateDialog.ui
UserInterface/Dialog/InstallUpdateDialog.cpp
UserInterface/Dialog/InstallUpdateDialog.ui
)
endif(UPDATER)
if (CMAKE_BUILD_TYPE MATCHES Release)
add_executable(RMG WIN32 ${RMG_SOURCES})
else()
@@ -50,7 +79,6 @@ endif()
target_link_libraries(RMG
RMG-Core
${SDL2_LIBRARIES}
)
target_include_directories(RMG PRIVATE
@@ -60,4 +88,9 @@ target_include_directories(RMG PRIVATE
${SDL2_INCLUDE_DIRS}
)
target_link_libraries(RMG Qt5::Gui Qt5::Widgets)
target_link_libraries(RMG ${QT_VERSION}::Gui ${QT_VERSION}::Widgets ${QT_VERSION}::OpenGL)
if (UPDATER)
target_link_libraries(RMG ${QT_VERSION}::Network)
endif(UPDATER)
+16 -2
View File
@@ -16,6 +16,7 @@
//
static CoreCallbacks* l_CoreCallbacks = nullptr;
static bool l_showVerboseMessages = false;
//
// Exported Functions
@@ -36,6 +37,8 @@ bool CoreCallbacks::Init(void)
// needed for Qt
qRegisterMetaType<CoreDebugMessageType>("CoreDebugMessageType");
this->LoadSettings();
l_CoreCallbacks = this;
return CoreSetupCallbacks(this->coreDebugCallback);
}
@@ -45,12 +48,23 @@ void CoreCallbacks::Stop(void)
l_CoreCallbacks = nullptr;
}
void CoreCallbacks::coreDebugCallback(CoreDebugMessageType type, std::string message)
void CoreCallbacks::LoadSettings(void)
{
l_showVerboseMessages = CoreSettingsGetBoolValue(SettingsID::GUI_ShowVerboseLogMessages);
}
void CoreCallbacks::coreDebugCallback(CoreDebugMessageType type, std::string context, std::string message)
{
if (l_CoreCallbacks == nullptr)
{
return;
}
emit l_CoreCallbacks->OnCoreDebugCallback(type, QString::fromStdString(message));
// only show verbose messages when enabled
if (!l_showVerboseMessages && type == CoreDebugMessageType::Verbose)
{
return;
}
emit l_CoreCallbacks->OnCoreDebugCallback(type, QString::fromStdString(context), QString::fromStdString(message));
}
+4 -2
View File
@@ -27,11 +27,13 @@ public:
bool Init(void);
void Stop(void);
void LoadSettings(void);
private:
static void coreDebugCallback(CoreDebugMessageType type, std::string message);
static void coreDebugCallback(CoreDebugMessageType type, std::string context, std::string message);
signals:
void OnCoreDebugCallback(CoreDebugMessageType type, QString message);
void OnCoreDebugCallback(CoreDebugMessageType type, QString context, QString message);
};
#endif // RMG_CALLBACKS_HPP
-7
View File
@@ -1,7 +0,0 @@
#ifndef CONFIG_HPP
#define CONFIG_HPP
#define WINDOW_TITLE "Rosalie's Mupen GUI (${GIT_VERSION})"
#define VERSION_STR "${GIT_VERSION}"
#endif // CONFIG_HPP
+2 -3
View File
@@ -44,9 +44,8 @@ class EmulationThread : public QThread
void on_VidExt_ResizeWindow(int, int);
void on_VidExt_Init(void);
void on_VidExt_SetMode(int, int, int, int, int);
void on_VidExt_SetWindowedModeWithRate(int, int, int, int, int);
void on_VidExt_SetFullscreenModeWithRate(int, int, int, int, int);
void on_VidExt_SetWindowedMode(int, int, int, int);
void on_VidExt_SetFullscreenMode(int, int, int, int);
void on_VidExt_SetCaption(QString);
void on_VidExt_ToggleFS(bool);
void on_VidExt_Quit(void);
+25 -12
View File
@@ -12,6 +12,7 @@
#include <QDir>
#include <QDirIterator>
#include <QElapsedTimer>
using namespace Thread;
@@ -28,22 +29,22 @@ RomSearcherThread::~RomSearcherThread(void)
void RomSearcherThread::SetDirectory(QString directory)
{
this->rom_Directory = directory;
this->directory = directory;
}
void RomSearcherThread::SetRecursive(bool value)
{
this->rom_Search_Recursive = value;
this->recursive = value;
}
void RomSearcherThread::SetMaximumFiles(int value)
{
this->rom_Search_MaxItems = value;
this->maxItems = value;
}
void RomSearcherThread::Stop(void)
{
this->rom_Search_Stop = true;
this->stop = true;
while (this->isRunning())
{
this->wait();
@@ -52,12 +53,12 @@ void RomSearcherThread::Stop(void)
void RomSearcherThread::run(void)
{
this->rom_Search_Stop = false;
this->rom_Search(this->rom_Directory);
this->stop = false;
this->searchDirectory(this->directory);
return;
}
void RomSearcherThread::rom_Search(QString directory)
void RomSearcherThread::searchDirectory(QString directory)
{
QDir dir(directory);
@@ -69,7 +70,7 @@ void RomSearcherThread::rom_Search(QString directory)
filter << "*.D64";
filter << "*.ZIP";
QDirIterator::IteratorFlag flag = this->rom_Search_Recursive ?
QDirIterator::IteratorFlag flag = this->recursive ?
QDirIterator::Subdirectories :
QDirIterator::NoIteratorFlags;
QDirIterator romDirIt(directory, filter, QDir::Files, flag);
@@ -83,6 +84,9 @@ void RomSearcherThread::rom_Search(QString directory)
{
QString file = romDirIt.next();
QElapsedTimer timer;
timer.start();
if (CoreHasRomHeaderAndSettingsCached(file.toStdU32String()))
{ // found cache entry
ret = CoreGetCachedRomHeaderAndSettings(file.toStdU32String(), header, settings);
@@ -104,18 +108,27 @@ void RomSearcherThread::rom_Search(QString directory)
if (ret)
{
if (count++ >= this->rom_Search_MaxItems)
if (count++ >= this->maxItems)
{
return;
break;
}
emit this->on_Rom_Found(file, header, settings);
emit this->RomFound(file, header, settings);
}
if (this->rom_Search_Stop)
if (this->stop)
{
break;
}
// ensure the UI thread has some breathing room
// instead of being locked up and unable to render anything
if (timer.elapsed() < 10)
{
QThread::msleep(10 - timer.elapsed());
}
}
emit this->Finished(this->stop);
}
+7 -6
View File
@@ -33,15 +33,16 @@ class RomSearcherThread : public QThread
void run(void) override;
private:
QString rom_Directory;
bool rom_Search_Recursive;
int rom_Search_MaxItems;
bool rom_Search_Stop = false;
QString directory;
bool recursive = false;
int maxItems = 0;
bool stop = false;
void rom_Search(QString);
void searchDirectory(QString);
signals:
void on_Rom_Found(QString file, CoreRomHeader header, CoreRomSettings settings);
void RomFound(QString file, CoreRomHeader header, CoreRomSettings settings);
void Finished(bool canceled);
};
} // namespace Thread
@@ -9,13 +9,13 @@
*/
#include "AboutDialog.hpp"
#include "Config.hpp"
#include <RMG-Core/Core.hpp>
using namespace UserInterface::Dialog;
AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent)
{
this->setupUi(this);
this->versionLabel->setText(QString("RMG %1").arg(VERSION_STR));
this->versionLabel->setText(QString("RMG %1").arg(QString::fromStdString(CoreGetVersion())));
}
@@ -94,7 +94,7 @@
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Copyright © 2020-2022 Rosalie Wanders</string>
<string>Copyright © 2020-2023 Rosalie Wanders</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
@@ -22,7 +22,7 @@
using namespace UserInterface::Dialog;
AddCheatDialog::AddCheatDialog(QWidget *parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
AddCheatDialog::AddCheatDialog(QWidget *parent) : QDialog(parent)
{
this->setupUi(this);
@@ -22,7 +22,7 @@ Q_DECLARE_METATYPE(CoreCheat);
using namespace UserInterface::Dialog;
CheatsDialog::CheatsDialog(QWidget *parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
CheatsDialog::CheatsDialog(QWidget *parent) : QDialog(parent)
{
qRegisterMetaType<CoreCheat>();
@@ -18,7 +18,7 @@ Q_DECLARE_METATYPE(CoreCheatOption);
using namespace UserInterface::Dialog;
ChooseCheatOptionDialog::ChooseCheatOptionDialog(CoreCheat cheat, QWidget *parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
ChooseCheatOptionDialog::ChooseCheatOptionDialog(CoreCheat cheat, QWidget *parent) : QDialog(parent)
{
qRegisterMetaType<CoreCheatOption>();
@@ -0,0 +1,102 @@
/*
* 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 "DownloadUpdateDialog.hpp"
#include <QMessageBox>
#include <QFileInfo>
#include <QPushButton>
#include <QDesktopServices>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QTemporaryDir>
#include <QFile>
using namespace UserInterface::Dialog;
DownloadUpdateDialog::DownloadUpdateDialog(QWidget *parent, QUrl url, QString filename) : QDialog(parent)
{
this->setupUi(this);
this->filename = filename;
this->label->setText("Downloading " + filename + "...");
QNetworkAccessManager* networkAccessManager = new QNetworkAccessManager(this);
QNetworkRequest request(url);
request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
this->reply = networkAccessManager->get(request);
connect(reply, &QNetworkReply::downloadProgress, this, &DownloadUpdateDialog::on_reply_downloadProgress);
connect(reply, &QNetworkReply::finished, this, &DownloadUpdateDialog::on_reply_finished);
}
DownloadUpdateDialog::~DownloadUpdateDialog(void)
{
}
QString DownloadUpdateDialog::GetTempDirectory(void)
{
return this->temporaryDirectory;
}
QString DownloadUpdateDialog::GetFileName(void)
{
return this->filename;
}
void DownloadUpdateDialog::showErrorMessage(QString error, QString details)
{
QMessageBox msgBox((this->isVisible() ? this : this->parentWidget()));
msgBox.setIcon(QMessageBox::Icon::Critical);
msgBox.setWindowTitle("Error");
msgBox.setText(error);
msgBox.setDetailedText(details);
msgBox.addButton(QMessageBox::Ok);
msgBox.exec();
}
void DownloadUpdateDialog::on_reply_downloadProgress(qint64 size, qint64 total)
{
this->progressBar->setMaximum(total);
this->progressBar->setMinimum(0);
this->progressBar->setValue(size);
}
void DownloadUpdateDialog::on_reply_finished(void)
{
if (this->reply->error())
{
this->showErrorMessage("Failed to download update file!", this->reply->errorString());
this->reply->deleteLater();
this->reject();
return;
}
QTemporaryDir temporaryDir;
temporaryDir.setAutoRemove(false);
if (!temporaryDir.isValid())
{
this->showErrorMessage("Failed to create temporary directory!", "");
this->reply->deleteLater();
this->reject();
return;
}
this->temporaryDirectory = temporaryDir.path();
QFile file(temporaryDir.filePath(this->filename));
file.open(QIODevice::WriteOnly);
file.write(this->reply->readAll());
file.close();
this->reply->deleteLater();
this->accept();
}
@@ -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/>.
*/
#ifndef DOWNLOADUPDATEDIALOG_HPP
#define DOWNLOADUPDATEDIALOG_HPP
#include <QWidget>
#include <QDialog>
#include <QJsonObject>
#include <QNetworkReply>
#include <RMG-Core/Core.hpp>
#include <qglobal.h>
#include "ui_DownloadUpdateDialog.h"
namespace UserInterface
{
namespace Dialog
{
class DownloadUpdateDialog : public QDialog, private Ui::DownloadUpdateDialog
{
Q_OBJECT
private:
QNetworkReply *reply;
QString temporaryDirectory;
QString filename;
void showErrorMessage(QString error, QString details);
public:
DownloadUpdateDialog(QWidget *parent, QUrl url, QString filename);
~DownloadUpdateDialog(void);
QString GetTempDirectory(void);
QString GetFileName(void);
private slots:
void on_reply_downloadProgress(qint64 size, qint64 total);
void on_reply_finished(void);
};
} // namespace Dialog
} // namespace UserInterface
#endif // DOWNLOADUPDATEDIALOG_HPP
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DownloadUpdateDialog</class>
<widget class="QDialog" name="DownloadUpdateDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>238</width>
<height>62</height>
</rect>
</property>
<property name="windowTitle">
<string>Downloading Update</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Downloading ...</string>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>0</number>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,167 @@
/*
* 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 "InstallUpdateDialog.hpp"
#include "RMG-Core/Error.hpp"
#include <QMessageBox>
#include <QProcess>
#include <QDir>
#include <QTextStream>
using namespace UserInterface::Dialog;
InstallUpdateDialog::InstallUpdateDialog(QWidget *parent, QString installationDirectory, QString temporaryDirectory, QString filename) : QDialog(parent)
{
this->setupUi(this);
this->installationDirectory = installationDirectory;
this->temporaryDirectory = temporaryDirectory;
this->filename = filename;
this->startTimer(100);
}
InstallUpdateDialog::~InstallUpdateDialog(void)
{
}
void InstallUpdateDialog::install(void)
{
QString fullFilePath;
fullFilePath = this->temporaryDirectory;
fullFilePath += "/" + this->filename;
QString appPath = QCoreApplication::applicationDirPath();
QString appPid = QString::number(QCoreApplication::applicationPid());
#ifdef _WIN32
if (this->filename.endsWith(".exe"))
{
this->label->setText("Executing " + this->filename + "...");
QStringList scriptLines =
{
"@echo off",
"taskkill /F /PID:" + appPid,
"\"" + fullFilePath + "\" /CLOSEAPPLICATIONS /SILENT /DIR=\"" + appPath + "\"",
"rmdir /S /Q \"" + this->temporaryDirectory + "\"",
};
this->writeAndRunScript(scriptLines);
this->accept();
return;
}
#endif // _WIN32
this->label->setText("Extracting " + this->filename + "...");
this->progressBar->setValue(50);
QDir dir(this->temporaryDirectory);
if (!dir.mkdir("extract"))
{
this->showErrorMessage("QDir::mkdir() Failed!", "");
this->reject();
return;
}
QString extractDirectory;
extractDirectory = this->temporaryDirectory;
extractDirectory += "/extract";
if (!CoreUnzip(fullFilePath.toStdU32String(), extractDirectory.toStdU32String()))
{
this->showErrorMessage("CoreUnzip() Failed!", QString::fromStdString(CoreGetError()));
this->reject();
return;
}
this->label->setText("Executing update script...");
this->progressBar->setValue(100);
#ifdef _WIN32
QStringList scriptLines =
{
"@echo off",
"del /F /Q \"" + fullFilePath + "\"",
"taskkill /F /PID:" + appPid,
"xcopy /S /Y /I \"" + extractDirectory + "\\*\" \"" + appPath + "/\"",
"start \"\" \"" + appPath + "\\RMG.exe\"",
"rmdir /S /Q \"" + this->temporaryDirectory + "\"",
};
this->writeAndRunScript(scriptLines);
#else // Linux
QStringList scriptLines =
{
"#!/usr/bin/env bash",
"set -e",
"rm -rf \"" + fullFilePath + "\"",
"kill -1 " + appPid,
"cp -R \"" + extractDirectory + "/\"* \"" + appPath + "/\"",
"chmod +x \"" + appPath + "/RMG\"",
"\"" + appPath + "/RMG\"&",
"rm -rf \"" + this->temporaryDirectory + "\"" ,
};
this->writeAndRunScript(scriptLines);
#endif // _WIN32
}
void InstallUpdateDialog::writeAndRunScript(QStringList stringList)
{
QString scriptPath;
scriptPath = this->temporaryDirectory;
#ifdef _WIN32
scriptPath += "/update.bat";
#else
scriptPath += "/update.sh";
#endif // _WIN32
QFile scriptFile(scriptPath);
if (!scriptFile.open(QIODevice::WriteOnly | QIODevice::Text))
{
this->showErrorMessage("QFile::open() Failed!", "");
return;
}
QTextStream textStream(&scriptFile);
// write script to file
for (const QString& str : stringList)
{
textStream << str << "\n";
}
scriptFile.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner);
scriptFile.close();
this->launchProcess(scriptPath, {});
}
void InstallUpdateDialog::launchProcess(QString file, QStringList arguments)
{
QProcess process;
process.setProgram(file);
process.setArguments(arguments);
process.startDetached();
}
void InstallUpdateDialog::showErrorMessage(QString error, QString details)
{
QMessageBox msgBox((this->isVisible() ? this : this->parentWidget()));
msgBox.setIcon(QMessageBox::Icon::Critical);
msgBox.setWindowTitle("Error");
msgBox.setText(error);
msgBox.setDetailedText(details);
msgBox.addButton(QMessageBox::Ok);
msgBox.exec();
}
void InstallUpdateDialog::timerEvent(QTimerEvent *event)
{
this->killTimer(event->timerId());
this->install();
}
@@ -0,0 +1,49 @@
/*
* 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 INSTALLUPDATEDIALOG_HPP
#define INSTALLUPDATEDIALOG_HPP
#include <QWidget>
#include <QDialog>
#include <RMG-Core/Core.hpp>
#include "ui_InstallUpdateDialog.h"
namespace UserInterface
{
namespace Dialog
{
class InstallUpdateDialog : public QDialog, private Ui::InstallUpdateDialog
{
Q_OBJECT
private:
QString installationDirectory;
QString temporaryDirectory;
QString filename;
void install(void);
void writeAndRunScript(QStringList stringList);
void launchProcess(QString file, QStringList arguments);
void showErrorMessage(QString error, QString details);
protected:
void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE;
public:
InstallUpdateDialog(QWidget *parent, QString installationDirectory, QString temporaryDirectory, QString filename);
~InstallUpdateDialog(void);
};
} // namespace Dialog
} // namespace UserInterface
#endif // INSTALLUPDATEDIALOG_HPP
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>InstallUpdateDialog</class>
<widget class="QDialog" name="InstallUpdateDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>223</width>
<height>62</height>
</rect>
</property>
<property name="windowTitle">
<string>Installing Update</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Installing...</string>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>0</number>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,66 @@
/*
* 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 "LogDialog.hpp"
#include <QMessageBox>
#include <QFileInfo>
#include <QFont>
#include <QIcon>
using namespace UserInterface::Dialog;
LogDialog::LogDialog(QWidget *parent) : QDialog(parent)
{
this->setupUi(this);
this->setWindowIcon(QIcon(":Resource/RMG.png"));
QFont font("monospace");
this->plainTextEdit->setFont(font);
}
LogDialog::~LogDialog(void)
{
}
void LogDialog::AddLogLine(CoreDebugMessageType type, QString context, QString line)
{
QString text;
text = context;
switch (type)
{
case CoreDebugMessageType::Error:
text += "[ERROR] ";
break;
case CoreDebugMessageType::Info:
text += "[INFO] ";
break;
case CoreDebugMessageType::Verbose:
text += "[VERBOSE] ";
break;
case CoreDebugMessageType::Warning:
text += "[WARNING] ";
break;
case CoreDebugMessageType::Status:
text += "[STATUS] ";
break;
}
text += line;
this->plainTextEdit->appendPlainText(text);
}
void LogDialog::Clear(void)
{
this->plainTextEdit->clear();
}
@@ -0,0 +1,41 @@
/*
* 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 LOGDIALOG_HPP
#define LOGDIALOG_HPP
#include <QWidget>
#include <QDialog>
#include <RMG-Core/Core.hpp>
#include "ui_LogDialog.h"
namespace UserInterface
{
namespace Dialog
{
class LogDialog : public QDialog, private Ui::LogDialog
{
Q_OBJECT
private:
public:
LogDialog(QWidget* parent = nullptr);
~LogDialog(void);
void Clear(void);
public slots:
void AddLogLine(CoreDebugMessageType type, QString context, QString line);
};
} // namespace Dialog
} // namespace UserInterface
#endif // LOGDIALOG_HPP
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LogDialog</class>
<widget class="QDialog" name="LogDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>550</width>
<height>480</height>
</rect>
</property>
<property name="windowTitle">
<string>Log</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPlainTextEdit" name="plainTextEdit">
<property name="lineWrapMode">
<enum>QPlainTextEdit::NoWrap</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

@@ -14,63 +14,25 @@
using namespace UserInterface::Dialog;
RomInfoDialog::RomInfoDialog(QString file, QWidget *parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
RomInfoDialog::RomInfoDialog(QString file, CoreRomHeader romHeader, CoreRomSettings romSettings, QWidget *parent) : QDialog(parent)
{
this->setupUi(this);
bool needCloseRom = false;
CoreRomHeader romHeader;
CoreRomSettings romSettings;
// try to open ROM
if (!CoreOpenRom(file.toStdU32String()))
{
this->showErrorMessage(parent, "CoreOpenRom() Failed", QString::fromStdString(CoreGetError()));
return;
}
// try to retrieve ROM header
if (!CoreGetCurrentRomHeader(romHeader))
{
this->showErrorMessage(parent, "CoreGetCurrentRomHeader() Failed", QString::fromStdString(CoreGetError()));
return;
}
// try to retrieve ROM settings
if (!CoreGetCurrentRomSettings(romSettings))
{
this->showErrorMessage(parent, "CoreGetCurrentRomSettings() Failed", QString::fromStdString(CoreGetError()));
return;
}
QFileInfo qFileInfo(file);
this->romNameLineEdit->setText(QString::fromStdString(romHeader.Name));
this->romNameLineEdit->setCursorPosition(0);
this->md5LineEdit->setText(QString::fromStdString(romSettings.MD5));
this->md5LineEdit->setCursorPosition(0);
this->fileNameLineEdit->setText(qFileInfo.fileName());
this->fileNameLineEdit->setCursorPosition(0);
this->locationLineEdit->setText(qFileInfo.absolutePath());
this->locationLineEdit->setCursorPosition(0);
this->crc1LineEdit->setText(QString::number(romHeader.CRC1, 16).toUpper());
this->crc2LineEdit->setText(QString::number(romHeader.CRC2, 16).toUpper());
if (!CoreCloseRom())
{
this->showErrorMessage(parent, "CoreCloseRom() Failed", QString::fromStdString(CoreGetError()));
return;
}
this->countryCodeLineEdit->setText(QString((char)romHeader.CountryCode));
}
RomInfoDialog::~RomInfoDialog(void)
{
}
void RomInfoDialog::showErrorMessage(QWidget* parent, QString error, QString details)
{
QMessageBox msgBox(parent);
msgBox.setIcon(QMessageBox::Icon::Critical);
msgBox.setWindowTitle("Error");
msgBox.setText(error);
msgBox.setDetailedText(details);
msgBox.addButton(QMessageBox::Ok);
msgBox.exec();
}
@@ -25,11 +25,8 @@ class RomInfoDialog : public QDialog, private Ui::RomInfoDialog
{
Q_OBJECT
private:
void showErrorMessage(QWidget* parent, QString error, QString details);
public:
RomInfoDialog(QString file, QWidget *parent);
RomInfoDialog(QString file, CoreRomHeader romHeader, CoreRomSettings romSettings, QWidget *parent);
~RomInfoDialog(void);
};
} // namespace Dialog
+217 -198
View File
@@ -13,206 +13,225 @@
<property name="windowTitle">
<string>ROM Information</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string/>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>ROM Information</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>ROM Name:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="romNameLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>File Name:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="fileNameLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Location:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="locationLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>MD5:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="md5LineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>CRC1:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="crc1LineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>CRC2</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="crc2LineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>112</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="romNameLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>File Name</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="fileNameLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Location</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="locationLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>MD5</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="md5LineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>CRC1</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="crc1LineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>CRC2</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="crc2LineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Country Code</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="countryCodeLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
@@ -8,18 +8,23 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "SettingsDialog.hpp"
#include "RMG-Core/DiscordRpc.hpp"
#include "RMG-Core/Settings/Settings.hpp"
#include "UserInterface/Widget/KeybindButton.hpp"
#include <QFileDialog>
#include <QMessageBox>
#include <QDirIterator>
#include <QLabel>
using namespace UserInterface::Dialog;
SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent)
{
this->setupUi(this);
this->setIconsForEmulationInfoText();
this->romOpened = CoreHasRomOpen();
if (romOpened)
{
@@ -42,13 +47,32 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent, Qt::WindowSyst
pluginList = CoreGetAllPlugins();
for (int i = 0; i < 10; i++)
for (int i = 0; i < 13; i++)
{
this->reloadSettings(i);
}
// connect hotkey settings to slot
this->commonHotkeySettings(-1);
this->commonHotkeySettings(SettingsDialogAction::ConnectSignals);
#ifndef UPDATER
this->checkForUpdatesCheckBox->setHidden(true);
#endif // !UPDATER
#ifndef DISCORD_RPC
this->discordRpcCheckBox->setHidden(true);
// if both DISCORD_RPC & UPDATER
// aren't defined, hide the tab
// with the settings for those
#ifndef UPDATER
this->innerInterfaceTabWidget->removeTab(4);
#endif // !UPDATER
#endif // !DISCORD_RPC
#ifndef _WIN32
this->innerInterfaceTabWidget->removeTab(3);
#endif
int width = CoreSettingsGetIntValue(SettingsID::GUI_SettingsDialogWidth);
int height = CoreSettingsGetIntValue(SettingsID::GUI_SettingsDialogHeight);
@@ -101,34 +125,43 @@ void SettingsDialog::restoreDefaults(int stackedWidgetIndex)
{
default:
case 0:
loadDefaultCoreSettings();
this->loadDefaultCoreSettings();
break;
case 1:
loadDefaultGameSettings();
this->loadDefaultGameSettings();
break;
case 2:
loadDefaultGameCoreSettings();
this->loadDefaultGameCoreSettings();
break;
case 3:
loadDefaultGamePluginSettings();
this->loadDefaultGamePluginSettings();
break;
case 4:
loadDefaultPluginSettings();
this->loadDefaultPluginSettings();
break;
case 5:
loadDefaultDirectorySettings();
this->loadDefaultDirectorySettings();
break;
case 6:
loadDefault64DDSettings();
this->loadDefault64DDSettings();
break;
case 7:
loadDefaultHotkeySettings();
this->loadDefaultHotkeySettings();
break;
case 8:
loadDefaultInterfaceEmulationSettings();
this->loadDefaultInterfaceEmulationSettings();
break;
case 9:
loadDefaultInterfaceRomBrowserSettings();
this->loadDefaultInterfaceRomBrowserSettings();
break;
case 10:
this->loadDefaultInterfaceLogWindowSettings();
break;
case 11:
this->loadDefaultInterfaceStyleSettings();
break;
case 12:
this->loadDefaultInterfaceMiscSettings();
break;
}
}
@@ -139,34 +172,43 @@ void SettingsDialog::reloadSettings(int stackedWidgetIndex)
{
default:
case 0:
loadCoreSettings();
this->loadCoreSettings();
break;
case 1:
loadGameSettings();
this->loadGameSettings();
break;
case 2:
loadGameCoreSettings();
this->loadGameCoreSettings();
break;
case 3:
loadGamePluginSettings();
this->loadGamePluginSettings();
break;
case 4:
loadPluginSettings();
this->loadPluginSettings();
break;
case 5:
loadDirectorySettings();
this->loadDirectorySettings();
break;
case 6:
load64DDSettings();
this->load64DDSettings();
break;
case 7:
loadHotkeySettings();
this->loadHotkeySettings();
break;
case 8:
loadInterfaceEmulationSettings();
this->loadInterfaceEmulationSettings();
break;
case 9:
loadInterfaceRomBrowserSettings();
this->loadInterfaceRomBrowserSettings();
break;
case 10:
this->loadInterfaceLogWindowSettings();
break;
case 11:
this->loadInterfaceStyleSettings();
break;
case 12:
this->loadInterfaceMiscSettings();
break;
}
}
@@ -191,7 +233,7 @@ void SettingsDialog::loadCoreSettings(void)
this->coreCpuEmulatorComboBox->setCurrentIndex(cpuEmulator);
this->coreRandomizeTimingCheckBox->setChecked(randomizeInterrupt);
this->coreDebuggerCheckBox->setChecked(debugger);
//this->coreDebuggerCheckBox->setChecked(debugger);
this->coreOverrideGameSettingsGroup->setChecked(overrideGameSettings);
@@ -282,7 +324,7 @@ void SettingsDialog::loadGamePluginSettings(void)
void SettingsDialog::loadPluginSettings(void)
{
this->commonPluginSettings(0);
this->commonPluginSettings(SettingsDialogAction::LoadSettings);
}
void SettingsDialog::loadDirectorySettings(void)
@@ -331,7 +373,7 @@ void SettingsDialog::load64DDSettings(void)
void SettingsDialog::loadHotkeySettings(void)
{
this->commonHotkeySettings(0);
this->commonHotkeySettings(SettingsDialogAction::LoadSettings);
}
void SettingsDialog::loadInterfaceEmulationSettings(void)
@@ -351,6 +393,26 @@ void SettingsDialog::loadInterfaceRomBrowserSettings(void)
this->romSearchLimitSpinBox->setValue(CoreSettingsGetIntValue(SettingsID::RomBrowser_MaxItems));
}
void SettingsDialog::loadInterfaceLogWindowSettings(void)
{
this->showVerboseLogMessagesCheckBox->setChecked(CoreSettingsGetBoolValue(SettingsID::GUI_ShowVerboseLogMessages));
}
void SettingsDialog::loadInterfaceStyleSettings(void)
{
this->commonInterfaceStyleSettings(SettingsDialogAction::LoadSettings);
}
void SettingsDialog::loadInterfaceMiscSettings(void)
{
#ifdef UPDATER
this->checkForUpdatesCheckBox->setChecked(CoreSettingsGetBoolValue(SettingsID::GUI_CheckForUpdates));
#endif // UPDATER
#ifdef DISCORD_RPC
this->discordRpcCheckBox->setChecked(CoreSettingsGetBoolValue(SettingsID::GUI_DiscordRpc));
#endif // DISCORD_RPC
}
void SettingsDialog::loadDefaultCoreSettings(void)
{
bool disableExtraMem = false;
@@ -371,7 +433,7 @@ void SettingsDialog::loadDefaultCoreSettings(void)
this->coreCpuEmulatorComboBox->setCurrentIndex(cpuEmulator);
this->coreRandomizeTimingCheckBox->setChecked(randomizeInterrupt);
this->coreDebuggerCheckBox->setChecked(debugger);
//this->coreDebuggerCheckBox->setChecked(debugger);
this->coreOverrideGameSettingsGroup->setChecked(overrideGameSettings);
@@ -425,7 +487,7 @@ void SettingsDialog::loadDefaultGamePluginSettings(void)
void SettingsDialog::loadDefaultPluginSettings(void)
{
this->commonPluginSettings(1);
this->commonPluginSettings(SettingsDialogAction::LoadDefaultSettings);
}
void SettingsDialog::loadDefaultDirectorySettings(void)
@@ -448,7 +510,7 @@ void SettingsDialog::loadDefault64DDSettings(void)
void SettingsDialog::loadDefaultHotkeySettings(void)
{
this->commonHotkeySettings(1);
this->commonHotkeySettings(SettingsDialogAction::LoadDefaultSettings);
}
void SettingsDialog::loadDefaultInterfaceEmulationSettings(void)
@@ -468,6 +530,26 @@ void SettingsDialog::loadDefaultInterfaceRomBrowserSettings(void)
this->romSearchLimitSpinBox->setValue(CoreSettingsGetDefaultIntValue(SettingsID::RomBrowser_MaxItems));
}
void SettingsDialog::loadDefaultInterfaceLogWindowSettings(void)
{
this->showVerboseLogMessagesCheckBox->setChecked(CoreSettingsGetDefaultBoolValue(SettingsID::GUI_ShowVerboseLogMessages));
}
void SettingsDialog::loadDefaultInterfaceStyleSettings(void)
{
this->commonInterfaceStyleSettings(SettingsDialogAction::LoadDefaultSettings);
}
void SettingsDialog::loadDefaultInterfaceMiscSettings(void)
{
#ifdef UPDATER
this->checkForUpdatesCheckBox->setChecked(CoreSettingsGetDefaultBoolValue(SettingsID::GUI_CheckForUpdates));
#endif // UPDATER
#ifdef DISCORD_RPC
this->discordRpcCheckBox->setChecked(CoreSettingsGetDefaultBoolValue(SettingsID::GUI_DiscordRpc));
#endif // DISCORD_RPC
}
void SettingsDialog::saveSettings(void)
{
this->saveCoreSettings();
@@ -485,6 +567,9 @@ void SettingsDialog::saveSettings(void)
this->saveHotkeySettings();
this->saveInterfaceEmulationSettings();
this->saveInterfaceRomBrowserSettings();
this->saveInterfaceLogWindowSettings();
this->saveInterfaceStyleSettings();
this->saveInterfaceMiscSettings();
}
void SettingsDialog::saveCoreSettings(void)
@@ -494,12 +579,12 @@ void SettingsDialog::saveCoreSettings(void)
int cpuEmulator = this->coreCpuEmulatorComboBox->currentIndex();
int siDmaDuration = this->coreSiDmaDurationSpinBox->value();
bool randomizeInterrupt = this->coreRandomizeTimingCheckBox->isChecked();
bool debugger = this->coreDebuggerCheckBox->isChecked();
//bool debugger = this->coreDebuggerCheckBox->isChecked();
bool overrideGameSettings = this->coreOverrideGameSettingsGroup->isChecked();
CoreSettingsSetValue(SettingsID::CoreOverlay_CPU_Emulator, cpuEmulator);
CoreSettingsSetValue(SettingsID::CoreOverlay_RandomizeInterrupt, randomizeInterrupt);
CoreSettingsSetValue(SettingsID::CoreOverlay_EnableDebugger, debugger);
//CoreSettingsSetValue(SettingsID::CoreOverlay_EnableDebugger, debugger);
CoreSettingsSetValue(SettingsID::Core_OverrideGameSpecificSettings, overrideGameSettings);
if (!overrideGameSettings)
@@ -623,7 +708,7 @@ void SettingsDialog::save64DDSettings(void)
void SettingsDialog::saveHotkeySettings(void)
{
this->commonHotkeySettings(2);
this->commonHotkeySettings(SettingsDialogAction::SaveSettings);
}
void SettingsDialog::saveInterfaceEmulationSettings(void)
@@ -643,47 +728,123 @@ void SettingsDialog::saveInterfaceRomBrowserSettings(void)
CoreSettingsSetValue(SettingsID::RomBrowser_MaxItems, this->romSearchLimitSpinBox->value());
}
void SettingsDialog::commonHotkeySettings(int action)
void SettingsDialog::saveInterfaceLogWindowSettings(void)
{
struct
CoreSettingsSetValue(SettingsID::GUI_ShowVerboseLogMessages, this->showVerboseLogMessagesCheckBox->isChecked());
}
void SettingsDialog::saveInterfaceStyleSettings(void)
{
#ifdef _WIN32
CoreSettingsSetValue(SettingsID::GUI_Style, this->styleComboBox->currentData().toString().toStdString());
CoreSettingsSetValue(SettingsID::GUI_IconTheme, this->iconThemeComboBox->currentText().toStdString());
#endif // _WIN32
}
void SettingsDialog::saveInterfaceMiscSettings(void)
{
#ifdef UPDATER
CoreSettingsSetValue(SettingsID::GUI_CheckForUpdates, this->checkForUpdatesCheckBox->isChecked());
#endif // UPDATER
#ifdef DISCORD_RPC
CoreSettingsSetValue(SettingsID::GUI_DiscordRpc, this->discordRpcCheckBox->isChecked());
#endif // DISCORD_RPC
}
void SettingsDialog::commonHotkeySettings(SettingsDialogAction action)
{
struct keybinding
{
KeybindButton* button;
SettingsID settingId;
} keybindings[] =
};
std::vector<keybinding> keybindings;
std::vector<keybinding> keybindings_System =
{
{ this->openRomKeyButton, SettingsID::KeyBinding_OpenROM },
{ this->openComboKeyButton, SettingsID::KeyBinding_OpenCombo },
{ this->startEmuKeyButton, SettingsID::KeyBinding_StartEmulation },
{ this->endEmuKeyButton, SettingsID::KeyBinding_EndEmulation },
{ this->startRomKeyButton, SettingsID::KeyBinding_StartROM },
{ this->startComboKeyButton, SettingsID::KeyBinding_StartCombo },
{ this->shutdownKeyButton, SettingsID::KeyBinding_Shutdown },
{ this->refreshRomListKeyButton, SettingsID::KeyBinding_RefreshROMList },
{ this->exitKeyButton, SettingsID::KeyBinding_Exit },
{ this->softResetKeyButton, SettingsID::KeyBinding_SoftReset },
{ this->hardResetKeyButton, SettingsID::KeyBinding_HardReset },
{ this->pauseKeyButton, SettingsID::KeyBinding_Resume },
{ this->generateBitmapKeyButton, SettingsID::KeyBinding_GenerateBitmap },
{ this->generateBitmapKeyButton, SettingsID::KeyBinding_Screenshot },
{ this->limitFPSKeyButton, SettingsID::KeyBinding_LimitFPS },
{ this->swapDiskKeyButton, SettingsID::KeyBinding_SwapDisk },
{ this->saveStateKeyButton, SettingsID::KeyBinding_SaveState },
{ this->saveAsKeyButton, SettingsID::KeyBinding_SaveAs },
{ this->loadStateKeyButton, SettingsID::KeyBinding_LoadState },
{ this->loadKeyButton, SettingsID::KeyBinding_Load },
{ this->cheatsKeyButton, SettingsID::KeyBinding_Cheats },
{ this->gsButtonKeyButton, SettingsID::KeyBinding_GSButton },
{ this->fullscreenKeyButton, SettingsID::KeyBinding_Fullscreen },
};
std::vector<keybinding> keybindings_CurrentSaveState =
{
{ this->saveState0KeyButton, SettingsID::KeyBinding_SaveStateSlot0 },
{ this->saveState1KeyButton, SettingsID::KeyBinding_SaveStateSlot1 },
{ this->saveState2KeyButton, SettingsID::KeyBinding_SaveStateSlot2 },
{ this->saveState3KeyButton, SettingsID::KeyBinding_SaveStateSlot3 },
{ this->saveState4KeyButton, SettingsID::KeyBinding_SaveStateSlot4 },
{ this->saveState5KeyButton, SettingsID::KeyBinding_SaveStateSlot5 },
{ this->saveState6KeyButton, SettingsID::KeyBinding_SaveStateSlot6 },
{ this->saveState7KeyButton, SettingsID::KeyBinding_SaveStateSlot7 },
{ this->saveState8KeyButton, SettingsID::KeyBinding_SaveStateSlot8 },
{ this->saveState9KeyButton, SettingsID::KeyBinding_SaveStateSlot9 },
};
std::vector<keybinding> keybindings_Settings =
{
{ this->settingsKeyButton, SettingsID::KeyBinding_Settings },
};
std::vector<keybinding> keybindings_View =
{
{ this->fullscreenKeyButton, SettingsID::KeyBinding_Fullscreen },
};
if (action == SettingsDialogAction::LoadDefaultSettings)
{
int index = this->keybindingsMenuTabWidget->currentIndex();
switch (index)
{
default:
case 0:
keybindings.insert(keybindings.end(), keybindings_System.begin(), keybindings_System.end());
break;
case 1:
keybindings.insert(keybindings.end(), keybindings_CurrentSaveState.begin(), keybindings_CurrentSaveState.end());
break;
case 2:
keybindings.insert(keybindings.end(), keybindings_Settings.begin(), keybindings_Settings.end());
break;
case 3:
keybindings.insert(keybindings.end(), keybindings_View.begin(), keybindings_View.end());
break;
}
}
else
{
keybindings.insert(keybindings.end(), keybindings_System.begin(), keybindings_System.end());
keybindings.insert(keybindings.end(), keybindings_CurrentSaveState.begin(), keybindings_CurrentSaveState.end());
keybindings.insert(keybindings.end(), keybindings_Settings.begin(), keybindings_Settings.end());
keybindings.insert(keybindings.end(), keybindings_View.begin(), keybindings_View.end());
}
switch (action)
{
default:
break;
case 0:
case SettingsDialogAction::LoadSettings:
this->removeDuplicateHotkeysCheckBox->setChecked(CoreSettingsGetBoolValue(SettingsID::KeyBinding_RemoveDuplicates));
break;
case 1:
case SettingsDialogAction::LoadDefaultSettings:
this->removeDuplicateHotkeysCheckBox->setChecked(CoreSettingsGetDefaultBoolValue(SettingsID::KeyBinding_RemoveDuplicates));
break;
case 2:
case SettingsDialogAction::SaveSettings:
CoreSettingsSetValue(SettingsID::KeyBinding_RemoveDuplicates, this->removeDuplicateHotkeysCheckBox->isChecked());
break;
}
@@ -693,22 +854,22 @@ void SettingsDialog::commonHotkeySettings(int action)
switch (action)
{
default:
case -1:
case SettingsDialogAction::ConnectSignals:
connect(keybinding.button, &KeybindButton::on_KeybindButton_KeybindingChanged, this, &SettingsDialog::on_KeybindButton_KeybindingChanged);
case 0:
case SettingsDialogAction::LoadSettings:
keybinding.button->setText(QString::fromStdString(CoreSettingsGetStringValue(keybinding.settingId)));
break;
case 1:
case SettingsDialogAction::LoadDefaultSettings:
keybinding.button->setText(QString::fromStdString(CoreSettingsGetDefaultStringValue(keybinding.settingId)));
break;
case 2:
case SettingsDialogAction::SaveSettings:
CoreSettingsSetValue(keybinding.settingId, keybinding.button->text().toStdString());
break;
}
}
}
void SettingsDialog::commonPluginSettings(int action)
void SettingsDialog::commonPluginSettings(SettingsDialogAction action)
{
QComboBox *comboBoxArray[] = {this->rspPluginsComboBox, this->videoPluginsComboBox,
this->audioPluginsComboBox, this->inputPluginsComboBox};
@@ -731,7 +892,7 @@ void SettingsDialog::commonPluginSettings(int action)
index = ((int)p.Type - 1);
comboBox = comboBoxArray[index];
pluginFileName = action == 0 ?
pluginFileName = action == SettingsDialogAction::LoadSettings ?
CoreSettingsGetStringValue(settingsIdArray[index]) :
CoreSettingsGetDefaultStringValue(settingsIdArray[index]);
@@ -755,11 +916,79 @@ void SettingsDialog::commonPluginSettings(int action)
}
}
void SettingsDialog::commonInterfaceStyleSettings(SettingsDialogAction action)
{
#ifdef _WIN32
this->styleComboBox->clear();
this->styleComboBox->addItem("None", "");
QString currentStyle = action == SettingsDialogAction::LoadSettings ?
QString::fromStdString(CoreSettingsGetStringValue(SettingsID::GUI_Style)) :
QString::fromStdString(CoreSettingsGetDefaultStringValue(SettingsID::GUI_Style));
QString directory;
directory = QString::fromStdString(CoreGetSharedDataDirectory().string());
directory += "\\Styles\\";
QStringList filter;
filter << "*.qss";
bool styleFound = false;
QDirIterator stylesDirectoryIter(directory, filter, QDir::Files, QDirIterator::NoIteratorFlags);
while (stylesDirectoryIter.hasNext())
{
QString filePath = stylesDirectoryIter.next();
QFileInfo fileInfo(filePath);
this->styleComboBox->addItem(fileInfo.baseName(), filePath);
if (filePath == currentStyle)
{
styleFound = true;
this->styleComboBox->setCurrentText(fileInfo.baseName());
}
}
if (currentStyle.isEmpty())
{
this->styleComboBox->setCurrentText("None");
styleFound = true;
}
if (!styleFound)
{
this->styleComboBox->addItem("", "");
this->styleComboBox->setCurrentText("");
}
QString currentIconTheme = action == SettingsDialogAction::LoadSettings ?
QString::fromStdString(CoreSettingsGetStringValue(SettingsID::GUI_IconTheme)) :
QString::fromStdString(CoreSettingsGetDefaultStringValue(SettingsID::GUI_IconTheme));
this->iconThemeComboBox->setCurrentText(currentIconTheme);
#endif // _WIN32
}
void SettingsDialog::setIconsForEmulationInfoText(void)
{
QLabel* labels[] = {
this->infoIconLabel_0, this->infoIconLabel_1, this->infoIconLabel_2,
this->infoIconLabel_3, this->infoIconLabel_4, this->infoIconLabel_5,
this->infoIconLabel_6, this->infoIconLabel_7
};
QIcon infoIcon = QIcon::fromTheme("information-line");
QPixmap infoIconPixmap = infoIcon.pixmap(16, 16);
for (QLabel* label : labels)
{
label->setPixmap(infoIconPixmap);
}
}
void SettingsDialog::hideEmulationInfoText(void)
{
QHBoxLayout *layouts[] = {this->emulationInfoLayout_0, this->emulationInfoLayout_1,
this->emulationInfoLayout_2, this->emulationInfoLayout_3,
this->emulationInfoLayout_9, this->emulationInfoLayout_13};
this->emulationInfoLayout_9};
for (const auto &layout : layouts)
{
@@ -797,6 +1026,40 @@ void SettingsDialog::chooseIPLRom(QLineEdit *lineEdit)
lineEdit->setText(file);
}
bool SettingsDialog::applyPluginSettings(void)
{
// attempt to apply plugin settings when emulation
// isn't running, when it fails, show the user the error and
// don't allow the user to save invalid settings
if (!CoreIsEmulationPaused() && !CoreIsEmulationRunning())
{
if (!CoreApplyPluginSettings())
{
QMessageBox msgBox(this);
msgBox.setIcon(QMessageBox::Icon::Critical);
msgBox.setWindowTitle("Error");
msgBox.setText("CoreApplyPluginSettings() Failed");
msgBox.setDetailedText(QString::fromStdString(CoreGetError()));
msgBox.addButton(QMessageBox::Ok);
msgBox.exec();
return false;
}
}
return true;
}
void SettingsDialog::closeEvent(QCloseEvent* event)
{
if (this->applyPluginSettings())
{
event->accept();
}
else
{
event->ignore();
}
}
void SettingsDialog::on_buttonBox_clicked(QAbstractButton *button)
{
QPushButton *pushButton = (QPushButton *)button;
@@ -812,22 +1075,9 @@ void SettingsDialog::on_buttonBox_clicked(QAbstractButton *button)
this->saveSettings();
}
// attempt to apply plugin settings when emulation
// isn't running, when it fails, show the user the error and
// don't allow the user to save invalid settings
if (!CoreIsEmulationPaused() && !CoreIsEmulationRunning())
if (!this->applyPluginSettings())
{
if (!CoreApplyPluginSettings())
{
QMessageBox msgBox(this);
msgBox.setIcon(QMessageBox::Icon::Critical);
msgBox.setWindowTitle("Error");
msgBox.setText("CoreApplyPluginSettings() Failed");
msgBox.setDetailedText(QString::fromStdString(CoreGetError()));
msgBox.addButton(QMessageBox::Ok);
msgBox.exec();
return;
}
return;
}
}
@@ -900,10 +1150,9 @@ void SettingsDialog::on_KeybindButton_KeybindingChanged(KeybindButton* button)
KeybindButton* keybindButtons[] =
{
this->openRomKeyButton,
this->openComboKeyButton,
this->startEmuKeyButton,
this->endEmuKeyButton,
this->startRomKeyButton,
this->startComboKeyButton,
this->shutdownKeyButton,
this->refreshRomListKeyButton,
this->exitKeyButton,
this->softResetKeyButton,
@@ -911,15 +1160,24 @@ void SettingsDialog::on_KeybindButton_KeybindingChanged(KeybindButton* button)
this->pauseKeyButton,
this->generateBitmapKeyButton,
this->limitFPSKeyButton,
this->swapDiskKeyButton,
this->saveStateKeyButton,
this->saveAsKeyButton,
this->loadStateKeyButton,
this->loadKeyButton,
this->cheatsKeyButton,
this->gsButtonKeyButton,
this->fullscreenKeyButton,
this->saveState0KeyButton,
this->saveState1KeyButton,
this->saveState2KeyButton,
this->saveState3KeyButton,
this->saveState4KeyButton,
this->saveState5KeyButton,
this->saveState6KeyButton,
this->saveState7KeyButton,
this->saveState8KeyButton,
this->saveState9KeyButton,
this->settingsKeyButton,
this->fullscreenKeyButton,
};
for (KeybindButton* keybindButton : keybindButtons)
@@ -37,6 +37,14 @@ class SettingsDialog : public QDialog, private Ui::SettingsDialog
Q_OBJECT
private:
enum class SettingsDialogAction
{
ConnectSignals = 0,
LoadSettings,
LoadDefaultSettings,
SaveSettings
};
bool romOpened = false;
CoreRomSettings currentGameSettings;
@@ -61,6 +69,9 @@ class SettingsDialog : public QDialog, private Ui::SettingsDialog
void loadHotkeySettings(void);
void loadInterfaceEmulationSettings(void);
void loadInterfaceRomBrowserSettings(void);
void loadInterfaceLogWindowSettings(void);
void loadInterfaceStyleSettings(void);
void loadInterfaceMiscSettings(void);
void loadDefaultCoreSettings(void);
void loadDefaultGameSettings(void);
@@ -72,6 +83,9 @@ class SettingsDialog : public QDialog, private Ui::SettingsDialog
void loadDefaultHotkeySettings(void);
void loadDefaultInterfaceEmulationSettings(void);
void loadDefaultInterfaceRomBrowserSettings(void);
void loadDefaultInterfaceLogWindowSettings(void);
void loadDefaultInterfaceStyleSettings(void);
void loadDefaultInterfaceMiscSettings(void);
void saveSettings(void);
void saveCoreSettings(void);
@@ -84,15 +98,25 @@ class SettingsDialog : public QDialog, private Ui::SettingsDialog
void saveHotkeySettings(void);
void saveInterfaceEmulationSettings(void);
void saveInterfaceRomBrowserSettings(void);
void saveInterfaceLogWindowSettings(void);
void saveInterfaceStyleSettings(void);
void saveInterfaceMiscSettings(void);
void commonHotkeySettings(int);
void commonPluginSettings(int);
void commonHotkeySettings(SettingsDialogAction);
void commonPluginSettings(SettingsDialogAction);
void commonInterfaceStyleSettings(SettingsDialogAction);
void setIconsForEmulationInfoText(void);
void hideEmulationInfoText(void);
void chooseDirectory(QLineEdit *);
void chooseIPLRom(QLineEdit *);
bool applyPluginSettings(void);
protected:
void closeEvent(QCloseEvent* event) Q_DECL_OVERRIDE;
private slots:
void on_buttonBox_clicked(QAbstractButton *);
@@ -1,5 +0,0 @@
<RCC>
<qresource prefix="newPrefix">
<file>Resource/Info.ico</file>
</qresource>
</RCC>

Some files were not shown because too many files have changed in this diff Show More