Compare commits

...

76 Commits

Author SHA1 Message Date
Rosalie Wanders bfbbbdda7b 3rdParty: update mupen64plus-input-gcn 2023-05-06 00:03:19 +02:00
Rosalie Wanders 67a885b43b 3rdParty: update mupen64plus-input-gcn 2023-05-05 23:26:50 +02:00
Rosalie Wanders a49fe03fc2 3rdParty: update mupen64plus-input-gcn 2023-05-05 22:21:29 +02:00
Rosalie Wanders a7b07dc0f9 ci: install libusb 2023-05-05 22:02:50 +02:00
Rosalie Wanders f9a767f8ae 3rdParty: remove mupen64plus-input-gca and add mupen64plus-input-gcn 2023-05-05 21:57:47 +02:00
Rosalie Wanders 42a4786a25 cmake: remove NO_RUST option 2023-05-05 21:57:29 +02:00
Rosalie Wanders b166eac200 Package: update InGame.png 2023-05-04 23:29:12 +02:00
Rosalie Wanders c06316f4aa Package: update RomBrowser.png 2023-05-04 23:27:22 +02:00
Rosalie Wanders 09d96d9e4d README: improve Support section 2023-05-04 23:18:23 +02:00
Rosalie Wanders 66703970b6 Package: v0.4.0 2023-05-04 22:49:45 +02:00
Rosalie Wanders 0d3314a39b 3rdParty: update mupen64plus-input-gca 2023-05-04 22:41:22 +02:00
Rosalie Wanders 748492cc68 Data: add more custom cheats from Gent 2023-05-04 22:25:00 +02:00
Rosalie Wanders e18ad31c53 RMG: set default QSurfaceFormat with vsync disabled in main.cpp 2023-05-04 22:24:32 +02:00
Rosalie Wanders 0dd297f0f8 3rdParty: update angrylion-rdp-plus 2023-04-24 16:42:52 +02:00
Rosalie Wanders 0da4becd46 3rdParty: update parallel-rsp 2023-04-24 16:40:35 +02:00
Rosalie Wanders d284911d4a Installer: don't skip Run when silent 2023-04-16 00:12:11 +02:00
Rosalie Wanders e772eb3906 RMG: don't install desktop icon on update on windows 2023-04-16 00:11:48 +02:00
Rosalie Wanders 577ee4c3e0 3rdParty: update GLideN64 2023-04-15 16:00:58 +02:00
Rosalie Wanders c534df8303 RMG: disable floating on toolbar 2023-04-13 17:47:47 +02:00
Rosalie Wanders a36c8f7de8 3rdParty: update SDL_GameControllerDB 2023-04-07 22:42:11 +02:00
Rosalie Wanders dfb5f1b687 Package: update InputSettings.png 2023-04-07 21:58:29 +02:00
Rosalie Wanders d8eea015fd RMG: allow the toolbar to be moved 2023-04-07 20:54:20 +02:00
Rosalie Wanders f17b7eb2c9 RMG-Core: add GUI_ToolbarArea setting 2023-04-07 20:52:06 +02:00
Rosalie Wanders 33146626a9 Package: v0.3.9 2023-04-06 14:34:29 +02:00
Rosalie Wanders 78e12f774d RMG: add "Edit Game Input Settings" to the context menu of the ROM browser 2023-04-06 14:11:58 +02:00
Rosalie Wanders 689d8debb1 RMG-Input: implement PluginConfig2() and PluginConfig2HasRomConfig() 2023-04-06 14:11:20 +02:00
Rosalie Wanders 8be1ed8af5 RMG-Core: introduce CorePluginsHasROMConfig() and CorePluginsOpenROMConfig() 2023-04-06 14:09:34 +02:00
Rosalie Wanders 0fabdb3f3a RMG-Input: account for versions which didn't have the sensitivity setting in main.cpp 2023-04-06 08:56:49 +02:00
Rosalie Wanders 7a64e7e479 RMG: show progress status in the loading screen of the ROM browser 2023-04-06 01:20:48 +02:00
Rosalie Wanders 8c1589d7cd RMG-Core: correct error message in read_7zip_file 2023-04-06 00:37:31 +02:00
Rosalie Wanders 5a74b137f2 RMG: implement 7-Zip support 2023-04-06 00:28:31 +02:00
Rosalie Wanders 52ba182610 RMG-Core: implement 7-Zip support 2023-04-06 00:28:31 +02:00
Rosalie Wanders b07eb79609 3rdParty: add 7-Zip 2023-04-06 00:28:31 +02:00
Rosalie Wanders 4e3915f527 RMG: only show 'Don't check for updates again' checkbox when needed 2023-04-05 16:22:27 +02:00
Rosalie Wanders 9f620f276d RMG-Input: account for versions which didn't have the sensitivity setting 2023-04-05 16:18:56 +02:00
JaxonWasTaken e3787b5ccf RMG-Input: implement "Analog Stick Sensitivity" 2023-03-31 19:47:31 +02:00
Rosalie Wanders 3d81a052c6 cmake: add NO_RUST option 2023-03-25 20:34:37 +01:00
Rosalie Wanders 6353be1599 RMG: expose CoreOverlay_SaveFileNameFormat setting 2023-03-12 21:47:20 +01:00
Rosalie Wanders bc6ee4877b RMG-Core: use {Core,CoreOverlay}_SaveFileNameFormat settings 2023-03-12 21:47:20 +01:00
Rosalie Wanders 6b38cc3740 RMG-Core: introduce {Core,CoreOverlay}_SaveFileNameFormat settings 2023-03-12 21:47:20 +01:00
Rosalie Wanders 9285fb9fdf 3rdParty: update mupen64plus-core 2023-03-12 21:47:19 +01:00
Rosalie Wanders f5c609413a Package: update archlinux PKGBUILD 2023-03-04 23:33:08 +01:00
RetraCarteR a304f11b1d RMG: introduce more columns (#119) 2023-03-04 23:10:01 +01:00
Rosalie Wanders e10ac1086f RMG: show window after opening ROM 2023-02-25 14:45:28 +01:00
Rosalie Wanders 4533ed61ac 3rdParty: update GLideN64 2023-02-25 14:44:15 +01:00
Rosalie Wanders 235e41653d Package: v0.3.8 2023-02-24 22:51:20 +01:00
Rosalie Wanders 433479b1c3 RMG: add date and time to OSD when selecting a save state slot 2023-02-24 22:47:29 +01:00
Rosalie Wanders 2b4736f224 RMG: add actions in MainWindow::Init() when showUI is false 2023-02-24 22:30:01 +01:00
Rosalie Wanders 41f1dcf9d2 RMG: use RomBrowser_ColumnVisibility 2023-02-24 22:19:41 +01:00
Rosalie Wanders 45b97cf39b RMG-Core: rename RomBrowser_Columns to RomBrowser_ColumnVisibility 2023-02-24 22:19:27 +01:00
Rosalie Wanders 95b1225219 3rdParty: update GLideN64 2023-02-24 22:08:43 +01:00
Rosalie Wanders 70f6c40b26 RMG: use Keybinding_ViewLog setting 2023-02-24 21:48:28 +01:00
Rosalie Wanders 43bc54fca9 RMG-Core: add Keybinding_ViewLog setting 2023-02-24 21:48:12 +01:00
Rosalie Wanders a5ec31ffef RMG: hook up state callback 2023-02-24 21:37:24 +01:00
Rosalie Wanders 81cbf82ddc RMG-Core: implement state callback 2023-02-24 21:36:54 +01:00
Rosalie Wanders 6cea506c6f RMG: implement -d/--debug-messages commandline option 2023-02-24 21:14:48 +01:00
Rosalie Wanders d7d49f261d RMG-Core: introduce CoreSetPrintDebugCallback() 2023-02-24 21:14:27 +01:00
Rosalie Wanders 4692a5c0b7 RMG-Core: use string() for std::filesystem::path in CoreGetSaveStatePath() 2023-02-24 20:04:43 +01:00
Rosalie Wanders d32ea32f1e Package: slight corrections to appdata 2023-02-24 19:57:27 +01:00
Rosalie Wanders f5f053cc4e RMG: add date and time to save state slot items in "Current Save State" 2023-02-24 19:54:24 +01:00
Rosalie Wanders bb3c6dc9fc RMG-Core: introduce CoreGetSaveStatePath() 2023-02-24 19:52:13 +01:00
RetraCarteR 496d4de1de RMG: slightly refactor RomBrowserWidget.cpp (#113) 2023-02-24 18:50:18 +01:00
Rosalie Wanders 71f8437ecb RMG: fix crash in RomBrowserWidget::on_RomBrowserThread_Finished() 2023-02-24 18:40:54 +01:00
Rosalie Wanders e7767105d6 RMG: simplify sanitizing filename in RomBrowserWidget 2023-02-24 00:46:07 +01:00
RetraCarteR 9cfda8514e RMG: implement toggling visibility for columns (#111) 2023-02-24 00:13:51 +01:00
Rosalie Wanders e0c6700a4d RMG: add info about LLE plugins to settings dialog 2023-02-23 22:10:57 +01:00
Rosalie Wanders 12bf158398 RMG: slightly refactor MainWindow.{cpp,hpp} 2023-02-23 21:38:21 +01:00
Rosalie Wanders ea01c86821 RMG: check for updates once an hour and add 'Check For Updates' to View 2023-02-23 15:45:32 +01:00
Rosalie Wanders 96459432a6 RMG-Core: add GUI_LastUpdateCheck setting 2023-02-23 15:36:15 +01:00
Rosalie Wanders 089194c663 Package: add version to AppImage filename 2023-02-23 14:54:28 +01:00
Rosalie Wanders 7a70227535 RMG: handle SIGINT and SIGTERM 2023-02-23 14:42:59 +01:00
Rosalie Wanders 7adfb3123b RMG: use new settings hotkeys 2023-02-23 14:31:19 +01:00
Rosalie Wanders 1d28075601 RMG-Input: add more settings hotkeys 2023-02-23 14:30:43 +01:00
Rosalie Wanders af7aa688bb RMG: implement -n/--nogui commandline option 2023-02-23 14:08:24 +01:00
Rosalie Wanders beb524f523 RMG: keep trying to set video size until it succeeds 2023-02-23 13:57:21 +01:00
Rosalie 18c9c151a8 RMG: hide AppImage commandline options 2023-02-23 09:07:00 +01:00
64 changed files with 2300 additions and 424 deletions
+2 -1
View File
@@ -18,7 +18,7 @@ jobs:
sudo add-apt-repository ppa:okirby/qt6-backports --yes
sudo apt-get -qq update
sudo apt-get upgrade
sudo apt-get -y install cmake ninja-build 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 appstream
sudo apt-get -y install cmake ninja-build libusb-1.0-0-dev 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 appstream
- name: Prepare Environment
run: |
echo "GIT_REVISION=$(git describe --tags --always)" >> $GITHUB_ENV
@@ -66,6 +66,7 @@ jobs:
mingw-w64-x86_64-SDL2
mingw-w64-x86_64-qt6
mingw-w64-x86_64-SDL2
mingw-w64-x86_64-libusb
mingw-w64-x86_64-hidapi
mingw-w64-x86_64-speexdsp
mingw-w64-x86_64-libsamplerate
+2 -1
View File
@@ -76,6 +76,7 @@ else()
endif()
add_subdirectory(Source/3rdParty)
add_subdirectory(Source/3rdParty/7-Zip)
add_subdirectory(Source/RMG-Core)
add_subdirectory(Source/RMG)
@@ -125,7 +126,7 @@ install(FILES ${MUPEN64PLUS_PLUGIN_RSP_PARALLEL}
install(FILES ${MUPEN64PLUS_PLUGIN_INPUT_RAPHNET}
DESTINATION ${PLUGIN_INSTALL_PATH}/Input
)
install(FILES ${MUPEN64PLUS_PLUGIN_INPUT_GCA}
install(FILES ${MUPEN64PLUS_PLUGIN_INPUT_GCN}
DESTINATION ${PLUGIN_INSTALL_PATH}/Input
)
install(FILES ${MUPEN64PLUS_PLUGIN_GFX_ANGRYLION}
@@ -0,0 +1,64 @@
[1FBAF161-2C1C54F1-C:41]
Name=1080 Snowboarding (JU) (M2)
$Enable All Levels & Boarders
80255089 00FF
8025508B 0005
81255096 FCFF
80255098 0007
$Have All\Contest First Place Done
80244098 0007
$Have All\Match Levels Completed
8025508A 0005
$Have All\Trick Attacks Done
81255096 FCFF
$Infinite Damage All Players & Levels
803F4C3C 0024
807F4C3C 0024
$Infinite Lives & Continues
8026B1CB 0003
$Always First Place (Player 1)
81267B88 2400
Note=The game will still show you in 2nd when you are behind. But when you cross the finish line, you will win!
$Open Level Character Select
Note=With these codes, you have to press the buttons listed below when you are viewing a certain boarders stats. Highlight Akari Hayami's stats, and then hold down the C-Left button and then press the A button to be the Crystal Boarder. Highlight Kensuke Kimachi's stats, and then hold down the C-Up button and then press the A button to be the Metal Boarder. Hightlight Rob Haywood's stats, and then hold down the C-Right button and then press the A button to be the Panda Boarder
8125508A 00??
01 Easy Level
02 Easy & Normal Level
03 Easy Normal & Hard Levels
04 Easy Normal Hard Levels & Crystal Boarder
05 Easy Normal Hard Levels & Crystal & Metal Boarders
$Play As
800200E7 00??
00 Dion Blaster
01 Kensuke Kimachi
02 Akari Hayami
03 Ricky Winterborn
04 Rob Haywood
05 Silver Boarder
06 Gold Boarder
07 Panda Boarder
$Freeze Timer In\Match Race
D1267B20 05E1
81267B20 1000
$Freeze Timer In\Time Attack
D12660CC 05E1
812660CC 1000
$Freeze Timer In\Trick Attack
D1266138 05E1
81266138 1000
$Freeze Timer In\Contest
D126628C 05E1
8126628C 1000
@@ -0,0 +1,55 @@
[58FD3F25-D92EAA8D-C:50]
Name=1080 Snowboarding (E) (M4)
$Enable All Levels & Boarders
80250AB9 00FF
80250ABB 0005
81250AC6 FCFF
80250AC8 0007
$Infinite Damage All Players and Levels
803F4C00 0024
807F4C00 0024
$Infinite Lives & Continues
802648A4 0003
$Open Level Character Select
Note=With these codes, you have to press the buttons listed below when you are viewing a certain boarders stats. Highlight Akari Hayami's stats, and then hold down the C-Left button and then press the A button to be the Crystal Boarder. Highlight Kensuke Kimachi's stats, and then hold down the C-Up button and then press the A button to be the Metal Boarder. Hightlight Rob Haywood's stats, and then hold down the C-Right button and then press the A button to be the Panda Boarder
8125508A 00??
01 Easy Level
02 Easy & Normal Level
03 Easy Normal & Hard Levels
04 Easy Normal Hard Levels & Crystal Boarder
05 Easy Normal Hard Levels & Crystal & Metal Boarders
$Play As
8001A0E7 00??
00 Dion Blaster
01 Kensuke Kimachi
02 Akari Hayami
03 Ricky Winterborn
04 Rob Haywood
05 Silver Boarder
06 Gold Boarder
07 Panda Boarder
$Always First Place (Player 1)
812679BC 2400
Note=The game will still show you in 2nd when you are behind. But when you cross the finish line, you will win!
$Freeze Timer In\Match Race
D1267954 05E1
81267954 1000
$Freeze Timer In\Time Attack
D1265D4C 05E1
81265D4C 1000
$Freeze Timer In\Trick Attack
D1265DB8 05E1
81265DB8 1000
$Freeze Timer In\Contest
D1265F48 05E1
81265F48 1000
+1 -1
View File
@@ -8,7 +8,7 @@ bin_dir="$toplvl_dir/Bin/AppImage" # RMG should be installed here
export QMAKE="$(which qmake6)"
export EXTRA_QT_PLUGINS="imageformats;iconengines;"
export VERSION="$(git describe --tags --always)"
export OUTPUT="$bin_dir/../RMG-Portable-Linux64.AppImage"
export OUTPUT="$bin_dir/../RMG-Portable-Linux64-$VERSION.AppImage"
if [ ! -f "$script_dir/linuxdeploy-x86_64.AppImage" ]
then
+4 -3
View File
@@ -1,14 +1,14 @@
# Maintainer: Rosalie Wanders <rosalie@mailbox.org>
pkgname=rmg
pkgver=0.3.7
pkgver=0.3.9
pkgrel=1
pkgdesc="Rosalie's Mupen GUI"
arch=('x86_64')
url="https://github.com/Rosalie241/$pkgname"
license=('GPL3')
depends=("hidapi" "libsamplerate" "minizip" "sdl2" "zlib" "freetype2" "qt6-base" "qt6-svg" "xdg-user-dirs")
makedepends=("git" "nasm" "cmake" "cargo" "ninja")
depends=("hidapi" "libsamplerate" "speexdsp" "minizip" "sdl2" "zlib" "freetype2" "qt6-base" "qt6-svg" "xdg-user-dirs")
makedepends=("git" "nasm" "cmake" "ninja")
source=("git+https://github.com/Rosalie241/$pkgname.git#tag=v$pkgver")
sha256sums=('SKIP')
@@ -24,6 +24,7 @@ build()
-DCMAKE_BUILD_TYPE="Release" \
-DPORTABLE_INSTALL="OFF" \
-DCMAKE_INSTALL_PREFIX="/usr" \
-DNO_RUST="ON" \
-G "Ninja"
cmake --build "$srcdir/$pkgname/build"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 KiB

After

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 85 KiB

+58 -8
View File
@@ -1,4 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<!-- Copyright 2022 Rosalie Wanders -->
<component type="desktop">
<!--Created with jdAppdataEdit 2.1-->
<id>com.github.Rosalie241.RMG</id>
@@ -11,33 +12,82 @@
<description><p>Rosalie's Mupen GUI is an easy to use yet customizable mupen64plus front-end, allowing you to easily play N64 games.</p></description>
<screenshots>
<screenshot type="default">
<caption>The Rom Browser</caption>
<caption>01 - The Rom Browser</caption>
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/RomBrowser.png</image>
</screenshot>
<screenshot type="default">
<caption>During A Game</caption>
<caption>02 - 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>
<caption>03 - Cheats</caption>
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/Cheats.png</image>
</screenshot>
<screenshot type="default">
<caption>Settings</caption>
<caption>04 - 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>
<caption>05 - Input Settings</caption>
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/InputSettings.png</image>
</screenshot>
</screenshots>
<releases>
<release version="v0.4.0" date="2023-05-04" type="stable">
<description>
<p>Changes:</p>
<ul>
<li>Fix updater on windows always installing the desktop icon</li>
<li>Fix updater on windows not re-launching RMG after installation</li>
<li>Fix the speed limiter toggle and speed factor options not working on linux on some systems</li>
<li>Fix the 1080 Snowboarding cheats (thank you Gent)</li>
<li>Add support for moving the toolbar (changes to the docked position are persistent across application runs)</li>
<li>Update GLideN64 and mupen64plus-input-gca</li>
</ul>
</description>
</release>
<release version="v0.3.9" date="2023-04-06" type="stable">
<description>
<p>Changes:</p>
<ul>
<li>Fix "Don't check for updates again" checkbox appearing when requesting an update check through Help -> Check For Updates</li>
<li>Add game format, file name, file extension, file size, game I.D. and game region columns to the list view of the ROM browser which can be toggled in the "Show/Hide Columns" menu of the context menu in the list view of the ROM browser (thank you RetraCarteR)</li>
<li>Add "Reset Column Sizes" to context menu of the list view of the ROM browser (thank you RetraCarteR)</li>
<li>Add "Analog Stick Sensitivity" setting to RMG-Input (thank you JaxonWasTaken)</li>
<li>Add "Save Filename Format" setting to the Core tab of the settings dialog</li>
<li>Add "Edit Game Input Settings" to the context menu of the ROM browser</li>
<li>Add support for 7z files</li>
<li>Add progress status to the loading screen in the ROM browser when loading takes more than 5 seconds</li>
</ul>
</description>
</release>
<release version="v0.3.8" date="2023-02-24" type="stable">
<description>
<p>Changes:</p>
<ul>
<li>Fix RMG not having the correct video size in some cases (i.e on a WM where resizing is not allowed to be done by an application)</li>
<li>Fix translations not working in GLideN64</li>
<li>Add -n/--nogui commandline option</li>
<li>Add -d/--debug-messages commandline option</li>
<li>Add hotkeys for graphics, audio, RSP and input settings</li>
<li>Add hotkey for viewing the log</li>
<li>Add SIGINT and SIGTERM handling on linux</li>
<li>Add "Check For Updates" to "View" in the toolbar</li>
<li>Add information about LLE plugins in the settings dialog</li>
<li>Add support for toggling visibility of columns in the ROM browser list view (thank you RetraCarteR)</li>
<li>Add date and time to the save state slot items in "Current Save State" menu in the menubar</li>
<li>Add date and time to the OSD when selecting a save state slot</li>
<li>Add failure messages to the OSD when loading/saving a save state fails</li>
<li>Improve updater behavior by checking for an update on startup with at least an hour in-between checks</li>
</ul>
</description>
</release>
<release version="v0.3.7" date="2023-02-19" type="stable">
<description>
<p>Changes:</p>
<ul>
<li>Fix icons not showing up in some cases when migrating from a version before v0.3.5</li>
<li>Fix plugin settings not being loaded properly in the settings dialog when migrating from a version before v0.3.5</li>
<li>Fix icons not showing up in some cases when migrating from a version before v0.3.6</li>
<li>Fix plugin settings not being loaded properly in the settings dialog when migrating from a version before v0.3.6</li>
</ul>
</description>
</release>
@@ -45,7 +95,7 @@
<description>
<p>Changes:</p>
<ul>
<li>Fix RMG not using xwayland when using wayland (wayland has lots of issues, can be disabled by building with the `-DFORCE_XCB=OFF` option)</li>
<li>Fix RMG not using xwayland when using wayland (wayland has lots of issues, can be disabled by building with the "-DFORCE_XCB=OFF" option)</li>
<li>Fix some non-fatal mupen64plus errors showing a pop-up</li>
<li>Fix window not returning to ROM browser when launching a game through the commandline and the plugins aren't ready</li>
<li>Add support for Qt stylesheets (place them in the 'user data directory/Styles' directory with the '.qss' extension, they'll show up in "Themes")</li>
+3 -1
View File
@@ -17,7 +17,9 @@ You can download Rosalie's Mupen GUI on
## Support
Join the [Rosalie's Mupen GUI Discord Server](https://discord.gg/k9GuyJ2PpF) for support
You can ask for help or report issues on
* [Github](https://github.com/Rosalie241/RMG/issues/new)
* [Discord](https://discord.gg/k9GuyJ2PpF)
## License
+40
View File
@@ -0,0 +1,40 @@
#
# 7-Zip CMakeLists.txt
#
project(7Zip)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(7ZIP_SOURCES
${CMAKE_CURRENT_BINARY_DIR}/C/Bcj2.c
${CMAKE_CURRENT_BINARY_DIR}/C/Bra.c
${CMAKE_CURRENT_BINARY_DIR}/C/Bra86.c
${CMAKE_CURRENT_BINARY_DIR}/C/BraIA64.c
${CMAKE_CURRENT_BINARY_DIR}/C/CpuArch.c
${CMAKE_CURRENT_BINARY_DIR}/C/Delta.c
${CMAKE_CURRENT_BINARY_DIR}/C/Lzma2Dec.c
${CMAKE_CURRENT_BINARY_DIR}/C/LzmaDec.c
${CMAKE_CURRENT_BINARY_DIR}/C/Ppmd7.c
${CMAKE_CURRENT_BINARY_DIR}/C/Ppmd7Dec.c
${CMAKE_CURRENT_BINARY_DIR}/C/7zCrc.c
${CMAKE_CURRENT_BINARY_DIR}/C/7zCrcOpt.c
${CMAKE_CURRENT_BINARY_DIR}/C/Sha256.c
${CMAKE_CURRENT_BINARY_DIR}/C/Sha256Opt.c
${CMAKE_CURRENT_BINARY_DIR}/C/7zAlloc.c
${CMAKE_CURRENT_BINARY_DIR}/C/7zArcIn.c
${CMAKE_CURRENT_BINARY_DIR}/C/7zBuf.c
${CMAKE_CURRENT_BINARY_DIR}/C/7zBuf2.c
${CMAKE_CURRENT_BINARY_DIR}/C/7zDec.c
${CMAKE_CURRENT_BINARY_DIR}/C/7zFile.c
${CMAKE_CURRENT_BINARY_DIR}/C/7zStream.c
)
add_custom_command(
OUTPUT ${7ZIP_SOURCES}
COMMAND ${CMAKE_COMMAND} -E tar "xvz" "${CMAKE_CURRENT_SOURCE_DIR}/lzma2201.tar.gz"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
add_definitions(-D_7ZIP_PPMD_SUPPPORT -DNDEBUG -D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE)
add_library(7Zip STATIC ${7ZIP_SOURCES})
+2
View File
@@ -0,0 +1,2 @@
# 7-Zip SDK v22.01
Downloaded from https://www.7-zip.org/sdk.html
Binary file not shown.
+20 -35
View File
@@ -5,22 +5,12 @@ include(ExternalProject)
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 OFF)
else()
set(BUILD_INPUT_GCA ON)
endif()
set(M64P_CORE_DIR ${THIRDPARTY_DIR}/mupen64plus-core)
if(WIN32)
set(SO_EXT "dll")
set(GCA_LIB "mupen64plus_input_gca.${SO_EXT}")
set(CORE_FILE "mupen64plus.dll")
else(WIN32)
set(SO_EXT "so")
set(GCA_LIB "libmupen64plus_input_gca.${SO_EXT}")
set(CORE_FILE "libmupen64plus.so")
endif(WIN32)
@@ -37,7 +27,7 @@ endif(USE_CCACHE)
if(NOT NO_GIT_CLONE)
set(MUPEN64PLUSCORE_URL "https://github.com/mupen64plus/mupen64plus-core")
set(MUPEN64PLUSCORE_TAG "7ee312cb282a7794c62d5d284bf93151c585dd1f")
set(MUPEN64PLUSCORE_TAG "d4f3e12db0609158c7b4e0beef2bb950aad0ccb9")
set(MUPEN64PLUS_RSP_CXD4_URL "https://github.com/mupen64plus/mupen64plus-rsp-cxd4")
set(MUPEN64PLUS_RSP_CXD4_TAG "39f79201baa15890c4cbae92f2215a634cc3ee6d")
@@ -46,19 +36,19 @@ if(NOT NO_GIT_CLONE)
set(MUPEN64PLUS_RSP_HLE_TAG "88093cb43499eff53d343653cddcae2132af17ef")
set(MUPEN64PLUS_RSP_PARALLEL_URL "https://github.com/Rosalie241/parallel-rsp")
set(MUPEN64PLUS_RSP_PARALLEL_TAG "cfeea3a0f89ba5bc4265acb75778e1267ed1e424")
set(MUPEN64PLUS_RSP_PARALLEL_TAG "dbecbe3a120e428436c5972fa7b872cfc2c9db3e")
set(MUPEN64PLUS_INPUT_RAPHNET_URL "https://github.com/raphnet/mupen64plus-input-raphnetraw")
set(MUPEN64PLUS_INPUT_RAPHNET_TAG "86112413e98a8648edb11d199673cc24d5799af8")
set(MUPEN64PLUS_INPUT_GCA_URL "https://github.com/amatho/mupen64plus-input-gca")
set(MUPEN64PLUS_INPUT_GCA_TAG "21639fb13dfa797a7c0949ffd9bbda9a3456fc69")
set(MUPEN64PLUS_INPUT_GCN_URL "https://github.com/Rosalie241/mupen64plus-input-gcn")
set(MUPEN64PLUS_INPUT_GCN_TAG "e220115fa8ad223be783c822a251d7e0f873ed4c")
set(MUPEN64PLUS_GFX_ANGRYLION_URL "https://github.com/Rosalie241/angrylion-rdp-plus")
set(MUPEN64PLUS_GFX_ANGRYLION_TAG "158e74d4ec1c818289cd19c3a05e498c3ceff758")
set(MUPEN64PLUS_GFX_ANGRYLION_TAG "670abbc972bd430fa77291b0967dd73128314317")
set(MUPEN64PLUS_GFX_GLIDEN64_URL "https://github.com/Rosalie241/GLideN64")
set(MUPEN64PLUS_GFX_GLIDEN64_TAG "71dcb55a398a5c4d2bdbfa9fc15b90f301f77a6b")
set(MUPEN64PLUS_GFX_GLIDEN64_URL "https://github.com/gonetz/GLideN64")
set(MUPEN64PLUS_GFX_GLIDEN64_TAG "0fee30d010d1feda7d343654871b3dfd05ccab70")
set(MUPEN64PLUS_GFX_PARALLEL_URL "https://github.com/Rosalie241/parallel-rdp-standalone")
set(MUPEN64PLUS_GFX_PARALLEL_TAG "2c2226517c4c8929e08ec944654867e26efe0cf5")
@@ -70,7 +60,7 @@ if(NOT NO_GIT_CLONE)
set(IMGUI_TAG "d7c8516a4b848c0291e3d75b627c0843f515f591")
set(SDL_GAMECONTROLLERDB_URL "https://github.com/gabomdq/SDL_GameControllerDB")
set(SDL_GAMECONTROLLERDB_TAG "0562b00eaf5c0308c49d329b79263d2dae1c3a85")
set(SDL_GAMECONTROLLERDB_TAG "b7e5701da82fc97beeede64d3818ef0f4d015aba")
endif(NOT NO_GIT_CLONE)
ExternalProject_Add(mupen64plus-core
@@ -161,23 +151,20 @@ ExternalProject_Add(mupen64plus-input-raphnetraw
DEPENDS mupen64plus-core
)
if (BUILD_INPUT_GCA)
ExternalProject_Add(mupen64plus-input-gca
SOURCE_DIR mupen64plus-input-gca/
ExternalProject_Add(mupen64plus-input-gcn
SOURCE_DIR mupen64plus-input-gcn
CONFIGURE_COMMAND ""
INSTALL_COMMAND ""
GIT_REPOSITORY ${MUPEN64PLUS_INPUT_GCN_URL}
GIT_TAG ${MUPEN64PLUS_INPUT_GCN_TAG}
GIT_REPOSITORY ${MUPEN64PLUS_INPUT_GCA_URL}
GIT_TAG ${MUPEN64PLUS_INPUT_GCA_TAG}
INSTALL_COMMAND ""
BUILD_COMMAND cargo build --release --features "m64p_compat"
BUILD_IN_SOURCE True
BUILD_IN_SOURCE True
CMAKE_ARGS ${CMAKE_CONFIGURE_ARGS}
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-input-gca/target/release/${GCA_LIB}
DEPENDS mupen64plus-core
)
endif(BUILD_INPUT_GCA)
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-input-gcn/mupen64plus-input-gcn.${SO_EXT}
DEPENDS mupen64plus-core
)
set(GLIDEN64_DIR "${THIRDPARTY_DIR}/mupen64plus-video-GLideN64")
set(GLIDEN64_BUILD_DIR "${GLIDEN64_DIR}/projects/cmake")
@@ -326,10 +313,8 @@ 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)
ExternalProject_Get_property(mupen64plus-input-gca BUILD_BYPRODUCTS)
set(MUPEN64PLUS_PLUGIN_INPUT_GCA ${BUILD_BYPRODUCTS} PARENT_SCOPE)
endif(BUILD_INPUT_GCA)
ExternalProject_Get_property(mupen64plus-input-gcn BUILD_BYPRODUCTS)
set(MUPEN64PLUS_PLUGIN_INPUT_GCN ${BUILD_BYPRODUCTS} PARENT_SCOPE)
ExternalProject_Get_property(mupen64plus-video-angrylion-plus BUILD_BYPRODUCTS)
set(MUPEN64PLUS_PLUGIN_GFX_ANGRYLION ${BUILD_BYPRODUCTS} PARENT_SCOPE)
+1 -1
View File
@@ -55,5 +55,5 @@ Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall
+1
View File
@@ -80,6 +80,7 @@ endif(WIN32)
target_link_libraries(RMG-Core
${MINIZIP_LIBRARIES}
7Zip
)
if (DISCORD_RPC)
+26 -2
View File
@@ -36,11 +36,13 @@
#define ROMHEADER_NAME_LEN 256
#define GOODNAME_LEN 256
#define MD5_LEN 33
#define GAMEID_LEN 5
#define REGION_LEN 18
#ifdef _WIN32
#define CACHE_FILE_MAGIC "RMGCoreHeaderAndSettingsCacheWindows_05"
#define CACHE_FILE_MAGIC "RMGCoreHeaderAndSettingsCacheWindows_06"
#else // Linux
#define CACHE_FILE_MAGIC "RMGCoreHeaderAndSettingsCacheLinux_05"
#define CACHE_FILE_MAGIC "RMGCoreHeaderAndSettingsCacheLinux_06"
#endif // _WIN32
#define CACHE_FILE_ITEMS_MAX 10000
@@ -103,6 +105,8 @@ void CoreReadRomHeaderAndSettingsCache(void)
char magicBuf[sizeof(CACHE_FILE_MAGIC)];
wchar_t fileNameBuf[MAX_FILENAME_LEN];
char headerNameBuf[ROMHEADER_NAME_LEN];
char gameIDBuf[GAMEID_LEN];
char regionBuf[REGION_LEN];
char goodNameBuf[GOODNAME_LEN];
char md5Buf[MD5_LEN];
uint32_t size;
@@ -131,6 +135,8 @@ void CoreReadRomHeaderAndSettingsCache(void)
size = 0;
memset(fileNameBuf, 0, sizeof(fileNameBuf));
memset(headerNameBuf, 0, sizeof(headerNameBuf));
memset(gameIDBuf, 0, sizeof(gameIDBuf));
memset(regionBuf, 0, sizeof(regionBuf));
memset(goodNameBuf, 0, sizeof(goodNameBuf));
memset(md5Buf, 0, sizeof(md5Buf));
@@ -144,7 +150,13 @@ void CoreReadRomHeaderAndSettingsCache(void)
// header
FREAD(size);
FREAD_STR(headerNameBuf, size);
FREAD(size);
FREAD_STR(gameIDBuf, size);
FREAD(size);
FREAD_STR(regionBuf, size);
cacheEntry.header.Name = std::string(headerNameBuf);
cacheEntry.header.GameID = std::string(gameIDBuf);
cacheEntry.header.Region = std::string(regionBuf);
FREAD(cacheEntry.header.CRC1);
FREAD(cacheEntry.header.CRC2);
// (partial) settings
@@ -169,6 +181,8 @@ bool CoreSaveRomHeaderAndSettingsCache(void)
std::ofstream outputStream;
wchar_t fileNameBuf[MAX_FILENAME_LEN];
char headerNameBuf[ROMHEADER_NAME_LEN];
char gameIDBuf[GAMEID_LEN];
char regionBuf[REGION_LEN];
char goodNameBuf[GOODNAME_LEN];
char md5Buf[MD5_LEN];
uint32_t size;
@@ -200,12 +214,16 @@ bool CoreSaveRomHeaderAndSettingsCache(void)
size = 0;
memset(fileNameBuf, 0, sizeof(fileNameBuf));
memset(headerNameBuf, 0, sizeof(headerNameBuf));
memset(gameIDBuf, 0, sizeof(gameIDBuf));
memset(regionBuf, 0, sizeof(regionBuf));
memset(goodNameBuf, 0, sizeof(goodNameBuf));
memset(md5Buf, 0, sizeof(md5Buf));
// copy strings into buffers
wcsncpy(fileNameBuf, cacheEntry.fileName.wstring().c_str(), MAX_FILENAME_LEN);
strncpy(headerNameBuf, cacheEntry.header.Name.c_str(), sizeof(headerNameBuf));
strncpy(gameIDBuf, cacheEntry.header.GameID.c_str(), sizeof(gameIDBuf));
strncpy(regionBuf, cacheEntry.header.Region.c_str(), sizeof(regionBuf));
strncpy(goodNameBuf, cacheEntry.settings.GoodName.c_str(), sizeof(goodNameBuf));
strncpy(md5Buf, cacheEntry.settings.MD5.c_str(), sizeof(md5Buf));
@@ -220,6 +238,12 @@ bool CoreSaveRomHeaderAndSettingsCache(void)
size = cacheEntry.header.Name.size();
FWRITE(size);
FWRITE_STR(headerNameBuf, size);
size = cacheEntry.header.GameID.size();
FWRITE(size);
FWRITE_STR(gameIDBuf, size);
size = cacheEntry.header.Region.size();
FWRITE(size);
FWRITE_STR(regionBuf, size);
FWRITE(cacheEntry.header.CRC1);
FWRITE(cacheEntry.header.CRC2);
// (partial) settings
+23 -2
View File
@@ -11,12 +11,16 @@
#include "Core.hpp"
#include "ConvertStringEncoding.hpp"
#include <iostream>
//
// Local Variables
//
static bool l_SetupCallbacks = false;
static std::function<void(enum CoreDebugMessageType, std::string, std::string)> l_DebugCallbackFunc;
static std::function<void(enum CoreStateCallbackType, int)> l_StateCallbackFunc;
static bool l_PrintCallbacks = false;
//
// Internal Functions
@@ -42,21 +46,38 @@ void CoreDebugCallback(void* context, int level, const char* message)
messageString = CoreConvertStringEncoding(message, CoreStringEncoding::Shift_JIS);
}
if (l_PrintCallbacks)
{
std::cout << contextString << messageString << std::endl;
}
l_DebugCallbackFunc((CoreDebugMessageType)level, contextString, messageString);
}
void CoreStateCallback(void* context, m64p_core_param param, int value)
{
// TODO
if (!l_SetupCallbacks)
{
return;
}
l_StateCallbackFunc((CoreStateCallbackType)param, value);
}
//
// Exported Functions
//
bool CoreSetupCallbacks(std::function<void(enum CoreDebugMessageType, std::string, std::string)> debugCallbackFunc)
bool CoreSetupCallbacks(std::function<void(enum CoreDebugMessageType, std::string, std::string)> debugCallbackFunc,
std::function<void(enum CoreStateCallbackType, int)> stateCallbackFunc)
{
l_DebugCallbackFunc = debugCallbackFunc;
l_StateCallbackFunc = stateCallbackFunc;
l_SetupCallbacks = true;
return true;
}
void CoreSetPrintDebugCallback(bool enabled)
{
l_PrintCallbacks = enabled;
}
+21 -1
View File
@@ -32,6 +32,26 @@ enum class CoreDebugMessageType
Verbose = 5
};
bool CoreSetupCallbacks(std::function<void(enum CoreDebugMessageType, std::string, std::string)> debugCallbackFunc);
enum class CoreStateCallbackType
{
EmulationState = 1,
VideoMode,
SaveStateSlot,
SpeedFactor,
SpeedLimiter,
VideoSize,
AudioVolume,
AudioMute,
GamesharkInput,
SaveStateLoaded,
SaveStateSaved,
};
// attempts to setup callbacks with the provided functions
bool CoreSetupCallbacks(std::function<void(enum CoreDebugMessageType, std::string, std::string)> debugCallbackFunc,
std::function<void(enum CoreStateCallbackType, int)> stateCallbackFunc);
// sets whether the debug callbacks will be printed to stdout
void CoreSetPrintDebugCallback(bool enabled);
#endif // CORE_CALLBACK_HPP
+1
View File
@@ -54,6 +54,7 @@ static void apply_coresettings_overlay(void)
CoreSettingsSetValue(SettingsID::Core_CountPerOp, CoreSettingsGetIntValue(SettingsID::CoreOverlay_CountPerOp));
CoreSettingsSetValue(SettingsID::Core_CountPerOpDenomPot, CoreSettingsGetIntValue(SettingsID::CoreOverlay_CountPerOpDenomPot));
CoreSettingsSetValue(SettingsID::Core_SiDmaDuration, CoreSettingsGetIntValue(SettingsID::CoreOverlay_SiDmaDuration));
CoreSettingsSetValue(SettingsID::Core_SaveFileNameFormat, CoreSettingsGetIntValue(SettingsID::CoreOverLay_SaveFileNameFormat));
}
static void apply_game_coresettings_overlay(void)
+91 -38
View File
@@ -285,6 +285,78 @@ bool apply_plugin_settings(std::string pluginSettings[4])
return true;
}
bool open_plugin_config(CorePluginType type, bool romConfig)
{
std::string error;
m64p_error ret;
bool resumeEmulation = false;
m64p::PluginApi* plugin;
std::string functionName;
if (!romConfig && !CorePluginsHasConfig(type))
{
error = "open_plugin_config Failed: ";
error += get_plugin_type_name(type);
error += " doesn't have the config or config2 function!";
CoreSetError(error);
return false;
}
else if (romConfig && !CorePluginsHasROMConfig(type))
{
error = "open_plugin_config Failed: ";
error += get_plugin_type_name(type);
error += " doesn't support ROM specific configuration!";
CoreSetError(error);
return false;
}
// try to pause emulation,
// when emulation is running
// and try to resume afterwards
if (CoreIsEmulationRunning())
{
// only resume emulation
// after running the config function
// when pausing succeeds
resumeEmulation = CorePauseEmulation();
}
plugin = get_plugin(type);
// check if the plugin has the Config2
// or Config function, the Config2 function
// has priority
if (plugin->Config2 != nullptr)
{
ret = plugin->Config2(romConfig ? 1 : 0);
functionName = "Config2";
}
else
{
ret = plugin->Config();
functionName = "Config";
}
if (ret != M64ERR_SUCCESS)
{
error = "CorePluginsOpenConfig (";
error += get_plugin_type_name(type);
error += ")->";
error += functionName;
error += "() Failed: ";
error += m64p::Core.ErrorMessage(ret);
CoreSetError(error);
}
// try to resume emulation when needed
if (resumeEmulation)
{
CoreResumeEmulation();
}
return ret == M64ERR_SUCCESS;
}
//
// Exported Functions
//
@@ -384,52 +456,33 @@ bool CoreArePluginsReady(void)
bool CorePluginsHasConfig(CorePluginType type)
{
return get_plugin(type)->Config != nullptr;
m64p::PluginApi* plugin;
plugin = get_plugin(type);
return plugin->Config != nullptr ||
plugin->Config2 != nullptr;
}
bool CorePluginsOpenConfig(CorePluginType type)
{
std::string error;
m64p_error ret;
bool resumeEmulation = false;
return open_plugin_config(type, false);
}
if (!CorePluginsHasConfig(type))
{
error = "CorePluginsOpenConfig Failed: ";
error += get_plugin_type_name(type);
error += " doesn't have config function!";
CoreSetError(error);
return false;
}
bool CorePluginsHasROMConfig(CorePluginType type)
{
m64p::PluginApi* plugin;
// try to pause emulation,
// when emulation is running
// and try to resume afterwards
if (CoreIsEmulationRunning())
{
// only resume emulation
// after running the config function
// when pausing succeeds
resumeEmulation = CorePauseEmulation();
}
plugin = get_plugin(type);
ret = get_plugin(type)->Config();
if (ret != M64ERR_SUCCESS)
{
error = "CorePluginsOpenConfig (";
error += get_plugin_type_name(type);
error += ")->Config() Failed: ";
error += m64p::Core.ErrorMessage(ret);
CoreSetError(error);
}
return plugin->Config2 != nullptr &&
plugin->Config2HasRomConfig != nullptr &&
plugin->Config2HasRomConfig() > 0;
}
// try to resume emulation when needed
if (resumeEmulation)
{
CoreResumeEmulation();
}
return ret == M64ERR_SUCCESS;
bool CorePluginsOpenROMConfig(CorePluginType type)
{
return open_plugin_config(type, true);
}
bool CoreAttachPlugins(void)
+8
View File
@@ -52,6 +52,14 @@ bool CorePluginsHasConfig(CorePluginType type);
// used plugin of given type
bool CorePluginsOpenConfig(CorePluginType type);
// returns wether the currently used plugin
// of the given type has a ROM config GUI
bool CorePluginsHasROMConfig(CorePluginType type);
// opens the ROM config GUI for the currently
// used plugin of given type
bool CorePluginsOpenROMConfig(CorePluginType type);
// attaches all used plugins
bool CoreAttachPlugins(void);
+174 -5
View File
@@ -16,6 +16,16 @@
#include "Cheats.hpp"
#include "osal/osal_files.hpp"
// 7-Zip includes
#include "../3rdParty/7-Zip/C/7zTypes.h"
#include "../3rdParty/7-Zip/C/7z.h"
#include "../3rdParty/7-Zip/C/7zAlloc.h"
#include "../3rdParty/7-Zip/C/7zBuf.h"
#include "../3rdParty/7-Zip/C/7zCrc.h"
#include "../3rdParty/7-Zip/C/7zFile.h"
#include "../3rdParty/7-Zip/C/7zVersion.h"
#include <string>
#include <unzip.h>
#include <fstream>
#include <cstdlib>
@@ -140,7 +150,7 @@ static bool read_zip_file(std::filesystem::path file, std::filesystem::path* ext
filefuncs.zclose_file = zlib_filefunc_close;
filefuncs.zerror_file = zlib_filefunc_testerror;
filefuncs.opaque = nullptr;
zipFile = unzOpen2_64((const void*)&file, &filefuncs);
if (zipFile == nullptr)
{
@@ -293,6 +303,155 @@ static bool read_zip_file(std::filesystem::path file, std::filesystem::path* ext
return false;
}
static bool read_7zip_file(std::filesystem::path file, std::filesystem::path* extractedFileName, bool* isDisk, char** buf, int* size)
{
std::string error;
const ISzAlloc alloc = { SzAlloc, SzFree };
const size_t bufSize = ((size_t)1 << 18);
ISzAlloc allocImp;
ISzAlloc allocTempImp;
CFileInStream archiveStream;
CLookToRead2 lookStream;
CSzArEx db;
SRes res;
// initialize allocator
allocImp = alloc;
allocTempImp = alloc;
// try to open file
#ifdef _WIN32
WRes wres = InFile_OpenW(&archiveStream.file, file.wstring().c_str());
#else
WRes wres = InFile_Open(&archiveStream.file, file.string().c_str());
#endif // _WIN32
if (wres != 0)
{
error = "read_7zip_file Failed: InFile_Open Failed: ";
error += std::to_string(wres);
CoreSetError(error);
return false;
}
// create vtables for streams
FileInStream_CreateVTable(&archiveStream);
archiveStream.wres = 0;
LookToRead2_CreateVTable(&lookStream, 0);
lookStream.buf = nullptr;
// allocate memory look reader
lookStream.buf = (Byte*)ISzAlloc_Alloc(&allocImp, bufSize);
if (lookStream.buf == nullptr)
{
error = "read_7zip_file Failed: ISzAlloc_Alloc Failed!";
CoreSetError(error);
return false;
}
// initialize look reader
lookStream.bufSize = bufSize;
lookStream.realStream = &archiveStream.vt;
LookToRead2_Init(&lookStream);
// initialize CRC table
CrcGenerateTable();
// initialize archive
SzArEx_Init(&db);
// try to open file
res = SzArEx_Open(&db, &lookStream.vt, &allocImp, &allocTempImp);
if (res != SZ_OK)
{
error = "read_7zip_file Failed: SzArEx_Open Failed: ";
error += std::to_string(res);
CoreSetError(error);
SzArEx_Free(&db, &allocImp);
ISzAlloc_Free(&allocImp, lookStream.buf);
return false;
}
for (int i = 0; i < db.NumFiles; i++)
{
size_t filename_size = 0;
uint16_t fileName[PATH_MAX];
// skip directories
if (SzArEx_IsDir(&db, i))
{
continue;
}
// skip when filename size exceeds our buffer size
filename_size = SzArEx_GetFileNameUtf16(&db, i, nullptr);
if (filename_size > PATH_MAX)
{
continue;
}
SzArEx_GetFileNameUtf16(&db, i, fileName);
std::filesystem::path fileNamePath((char16_t*)fileName);
std::string fileExtension = fileNamePath.has_extension() ? fileNamePath.extension().string() : "";
fileExtension = to_lower_str(fileExtension);
if (fileExtension == ".z64" ||
fileExtension == ".v64" ||
fileExtension == ".n64" ||
fileExtension == ".ndd" ||
fileExtension == ".d64")
{
uint32_t blockIndex = 0xFFFFFFFF;
uint8_t* outBuffer = nullptr;
size_t outBufferSize = 0;
size_t offset = 0;
size_t outSizeProcessed = 0;
res = SzArEx_Extract(&db, &lookStream.vt, i,
&blockIndex, &outBuffer, &outBufferSize,
&offset, &outSizeProcessed,
&allocImp, &allocTempImp);
if (res != SZ_OK)
{
error = "read_7zip_file Failed: SzArEx_Extract Failed: ";
error += std::to_string(res);
CoreSetError(error);
SzArEx_Free(&db, &allocImp);
ISzAlloc_Free(&allocImp, lookStream.buf);
File_Close(&archiveStream.file);
ISzAlloc_Free(&allocImp, outBuffer);
return false;
}
*size = outSizeProcessed;
// we have to memcpy it into buf, otherwise
// the free() in CoreOpenRom() crashes
*buf = (char*)malloc(outSizeProcessed);
memcpy(*buf, (outBuffer + offset), outSizeProcessed);
*extractedFileName = fileNamePath;
*isDisk = (fileExtension == ".ndd" || fileExtension == ".d64");
SzArEx_Free(&db, &allocImp);
ISzAlloc_Free(&allocImp, lookStream.buf);
File_Close(&archiveStream.file);
ISzAlloc_Free(&allocImp, outBuffer);
return true;
}
}
// cleanup
SzArEx_Free(&db, &allocImp);
ISzAlloc_Free(&allocImp, lookStream.buf);
File_Close(&archiveStream.file);
error = "read_7zip_file Failed: no valid ROMs found in 7zip!";
CoreSetError(error);
return false;
}
static bool read_raw_file(std::filesystem::path file, char** buf, int* size)
{
std::string error;
@@ -362,7 +521,6 @@ static bool write_file(std::filesystem::path file, char* buf, int size)
// write buffer to file
fileStream.write(buf, size);
fileStream.close();
return true;
}
@@ -395,14 +553,25 @@ bool CoreOpenRom(std::filesystem::path file)
file_extension = file.has_extension() ? file.extension().string() : "";
file_extension = to_lower_str(file_extension);
if (file_extension == ".zip")
if (file_extension == ".zip" ||
file_extension == ".7z")
{
std::filesystem::path extracted_file;
bool is_disk = false;
if (!read_zip_file(file, &extracted_file, &is_disk, &buf, &buf_size))
if (file_extension == ".zip")
{
return false;
if (!read_zip_file(file, &extracted_file, &is_disk, &buf, &buf_size))
{
return false;
}
}
else
{
if (!read_7zip_file(file, &extracted_file, &is_disk, &buf, &buf_size))
{
return false;
}
}
if (is_disk)
+94 -1
View File
@@ -21,6 +21,97 @@
#include "Error.hpp"
#include "Rom.hpp"
//
// Local Functions
//
static std::string get_gameid_from_header(m64p_rom_header header)
{
std::string gameID;
if (header.Manufacturer_ID == 0)
{
return "????";
}
gameID.push_back(char(ntohl(header.Manufacturer_ID)));
gameID.push_back(char(header.Cartridge_ID % 256));
gameID.push_back(char(header.Cartridge_ID / 256));
gameID.push_back(char(header.Country_code));
return gameID;
}
static std::string get_region_from_countrycode(char countryCode)
{
std::string region;
switch (countryCode)
{
case 'A':
region = "Region-Free";
break;
case 'B':
region = "Brazil";
break;
case 'C':
region = "China";
break;
case 'D':
region = "Germany";
break;
case 'E':
region = "North America";
break;
case 'F':
region = "France";
break;
case 'G':
region = "Gateway 64 (NTSC)";
break;
case 'H':
region = "Netherlands";
break;
case 'I':
region = "Italy";
break;
case 'J':
region = "Japan";
break;
case 'K':
region = "Korea";
break;
case 'L':
region = "Gateway 64 (PAL)";
break;
case 'N':
region = "Canada";
break;
case 'P':
case 'X':
region = "Europe/Australia";
break;
case 'S':
region = "Spain";
break;
case 'U':
region = "Australia";
break;
case 'W':
region = "Scandanavia";
break;
case 'Y':
case 'Z':
region = "Europe";
break;
default:
region = "Unknown";
break;
}
return region;
}
//
// Exported Functions
//
@@ -49,6 +140,8 @@ bool CoreGetCurrentRomHeader(CoreRomHeader& header)
header.CRC2 = ntohl(m64p_header.CRC2);
header.CountryCode = m64p_header.Country_code;
header.Name = CoreConvertStringEncoding((char*)m64p_header.Name, CoreStringEncoding::Shift_JIS);
header.GameID = get_gameid_from_header(m64p_header);
header.Region = get_region_from_countrycode((char)header.CountryCode);
return true;
}
+2
View File
@@ -19,6 +19,8 @@ struct CoreRomHeader
uint32_t CRC2;
uint32_t CountryCode;
std::string Name;
std::string GameID;
std::string Region;
};
// retrieves the currently opened ROM header
+109
View File
@@ -8,10 +8,33 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "SaveState.hpp"
#include "Directories.hpp"
#include "RomSettings.hpp"
#include "RomHeader.hpp"
#include "Error.hpp"
#include "Settings/Settings.hpp"
#include "m64p/Api.hpp"
#include <algorithm>
//
// Local Functions
//
// replaces all occurences of any chars in replace with c inside str
static void str_replace_chars(std::string& str, const std::string replace, const char c)
{
for (int i = 0; i < str.size(); i++)
{
char str_char = str.at(i);
if (replace.find(str_char) != std::string::npos)
{
str.at(i) = c;
}
}
}
//
// Exported Functions
//
@@ -59,6 +82,92 @@ int CoreGetSaveStateSlot(void)
return slot;
}
bool CoreGetSaveStatePath(int slot, std::filesystem::path& path)
{
// TODO: this should probably be an API function
// in mupen64plus-core instead
std::filesystem::path saveStatePath;
std::filesystem::path oldSaveStatePath;
std::string saveStateFileName;
std::filesystem::path saveStateExtension;
CoreRomHeader romHeader;
CoreRomSettings romSettings;
// attempt to retrieve the current
// rom header and settings
if (!CoreGetCurrentRomHeader(romHeader) ||
!CoreGetCurrentRomSettings(romSettings))
{
return false;
}
// retrieve save state directory
saveStatePath = CoreGetSaveStateDirectory();
saveStatePath += "/";
// construct extension
saveStateExtension = ".st";
saveStateExtension += std::to_string(slot);
// construct old save state path
oldSaveStatePath = saveStatePath;
oldSaveStatePath += romSettings.GoodName;
oldSaveStatePath += saveStateExtension;
// use old filename if it exists
if (std::filesystem::is_regular_file(oldSaveStatePath))
{
path = oldSaveStatePath;
return true;
}
// else use new filename
int format = CoreSettingsGetIntValue(SettingsID::Core_SaveFileNameFormat);
if (format == 0)
{
saveStatePath += romHeader.Name;
saveStatePath += saveStateExtension;
}
else
{
if (romSettings.GoodName.find("(unknown rom)") == std::string::npos)
{
if (romSettings.GoodName.size() < 32)
{
saveStatePath += romSettings.GoodName;
}
else
{
saveStatePath += romSettings.GoodName.substr(0, 32);
}
}
else if (!romHeader.Name.empty())
{
saveStatePath += romHeader.Name;
}
else
{
saveStatePath += "unknown";
}
saveStatePath += "-";
saveStatePath += romSettings.MD5.substr(0, 8);
saveStatePath += saveStateExtension;
}
// retrieve filename from path
saveStateFileName = saveStatePath.filename().string();
// sanitize filename
str_replace_chars(saveStateFileName, ":<>\"/\\|?*", '_');
// replace filename in path
saveStatePath.replace_filename(saveStateFileName);
path = saveStatePath;
return true;
}
bool CoreSaveState(void)
{
std::string error;
+4
View File
@@ -19,6 +19,10 @@ bool CoreSetSaveStateSlot(int slot);
// returns -1 on error
int CoreGetSaveStateSlot(void);
// retrieves the file path for
// the save state in the given slot
bool CoreGetSaveStatePath(int slot, std::filesystem::path& path);
// saves state
bool CoreSaveState(void);
+35 -2
View File
@@ -183,6 +183,9 @@ static l_Setting get_setting(SettingsID settingId)
case SettingsID::GUI_Toolbar:
setting = {SETTING_SECTION_GUI, "Toolbar", true};
break;
case SettingsID::GUI_ToolbarArea:
setting = {SETTING_SECTION_GUI, "ToolbarArea", 0};
break;
case SettingsID::GUI_StatusBar:
setting = {SETTING_SECTION_GUI, "StatusBar", true};
break;
@@ -195,6 +198,9 @@ static l_Setting get_setting(SettingsID settingId)
case SettingsID::GUI_CheckForUpdates:
setting = {SETTING_SECTION_GUI, "CheckForUpdates", true};
break;
case SettingsID::GUI_LastUpdateCheck:
setting = {SETTING_SECTION_GUI, "LastUpdateCheck", ""};
break;
case SettingsID::GUI_DiscordRpc:
setting = {SETTING_SECTION_GUI, "DiscordRpc", true};
break;
@@ -274,6 +280,9 @@ static l_Setting get_setting(SettingsID settingId)
case SettingsID::Core_SiDmaDuration:
setting = {SETTING_SECTION_M64P, "SiDmaDuration", -1};
break;
case SettingsID::Core_SaveFileNameFormat:
setting = {SETTING_SECTION_M64P, "SaveFilenameFormat", 1};
break;
case SettingsID::CoreOverlay_RandomizeInterrupt:
setting = {SETTING_SECTION_OVERLAY, "RandomizeInterrupt", true};
@@ -296,6 +305,9 @@ static l_Setting get_setting(SettingsID settingId)
case SettingsID::CoreOverlay_SiDmaDuration:
setting = {SETTING_SECTION_OVERLAY, "SiDmaDuration", -1};
break;
case SettingsID::CoreOverLay_SaveFileNameFormat:
setting = {SETTING_SECTION_OVERLAY, "SaveFilenameFormat", 1};
break;
case SettingsID::Core_ScreenshotPath:
setting = {SETTING_SECTION_M64P, "ScreenshotPath", CoreGetDefaultScreenshotDirectory(), "", true};
@@ -507,6 +519,21 @@ static l_Setting get_setting(SettingsID settingId)
case SettingsID::KeyBinding_Fullscreen:
setting = {SETTING_SECTION_KEYBIND, "Fullscreen", "Alt+Return"};
break;
case SettingsID::Keybinding_ViewLog:
setting = {SETTING_SECTION_KEYBIND, "ViewLog", "Ctrl+L"};
break;
case SettingsID::KeyBinding_GraphicsSettings:
setting = {SETTING_SECTION_KEYBIND, "GraphicsSettings", "Ctrl+G"};
break;
case SettingsID::KeyBinding_AudioSettings:
setting = {SETTING_SECTION_KEYBIND, "AudioSettings", "Ctrl+A"};
break;
case SettingsID::KeyBinding_RspSettings:
setting = {SETTING_SECTION_KEYBIND, "RspSettings", "Ctrl+R"};
break;
case SettingsID::KeyBinding_InputSettings:
setting = {SETTING_SECTION_KEYBIND, "InputSettings", "Ctrl+I"};
break;
case SettingsID::KeyBinding_Settings:
setting = {SETTING_SECTION_KEYBIND, "Settings", "Ctrl+T"};
break;
@@ -526,11 +553,14 @@ static l_Setting get_setting(SettingsID settingId)
case SettingsID::RomBrowser_MaxItems:
setting = {SETTING_SECTION_ROMBROWSER, "MaxItems", 250};
break;
case SettingsID::RomBrowser_ColumnVisibility:
setting = {SETTING_SECTION_ROMBROWSER, "ColumnVisibility", std::vector<int>({1, 1, 1, 0, 0, 0, 0, 0, 0})};
break;
case SettingsID::RomBrowser_ColumnOrder:
setting = {SETTING_SECTION_ROMBROWSER, "ColumnOrder", std::vector<int>({0, 1, 2})};
setting = {SETTING_SECTION_ROMBROWSER, "ColumnOrder", std::vector<int>({0, 1, 2, 3, 4, 5, 6, 7, 8})};
break;
case SettingsID::RomBrowser_ColumnSizes:
setting = {SETTING_SECTION_ROMBROWSER, "ColumnSizes", std::vector<int>({-1, -1, -1})};
setting = {SETTING_SECTION_ROMBROWSER, "ColumnSizes", std::vector<int>({-1, -1, -1, -1, -1, -1, -1, -1, -1})};
break;
case SettingsID::RomBrowser_SortAfterSearch:
setting = {SETTING_SECTION_ROMBROWSER, "SortAfterSearch", true};
@@ -610,6 +640,9 @@ static l_Setting get_setting(SettingsID settingId)
case SettingsID::Input_Deadzone:
setting = {"", "Deadzone"};
break;
case SettingsID::Input_Sensitivity:
setting = {"", "Sensitivity"};
break;
case SettingsID::Input_Pak:
setting = {"", "Pak"};
break;
+11
View File
@@ -20,10 +20,12 @@ enum class SettingsID
GUI_OnScreenDisplayOpacity,
GUI_OnScreenDisplayDuration,
GUI_Toolbar,
GUI_ToolbarArea,
GUI_StatusBar,
GUI_Theme,
GUI_IconTheme,
GUI_CheckForUpdates,
GUI_LastUpdateCheck,
GUI_DiscordRpc,
GUI_Version,
@@ -63,6 +65,7 @@ enum class SettingsID
Core_CountPerOp,
Core_CountPerOpDenomPot,
Core_SiDmaDuration,
Core_SaveFileNameFormat,
// (mupen64plus) Overlay Core Settings
CoreOverlay_RandomizeInterrupt,
@@ -72,6 +75,7 @@ enum class SettingsID
CoreOverlay_CountPerOp,
CoreOverlay_CountPerOpDenomPot,
CoreOverlay_SiDmaDuration,
CoreOverLay_SaveFileNameFormat,
// (mupen64plus) Core Directory Settings
Core_ScreenshotPath,
@@ -138,6 +142,11 @@ enum class SettingsID
KeyBinding_SaveStateSlot8,
KeyBinding_SaveStateSlot9,
KeyBinding_Fullscreen,
Keybinding_ViewLog,
KeyBinding_GraphicsSettings,
KeyBinding_AudioSettings,
KeyBinding_RspSettings,
KeyBinding_InputSettings,
KeyBinding_Settings,
// RomBrowser Settings
@@ -146,6 +155,7 @@ enum class SettingsID
RomBrowser_Maximized,
RomBrowser_Recursive,
RomBrowser_MaxItems,
RomBrowser_ColumnVisibility,
RomBrowser_ColumnOrder,
RomBrowser_ColumnSizes,
RomBrowser_SortAfterSearch,
@@ -179,6 +189,7 @@ enum class SettingsID
Input_DeviceName,
Input_DeviceNum,
Input_Deadzone,
Input_Sensitivity,
Input_Pak,
Input_GameboyRom,
Input_GameboySave,
+4
View File
@@ -28,6 +28,8 @@ bool PluginApi::Hook(m64p_dynlib_handle handle)
HOOK_FUNC(handle, Plugin, Startup);
HOOK_FUNC(handle, Plugin, Shutdown);
HOOK_FUNC_OPT(handle, Plugin, Config);
HOOK_FUNC_OPT(handle, Plugin, Config2);
HOOK_FUNC_OPT(handle, Plugin, Config2HasRomConfig);
HOOK_FUNC(handle, Plugin, GetVersion);
this->handle = handle;
@@ -40,6 +42,8 @@ bool PluginApi::Unhook(void)
UNHOOK_FUNC(Plugin, Startup);
UNHOOK_FUNC(Plugin, Shutdown);
UNHOOK_FUNC(Plugin, Config);
UNHOOK_FUNC(Plugin, Config2);
UNHOOK_FUNC(Plugin, Config2HasRomConfig);
UNHOOK_FUNC(Plugin, GetVersion);
this->handle = nullptr;
+2
View File
@@ -34,6 +34,8 @@ class PluginApi
ptr_PluginStartup Startup;
ptr_PluginShutdown Shutdown;
ptr_PluginConfig Config;
ptr_PluginConfig2 Config2;
ptr_PluginConfig2HasRomConfig Config2HasRomConfig;
ptr_PluginGetVersion GetVersion;
private:
+23
View File
@@ -21,6 +21,29 @@ typedef m64p_error (*ptr_PluginConfig)(void);
EXPORT m64p_error CALL PluginConfig(void);
#endif
/* PluginConfig2(int romConfig)
*
* This optional function opens a configuration GUI for the plugin
* https://github.com/mupen64plus/mupen64plus-core/pull/774
*
* romConfig argument determines if it should open the ROM specific config
*/
typedef m64p_error (*ptr_PluginConfig2)(int);
#if defined(M64P_PLUGIN_PROTOTYPES) || defined(M64P_CORE_PROTOTYPES)
EXPORT m64p_error CALL PluginConfig2(int);
#endif
/* PluginConfig2HasRomConfig(void)
*
* This optional function returns wether the plugin supports ROM specific config
* using PluginConfig2
*
*/
typedef int (*ptr_PluginConfig2HasRomConfig)(void);
#if defined(M64P_PLUGIN_PROTOTYPES) || defined(M64P_CORE_PROTOTYPES)
EXPORT int CALL PluginConfig2HasRomConfig(void);
#endif
#ifdef __cplusplus
}
#endif
@@ -18,7 +18,7 @@
using namespace UserInterface;
MainDialog::MainDialog(QWidget* parent, Thread::SDLThread* sdlThread) : QDialog(parent)
MainDialog::MainDialog(QWidget* parent, Thread::SDLThread* sdlThread, bool romConfig) : QDialog(parent)
{
this->setupUi(this);
this->setWindowIcon(QIcon(":Resource/RMG.png"));
@@ -41,6 +41,7 @@ MainDialog::MainDialog(QWidget* parent, Thread::SDLThread* sdlThread) : QDialog(
for (int i = 0; i < this->tabWidget->count(); i++)
{
Widget::ControllerWidget* widget = new Widget::ControllerWidget(this, this->eventFilter);
widget->SetOnlyLoadGameProfile(romConfig);
widget->SetSettingsSection("Player " + QString::number(i + 1), "Rosalie's Mupen GUI - Input Plugin Profile " + QString::number(i));
widget->LoadSettings();
this->tabWidget->widget(i)->layout()->addWidget(widget);
@@ -59,7 +59,7 @@ private:
void closeInputDevice();
public:
MainDialog(QWidget *parent, Thread::SDLThread*);
MainDialog(QWidget *parent, Thread::SDLThread*, bool);
~MainDialog(void);
public slots:
@@ -10,8 +10,8 @@
#include "ControllerImageWidget.hpp"
#include <QSvgRenderer>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <QPainter>
#include <QResizeEvent>
@@ -62,6 +62,15 @@ void ControllerImageWidget::SetDeadzone(int value)
}
}
void ControllerImageWidget::SetSensitivity(int value)
{
if (this->sensitivityValue != value)
{
this->sensitivityValue = value;
this->needImageUpdate = true;
}
}
void ControllerImageWidget::ClearControllerState()
{
// reset button state
@@ -153,27 +162,35 @@ void ControllerImageWidget::paintEvent(QPaintEvent *event)
renderer.setAspectRatioMode(Qt::AspectRatioMode::KeepAspectRatio);
QRectF rectF = renderer.viewBoxF();
double offsetx = 0, offsety = 0;
const int width = rectF.width();
const int height = rectF.height();
// we'll move the analog stick by a percentage
// of the total width/height from the image
const double maxOffsety = ((double)(height * 0.12265f) / 2);
const double maxOffsetx = maxOffsety;
const double dist = sqrt(pow(this->xAxisState, 2) + pow(this->yAxisState, 2));
const double absoluteMaxOffset = ((double)(height * 0.12265f) / 2);
// slope as in line gradient
const double offsetSlope = absoluteMaxOffset / 100;
// take sensitivity into account
const double sensitivityFactor = this->sensitivityValue / 100.0;
const double sensitivityAdjustedMaxOffset = absoluteMaxOffset * std::min(sensitivityFactor, 1.0);
double offsetDeadzone = this->deadzoneValue * sensitivityFactor * offsetSlope;
int offsetx = this->xAxisState * sensitivityFactor * offsetSlope;
int offsety = this->yAxisState * sensitivityFactor * offsetSlope;
const double offsetDist = sqrt(pow(offsetx, 2) + pow(offsety, 2));
// take deadzone into account
if (dist > this->deadzoneValue)
// deadzone grows with sensitivity such that the deadzone
// is always a percentage of the real stick range
if (offsetDist <= offsetDeadzone)
{
offsetx = (maxOffsetx / 100 * this->xAxisState);
offsety = (maxOffsety / 100 * this->yAxisState);
offsetx = 0;
offsety = 0;
}
// take circle range into account
if (dist > 100)
if (offsetDist > sensitivityAdjustedMaxOffset)
{
offsetx = (maxOffsetx / 100 * (this->xAxisState / dist * 100));
offsety = (maxOffsety / 100 * (this->yAxisState / dist * 100));
offsetx = (offsetx / offsetDist) * sensitivityAdjustedMaxOffset;
offsety = (offsety / offsetDist) * sensitivityAdjustedMaxOffset;
}
// adjust rect with offset
@@ -31,6 +31,8 @@ private:
int yAxisState = 0;
// deadzone value, 0-100
int deadzoneValue = 0;
// sensitivity value, 25-175
int sensitivityValue = 100;
bool needImageUpdate = false;
public:
@@ -41,6 +43,7 @@ public:
void SetXAxisState(int xAxis);
void SetYAxisState(int yAxis);
void SetDeadzone(int value);
void SetSensitivity(int value);
void ClearControllerState();
void UpdateImage();
@@ -323,6 +323,7 @@ void ControllerWidget::setPluggedIn(bool value)
this->analogStickDownButton, this->analogStickDownAddButton, this->analogStickDownRemoveButton,
this->analogStickLeftButton, this->analogStickLeftAddButton, this->analogStickLeftRemoveButton,
this->analogStickRightButton, this->analogStickRightAddButton, this->analogStickRightRemoveButton,
this->analogStickSensitivitySlider,
// cbuttons
this->cButtonsGroupBox,
this->cbuttonUpButton, this->cbuttonUpAddButton, this->cbuttonUpRemoveButton,
@@ -354,6 +355,67 @@ void ControllerWidget::setPluggedIn(bool value)
this->ClearControllerImage();
}
bool ControllerWidget::hasAnyGameSettingChanged(void)
{
std::string section = this->getCurrentSettingsSection().toStdString();
// fallback to main section
if (!CoreSettingsSectionExists(section))
{
section = this->settingsSection.toStdString();
}
// retrieve data from settings
bool settingsIsPluggedIn = CoreSettingsGetBoolValue(SettingsID::Input_PluggedIn, section);
int settingsDeadZone = CoreSettingsGetIntValue(SettingsID::Input_Deadzone, section);
int settingsAnalogSensitivity = 100;
// account for profiles before v0.3.9
if (CoreSettingsKeyExists(section, "Sensitivity"))
{
settingsAnalogSensitivity = CoreSettingsGetIntValue(SettingsID::Input_Sensitivity, section);
}
// retrieve current data
bool currentIsPluggedIn = this->inputDeviceComboBox->currentText() != "None";
int currentDeadZone = this->deadZoneSlider->value();
int currentAnalogSensitivity = this->analogStickSensitivitySlider->value();
// compare data
if (settingsIsPluggedIn != currentIsPluggedIn ||
settingsDeadZone != currentDeadZone ||
settingsAnalogSensitivity != currentAnalogSensitivity)
{
return true;
}
// compare button mappings with settings
for (auto& buttonSetting : this->buttonSettingMappings)
{
// retrieve data from settings
std::vector<int> settingsTypes = CoreSettingsGetIntListValue(buttonSetting.inputTypeSettingsId, section);
std::vector<std::string> settingsNames = CoreSettingsGetStringListValue(buttonSetting.nameSettingsId, section);
std::vector<int> settingsData = CoreSettingsGetIntListValue(buttonSetting.dataSettingsId, section);
std::vector<int> settingsExtraData = CoreSettingsGetIntListValue(buttonSetting.extraDataSettingsId, section);
// retrieve current data
std::vector<int> currentTypes = buttonSetting.button->GetInputType();
std::vector<std::string> currentNames = buttonSetting.button->GetInputText();
std::vector<int> currentData = buttonSetting.button->GetInputData();
std::vector<int> currentExtraData = buttonSetting.button->GetExtraInputData();
// compare data
if (settingsTypes != currentTypes ||
settingsNames != currentNames ||
settingsData != currentData ||
settingsExtraData != currentExtraData)
{
return true;
}
}
// no differences found
return false;
}
void ControllerWidget::showErrorMessage(QString text, QString details)
{
QMessageBox msgBox(this);
@@ -509,6 +571,16 @@ void ControllerWidget::on_deadZoneSlider_valueChanged(int value)
this->controllerImageWidget->SetDeadzone(value);
}
void ControllerWidget::on_analogStickSensitivitySlider_valueChanged(int value)
{
QString title = tr("Analog Stick Sensitivity: ");
title += QString::number(value);
title += "%";
this->analogStickSensitivityGroupBox->setTitle(title);
this->controllerImageWidget->SetSensitivity(value);
}
void ControllerWidget::on_profileComboBox_currentIndexChanged(int value)
{
// save profile when switching profile
@@ -622,7 +694,7 @@ void ControllerWidget::on_removeProfileButton_clicked()
{
bool ret;
if (this->profileComboBox->currentIndex() == 0)
if (this->profileComboBox->currentData().toString() == this->settingsSection)
{
QMessageBox messageBox(this);
messageBox.setIcon(QMessageBox::Icon::Warning);
@@ -678,6 +750,13 @@ void ControllerWidget::on_removeProfileButton_clicked()
this->previousProfileComboBoxIndex = -1;
this->profileComboBox->setCurrentIndex(0);
}
// force a re-load when
// we're only loading the game profile
if (this->onlyLoadGameProfile)
{
this->LoadSettings(this->settingsSection);
}
}
void ControllerWidget::on_resetButton_clicked()
@@ -1093,10 +1172,21 @@ bool ControllerWidget::IsPluggedIn()
return this->inputDeviceComboBox->currentData().toInt() != (int)InputDeviceType::None;
}
void ControllerWidget::SetOnlyLoadGameProfile(bool value)
{
this->onlyLoadGameProfile = value;
// update UI element
this->addProfileButton->setDisabled(value);
}
void ControllerWidget::SetSettingsSection(QString profile, QString section)
{
this->settingsSection = section;
this->profileComboBox->addItem(profile, section);
if (!this->onlyLoadGameProfile)
{
this->profileComboBox->addItem(profile, section);
}
}
void ControllerWidget::SetInitialized(bool value)
@@ -1145,41 +1235,53 @@ void ControllerWidget::LoadSettings()
// if a game specific section exists,
// select it in the profile combobox
// and use it to load the settings
if (CoreSettingsSectionExists(this->gameSection.toStdString()))
if (CoreSettingsSectionExists(this->gameSection.toStdString()) ||
this->onlyLoadGameProfile)
{
// check if the key 'UseGameProfile' exists,
// if it doesn't then use the profile,
// else check if it's true and use it
if (!CoreSettingsKeyExists(this->gameSection.toStdString(), "UseGameProfile") ||
// else check if it's true and use it,
// or if we're only loading the game profile
if (this->onlyLoadGameProfile ||
!CoreSettingsKeyExists(this->gameSection.toStdString(), "UseGameProfile") ||
CoreSettingsGetBoolValue(SettingsID::Input_UseGameProfile, this->gameSection.toStdString()))
{
this->profileComboBox->setCurrentText(internalName);
section = this->gameSection;
// only use game section if it exists
if (CoreSettingsSectionExists(this->gameSection.toStdString()))
{
section = this->gameSection;
}
}
}
}
// clear profiles list
profiles.clear();
// try to add all the user's profiles
userProfiles = CoreSettingsGetStringListValue(SettingsID::Input_Profiles);
for (const std::string& profile : userProfiles)
// try to add all the user's profiles when we're not only loading the
// game profile
if (!this->onlyLoadGameProfile)
{
QString profileSection = this->getUserProfileSectionName(QString::fromStdString(profile));
// clear profiles list
profiles.clear();
// ensure the profile section exists,
// if it does, add it when it doesn't
// exist yet
if (CoreSettingsSectionExists(profileSection.toStdString()))
userProfiles = CoreSettingsGetStringListValue(SettingsID::Input_Profiles);
for (const std::string& profile : userProfiles)
{
// add to profiles list
this->profiles.push_back(profileSection);
QString profileSection = this->getUserProfileSectionName(QString::fromStdString(profile));
int index = this->profileComboBox->findData(profileSection);
if (index == -1)
// ensure the profile section exists,
// if it does, add it when it doesn't
// exist yet
if (CoreSettingsSectionExists(profileSection.toStdString()))
{
this->profileComboBox->addItem(QString::fromStdString(profile), profileSection);
// add to profiles list
this->profiles.push_back(profileSection);
int index = this->profileComboBox->findData(profileSection);
if (index == -1)
{
this->profileComboBox->addItem(QString::fromStdString(profile), profileSection);
}
}
}
}
@@ -1219,7 +1321,7 @@ void ControllerWidget::LoadSettings(QString sectionQString, bool loadUserProfile
// if it does, see if that profile exists, then load
// that instead
useProfile = CoreSettingsGetStringValue(SettingsID::Input_UseProfile, section);
if (loadUserProfile && !useProfile.empty())
if (!this->onlyLoadGameProfile && loadUserProfile && !useProfile.empty())
{
QString profileSection = this->getUserProfileSectionName(QString::fromStdString(useProfile));
@@ -1232,6 +1334,16 @@ void ControllerWidget::LoadSettings(QString sectionQString, bool loadUserProfile
}
}
// keep backwards compatibility with versions before v0.3.9
if (CoreSettingsKeyExists(section, "Sensitivity"))
{
this->analogStickSensitivitySlider->setValue(CoreSettingsGetIntValue(SettingsID::Input_Sensitivity, section));
}
else
{
this->analogStickSensitivitySlider->setValue(100);
}
this->deadZoneSlider->setValue(CoreSettingsGetIntValue(SettingsID::Input_Deadzone, section));
this->optionsDialogSettings.RemoveDuplicateMappings = CoreSettingsGetBoolValue(SettingsID::Input_RemoveDuplicateMappings, section);
this->optionsDialogSettings.ControllerPak = CoreSettingsGetIntValue(SettingsID::Input_Pak, section);
@@ -1309,6 +1421,7 @@ void ControllerWidget::SaveDefaultSettings()
CoreSettingsSetValue(SettingsID::Input_DeviceName, section, std::string("None"));
CoreSettingsSetValue(SettingsID::Input_DeviceNum, section, (int)InputDeviceType::None);
CoreSettingsSetValue(SettingsID::Input_Deadzone, section, 9);
CoreSettingsSetValue(SettingsID::Input_Sensitivity, section, 100);
CoreSettingsSetValue(SettingsID::Input_Pak, section, 0);
CoreSettingsSetValue(SettingsID::Input_RemoveDuplicateMappings, section, true);
CoreSettingsSetValue(SettingsID::Input_FilterEventsForButtons, section, true);
@@ -1330,6 +1443,14 @@ void ControllerWidget::SaveSettings()
return;
}
// when we're only loading the game profile,
// we should only save when anything has changed
if (this->onlyLoadGameProfile &&
!this->hasAnyGameSettingChanged())
{
return;
}
this->SaveSettings(this->getCurrentSettingsSection());
// delete all removed profile sections
@@ -1393,6 +1514,7 @@ void ControllerWidget::SaveSettings(QString section)
CoreSettingsSetValue(SettingsID::Input_DeviceName, sectionStr, deviceName.toStdString());
CoreSettingsSetValue(SettingsID::Input_DeviceNum, sectionStr, deviceNum);
CoreSettingsSetValue(SettingsID::Input_Deadzone, sectionStr, this->deadZoneSlider->value());
CoreSettingsSetValue(SettingsID::Input_Sensitivity, sectionStr, this->analogStickSensitivitySlider->value());
CoreSettingsSetValue(SettingsID::Input_Pak, sectionStr, this->optionsDialogSettings.ControllerPak);
CoreSettingsSetValue(SettingsID::Input_GameboyRom, sectionStr, this->optionsDialogSettings.GameboyRom);
CoreSettingsSetValue(SettingsID::Input_GameboySave, sectionStr, this->optionsDialogSettings.GameboySave);
@@ -1425,6 +1547,14 @@ void ControllerWidget::RevertSettings()
CoreSettingsRevertSection(section.toStdString());
}
// don't compare profiles,
// when we're only loading
// the game profile
if (this->onlyLoadGameProfile)
{
return;
}
// delete all sections for added & removed profiles,
// which aren't in the base profile section list
sections.clear();
@@ -95,6 +95,8 @@ private:
void setPluggedIn(bool value);
bool hasAnyGameSettingChanged(void);
void showErrorMessage(QString text, QString details = "");
SDL_JoystickID currentJoystickId = -1;
@@ -102,6 +104,8 @@ private:
int previousProfileComboBoxIndex = -1;
bool onlyLoadGameProfile = false;
public:
ControllerWidget(QWidget* parent, EventFilter* eventFilter);
~ControllerWidget();
@@ -116,6 +120,8 @@ public:
void GetCurrentInputDevice(QString& deviceName, int& deviceNum, bool ignoreDeviceNotFound = false);
bool IsPluggedIn();
void SetOnlyLoadGameProfile(bool value);
void SetSettingsSection(QString profile, QString section);
void SetInitialized(bool value);
@@ -138,6 +144,7 @@ public:
private slots:
void on_deadZoneSlider_valueChanged(int value);
void on_analogStickSensitivitySlider_valueChanged(int value);
void on_profileComboBox_currentIndexChanged(int value);
@@ -601,6 +601,43 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="analogStickSensitivityGroupBox">
<property name="title">
<string>Analog Stick Sensitivity: 100%</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_15">
<item>
<widget class="QSlider" name="analogStickSensitivitySlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>25</number>
</property>
<property name="maximum">
<number>175</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>15</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
+29 -12
View File
@@ -21,7 +21,7 @@
#include <QApplication>
#include <SDL.h>
#include <iostream>
#include <algorithm>
#include <chrono>
//
@@ -60,6 +60,7 @@ struct InputProfile
{
bool PluggedIn = false;
int DeadzoneValue = 0;
int SensitivityValue = 100;
N64ControllerPak ControllerPak = N64ControllerPak::None;
@@ -223,6 +224,16 @@ static void load_settings(void)
profile->GameboyRom = CoreSettingsGetStringValue(SettingsID::Input_GameboyRom, section);
profile->GameboySave = CoreSettingsGetStringValue(SettingsID::Input_GameboySave, section);
// keep compatibility with profiles before version v0.3.9
if (CoreSettingsKeyExists(section, "Sensitivity"))
{
profile->SensitivityValue = CoreSettingsGetIntValue(SettingsID::Input_Sensitivity, section);
}
else
{
profile->SensitivityValue = 100;
}
// load inputmapping settings
load_inputmapping_settings(&profile->Button_A, section, SettingsID::Input_A_Name, SettingsID::Input_A_InputType, SettingsID::Input_A_Data, SettingsID::Input_A_ExtraData);
load_inputmapping_settings(&profile->Button_B, section, SettingsID::Input_B_Name, SettingsID::Input_B_InputType, SettingsID::Input_B_Data, SettingsID::Input_B_ExtraData);
@@ -406,7 +417,7 @@ static void close_controllers(void)
for (int i = 0; i < NUM_CONTROLLERS; i++)
{
InputProfile* profile = &l_InputProfiles[i];
profile->InputDevice.CloseDevice();
}
}
@@ -537,16 +548,17 @@ static double simulate_deadzone(const double n64InputAxis, const double maxAxis,
return axisAbsolute;
}
// Credit: MerryMage
static void simulate_octagon(const double inputX, const double inputY, const double deadzoneFactor, int& outputX, int& outputY)
// Credit: MerryMage & fzurita
static void simulate_octagon(const double inputX, const double inputY, const double deadzoneFactor, const double sensitivityFactor, int& outputX, int& outputY)
{
const double maxAxis = N64_AXIS_PEAK;
const double maxDiagonal = MAX_DIAGONAL_VALUE;
const int deadzone = (int)(deadzoneFactor * N64_AXIS_PEAK);
// don't increase emulated range at higher than 100% sensitivity
const double maxAxis = N64_AXIS_PEAK * std::min(sensitivityFactor, 1.0);
const double maxDiagonal = MAX_DIAGONAL_VALUE * std::min(sensitivityFactor, 1.0);
const int deadzone = (int)(deadzoneFactor * N64_AXIS_PEAK * sensitivityFactor);
const double axisRange = maxAxis - deadzone;
// scale to [-maxAxis, maxAxis]
double ax = inputX * maxAxis;
double ay = inputY * maxAxis;
double ax = std::min(inputX * sensitivityFactor, 1.0) * maxAxis;
double ay = std::min(inputY * sensitivityFactor, 1.0) * maxAxis;
// check whether (ax, ay) is within the circle of radius MAX_AXIS
double len = std::sqrt(ax*ax + ay*ay);
@@ -719,7 +731,7 @@ EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *pluginType, int *plugi
// Custom Plugin Functions
//
EXPORT m64p_error CALL PluginConfig()
EXPORT m64p_error CALL PluginConfig2(int romConfig)
{
if (l_SDLThread == nullptr)
{
@@ -731,7 +743,7 @@ EXPORT m64p_error CALL PluginConfig()
l_SDLThread->SetAction(SDLThreadAction::SDLPumpEvents);
UserInterface::MainDialog dialog(nullptr, l_SDLThread);
UserInterface::MainDialog dialog(nullptr, l_SDLThread, romConfig);
dialog.exec();
l_SDLThread->SetAction(SDLThreadAction::None);
@@ -742,7 +754,6 @@ EXPORT m64p_error CALL PluginConfig()
QThread::msleep(5);
}
// reload settings
load_settings();
@@ -758,6 +769,11 @@ EXPORT m64p_error CALL PluginConfig()
return M64ERR_SUCCESS;
}
EXPORT int CALL PluginConfig2HasRomConfig(void)
{
return 1;
}
//
// Input Plugin Functions
//
@@ -879,6 +895,7 @@ EXPORT void CALL GetKeys(int Control, BUTTONS* Keys)
inputX, // inputX
inputY, // inputY
profile->DeadzoneValue / 100.0, // deadzoneFactor
profile->SensitivityValue / 100.0, // sensitivityFactor
octagonX, // outputX
octagonY // outputY
);
+12 -1
View File
@@ -36,11 +36,12 @@ bool CoreCallbacks::Init(void)
{
// needed for Qt
qRegisterMetaType<CoreDebugMessageType>("CoreDebugMessageType");
qRegisterMetaType<CoreDebugMessageType>("CoreStateCallbackType");
this->LoadSettings();
l_CoreCallbacks = this;
return CoreSetupCallbacks(this->coreDebugCallback);
return CoreSetupCallbacks(this->coreDebugCallback, this->coreStateCallback);
}
void CoreCallbacks::Stop(void)
@@ -78,3 +79,13 @@ void CoreCallbacks::coreDebugCallback(CoreDebugMessageType type, std::string con
emit l_CoreCallbacks->OnCoreDebugCallback(type, QString::fromStdString(context), QString::fromStdString(message));
}
void CoreCallbacks::coreStateCallback(CoreStateCallbackType type, int value)
{
if (l_CoreCallbacks == nullptr)
{
return;
}
emit l_CoreCallbacks->OnCoreStateCallback(type, value);
}
+2
View File
@@ -31,9 +31,11 @@ public:
private:
static void coreDebugCallback(CoreDebugMessageType type, std::string context, std::string message);
static void coreStateCallback(CoreStateCallbackType type, int value);
signals:
void OnCoreDebugCallback(CoreDebugMessageType type, QString context, QString message);
void OnCoreStateCallback(CoreStateCallbackType type, int value);
};
#endif // RMG_CALLBACKS_HPP
+10 -7
View File
@@ -70,6 +70,7 @@ void RomSearcherThread::searchDirectory(QString directory)
filter << "*.NDD";
filter << "*.D64";
filter << "*.ZIP";
filter << "*.7Z";
QDirIterator::IteratorFlag flag = this->recursive ?
QDirIterator::Subdirectories :
@@ -82,9 +83,16 @@ void RomSearcherThread::searchDirectory(QString directory)
bool ret;
int count = 0;
QList<QString> roms;
while (romDirIt.hasNext())
{
QString file = romDirIt.next();
roms.push_back(romDirIt.next());
}
int romAmount = std::min(this->maxItems, (int)roms.size());
for (int i = 0; i < romAmount; i++)
{
QString file = roms.at(i);
QElapsedTimer timer;
timer.start();
@@ -111,12 +119,7 @@ void RomSearcherThread::searchDirectory(QString directory)
if (ret)
{
if (count++ >= this->maxItems)
{
break;
}
emit this->RomFound(file, type, header, settings);
emit this->RomFound(file, type, header, settings, (i + 1), romAmount);
}
if (this->stop)
+1 -1
View File
@@ -40,7 +40,7 @@ class RomSearcherThread : public QThread
void searchDirectory(QString);
signals:
void RomFound(QString file, CoreRomType type, CoreRomHeader header, CoreRomSettings settings);
void RomFound(QString file, CoreRomType type, CoreRomHeader header, CoreRomSettings settings, int index, int count);
void Finished(bool canceled);
};
} // namespace Thread
@@ -66,7 +66,7 @@ void InstallUpdateDialog::install(void)
" echo == Attemping to kill PID " + appPid + outputToLogLine,
" taskkill /F /PID:" + appPid + outputToLogLine,
" echo == Attemping to start \'" + fullFilePath + "\'" + outputToLogLine,
" \"" + fullFilePath + "\" /CLOSEAPPLICATIONS /NOCANCEL /SILENT /DIR=\"" + appPath + "\"" + outputToLogLine,
" \"" + fullFilePath + "\" /CLOSEAPPLICATIONS /NOCANCEL /MERGETASKS=\"!desktopicon\" /SILENT /DIR=\"" + appPath + "\"" + outputToLogLine,
")",
"IF NOT ERRORLEVEL 0 (",
" start \"\" cmd /c \"echo Rosalie's Mupen GUI failed to update, check the updater.log file in the Cache directory for more information && pause\"",
@@ -30,7 +30,8 @@ RomInfoDialog::RomInfoDialog(QString file, CoreRomHeader romHeader, CoreRomSetti
this->locationLineEdit->setCursorPosition(0);
this->crc1LineEdit->setText(QString::number(romHeader.CRC1, 16).toUpper());
this->crc2LineEdit->setText(QString::number(romHeader.CRC2, 16).toUpper());
this->countryCodeLineEdit->setText(QString((char)romHeader.CountryCode));
this->gameIDLineEdit->setText(QString::fromStdString(romHeader.GameID));
this->gameRegionLineEdit->setText(QString::fromStdString(romHeader.Region));
}
RomInfoDialog::~RomInfoDialog(void)
@@ -199,12 +199,36 @@
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Country Code</string>
<string>Game I.D.</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="countryCodeLineEdit">
<widget class="QLineEdit" name="gameIDLineEdit">
<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_8">
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>Game Region</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="gameRegionLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
@@ -214,6 +214,7 @@ void SettingsDialog::loadCoreSettings(void)
bool disableExtraMem = false;
int counterFactor = 0;
int cpuEmulator = 0;
int saveFilenameFormat = 0;
int siDmaDuration = -1;
bool randomizeInterrupt = true;
bool debugger = false;
@@ -222,12 +223,14 @@ void SettingsDialog::loadCoreSettings(void)
disableExtraMem = CoreSettingsGetBoolValue(SettingsID::CoreOverlay_DisableExtraMem);
counterFactor = CoreSettingsGetIntValue(SettingsID::CoreOverlay_CountPerOp);
cpuEmulator = CoreSettingsGetIntValue(SettingsID::CoreOverlay_CPU_Emulator);
saveFilenameFormat = CoreSettingsGetIntValue(SettingsID::CoreOverLay_SaveFileNameFormat);
siDmaDuration = CoreSettingsGetIntValue(SettingsID::CoreOverlay_SiDmaDuration);
randomizeInterrupt = CoreSettingsGetBoolValue(SettingsID::CoreOverlay_RandomizeInterrupt);
debugger = CoreSettingsGetBoolValue(SettingsID::CoreOverlay_EnableDebugger);
overrideGameSettings = CoreSettingsGetBoolValue(SettingsID::Core_OverrideGameSpecificSettings);
this->coreCpuEmulatorComboBox->setCurrentIndex(cpuEmulator);
this->coreSaveFilenameFormatComboBox->setCurrentIndex(saveFilenameFormat);
this->coreRandomizeTimingCheckBox->setChecked(randomizeInterrupt);
//this->coreDebuggerCheckBox->setChecked(debugger);
@@ -437,6 +440,7 @@ void SettingsDialog::loadDefaultCoreSettings(void)
bool disableExtraMem = false;
int counterFactor = 0;
int cpuEmulator = 0;
int saveFilenameFormat = 0;
int siDmaDuration = -1;
bool randomizeInterrupt = true;
bool debugger = false;
@@ -446,11 +450,13 @@ void SettingsDialog::loadDefaultCoreSettings(void)
counterFactor = CoreSettingsGetDefaultIntValue(SettingsID::CoreOverlay_CountPerOp);
cpuEmulator = CoreSettingsGetDefaultIntValue(SettingsID::CoreOverlay_CPU_Emulator);
siDmaDuration = CoreSettingsGetDefaultIntValue(SettingsID::CoreOverlay_SiDmaDuration);
saveFilenameFormat = CoreSettingsGetDefaultIntValue(SettingsID::CoreOverLay_SaveFileNameFormat);
randomizeInterrupt = CoreSettingsGetDefaultBoolValue(SettingsID::CoreOverlay_RandomizeInterrupt);
debugger = CoreSettingsGetDefaultBoolValue(SettingsID::CoreOverlay_EnableDebugger);
overrideGameSettings = CoreSettingsGetDefaultBoolValue(SettingsID::Core_OverrideGameSpecificSettings);
this->coreCpuEmulatorComboBox->setCurrentIndex(cpuEmulator);
this->coreSaveFilenameFormatComboBox->setCurrentIndex(saveFilenameFormat);
this->coreRandomizeTimingCheckBox->setChecked(randomizeInterrupt);
//this->coreDebuggerCheckBox->setChecked(debugger);
@@ -603,12 +609,14 @@ void SettingsDialog::saveCoreSettings(void)
bool disableExtraMem = (this->coreMemorySizeComboBox->currentIndex() == 0);
int counterFactor = this->coreCounterFactorComboBox->currentIndex() + 1;
int cpuEmulator = this->coreCpuEmulatorComboBox->currentIndex();
int saveFilenameFormat = this->coreSaveFilenameFormatComboBox->currentIndex();
int siDmaDuration = this->coreSiDmaDurationSpinBox->value();
bool randomizeInterrupt = this->coreRandomizeTimingCheckBox->isChecked();
//bool debugger = this->coreDebuggerCheckBox->isChecked();
bool overrideGameSettings = this->coreOverrideGameSettingsGroup->isChecked();
CoreSettingsSetValue(SettingsID::CoreOverlay_CPU_Emulator, cpuEmulator);
CoreSettingsSetValue(SettingsID::CoreOverLay_SaveFileNameFormat, saveFilenameFormat);
CoreSettingsSetValue(SettingsID::CoreOverlay_RandomizeInterrupt, randomizeInterrupt);
//CoreSettingsSetValue(SettingsID::CoreOverlay_EnableDebugger, debugger);
CoreSettingsSetValue(SettingsID::Core_OverrideGameSpecificSettings, overrideGameSettings);
@@ -843,12 +851,17 @@ void SettingsDialog::commonHotkeySettings(SettingsDialogAction action)
std::vector<keybinding> keybindings_Settings =
{
{ this->graphicsSettingsKeyButton, SettingsID::KeyBinding_GraphicsSettings },
{ this->audioSettingsKeyButton, SettingsID::KeyBinding_AudioSettings },
{ this->rspSettingsKeyButton, SettingsID::KeyBinding_RspSettings },
{ this->inputSettingsKeyButton, SettingsID::KeyBinding_InputSettings },
{ this->settingsKeyButton, SettingsID::KeyBinding_Settings },
};
std::vector<keybinding> keybindings_View =
{
{ this->fullscreenKeyButton, SettingsID::KeyBinding_Fullscreen },
{ this->logKeyButton, SettingsID::Keybinding_ViewLog },
{ this->refreshRomListKeyButton, SettingsID::KeyBinding_RefreshROMList }
};
@@ -976,7 +989,7 @@ 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_7
this->infoIconLabel_7, this->infoIconLabel_6, this->infoIconLabel_8
};
QIcon infoIcon = QIcon::fromTheme("information-line");
@@ -1190,7 +1203,12 @@ void SettingsDialog::on_KeybindButton_KeybindingChanged(KeybindButton* button)
this->startComboKeyButton,
this->shutdownKeyButton,
this->exitKeyButton,
this->graphicsSettingsKeyButton,
this->audioSettingsKeyButton,
this->rspSettingsKeyButton,
this->inputSettingsKeyButton,
this->settingsKeyButton,
this->logKeyButton,
this->refreshRomListKeyButton,
};
@@ -1231,7 +1249,12 @@ void SettingsDialog::on_KeybindButton_KeybindingChanged(KeybindButton* button)
this->saveState8KeyButton,
this->saveState9KeyButton,
this->exitKeyButton,
this->graphicsSettingsKeyButton,
this->audioSettingsKeyButton,
this->rspSettingsKeyButton,
this->inputSettingsKeyButton,
this->settingsKeyButton,
this->logKeyButton,
this->fullscreenKeyButton,
};
@@ -1301,7 +1301,79 @@
<attribute name="title">
<string>Settings</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_37">
<layout class="QVBoxLayout" name="verticalLayout_14">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_92">
<item>
<widget class="QLabel" name="label_85">
<property name="text">
<string>Graphics</string>
</property>
</widget>
</item>
<item>
<widget class="KeybindButton" name="graphicsSettingsKeyButton">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_93">
<item>
<widget class="QLabel" name="label_87">
<property name="text">
<string>Audio</string>
</property>
</widget>
</item>
<item>
<widget class="KeybindButton" name="audioSettingsKeyButton">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_94">
<item>
<widget class="QLabel" name="label_89">
<property name="text">
<string>RSP</string>
</property>
</widget>
</item>
<item>
<widget class="KeybindButton" name="rspSettingsKeyButton">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_117">
<item>
<widget class="QLabel" name="label_90">
<property name="text">
<string>Input</string>
</property>
</widget>
</item>
<item>
<widget class="KeybindButton" name="inputSettingsKeyButton">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_87">
<item>
@@ -1358,6 +1430,24 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_118">
<item>
<widget class="QLabel" name="label_114">
<property name="text">
<string>Log</string>
</property>
</widget>
</item>
<item>
<widget class="KeybindButton" name="logKeyButton">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_73">
<item>
@@ -1410,7 +1500,7 @@
<attribute name="title">
<string>Core</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_19">
<layout class="QVBoxLayout" name="verticalLayout_17">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_43">
<item>
@@ -1441,6 +1531,31 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_46">
<item>
<widget class="QLabel" name="label_25">
<property name="text">
<string>Save Filename Format</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="coreSaveFilenameFormatComboBox">
<item>
<property name="text">
<string>Internal ROM Name</string>
</property>
</item>
<item>
<property name="text">
<string>Automatic</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="coreOverrideGameSettingsGroup">
<property name="enabled">
@@ -1958,7 +2073,7 @@
<attribute name="title">
<string>Plugins</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_24">
<layout class="QVBoxLayout" name="verticalLayout_16">
<item>
<widget class="QGroupBox" name="groupBox_19">
<property name="enabled">
@@ -2090,6 +2205,51 @@
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="emulationInfoLayout_6">
<item>
<widget class="QLabel" name="infoIconLabel_8">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap>:/newPrefix/Resource/Info.ico</pixmap>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_68">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="midLineWidth">
<number>1</number>
</property>
<property name="text">
<string>Make sure to use a LLE RSP plugin (i.e paraLLEl RSP) when using a LLE Video plugin (i.e paraLLEl)</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
@@ -2142,7 +2302,7 @@
<attribute name="title">
<string>Plugins</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_25">
<layout class="QVBoxLayout" name="verticalLayout_15">
<item>
<widget class="QGroupBox" name="groupBox_25">
<property name="title">
@@ -2241,6 +2401,51 @@
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="emulationInfoLayout_4">
<item>
<widget class="QLabel" name="infoIconLabel_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap>:/newPrefix/Resource/Info.ico</pixmap>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_64">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="midLineWidth">
<number>1</number>
</property>
<property name="text">
<string>Make sure to use a LLE RSP plugin (i.e paraLLEl RSP) when using a LLE Video plugin (i.e paraLLEl)</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="emulationInfoLayout_1">
<item>
@@ -23,7 +23,7 @@
using namespace UserInterface::Dialog;
UpdateDialog::UpdateDialog(QWidget *parent, QJsonObject jsonObject) : QDialog(parent)
UpdateDialog::UpdateDialog(QWidget *parent, QJsonObject jsonObject, bool forced) : QDialog(parent)
{
this->setupUi(this);
@@ -35,6 +35,10 @@ UpdateDialog::UpdateDialog(QWidget *parent, QJsonObject jsonObject) : QDialog(pa
// change ok button text to 'Update'
QPushButton* button = this->buttonBox->button(QDialogButtonBox::Ok);
button->setText("Update");
// don't show the 'Don't check for updates again' checkbox,
// when the user requested we check for updates
this->disableUpdateCheckCheckBox->setHidden(forced);
}
UpdateDialog::~UpdateDialog(void)
@@ -36,7 +36,7 @@ class UpdateDialog : public QDialog, private Ui::UpdateDialog
#endif // _WIN32
public:
UpdateDialog(QWidget *parent, QJsonObject jsonObject);
UpdateDialog(QWidget *parent, QJsonObject jsonObject, bool forced);
~UpdateDialog(void);
QString GetFileName(void);
+429 -150
View File
@@ -48,7 +48,7 @@ MainWindow::~MainWindow()
{
}
bool MainWindow::Init(QApplication* app)
bool MainWindow::Init(QApplication* app, bool showUI)
{
if (!CoreInit())
{
@@ -64,14 +64,16 @@ bool MainWindow::Init(QApplication* app)
this->configureTheme(app);
this->initializeUI();
this->configureUI(app);
this->configureUI(app, showUI);
this->connectActionSignals();
this->configureActions();
this->updateActions(false, false);
#ifdef UPDATER
this->checkForUpdates();
this->checkForUpdates(true, false);
#else
this->action_Help_Update->setVisible(false);
#endif // UPDATER
this->initializeEmulationThread();
@@ -90,8 +92,15 @@ bool MainWindow::Init(QApplication* app)
return false;
}
// add actions when there's no UI
if (!showUI)
{
this->addActions();
}
connect(coreCallBacks, &CoreCallbacks::OnCoreDebugCallback, this, &MainWindow::on_Core_DebugCallback);
connect(coreCallBacks, &CoreCallbacks::OnCoreDebugCallback, &this->logDialog, &Dialog::LogDialog::AddLogLine);
connect(coreCallBacks, &CoreCallbacks::OnCoreStateCallback, this, &MainWindow::on_Core_StateCallback);
connect(app, &QGuiApplication::applicationStateChanged, this, &MainWindow::on_QGuiApplication_applicationStateChanged);
return true;
@@ -119,9 +128,13 @@ void MainWindow::closeEvent(QCloseEvent *event)
if (!this->ui_QuitAfterEmulation &&
!this->emulationThread->isRunning())
{
this->storeGeometry();
this->storeGeometry();
}
// store toolbar location to settings
Qt::ToolBarArea toolbarArea = this->toolBarArea(this->toolBar);
CoreSettingsSetValue(SettingsID::GUI_ToolbarArea, this->getToolbarSettingAreaFromArea(toolbarArea));
this->ui_NoSwitchToRomBrowser = true;
this->on_Action_System_Shutdown();
@@ -160,6 +173,8 @@ void MainWindow::initializeUI(void)
&MainWindow::on_RomBrowser_PlayGameWith);
connect(this->ui_Widget_RomBrowser, &Widget::RomBrowserWidget::EditGameSettings, this,
&MainWindow::on_RomBrowser_EditGameSettings);
connect(this->ui_Widget_RomBrowser, &Widget::RomBrowserWidget::EditGameInputSettings, this,
&MainWindow::on_RomBrowser_EditGameInputSettings);
connect(this->ui_Widget_RomBrowser, &Widget::RomBrowserWidget::Cheats, this,
&MainWindow::on_RomBrowser_Cheats);
connect(this->ui_Widget_RomBrowser, &Widget::RomBrowserWidget::ChangeRomDirectory, this,
@@ -173,7 +188,7 @@ void MainWindow::initializeUI(void)
&MainWindow::on_EventFilter_KeyReleased);
}
void MainWindow::configureUI(QApplication* app)
void MainWindow::configureUI(QApplication* app, bool showUI)
{
this->setCentralWidget(this->ui_Widgets);
@@ -191,13 +206,35 @@ void MainWindow::configureUI(QApplication* app)
this->restoreGeometry(QByteArray::fromBase64(geometry.toLocal8Bit()));
}
this->ui_ShowToolbar = CoreSettingsGetBoolValue(SettingsID::GUI_Toolbar);
this->ui_ShowStatusbar = CoreSettingsGetBoolValue(SettingsID::GUI_StatusBar);
this->ui_ShowUI = showUI;
if (this->ui_ShowUI)
{
this->ui_ShowMenubar = true;
this->ui_ShowToolbar = CoreSettingsGetBoolValue(SettingsID::GUI_Toolbar);
this->ui_ShowStatusbar = CoreSettingsGetBoolValue(SettingsID::GUI_StatusBar);
}
else
{
this->ui_ShowMenubar = false;
this->ui_ShowToolbar = false;
this->ui_ShowStatusbar = false;
}
this->menuBar()->setVisible(this->ui_ShowMenubar);
this->toolBar->setVisible(this->ui_ShowToolbar);
this->statusBar()->setVisible(this->ui_ShowStatusbar);
this->statusBar()->addPermanentWidget(this->ui_StatusBar_Label, 1);
// set toolbar position according to setting
int toolbarAreaSetting = CoreSettingsGetIntValue(SettingsID::GUI_ToolbarArea);
Qt::ToolBarArea toolbarArea = this->getToolbarAreaFromSettingArea(toolbarAreaSetting);
if (this->toolBarArea(this->toolBar) != toolbarArea)
{
this->removeToolBar(this->toolBar);
this->addToolBar(toolbarArea, this->toolBar);
}
this->ui_TimerTimeout = CoreSettingsGetIntValue(SettingsID::GUI_StatusbarMessageDuration);
this->ui_Widgets->addWidget(this->ui_Widget_RomBrowser);
@@ -313,7 +350,7 @@ void MainWindow::configureTheme(QApplication* app)
QIcon::setFallbackThemeName(fallbackThemeName);
}
void MainWindow::showErrorMessage(QString text, QString details = "")
void MainWindow::showErrorMessage(QString text, QString details)
{
QMessageBox msgBox(this);
msgBox.setIcon(QMessageBox::Icon::Critical);
@@ -396,20 +433,32 @@ void MainWindow::loadGeometry(void)
this->showNormal();
}
if (this->menuBar()->isHidden())
if (this->ui_ShowMenubar && this->menuBar()->isHidden())
{
this->menuBar()->show();
}
else if (!this->ui_ShowMenubar && !this->menuBar()->isHidden())
{
this->menuBar()->hide();
}
if (this->ui_ShowToolbar && this->toolBar->isHidden())
{
this->toolBar->show();
}
else if (!this->ui_ShowToolbar && !this->toolBar->isHidden())
{
this->toolBar->hide();
}
if (this->ui_ShowStatusbar && this->statusBar()->isHidden())
{
this->statusBar()->show();
}
else if (!this->ui_ShowStatusbar && !this->statusBar()->isHidden())
{
this->statusBar()->hide();
}
this->ui_Geometry_Saved = false;
}
@@ -478,8 +527,12 @@ void MainWindow::launchEmulationThread(QString cartRom, QString diskRom)
this->ui_HideCursorInEmulation = CoreSettingsGetBoolValue(SettingsID::GUI_HideCursorInEmulation);
this->ui_HideCursorInFullscreenEmulation = CoreSettingsGetBoolValue(SettingsID::GUI_HideCursorInFullscreenEmulation);
this->ui_ShowToolbar = CoreSettingsGetBoolValue(SettingsID::GUI_Toolbar);
this->ui_ShowStatusbar = CoreSettingsGetBoolValue(SettingsID::GUI_StatusBar);
if (this->ui_ShowUI)
{
this->ui_ShowToolbar = CoreSettingsGetBoolValue(SettingsID::GUI_Toolbar);
this->ui_ShowStatusbar = CoreSettingsGetBoolValue(SettingsID::GUI_StatusBar);
}
this->ui_Widget_OpenGL->SetHideCursor(this->ui_HideCursorInEmulation);
@@ -488,11 +541,6 @@ void MainWindow::launchEmulationThread(QString cartRom, QString diskRom)
this->emulationThread->start();
}
void MainWindow::launchEmulationThread(QString file)
{
this->launchEmulationThread(file, "");
}
void MainWindow::updateActions(bool inEmulation, bool isPaused)
{
QString keyBinding;
@@ -571,13 +619,6 @@ void MainWindow::updateActions(bool inEmulation, bool isPaused)
}
// configure keybindings for save slots
QAction* slotActions[] =
{
this->actionSlot_0, this->actionSlot_1, this->actionSlot_2,
this->actionSlot_3, this->actionSlot_4, this->actionSlot_5,
this->actionSlot_6, this->actionSlot_7, this->actionSlot_8,
this->actionSlot_9
};
SettingsID slotKeybindSettingsId[] =
{
SettingsID::KeyBinding_SaveStateSlot0, SettingsID::KeyBinding_SaveStateSlot1,
@@ -586,16 +627,29 @@ void MainWindow::updateActions(bool inEmulation, bool isPaused)
SettingsID::KeyBinding_SaveStateSlot6, SettingsID::KeyBinding_SaveStateSlot7,
SettingsID::KeyBinding_SaveStateSlot8, SettingsID::KeyBinding_SaveStateSlot9
};
int currentSlot = CoreGetSaveStateSlot();
for (int i = 0; i < 10; i++)
{
keyBinding = QString::fromStdString(CoreSettingsGetStringValue(slotKeybindSettingsId[i]));
slotActions[i]->setShortcut(QKeySequence(keyBinding));
this->ui_SlotActions[i]->setShortcut(QKeySequence(keyBinding));
this->ui_SlotActions[i]->setChecked(i == currentSlot);
}
// configure text and filename data for save slots
this->updateSaveStateSlotActions(inEmulation, isPaused);
keyBinding = QString::fromStdString(CoreSettingsGetStringValue(SettingsID::KeyBinding_GraphicsSettings));
this->action_Settings_Graphics->setEnabled(CorePluginsHasConfig(CorePluginType::Gfx));
this->action_Settings_Graphics->setShortcut(QKeySequence(keyBinding));
keyBinding = QString::fromStdString(CoreSettingsGetStringValue(SettingsID::KeyBinding_AudioSettings));
this->action_Settings_Audio->setEnabled(CorePluginsHasConfig(CorePluginType::Audio));
this->action_Settings_Audio->setShortcut(QKeySequence(keyBinding));
keyBinding = QString::fromStdString(CoreSettingsGetStringValue(SettingsID::KeyBinding_RspSettings));
this->action_Settings_Rsp->setEnabled(CorePluginsHasConfig(CorePluginType::Rsp));
this->action_Settings_Rsp->setShortcut(QKeySequence(keyBinding));
keyBinding = QString::fromStdString(CoreSettingsGetStringValue(SettingsID::KeyBinding_InputSettings));
this->action_Settings_Input->setEnabled(CorePluginsHasConfig(CorePluginType::Input));
this->action_Settings_Input->setShortcut(QKeySequence(keyBinding));
keyBinding = QString::fromStdString(CoreSettingsGetStringValue(SettingsID::KeyBinding_Settings));
this->action_Settings_Settings->setShortcut(QKeySequence(keyBinding));
@@ -606,109 +660,182 @@ void MainWindow::updateActions(bool inEmulation, bool isPaused)
keyBinding = QString::fromStdString(CoreSettingsGetStringValue(SettingsID::KeyBinding_RefreshROMList));
this->action_View_RefreshRoms->setEnabled(!inEmulation);
this->action_View_RefreshRoms->setShortcut(QKeySequence(keyBinding));
keyBinding = QString::fromStdString(CoreSettingsGetStringValue(SettingsID::Keybinding_ViewLog));
this->action_View_Log->setShortcut(QKeySequence(keyBinding));
this->action_View_ClearRomCache->setEnabled(!inEmulation);
}
void MainWindow::addFullscreenActions(void)
void MainWindow::updateSaveStateSlotActions(bool inEmulation, bool isPaused)
{
this->addAction(this->action_System_StartRom);
this->addAction(this->action_System_OpenCombo);
this->addAction(this->action_System_Shutdown);
this->addAction(this->action_System_SoftReset);
this->addAction(this->action_System_HardReset);
this->addAction(this->action_System_Pause);
this->addAction(this->action_System_Screenshot);
this->addAction(this->action_System_LimitFPS);
this->addAction(this->actionSpeed25);
this->addAction(this->actionSpeed50);
this->addAction(this->actionSpeed75);
this->addAction(this->actionSpeed100);
this->addAction(this->actionSpeed125);
this->addAction(this->actionSpeed150);
this->addAction(this->actionSpeed175);
this->addAction(this->actionSpeed200);
this->addAction(this->actionSpeed225);
this->addAction(this->actionSpeed250);
this->addAction(this->actionSpeed275);
this->addAction(this->actionSpeed300);
this->addAction(this->action_System_SaveState);
this->addAction(this->action_System_SaveAs);
this->addAction(this->action_System_LoadState);
this->addAction(this->action_System_Load);
this->addAction(this->actionSlot_0);
this->addAction(this->actionSlot_1);
this->addAction(this->actionSlot_2);
this->addAction(this->actionSlot_3);
this->addAction(this->actionSlot_4);
this->addAction(this->actionSlot_5);
this->addAction(this->actionSlot_6);
this->addAction(this->actionSlot_7);
this->addAction(this->actionSlot_8);
this->addAction(this->actionSlot_9);
this->addAction(this->action_System_Cheats);
this->addAction(this->action_System_GSButton);
this->addAction(this->action_System_Exit);
this->addAction(this->action_Settings_Graphics);
this->addAction(this->action_Settings_Audio);
this->addAction(this->action_Settings_Rsp);
this->addAction(this->action_Settings_Input);
this->addAction(this->action_Settings_Settings);
this->addAction(this->action_View_Fullscreen);
this->addAction(this->action_Help_Github);
this->addAction(this->action_Help_About);
std::filesystem::path saveStatePath;
// do nothing when paused
if (isPaused)
{
return;
}
for (int i = 0; i < 10; i++)
{
if (inEmulation &&
CoreGetSaveStatePath(i, saveStatePath))
{
this->ui_SlotActions[i]->setData(QString::fromStdString(saveStatePath.string()));
this->ui_SlotActions[i]->setText(this->getSaveStateSlotText(this->ui_SlotActions[i], i));
}
else
{
this->ui_SlotActions[i]->setData("");
this->ui_SlotActions[i]->setText(this->getSaveStateSlotText(this->ui_SlotActions[i], i));
}
}
}
void MainWindow::removeFullscreenActions(void)
void MainWindow::addActions(void)
{
this->removeAction(this->action_System_StartRom);
this->removeAction(this->action_System_OpenCombo);
this->removeAction(this->action_System_Shutdown);
this->removeAction(this->action_System_SoftReset);
this->removeAction(this->action_System_HardReset);
this->removeAction(this->action_System_Pause);
this->removeAction(this->action_System_Screenshot);
this->removeAction(this->action_System_LimitFPS);
this->removeAction(this->actionSpeed25);
this->removeAction(this->actionSpeed50);
this->removeAction(this->actionSpeed75);
this->removeAction(this->actionSpeed100);
this->removeAction(this->actionSpeed125);
this->removeAction(this->actionSpeed150);
this->removeAction(this->actionSpeed175);
this->removeAction(this->actionSpeed200);
this->removeAction(this->actionSpeed225);
this->removeAction(this->actionSpeed250);
this->removeAction(this->actionSpeed275);
this->removeAction(this->actionSpeed300);
this->removeAction(this->action_System_SaveState);
this->removeAction(this->action_System_SaveAs);
this->removeAction(this->action_System_LoadState);
this->removeAction(this->action_System_Load);
this->removeAction(this->actionSlot_0);
this->removeAction(this->actionSlot_1);
this->removeAction(this->actionSlot_2);
this->removeAction(this->actionSlot_3);
this->removeAction(this->actionSlot_4);
this->removeAction(this->actionSlot_5);
this->removeAction(this->actionSlot_6);
this->removeAction(this->actionSlot_7);
this->removeAction(this->actionSlot_8);
this->removeAction(this->actionSlot_9);
this->removeAction(this->action_System_Cheats);
this->removeAction(this->action_System_GSButton);
this->removeAction(this->action_System_Exit);
this->removeAction(this->action_Settings_Graphics);
this->removeAction(this->action_Settings_Audio);
this->removeAction(this->action_Settings_Rsp);
this->removeAction(this->action_Settings_Input);
this->removeAction(this->action_Settings_Settings);
this->removeAction(this->action_View_Fullscreen);
this->removeAction(this->action_Help_Github);
this->removeAction(this->action_Help_About);
if (this->ui_AddedActions)
{
return;
}
for (QAction* action : this->ui_Actions)
{
this->addAction(action);
}
this->ui_AddedActions = true;
}
void MainWindow::removeActions(void)
{
if (!this->ui_AddedActions)
{
return;
}
for (QAction* action : this->ui_Actions)
{
this->removeAction(action);
}
this->ui_AddedActions = false;
}
QString MainWindow::getSaveStateSlotDateTimeText(QAction* action)
{
QString saveStateSlotText;
QString filePath;
// retrieve file name
filePath = action->data().toString();
// check if file exists, if it does,
// return a string with the datetime
QFileInfo saveStateFileInfo(filePath);
if (!filePath.isEmpty() && saveStateFileInfo.exists())
{
saveStateSlotText = saveStateFileInfo.lastModified().toString("dd/MM/yyyy hh:mm");
}
return saveStateSlotText;
}
QString MainWindow::getSaveStateSlotText(QAction* action, int slot)
{
QString saveStateSlotText;
QString dateTimeText;
QString filePath;
// base text
saveStateSlotText = "Slot " + QString::number(slot);
// add date and time text when it isnt empty
dateTimeText = this->getSaveStateSlotDateTimeText(action);
if (!dateTimeText.isEmpty())
{
saveStateSlotText += " - ";
saveStateSlotText += dateTimeText;
}
return saveStateSlotText;
}
int MainWindow::getToolbarSettingAreaFromArea(Qt::ToolBarArea area)
{
switch (area)
{
case Qt::ToolBarArea::TopToolBarArea:
return 0;
case Qt::ToolBarArea::BottomToolBarArea:
return 1;
case Qt::ToolBarArea::LeftToolBarArea:
return 2;
case Qt::ToolBarArea::RightToolBarArea:
return 3;
default:
return 0;
}
}
Qt::ToolBarArea MainWindow::getToolbarAreaFromSettingArea(int value)
{
switch (value)
{
default:
case 0:
return Qt::ToolBarArea::TopToolBarArea;
case 1:
return Qt::ToolBarArea::BottomToolBarArea;
case 2:
return Qt::ToolBarArea::LeftToolBarArea;
case 3:
return Qt::ToolBarArea::RightToolBarArea;
}
}
void MainWindow::configureActions(void)
{
// configure actions list
this->ui_Actions.append(
{
// System actions
this->action_System_StartRom, this->action_System_OpenCombo,
this->action_System_Shutdown, this->action_System_SoftReset,
this->action_System_HardReset, this->action_System_Pause,
this->action_System_Screenshot, this->action_System_LimitFPS,
this->actionSpeed25, this->actionSpeed50, this->actionSpeed75,
this->actionSpeed100, this->actionSpeed125, this->actionSpeed150,
this->actionSpeed175, this->actionSpeed200, this->actionSpeed225,
this->actionSpeed250, this->actionSpeed275, this->actionSpeed300,
this->action_System_SaveState, this->action_System_SaveAs,
this->action_System_LoadState, this->action_System_Load,
this->actionSlot_0, this->actionSlot_1, this->actionSlot_2,
this->actionSlot_3, this->actionSlot_4, this->actionSlot_5,
this->actionSlot_6, this->actionSlot_7, this->actionSlot_8,
this->actionSlot_9, this->action_System_Cheats,
this->action_System_GSButton, this->action_System_Exit,
// Settings actions
this->action_Settings_Graphics, this->action_Settings_Audio,
this->action_Settings_Rsp, this->action_Settings_Input,
this->action_Settings_Settings,
// View actions
this->action_View_Fullscreen, this->action_View_RefreshRoms,
this->action_View_Log,
// Help actions
this->action_Help_Github, this->action_Help_About,
});
// configure save slot actions
this->ui_SlotActions.append(
{
this->actionSlot_0, this->actionSlot_1, this->actionSlot_2,
this->actionSlot_3, this->actionSlot_4, this->actionSlot_5,
this->actionSlot_6, this->actionSlot_7, this->actionSlot_8,
this->actionSlot_9
});
// configure emulation speed actions
QActionGroup* speedActionGroup = new QActionGroup(this);
QAction* speedActions[] =
@@ -747,20 +874,12 @@ void MainWindow::configureActions(void)
// configure save slot actions
QActionGroup* slotActionGroup = new QActionGroup(this);
QAction* slotActions[] =
{
this->actionSlot_0, this->actionSlot_1, this->actionSlot_2,
this->actionSlot_3, this->actionSlot_4, this->actionSlot_5,
this->actionSlot_6, this->actionSlot_7, this->actionSlot_8,
this->actionSlot_9
};
int currentSlot = CoreGetSaveStateSlot();
for (int i = 0; i < 10; i++)
{
QAction* slotAction = slotActions[i];
QAction* slotAction = this->ui_SlotActions[i];
slotAction->setCheckable(true);
slotAction->setChecked(i == currentSlot);
slotAction->setChecked(i == 0);
slotAction->setActionGroup(slotActionGroup);
// connect slot action here because we need to do
@@ -769,7 +888,7 @@ void MainWindow::configureActions(void)
{
if (checked)
{
int slot = slotAction->text().split(" ").last().toInt();
int slot = slotAction->text().split(" ").at(1).toInt();
this->on_Action_System_CurrentSaveState(slot);
}
});
@@ -839,16 +958,44 @@ void MainWindow::connectActionSignals(void)
connect(this->action_Help_Github, &QAction::triggered, this, &MainWindow::on_Action_Help_Github);
connect(this->action_Help_About, &QAction::triggered, this, &MainWindow::on_Action_Help_About);
connect(this->action_Help_Update, &QAction::triggered, this, &MainWindow::on_Action_Help_Update);
}
#ifdef UPDATER
void MainWindow::checkForUpdates(void)
void MainWindow::checkForUpdates(bool silent, bool force)
{
if (!CoreSettingsGetBoolValue(SettingsID::GUI_CheckForUpdates))
if (!force && !CoreSettingsGetBoolValue(SettingsID::GUI_CheckForUpdates))
{
return;
}
// only check for updates on the stable versions unless forced
QString currentVersion = QString::fromStdString(CoreGetVersion());
if (!force && currentVersion.size() != 6)
{
return;
}
QString dateTimeFormat = "dd-MM-yyyy_hh:mm";
QString lastUpdateCheckDateTimeString = QString::fromStdString(CoreSettingsGetStringValue(SettingsID::GUI_LastUpdateCheck));
QDateTime lastUpdateCheckDateTime = QDateTime::fromString(lastUpdateCheckDateTimeString, dateTimeFormat);
QDateTime currentDateTime = QDateTime::currentDateTime();
// only check for updates once every hour unless forced
if (!force &&
lastUpdateCheckDateTime.isValid() &&
lastUpdateCheckDateTime.addSecs(3600) > currentDateTime)
{
return;
}
// update last update check date & time
CoreSettingsSetValue(SettingsID::GUI_LastUpdateCheck, currentDateTime.toString(dateTimeFormat).toStdString());
// whether or not the update check is silent
this->ui_SilentUpdateCheck = silent;
// execute update check
QNetworkAccessManager* networkAccessManager = new QNetworkAccessManager(this);
connect(networkAccessManager, &QNetworkAccessManager::finished, this, &MainWindow::on_networkAccessManager_Finished);
networkAccessManager->get(QNetworkRequest(QUrl("https://api.github.com/repos/Rosalie241/RMG/releases/latest")));
@@ -893,6 +1040,13 @@ void MainWindow::timerEvent(QTimerEvent *event)
this->ui_GamesharkButtonTimerId = 0;
}
}
else if (timerId == this->ui_UpdateSaveStateSlotTimerId)
{
this->updateSaveStateSlotActions(CoreIsEmulationRunning(), false);
this->killTimer(timerId);
this->ui_UpdateSaveStateSlotTimerId = 0;
}
}
void MainWindow::on_EventFilter_KeyPressed(QKeyEvent *event)
@@ -960,6 +1114,10 @@ void MainWindow::on_networkAccessManager_Finished(QNetworkReply* reply)
{
if (reply->error())
{
if (!this->ui_SilentUpdateCheck)
{
this->showErrorMessage("Failed to check for updates!", reply->errorString());
}
reply->deleteLater();
return;
}
@@ -972,22 +1130,19 @@ void MainWindow::on_networkAccessManager_Finished(QNetworkReply* reply)
reply->deleteLater();
// make sure the current version is valid
// and not a dev version
if (currentVersion.size() != 6)
{
return;
}
// do nothing when versions match
if (currentVersion == latestVersion)
{
if (!this->ui_SilentUpdateCheck)
{
this->showErrorMessage("You're already on the latest version!");
}
return;
}
int ret = 0;
Dialog::UpdateDialog updateDialog(this, jsonObject);
Dialog::UpdateDialog updateDialog(this, jsonObject, !this->ui_SilentUpdateCheck);
ret = updateDialog.exec();
if (ret != QDialog::Accepted)
{
@@ -1026,7 +1181,7 @@ void MainWindow::on_Action_System_OpenRom(void)
QString romFile;
romFile = QFileDialog::getOpenFileName(this, "", "", "N64 ROMs & Disks (*.n64 *.z64 *.v64 *.ndd *.d64 *.zip)");
romFile = QFileDialog::getOpenFileName(this, "", "", "N64 ROMs & Disks (*.n64 *.z64 *.v64 *.ndd *.d64 *.zip *.7z)");
if (romFile.isEmpty())
{
@@ -1057,7 +1212,7 @@ void MainWindow::on_Action_System_OpenCombo(void)
QString cartRom, diskRom;
cartRom = QFileDialog::getOpenFileName(this, "", "", "N64 ROMs (*.n64 *.z64 *.v64 *.zip)");
cartRom = QFileDialog::getOpenFileName(this, "", "", "N64 ROMs (*.n64 *.z64 *.v64 *.zip *.7z)");
if (cartRom.isEmpty())
{
@@ -1209,6 +1364,15 @@ void MainWindow::on_Action_System_SaveState(void)
else
{
OnScreenDisplaySetMessage("Saved state to slot: " + std::to_string(CoreGetSaveStateSlot()));
// refresh savestate slot times in 1 second,
// kill any existing timers
if (this->ui_UpdateSaveStateSlotTimerId != 0)
{
this->killTimer(this->ui_UpdateSaveStateSlotTimerId);
this->ui_UpdateSaveStateSlotTimerId = 0;
}
this->ui_UpdateSaveStateSlotTimerId = this->startTimer(1000);
}
}
@@ -1287,13 +1451,36 @@ void MainWindow::on_Action_System_Load(void)
void MainWindow::on_Action_System_CurrentSaveState(int slot)
{
QAction* slotAction;
QString dateTimeText;
std::string message;
if (!CoreSetSaveStateSlot(slot))
{
this->showErrorMessage("CoreSetSaveStateSlot() Failed", QString::fromStdString(CoreGetError()));
}
else
{
OnScreenDisplaySetMessage("Selected save slot: " + std::to_string(slot));
slotAction = this->ui_SlotActions[slot];
dateTimeText = this->getSaveStateSlotDateTimeText(slotAction);
// construct OSD message
message = "Selected save slot: " + std::to_string(slot);
// add date and time when available
if (!dateTimeText.isEmpty())
{
message += " [";
message += dateTimeText.toStdString();
message += "]";
}
else
{
message += " [N/A]";
}
// display message
OnScreenDisplaySetMessage(message);
}
}
@@ -1381,6 +1568,11 @@ void MainWindow::on_Action_Settings_Settings(void)
void MainWindow::on_Action_View_Toolbar(bool checked)
{
if (!this->ui_ShowUI)
{
return;
}
CoreSettingsSetValue(SettingsID::GUI_Toolbar, checked);
this->toolBar->setVisible(checked);
this->ui_ShowToolbar = checked;
@@ -1388,6 +1580,11 @@ void MainWindow::on_Action_View_Toolbar(bool checked)
void MainWindow::on_Action_View_StatusBar(bool checked)
{
if (!this->ui_ShowUI)
{
return;
}
CoreSettingsSetValue(SettingsID::GUI_StatusBar, checked);
this->statusBar()->setVisible(checked);
this->ui_ShowStatusbar = checked;
@@ -1457,6 +1654,13 @@ void MainWindow::on_Action_Help_About(void)
dialog.exec();
}
void MainWindow::on_Action_Help_Update(void)
{
#ifdef UPDATER
this->checkForUpdates(false, true);
#endif // UPDATER
}
void MainWindow::on_Emulation_Started(void)
{
this->logDialog.Clear();
@@ -1517,7 +1721,7 @@ void MainWindow::on_RomBrowser_PlayGameWith(CoreRomType type, QString file)
}
else
{ // disk
mainRom = QFileDialog::getOpenFileName(this, "", "", "N64 ROMs (*.n64 *.z64 *.v64 *.zip)");
mainRom = QFileDialog::getOpenFileName(this, "", "", "N64 ROMs (*.n64 *.z64 *.v64 *.zip *.7z)");
otherRom = file;
}
@@ -1620,6 +1824,34 @@ void MainWindow::on_RomBrowser_EditGameSettings(QString file)
}
}
void MainWindow::on_RomBrowser_EditGameInputSettings(QString file)
{
bool isRefreshingRomList = this->ui_Widget_RomBrowser->IsRefreshingRomList();
if (isRefreshingRomList)
{
this->ui_Widget_RomBrowser->StopRefreshRomList();
}
if (!CoreOpenRom(file.toStdU32String()))
{
this->showErrorMessage("CoreOpenRom() Failed", QString::fromStdString(CoreGetError()));
return;
}
CorePluginsOpenROMConfig(CorePluginType::Input);
if (!CoreCloseRom())
{
this->showErrorMessage("CoreCloseRom() Failed", QString::fromStdString(CoreGetError()));
return;
}
if (isRefreshingRomList)
{
this->ui_Widget_RomBrowser->RefreshRomList();
}
}
void MainWindow::on_RomBrowser_Cheats(QString file)
{
bool isRefreshingRomList = this->ui_Widget_RomBrowser->IsRefreshingRomList();
@@ -1674,7 +1906,7 @@ void MainWindow::on_VidExt_SetWindowedMode(int width, int height, int bps, int f
this->showNormal();
}
if (this->menuBar()->isHidden())
if (this->ui_ShowMenubar && this->menuBar()->isHidden())
{
this->menuBar()->show();
}
@@ -1694,7 +1926,10 @@ void MainWindow::on_VidExt_SetWindowedMode(int width, int height, int bps, int f
this->ui_Widget_OpenGL->SetHideCursor(false);
}
this->removeFullscreenActions();
if (this->ui_ShowUI)
{
this->removeActions();
}
// only resize window when we're
// not returning from fullscreen
@@ -1731,7 +1966,10 @@ void MainWindow::on_VidExt_SetFullscreenMode(int width, int height, int bps, int
this->ui_Widget_OpenGL->SetHideCursor(true);
}
this->addFullscreenActions();
if (this->ui_ShowUI)
{
this->addActions();
}
}
void MainWindow::on_VidExt_ResizeWindow(int width, int height)
@@ -1750,7 +1988,24 @@ void MainWindow::on_VidExt_ResizeWindow(int width, int height)
if (!this->toolBar->isHidden())
{
height += this->toolBar->height();
Qt::ToolBarArea area = this->toolBarArea(this->toolBar);
// dont resize when toolbar is floating
if (this->toolBar->isFloating())
{
return;
}
if (area == Qt::ToolBarArea::TopToolBarArea ||
area == Qt::ToolBarArea::BottomToolBarArea)
{
height += this->toolBar->height();
}
else if (area == Qt::ToolBarArea::LeftToolBarArea ||
area == Qt::ToolBarArea::RightToolBarArea)
{
width += this->toolBar->width();
}
}
if (!this->statusBar()->isHidden())
@@ -1787,7 +2042,7 @@ void MainWindow::on_VidExt_ToggleFS(bool fullscreen)
this->showFullScreen();
}
if (!this->menuBar()->isHidden())
if (this->ui_ShowMenubar && !this->menuBar()->isHidden())
{
this->menuBar()->hide();
}
@@ -1807,7 +2062,10 @@ void MainWindow::on_VidExt_ToggleFS(bool fullscreen)
this->ui_Widget_OpenGL->SetHideCursor(true);
}
this->addFullscreenActions();
if (this->ui_ShowUI)
{
this->addActions();
}
}
else
{
@@ -1816,11 +2074,11 @@ void MainWindow::on_VidExt_ToggleFS(bool fullscreen)
this->showNormal();
}
if (this->menuBar()->isHidden())
if (this->ui_ShowMenubar && this->menuBar()->isHidden())
{
this->menuBar()->show();
}
if (this->ui_ShowToolbar && this->toolBar->isHidden())
{
this->toolBar->show();
@@ -1836,7 +2094,10 @@ void MainWindow::on_VidExt_ToggleFS(bool fullscreen)
this->ui_Widget_OpenGL->SetHideCursor(false);
}
this->removeFullscreenActions();
if (this->ui_ShowUI)
{
this->removeActions();
}
}
}
@@ -1885,3 +2146,21 @@ void MainWindow::on_Core_DebugCallback(CoreDebugMessageType type, QString contex
}
this->ui_TimerId = this->startTimer(this->ui_TimerTimeout * 1000);
}
void MainWindow::on_Core_StateCallback(CoreStateCallbackType type, int value)
{
if (type == CoreStateCallbackType::SaveStateLoaded)
{
if (value == 0)
{
OnScreenDisplaySetMessage("Failed to load save state.");
}
}
else if (type == CoreStateCallbackType::SaveStateSaved)
{
if (value == 0)
{
OnScreenDisplaySetMessage("Failed to save state.");
}
}
}
+64 -45
View File
@@ -47,19 +47,19 @@ class MainWindow : public QMainWindow, private Ui::MainWindow
MainWindow(void);
~MainWindow(void);
bool Init(QApplication*);
void OpenROM(QString, QString, bool, bool);
bool Init(QApplication* app, bool showUI);
void OpenROM(QString file, QString disk, bool fullscreen, bool quitAfterEmulation);
private:
Thread::EmulationThread *emulationThread;
Thread::EmulationThread *emulationThread = nullptr;
CoreCallbacks* coreCallBacks;
CoreCallbacks* coreCallBacks = nullptr;
QStackedWidget *ui_Widgets;
Widget::OGLWidget *ui_Widget_OpenGL;
Widget::RomBrowserWidget *ui_Widget_RomBrowser;
EventFilter *ui_EventFilter;
QLabel *ui_StatusBar_Label;
QStackedWidget *ui_Widgets = nullptr;
Widget::OGLWidget *ui_Widget_OpenGL = nullptr;
Widget::RomBrowserWidget *ui_Widget_RomBrowser = nullptr;
EventFilter *ui_EventFilter = nullptr;
QLabel *ui_StatusBar_Label = nullptr;
QByteArray ui_Geometry;
bool ui_Geometry_Maximized = false;
@@ -73,16 +73,26 @@ class MainWindow : public QMainWindow, private Ui::MainWindow
bool ui_QuitAfterEmulation = false;
bool ui_RefreshRomListAfterEmulation = false;
bool ui_ShowUI = false;
bool ui_ShowMenubar = false;
bool ui_ShowToolbar = false;
bool ui_ShowStatusbar = false;
bool ui_ManuallyPaused = true;
QList<QAction*> ui_Actions;
bool ui_AddedActions = false;
QList<QAction*> ui_SlotActions;
bool ui_SilentUpdateCheck = false;
int ui_TimerId = 0;
int ui_TimerTimeout = 0;
int ui_FullscreenTimerId = 0;
int ui_GamesharkButtonTimerId = 0;
int ui_UpdateSaveStateSlotTimerId = 0;
QString ui_WindowTitle;
@@ -91,43 +101,49 @@ class MainWindow : public QMainWindow, private Ui::MainWindow
void closeEvent(QCloseEvent *) Q_DECL_OVERRIDE;
void initializeUI();
void configureUI(QApplication*);
void configureTheme(QApplication*);
void showErrorMessage(QString, QString);
void updateUI(bool, bool);
void configureUI(QApplication* app, bool showUI);
void configureTheme(QApplication* app);
void showErrorMessage(QString text, QString details = "");
void updateUI(bool inEmulation, bool isPaused);
void storeGeometry(void);
void loadGeometry(void);
void initializeEmulationThread(void);
void connectEmulationThreadSignals(void);
void launchEmulationThread(QString, QString);
void launchEmulationThread(QString);
void launchEmulationThread(QString cartRom, QString diskRom = "");
QString getSaveStateSlotDateTimeText(QAction* action);
QString getSaveStateSlotText(QAction* action, int slot);
int getToolbarSettingAreaFromArea(Qt::ToolBarArea area);
Qt::ToolBarArea getToolbarAreaFromSettingArea(int value);
void configureActions(void);
void connectActionSignals(void);
void updateActions(bool, bool);
void updateActions(bool inEmulation, bool isPaused);
void updateSaveStateSlotActions(bool inEmulation, bool isPaused);
void addFullscreenActions(void);
void removeFullscreenActions(void);
void addActions(void);
void removeActions(void);
#ifdef UPDATER
void checkForUpdates(void);
void checkForUpdates(bool silent, bool force);
#endif // UPDATER
protected:
void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE;
void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
private slots:
void on_EventFilter_KeyPressed(QKeyEvent *);
void on_EventFilter_KeyReleased(QKeyEvent *);
void on_EventFilter_KeyPressed(QKeyEvent *event);
void on_EventFilter_KeyReleased(QKeyEvent *event);
void on_QGuiApplication_applicationStateChanged(Qt::ApplicationState);
void on_QGuiApplication_applicationStateChanged(Qt::ApplicationState state);
#ifdef UPDATER
void on_networkAccessManager_Finished(QNetworkReply *);
void on_networkAccessManager_Finished(QNetworkReply *reply);
#endif // UPDATER
void on_Action_System_OpenRom(void);
@@ -138,12 +154,12 @@ class MainWindow : public QMainWindow, private Ui::MainWindow
void on_Action_System_Pause(void);
void on_Action_System_Screenshot(void);
void on_Action_System_LimitFPS(void);
void on_Action_System_SpeedFactor(int);
void on_Action_System_SpeedFactor(int factor);
void on_Action_System_SaveState(void);
void on_Action_System_SaveAs(void);
void on_Action_System_LoadState(void);
void on_Action_System_Load(void);
void on_Action_System_CurrentSaveState(int);
void on_Action_System_CurrentSaveState(int slot);
void on_Action_System_Cheats(void);
void on_Action_System_GSButton(void);
void on_Action_System_Exit(void);
@@ -154,11 +170,11 @@ class MainWindow : public QMainWindow, private Ui::MainWindow
void on_Action_Settings_Input(void);
void on_Action_Settings_Settings(void);
void on_Action_View_Toolbar(bool);
void on_Action_View_StatusBar(bool);
void on_Action_View_GameList(bool);
void on_Action_View_GameGrid(bool);
void on_Action_View_UniformSize(bool);
void on_Action_View_Toolbar(bool checked);
void on_Action_View_StatusBar(bool checked);
void on_Action_View_GameList(bool checked);
void on_Action_View_GameGrid(bool checked);
void on_Action_View_UniformSize(bool checked);
void on_Action_View_Fullscreen(void);
void on_Action_View_RefreshRoms(void);
void on_Action_View_ClearRomCache(void);
@@ -166,27 +182,30 @@ class MainWindow : public QMainWindow, private Ui::MainWindow
void on_Action_Help_Github(void);
void on_Action_Help_About(void);
void on_Action_Help_Update(void);
void on_Emulation_Started(void);
void on_Emulation_Finished(bool);
void on_Emulation_Finished(bool ret);
void on_RomBrowser_PlayGame(QString);
void on_RomBrowser_PlayGameWith(CoreRomType, QString);
void on_RomBrowser_PlayGame(QString file);
void on_RomBrowser_PlayGameWith(CoreRomType type, QString file);
void on_RomBrowser_ChangeRomDirectory(void);
void on_RomBrowser_RomInformation(QString);
void on_RomBrowser_EditGameSettings(QString);
void on_RomBrowser_Cheats(QString);
void on_RomBrowser_RomInformation(QString file);
void on_RomBrowser_EditGameSettings(QString file);
void on_RomBrowser_EditGameInputSettings(QString file);
void on_RomBrowser_Cheats(QString file);
public slots:
void on_VidExt_Init(void);
void on_VidExt_SetupOGL(QSurfaceFormat, QThread *);
void on_VidExt_SetWindowedMode(int, int, int, int);
void on_VidExt_SetFullscreenMode(int, int, int, int);
void on_VidExt_ResizeWindow(int, int);
void on_VidExt_ToggleFS(bool);
void on_VidExt_SetupOGL(QSurfaceFormat format, QThread *thread);
void on_VidExt_SetWindowedMode(int width, int height, int bps, int flags);
void on_VidExt_SetFullscreenMode(int width, int height, int bps, int flags);
void on_VidExt_ResizeWindow(int width, int height);
void on_VidExt_ToggleFS(bool fullscreen);
void on_Core_DebugCallback(CoreDebugMessageType, QString, QString);
void on_Core_DebugCallback(CoreDebugMessageType type, QString context, QString message);
void on_Core_StateCallback(CoreStateCallbackType type, int value);
};
} // namespace UserInterface
+15 -1
View File
@@ -147,6 +147,8 @@
</property>
<addaction name="action_Help_Github"/>
<addaction name="separator"/>
<addaction name="action_Help_Update"/>
<addaction name="separator"/>
<addaction name="action_Help_About"/>
</widget>
<addaction name="menuSystem"/>
@@ -160,11 +162,14 @@
<string>toolBar</string>
</property>
<property name="movable">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
<property name="floatable">
<bool>false</bool>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
@@ -620,6 +625,15 @@
<string>300%</string>
</property>
</action>
<action name="action_Help_Update">
<property name="icon">
<iconset theme="download-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Check For Updates</string>
</property>
</action>
</widget>
<resources>
<include location="UIResources.qrc"/>
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M3 19h18v2H3v-2zm10-5.828L19.071 7.1l1.414 1.414L12 17 3.515 8.515 4.929 7.1 11 13.17V2h2v11.172z"/></svg>

After

Width:  |  Height:  |  Size: 235 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M3 19h18v2H3v-2zm10-5.828L19.071 7.1l1.414 1.414L12 17 3.515 8.515 4.929 7.1 11 13.17V2h2v11.172z" fill="#ffffff"/></svg>

After

Width:  |  Height:  |  Size: 250 B

+2
View File
@@ -11,6 +11,7 @@
<file alias="icons/black/svg/delete-back-line.svg">Resource/icons/black/svg/delete-back-line.svg</file>
<file alias="icons/black/svg/delete-bin-line.svg">Resource/icons/black/svg/delete-bin-line.svg</file>
<file alias="icons/black/svg/door-open-line.svg">Resource/icons/black/svg/door-open-line.svg</file>
<file alias="icons/black/svg/download-line.svg">Resource/icons/black/svg/download-line.svg</file>
<file alias="icons/black/svg/file-line.svg">Resource/icons/black/svg/file-line.svg</file>
<file alias="icons/black/svg/file-list-line.svg">Resource/icons/black/svg/file-list-line.svg</file>
<file alias="icons/black/svg/folder-open-line.svg">Resource/icons/black/svg/folder-open-line.svg</file>
@@ -40,6 +41,7 @@
<file alias="icons/white/svg/delete-back-line.svg">Resource/icons/white/svg/delete-back-line.svg</file>
<file alias="icons/white/svg/delete-bin-line.svg">Resource/icons/white/svg/delete-bin-line.svg</file>
<file alias="icons/white/svg/door-open-line.svg">Resource/icons/white/svg/door-open-line.svg</file>
<file alias="icons/white/svg/download-line.svg">Resource/icons/white/svg/download-line.svg</file>
<file alias="icons/white/svg/file-line.svg">Resource/icons/white/svg/file-line.svg</file>
<file alias="icons/white/svg/file-list-line.svg">Resource/icons/white/svg/file-list-line.svg</file>
<file alias="icons/white/svg/folder-open-line.svg">Resource/icons/white/svg/folder-open-line.svg</file>
@@ -65,9 +65,11 @@ void OGLWidget::resizeEvent(QResizeEvent *event)
void OGLWidget::timerEvent(QTimerEvent *event)
{
CoreSetVideoSize(this->width, this->height);
// remove current timer
this->killTimer(this->timerId);
this->timerId = 0;
// only remove current timer
// when setting the video size succeeds
if (CoreSetVideoSize(this->width, this->height))
{
this->killTimer(this->timerId);
this->timerId = 0;
}
}
@@ -11,6 +11,7 @@
#include <QLabel>
#include <QHBoxLayout>
#include <QTimerEvent>
using namespace UserInterface::Widget;
@@ -36,6 +37,12 @@ void RomBrowserLoadingWidget::SetWidgetIndex(int index)
this->widgetIndex = index;
}
void RomBrowserLoadingWidget::SetCurrentRomIndex(int index, int count)
{
this->romIndex = index;
this->romCount = count;
}
void RomBrowserLoadingWidget::on_RomBrowserWidget_currentChanged(int index)
{
// start timer when it isnt running
@@ -45,6 +52,12 @@ void RomBrowserLoadingWidget::on_RomBrowserWidget_currentChanged(int index)
{
if (this->loadingLabelTimerId == -1)
{
this->dotCount = 0;
this->romIndex = 0;
this->romCount = 0;
this->elapsedTimeSinceLoading.start();
// reset loading text
this->updateLoadingText();
this->loadingLabelTimerId = this->startTimer(1000);
}
}
@@ -52,20 +65,52 @@ void RomBrowserLoadingWidget::on_RomBrowserWidget_currentChanged(int index)
{
if (this->loadingLabelTimerId != -1)
{
this->elapsedTimeSinceLoading.invalidate();
this->killTimer(this->loadingLabelTimerId);
this->loadingLabelTimerId = -1;
}
}
}
void RomBrowserLoadingWidget::timerEvent(QTimerEvent *event)
void RomBrowserLoadingWidget::updateLoadingText()
{
if (this->loadingLabel->text().size() >= 10)
QString loadingText = "Loading";
if (this->elapsedTimeSinceLoading.isValid() &&
this->elapsedTimeSinceLoading.elapsed() >= 5000)
{
this->loadingLabel->setText("Loading");
QString romCountString = QString::number(this->romCount);
loadingText += " [";
loadingText += QString::number(this->romIndex).rightJustified(romCountString.size(), '0', false);
loadingText += "/";
loadingText += romCountString;
loadingText += "]";
}
if (dotCount <= 3)
{
for (int i = 0; i < dotCount; i++)
{
loadingText += ".";
}
dotCount++;
}
else
{
this->loadingLabel->setText(this->loadingLabel->text() + ".");
dotCount = 1;
}
this->loadingLabel->setText(loadingText);
}
void RomBrowserLoadingWidget::timerEvent(QTimerEvent *event)
{
if (event->timerId() != this->loadingLabelTimerId)
{
return;
}
this->updateLoadingText();
}
@@ -12,6 +12,7 @@
#include <QWidget>
#include <QLabel>
#include <QElapsedTimer>
namespace UserInterface
{
@@ -26,6 +27,8 @@ public:
void SetWidgetIndex(int index);
void SetCurrentRomIndex(int index, int count);
public slots:
void on_RomBrowserWidget_currentChanged(int index);
@@ -33,6 +36,13 @@ private:
QLabel* loadingLabel;
int loadingLabelTimerId = -1;
int widgetIndex = -1;
int romIndex = 0;
int romCount = 0;
int dotCount = 0;
QElapsedTimer elapsedTimeSinceLoading;
void updateLoadingText();
protected:
void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
@@ -98,21 +98,38 @@ RomBrowserWidget::RomBrowserWidget(QWidget *parent) : QStackedWidget(parent)
this->listViewWidget->horizontalHeader()->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
this->addWidget(this->listViewWidget);
connect(this->listViewWidget, &QTableView::doubleClicked, this, &RomBrowserWidget::on_DoubleClicked);
connect(this->listViewWidget, &QTableView::customContextMenuRequested, this, &RomBrowserListViewWidget::customContextMenuRequested);
connect(this->listViewWidget->horizontalHeader(), &QHeaderView::sortIndicatorChanged, this, &RomBrowserWidget::on_listViewWidget_sortIndicatorChanged);
connect(this->listViewWidget->horizontalHeader(), &QHeaderView::sectionResized, this, &RomBrowserWidget::on_listViewWidget_sectionResized);
connect(this->listViewWidget->horizontalHeader(), &QHeaderView::sectionMoved, this, &RomBrowserWidget::on_listViewWidget_sectionMoved);
connect(this->listViewWidget->horizontalHeader(), &QHeaderView::customContextMenuRequested, this, &RomBrowserWidget::on_listViewWidget_headerContextMenuRequested);
connect(this->listViewWidget, &Widget::RomBrowserListViewWidget::ZoomIn, this, &RomBrowserWidget::on_ZoomIn);
connect(this->listViewWidget, &Widget::RomBrowserListViewWidget::ZoomOut, this, &RomBrowserWidget::on_ZoomOut);
// TODO
// set up list view's columns
QStringList labels;
labels << "Name";
labels << "Internal Name";
labels << "MD5";
labels << "Format";
labels << "File Name";
labels << "File Ext.";
labels << "File Size";
labels << "I.D.";
labels << "Region";
this->listViewModel->setColumnCount(labels.size());
this->listViewModel->setHorizontalHeaderLabels(labels);
// set full names of list view's columns
this->columnNames << labels.at(0);
this->columnNames << labels.at(1);
this->columnNames << labels.at(2);
this->columnNames << "Game Format";
this->columnNames << labels.at(4);
this->columnNames << "File Extension";
this->columnNames << labels.at(6);
this->columnNames << "Game I.D.";
this->columnNames << "Game Region";
// configure grid view widget
this->gridViewWidget = new Widget::RomBrowserGridViewWidget(this);
this->gridViewModel = new QStandardItemModel(this);
@@ -128,14 +145,12 @@ RomBrowserWidget::RomBrowserWidget(QWidget *parent) : QStackedWidget(parent)
this->gridViewWidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
this->gridViewWidget->verticalScrollBar()->setSingleStep(15);
this->gridViewWidget->setWordWrap(true);
this->gridViewWidget->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
this->gridViewWidget->setFrameStyle(QFrame::NoFrame);
int iconWidth = CoreSettingsGetIntValue(SettingsID::RomBrowser_GridViewIconWidth);
int iconHeight = CoreSettingsGetIntValue(SettingsID::RomBrowser_GridViewIconHeight);
this->gridViewWidget->setIconSize(QSize(iconWidth, iconHeight));
this->addWidget(this->gridViewWidget);
connect(this->gridViewWidget, &QListView::doubleClicked, this, &RomBrowserWidget::on_DoubleClicked);
connect(this->gridViewWidget, &QListView::customContextMenuRequested, this, &RomBrowserListViewWidget::customContextMenuRequested);
connect(this->gridViewWidget, &QListView::iconSizeChanged, this, &RomBrowserWidget::on_gridViewWidget_iconSizeChanged);
connect(this->gridViewWidget, &Widget::RomBrowserGridViewWidget::ZoomIn, this, &RomBrowserWidget::on_ZoomIn);
connect(this->gridViewWidget, &Widget::RomBrowserGridViewWidget::ZoomOut, this, &RomBrowserWidget::on_ZoomOut);
@@ -144,7 +159,8 @@ RomBrowserWidget::RomBrowserWidget(QWidget *parent) : QStackedWidget(parent)
this->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
connect(this, &QStackedWidget::customContextMenuRequested, this, &RomBrowserWidget::customContextMenuRequested);
// configure context menu actions
// define context menu and its contents
this->contextMenu = new QMenu(this);
this->action_PlayGame = new QAction(this);
this->action_PlayGameWith = new QAction(this);
this->action_RefreshRomList = new QAction(this);
@@ -152,9 +168,17 @@ RomBrowserWidget::RomBrowserWidget(QWidget *parent) : QStackedWidget(parent)
this->action_ChangeRomDirectory = new QAction(this);
this->action_RomInformation = new QAction(this);
this->action_EditGameSettings = new QAction(this);
this->action_EditGameInputSettings = new QAction(this);
this->action_EditCheats = new QAction(this);
this->action_ResetColumnSizes = new QAction(this);
this->action_SetCoverImage = new QAction(this);
this->action_RemoveCoverImage = new QAction(this);
// define columns menu and its contents
this->menu_Columns = new QMenu(this);
this->action_ColumnsMenuEntry = new QAction(this);
// configure context menu contents
this->action_PlayGame->setText("Play Game");
this->action_PlayGameWith->setText("Play Game with Disk");
this->action_RefreshRomList->setText("Refresh ROM List");
@@ -162,7 +186,10 @@ RomBrowserWidget::RomBrowserWidget(QWidget *parent) : QStackedWidget(parent)
this->action_ChangeRomDirectory->setText("Change ROM Directory...");
this->action_RomInformation->setText("ROM Information");
this->action_EditGameSettings->setText("Edit Game Settings");
this->action_EditGameInputSettings->setText("Edit Game Input Settings");
this->action_EditCheats->setText("Edit Cheats");
this->action_ResetColumnSizes->setText("Reset Column Sizes");
this->menu_Columns->menuAction()->setText("Show/Hide Columns");
this->action_SetCoverImage->setText("Set Cover Image...");
this->action_RemoveCoverImage->setText("Remove Cover Image");
connect(this->action_PlayGame, &QAction::triggered, this, &RomBrowserWidget::on_Action_PlayGame);
@@ -172,12 +199,13 @@ RomBrowserWidget::RomBrowserWidget(QWidget *parent) : QStackedWidget(parent)
connect(this->action_ChangeRomDirectory, &QAction::triggered, this, &RomBrowserWidget::on_Action_ChangeRomDirectory);
connect(this->action_RomInformation, &QAction::triggered, this, &RomBrowserWidget::on_Action_RomInformation);
connect(this->action_EditGameSettings, &QAction::triggered, this, &RomBrowserWidget::on_Action_EditGameSettings);
connect(this->action_EditGameInputSettings, &QAction::triggered, this, &RomBrowserWidget::on_Action_EditGameInputSettings);
connect(this->action_EditCheats, &QAction::triggered, this, &RomBrowserWidget::on_Action_EditCheats);
connect(this->action_ResetColumnSizes, &QAction::triggered, this, &RomBrowserWidget::on_Action_ResetColumnSizes);
connect(this->action_SetCoverImage, &QAction::triggered, this, &RomBrowserWidget::on_Action_SetCoverImage);
connect(this->action_RemoveCoverImage, &QAction::triggered, this, &RomBrowserWidget::on_Action_RemoveCoverImage);
// configure context menu
this->contextMenu = new QMenu(this);
this->contextMenu->addAction(this->action_PlayGame);
this->contextMenu->addAction(this->action_PlayGameWith);
this->contextMenu->addSeparator();
@@ -189,8 +217,11 @@ RomBrowserWidget::RomBrowserWidget(QWidget *parent) : QStackedWidget(parent)
this->contextMenu->addAction(this->action_RomInformation);
this->contextMenu->addSeparator();
this->contextMenu->addAction(this->action_EditGameSettings);
this->contextMenu->addAction(this->action_EditGameInputSettings);
this->contextMenu->addAction(this->action_EditCheats);
this->contextMenu->addSeparator();
this->contextMenu->addAction(this->action_ResetColumnSizes);
this->contextMenu->addMenu(this->menu_Columns);
this->contextMenu->addAction(this->action_SetCoverImage);
this->contextMenu->addAction(this->action_RemoveCoverImage);
@@ -384,14 +415,8 @@ QIcon RomBrowserWidget::getCurrentCover(QString file, CoreRomHeader header, Core
{
// fixup file name
QString fixedName = name;
for (const char c : ":<>\"/\\|?*")
for (const QChar c : QString(":<>\"/\\|?*"))
{
// skip empty characters
if (c == '\0')
{
continue;
}
fixedName.replace(c, "_");
}
@@ -464,7 +489,10 @@ void RomBrowserWidget::customContextMenuRequested(QPoint position)
this->action_PlayGameWith->setEnabled(hasSelection);
this->action_RomInformation->setEnabled(hasSelection);
this->action_EditGameSettings->setEnabled(hasSelection);
this->action_EditGameInputSettings->setEnabled(hasSelection && CorePluginsHasROMConfig(CorePluginType::Input));
this->action_EditCheats->setEnabled(hasSelection);
this->action_ResetColumnSizes->setVisible(view == this->listViewWidget);
this->menu_Columns->menuAction()->setVisible(view == this->listViewWidget);
this->action_SetCoverImage->setEnabled(hasSelection);
this->action_SetCoverImage->setVisible(view == this->gridViewWidget);
this->action_RemoveCoverImage->setEnabled(hasSelection && !data.coverFile.isEmpty());
@@ -479,6 +507,11 @@ void RomBrowserWidget::customContextMenuRequested(QPoint position)
this->action_PlayGameWith->setText("Play Game with Disk");
}
if (view == this->listViewWidget)
{ // list view
this->generateColumnsMenu();
}
if (view == this->gridViewWidget)
{ // grid view
if (data.coverFile.isEmpty())
@@ -494,6 +527,24 @@ void RomBrowserWidget::customContextMenuRequested(QPoint position)
this->contextMenu->popup(this->mapToGlobal(position));
}
void RomBrowserWidget::generateColumnsMenu(void)
{
this->menu_Columns->clear();
for (int i = 0; i < this->listViewModel->columnCount(); i++)
{
int column = this->listViewWidget->horizontalHeader()->logicalIndex(i);
this->action_ColumnsMenuEntry = menu_Columns->addAction(this->columnNames.at(column));
this->action_ColumnsMenuEntry->setCheckable(true);
this->action_ColumnsMenuEntry->setChecked(!this->listViewWidget->horizontalHeader()->isSectionHidden(column));
connect(this->action_ColumnsMenuEntry, &QAction::toggled, [this, column](bool checked)
{
this->listViewWidget->horizontalHeader()->setSectionHidden(column, !checked);
});
}
}
void RomBrowserWidget::on_listViewWidget_sortIndicatorChanged(int logicalIndex, Qt::SortOrder sortOrder)
{
CoreSettingsSetValue(SettingsID::RomBrowser_ListViewSortSection, logicalIndex);
@@ -504,23 +555,42 @@ void RomBrowserWidget::on_listViewWidget_sectionResized(int logicalIndex, int ol
{
std::vector<int> columnSizes = CoreSettingsGetIntListValue(SettingsID::RomBrowser_ColumnSizes);
if (columnSizes.size() <= logicalIndex)
if (!this->listViewWidget->horizontalHeader()->stretchLastSection())
{
columnSizes.push_back(newWidth);
columnSizes.at(logicalIndex) = newWidth;
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnSizes, columnSizes);
}
else
{
if (this->listViewWidget->horizontalHeader()->visualIndex(logicalIndex) == (columnSizes.size() - 1))
std::vector<int> columnVisibility = CoreSettingsGetIntListValue(SettingsID::RomBrowser_ColumnVisibility);
if (newWidth == 0)
{
this->listViewWidget->horizontalHeader()->resizeSection(logicalIndex, columnSizes.at(logicalIndex));
columnVisibility.at(logicalIndex) = 0;
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnVisibility, columnVisibility);
}
else
{
columnSizes.at(logicalIndex) = newWidth;
columnVisibility.at(logicalIndex) = 1;
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnVisibility, columnVisibility);
int lastVisibleColumn = -1;
for (int i = 0; i < this->listViewModel->columnCount(); i++)
{
int column = this->listViewWidget->horizontalHeader()->logicalIndex(i);
if (!this->listViewWidget->horizontalHeader()->isSectionHidden(column))
{
lastVisibleColumn = column;
}
}
if (logicalIndex != lastVisibleColumn)
{
columnSizes.at(logicalIndex) = newWidth;
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnSizes, columnSizes);
}
}
}
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnSizes, columnSizes);
}
void RomBrowserWidget::on_listViewWidget_sectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex)
@@ -535,6 +605,12 @@ void RomBrowserWidget::on_listViewWidget_sectionMoved(int logicalIndex, int oldV
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnOrder, columnOrder);
}
void RomBrowserWidget::on_listViewWidget_headerContextMenuRequested(QPoint position)
{
this->generateColumnsMenu();
this->menu_Columns->popup(this->mapToGlobal(position));
}
void RomBrowserWidget::on_gridViewWidget_iconSizeChanged(const QSize& size)
{
CoreSettingsSetValue(SettingsID::RomBrowser_GridViewIconWidth, size.width());
@@ -563,9 +639,12 @@ void RomBrowserWidget::on_ZoomOut(void)
view->setIconSize(view->iconSize() - QSize(10, 10));
}
void RomBrowserWidget::on_RomBrowserThread_RomFound(QString file, CoreRomType type, CoreRomHeader header, CoreRomSettings settings)
void RomBrowserWidget::on_RomBrowserThread_RomFound(QString file, CoreRomType type, CoreRomHeader header, CoreRomSettings settings, int index, int count)
{
QString name;
QString gameFormat;
float fileSize;
QString fileSizeString;
QString coverFile;
QIcon coverIcon;
QVariant itemData;
@@ -582,6 +661,24 @@ void RomBrowserWidget::on_RomBrowserThread_RomFound(QString file, CoreRomType ty
name = QFileInfo(file).fileName();
}
// generate game format to use in UI
if (type == CoreRomType::Disk)
{
gameFormat = "Disk";
}
else
{
gameFormat = "Cartridge";
}
// generate file size to use in UI
fileSize = QFileInfo(file).size()/1048576.0;
fileSizeString = (QString::number(fileSize, 'f', 2)).append(" MB");
if (fileSizeString.size() == 7)
{
fileSizeString = fileSizeString.prepend(" ");
}
// retrieve cover image
coverIcon = this->getCurrentCover(file, header, settings, coverFile);
modelData.coverFile = coverFile;
@@ -605,6 +702,36 @@ void RomBrowserWidget::on_RomBrowserThread_RomFound(QString file, CoreRomType ty
listViewItem3->setText(QString::fromStdString(settings.MD5));
listViewItem3->setData(itemData);
listViewRow.append(listViewItem3);
// game format
QStandardItem* listViewItem4 = new QStandardItem();
listViewItem4->setText(gameFormat);
listViewItem4->setData(itemData);
listViewRow.append(listViewItem4);
// file name
QStandardItem* listViewItem5 = new QStandardItem();
listViewItem5->setText(QFileInfo(file).completeBaseName());
listViewItem5->setData(itemData);
listViewRow.append(listViewItem5);
// file extension
QStandardItem* listViewItem6 = new QStandardItem();
listViewItem6->setText(((QFileInfo(file).suffix()).prepend(".")).toUpper());
listViewItem6->setData(itemData);
listViewRow.append(listViewItem6);
// file size
QStandardItem* listViewItem7 = new QStandardItem();
listViewItem7->setText(fileSizeString);
listViewItem7->setData(itemData);
listViewRow.append(listViewItem7);
// game i.d.
QStandardItem* listViewItem8 = new QStandardItem();
listViewItem8->setText(QString::fromStdString(header.GameID));
listViewItem8->setData(itemData);
listViewRow.append(listViewItem8);
// region
QStandardItem* listViewItem9 = new QStandardItem();
listViewItem9->setText(QString::fromStdString(header.Region));
listViewItem9->setData(itemData);
listViewRow.append(listViewItem9);
this->listViewModel->appendRow(listViewRow);
QStandardItem* gridViewItem = new QStandardItem();
@@ -612,6 +739,9 @@ void RomBrowserWidget::on_RomBrowserThread_RomFound(QString file, CoreRomType ty
gridViewItem->setText(name);
gridViewItem->setData(itemData);
this->gridViewModel->appendRow(gridViewItem);
// update loading widget
this->loadingWidget->SetCurrentRomIndex(index, count);
}
void RomBrowserWidget::on_RomBrowserThread_Finished(bool canceled)
@@ -623,46 +753,80 @@ void RomBrowserWidget::on_RomBrowserThread_Finished(bool canceled)
this->gridViewModel->sort(0, Qt::SortOrder::AscendingOrder);
}
// retrieve column settings
std::vector<int> columnSizes = CoreSettingsGetIntListValue(SettingsID::RomBrowser_ColumnSizes);
std::vector<int> columnOrder = CoreSettingsGetIntListValue(SettingsID::RomBrowser_ColumnOrder);
std::vector<int> columnVisibility = CoreSettingsGetIntListValue(SettingsID::RomBrowser_ColumnVisibility);
// temporarily disable stretching last column in list view
this->listViewWidget->horizontalHeader()->setStretchLastSection(false);
// resize list view's columns
std::vector<int> columnSizes = CoreSettingsGetIntListValue(SettingsID::RomBrowser_ColumnSizes);
if (columnSizes.size() != this->listViewModel->columnCount())
// reset column sizes setting in config file if number of values is incorrect
if (!columnSizes.empty() &&
columnSizes.size() != this->listViewModel->columnCount())
{
// reset column sizes setting
columnSizes.clear();
columnSizes.resize(this->listViewModel->columnCount(), -1);
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnSizes, columnSizes);
this->listViewWidget->resizeColumnsToContents();
}
else
// update list view's column sizes
for (int i = 0; i < columnSizes.size(); i++)
{
// use settings' width (or resize to content if not already set)
for (int i = 0; i < columnSizes.size(); i++)
// set column widths to values specified in config file (or resize to content if not already specified)
if (columnSizes.at(i) == -1)
{
if (columnSizes.at(i) == -1)
{
this->listViewWidget->resizeColumnToContents(i);
columnSizes.at(i) = this->listViewWidget->columnWidth(i);
}
else
{
this->listViewWidget->setColumnWidth(i, columnSizes.at(i));
}
this->listViewWidget->resizeColumnToContents(i);
}
else
{
this->listViewWidget->setColumnWidth(i, columnSizes.at(i));
}
}
// enable stretching last column in list view
this->listViewWidget->horizontalHeader()->setStretchLastSection(true);
// update column order
std::vector<int> columnOrder = CoreSettingsGetIntListValue(SettingsID::RomBrowser_ColumnOrder);
// reset column order setting in config file if number of values is incorrect
if (!columnOrder.empty() &&
columnOrder.size() != this->listViewModel->columnCount())
{
columnOrder.clear();
for (int i = 0; i < this->listViewModel->columnCount(); i++)
{
columnOrder.push_back(i);
}
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnOrder, columnOrder);
}
// update list view's column order
for (int i = 0; i < columnOrder.size(); i++)
{
this->listViewWidget->horizontalHeader()->moveSection(this->listViewWidget->horizontalHeader()->visualIndex(i), columnOrder.at(i));
}
// reset column visibility setting in config file if number of values is incorrect
if (!columnVisibility.empty() &&
columnVisibility.size() != this->listViewModel->columnCount())
{
columnVisibility.clear();
columnVisibility.resize(this->listViewModel->columnCount(), 0);
for (int i = 0; i < 3; i++)
{
columnVisibility.at(i) = 1;
}
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnVisibility, columnVisibility);
}
// update list view's column visibilities
for (int i = 0; i < columnVisibility.size(); i++)
{
if (columnVisibility.at(i) == 0)
{
this->listViewWidget->horizontalHeader()->setSectionHidden(i, true);
}
}
if (!canceled)
{
if (this->listViewModel->rowCount() == 0)
@@ -733,11 +897,38 @@ void RomBrowserWidget::on_Action_EditGameSettings(void)
emit this->EditGameSettings(this->getCurrentRom());
}
void RomBrowserWidget::on_Action_EditGameInputSettings(void)
{
emit this->EditGameInputSettings(this->getCurrentRom());
}
void RomBrowserWidget::on_Action_EditCheats(void)
{
emit this->Cheats(this->getCurrentRom());
}
void RomBrowserWidget::on_Action_ResetColumnSizes(void)
{
std::vector<int> columnVisibility = CoreSettingsGetIntListValue(SettingsID::RomBrowser_ColumnVisibility);
this->listViewWidget->horizontalHeader()->setStretchLastSection(false);
for (int i = 0; i < this->listViewModel->columnCount(); i++)
{
this->listViewWidget->horizontalHeader()->setSectionHidden(i, false);
}
this->listViewWidget->resizeColumnsToContents();
this->listViewWidget->horizontalHeader()->setStretchLastSection(true);
for (int i = 0; i < columnVisibility.size(); i++)
{
if (columnVisibility.at(i) == 0)
{
this->listViewWidget->horizontalHeader()->setSectionHidden(i, true);
}
}
}
void RomBrowserWidget::on_Action_SetCoverImage(void)
{
QString sourceFile;
@@ -72,6 +72,8 @@ class RomBrowserWidget : public QStackedWidget
int listViewSortSection = 0;
int listViewSortOrder = 0;
QStringList columnNames;
QMenu* contextMenu;
QAction* action_PlayGame;
QAction* action_PlayGameWith;
@@ -80,10 +82,15 @@ class RomBrowserWidget : public QStackedWidget
QAction* action_ChangeRomDirectory;
QAction* action_RomInformation;
QAction* action_EditGameSettings;
QAction* action_EditGameInputSettings;
QAction* action_EditCheats;
QAction* action_ResetColumnSizes;
QAction* action_SetCoverImage;
QAction* action_RemoveCoverImage;
QMenu* menu_Columns;
QAction* action_ColumnsMenuEntry;
QString coversDirectory;
QStandardItemModel* getCurrentModel(void);
@@ -99,18 +106,20 @@ class RomBrowserWidget : public QStackedWidget
private slots:
void on_DoubleClicked(const QModelIndex& index);
void customContextMenuRequested(QPoint point);
void customContextMenuRequested(QPoint position);
void generateColumnsMenu(void);
void on_listViewWidget_sortIndicatorChanged(int logicalIndex, Qt::SortOrder sortOrder);
void on_listViewWidget_sectionResized(int logicalIndex, int oldWidth, int newWidth);
void on_listViewWidget_sectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex);
void on_listViewWidget_headerContextMenuRequested(QPoint position);
void on_gridViewWidget_iconSizeChanged(const QSize& size);
void on_ZoomIn(void);
void on_ZoomOut(void);
void on_RomBrowserThread_RomFound(QString file, CoreRomType type, CoreRomHeader header, CoreRomSettings settings);
void on_RomBrowserThread_RomFound(QString file, CoreRomType type, CoreRomHeader header, CoreRomSettings settings, int index, int count);
void on_RomBrowserThread_Finished(bool canceled);
void on_Action_PlayGame(void);
@@ -120,7 +129,9 @@ class RomBrowserWidget : public QStackedWidget
void on_Action_ChangeRomDirectory(void);
void on_Action_RomInformation(void);
void on_Action_EditGameSettings(void);
void on_Action_EditGameInputSettings(void);
void on_Action_EditCheats(void);
void on_Action_ResetColumnSizes(void);
void on_Action_SetCoverImage(void);
void on_Action_RemoveCoverImage(void);
@@ -128,6 +139,7 @@ class RomBrowserWidget : public QStackedWidget
void PlayGame(QString);
void PlayGameWith(CoreRomType, QString);
void EditGameSettings(QString);
void EditGameInputSettings(QString);
void Cheats(QString);
void ChangeRomDirectory(void);
void RomInformation(QString);
+42 -6
View File
@@ -18,6 +18,10 @@
#include <iostream>
#include <cstdlib>
#ifndef _WIN32
#include <signal.h>
#endif
//
// Local Functions
//
@@ -66,6 +70,11 @@ void message_handler(QtMsgType type, const QMessageLogContext &context, const QS
std::cerr << typeString << localMsg.constData() << std::endl;
}
void signal_handler(int sig)
{
QGuiApplication::quit();
}
//
// Exported Functions
//
@@ -75,10 +84,25 @@ int main(int argc, char **argv)
// install message handler
qInstallMessageHandler(message_handler);
#ifndef _WIN32
// install signal handler
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
#endif
#ifdef FORCE_XCB
setenv("QT_QPA_PLATFORM", "xcb", 1);
#endif // FORCE_XCB
#ifndef _WIN32
// ensure the default OpenGL format
// doesn't have vsync enabled by default,
// only needed for linux (for now)
QSurfaceFormat format = QSurfaceFormat::defaultFormat();
format.setSwapInterval(0);
QSurfaceFormat::setDefaultFormat(format);
#endif
QApplication app(argc, argv);
UserInterface::MainWindow window;
@@ -100,9 +124,14 @@ int main(int argc, char **argv)
QCommandLineOption corePathOption("core-path", "Changes the path where the core library is stored", "path");
QCommandLineOption pluginPathOption("plugin-path", "Changes the path where the plugins are stored", "path");
QCommandLineOption sharedDataPathOption("shared-data-path", "Changes the path where the shared data is stored", "path");
corePathOption.setFlags(QCommandLineOption::HiddenFromHelp);
pluginPathOption.setFlags(QCommandLineOption::HiddenFromHelp);
sharedDataPathOption.setFlags(QCommandLineOption::HiddenFromHelp);
#endif // PORTABLE_INSTALL
QCommandLineOption debugMessagesOption({"d", "debug-messages"}, "Prints debug callback messages to stdout");
QCommandLineOption fullscreenOption({"f", "fullscreen"}, "Launches ROM in fullscreen mode");
QCommandLineOption quitAfterEmulation({"q", "quit-after-emulation"}, "Quits RMG when emulation has finished");
QCommandLineOption noGuiOption({"n", "nogui"}, "Hides GUI elements (menubar, toolbar, statusbar)");
QCommandLineOption quitAfterEmulationOption({"q", "quit-after-emulation"}, "Quits RMG when emulation has finished");
QCommandLineOption diskOption("disk", "64DD Disk to open ROM in combination with", "64DD Disk");
#ifndef PORTABLE_INSTALL
@@ -110,8 +139,10 @@ int main(int argc, char **argv)
parser.addOption(pluginPathOption);
parser.addOption(sharedDataPathOption);
#endif // PORTABLE_INSTALL
parser.addOption(debugMessagesOption);
parser.addOption(fullscreenOption);
parser.addOption(quitAfterEmulation);
parser.addOption(noGuiOption);
parser.addOption(quitAfterEmulationOption);
parser.addOption(diskOption);
parser.addPositionalArgument("ROM", "ROM to open");
@@ -137,18 +168,23 @@ int main(int argc, char **argv)
}
#endif // PORTABLE_INSTALL
// print debug callbacks to stdout if needed
CoreSetPrintDebugCallback(parser.isSet(debugMessagesOption));
// initialize window
if (!window.Init(&app))
if (!window.Init(&app, !parser.isSet(noGuiOption)))
{
return 1;
}
window.show();
QStringList args = parser.positionalArguments();
if (!args.empty())
{
window.OpenROM(args.at(0), parser.value(diskOption), parser.isSet(fullscreenOption), parser.isSet(quitAfterEmulation));
window.OpenROM(args.at(0), parser.value(diskOption), parser.isSet(fullscreenOption), parser.isSet(quitAfterEmulationOption));
}
// show window
window.show();
return app.exec();
}
}