Compare commits
131 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 32a39afc75 | |||
| fd967cc2a3 | |||
| 8c0bb09667 | |||
| 8c753d6cfe | |||
| 276e681f29 | |||
| f23b17e1b8 | |||
| f1e10fa4b1 | |||
| be67cd03cb | |||
| d7dfe12fb4 | |||
| be437afd2f | |||
| f72688773a | |||
| fb328d8d92 | |||
| 36e6d2fcc7 | |||
| 7b3293341b | |||
| 0a7b72a51b | |||
| 6265973cc6 | |||
| f1edc47a80 | |||
| 8f60d5c80f | |||
| c42489fa81 | |||
| 66b60c988a | |||
| 5d20e98aba | |||
| 617ee3f96c | |||
| 083f7c2e4f | |||
| a8ea1795bf | |||
| 8a6cb4b5a8 | |||
| 53edf065a5 | |||
| bf65be483d | |||
| 1e90047368 | |||
| abd1160f87 | |||
| 55d7dd9d89 | |||
| b7eb1afb86 | |||
| 25ddb4a531 | |||
| 79f7c2224b | |||
| 8adda4fc7d | |||
| 5d23743133 | |||
| 2558e5d6a6 | |||
| 859b81b7e0 | |||
| 30369f58a9 | |||
| 30afc80a64 | |||
| 949eee8d08 | |||
| 1fae30bd33 | |||
| d8817bf0f3 | |||
| 5279b10b67 | |||
| 391f46be22 | |||
| 44809bf28f | |||
| 3cd113c46f | |||
| 3d195c6a4d | |||
| 423d30ac29 | |||
| b07b73e005 | |||
| 418d9c4684 | |||
| 1801a48eaa | |||
| 8e8fbcdd2e | |||
| d5834de5e7 | |||
| a52e3fe1e5 | |||
| eb261bc2bf | |||
| 7b5f735714 | |||
| 404c2c4f43 | |||
| 57f1a33e51 | |||
| fa277352b0 | |||
| f502984e05 | |||
| c205b5bfd3 | |||
| c6625e137d | |||
| 0ad7e1d715 | |||
| 1f8d5be9a7 | |||
| 21673affbb | |||
| a0a1255ef3 | |||
| 206a5ec7f6 | |||
| 8661273568 | |||
| 6aed340831 | |||
| f7bfb6aea1 | |||
| c5ae117cf8 | |||
| a1c9dc3f12 | |||
| 0f3e70706d | |||
| 722ca67b87 | |||
| 981897df8c | |||
| 3a066dfc03 | |||
| 870481e34e | |||
| 9f5f2334d7 | |||
| 330a66c81c | |||
| 92b4d4dc32 | |||
| 531fab51be | |||
| 3f027fad63 | |||
| 6eb46dd63c | |||
| 70830ae016 | |||
| 8a88a736ad | |||
| d580d2be9a | |||
| 0e3fc0e981 | |||
| 4907b2dd32 | |||
| 3ad2a5760e | |||
| e474a09642 | |||
| f5296c9f79 | |||
| f8e1ed3920 | |||
| 9aeca88946 | |||
| 3961c066be | |||
| 4aeb3da6eb | |||
| bf9e370ddd | |||
| 7c72fa98fd | |||
| 0824586db9 | |||
| 8a22c6d929 | |||
| 8f76619d7d | |||
| d94d9fc5d7 | |||
| 38312f8add | |||
| d52b1e1b5a | |||
| 06c9d9b826 | |||
| 20a669dbbb | |||
| 68c8c431a2 | |||
| d6b1fdfa7b | |||
| 6ac9208c7f | |||
| fdcfaf3fad | |||
| dd08dfafc8 | |||
| 22a019abb1 | |||
| e112ae75eb | |||
| 0de1073094 | |||
| 18a1a6afe6 | |||
| 149bd86a89 | |||
| dbe67853dc | |||
| 4f30be19b1 | |||
| 0347033d89 | |||
| 5fc36d5743 | |||
| c745ec18bb | |||
| 0e84317fbc | |||
| b7df075dec | |||
| da3e30f735 | |||
| 9bd0ea0ba6 | |||
| 91df63c660 | |||
| bea8abd60d | |||
| 86bb226db4 | |||
| 5bbdc7f821 | |||
| f23b0ca493 | |||
| 538b503bcb | |||
| cabc56550b |
@@ -9,11 +9,14 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: hendrikmuhs/ccache-action@v1.2.5
|
||||
with:
|
||||
key: Linux
|
||||
- name: Install Packages
|
||||
run: |
|
||||
sudo apt-get -qq update
|
||||
sudo apt-get upgrade
|
||||
sudo apt-get -y install cmake libhidapi-dev libsamplerate0-dev libspeex-dev libminizip-dev libsdl2-dev libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev pkg-config zlib1g-dev binutils-dev libspeexdsp-dev qtbase5-dev libqt5svg5-dev build-essential nasm git zip
|
||||
sudo apt-get -y install cmake libhidapi-dev libsamplerate0-dev libspeex-dev libminizip-dev libsdl2-dev libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev pkg-config zlib1g-dev binutils-dev libspeexdsp-dev qt6-base-dev libqt6svg6-dev build-essential nasm git zip
|
||||
- name: Prepare Environment
|
||||
run: |
|
||||
echo "GIT_REVISION=$(git describe --tags --always)" >> $GITHUB_ENV
|
||||
@@ -32,6 +35,9 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: hendrikmuhs/ccache-action@v1.2.5
|
||||
with:
|
||||
key: Windows
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
path-type: inherit
|
||||
@@ -45,7 +51,7 @@ jobs:
|
||||
mingw-w64-x86_64-libpng
|
||||
mingw-w64-x86_64-SDL2
|
||||
mingw-w64-x86_64-jasper
|
||||
mingw-w64-x86_64-qt5
|
||||
mingw-w64-x86_64-qt6
|
||||
mingw-w64-x86_64-SDL2
|
||||
mingw-w64-x86_64-hidapi
|
||||
mingw-w64-x86_64-speexdsp
|
||||
@@ -53,6 +59,7 @@ jobs:
|
||||
mingw-w64-x86_64-python3-pip
|
||||
mingw-w64-x86_64-python3-pyopenssl
|
||||
mingw-w64-x86_64-nasm
|
||||
mingw-w64-x86_64-minizip
|
||||
git
|
||||
- name: Prepare Environment
|
||||
run: |
|
||||
@@ -62,6 +69,9 @@ jobs:
|
||||
- name: Build RMG (Portable)
|
||||
run: ./Source/Script/Build.sh Release
|
||||
shell: msys2 {0}
|
||||
- name: Download Styles
|
||||
run: ./Source/Script/DownloadStyles.sh
|
||||
shell: msys2 {0}
|
||||
- name: Create Installer
|
||||
run: .\Build\Release\Source\Installer\CreateInstaller.bat
|
||||
- name: Upload RMG (Portable)
|
||||
|
||||
@@ -5,6 +5,10 @@ cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
option(PORTABLE_INSTALL "Portable Installation" ON)
|
||||
option(NO_GIT_CLONE "Disables git clone usage for 3rdParty dependencies" OFF)
|
||||
option(UPDATER "Enables updater" ${PORTABLE_INSTALL})
|
||||
option(DISCORD_RPC "Enables Discord Rich Presence" ON)
|
||||
option(USE_QT5 "Enables Qt5 instead of Qt6 (will be removed in the future)" OFF)
|
||||
option(USE_CCACHE "Enables usage of ccache when ccache has been found" ON)
|
||||
|
||||
project(RMG)
|
||||
|
||||
@@ -17,11 +21,25 @@ execute_process(
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
if (USE_CCACHE)
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if (CCACHE_FOUND)
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
|
||||
else(CCACHE_FOUND)
|
||||
set(USE_CCACHE OFF)
|
||||
endif(CCACHE_FOUND)
|
||||
endif(USE_CCACHE)
|
||||
|
||||
if (NOT PORTABLE_INSTALL AND (WIN32 OR MSYS))
|
||||
message(WARNING "Not-Portable build not supported on windows, re-enabling PORTABLE_INSTALL!")
|
||||
set(PORTABLE_INSTALL ON)
|
||||
endif()
|
||||
|
||||
if (NOT PORTABLE_INSTALL AND UPDATER)
|
||||
message(WARNING "Not-Portable builds don't support the updater, disabling UPDATER")
|
||||
set(UPDATER OFF)
|
||||
endif()
|
||||
|
||||
if (PORTABLE_INSTALL)
|
||||
set(CMAKE_INSTALL_PREFIX "")
|
||||
set(INSTALL_PATH "Bin/${CMAKE_BUILD_TYPE}")
|
||||
@@ -41,6 +59,16 @@ else()
|
||||
set(ICON_INSTALL_PATH "share/icons/hicolor/scalable/apps/")
|
||||
endif()
|
||||
|
||||
if (USE_QT5)
|
||||
set(QT_VERSION "Qt5")
|
||||
set(USE_QT6 OFF)
|
||||
else(USE_QT5)
|
||||
set(QT_VERSION "Qt6")
|
||||
set(USE_QT6 ON)
|
||||
endif(USE_QT5)
|
||||
|
||||
add_subdirectory(Source/3rdParty)
|
||||
|
||||
add_subdirectory(Source/RMG-Core)
|
||||
add_subdirectory(Source/RMG)
|
||||
add_subdirectory(Source/RMG-Audio)
|
||||
@@ -63,11 +91,10 @@ if (WIN32)
|
||||
)
|
||||
endif()
|
||||
|
||||
add_subdirectory(Source/3rdParty)
|
||||
install(FILES ${MUPEN64PLUSCORE_LIB}
|
||||
DESTINATION ${CORE_INSTALL_PATH}
|
||||
)
|
||||
install(FILES ${MUPEN64PLUSCORE_INI} Data/font.ttf Data/stylesheet.qss
|
||||
install(FILES ${MUPEN64PLUSCORE_INI} Data/font.ttf
|
||||
DESTINATION ${DATA_INSTALL_PATH}
|
||||
)
|
||||
file(GLOB GENERATED_CHEAT_FILES ${CMAKE_SOURCE_DIR}/Data/Cheats/Generated/*.cht)
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
[0CA6AEDA-BB9CFDD9-C:45]
|
||||
Name=Carnivale - Cenzo's Adventure (USA) (Prototype)
|
||||
|
||||
$Infinite Max Silver & Gold Coins
|
||||
Note=This seems to act as Health?
|
||||
810A2E7E 001E
|
||||
810A2E80 001E
|
||||
810A2E82 001E
|
||||
|
||||
$Infinite Max Peas
|
||||
Note=Max Pea Shooter Ammo
|
||||
810A2E7A 001E
|
||||
|
||||
$Unlock Everything
|
||||
Note=This Unlocks All Items in Single & All Multi Player Characters and Tracks.(Thanks Retroben!)
|
||||
810A2E90 0003
|
||||
810A2E92 87F9
|
||||
810A2E94 87F9
|
||||
|
||||
$Press L for Warp Select (Single Mode)
|
||||
Note=Press the L-Button as you go through a door (Thanks SubDrag!)
|
||||
D00A3359 0020
|
||||
800CA85B 00??
|
||||
01 Blue Background Race
|
||||
02 Dark Mountains Race
|
||||
03 Purple/Yellow Mountains Race
|
||||
04 Cloud Floor Race (from the locked main area)
|
||||
05 Main Area
|
||||
06 Maze
|
||||
07 King Race Super Rat Ride
|
||||
08 Mallet Game
|
||||
09 Duck Game
|
||||
0A Puppet Show (Come back later)
|
||||
0B Rock Paper Scissors Game
|
||||
0C Create Password
|
||||
0D Main Menu
|
||||
0E Select New Game
|
||||
0F Boss Intro Guy with hammer
|
||||
10 Options Menu
|
||||
11 Boss Intro Meet Strongman
|
||||
12 Main Menu
|
||||
|
||||
$Max Strength in Mallet Game
|
||||
811B08A6 0162
|
||||
|
||||
$Perfect Aim In Mallet Game (Line up and Shoot)
|
||||
Note=Use with Max Strength in Mallet Game. Wait until the Eyeball is past the 2 Red Lines (centre) and then press A
|
||||
811B0BD4 FFF2
|
||||
811B0B28 FDD2
|
||||
811605C8 FDD2
|
||||
81153148 FDD2
|
||||
|
||||
$1 Lap to Race (All Characters & Races)
|
||||
Note=For Single and Multi Player Modes. This will display 1 of 3, but on the first checkpoint you will get the message "You win" 1 Lap to race will also make you come in 1st and win. a big thanks to Parasyte for working with me on this! You are "Magic" lol
|
||||
81060020 2400
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
[7BD65F9E-76B6A083-C:45]
|
||||
Name=007 - The World is Not Enough (U) (Prototype - 2020 release)
|
||||
|
||||
$Enable Cheats Menu
|
||||
800811F0 0005
|
||||
|
||||
$Invincible
|
||||
80130ACD 00??
|
||||
01 On
|
||||
00 Off
|
||||
|
||||
$All Weapons
|
||||
80130AE0 00??
|
||||
01 On
|
||||
00 Off
|
||||
|
||||
$All Gadgets
|
||||
80130AE1 00??
|
||||
01 On
|
||||
00 Off
|
||||
|
||||
$All Missions
|
||||
80130AE2 00??
|
||||
01 On
|
||||
00 Off
|
||||
|
||||
$Infinite Health (All Levels)
|
||||
81045D68 2400
|
||||
|
||||
$Infinite Ammo (All Guns for all Levels)
|
||||
Note=The Clip will count down but you will never run out of Ammo.
|
||||
81040730 2400
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
[8825E18B-3297746B-C:50]
|
||||
Name=Aidyn Chronicles - The First Mage (Europe) (Prototype) (2)
|
||||
|
||||
$Infinite\Max Health
|
||||
80279308 001E
|
||||
|
||||
$Infinite\99 Health Potions
|
||||
Note=Do Not put this cheat on until you have collected your 1st Health Potion from the 1st Cheat or you will not be able to get into the Sub menu and Continue the game.
|
||||
80278D3B 0063
|
||||
|
||||
$Have\Max Gold
|
||||
50000401 0000
|
||||
80277AA5 00FF
|
||||
|
||||
$Have\Max Total XP
|
||||
50000401 0000
|
||||
8027931D 00FF
|
||||
|
||||
$Have\Max Total XP Remaning to Start
|
||||
Note=This will give you 16777215 Total XP Remaning to start with and after your 1st batle will allow you to buy your Max Stats
|
||||
50000401 0000
|
||||
80279321 00FF
|
||||
|
||||
$Play As Character
|
||||
Note=Enable this at the start of a Game, before a next Level, or before a Cutscene to become your chosen option.
|
||||
810E108E ????
|
||||
25F9 Alaron
|
||||
2A43 Marari Female
|
||||
2C17 Spirit
|
||||
2CC0 Marari Male
|
||||
2D4A GiantBat
|
||||
2E82 Chaos Trooper
|
||||
3094 Gryphon
|
||||
324D Ogre
|
||||
32CC GiantRat
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
[8EAA1A2C-61C09930-C:00]
|
||||
Name=Aidyn Chronicles - The First Mage (USA) (Prototype)
|
||||
|
||||
$Infinite\Max Health
|
||||
80275AA1 001E
|
||||
|
||||
$Infinite\99 Health Potions
|
||||
Note=Do Not put this cheat on until you have collected your 1st Health Potion from the 1st Cheat or you will not be able to get into the Sub menu and Continue the game.
|
||||
8027540F 0063
|
||||
|
||||
$Have\Max Gold
|
||||
50000401 0000
|
||||
8027423E 00FF
|
||||
|
||||
$Have\Max Total XP
|
||||
50000401 0000
|
||||
80275AB6 00FF
|
||||
|
||||
$Have\Max Total XP Remaning to Start
|
||||
Note=This will give you 16777215 Total XP Remaning to start with and after your 1st batle will allow you to buy your Max Stats
|
||||
50000401 0000
|
||||
80275ABA 00FF
|
||||
|
||||
$Play As Character
|
||||
Note=Enable this at the start of a Game, before a next Level, or before a Cutscene to become your chosen option.
|
||||
810E0D6E ????
|
||||
25F9 Alaron
|
||||
2A43 Marari Female
|
||||
2C17 Spirit
|
||||
2CC0 Marari Male
|
||||
2D4A GiantBat
|
||||
2E82 Chaos Trooper
|
||||
3094 Gryphon
|
||||
324D Ogre
|
||||
32CC GiantRat
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
[A92E0966-341C3912-C:45]
|
||||
Name=007 - The World is Not Enough (U) (Beta) [!]
|
||||
|
||||
$Invincible
|
||||
8011E157 00??
|
||||
01 On
|
||||
00 Off
|
||||
|
||||
$Have All Gadgets
|
||||
8011E159 00??
|
||||
01 On
|
||||
00 Off
|
||||
|
||||
$Enable All Missions
|
||||
8011E15A 00??
|
||||
01 On
|
||||
00 Off
|
||||
|
||||
$Have All Weapons
|
||||
8011E158 00??
|
||||
01 On
|
||||
00 Off
|
||||
|
||||
$Infinite Health (All Levels)
|
||||
8106AC88 2400
|
||||
|
||||
$Infinite Ammo (All Guns for all Levels)
|
||||
8106246C 2400
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
[D0E29F11-E029063F-C:50]
|
||||
Name=Aidyn Chronicles - The First Mage (Europe) (Prototype) (1)
|
||||
|
||||
$Infinite\Max Health
|
||||
80279208 001E
|
||||
|
||||
$Infinite\99 Health Potions
|
||||
Note=Do Not put this cheat on until you have collected your 1st Health Potion from the 1st Cheat or you will not be able to get into the Sub menu and Continue the game.
|
||||
80278C3B 0063
|
||||
|
||||
$Have\Max Gold
|
||||
50000401 0000
|
||||
802779A5 00FF
|
||||
|
||||
$Have\Max Total XP
|
||||
50000401 0000
|
||||
8027921D 00FF
|
||||
|
||||
$Have\Max Total XP Remaning to Start
|
||||
Note=This will give you 16777215 Total XP Remaning to start with and after your 1st batle will allow you to buy your Max Stats
|
||||
50000401 0000
|
||||
80279221 00FF
|
||||
|
||||
$Play As Character
|
||||
Note=Enable this at the start of a Game, before a next Level, or before a Cutscene to become your chosen option.
|
||||
810E0F9E ????
|
||||
25F9 Alaron
|
||||
2A43 Marari Female
|
||||
2C17 Spirit
|
||||
2CC0 Marari Male
|
||||
2D4A GiantBat
|
||||
2E82 Chaos Trooper
|
||||
3094 Gryphon
|
||||
324D Ogre
|
||||
32CC GiantRat
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
[E48E01F5-E6E51F9B-C:59]
|
||||
Name=Carmageddon 64 (E) (M4) (Eng-Spa-Fre-Ita) [!]
|
||||
|
||||
$Have Everything Unlocked
|
||||
Note=This will unlock Cars, Races, Missions and the in-built Cheat Menu. This will also replace all the Zombies with Dinosaurs. To access Cheat menu options: Pause Game: Use Control Stick, to scroll the Cheat Menu. Press A, to activate Cheats
|
||||
801BE43D 000F
|
||||
|
||||
$Have Infinite\Invunerability
|
||||
81097EAC ????
|
||||
0BBB On
|
||||
0000 Off
|
||||
|
||||
$Have Infinite\Free Repairs
|
||||
81097EC4 ????
|
||||
0BBB On
|
||||
0000 Off
|
||||
|
||||
$Have Infinite\Underwater Ability
|
||||
81097EF4 ????
|
||||
0BBB On
|
||||
0000 Off
|
||||
|
||||
$Have Infinite\Turbo
|
||||
81097E34 ????
|
||||
0BBB On
|
||||
0000 Off
|
||||
|
||||
$Have Infinite\Mega Turbo
|
||||
81097E4C ????
|
||||
0BBB On
|
||||
0000 Off
|
||||
|
||||
$Have Infinite\Hot Rod
|
||||
81097E64 ????
|
||||
0BBB On
|
||||
0000 Off
|
||||
|
||||
$Have Infinite\Turbo Nitrous
|
||||
81097E7C ????
|
||||
0BBB On
|
||||
0000 Off
|
||||
|
||||
$Have Infinite\Frozen Opponents
|
||||
81097F24 ????
|
||||
0BBB On
|
||||
0000 Off
|
||||
|
||||
$Have Infinite\Grip-O-Matic Tires
|
||||
8109805C ????
|
||||
0BBB On
|
||||
0000 Off
|
||||
|
||||
$Have Infinite\Mine Dropping Ability
|
||||
81098118 ????
|
||||
0064 On
|
||||
0000 Off
|
||||
|
||||
$Freeze Timer at 04:59
|
||||
Note=Do not enable until count down to race is finished
|
||||
811BE21E 3A70
|
||||
|
||||
$Max Credits
|
||||
Note=This is also Infinite until disabled
|
||||
811BE29A FFFF
|
||||
|
||||
$Max Kills
|
||||
Note=This will automatically Clear the stage if enabled and go back to the stage menu
|
||||
81094BEE 01F4
|
||||
|
||||
$Have All Groups Completed
|
||||
Note=This gives you all Cups for all Groups.
|
||||
50002801 0000
|
||||
801BE35C 0002
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
[F1642508-BEE60CF6-C:45]
|
||||
Name=Bust-A-Move 3 DX (USA) (Prototype)
|
||||
|
||||
$Always Have\guide line on
|
||||
800558CC 0082
|
||||
|
||||
$Pointer always active
|
||||
D0055BA0 0002
|
||||
80055BA0 0082
|
||||
|
||||
$Play As Select\Player 1
|
||||
800E1E50 00??
|
||||
00 Bubbloon
|
||||
01 Twinkie
|
||||
02 Prettio
|
||||
03 Marina
|
||||
04 Musashi
|
||||
05 Luna
|
||||
06 Jack
|
||||
07 SSB
|
||||
08 Dragoon
|
||||
09 Gnome
|
||||
10 Monkey
|
||||
11 furby? (looks like 2 balloons)
|
||||
12 Blue Gnome
|
||||
13 1 of the two Ballons
|
||||
14 Water under ballons
|
||||
|
||||
$Play As Select\Player 2
|
||||
800E1E58 00??
|
||||
00 Bubbloon
|
||||
01 Twinkie
|
||||
02 Prettio
|
||||
03 Marina
|
||||
04 Musashi
|
||||
05 Luna
|
||||
06 Jack
|
||||
07 SSB
|
||||
08 Dragoon
|
||||
09 Gnome
|
||||
10 Monkey
|
||||
11 furby? (looks like 2 balloons)
|
||||
12 Blue Gnome
|
||||
13 1 of the two Ballons
|
||||
14 Water under ballons
|
||||
|
||||
$Next Bubble Select\Player 1
|
||||
800EBA19 00??
|
||||
00 No Bubble
|
||||
01 Red
|
||||
02 Green
|
||||
03 Blue
|
||||
04 Yellow
|
||||
05 Orange
|
||||
06 Purple
|
||||
07 White
|
||||
08 Black
|
||||
|
||||
$Next Bubble Select\Player 2
|
||||
800EBB09 00??
|
||||
00 No Bubble
|
||||
01 Red
|
||||
02 Green
|
||||
03 Blue
|
||||
04 Yellow
|
||||
05 Orange
|
||||
06 Purple
|
||||
07 White
|
||||
08 Black
|
||||
|
||||
$Press GS Button to Reset Player 2 score to 0
|
||||
8809C5C0 0000
|
||||
8809C5C2 0000
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
[F7AA4F819F41CB4236792A8145684627]
|
||||
Name=Yoshi's Story (CHN) (iQue)
|
||||
|
||||
$Infinite\Health
|
||||
Note=This is for All Yoshis All levels
|
||||
50000804 0000
|
||||
8012FD1F 00??
|
||||
08 Infinite Health
|
||||
09 Infinite Max Health
|
||||
|
||||
$Infinite\Eggs (Once You Get One)
|
||||
Note=This is for All Yoshis All levels
|
||||
8103E52C 2400
|
||||
|
||||
$Infinite\Lives
|
||||
Note=This is for All Yoshis All levels
|
||||
8012FD5F 00FF
|
||||
|
||||
$Press GS Button To Have All Fruit
|
||||
8812F93B 001E
|
||||
|
||||
$Enable All Levels (Trial Mode)
|
||||
8112FDC4 FFFF
|
||||
8112FDC6 FFFF
|
||||
|
||||
@@ -11,8 +11,8 @@ license=('GPLv3')
|
||||
provides=("$_pkgname")
|
||||
conflicts=("$_pkgname")
|
||||
|
||||
depends=("hidapi" "libsamplerate" "minizip" "sdl2" "zlib" "freetype2" "qt5-base" "qt5-svg")
|
||||
makedepends=("git" "pkg-config" "nasm" "cmake" "rustup")
|
||||
depends=("hidapi" "libsamplerate" "minizip" "sdl2" "zlib" "freetype2" "qt6-base" "qt6-svg" "xdg-user-dirs")
|
||||
makedepends=("git" "pkg-config" "nasm" "cmake" "cargo")
|
||||
|
||||
source=("git+https://github.com/Rosalie241/${_pkgname}.git")
|
||||
sha256sums=('SKIP')
|
||||
|
||||
|
After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 206 KiB After Width: | Height: | Size: 445 KiB |
|
After Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 274 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 47 KiB |
@@ -18,13 +18,126 @@
|
||||
<caption>During A Game</caption>
|
||||
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/InGame.png</image>
|
||||
</screenshot>
|
||||
<screenshot type="default">
|
||||
<caption>Cheats</caption>
|
||||
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/Cheats.png</image>
|
||||
</screenshot>
|
||||
<screenshot type="default">
|
||||
<caption>Settings</caption>
|
||||
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/Settings.png</image>
|
||||
</screenshot>
|
||||
<screenshot type="default">
|
||||
<caption>Input Settings</caption>
|
||||
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/InputSettings.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<description/>
|
||||
<releases>
|
||||
<release version="v0.2.9" date="2023-01-03" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix wrong 64DD Disk extension being listed in empty ROM browser</li>
|
||||
<li>Fix memory corruption when having 64DD Disk files</li>
|
||||
<li>Fix possible crash when render window wasn't visible yet</li>
|
||||
<li>Fix RMG changing the current directory on non-portable installs</li>
|
||||
<li>Remove Qt warning messages (you can view them by setting RMG_SHOW_DEBUG_QT_MESSAGES to 1)</li>
|
||||
<li>Change "Choose ROM Directory" to "Change ROM Directory"</li>
|
||||
<li>Add -q/--quit-after-emulation commandline option</li>
|
||||
<li>Add 2 more icons to menubar menus/items</li>
|
||||
<li>Add "Current Save State" tab to Hotkeys tab in settings dialog (this allows you to use a hotkey to change save state slots)</li>
|
||||
<li>Improve behavior of Hotkeys tab in settings dialog</li>
|
||||
<li>Improve behavior of window when exiting RMG while in-game</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.2.8" date="2023-01-01" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix 'Uniform Size (Grid View)' not being disabled during emulation</li>
|
||||
<li>Fix toolbar not respecting the view setting</li>
|
||||
<li>Fix being stuck at the loading screen when having more ROMs than the ROM search limit</li>
|
||||
<li>Improve error message when opening a ROM fails</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.2.7" date="2022-12-29" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix core error not showing when the statusbar was hidden</li>
|
||||
<li>Fix .ndd/.64d not being in the empty ROM Browser widget</li>
|
||||
<li>Fix .jpg/.jpeg files not working on covers on Windows</li>
|
||||
<li>Fix updater script not copying subdirectories on Windows (for portable installs)</li>
|
||||
<li>Fix 64DD Disks which required the development IPL not working</li>
|
||||
<li>Fix 64DD Disks showing the wrong internal ROM name (this fix requires clearing the ROM cache)</li>
|
||||
<li>Fix cover filenames allowing invalid characters (they will now be replaced by _)</li>
|
||||
<li>Add more icons to View menu in the menu bar</li>
|
||||
<li>Add 'Uniform Size (Grid View)' to View menu in the menu bar</li>
|
||||
<li>Add smooth scrolling to List View and Grid View</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.2.6" date="2022-12-28" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix default save state/game directory being incorrect on first run (on non-portable installs)</li>
|
||||
<li>Fix angrylion-rdp-plus not loading settings correctly</li>
|
||||
<li>Fix cheat settings not moving over when renaming a cheat</li>
|
||||
<li>Remove fullscreen resolution combobox from GLideN64 because it did nothing</li>
|
||||
<li>Remove File menu from menu bar</li>
|
||||
<li>Implement disk support without requiring a cartridge</li>
|
||||
<li>Add toolbar</li>
|
||||
<li>Add View menu to menu bar</li>
|
||||
<li>Add Grid view to ROM browser</li>
|
||||
<li>Add icons to all menu bar items</li>
|
||||
<li>Add log dialog</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.2.5" date="2022-12-14" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix incorrect controller being selected in RMG-Input when having 2 controllers with the same name</li>
|
||||
<li>Fix some UI elements being enabled while the 'Controller Is Plugged In' checkbox is disabled in RMG-Input</li>
|
||||
<li>Fix extra padding being added when having a controller selected and opening RMG-Input</li>
|
||||
<li>Fix creating a new profile in GLideN64</li>
|
||||
<li>Add Z-Trigger visualization in RMG-Input</li>
|
||||
<li>Remove Debugger checkbox in the settings dialog because it did nothing</li>
|
||||
<li>Remove About buttons in the plugin tab of the settings dialog because it did nothing</li>
|
||||
<li>Implement close button on all dialogs</li>
|
||||
<li>Implement custom style support (for Windows only)</li>
|
||||
<li>Implement the ability to remove/reset the main profile in RMG-Input</li>
|
||||
<li>Rename Interface tab in settings dialog to User Interface</li>
|
||||
<li>Migrate to Qt6 (currently the flatpak will remain Qt5)</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.2.4" date="2022-12-08" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix Discord Rich Presence breaking when opening the settings dialog</li>
|
||||
<li>Fix install update window not showing</li>
|
||||
<li>Fix 'Limit FPS' not working with new RMG-Audio (this disables the 'synchronize audio' option)</li>
|
||||
<li>Implement support for Japanese characters in the ROM header</li>
|
||||
<li>Implement dynamic buffer sizes in the ROM browser cache (this reduces the ROM browser cache size)</li>
|
||||
<li>Add more cheats from Gent</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.2.3" date="2022-12-05" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Add updater for portable installations</li>
|
||||
<li>Add Discord Rich Presence</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.2.2" date="2022-12-03" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
|
||||
@@ -8,9 +8,9 @@ set(THIRDPARTY_DIR ${CMAKE_BINARY_DIR}/Source/3rdParty)
|
||||
find_program(RUST_CARGO cargo)
|
||||
if(${RUST_CARGO} STREQUAL "RUST_CARGO-NOTFOUND")
|
||||
message(WARNING "mupen64plus-input-gca will not be built due to not having cargo installed")
|
||||
set(BUILD_INPUT_GCA "0")
|
||||
set(BUILD_INPUT_GCA OFF)
|
||||
else()
|
||||
set(BUILD_INPUT_GCA "1")
|
||||
set(BUILD_INPUT_GCA ON)
|
||||
endif()
|
||||
|
||||
set(M64P_CORE_DIR ${THIRDPARTY_DIR}/mupen64plus-core)
|
||||
@@ -24,9 +24,20 @@ else(WIN32)
|
||||
set(CORE_FILE "libmupen64plus.so")
|
||||
endif(WIN32)
|
||||
|
||||
set(BASE_CMAKE_CONFIGURE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER})
|
||||
if (USE_CCACHE)
|
||||
set(CMAKE_CONFIGURE_ARGS ${BASE_CMAKE_CONFIGURE_ARGS} -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache)
|
||||
set(MAKE_CC_COMPILER "ccache ${CMAKE_C_COMPILER}")
|
||||
set(MAKE_CXX_COMPILER "ccache ${CMAKE_CXX_COMPILER}")
|
||||
else(USE_CCACHE)
|
||||
set(CMAKE_CONFIGURE_ARGS ${BASE_CMAKE_CONFIGURE_ARGS})
|
||||
set(MAKE_CC_COMPILER "${CMAKE_C_COMPILER}")
|
||||
set(MAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER}")
|
||||
endif(USE_CCACHE)
|
||||
|
||||
if(NOT NO_GIT_CLONE)
|
||||
set(MUPEN64PLUSCORE_URL "https://github.com/mupen64plus/mupen64plus-core")
|
||||
set(MUPEN64PLUSCORE_TAG "f63e1b35063241738d848f73311496b76c8aa918")
|
||||
set(MUPEN64PLUSCORE_URL "https://github.com/Rosalie241/mupen64plus-core")
|
||||
set(MUPEN64PLUSCORE_TAG "3b6523edd467eb9224310e0862005c7e5ae9c290")
|
||||
|
||||
set(MUPEN64PLUS_RSP_CXD4_URL "https://github.com/mupen64plus/mupen64plus-rsp-cxd4")
|
||||
set(MUPEN64PLUS_RSP_CXD4_TAG "39f79201baa15890c4cbae92f2215a634cc3ee6d")
|
||||
@@ -44,13 +55,16 @@ if(NOT NO_GIT_CLONE)
|
||||
set(MUPEN64PLUS_INPUT_GCA_TAG "21639fb13dfa797a7c0949ffd9bbda9a3456fc69")
|
||||
|
||||
set(MUPEN64PLUS_GFX_ANGRYLION_URL "https://github.com/Rosalie241/angrylion-rdp-plus")
|
||||
set(MUPEN64PLUS_GFX_ANGRYLION_TAG "9d71074f6b71750e99ad06a713f28a9c32ad15cb")
|
||||
set(MUPEN64PLUS_GFX_ANGRYLION_TAG "158e74d4ec1c818289cd19c3a05e498c3ceff758")
|
||||
|
||||
set(MUPEN64PLUS_GFX_GLIDEN64_URL "https://github.com/gonetz/GLideN64")
|
||||
set(MUPEN64PLUS_GFX_GLIDEN64_TAG "a2ecb92e954fdc1dd1130b331935f04381b29e28")
|
||||
set(MUPEN64PLUS_GFX_GLIDEN64_TAG "7bbde56cf08ff96108efb592848e5b6eaac293c9")
|
||||
|
||||
set(MUPEN64PLUS_GFX_PARALLEL_URL "https://github.com/Rosalie241/parallel-rdp-standalone")
|
||||
set(MUPEN64PLUS_GFX_PARALLEL_TAG "693f607728aca78d94ba5d45b0ce119b4ccbcd8c")
|
||||
set(MUPEN64PLUS_GFX_PARALLEL_TAG "88d3626362e41aa9b011fca1f65e1c1237ddb3b2")
|
||||
|
||||
set(DISCORD_RPC_URL "https://github.com/discord/discord-rpc")
|
||||
set(DISCORD_RPC_TAG "963aa9f3e5ce81a4682c6ca3d136cddda614db33")
|
||||
endif(NOT NO_GIT_CLONE)
|
||||
|
||||
ExternalProject_Add(mupen64plus-core
|
||||
@@ -62,7 +76,7 @@ ExternalProject_Add(mupen64plus-core
|
||||
GIT_REPOSITORY ${MUPEN64PLUSCORE_URL}
|
||||
GIT_TAG ${MUPEN64PLUSCORE_TAG}
|
||||
|
||||
BUILD_COMMAND make all OSD=0 NEW_DYNAREC=1 TARGET=${CORE_FILE} DEBUG=$<CONFIG:Debug> KEYBINDINGS=0
|
||||
BUILD_COMMAND $(MAKE) all OSD=0 NEW_DYNAREC=1 TARGET=${CORE_FILE} DEBUG=$<CONFIG:Debug> KEYBINDINGS=0 CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
|
||||
BUILD_IN_SOURCE False
|
||||
|
||||
BINARY_DIR ${M64P_CORE_DIR}/projects/unix
|
||||
@@ -81,7 +95,7 @@ ExternalProject_Add(mupen64plus-rsp-cxd4
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_RSP_CXD4_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_RSP_CXD4_TAG}
|
||||
|
||||
BUILD_COMMAND make all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug> POSTFIX=
|
||||
BUILD_COMMAND $(MAKE) all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug> POSTFIX= CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
|
||||
BUILD_IN_SOURCE False
|
||||
|
||||
BINARY_DIR ${THIRDPARTY_DIR}/mupen64plus-rsp-cxd4/projects/unix
|
||||
@@ -99,7 +113,7 @@ ExternalProject_Add(mupen64plus-rsp-hle
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_RSP_HLE_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_RSP_HLE_TAG}
|
||||
|
||||
BUILD_COMMAND make all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug>
|
||||
BUILD_COMMAND $(MAKE) all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug> CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
|
||||
BUILD_IN_SOURCE False
|
||||
|
||||
BINARY_DIR ${THIRDPARTY_DIR}/mupen64plus-rsp-hle/projects/unix
|
||||
@@ -117,7 +131,7 @@ ExternalProject_Add(mupen64plus-rsp-parallel
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
BUILD_IN_SOURCE True
|
||||
CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
CMAKE_ARGS ${CMAKE_CONFIGURE_ARGS}
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-rsp-parallel/mupen64plus-rsp-parallel.${SO_EXT}
|
||||
DEPENDS mupen64plus-core
|
||||
@@ -132,7 +146,7 @@ ExternalProject_Add(mupen64plus-input-raphnetraw
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_INPUT_RAPHNET_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_INPUT_RAPHNET_TAG}
|
||||
|
||||
BUILD_COMMAND make all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug>
|
||||
BUILD_COMMAND $(MAKE) all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug> CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
|
||||
BUILD_IN_SOURCE False
|
||||
|
||||
BINARY_DIR ${THIRDPARTY_DIR}/mupen64plus-input-raphnetraw/projects/unix
|
||||
@@ -141,7 +155,7 @@ ExternalProject_Add(mupen64plus-input-raphnetraw
|
||||
DEPENDS mupen64plus-core
|
||||
)
|
||||
|
||||
if (${BUILD_INPUT_GCA} STREQUAL "1")
|
||||
if (BUILD_INPUT_GCA)
|
||||
ExternalProject_Add(mupen64plus-input-gca
|
||||
SOURCE_DIR mupen64plus-input-gca/
|
||||
|
||||
@@ -157,7 +171,7 @@ if (${BUILD_INPUT_GCA} STREQUAL "1")
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-input-gca/target/release/${GCA_LIB}
|
||||
DEPENDS mupen64plus-core
|
||||
)
|
||||
endif()
|
||||
endif(BUILD_INPUT_GCA)
|
||||
|
||||
set(GLIDEN64_DIR "${THIRDPARTY_DIR}/mupen64plus-video-GLideN64")
|
||||
set(GLIDEN64_BUILD_DIR "${GLIDEN64_DIR}/projects/cmake")
|
||||
@@ -181,7 +195,7 @@ ExternalProject_Add(mupen64plus-video-angrylion-plus
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
BUILD_IN_SOURCE True
|
||||
CMAKE_ARGS -DBUILD_MUPEN64PLUS=ON -DBUILD_PROJECT64=OFF -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
CMAKE_ARGS -DBUILD_MUPEN64PLUS=ON -DBUILD_PROJECT64=OFF -DUSE_QT5=${USE_QT5} ${CMAKE_CONFIGURE_ARGS}
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-video-angrylion-plus/mupen64plus-video-angrylion-plus.${SO_EXT}
|
||||
DEPENDS mupen64plus-core
|
||||
@@ -196,7 +210,7 @@ ExternalProject_Add(mupen64plus-video-GLideN64
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
BUILD_IN_SOURCE False
|
||||
CMAKE_ARGS -DMUPENPLUSAPI=ON -DMUPENPLUSAPI_GLIDENUI=ON -DUSE_SYSTEM_LIBS=ON -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
CMAKE_ARGS -DMUPENPLUSAPI=ON -DMUPENPLUSAPI_GLIDENUI=ON -DGLIDENUI_QT6=${USE_QT6} -DUSE_SYSTEM_LIBS=ON ${CMAKE_CONFIGURE_ARGS}
|
||||
|
||||
SOURCE_SUBDIR ./src/
|
||||
BINARY_DIR ${GLIDEN64_BUILD_DIR}
|
||||
@@ -215,12 +229,28 @@ ExternalProject_Add(mupen64plus-video-parallel
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
BUILD_IN_SOURCE True
|
||||
CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
CMAKE_ARGS -DUSE_QT5=${USE_QT5} ${CMAKE_CONFIGURE_ARGS}
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-video-parallel/mupen64plus-video-parallel.${SO_EXT}
|
||||
DEPENDS mupen64plus-core
|
||||
)
|
||||
|
||||
if (DISCORD_RPC)
|
||||
ExternalProject_Add(discord-rpc
|
||||
SOURCE_DIR discord-rpc
|
||||
|
||||
GIT_REPOSITORY ${DISCORD_RPC_URL}
|
||||
GIT_TAG ${DISCORD_RPC_TAG}
|
||||
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
BUILD_IN_SOURCE True
|
||||
CMAKE_ARGS -DBUILD_EXAMPLES=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON ${CMAKE_CONFIGURE_ARGS}
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/discord-rpc/src/libdiscord-rpc.a
|
||||
)
|
||||
endif(DISCORD_RPC)
|
||||
|
||||
ExternalProject_Get_property(mupen64plus-core BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUSCORE_LIB ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
set(MUPEN64PLUSCORE_INI ${M64P_CORE_DIR}/data/mupen64plus.ini PARENT_SCOPE)
|
||||
@@ -237,10 +267,10 @@ set(MUPEN64PLUS_PLUGIN_RSP_PARALLEL ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
ExternalProject_Get_property(mupen64plus-input-raphnetraw BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_INPUT_RAPHNET ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
|
||||
if (${BUILD_INPUT_GCA} STREQUAL "1")
|
||||
if (BUILD_INPUT_GCA)
|
||||
ExternalProject_Get_property(mupen64plus-input-gca BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_INPUT_GCA ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
endif()
|
||||
endif(BUILD_INPUT_GCA)
|
||||
|
||||
ExternalProject_Get_property(mupen64plus-video-angrylion-plus BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_GFX_ANGRYLION ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
@@ -250,3 +280,8 @@ set(MUPEN64PLUS_PLUGIN_GFX_GLIDEN64 ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
|
||||
ExternalProject_Get_property(mupen64plus-video-parallel BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_GFX_PARALLEL ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
|
||||
if (DISCORD_RPC)
|
||||
ExternalProject_Get_property(discord-rpc BUILD_BYPRODUCTS)
|
||||
set(DISCORD_RPC_LIB ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
endif(DISCORD_RPC)
|
||||
|
||||
@@ -7,7 +7,7 @@ set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
|
||||
find_package(Qt5 COMPONENTS Gui Widgets Core REQUIRED)
|
||||
find_package(${QT_VERSION} COMPONENTS Gui Widgets Core REQUIRED)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(SDL2 REQUIRED sdl2)
|
||||
@@ -36,7 +36,7 @@ target_link_libraries(RMG-Audio
|
||||
${SDL2_LIBRARIES}
|
||||
${SPEEX_LIBRARIES}
|
||||
${SAMPLERATE_LIBRARIES}
|
||||
Qt5::Gui Qt5::Widgets
|
||||
${QT_VERSION}::Gui ${QT_VERSION}::Widgets
|
||||
)
|
||||
|
||||
target_include_directories(RMG-Audio PRIVATE
|
||||
|
||||
@@ -12,11 +12,13 @@
|
||||
|
||||
using namespace UserInterface;
|
||||
|
||||
MainDialog::MainDialog(QWidget* parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
|
||||
MainDialog::MainDialog(QWidget* parent) : QDialog(parent)
|
||||
{
|
||||
this->setupUi(this);
|
||||
this->setWindowIcon(QIcon(":Resource/RMG.png"));
|
||||
|
||||
this->setIconsForEmulationInfoText();
|
||||
|
||||
this->volumeSlider->setValue(CoreSettingsGetIntValue(SettingsID::Audio_Volume));
|
||||
this->muteCheckBox->setChecked(CoreSettingsGetBoolValue(SettingsID::Audio_Muted));
|
||||
|
||||
@@ -38,6 +40,21 @@ MainDialog::~MainDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void MainDialog::setIconsForEmulationInfoText(void)
|
||||
{
|
||||
QLabel* labels[] = {
|
||||
this->infoIconLabel_0
|
||||
};
|
||||
|
||||
QIcon infoIcon = QIcon::fromTheme("information-line");
|
||||
QPixmap infoIconPixmap = infoIcon.pixmap(16, 16);
|
||||
|
||||
for (QLabel* label : labels)
|
||||
{
|
||||
label->setPixmap(infoIconPixmap);
|
||||
}
|
||||
}
|
||||
|
||||
void MainDialog::hideEmulationInfoText(void)
|
||||
{
|
||||
QHBoxLayout *layouts[] = {this->emulationInfoLayout};
|
||||
|
||||
@@ -25,6 +25,7 @@ public:
|
||||
~MainDialog(void);
|
||||
|
||||
private:
|
||||
void setIconsForEmulationInfoText(void);
|
||||
void hideEmulationInfoText(void);
|
||||
|
||||
private slots:
|
||||
|
||||
@@ -324,7 +324,7 @@
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="emulationInfoLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<widget class="QLabel" name="infoIconLabel_0">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -335,7 +335,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="UIResources.qrc">:/Resource/Info.ico</pixmap>
|
||||
<pixmap>:/Resource/Info.ico</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>false</bool>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,6 +1,5 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file>Resource/RMG.png</file>
|
||||
<file>Resource/Info.ico</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -9,6 +9,9 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(SDL2 REQUIRED sdl2)
|
||||
pkg_check_modules(MINIZIP REQUIRED minizip)
|
||||
if (WIN32)
|
||||
pkg_check_modules(ICONV REQUIRED iconv)
|
||||
endif(WIN32)
|
||||
|
||||
configure_file(Config.hpp.in Config.hpp)
|
||||
|
||||
@@ -18,6 +21,7 @@ set(RMG_CORE_SOURCES
|
||||
m64p/ConfigApi.cpp
|
||||
m64p/PluginApi.cpp
|
||||
CachedRomHeaderAndSettings.cpp
|
||||
ConvertStringEncoding.cpp
|
||||
Settings/Settings.cpp
|
||||
SpeedLimiter.cpp
|
||||
RomSettings.cpp
|
||||
@@ -29,10 +33,12 @@ set(RMG_CORE_SOURCES
|
||||
SaveState.cpp
|
||||
Callback.cpp
|
||||
Plugins.cpp
|
||||
Version.cpp
|
||||
Cheats.cpp
|
||||
VidExt.cpp
|
||||
Video.cpp
|
||||
Error.cpp
|
||||
Unzip.cpp
|
||||
Core.cpp
|
||||
Key.cpp
|
||||
Rom.cpp
|
||||
@@ -50,8 +56,15 @@ else()
|
||||
)
|
||||
endif()
|
||||
|
||||
if (DISCORD_RPC)
|
||||
list(APPEND RMG_CORE_SOURCES
|
||||
DiscordRpc.cpp
|
||||
)
|
||||
add_definitions(-DDISCORD_RPC)
|
||||
endif(DISCORD_RPC)
|
||||
|
||||
if (PORTABLE_INSTALL)
|
||||
add_definitions(-DPORTABLE_INSTALL)
|
||||
add_definitions(-DPORTABLE_INSTALL)
|
||||
endif(PORTABLE_INSTALL)
|
||||
|
||||
add_library(RMG-Core STATIC ${RMG_CORE_SOURCES})
|
||||
@@ -61,13 +74,20 @@ if(UNIX)
|
||||
endif(UNIX)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(RMG-Core wsock32 ws2_32)
|
||||
target_link_libraries(RMG-Core wsock32 ws2_32 ${ICONV_LIBRARIES})
|
||||
endif(WIN32)
|
||||
|
||||
target_link_libraries(RMG-Core
|
||||
${MINIZIP_LIBRARIES}
|
||||
)
|
||||
|
||||
if (DISCORD_RPC)
|
||||
target_link_libraries(RMG-Core
|
||||
${DISCORD_RPC_LIB}
|
||||
)
|
||||
add_dependencies(RMG-Core discord-rpc)
|
||||
endif(DISCORD_RPC)
|
||||
|
||||
target_include_directories(RMG-Core PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
|
||||
@@ -18,16 +18,30 @@
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#else // Linux
|
||||
#include <linux/limits.h>
|
||||
#endif // _WIN32
|
||||
|
||||
//
|
||||
// Local Defines
|
||||
//
|
||||
|
||||
#define MAX_FILENAME_LEN 4096
|
||||
#define ROMHEADER_NAME_LEN 21
|
||||
#ifdef _WIN32
|
||||
#define MAX_FILENAME_LEN MAX_PATH
|
||||
#else // Linux
|
||||
#define MAX_FILENAME_LEN PATH_MAX
|
||||
#endif // _WIN32
|
||||
#define ROMHEADER_NAME_LEN 256
|
||||
#define GOODNAME_LEN 256
|
||||
#define MD5_LEN 33
|
||||
|
||||
#define CACHE_FILE_MAGIC "RMGCoreHeaderAndSettingsCache_03"
|
||||
#ifdef _WIN32
|
||||
#define CACHE_FILE_MAGIC "RMGCoreHeaderAndSettingsCacheWindows_04"
|
||||
#else // Linux
|
||||
#define CACHE_FILE_MAGIC "RMGCoreHeaderAndSettingsCacheLinux_04"
|
||||
#endif // _WIN32
|
||||
#define CACHE_FILE_ITEMS_MAX 10000
|
||||
|
||||
//
|
||||
@@ -90,6 +104,7 @@ void CoreReadRomHeaderAndSettingsCache(void)
|
||||
char headerNameBuf[ROMHEADER_NAME_LEN];
|
||||
char goodNameBuf[GOODNAME_LEN];
|
||||
char md5Buf[MD5_LEN];
|
||||
uint32_t size;
|
||||
l_CacheEntry cacheEntry;
|
||||
|
||||
inputStream.open(get_cache_file_name(), std::ios::binary);
|
||||
@@ -108,27 +123,32 @@ void CoreReadRomHeaderAndSettingsCache(void)
|
||||
|
||||
// read all file entries
|
||||
#define FREAD(x) inputStream.read((char*)&x, sizeof(x))
|
||||
#define FREAD_STR(x) inputStream.read((char*)x, sizeof(x))
|
||||
#define FREAD_STR(x, y) inputStream.read((char*)x, y)
|
||||
while (!inputStream.eof())
|
||||
{
|
||||
// reset buffers
|
||||
size = 0;
|
||||
memset(fileNameBuf, 0, sizeof(fileNameBuf));
|
||||
memset(headerNameBuf, 0, sizeof(headerNameBuf));
|
||||
memset(goodNameBuf, 0, sizeof(goodNameBuf));
|
||||
memset(md5Buf, 0, sizeof(md5Buf));
|
||||
|
||||
// file info
|
||||
FREAD_STR(fileNameBuf);
|
||||
FREAD(size);
|
||||
FREAD_STR(fileNameBuf, size);
|
||||
cacheEntry.fileName = std::filesystem::path(fileNameBuf);
|
||||
FREAD(cacheEntry.fileTime);
|
||||
// header
|
||||
FREAD_STR(headerNameBuf);
|
||||
FREAD(size);
|
||||
FREAD_STR(headerNameBuf, size);
|
||||
cacheEntry.header.Name = std::string(headerNameBuf);
|
||||
FREAD(cacheEntry.header.CRC1);
|
||||
FREAD(cacheEntry.header.CRC2);
|
||||
// (partial) settings
|
||||
FREAD_STR(goodNameBuf);
|
||||
FREAD_STR(md5Buf);
|
||||
FREAD(size);
|
||||
FREAD_STR(goodNameBuf, size);
|
||||
FREAD(size);
|
||||
FREAD_STR(md5Buf, size);
|
||||
cacheEntry.settings.GoodName = std::string(goodNameBuf);
|
||||
cacheEntry.settings.MD5 = std::string(md5Buf);
|
||||
|
||||
@@ -148,6 +168,7 @@ bool CoreSaveRomHeaderAndSettingsCache(void)
|
||||
char headerNameBuf[ROMHEADER_NAME_LEN];
|
||||
char goodNameBuf[GOODNAME_LEN];
|
||||
char md5Buf[MD5_LEN];
|
||||
uint32_t size;
|
||||
l_CacheEntry cacheEntry;
|
||||
|
||||
// only save cache when the entries have changed
|
||||
@@ -167,12 +188,13 @@ bool CoreSaveRomHeaderAndSettingsCache(void)
|
||||
|
||||
// write each entry in the file
|
||||
#define FWRITE(x) outputStream.write((char*)&x, sizeof(x))
|
||||
#define FWRITE_STR(x) outputStream.write((char*)x, sizeof(x))
|
||||
#define FWRITE_STR(x, y) outputStream.write((char*)x, y)
|
||||
for (auto iter = l_CacheEntries.cbegin(); iter != l_CacheEntries.end(); iter++)
|
||||
{
|
||||
cacheEntry = (*iter);
|
||||
|
||||
// reset buffers
|
||||
size = 0;
|
||||
memset(fileNameBuf, 0, sizeof(fileNameBuf));
|
||||
memset(headerNameBuf, 0, sizeof(headerNameBuf));
|
||||
memset(goodNameBuf, 0, sizeof(goodNameBuf));
|
||||
@@ -185,15 +207,23 @@ bool CoreSaveRomHeaderAndSettingsCache(void)
|
||||
strncpy(md5Buf, cacheEntry.settings.MD5.c_str(), sizeof(md5Buf));
|
||||
|
||||
// file info
|
||||
FWRITE_STR(fileNameBuf);
|
||||
size = cacheEntry.fileName.wstring().size() * sizeof(wchar_t);
|
||||
FWRITE(size);
|
||||
FWRITE_STR(fileNameBuf, size);
|
||||
FWRITE(cacheEntry.fileTime);
|
||||
// header
|
||||
FWRITE_STR(headerNameBuf);
|
||||
size = cacheEntry.header.Name.size();
|
||||
FWRITE(size);
|
||||
FWRITE_STR(headerNameBuf, size);
|
||||
FWRITE(cacheEntry.header.CRC1);
|
||||
FWRITE(cacheEntry.header.CRC2);
|
||||
// (partial) settings
|
||||
FWRITE_STR(goodNameBuf);
|
||||
FWRITE_STR(md5Buf);
|
||||
size = cacheEntry.settings.GoodName.size();
|
||||
FWRITE(size);
|
||||
FWRITE_STR(goodNameBuf, size);
|
||||
size = cacheEntry.settings.MD5.size();
|
||||
FWRITE(size);
|
||||
FWRITE_STR(md5Buf, size);
|
||||
}
|
||||
#undef FWRITE
|
||||
#undef FWRITE_STR
|
||||
@@ -245,3 +275,10 @@ bool CoreAddCachedRomHeaderAndSettings(std::filesystem::path file, CoreRomHeader
|
||||
l_CacheEntriesChanged = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CoreClearRomHeaderAndSettingsCache(void)
|
||||
{
|
||||
l_CacheEntries.clear();
|
||||
l_CacheEntriesChanged = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -36,4 +36,8 @@ bool CoreGetCachedRomHeaderAndSettings(std::filesystem::path file, CoreRomHeader
|
||||
// for given filename succeeds
|
||||
bool CoreAddCachedRomHeaderAndSettings(std::filesystem::path file, CoreRomHeader header, CoreRomSettings settings);
|
||||
|
||||
// returns whether clearing rom header & settings cache
|
||||
// succeeds
|
||||
bool CoreClearRomHeaderAndSettingsCache(void);
|
||||
|
||||
#endif // CORE_CACHEDROMHEADERANDSETTINGS_HPP
|
||||
|
||||
@@ -9,13 +9,14 @@
|
||||
*/
|
||||
#define CORE_INTERNAL
|
||||
#include "Core.hpp"
|
||||
#include "ConvertStringEncoding.hpp"
|
||||
|
||||
//
|
||||
// Local Variables
|
||||
//
|
||||
|
||||
static bool l_SetupCallbacks = false;
|
||||
static std::function<void(enum CoreDebugMessageType, std::string)> l_DebugCallbackFunc;
|
||||
static std::function<void(enum CoreDebugMessageType, std::string, std::string)> l_DebugCallbackFunc;
|
||||
|
||||
//
|
||||
// Internal Functions
|
||||
@@ -28,7 +29,20 @@ void CoreDebugCallback(void* context, int level, const char* message)
|
||||
return;
|
||||
}
|
||||
|
||||
l_DebugCallbackFunc((CoreDebugMessageType)level, std::string(message));
|
||||
std::string contextString((const char*)context);
|
||||
std::string messageString(message);
|
||||
|
||||
// convert string encoding accordingly
|
||||
if (messageString.starts_with("IS64:"))
|
||||
{
|
||||
messageString = CoreConvertStringEncoding(message, CoreStringEncoding::EUC_JP);
|
||||
}
|
||||
else
|
||||
{
|
||||
messageString = CoreConvertStringEncoding(message, CoreStringEncoding::Shift_JIS);
|
||||
}
|
||||
|
||||
l_DebugCallbackFunc((CoreDebugMessageType)level, contextString, messageString);
|
||||
}
|
||||
|
||||
void CoreStateCallback(void* context, m64p_core_param param, int value)
|
||||
@@ -40,7 +54,7 @@ void CoreStateCallback(void* context, m64p_core_param param, int value)
|
||||
// Exported Functions
|
||||
//
|
||||
|
||||
bool CoreSetupCallbacks(std::function<void(enum CoreDebugMessageType, std::string)> debugCallbackFunc)
|
||||
bool CoreSetupCallbacks(std::function<void(enum CoreDebugMessageType, std::string, std::string)> debugCallbackFunc)
|
||||
{
|
||||
l_DebugCallbackFunc = debugCallbackFunc;
|
||||
l_SetupCallbacks = true;
|
||||
|
||||
@@ -32,6 +32,6 @@ enum class CoreDebugMessageType
|
||||
Verbose = 5
|
||||
};
|
||||
|
||||
bool CoreSetupCallbacks(std::function<void(enum CoreDebugMessageType, std::string)> debugCallbackFunc);
|
||||
bool CoreSetupCallbacks(std::function<void(enum CoreDebugMessageType, std::string, std::string)> debugCallbackFunc);
|
||||
|
||||
#endif // CORE_CALLBACK_HPP
|
||||
|
||||
@@ -717,6 +717,7 @@ bool CoreUpdateCheat(CoreCheat oldCheat, CoreCheat newCheat)
|
||||
CoreRomHeader romHeader;
|
||||
CoreRomSettings romSettings;
|
||||
std::filesystem::path cheatFilePath;
|
||||
CoreCheatOption cheatOption;
|
||||
|
||||
if (!CoreGetCurrentRomHeader(romHeader) ||
|
||||
!CoreGetCurrentRomSettings(romSettings))
|
||||
@@ -726,6 +727,23 @@ bool CoreUpdateCheat(CoreCheat oldCheat, CoreCheat newCheat)
|
||||
|
||||
cheatFilePath = get_user_cheat_file_path(romHeader, romSettings);
|
||||
|
||||
// copy over cheat settings when name has changed
|
||||
if (oldCheat.Name != newCheat.Name)
|
||||
{
|
||||
CoreEnableCheat(newCheat, CoreIsCheatEnabled(oldCheat));
|
||||
|
||||
// only set option to new cheat when
|
||||
// retrieving from old one succeeds
|
||||
if (CoreGetCheatOption(oldCheat, cheatOption))
|
||||
{
|
||||
CoreSetCheatOption(newCheat, cheatOption);
|
||||
}
|
||||
|
||||
// reset old cheat settings
|
||||
CoreEnableCheat(oldCheat, false);
|
||||
CoreResetCheatOption(oldCheat);
|
||||
}
|
||||
|
||||
// try to find old cheat in user cheats,
|
||||
// when it isnt found, it's most likely a system cheat
|
||||
auto iter = find_user_cheat_using_name(oldCheat.Name);
|
||||
@@ -892,6 +910,29 @@ bool CoreGetCheatOption(CoreCheat cheat, CoreCheatOption& option)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CoreResetCheatOption(CoreCheat cheat)
|
||||
{
|
||||
CoreRomSettings romSettings;
|
||||
std::string settingSection;
|
||||
std::string settingKey;
|
||||
|
||||
if (!cheat.HasOptions)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CoreGetCurrentRomSettings(romSettings))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
settingSection = romSettings.MD5 + " Cheats";
|
||||
settingKey = "Cheat \"" + cheat.Name + "\" Option";
|
||||
|
||||
CoreSettingsSetValue(settingSection, settingKey, -1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CoreApplyCheats(void)
|
||||
{
|
||||
std::string error;
|
||||
|
||||
@@ -136,6 +136,9 @@ bool CoreSetCheatOption(CoreCheat cheat, CoreCheatOption option);
|
||||
// attempts to retrieve the currently's set cheat's option
|
||||
bool CoreGetCheatOption(CoreCheat cheat, CoreCheatOption& option);
|
||||
|
||||
// attempts to reset the cheat option
|
||||
bool CoreResetCheatOption(CoreCheat cheat);
|
||||
|
||||
// attempts to apply the enabled cheats to the currently opened ROM
|
||||
bool CoreApplyCheats(void);
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#define CORE_VERSION "${GIT_VERSION}"
|
||||
|
||||
#ifndef PORTABLE_INSTALL
|
||||
#define CORE_INSTAlL_PREFIX "${CMAKE_INSTALL_PREFIX}"
|
||||
#define CORE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}"
|
||||
#endif // PORTABLE_INSTALL
|
||||
|
||||
#endif // CORE_CONFIG_HPP
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#define CORE_INTERNAL
|
||||
#include "ConvertStringEncoding.hpp"
|
||||
|
||||
#include "Error.hpp"
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include <iconv.h>
|
||||
|
||||
//
|
||||
// Exported Functions
|
||||
//
|
||||
|
||||
std::string CoreConvertStringEncoding(std::string str, CoreStringEncoding encoding)
|
||||
{
|
||||
std::string error;
|
||||
std::string encodingString;
|
||||
|
||||
iconv_t cd;
|
||||
|
||||
char inputBuf[256] = {0};
|
||||
char outputBuf[256] = {0};
|
||||
|
||||
char* inputBufPtr = (char*)str.c_str();
|
||||
char* outputBufPtr = outputBuf;
|
||||
|
||||
size_t inputBufSize = str.size();
|
||||
size_t outputBufSize = sizeof(outputBuf);
|
||||
|
||||
if (encoding == CoreStringEncoding::EUC_JP)
|
||||
{
|
||||
encodingString = "EUC-JP";
|
||||
}
|
||||
else
|
||||
{
|
||||
encodingString = "Shift_JIS";
|
||||
}
|
||||
|
||||
cd = iconv_open("UTF-8//TRANSLIT//IGNORE", encodingString.c_str());
|
||||
if (cd == (iconv_t)-1)
|
||||
{
|
||||
error = "CoreConvertStringEncoding Failed: ";
|
||||
error += "iconv_open Failed: ";
|
||||
error += errno;
|
||||
CoreSetError(error);
|
||||
return str;
|
||||
}
|
||||
|
||||
size_t ret = iconv(cd, &inputBufPtr, &inputBufSize, &outputBufPtr, &outputBufSize);
|
||||
if (ret == -1)
|
||||
{
|
||||
error = "CoreConvertStringEncoding Failed: ";
|
||||
error += "iconv Failed: ";
|
||||
error += errno;
|
||||
CoreSetError(error);
|
||||
|
||||
// reset iconv
|
||||
iconv(cd, nullptr, nullptr, nullptr, nullptr);
|
||||
iconv_close(cd);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
// reset iconv
|
||||
iconv(cd, nullptr, nullptr, nullptr, nullptr);
|
||||
iconv_close(cd);
|
||||
|
||||
return std::string(outputBuf);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef CORE_CONVERTSTRINGENCODING_HPP
|
||||
#define CORE_CONVERTSTRINGENCODING_HPP
|
||||
#ifdef CORE_INTERNAL
|
||||
|
||||
#include <string>
|
||||
|
||||
enum class CoreStringEncoding : int
|
||||
{
|
||||
EUC_JP = 0,
|
||||
Shift_JIS = 1
|
||||
};
|
||||
|
||||
// attempts to convert the string (which uses encoding) to UTF-8,
|
||||
// on failure, returns original string
|
||||
std::string CoreConvertStringEncoding(std::string str, CoreStringEncoding encoding);
|
||||
|
||||
#endif // CORE_INTERNAL
|
||||
#endif // CORE_CONVERTSTRINGENCODING_HPP
|
||||
@@ -9,35 +9,40 @@
|
||||
*/
|
||||
#define CORE_INTERNAL
|
||||
#include "Core.hpp"
|
||||
|
||||
#ifdef DISCORD_RPC
|
||||
#include "DiscordRpc.hpp"
|
||||
#endif // DISCORD_RPC
|
||||
#include "osal/osal_dynlib.hpp"
|
||||
#include "m64p/Api.hpp"
|
||||
#include "m64p/api/version.h"
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
//
|
||||
// Local Variables
|
||||
//
|
||||
|
||||
static osal_dynlib_lib_handle l_CoreLibHandle;
|
||||
static char l_CoreContextString[20];
|
||||
|
||||
//
|
||||
// Local Functions
|
||||
//
|
||||
|
||||
std::string find_core_lib(void)
|
||||
std::filesystem::path find_core_lib(void)
|
||||
{
|
||||
for (const auto& entry : std::filesystem::recursive_directory_iterator(CoreGetCoreDirectory()))
|
||||
{
|
||||
std::string path = entry.path().string();
|
||||
if (path.ends_with(OSAL_DYNLIB_LIB_EXT_STR))
|
||||
std::filesystem::path path = entry.path();
|
||||
if (path.has_extension() &&
|
||||
path.extension() == OSAL_DYNLIB_LIB_EXT_STR)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
return std::string();
|
||||
return std::filesystem::path();
|
||||
}
|
||||
|
||||
bool config_override_user_dirs(void)
|
||||
@@ -74,11 +79,14 @@ bool config_override_user_dirs(void)
|
||||
|
||||
bool CoreInit(void)
|
||||
{
|
||||
std::string error;
|
||||
std::string core_file;
|
||||
m64p_error m64p_ret;
|
||||
std::string error;
|
||||
std::filesystem::path core_file;
|
||||
m64p_error m64p_ret;
|
||||
bool ret = false;
|
||||
|
||||
// initialize context string
|
||||
std::strcpy(l_CoreContextString, "[CORE] ");
|
||||
|
||||
core_file = find_core_lib();
|
||||
if (core_file.empty())
|
||||
{
|
||||
@@ -87,7 +95,7 @@ bool CoreInit(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
l_CoreLibHandle = osal_dynlib_open(core_file.c_str());
|
||||
l_CoreLibHandle = osal_dynlib_open(core_file);
|
||||
if (l_CoreLibHandle == nullptr)
|
||||
{
|
||||
error = "osal_dynlib_open Failed: ";
|
||||
@@ -112,7 +120,7 @@ bool CoreInit(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
m64p_ret = m64p::Core.Startup(FRONTEND_API_VERSION, CoreGetUserConfigDirectory().string().c_str(), CoreGetSharedDataDirectory().string().c_str(), nullptr, CoreDebugCallback, nullptr, CoreStateCallback);
|
||||
m64p_ret = m64p::Core.Startup(FRONTEND_API_VERSION, CoreGetUserConfigDirectory().string().c_str(), CoreGetSharedDataDirectory().string().c_str(), (void*)l_CoreContextString, CoreDebugCallback, nullptr, CoreStateCallback);
|
||||
if (m64p_ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "CoreInit M64P::Core.Startup() Failed: ";
|
||||
@@ -153,6 +161,11 @@ bool CoreInit(void)
|
||||
|
||||
CoreReadRomHeaderAndSettingsCache();
|
||||
|
||||
#ifdef DISCORD_RPC
|
||||
CoreDiscordRpcInit();
|
||||
CoreDiscordRpcUpdate(false);
|
||||
#endif // DISCORD_RPC
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -186,6 +199,10 @@ void CoreShutdown(void)
|
||||
|
||||
CoreSaveRomHeaderAndSettingsCache();
|
||||
|
||||
#ifdef DISCORD_RPC
|
||||
CoreDiscordRpcShutdown();
|
||||
#endif // DISCORD_RPC
|
||||
|
||||
m64p::Core.Unhook();
|
||||
m64p::Config.Unhook();
|
||||
|
||||
|
||||
@@ -22,8 +22,10 @@
|
||||
#include "RomHeader.hpp"
|
||||
#include "Callback.hpp"
|
||||
#include "Plugins.hpp"
|
||||
#include "Version.hpp"
|
||||
#include "Cheats.hpp"
|
||||
#include "Error.hpp"
|
||||
#include "Unzip.hpp"
|
||||
#include "Video.hpp"
|
||||
#include "Key.hpp"
|
||||
#include "Rom.hpp"
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "Directories.hpp"
|
||||
#include "Config.hpp"
|
||||
#include "Error.hpp"
|
||||
#include "Core.hpp"
|
||||
#include "Config.hpp"
|
||||
#include "m64p/Api.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
@@ -123,7 +123,7 @@ std::filesystem::path CoreGetCoreDirectory(void)
|
||||
#ifdef PORTABLE_INSTALL
|
||||
directory = "Core";
|
||||
#else // Not Portable
|
||||
directory = CORE_INSTAlL_PREFIX;
|
||||
directory = CORE_INSTALL_PREFIX;
|
||||
directory += "/lib/RMG/Core";
|
||||
#endif // PORTABLE_INSTALL
|
||||
return directory;
|
||||
@@ -135,7 +135,7 @@ std::filesystem::path CoreGetPluginDirectory(void)
|
||||
#ifdef PORTABLE_INSTALL
|
||||
directory = "Plugin";
|
||||
#else // Not Portable
|
||||
directory = CORE_INSTAlL_PREFIX;
|
||||
directory = CORE_INSTALL_PREFIX;
|
||||
directory += "/lib/RMG/Plugin";
|
||||
#endif // PORTABLE_INSTALL
|
||||
return directory;
|
||||
@@ -180,7 +180,7 @@ std::filesystem::path CoreGetDefaultSaveDirectory(void)
|
||||
#ifdef PORTABLE_INSTALL
|
||||
directory = "Save/Game";
|
||||
#else // Not Portable
|
||||
directory = CoreGetUserDataDirectory();
|
||||
directory = CoreGetDefaultUserDataDirectory();
|
||||
directory += "/Save/Game";
|
||||
#endif // PORTABLE_INSTALL
|
||||
return directory;
|
||||
@@ -192,7 +192,7 @@ std::filesystem::path CoreGetDefaultSaveStateDirectory(void)
|
||||
#ifdef PORTABLE_INSTALL
|
||||
directory = "Save/State";
|
||||
#else // Not Portable
|
||||
directory = CoreGetUserDataDirectory();
|
||||
directory = CoreGetDefaultUserDataDirectory();
|
||||
directory += "/Save/State";
|
||||
#endif // PORTABLE_INSTALL
|
||||
return directory;
|
||||
@@ -233,7 +233,7 @@ std::filesystem::path CoreGetSharedDataDirectory(void)
|
||||
#ifdef PORTABLE_INSTALL
|
||||
directory = "Data";
|
||||
#else // Not Portable
|
||||
directory = CORE_INSTAlL_PREFIX;
|
||||
directory = CORE_INSTALL_PREFIX;
|
||||
directory += "/share/RMG";
|
||||
#endif // PORTABLE_INSTALL
|
||||
return directory;
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "Settings/Settings.hpp"
|
||||
#include "DiscordRpc.hpp"
|
||||
#include "RomSettings.hpp"
|
||||
#include "RomHeader.hpp"
|
||||
|
||||
#include <../3rdParty/discord-rpc/include/discord_rpc.h>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <algorithm>
|
||||
|
||||
//
|
||||
// Exported Functions
|
||||
//
|
||||
|
||||
void CoreDiscordRpcInit(void)
|
||||
{
|
||||
if (!CoreSettingsGetBoolValue(SettingsID::GUI_DiscordRpc))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Discord_Initialize("801450412280119356", nullptr, 0, "");
|
||||
}
|
||||
|
||||
void CoreDiscordRpcShutdown(void)
|
||||
{
|
||||
Discord_Shutdown();
|
||||
}
|
||||
|
||||
void CoreDiscordRpcUpdate(bool inGame)
|
||||
{
|
||||
std::string smallImageKey;
|
||||
std::string largeImageKey;
|
||||
std::string details;
|
||||
|
||||
if (!CoreSettingsGetBoolValue(SettingsID::GUI_DiscordRpc))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (inGame)
|
||||
{
|
||||
CoreRomSettings romSettings;
|
||||
CoreRomHeader romHeader;
|
||||
|
||||
// make sure we retrieve the rom settings & header
|
||||
if (!CoreGetCurrentRomSettings(romSettings) ||
|
||||
!CoreGetCurrentRomHeader(romHeader))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
smallImageKey = "rmg-icon";
|
||||
largeImageKey = romHeader.Name;
|
||||
details = romSettings.GoodName;
|
||||
|
||||
// replace ' ' with '_' and replace '&' with '_'
|
||||
// also tolower the entire string
|
||||
std::replace(largeImageKey.begin(),largeImageKey.end(),' ','_');
|
||||
std::replace(largeImageKey.begin(),largeImageKey.end(),'&','_');
|
||||
std::transform(largeImageKey.begin(), largeImageKey.end(), largeImageKey.begin(), ::tolower);
|
||||
}
|
||||
else
|
||||
{
|
||||
largeImageKey = "rmg-icon";
|
||||
details = "Not in-game";
|
||||
}
|
||||
|
||||
DiscordRichPresence discordPresence;
|
||||
memset(&discordPresence, 0, sizeof(discordPresence));
|
||||
discordPresence.smallImageKey = smallImageKey.c_str();
|
||||
discordPresence.largeImageKey = largeImageKey.c_str();
|
||||
discordPresence.largeImageText = "Rosalie's Mupen GUI";
|
||||
discordPresence.details = details.c_str();
|
||||
discordPresence.startTimestamp = time(nullptr);
|
||||
|
||||
Discord_UpdatePresence(&discordPresence);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef CORE_DISCORDRPC_HPP
|
||||
#define CORE_DISCORDRPC_HPP
|
||||
|
||||
// initializes the discord rpc library
|
||||
void CoreDiscordRpcInit(void);
|
||||
|
||||
// shuts down the discord rpc library
|
||||
void CoreDiscordRpcShutdown(void);
|
||||
|
||||
// updates the state of the discord rpc library
|
||||
void CoreDiscordRpcUpdate(bool inGame);
|
||||
|
||||
#endif // CORE_DISCORDRPC_HPP
|
||||
@@ -16,6 +16,9 @@
|
||||
#include "Cheats.hpp"
|
||||
#include "Error.hpp"
|
||||
#include "Rom.hpp"
|
||||
#ifdef DISCORD_RPC
|
||||
#include "DiscordRpc.hpp"
|
||||
#endif // DISCORD_RPC
|
||||
|
||||
//
|
||||
// Local Functions
|
||||
@@ -123,8 +126,11 @@ bool CoreStartEmulation(std::filesystem::path n64rom, std::filesystem::path n64d
|
||||
return false;
|
||||
}
|
||||
|
||||
// set disk file in media loader
|
||||
CoreMediaLoaderSetDiskFile(n64ddrom);
|
||||
// set disk file in media loader when ROM is a cartridge
|
||||
if (CoreGetRomType() == CoreRomType::Cartridge)
|
||||
{
|
||||
CoreMediaLoaderSetDiskFile(n64ddrom);
|
||||
}
|
||||
|
||||
// apply core settings overlay
|
||||
apply_coresettings_overlay();
|
||||
@@ -132,6 +138,10 @@ bool CoreStartEmulation(std::filesystem::path n64rom, std::filesystem::path n64d
|
||||
// apply game core settings overrides
|
||||
apply_game_coresettings_overlay();
|
||||
|
||||
#ifdef DISCORD_RPC
|
||||
CoreDiscordRpcUpdate(true);
|
||||
#endif // DISCORD_RPC
|
||||
|
||||
ret = m64p::Core.DoCommand(M64CMD_EXECUTE, 0, nullptr);
|
||||
if (ret != M64ERR_SUCCESS)
|
||||
{
|
||||
@@ -147,6 +157,10 @@ bool CoreStartEmulation(std::filesystem::path n64rom, std::filesystem::path n64d
|
||||
// restore plugin settings
|
||||
CoreApplyPluginSettings();
|
||||
|
||||
#ifdef DISCORD_RPC
|
||||
CoreDiscordRpcUpdate(false);
|
||||
#endif // DISCORD_RPC
|
||||
|
||||
return ret == M64ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#define CORE_INTERNAL
|
||||
#include "Plugins.hpp"
|
||||
#include "Callback.hpp"
|
||||
#include "Directories.hpp"
|
||||
#include "Error.hpp"
|
||||
#include "Emulation.hpp"
|
||||
@@ -21,6 +23,7 @@
|
||||
#include "m64p/Api.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
#include <cstring>
|
||||
|
||||
//
|
||||
// Local Variables
|
||||
@@ -28,6 +31,7 @@
|
||||
|
||||
static m64p::PluginApi l_Plugins[(int)CorePluginType::Input];
|
||||
static std::string l_PluginFiles[(int)CorePluginType::Input];
|
||||
static char l_PluginContext[(int)CorePluginType::Input][20];
|
||||
|
||||
//
|
||||
// Local Functions
|
||||
@@ -101,6 +105,32 @@ std::string get_plugin_type_name(CorePluginType type)
|
||||
return name + " Plugin";
|
||||
}
|
||||
|
||||
std::string get_plugin_context_name(CorePluginType type)
|
||||
{
|
||||
std::string name;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
default:
|
||||
name = "[UNKNOWN]";
|
||||
break;
|
||||
case CorePluginType::Rsp:
|
||||
name = "[RSP] ";
|
||||
break;
|
||||
case CorePluginType::Gfx:
|
||||
name = "[GFX] ";
|
||||
break;
|
||||
case CorePluginType::Audio:
|
||||
name = "[AUDIO] ";
|
||||
break;
|
||||
case CorePluginType::Input:
|
||||
name = "[INPUT] ";
|
||||
break;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
bool apply_plugin_settings(std::string pluginSettings[4])
|
||||
{
|
||||
std::string error;
|
||||
@@ -121,6 +151,9 @@ bool apply_plugin_settings(std::string pluginSettings[4])
|
||||
|
||||
pluginType = (CorePluginType)(i + 1);
|
||||
|
||||
// copy context string to a c string using strcpy
|
||||
std::strcpy(l_PluginContext[(int)pluginType], get_plugin_context_name(pluginType).c_str());
|
||||
|
||||
if (settingValue != l_PluginFiles[i])
|
||||
{
|
||||
plugin = &l_Plugins[i];
|
||||
@@ -179,7 +212,7 @@ bool apply_plugin_settings(std::string pluginSettings[4])
|
||||
}
|
||||
|
||||
// attempt to start plugin
|
||||
ret = plugin->Startup(m64p::Core.GetHandle(), nullptr, nullptr);
|
||||
ret = plugin->Startup(m64p::Core.GetHandle(), (void*)l_PluginContext[(int)pluginType], CoreDebugCallback);
|
||||
if (ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "apply_plugin_settings (";
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
#include "Rom.hpp"
|
||||
#include "Error.hpp"
|
||||
#include "MediaLoader.hpp"
|
||||
#include "m64p/Api.hpp"
|
||||
#include "RomSettings.hpp"
|
||||
#include "Cheats.hpp"
|
||||
@@ -17,6 +18,7 @@
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
||||
//
|
||||
// Local Defines
|
||||
@@ -29,11 +31,26 @@
|
||||
//
|
||||
|
||||
static bool l_HasRomOpen = false;
|
||||
static bool l_HasDisk = false;
|
||||
|
||||
//
|
||||
// Local Functions
|
||||
//
|
||||
|
||||
static std::string to_lower_str(std::string str)
|
||||
{
|
||||
std::string resultString = str;
|
||||
|
||||
std::transform(resultString.begin(), resultString.end(), resultString.begin(),
|
||||
[](unsigned char c)
|
||||
{
|
||||
return std::tolower(c);
|
||||
}
|
||||
);
|
||||
|
||||
return resultString;
|
||||
}
|
||||
|
||||
static bool read_zip_file(std::filesystem::path file, char** buf, int* size)
|
||||
{
|
||||
std::string error;
|
||||
@@ -74,9 +91,11 @@ static bool read_zip_file(std::filesystem::path file, char** buf, int* size)
|
||||
// make sure file has supported file format,
|
||||
// if it does, read it in memory
|
||||
std::filesystem::path fileNamePath(fileName);
|
||||
if (fileNamePath.extension() == ".z64" ||
|
||||
fileNamePath.extension() == ".v64" ||
|
||||
fileNamePath.extension() == ".n64")
|
||||
std::string fileExtension = fileNamePath.has_extension() ? fileNamePath.extension().string() : "";
|
||||
fileExtension = to_lower_str(fileExtension);
|
||||
if (fileExtension == ".z64" ||
|
||||
fileExtension == ".v64" ||
|
||||
fileExtension == ".n64")
|
||||
{
|
||||
char* buffer;
|
||||
char* outBuffer;
|
||||
@@ -190,7 +209,11 @@ static bool read_raw_file(std::filesystem::path file, char** buf, int* size)
|
||||
if (!fileStream.is_open())
|
||||
{
|
||||
error = "read_raw_file Failed: ";
|
||||
error += "failed to open file!";
|
||||
error += "failed to open file: ";
|
||||
error += strerror(errno);
|
||||
error += " (";
|
||||
error += std::to_string(errno);
|
||||
error += ")";
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
@@ -230,8 +253,9 @@ bool CoreOpenRom(std::filesystem::path file)
|
||||
{
|
||||
std::string error;
|
||||
m64p_error ret;
|
||||
char* buf;
|
||||
int buf_size;
|
||||
char* buf = nullptr;
|
||||
int buf_size = 0;
|
||||
std::string file_extension;
|
||||
|
||||
if (!m64p::Core.IsHooked())
|
||||
{
|
||||
@@ -246,12 +270,23 @@ bool CoreOpenRom(std::filesystem::path file)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file.has_extension() && file.extension() == ".zip")
|
||||
file_extension = file.has_extension() ? file.extension().string() : "";
|
||||
file_extension = to_lower_str(file_extension);
|
||||
|
||||
if (file_extension == ".zip")
|
||||
{
|
||||
if (!read_zip_file(file, &buf, &buf_size))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
l_HasDisk = false;
|
||||
}
|
||||
else if (file_extension == ".d64" ||
|
||||
file_extension == ".ndd")
|
||||
{
|
||||
CoreMediaLoaderSetDiskFile(file);
|
||||
l_HasDisk = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -259,17 +294,28 @@ bool CoreOpenRom(std::filesystem::path file)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
l_HasDisk = false;
|
||||
}
|
||||
|
||||
if (l_HasDisk)
|
||||
{
|
||||
ret = m64p::Core.DoCommand(M64CMD_DISK_OPEN, 0, nullptr);
|
||||
error = "CoreOpenRom: m64p::Core.DoCommand(M64CMD_DISK_OPEN) Failed: ";
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = m64p::Core.DoCommand(M64CMD_ROM_OPEN, buf_size, buf);
|
||||
error = "CoreOpenRom: m64p::Core.DoCommand(M64CMD_ROM_OPEN) Failed: ";
|
||||
free(buf);
|
||||
}
|
||||
|
||||
ret = m64p::Core.DoCommand(M64CMD_ROM_OPEN, buf_size, buf);
|
||||
if (ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "CoreOpenRom: m64p::Core.DoCommand(M64CMD_ROM_OPEN) Failed: ";
|
||||
error += m64p::Core.ErrorMessage(ret);
|
||||
CoreSetError(error);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
l_HasRomOpen = (ret == M64ERR_SUCCESS);
|
||||
|
||||
if (l_HasRomOpen)
|
||||
@@ -288,6 +334,11 @@ bool CoreHasRomOpen(void)
|
||||
return l_HasRomOpen;
|
||||
}
|
||||
|
||||
CoreRomType CoreGetRomType(void)
|
||||
{
|
||||
return l_HasDisk ? CoreRomType::Disk : CoreRomType::Cartridge;
|
||||
}
|
||||
|
||||
bool CoreCloseRom(void)
|
||||
{
|
||||
std::string error;
|
||||
@@ -311,10 +362,19 @@ bool CoreCloseRom(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = m64p::Core.DoCommand(M64CMD_ROM_CLOSE, 0, nullptr);
|
||||
if (l_HasDisk)
|
||||
{
|
||||
ret = m64p::Core.DoCommand(M64CMD_DISK_CLOSE, 0, nullptr);
|
||||
error = "CoreCloseRom: m64p::Core.DoCommand(M64CMD_DISK_CLOSE) Failed: ";
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = m64p::Core.DoCommand(M64CMD_ROM_CLOSE, 0, nullptr);
|
||||
error = "CoreCloseRom: m64p::Core.DoCommand(M64CMD_ROM_CLOSE) Failed: ";
|
||||
}
|
||||
|
||||
if (ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "CoreCloseRom: m64p::Core.DoCommand(M64CMD_ROM_CLOSE) Failed: ";
|
||||
error += m64p::Core.ErrorMessage(ret);
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
|
||||
@@ -12,12 +12,21 @@
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
enum class CoreRomType
|
||||
{
|
||||
Cartridge,
|
||||
Disk
|
||||
};
|
||||
|
||||
// opens the given file as ROM
|
||||
bool CoreOpenRom(std::filesystem::path file);
|
||||
|
||||
// returns whether core has a ROM opened
|
||||
bool CoreHasRomOpen(void);
|
||||
|
||||
// returns the opened ROM's type
|
||||
CoreRomType CoreGetRomType(void);
|
||||
|
||||
// closes ROM
|
||||
bool CoreCloseRom(void);
|
||||
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
#include <arpa/inet.h>
|
||||
#endif // _WIN32
|
||||
|
||||
#define CORE_INTERNAL
|
||||
#include "RomHeader.hpp"
|
||||
#include "ConvertStringEncoding.hpp"
|
||||
#include "Emulation.hpp"
|
||||
#include "m64p/Api.hpp"
|
||||
#include "Error.hpp"
|
||||
@@ -46,6 +48,7 @@ bool CoreGetCurrentRomHeader(CoreRomHeader& header)
|
||||
header.CRC1 = ntohl(m64p_header.CRC1);
|
||||
header.CRC2 = ntohl(m64p_header.CRC2);
|
||||
header.CountryCode = m64p_header.Country_code;
|
||||
header.Name = std::string((char*)m64p_header.Name);
|
||||
header.Name = CoreConvertStringEncoding((char*)m64p_header.Name, CoreStringEncoding::Shift_JIS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -7,13 +7,16 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#define CORE_INTERNAL
|
||||
#include "RomSettings.hpp"
|
||||
#include "Emulation.hpp"
|
||||
#include "RomHeader.hpp"
|
||||
#include "m64p/Api.hpp"
|
||||
#include "Error.hpp"
|
||||
#include "Rom.hpp"
|
||||
|
||||
#include "Settings/Settings.hpp"
|
||||
#include "ConvertStringEncoding.hpp"
|
||||
|
||||
//
|
||||
// Local Variables
|
||||
@@ -46,7 +49,7 @@ bool CoreGetCurrentRomSettings(CoreRomSettings& settings)
|
||||
return false;
|
||||
}
|
||||
|
||||
settings.GoodName = std::string(m64p_settings.goodname);
|
||||
settings.GoodName = CoreConvertStringEncoding(m64p_settings.goodname, CoreStringEncoding::Shift_JIS);
|
||||
settings.MD5 = std::string(m64p_settings.MD5);
|
||||
settings.SaveType = m64p_settings.savetype;
|
||||
settings.DisableExtraMem = m64p_settings.disableextramem;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "Settings.hpp"
|
||||
|
||||
#include "Directories.hpp"
|
||||
#include "Config.hpp"
|
||||
#include "Version.hpp"
|
||||
#include "m64p/Api.hpp"
|
||||
#include "Error.hpp"
|
||||
#include "m64p/api/m64p_types.h"
|
||||
@@ -161,8 +161,29 @@ static l_Setting get_setting(SettingsID settingId)
|
||||
case SettingsID::GUI_AutomaticFullscreen:
|
||||
setting = {SETTING_SECTION_GUI, "AutomaticFullscreen", false};
|
||||
break;
|
||||
case SettingsID::GUI_ShowVerboseLogMessages:
|
||||
setting = {SETTING_SECTION_GUI, "ShowVerboseLogMessages", false};
|
||||
break;
|
||||
case SettingsID::GUI_Toolbar:
|
||||
setting = {SETTING_SECTION_GUI, "Toolbar", true};
|
||||
break;
|
||||
case SettingsID::GUI_StatusBar:
|
||||
setting = {SETTING_SECTION_GUI, "StatusBar", true};
|
||||
break;
|
||||
case SettingsID::GUI_Style:
|
||||
setting = {SETTING_SECTION_GUI, "Style", ""};
|
||||
break;
|
||||
case SettingsID::GUI_IconTheme:
|
||||
setting = {SETTING_SECTION_GUI, "IconTheme", "black"};
|
||||
break;
|
||||
case SettingsID::GUI_CheckForUpdates:
|
||||
setting = {SETTING_SECTION_GUI, "CheckForUpdates", true};
|
||||
break;
|
||||
case SettingsID::GUI_DiscordRpc:
|
||||
setting = {SETTING_SECTION_GUI, "DiscordRpc", true};
|
||||
break;
|
||||
case SettingsID::GUI_Version:
|
||||
setting = {SETTING_SECTION_GUI, "Version", CORE_VERSION};
|
||||
setting = {SETTING_SECTION_GUI, "Version", CoreGetVersion()};
|
||||
break;
|
||||
|
||||
case SettingsID::Core_GFX_Plugin:
|
||||
@@ -353,17 +374,14 @@ static l_Setting get_setting(SettingsID settingId)
|
||||
case SettingsID::KeyBinding_RemoveDuplicates:
|
||||
setting = {SETTING_SECTION_KEYBIND, "RemoveDuplicates", true};
|
||||
break;
|
||||
case SettingsID::KeyBinding_OpenROM:
|
||||
setting = {SETTING_SECTION_KEYBIND, "OpenROM", "Ctrl+O"};
|
||||
case SettingsID::KeyBinding_StartROM:
|
||||
setting = {SETTING_SECTION_KEYBIND, "StartROM", "Ctrl+O"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_OpenCombo:
|
||||
setting = {SETTING_SECTION_KEYBIND, "OpenCombo", "Ctrl+Shift+O"};
|
||||
case SettingsID::KeyBinding_StartCombo:
|
||||
setting = {SETTING_SECTION_KEYBIND, "StartCombo", "Ctrl+Shift+O"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_StartEmulation:
|
||||
setting = {SETTING_SECTION_KEYBIND, "StartEmulation", "F11"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_EndEmulation:
|
||||
setting = {SETTING_SECTION_KEYBIND, "EndEmulation", "F12"};
|
||||
case SettingsID::KeyBinding_Shutdown:
|
||||
setting = {SETTING_SECTION_KEYBIND, "Shutdown", "F12"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_RefreshROMList:
|
||||
setting = {SETTING_SECTION_KEYBIND, "RefreshROMList", "F5"};
|
||||
@@ -380,15 +398,12 @@ static l_Setting get_setting(SettingsID settingId)
|
||||
case SettingsID::KeyBinding_Resume:
|
||||
setting = {SETTING_SECTION_KEYBIND, "Resume", "F2"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_GenerateBitmap:
|
||||
setting = {SETTING_SECTION_KEYBIND, "GenerateBitmap", "F3"};
|
||||
case SettingsID::KeyBinding_Screenshot:
|
||||
setting = {SETTING_SECTION_KEYBIND, "Screenshot", "F3"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_LimitFPS:
|
||||
setting = {SETTING_SECTION_KEYBIND, "LimitFPS", "F4"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_SwapDisk:
|
||||
setting = {SETTING_SECTION_KEYBIND, "SwapDisk", "Ctrl+D"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_SaveState:
|
||||
setting = {SETTING_SECTION_KEYBIND, "SaveState", "F5"};
|
||||
break;
|
||||
@@ -407,6 +422,36 @@ static l_Setting get_setting(SettingsID settingId)
|
||||
case SettingsID::KeyBinding_GSButton:
|
||||
setting = {SETTING_SECTION_KEYBIND, "GSButton", "F9"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_SaveStateSlot0:
|
||||
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot0", "Ctrl+0"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_SaveStateSlot1:
|
||||
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot1", "Ctrl+1"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_SaveStateSlot2:
|
||||
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot2", "Ctrl+2"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_SaveStateSlot3:
|
||||
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot3", "Ctrl+3"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_SaveStateSlot4:
|
||||
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot4", "Ctrl+4"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_SaveStateSlot5:
|
||||
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot5", "Ctrl+5"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_SaveStateSlot6:
|
||||
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot6", "Ctrl+6"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_SaveStateSlot7:
|
||||
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot7", "Ctrl+7"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_SaveStateSlot8:
|
||||
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot8", "Ctrl+8"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_SaveStateSlot9:
|
||||
setting = {SETTING_SECTION_KEYBIND, "SaveStateSlot9", "Ctrl+9"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_Fullscreen:
|
||||
setting = {SETTING_SECTION_KEYBIND, "Fullscreen", "Alt+Return"};
|
||||
break;
|
||||
@@ -430,7 +475,25 @@ static l_Setting get_setting(SettingsID settingId)
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "Columns", std::vector<int>({0, 1, 2})};
|
||||
break;
|
||||
case SettingsID::RomBrowser_ColumnSizes:
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "ColumnSizes", std::vector<int>({0, 250, 1, 100, 2, 100})};
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "ColumnSizes", std::vector<int>({-1, -1, -1})};
|
||||
break;
|
||||
case SettingsID::RomBrowser_ViewMode:
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "ViewMode", 0};
|
||||
break;
|
||||
case SettingsID::RomBrowser_ListViewSortSection:
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "ListViewSortSection", 0};
|
||||
break;
|
||||
case SettingsID::RomBrowser_ListViewSortOrder:
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "ListViewSortOrder", 0};
|
||||
break;
|
||||
case SettingsID::RomBrowser_GridViewIconWidth:
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "GridViewIconWidth", 180};
|
||||
break;
|
||||
case SettingsID::RomBrowser_GridViewIconHeight:
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "GridViewIconHeight", 126};
|
||||
break;
|
||||
case SettingsID::RomBrowser_GridViewUniformItemSizes:
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "GridViewUniformItemSizes", true};
|
||||
break;
|
||||
|
||||
case SettingsID::Settings_HasForceUsedSetOnce:
|
||||
@@ -462,7 +525,7 @@ static l_Setting get_setting(SettingsID settingId)
|
||||
setting = {SETTING_SECTION_AUDIO, "Muted", false};
|
||||
break;
|
||||
case SettingsID::Audio_Synchronize:
|
||||
setting = {SETTING_SECTION_AUDIO, "Synchronize", true};
|
||||
setting = {SETTING_SECTION_AUDIO, "Synchronize", false};
|
||||
break;
|
||||
|
||||
case SettingsID::Input_PluggedIn:
|
||||
@@ -951,7 +1014,7 @@ bool CoreSettingsUpgrade(void)
|
||||
|
||||
// we don't need to do anything
|
||||
// when the core version and the settings version match
|
||||
if (settingsVersion == CORE_VERSION)
|
||||
if (settingsVersion == CoreGetVersion())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -972,11 +1035,27 @@ bool CoreSettingsUpgrade(void)
|
||||
CoreSettingsSetValue(SettingsID::Core_ScreenshotPath, CoreGetDefaultScreenshotDirectory());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (settingsVersion == "v0.2.1" ||
|
||||
settingsVersion == "v0.2.2" ||
|
||||
settingsVersion == "v0.2.3")
|
||||
{
|
||||
// sadly when introducing the new RMG-Audio based on mupen64plus-audio-sdl
|
||||
// 1) sync audio seems to cause crackling for some users
|
||||
// 2) sync audio breaks the 'Limit FPS' option
|
||||
// so to fix those issues, we'll disable the sync audio option
|
||||
// if it's enabled
|
||||
if (CoreSettingsGetBoolValue(SettingsID::Audio_Synchronize))
|
||||
{
|
||||
CoreSettingsSetValue(SettingsID::Audio_Synchronize, false);
|
||||
}
|
||||
}
|
||||
|
||||
// save core version
|
||||
return CoreSettingsSetValue(SettingsID::GUI_Version, std::string(CORE_VERSION));
|
||||
CoreSettingsSetValue(SettingsID::GUI_Version, CoreGetVersion());
|
||||
CoreSettingsSave();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CoreSettingsSetupDefaults(void)
|
||||
|
||||
@@ -13,6 +13,13 @@ enum class SettingsID
|
||||
GUI_PauseEmulationOnFocusLoss,
|
||||
GUI_ResumeEmulationOnFocus,
|
||||
GUI_AutomaticFullscreen,
|
||||
GUI_ShowVerboseLogMessages,
|
||||
GUI_Toolbar,
|
||||
GUI_StatusBar,
|
||||
GUI_Style,
|
||||
GUI_IconTheme,
|
||||
GUI_CheckForUpdates,
|
||||
GUI_DiscordRpc,
|
||||
GUI_Version,
|
||||
|
||||
// Core Plugin Settings
|
||||
@@ -87,24 +94,32 @@ enum class SettingsID
|
||||
|
||||
// GUI KeyBindings
|
||||
KeyBinding_RemoveDuplicates,
|
||||
KeyBinding_OpenROM,
|
||||
KeyBinding_OpenCombo,
|
||||
KeyBinding_StartEmulation,
|
||||
KeyBinding_EndEmulation,
|
||||
KeyBinding_StartROM,
|
||||
KeyBinding_StartCombo,
|
||||
KeyBinding_Shutdown,
|
||||
KeyBinding_RefreshROMList,
|
||||
KeyBinding_Exit,
|
||||
KeyBinding_SoftReset,
|
||||
KeyBinding_HardReset,
|
||||
KeyBinding_Resume,
|
||||
KeyBinding_GenerateBitmap,
|
||||
KeyBinding_Screenshot,
|
||||
KeyBinding_LimitFPS,
|
||||
KeyBinding_SwapDisk,
|
||||
KeyBinding_SaveState,
|
||||
KeyBinding_SaveAs,
|
||||
KeyBinding_LoadState,
|
||||
KeyBinding_Load,
|
||||
KeyBinding_Cheats,
|
||||
KeyBinding_GSButton,
|
||||
KeyBinding_SaveStateSlot0,
|
||||
KeyBinding_SaveStateSlot1,
|
||||
KeyBinding_SaveStateSlot2,
|
||||
KeyBinding_SaveStateSlot3,
|
||||
KeyBinding_SaveStateSlot4,
|
||||
KeyBinding_SaveStateSlot5,
|
||||
KeyBinding_SaveStateSlot6,
|
||||
KeyBinding_SaveStateSlot7,
|
||||
KeyBinding_SaveStateSlot8,
|
||||
KeyBinding_SaveStateSlot9,
|
||||
KeyBinding_Fullscreen,
|
||||
KeyBinding_Settings,
|
||||
|
||||
@@ -115,7 +130,13 @@ enum class SettingsID
|
||||
RomBrowser_MaxItems,
|
||||
RomBrowser_Columns,
|
||||
RomBrowser_ColumnSizes,
|
||||
|
||||
RomBrowser_ViewMode,
|
||||
RomBrowser_ListViewSortSection,
|
||||
RomBrowser_ListViewSortOrder,
|
||||
RomBrowser_GridViewIconWidth,
|
||||
RomBrowser_GridViewIconHeight,
|
||||
RomBrowser_GridViewUniformItemSizes,
|
||||
|
||||
// Settings Settings
|
||||
Settings_HasForceUsedSetOnce,
|
||||
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "Unzip.hpp"
|
||||
#include "Error.hpp"
|
||||
|
||||
#include <exception>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <unzip.h>
|
||||
|
||||
//
|
||||
// Local Defines
|
||||
//
|
||||
|
||||
#define UNZIP_READ_SIZE 67108860 /* 64 MiB */
|
||||
|
||||
//
|
||||
// Exported Functions
|
||||
//
|
||||
|
||||
bool CoreUnzip(std::filesystem::path file, std::filesystem::path path)
|
||||
{
|
||||
std::string error;
|
||||
|
||||
unzFile zipFile;
|
||||
unz_global_info zipInfo;
|
||||
std::ofstream outputStream;
|
||||
char* read_buffer = (char*)malloc(UNZIP_READ_SIZE);
|
||||
size_t bytes_read = 0;
|
||||
|
||||
if (read_buffer == nullptr)
|
||||
{
|
||||
error = "CoreUnzip: malloc Failed!";
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
zipFile = unzOpen(file.string().c_str());
|
||||
if (zipFile == nullptr)
|
||||
{
|
||||
free(read_buffer);
|
||||
error = "CoreUnzip: unzOpen Failed!";
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (unzGetGlobalInfo(zipFile, &zipInfo) != UNZ_OK)
|
||||
{
|
||||
free(read_buffer);
|
||||
error = "CoreUnzip: unzGetGlobalInfo Failed!";
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < zipInfo.number_entry; i++)
|
||||
{
|
||||
unz_file_info fileInfo;
|
||||
char fileName[PATH_MAX];
|
||||
std::filesystem::path targetPath;
|
||||
|
||||
// ensure we can retrieve the current file info
|
||||
if (unzGetCurrentFileInfo(zipFile, &fileInfo, fileName, PATH_MAX, nullptr, 0, nullptr, 0) != UNZ_OK)
|
||||
{
|
||||
free(read_buffer);
|
||||
unzClose(zipFile);
|
||||
error = "CoreUnzip: unzGetCurrentFileInfo Failed!";
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
targetPath = path;
|
||||
targetPath += "/";
|
||||
targetPath += fileName;
|
||||
|
||||
if (targetPath.string().ends_with("/"))
|
||||
{ // directory
|
||||
try
|
||||
{
|
||||
if (!std::filesystem::is_directory(targetPath) &&
|
||||
!std::filesystem::create_directory(targetPath))
|
||||
{
|
||||
throw std::exception();
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
free(read_buffer);
|
||||
unzClose(zipFile);
|
||||
error = "CoreUnzip: std::filesystem::create_directory(";
|
||||
error += targetPath.string();
|
||||
error += ") Failed!";
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // file
|
||||
if (unzOpenCurrentFile(zipFile) != UNZ_OK)
|
||||
{
|
||||
free(read_buffer);
|
||||
unzClose(zipFile);
|
||||
error = "CoreUnzip: unzOpenCurrentFile Failed!";
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
outputStream.open(targetPath, std::ios::trunc | std::ios::binary);
|
||||
if (!outputStream.is_open())
|
||||
{
|
||||
free(read_buffer);
|
||||
unzCloseCurrentFile(zipFile);
|
||||
unzClose(zipFile);
|
||||
error = "CoreUnzip: failed to open file!";
|
||||
error += targetPath.string();
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
bytes_read = unzReadCurrentFile(zipFile, read_buffer, UNZIP_READ_SIZE);
|
||||
if (bytes_read < 0)
|
||||
{
|
||||
free(read_buffer);
|
||||
unzCloseCurrentFile(zipFile);
|
||||
unzClose(zipFile);
|
||||
error = "CoreUnzip: unzReadCurrentFile Failed!";
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{ // write data to file
|
||||
outputStream.write(read_buffer, bytes_read);
|
||||
}
|
||||
} while (bytes_read > 0);
|
||||
|
||||
outputStream.close();
|
||||
unzCloseCurrentFile(zipFile);
|
||||
}
|
||||
|
||||
// break when we've iterated over all entries
|
||||
if ((i + 1) >= zipInfo.number_entry)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// move to next file
|
||||
if (unzGoToNextFile(zipFile) != UNZ_OK)
|
||||
{
|
||||
free(read_buffer);
|
||||
unzClose(zipFile);
|
||||
error = "CoreUnzip: unzGoToNextFile Failed!";
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
unzClose(zipFile);
|
||||
free(read_buffer);
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef CORE_UNZIP_HPP
|
||||
#define CORE_UNZIP_HPP
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
// attempts to unzip the file to path
|
||||
bool CoreUnzip(std::filesystem::path file, std::filesystem::path path);
|
||||
|
||||
#endif // CORE_UNZIP_HPP
|
||||
@@ -7,10 +7,14 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
QTableView
|
||||
#include "Version.hpp"
|
||||
#include "Config.hpp"
|
||||
|
||||
//
|
||||
// Exported Functions
|
||||
//
|
||||
|
||||
std::string CoreGetVersion(void)
|
||||
{
|
||||
border: none;
|
||||
color: #0096d3;
|
||||
selection-color: #FFFFFF;
|
||||
selection-background-color: #0096d3;
|
||||
return std::string(CORE_VERSION);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef CORE_VERSION_HPP
|
||||
#define CORE_VERSION_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
// returns the current RMG-Core version (as string)
|
||||
std::string CoreGetVersion(void);
|
||||
|
||||
#endif // CORE_VERSION_HPP
|
||||
@@ -168,7 +168,9 @@ typedef enum {
|
||||
M64CMD_NETPLAY_GET_VERSION,
|
||||
M64CMD_NETPLAY_CLOSE,
|
||||
M64CMD_PIF_OPEN,
|
||||
M64CMD_ROM_SET_SETTINGS
|
||||
M64CMD_ROM_SET_SETTINGS,
|
||||
M64CMD_DISK_OPEN,
|
||||
M64CMD_DISK_CLOSE
|
||||
} m64p_command;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define OSAL_DYNLIB_HPP
|
||||
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
@@ -25,11 +26,11 @@ typedef void* osal_dynlib_lib_sym;
|
||||
|
||||
// returns library handle for given filename,
|
||||
// return nullptr when invalid library
|
||||
osal_dynlib_lib_handle osal_dynlib_open(const char *);
|
||||
osal_dynlib_lib_handle osal_dynlib_open(std::filesystem::path path);
|
||||
|
||||
// retrieves symbol handle for given library
|
||||
// handle, returns nullptr when not found
|
||||
osal_dynlib_lib_sym osal_dynlib_sym(osal_dynlib_lib_handle, const char *);
|
||||
osal_dynlib_lib_sym osal_dynlib_sym(osal_dynlib_lib_handle, const char* symbol);
|
||||
|
||||
// closes library handle
|
||||
void osal_dynlib_close(osal_dynlib_lib_handle);
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
osal_dynlib_lib_handle osal_dynlib_open(const char* file)
|
||||
osal_dynlib_lib_handle osal_dynlib_open(std::filesystem::path path)
|
||||
{
|
||||
return dlopen(file, RTLD_LAZY);
|
||||
return dlopen(path.string().c_str(), RTLD_LAZY);
|
||||
}
|
||||
|
||||
osal_dynlib_lib_sym osal_dynlib_sym(osal_dynlib_lib_handle handle, const char *sym)
|
||||
osal_dynlib_lib_sym osal_dynlib_sym(osal_dynlib_lib_handle handle, const char* symbol)
|
||||
{
|
||||
return dlsym(handle, sym);
|
||||
return dlsym(handle, symbol);
|
||||
}
|
||||
|
||||
void osal_dynlib_close(osal_dynlib_lib_handle handle)
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
*/
|
||||
#include "osal_dynlib.hpp"
|
||||
|
||||
osal_dynlib_lib_handle osal_dynlib_open(const char* file)
|
||||
osal_dynlib_lib_handle osal_dynlib_open(std::filesystem::path path)
|
||||
{
|
||||
return LoadLibrary(file);
|
||||
return LoadLibraryW(path.wstring().c_str());
|
||||
}
|
||||
|
||||
osal_dynlib_lib_sym osal_dynlib_sym(osal_dynlib_lib_handle handle, const char *sym)
|
||||
osal_dynlib_lib_sym osal_dynlib_sym(osal_dynlib_lib_handle handle, const char* symbol)
|
||||
{
|
||||
return GetProcAddress(handle, sym);
|
||||
return GetProcAddress(handle, symbol);
|
||||
}
|
||||
|
||||
void osal_dynlib_close(osal_dynlib_lib_handle handle)
|
||||
|
||||
@@ -17,8 +17,9 @@ osal_files_file_time osal_files_get_file_time(std::filesystem::path file)
|
||||
BOOL ret;
|
||||
HANDLE file_handle;
|
||||
FILETIME file_time;
|
||||
ULARGE_INTEGER ularge_int;
|
||||
|
||||
file_handle = CreateFileA(file.string().c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
file_handle = CreateFileW(file.wstring().c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (file_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return -1;
|
||||
@@ -36,7 +37,8 @@ osal_files_file_time osal_files_get_file_time(std::filesystem::path file)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// this is probably incorrect but it doesn't matter
|
||||
// for our use-case
|
||||
return file_time.dwLowDateTime + file_time.dwHighDateTime;
|
||||
ularge_int.LowPart = file_time.dwLowDateTime;
|
||||
ularge_int.HighPart = file_time.dwHighDateTime;
|
||||
|
||||
return ularge_int.QuadPart;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ set(CMAKE_AUTOUIC ON)
|
||||
# disable lib prefix
|
||||
set(CMAKE_SHARED_LIBRARY_PREFIX "")
|
||||
|
||||
find_package(Qt5 COMPONENTS Gui Widgets Core Svg REQUIRED)
|
||||
find_package(${QT_VERSION} COMPONENTS Gui Widgets Core Svg REQUIRED)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(SDL2 REQUIRED sdl2)
|
||||
@@ -41,4 +41,4 @@ target_include_directories(RMG-Input PRIVATE
|
||||
${SDL2_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(RMG-Input Qt5::Gui Qt5::Widgets Qt5::Svg)
|
||||
target_link_libraries(RMG-Input ${QT_VERSION}::Gui ${QT_VERSION}::Widgets ${QT_VERSION}::Svg)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
using namespace UserInterface;
|
||||
|
||||
MainDialog::MainDialog(QWidget* parent, Thread::SDLThread* sdlThread) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
|
||||
MainDialog::MainDialog(QWidget* parent, Thread::SDLThread* sdlThread) : QDialog(parent)
|
||||
{
|
||||
this->setupUi(this);
|
||||
this->setWindowIcon(QIcon(":Resource/RMG.png"));
|
||||
|
||||
@@ -28,7 +28,7 @@ private:
|
||||
QString deviceName;
|
||||
int deviceNum;
|
||||
|
||||
bool operator== (inputDevice_t other)
|
||||
bool operator== (inputDevice_t other) const
|
||||
{
|
||||
return other.deviceNum == deviceNum &&
|
||||
other.deviceName == deviceName;
|
||||
|
||||
@@ -18,11 +18,14 @@ OptionsDialog::OptionsDialog(QWidget* parent, OptionsDialogSettings settings) :
|
||||
{
|
||||
this->setupUi(this);
|
||||
|
||||
this->setIconsForEmulationInfoText();
|
||||
|
||||
this->controllerPakComboBox->setCurrentIndex(settings.ControllerPak);
|
||||
this->gameboyRomLineEdit->setText(QString::fromStdString(settings.GameboyRom));
|
||||
this->gameboySaveLineEdit->setText(QString::fromStdString(settings.GameboySave));
|
||||
this->removeDuplicateMappingsCheckbox->setChecked(settings.RemoveDuplicateMappings);
|
||||
this->invertAxisCheckBox->setChecked(settings.InvertAxis);
|
||||
|
||||
if (!CoreIsEmulationRunning() && !CoreIsEmulationPaused())
|
||||
{
|
||||
this->hideEmulationInfoText();
|
||||
@@ -39,6 +42,21 @@ OptionsDialogSettings OptionsDialog::GetSettings()
|
||||
return this->settings;
|
||||
}
|
||||
|
||||
void OptionsDialog::setIconsForEmulationInfoText(void)
|
||||
{
|
||||
QLabel* labels[] = {
|
||||
this->infoIconLabel_0
|
||||
};
|
||||
|
||||
QIcon infoIcon = QIcon::fromTheme("information-line");
|
||||
QPixmap infoIconPixmap = infoIcon.pixmap(16, 16);
|
||||
|
||||
for (QLabel* label : labels)
|
||||
{
|
||||
label->setPixmap(infoIconPixmap);
|
||||
}
|
||||
}
|
||||
|
||||
void OptionsDialog::hideEmulationInfoText(void)
|
||||
{
|
||||
QHBoxLayout *layouts[] = {this->emulationInfoLayout_1};
|
||||
|
||||
@@ -43,6 +43,7 @@ private:
|
||||
bool hasSaved = false;
|
||||
OptionsDialogSettings settings;
|
||||
|
||||
void setIconsForEmulationInfoText(void);
|
||||
void hideEmulationInfoText(void);
|
||||
|
||||
private slots:
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="emulationInfoLayout_1">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<widget class="QLabel" name="infoIconLabel_0">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -162,7 +162,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="UIResources.qrc">:/Resource/Info.ico</pixmap>
|
||||
<pixmap>:/Resource/Info.ico</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>false</bool>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"
|
||||
id="svg21"
|
||||
sodipodi:docname="Controller.svg"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -23,15 +23,17 @@
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.28240146"
|
||||
inkscape:cx="-426.69751"
|
||||
inkscape:cy="3454.3023"
|
||||
inkscape:zoom="0.070600365"
|
||||
inkscape:cx="6019.7989"
|
||||
inkscape:cy="1600.5583"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg21" />
|
||||
inkscape:current-layer="layer2"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<path
|
||||
id="Dark-Grey-Background"
|
||||
serif:id="Dark Grey Background"
|
||||
@@ -111,4 +113,39 @@
|
||||
style="fill:#ec3f21"
|
||||
id="circle18" />
|
||||
</g>
|
||||
</svg>
|
||||
<g
|
||||
id="layer2"
|
||||
inkscape:label="Z-Button"
|
||||
style="display:inline;opacity:1;stroke-width:1;stroke-dasharray:none;paint-order:markers stroke fill"
|
||||
transform="matrix(50.366966,0,0,50.366966,3240.0678,-579.56452)"><g
|
||||
id="layer2-0"
|
||||
inkscape:label="Z-Button"
|
||||
style="clip-rule:evenodd;display:inline;fill-rule:evenodd;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:2;stroke-dasharray:none;paint-order:markers stroke fill"><rect
|
||||
style="clip-rule:evenodd;display:inline;opacity:1;fill:#5c5c5c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill;image-rendering:auto"
|
||||
id="rect1917-0-4"
|
||||
width="11.478539"
|
||||
height="16.72587"
|
||||
x="-32.517441"
|
||||
y="86.256668"
|
||||
ry="3.4675589"
|
||||
inkscape:label="btnZ-outline"
|
||||
class="theme-button"
|
||||
ojd-button="Z" /><rect
|
||||
style="display:inline;opacity:1;fill:#bcbdbf;fill-opacity:1;stroke:none;stroke-width:0.960842;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill;image-rendering:auto"
|
||||
id="rect1917-8"
|
||||
width="10.956328"
|
||||
height="16.177647"
|
||||
x="-32.225891"
|
||||
y="86.523468"
|
||||
ry="3.3539019"
|
||||
inkscape:label="btnZ"
|
||||
class="theme-button"
|
||||
ojd-button="Z" /><g
|
||||
aria-label="Z"
|
||||
style="font-style:normal;font-weight:normal;font-size:5.73478px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;clip-rule:evenodd;display:inline;opacity:1;fill:#56575b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.751267;stroke-linejoin:round;stroke-miterlimit:2;stroke-dasharray:none;paint-order:markers stroke fill"
|
||||
id="text1921-7"
|
||||
transform="matrix(1.3310888,0,0,1.3310888,-67.459296,-40.853038)"><path
|
||||
d="m 28.805176,99.685474 h 3.514231 v 0.652446 l -2.242948,2.71338 h 2.307352 v 0.81485 h -3.64304 v -0.65244 l 2.242948,-2.71338 h -2.178543 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#56575b;fill-opacity:1;stroke-width:0.751267;stroke-dasharray:none;paint-order:markers stroke fill"
|
||||
id="path2008-2"
|
||||
inkscape:connector-curvature="0" /></g></g></g></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 14 KiB |
@@ -8,7 +8,7 @@
|
||||
style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"
|
||||
id="svg21"
|
||||
sodipodi:docname="Controller_NoAnalogStick.svg"
|
||||
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
|
||||
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -23,15 +23,17 @@
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.14120073"
|
||||
inkscape:cx="2549.5619"
|
||||
inkscape:cy="3325.0536"
|
||||
inkscape:zoom="0.099843994"
|
||||
inkscape:cx="2829.4141"
|
||||
inkscape:cy="3475.4219"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1007"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg21" />
|
||||
inkscape:current-layer="svg21"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<path
|
||||
id="Dark-Grey-Background"
|
||||
serif:id="Dark Grey Background"
|
||||
@@ -101,4 +103,36 @@
|
||||
style="fill:#ec3f21"
|
||||
id="circle18" />
|
||||
</g>
|
||||
</svg>
|
||||
<g
|
||||
id="layer2"
|
||||
inkscape:label="Z-Button"
|
||||
style="display:inline;opacity:1;stroke-width:1;stroke-dasharray:none;paint-order:markers stroke fill"
|
||||
transform="matrix(50.366966,0,0,50.366966,3240.0678,-579.56452)"><rect
|
||||
style="clip-rule:evenodd;display:inline;opacity:1;fill:#5c5c5c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill;image-rendering:auto"
|
||||
id="rect1917-0"
|
||||
width="11.478539"
|
||||
height="16.72587"
|
||||
x="-32.517441"
|
||||
y="86.256668"
|
||||
ry="3.4675589"
|
||||
inkscape:label="btnZ-outline"
|
||||
class="theme-button"
|
||||
ojd-button="Z" /><rect
|
||||
style="display:inline;opacity:1;fill:#bcbdbf;fill-opacity:1;stroke:none;stroke-width:0.960842;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill;image-rendering:auto"
|
||||
id="rect1917"
|
||||
width="10.956328"
|
||||
height="16.177647"
|
||||
x="-32.225891"
|
||||
y="86.523468"
|
||||
ry="3.3539019"
|
||||
inkscape:label="btnZ"
|
||||
class="theme-button"
|
||||
ojd-button="Z" /><g
|
||||
aria-label="Z"
|
||||
style="font-style:normal;font-weight:normal;font-size:5.73478px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;clip-rule:evenodd;display:inline;opacity:1;fill:#56575b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.751267;stroke-linejoin:round;stroke-miterlimit:2;stroke-dasharray:none;paint-order:markers stroke fill"
|
||||
id="text1921"
|
||||
transform="matrix(1.3310888,0,0,1.3310888,-67.459296,-40.853038)"><path
|
||||
d="m 28.805176,99.685474 h 3.514231 v 0.652446 l -2.242948,2.71338 h 2.307352 v 0.81485 h -3.64304 v -0.65244 l 2.242948,-2.71338 h -2.178543 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#56575b;fill-opacity:1;stroke-width:0.751267;stroke-dasharray:none;paint-order:markers stroke fill"
|
||||
id="path2008"
|
||||
inkscape:connector-curvature="0" /></g></g></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="6939.9795"
|
||||
height="6772.564"
|
||||
viewBox="0 0 6939.9795 6772.564"
|
||||
version="1.1"
|
||||
xml:space="preserve"
|
||||
style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"
|
||||
id="svg21"
|
||||
sodipodi:docname="Controller_Pressed_ZTrigger.svg"
|
||||
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs25" /><sodipodi:namedview
|
||||
id="namedview23"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.099843994"
|
||||
inkscape:cx="2468.8516"
|
||||
inkscape:cy="3856.0156"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg21"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<g
|
||||
style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"
|
||||
id="g5916"
|
||||
transform="matrix(1.0882331,0,0,1.0882331,512.32815,1416.6572)"><circle
|
||||
style="opacity:0.62;fill:#ececec;fill-rule:evenodd;stroke-width:0.280377"
|
||||
id="path42"
|
||||
cx="1267.6501"
|
||||
cy="2546.3296"
|
||||
r="180.5985" /></g></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -15,7 +15,7 @@
|
||||
<file>Resource/Controller_Pressed_Start.svg</file>
|
||||
<file>Resource/Controller_Pressed_LeftTrigger.svg</file>
|
||||
<file>Resource/Controller_Pressed_RightTrigger.svg</file>
|
||||
<file>Resource/Controller_Pressed_ZTrigger.svg</file>
|
||||
<file>Resource/RMG.png</file>
|
||||
<file>Resource/Info.ico</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -125,6 +125,7 @@ void ControllerImageWidget::paintEvent(QPaintEvent *event)
|
||||
{ N64ControllerButton::CButtonRight, ":Resource/Controller_Pressed_CButtonRight.svg" },
|
||||
{ N64ControllerButton::LeftTrigger, ":Resource/Controller_Pressed_LeftTrigger.svg" },
|
||||
{ N64ControllerButton::RightTrigger, ":Resource/Controller_Pressed_RightTrigger.svg" },
|
||||
{ N64ControllerButton::ZTrigger, ":Resource/Controller_Pressed_ZTrigger.svg" }
|
||||
};
|
||||
|
||||
static const QString baseImageUri = ":Resource/Controller_NoAnalogStick.svg";
|
||||
|
||||
@@ -58,6 +58,7 @@ ControllerWidget::ControllerWidget(QWidget* parent, EventFilter* eventFilter) :
|
||||
{ N64ControllerButton::CButtonRight, this->cbuttonRightButton },
|
||||
{ N64ControllerButton::LeftTrigger, this->leftTriggerButton },
|
||||
{ N64ControllerButton::RightTrigger, this->rightTriggerButton },
|
||||
{ N64ControllerButton::ZTrigger, this->zTriggerButton }
|
||||
});
|
||||
|
||||
this->joystickWidgetMappings.append(
|
||||
@@ -121,7 +122,7 @@ ControllerWidget::ControllerWidget(QWidget* parent, EventFilter* eventFilter) :
|
||||
this->setupButtonWidgets.append(button);
|
||||
}
|
||||
|
||||
|
||||
this->on_controllerPluggedCheckBox_toggled(false);
|
||||
this->initializeButtons();
|
||||
}
|
||||
|
||||
@@ -292,6 +293,13 @@ void ControllerWidget::CheckInputDeviceSettings()
|
||||
std::string deviceName = CoreSettingsGetStringValue(SettingsID::Input_DeviceName, section);
|
||||
int deviceNum = CoreSettingsGetIntValue(SettingsID::Input_DeviceNum, section);
|
||||
|
||||
// do nothing when input device combobox
|
||||
// is empty
|
||||
if (this->inputDeviceComboBox->count() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// clear (not found) devices first
|
||||
int notFoundIndex = this->inputDeviceComboBox->findText("(not found)", Qt::MatchFlag::MatchEndsWith);
|
||||
if (notFoundIndex != -1)
|
||||
@@ -302,11 +310,11 @@ void ControllerWidget::CheckInputDeviceSettings()
|
||||
|
||||
int deviceNameIndex = this->inputDeviceComboBox->findText(QString::fromStdString(deviceName), Qt::MatchFlag::MatchStartsWith);
|
||||
int deviceNumIndex = this->inputDeviceComboBox->findData(deviceNum);
|
||||
|
||||
if ((deviceNameIndex == deviceNumIndex) &&
|
||||
(deviceNameIndex != -1))
|
||||
|
||||
if ((deviceNumIndex != -1) &&
|
||||
(this->inputDeviceComboBox->itemText(deviceNumIndex).startsWith(QString::fromStdString(deviceName))))
|
||||
{ // full match
|
||||
this->inputDeviceComboBox->setCurrentIndex(deviceNameIndex);
|
||||
this->inputDeviceComboBox->setCurrentIndex(deviceNumIndex);
|
||||
}
|
||||
else if (deviceNameIndex != -1)
|
||||
{ // name only match
|
||||
@@ -363,7 +371,7 @@ void ControllerWidget::on_profileComboBox_currentIndexChanged(int value)
|
||||
// reload settings from section
|
||||
this->LoadSettings(this->getCurrentSettingsSection());
|
||||
// reload input device settings
|
||||
CheckInputDeviceSettings();
|
||||
this->CheckInputDeviceSettings();
|
||||
}
|
||||
|
||||
void ControllerWidget::on_inputDeviceComboBox_currentIndexChanged(int value)
|
||||
@@ -446,11 +454,15 @@ void ControllerWidget::on_removeProfileButton_clicked()
|
||||
if (this->profileComboBox->currentIndex() == 0)
|
||||
{
|
||||
QMessageBox messageBox(this);
|
||||
messageBox.setIcon(QMessageBox::Icon::Critical);
|
||||
messageBox.setWindowTitle("Error");
|
||||
messageBox.setText("Cannot remove main profile!");
|
||||
messageBox.addButton(QMessageBox::Ok);
|
||||
messageBox.exec();
|
||||
messageBox.setIcon(QMessageBox::Icon::Warning);
|
||||
messageBox.setText("Are you sure you want to reset the main profile?");
|
||||
messageBox.addButton(QMessageBox::Yes);
|
||||
messageBox.addButton(QMessageBox::No);
|
||||
if (messageBox.exec() == QMessageBox::Yes)
|
||||
{
|
||||
this->SaveDefaultSettings();
|
||||
this->LoadSettings(this->getCurrentSettingsSection());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -911,6 +923,8 @@ void ControllerWidget::LoadSettings(QString sectionQString)
|
||||
|
||||
buttonSetting.button->SetInputData(type, data, extraData, QString::fromStdString(name));
|
||||
}
|
||||
|
||||
this->on_controllerPluggedCheckBox_toggled(this->IsPluggedIn());
|
||||
}
|
||||
|
||||
void ControllerWidget::SaveDefaultSettings()
|
||||
@@ -927,7 +941,11 @@ void ControllerWidget::SaveDefaultSettings()
|
||||
CoreSettingsSetValue(SettingsID::Input_DeviceNum, section, -1);
|
||||
CoreSettingsSetValue(SettingsID::Input_Deadzone, section, 9);
|
||||
CoreSettingsSetValue(SettingsID::Input_Pak, section, 0);
|
||||
#ifdef _WIN32
|
||||
CoreSettingsSetValue(SettingsID::Input_RemoveDuplicateMappings, section, true);
|
||||
#else
|
||||
CoreSettingsSetValue(SettingsID::Input_RemoveDuplicateMappings, section, false);
|
||||
#endif // _WIN32
|
||||
CoreSettingsSetValue(SettingsID::Input_InvertAxis, section, true);
|
||||
|
||||
for (auto& buttonSetting : this->buttonSettingMappings)
|
||||
|
||||
@@ -5,21 +5,37 @@ set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
|
||||
find_package(Qt5 COMPONENTS Gui Widgets Core REQUIRED)
|
||||
find_package(${QT_VERSION} COMPONENTS Gui Widgets Core OpenGL REQUIRED)
|
||||
|
||||
if (PORTABLE_INSTALL)
|
||||
add_definitions(-DPORTABLE_INSTALL)
|
||||
endif(PORTABLE_INSTALL)
|
||||
|
||||
if (UPDATER)
|
||||
find_package(${QT_VERSION} COMPONENTS Network REQUIRED)
|
||||
add_definitions(-DUPDATER)
|
||||
endif(UPDATER)
|
||||
|
||||
if (DISCORD_RPC)
|
||||
add_definitions(-DDISCORD_RPC)
|
||||
endif(DISCORD_RPC)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(SDL2 REQUIRED sdl2)
|
||||
|
||||
configure_file(Config.hpp.in Config.hpp)
|
||||
|
||||
set(RMG_SOURCES
|
||||
UserInterface/MainWindow.cpp
|
||||
UserInterface/MainWindow.ui
|
||||
UserInterface/Widget/RomBrowserWidget.cpp
|
||||
UserInterface/Widget/RomBrowserListViewWidget.cpp
|
||||
UserInterface/Widget/RomBrowserGridViewWidget.cpp
|
||||
UserInterface/Widget/RomBrowserLoadingWidget.cpp
|
||||
UserInterface/Widget/RomBrowserEmptyWidget.cpp
|
||||
UserInterface/Widget/RomBrowserEmptyWidget.ui
|
||||
UserInterface/Widget/OGLWidget.cpp
|
||||
UserInterface/Widget/KeybindButton.cpp
|
||||
UserInterface/Dialog/SettingsDialog.cpp
|
||||
UserInterface/Dialog/SettingsDialog.ui
|
||||
UserInterface/Dialog/SettingsDialog.qrc
|
||||
UserInterface/Dialog/CheatsDialog.cpp
|
||||
UserInterface/Dialog/CheatsDialog.ui
|
||||
UserInterface/Dialog/AddCheatDialog.cpp
|
||||
@@ -30,6 +46,8 @@ set(RMG_SOURCES
|
||||
UserInterface/Dialog/RomInfoDialog.ui
|
||||
UserInterface/Dialog/AboutDialog.cpp
|
||||
UserInterface/Dialog/AboutDialog.ui
|
||||
UserInterface/Dialog/LogDialog.cpp
|
||||
UserInterface/Dialog/LogDialog.ui
|
||||
UserInterface/NoFocusDelegate.cpp
|
||||
UserInterface/EventFilter.cpp
|
||||
UserInterface/UIResources.rc
|
||||
@@ -42,6 +60,17 @@ set(RMG_SOURCES
|
||||
main.cpp
|
||||
)
|
||||
|
||||
if (UPDATER)
|
||||
list(APPEND RMG_SOURCES
|
||||
UserInterface/Dialog/UpdateDialog.cpp
|
||||
UserInterface/Dialog/UpdateDialog.ui
|
||||
UserInterface/Dialog/DownloadUpdateDialog.cpp
|
||||
UserInterface/Dialog/DownloadUpdateDialog.ui
|
||||
UserInterface/Dialog/InstallUpdateDialog.cpp
|
||||
UserInterface/Dialog/InstallUpdateDialog.ui
|
||||
)
|
||||
endif(UPDATER)
|
||||
|
||||
if (CMAKE_BUILD_TYPE MATCHES Release)
|
||||
add_executable(RMG WIN32 ${RMG_SOURCES})
|
||||
else()
|
||||
@@ -50,7 +79,6 @@ endif()
|
||||
|
||||
target_link_libraries(RMG
|
||||
RMG-Core
|
||||
${SDL2_LIBRARIES}
|
||||
)
|
||||
|
||||
target_include_directories(RMG PRIVATE
|
||||
@@ -60,4 +88,9 @@ target_include_directories(RMG PRIVATE
|
||||
${SDL2_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(RMG Qt5::Gui Qt5::Widgets)
|
||||
target_link_libraries(RMG ${QT_VERSION}::Gui ${QT_VERSION}::Widgets ${QT_VERSION}::OpenGL)
|
||||
|
||||
if (UPDATER)
|
||||
target_link_libraries(RMG ${QT_VERSION}::Network)
|
||||
endif(UPDATER)
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
//
|
||||
|
||||
static CoreCallbacks* l_CoreCallbacks = nullptr;
|
||||
static bool l_showVerboseMessages = false;
|
||||
|
||||
//
|
||||
// Exported Functions
|
||||
@@ -36,6 +37,8 @@ bool CoreCallbacks::Init(void)
|
||||
// needed for Qt
|
||||
qRegisterMetaType<CoreDebugMessageType>("CoreDebugMessageType");
|
||||
|
||||
this->LoadSettings();
|
||||
|
||||
l_CoreCallbacks = this;
|
||||
return CoreSetupCallbacks(this->coreDebugCallback);
|
||||
}
|
||||
@@ -45,12 +48,23 @@ void CoreCallbacks::Stop(void)
|
||||
l_CoreCallbacks = nullptr;
|
||||
}
|
||||
|
||||
void CoreCallbacks::coreDebugCallback(CoreDebugMessageType type, std::string message)
|
||||
void CoreCallbacks::LoadSettings(void)
|
||||
{
|
||||
l_showVerboseMessages = CoreSettingsGetBoolValue(SettingsID::GUI_ShowVerboseLogMessages);
|
||||
}
|
||||
|
||||
void CoreCallbacks::coreDebugCallback(CoreDebugMessageType type, std::string context, std::string message)
|
||||
{
|
||||
if (l_CoreCallbacks == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
emit l_CoreCallbacks->OnCoreDebugCallback(type, QString::fromStdString(message));
|
||||
// only show verbose messages when enabled
|
||||
if (!l_showVerboseMessages && type == CoreDebugMessageType::Verbose)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
emit l_CoreCallbacks->OnCoreDebugCallback(type, QString::fromStdString(context), QString::fromStdString(message));
|
||||
}
|
||||
|
||||
@@ -27,11 +27,13 @@ public:
|
||||
bool Init(void);
|
||||
void Stop(void);
|
||||
|
||||
void LoadSettings(void);
|
||||
|
||||
private:
|
||||
static void coreDebugCallback(CoreDebugMessageType type, std::string message);
|
||||
static void coreDebugCallback(CoreDebugMessageType type, std::string context, std::string message);
|
||||
|
||||
signals:
|
||||
void OnCoreDebugCallback(CoreDebugMessageType type, QString message);
|
||||
void OnCoreDebugCallback(CoreDebugMessageType type, QString context, QString message);
|
||||
};
|
||||
|
||||
#endif // RMG_CALLBACKS_HPP
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef CONFIG_HPP
|
||||
#define CONFIG_HPP
|
||||
|
||||
#define WINDOW_TITLE "Rosalie's Mupen GUI (${GIT_VERSION})"
|
||||
#define VERSION_STR "${GIT_VERSION}"
|
||||
|
||||
#endif // CONFIG_HPP
|
||||
@@ -44,9 +44,8 @@ class EmulationThread : public QThread
|
||||
void on_VidExt_ResizeWindow(int, int);
|
||||
|
||||
void on_VidExt_Init(void);
|
||||
void on_VidExt_SetMode(int, int, int, int, int);
|
||||
void on_VidExt_SetWindowedModeWithRate(int, int, int, int, int);
|
||||
void on_VidExt_SetFullscreenModeWithRate(int, int, int, int, int);
|
||||
void on_VidExt_SetWindowedMode(int, int, int, int);
|
||||
void on_VidExt_SetFullscreenMode(int, int, int, int);
|
||||
void on_VidExt_SetCaption(QString);
|
||||
void on_VidExt_ToggleFS(bool);
|
||||
void on_VidExt_Quit(void);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <QDir>
|
||||
#include <QDirIterator>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
using namespace Thread;
|
||||
|
||||
@@ -28,22 +29,22 @@ RomSearcherThread::~RomSearcherThread(void)
|
||||
|
||||
void RomSearcherThread::SetDirectory(QString directory)
|
||||
{
|
||||
this->rom_Directory = directory;
|
||||
this->directory = directory;
|
||||
}
|
||||
|
||||
void RomSearcherThread::SetRecursive(bool value)
|
||||
{
|
||||
this->rom_Search_Recursive = value;
|
||||
this->recursive = value;
|
||||
}
|
||||
|
||||
void RomSearcherThread::SetMaximumFiles(int value)
|
||||
{
|
||||
this->rom_Search_MaxItems = value;
|
||||
this->maxItems = value;
|
||||
}
|
||||
|
||||
void RomSearcherThread::Stop(void)
|
||||
{
|
||||
this->rom_Search_Stop = true;
|
||||
this->stop = true;
|
||||
while (this->isRunning())
|
||||
{
|
||||
this->wait();
|
||||
@@ -52,12 +53,12 @@ void RomSearcherThread::Stop(void)
|
||||
|
||||
void RomSearcherThread::run(void)
|
||||
{
|
||||
this->rom_Search_Stop = false;
|
||||
this->rom_Search(this->rom_Directory);
|
||||
this->stop = false;
|
||||
this->searchDirectory(this->directory);
|
||||
return;
|
||||
}
|
||||
|
||||
void RomSearcherThread::rom_Search(QString directory)
|
||||
void RomSearcherThread::searchDirectory(QString directory)
|
||||
{
|
||||
QDir dir(directory);
|
||||
|
||||
@@ -69,7 +70,7 @@ void RomSearcherThread::rom_Search(QString directory)
|
||||
filter << "*.D64";
|
||||
filter << "*.ZIP";
|
||||
|
||||
QDirIterator::IteratorFlag flag = this->rom_Search_Recursive ?
|
||||
QDirIterator::IteratorFlag flag = this->recursive ?
|
||||
QDirIterator::Subdirectories :
|
||||
QDirIterator::NoIteratorFlags;
|
||||
QDirIterator romDirIt(directory, filter, QDir::Files, flag);
|
||||
@@ -83,6 +84,9 @@ void RomSearcherThread::rom_Search(QString directory)
|
||||
{
|
||||
QString file = romDirIt.next();
|
||||
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
if (CoreHasRomHeaderAndSettingsCached(file.toStdU32String()))
|
||||
{ // found cache entry
|
||||
ret = CoreGetCachedRomHeaderAndSettings(file.toStdU32String(), header, settings);
|
||||
@@ -104,18 +108,27 @@ void RomSearcherThread::rom_Search(QString directory)
|
||||
|
||||
if (ret)
|
||||
{
|
||||
if (count++ >= this->rom_Search_MaxItems)
|
||||
if (count++ >= this->maxItems)
|
||||
{
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
emit this->on_Rom_Found(file, header, settings);
|
||||
emit this->RomFound(file, header, settings);
|
||||
}
|
||||
|
||||
if (this->rom_Search_Stop)
|
||||
if (this->stop)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// ensure the UI thread has some breathing room
|
||||
// instead of being locked up and unable to render anything
|
||||
if (timer.elapsed() < 10)
|
||||
{
|
||||
QThread::msleep(10 - timer.elapsed());
|
||||
}
|
||||
}
|
||||
|
||||
emit this->Finished(this->stop);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,15 +33,16 @@ class RomSearcherThread : public QThread
|
||||
void run(void) override;
|
||||
|
||||
private:
|
||||
QString rom_Directory;
|
||||
bool rom_Search_Recursive;
|
||||
int rom_Search_MaxItems;
|
||||
bool rom_Search_Stop = false;
|
||||
QString directory;
|
||||
bool recursive = false;
|
||||
int maxItems = 0;
|
||||
bool stop = false;
|
||||
|
||||
void rom_Search(QString);
|
||||
void searchDirectory(QString);
|
||||
|
||||
signals:
|
||||
void on_Rom_Found(QString file, CoreRomHeader header, CoreRomSettings settings);
|
||||
void RomFound(QString file, CoreRomHeader header, CoreRomSettings settings);
|
||||
void Finished(bool canceled);
|
||||
};
|
||||
} // namespace Thread
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
*/
|
||||
#include "AboutDialog.hpp"
|
||||
|
||||
#include "Config.hpp"
|
||||
#include <RMG-Core/Core.hpp>
|
||||
|
||||
using namespace UserInterface::Dialog;
|
||||
|
||||
AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
|
||||
AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent)
|
||||
{
|
||||
this->setupUi(this);
|
||||
|
||||
this->versionLabel->setText(QString("RMG %1").arg(VERSION_STR));
|
||||
this->versionLabel->setText(QString("RMG %1").arg(QString::fromStdString(CoreGetVersion())));
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Copyright © 2020-2022 Rosalie Wanders</string>
|
||||
<string>Copyright © 2020-2023 Rosalie Wanders</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
using namespace UserInterface::Dialog;
|
||||
|
||||
AddCheatDialog::AddCheatDialog(QWidget *parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
|
||||
AddCheatDialog::AddCheatDialog(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
this->setupUi(this);
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ Q_DECLARE_METATYPE(CoreCheat);
|
||||
|
||||
using namespace UserInterface::Dialog;
|
||||
|
||||
CheatsDialog::CheatsDialog(QWidget *parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
|
||||
CheatsDialog::CheatsDialog(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
qRegisterMetaType<CoreCheat>();
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ Q_DECLARE_METATYPE(CoreCheatOption);
|
||||
|
||||
using namespace UserInterface::Dialog;
|
||||
|
||||
ChooseCheatOptionDialog::ChooseCheatOptionDialog(CoreCheat cheat, QWidget *parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
|
||||
ChooseCheatOptionDialog::ChooseCheatOptionDialog(CoreCheat cheat, QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
qRegisterMetaType<CoreCheatOption>();
|
||||
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "DownloadUpdateDialog.hpp"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QFileInfo>
|
||||
#include <QPushButton>
|
||||
#include <QDesktopServices>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
#include <QTemporaryDir>
|
||||
#include <QFile>
|
||||
|
||||
using namespace UserInterface::Dialog;
|
||||
|
||||
DownloadUpdateDialog::DownloadUpdateDialog(QWidget *parent, QUrl url, QString filename) : QDialog(parent)
|
||||
{
|
||||
this->setupUi(this);
|
||||
|
||||
this->filename = filename;
|
||||
this->label->setText("Downloading " + filename + "...");
|
||||
|
||||
QNetworkAccessManager* networkAccessManager = new QNetworkAccessManager(this);
|
||||
QNetworkRequest request(url);
|
||||
request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||
|
||||
this->reply = networkAccessManager->get(request);
|
||||
connect(reply, &QNetworkReply::downloadProgress, this, &DownloadUpdateDialog::on_reply_downloadProgress);
|
||||
connect(reply, &QNetworkReply::finished, this, &DownloadUpdateDialog::on_reply_finished);
|
||||
}
|
||||
|
||||
DownloadUpdateDialog::~DownloadUpdateDialog(void)
|
||||
{
|
||||
}
|
||||
|
||||
QString DownloadUpdateDialog::GetTempDirectory(void)
|
||||
{
|
||||
return this->temporaryDirectory;
|
||||
}
|
||||
|
||||
QString DownloadUpdateDialog::GetFileName(void)
|
||||
{
|
||||
return this->filename;
|
||||
}
|
||||
|
||||
void DownloadUpdateDialog::showErrorMessage(QString error, QString details)
|
||||
{
|
||||
QMessageBox msgBox((this->isVisible() ? this : this->parentWidget()));
|
||||
msgBox.setIcon(QMessageBox::Icon::Critical);
|
||||
msgBox.setWindowTitle("Error");
|
||||
msgBox.setText(error);
|
||||
msgBox.setDetailedText(details);
|
||||
msgBox.addButton(QMessageBox::Ok);
|
||||
msgBox.exec();
|
||||
}
|
||||
|
||||
void DownloadUpdateDialog::on_reply_downloadProgress(qint64 size, qint64 total)
|
||||
{
|
||||
this->progressBar->setMaximum(total);
|
||||
this->progressBar->setMinimum(0);
|
||||
this->progressBar->setValue(size);
|
||||
}
|
||||
|
||||
void DownloadUpdateDialog::on_reply_finished(void)
|
||||
{
|
||||
if (this->reply->error())
|
||||
{
|
||||
this->showErrorMessage("Failed to download update file!", this->reply->errorString());
|
||||
this->reply->deleteLater();
|
||||
this->reject();
|
||||
return;
|
||||
}
|
||||
|
||||
QTemporaryDir temporaryDir;
|
||||
temporaryDir.setAutoRemove(false);
|
||||
if (!temporaryDir.isValid())
|
||||
{
|
||||
this->showErrorMessage("Failed to create temporary directory!", "");
|
||||
this->reply->deleteLater();
|
||||
this->reject();
|
||||
return;
|
||||
}
|
||||
|
||||
this->temporaryDirectory = temporaryDir.path();
|
||||
|
||||
QFile file(temporaryDir.filePath(this->filename));
|
||||
file.open(QIODevice::WriteOnly);
|
||||
file.write(this->reply->readAll());
|
||||
file.close();
|
||||
|
||||
this->reply->deleteLater();
|
||||
this->accept();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef DOWNLOADUPDATEDIALOG_HPP
|
||||
#define DOWNLOADUPDATEDIALOG_HPP
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
#include <QJsonObject>
|
||||
#include <QNetworkReply>
|
||||
|
||||
#include <RMG-Core/Core.hpp>
|
||||
#include <qglobal.h>
|
||||
|
||||
#include "ui_DownloadUpdateDialog.h"
|
||||
|
||||
namespace UserInterface
|
||||
{
|
||||
namespace Dialog
|
||||
{
|
||||
class DownloadUpdateDialog : public QDialog, private Ui::DownloadUpdateDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QNetworkReply *reply;
|
||||
QString temporaryDirectory;
|
||||
QString filename;
|
||||
|
||||
void showErrorMessage(QString error, QString details);
|
||||
|
||||
public:
|
||||
DownloadUpdateDialog(QWidget *parent, QUrl url, QString filename);
|
||||
~DownloadUpdateDialog(void);
|
||||
|
||||
QString GetTempDirectory(void);
|
||||
QString GetFileName(void);
|
||||
|
||||
private slots:
|
||||
void on_reply_downloadProgress(qint64 size, qint64 total);
|
||||
void on_reply_finished(void);
|
||||
};
|
||||
} // namespace Dialog
|
||||
} // namespace UserInterface
|
||||
|
||||
#endif // DOWNLOADUPDATEDIALOG_HPP
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DownloadUpdateDialog</class>
|
||||
<widget class="QDialog" name="DownloadUpdateDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>238</width>
|
||||
<height>62</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Downloading Update</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Downloading ...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "InstallUpdateDialog.hpp"
|
||||
#include "RMG-Core/Error.hpp"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QProcess>
|
||||
#include <QDir>
|
||||
#include <QTextStream>
|
||||
|
||||
using namespace UserInterface::Dialog;
|
||||
|
||||
InstallUpdateDialog::InstallUpdateDialog(QWidget *parent, QString installationDirectory, QString temporaryDirectory, QString filename) : QDialog(parent)
|
||||
{
|
||||
this->setupUi(this);
|
||||
|
||||
this->installationDirectory = installationDirectory;
|
||||
this->temporaryDirectory = temporaryDirectory;
|
||||
this->filename = filename;
|
||||
this->startTimer(100);
|
||||
}
|
||||
|
||||
InstallUpdateDialog::~InstallUpdateDialog(void)
|
||||
{
|
||||
}
|
||||
|
||||
void InstallUpdateDialog::install(void)
|
||||
{
|
||||
QString fullFilePath;
|
||||
fullFilePath = this->temporaryDirectory;
|
||||
fullFilePath += "/" + this->filename;
|
||||
|
||||
QString appPath = QCoreApplication::applicationDirPath();
|
||||
QString appPid = QString::number(QCoreApplication::applicationPid());
|
||||
|
||||
#ifdef _WIN32
|
||||
if (this->filename.endsWith(".exe"))
|
||||
{
|
||||
this->label->setText("Executing " + this->filename + "...");
|
||||
QStringList scriptLines =
|
||||
{
|
||||
"@echo off",
|
||||
"taskkill /F /PID:" + appPid,
|
||||
"\"" + fullFilePath + "\" /CLOSEAPPLICATIONS /SILENT /DIR=\"" + appPath + "\"",
|
||||
"rmdir /S /Q \"" + this->temporaryDirectory + "\"",
|
||||
};
|
||||
this->writeAndRunScript(scriptLines);
|
||||
this->accept();
|
||||
return;
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
this->label->setText("Extracting " + this->filename + "...");
|
||||
this->progressBar->setValue(50);
|
||||
|
||||
QDir dir(this->temporaryDirectory);
|
||||
if (!dir.mkdir("extract"))
|
||||
{
|
||||
this->showErrorMessage("QDir::mkdir() Failed!", "");
|
||||
this->reject();
|
||||
return;
|
||||
}
|
||||
|
||||
QString extractDirectory;
|
||||
extractDirectory = this->temporaryDirectory;
|
||||
extractDirectory += "/extract";
|
||||
|
||||
if (!CoreUnzip(fullFilePath.toStdU32String(), extractDirectory.toStdU32String()))
|
||||
{
|
||||
this->showErrorMessage("CoreUnzip() Failed!", QString::fromStdString(CoreGetError()));
|
||||
this->reject();
|
||||
return;
|
||||
}
|
||||
|
||||
this->label->setText("Executing update script...");
|
||||
this->progressBar->setValue(100);
|
||||
|
||||
#ifdef _WIN32
|
||||
QStringList scriptLines =
|
||||
{
|
||||
"@echo off",
|
||||
"del /F /Q \"" + fullFilePath + "\"",
|
||||
"taskkill /F /PID:" + appPid,
|
||||
"xcopy /S /Y /I \"" + extractDirectory + "\\*\" \"" + appPath + "/\"",
|
||||
"start \"\" \"" + appPath + "\\RMG.exe\"",
|
||||
"rmdir /S /Q \"" + this->temporaryDirectory + "\"",
|
||||
};
|
||||
this->writeAndRunScript(scriptLines);
|
||||
#else // Linux
|
||||
QStringList scriptLines =
|
||||
{
|
||||
"#!/usr/bin/env bash",
|
||||
"set -e",
|
||||
"rm -rf \"" + fullFilePath + "\"",
|
||||
"kill -1 " + appPid,
|
||||
"cp -R \"" + extractDirectory + "/\"* \"" + appPath + "/\"",
|
||||
"chmod +x \"" + appPath + "/RMG\"",
|
||||
"\"" + appPath + "/RMG\"&",
|
||||
"rm -rf \"" + this->temporaryDirectory + "\"" ,
|
||||
};
|
||||
this->writeAndRunScript(scriptLines);
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
void InstallUpdateDialog::writeAndRunScript(QStringList stringList)
|
||||
{
|
||||
QString scriptPath;
|
||||
scriptPath = this->temporaryDirectory;
|
||||
#ifdef _WIN32
|
||||
scriptPath += "/update.bat";
|
||||
#else
|
||||
scriptPath += "/update.sh";
|
||||
#endif // _WIN32
|
||||
|
||||
QFile scriptFile(scriptPath);
|
||||
if (!scriptFile.open(QIODevice::WriteOnly | QIODevice::Text))
|
||||
{
|
||||
this->showErrorMessage("QFile::open() Failed!", "");
|
||||
return;
|
||||
}
|
||||
|
||||
QTextStream textStream(&scriptFile);
|
||||
|
||||
// write script to file
|
||||
for (const QString& str : stringList)
|
||||
{
|
||||
textStream << str << "\n";
|
||||
}
|
||||
|
||||
scriptFile.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner);
|
||||
scriptFile.close();
|
||||
|
||||
this->launchProcess(scriptPath, {});
|
||||
}
|
||||
|
||||
void InstallUpdateDialog::launchProcess(QString file, QStringList arguments)
|
||||
{
|
||||
QProcess process;
|
||||
process.setProgram(file);
|
||||
process.setArguments(arguments);
|
||||
process.startDetached();
|
||||
}
|
||||
|
||||
void InstallUpdateDialog::showErrorMessage(QString error, QString details)
|
||||
{
|
||||
QMessageBox msgBox((this->isVisible() ? this : this->parentWidget()));
|
||||
msgBox.setIcon(QMessageBox::Icon::Critical);
|
||||
msgBox.setWindowTitle("Error");
|
||||
msgBox.setText(error);
|
||||
msgBox.setDetailedText(details);
|
||||
msgBox.addButton(QMessageBox::Ok);
|
||||
msgBox.exec();
|
||||
}
|
||||
|
||||
void InstallUpdateDialog::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
this->killTimer(event->timerId());
|
||||
this->install();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef INSTALLUPDATEDIALOG_HPP
|
||||
#define INSTALLUPDATEDIALOG_HPP
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
|
||||
#include <RMG-Core/Core.hpp>
|
||||
|
||||
#include "ui_InstallUpdateDialog.h"
|
||||
|
||||
namespace UserInterface
|
||||
{
|
||||
namespace Dialog
|
||||
{
|
||||
class InstallUpdateDialog : public QDialog, private Ui::InstallUpdateDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QString installationDirectory;
|
||||
QString temporaryDirectory;
|
||||
QString filename;
|
||||
|
||||
void install(void);
|
||||
|
||||
void writeAndRunScript(QStringList stringList);
|
||||
void launchProcess(QString file, QStringList arguments);
|
||||
void showErrorMessage(QString error, QString details);
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE;
|
||||
|
||||
public:
|
||||
InstallUpdateDialog(QWidget *parent, QString installationDirectory, QString temporaryDirectory, QString filename);
|
||||
~InstallUpdateDialog(void);
|
||||
};
|
||||
} // namespace Dialog
|
||||
} // namespace UserInterface
|
||||
|
||||
#endif // INSTALLUPDATEDIALOG_HPP
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>InstallUpdateDialog</class>
|
||||
<widget class="QDialog" name="InstallUpdateDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>223</width>
|
||||
<height>62</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Installing Update</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Installing...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "LogDialog.hpp"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QFileInfo>
|
||||
#include <QFont>
|
||||
#include <QIcon>
|
||||
|
||||
using namespace UserInterface::Dialog;
|
||||
|
||||
LogDialog::LogDialog(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
this->setupUi(this);
|
||||
this->setWindowIcon(QIcon(":Resource/RMG.png"));
|
||||
|
||||
QFont font("monospace");
|
||||
this->plainTextEdit->setFont(font);
|
||||
}
|
||||
|
||||
LogDialog::~LogDialog(void)
|
||||
{
|
||||
}
|
||||
|
||||
void LogDialog::AddLogLine(CoreDebugMessageType type, QString context, QString line)
|
||||
{
|
||||
QString text;
|
||||
|
||||
text = context;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case CoreDebugMessageType::Error:
|
||||
text += "[ERROR] ";
|
||||
break;
|
||||
case CoreDebugMessageType::Info:
|
||||
text += "[INFO] ";
|
||||
break;
|
||||
case CoreDebugMessageType::Verbose:
|
||||
text += "[VERBOSE] ";
|
||||
break;
|
||||
case CoreDebugMessageType::Warning:
|
||||
text += "[WARNING] ";
|
||||
break;
|
||||
case CoreDebugMessageType::Status:
|
||||
text += "[STATUS] ";
|
||||
break;
|
||||
}
|
||||
|
||||
text += line;
|
||||
|
||||
this->plainTextEdit->appendPlainText(text);
|
||||
}
|
||||
|
||||
void LogDialog::Clear(void)
|
||||
{
|
||||
this->plainTextEdit->clear();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef LOGDIALOG_HPP
|
||||
#define LOGDIALOG_HPP
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
|
||||
#include <RMG-Core/Core.hpp>
|
||||
|
||||
#include "ui_LogDialog.h"
|
||||
|
||||
namespace UserInterface
|
||||
{
|
||||
namespace Dialog
|
||||
{
|
||||
class LogDialog : public QDialog, private Ui::LogDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
|
||||
public:
|
||||
LogDialog(QWidget* parent = nullptr);
|
||||
~LogDialog(void);
|
||||
|
||||
void Clear(void);
|
||||
public slots:
|
||||
void AddLogLine(CoreDebugMessageType type, QString context, QString line);
|
||||
};
|
||||
} // namespace Dialog
|
||||
} // namespace UserInterface
|
||||
|
||||
#endif // LOGDIALOG_HPP
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>LogDialog</class>
|
||||
<widget class="QDialog" name="LogDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>550</width>
|
||||
<height>480</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Log</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="plainTextEdit">
|
||||
<property name="lineWrapMode">
|
||||
<enum>QPlainTextEdit::NoWrap</enum>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -14,63 +14,25 @@
|
||||
|
||||
using namespace UserInterface::Dialog;
|
||||
|
||||
RomInfoDialog::RomInfoDialog(QString file, QWidget *parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
|
||||
RomInfoDialog::RomInfoDialog(QString file, CoreRomHeader romHeader, CoreRomSettings romSettings, QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
this->setupUi(this);
|
||||
|
||||
bool needCloseRom = false;
|
||||
|
||||
CoreRomHeader romHeader;
|
||||
CoreRomSettings romSettings;
|
||||
|
||||
// try to open ROM
|
||||
if (!CoreOpenRom(file.toStdU32String()))
|
||||
{
|
||||
this->showErrorMessage(parent, "CoreOpenRom() Failed", QString::fromStdString(CoreGetError()));
|
||||
return;
|
||||
}
|
||||
|
||||
// try to retrieve ROM header
|
||||
if (!CoreGetCurrentRomHeader(romHeader))
|
||||
{
|
||||
this->showErrorMessage(parent, "CoreGetCurrentRomHeader() Failed", QString::fromStdString(CoreGetError()));
|
||||
return;
|
||||
}
|
||||
|
||||
// try to retrieve ROM settings
|
||||
if (!CoreGetCurrentRomSettings(romSettings))
|
||||
{
|
||||
this->showErrorMessage(parent, "CoreGetCurrentRomSettings() Failed", QString::fromStdString(CoreGetError()));
|
||||
return;
|
||||
}
|
||||
|
||||
QFileInfo qFileInfo(file);
|
||||
|
||||
this->romNameLineEdit->setText(QString::fromStdString(romHeader.Name));
|
||||
this->romNameLineEdit->setCursorPosition(0);
|
||||
this->md5LineEdit->setText(QString::fromStdString(romSettings.MD5));
|
||||
this->md5LineEdit->setCursorPosition(0);
|
||||
this->fileNameLineEdit->setText(qFileInfo.fileName());
|
||||
this->fileNameLineEdit->setCursorPosition(0);
|
||||
this->locationLineEdit->setText(qFileInfo.absolutePath());
|
||||
this->locationLineEdit->setCursorPosition(0);
|
||||
this->crc1LineEdit->setText(QString::number(romHeader.CRC1, 16).toUpper());
|
||||
this->crc2LineEdit->setText(QString::number(romHeader.CRC2, 16).toUpper());
|
||||
|
||||
if (!CoreCloseRom())
|
||||
{
|
||||
this->showErrorMessage(parent, "CoreCloseRom() Failed", QString::fromStdString(CoreGetError()));
|
||||
return;
|
||||
}
|
||||
this->countryCodeLineEdit->setText(QString((char)romHeader.CountryCode));
|
||||
}
|
||||
|
||||
RomInfoDialog::~RomInfoDialog(void)
|
||||
{
|
||||
}
|
||||
|
||||
void RomInfoDialog::showErrorMessage(QWidget* parent, QString error, QString details)
|
||||
{
|
||||
QMessageBox msgBox(parent);
|
||||
msgBox.setIcon(QMessageBox::Icon::Critical);
|
||||
msgBox.setWindowTitle("Error");
|
||||
msgBox.setText(error);
|
||||
msgBox.setDetailedText(details);
|
||||
msgBox.addButton(QMessageBox::Ok);
|
||||
msgBox.exec();
|
||||
}
|
||||
|
||||
@@ -25,11 +25,8 @@ class RomInfoDialog : public QDialog, private Ui::RomInfoDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
void showErrorMessage(QWidget* parent, QString error, QString details);
|
||||
|
||||
public:
|
||||
RomInfoDialog(QString file, QWidget *parent);
|
||||
RomInfoDialog(QString file, CoreRomHeader romHeader, CoreRomSettings romSettings, QWidget *parent);
|
||||
~RomInfoDialog(void);
|
||||
};
|
||||
} // namespace Dialog
|
||||
|
||||
@@ -13,206 +13,225 @@
|
||||
<property name="windowTitle">
|
||||
<string>ROM Information</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string/>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>ROM Information</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ROM Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="romNameLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>File Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="fileNameLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Location:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="locationLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>MD5:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="md5LineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>CRC1:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="crc1LineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>CRC2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="crc2LineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>112</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="romNameLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>File Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="fileNameLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Location</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="locationLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>MD5</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="md5LineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>CRC1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="crc1LineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>CRC2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="crc2LineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Country Code</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="countryCodeLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
||||
@@ -8,18 +8,23 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "SettingsDialog.hpp"
|
||||
#include "RMG-Core/DiscordRpc.hpp"
|
||||
#include "RMG-Core/Settings/Settings.hpp"
|
||||
#include "UserInterface/Widget/KeybindButton.hpp"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QDirIterator>
|
||||
#include <QLabel>
|
||||
|
||||
using namespace UserInterface::Dialog;
|
||||
|
||||
SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
|
||||
SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
this->setupUi(this);
|
||||
|
||||
this->setIconsForEmulationInfoText();
|
||||
|
||||
this->romOpened = CoreHasRomOpen();
|
||||
if (romOpened)
|
||||
{
|
||||
@@ -42,13 +47,32 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent, Qt::WindowSyst
|
||||
|
||||
pluginList = CoreGetAllPlugins();
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
for (int i = 0; i < 13; i++)
|
||||
{
|
||||
this->reloadSettings(i);
|
||||
}
|
||||
|
||||
// connect hotkey settings to slot
|
||||
this->commonHotkeySettings(-1);
|
||||
this->commonHotkeySettings(SettingsDialogAction::ConnectSignals);
|
||||
|
||||
#ifndef UPDATER
|
||||
this->checkForUpdatesCheckBox->setHidden(true);
|
||||
#endif // !UPDATER
|
||||
|
||||
#ifndef DISCORD_RPC
|
||||
this->discordRpcCheckBox->setHidden(true);
|
||||
|
||||
// if both DISCORD_RPC & UPDATER
|
||||
// aren't defined, hide the tab
|
||||
// with the settings for those
|
||||
#ifndef UPDATER
|
||||
this->innerInterfaceTabWidget->removeTab(4);
|
||||
#endif // !UPDATER
|
||||
#endif // !DISCORD_RPC
|
||||
|
||||
#ifndef _WIN32
|
||||
this->innerInterfaceTabWidget->removeTab(3);
|
||||
#endif
|
||||
|
||||
int width = CoreSettingsGetIntValue(SettingsID::GUI_SettingsDialogWidth);
|
||||
int height = CoreSettingsGetIntValue(SettingsID::GUI_SettingsDialogHeight);
|
||||
@@ -101,34 +125,43 @@ void SettingsDialog::restoreDefaults(int stackedWidgetIndex)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
loadDefaultCoreSettings();
|
||||
this->loadDefaultCoreSettings();
|
||||
break;
|
||||
case 1:
|
||||
loadDefaultGameSettings();
|
||||
this->loadDefaultGameSettings();
|
||||
break;
|
||||
case 2:
|
||||
loadDefaultGameCoreSettings();
|
||||
this->loadDefaultGameCoreSettings();
|
||||
break;
|
||||
case 3:
|
||||
loadDefaultGamePluginSettings();
|
||||
this->loadDefaultGamePluginSettings();
|
||||
break;
|
||||
case 4:
|
||||
loadDefaultPluginSettings();
|
||||
this->loadDefaultPluginSettings();
|
||||
break;
|
||||
case 5:
|
||||
loadDefaultDirectorySettings();
|
||||
this->loadDefaultDirectorySettings();
|
||||
break;
|
||||
case 6:
|
||||
loadDefault64DDSettings();
|
||||
this->loadDefault64DDSettings();
|
||||
break;
|
||||
case 7:
|
||||
loadDefaultHotkeySettings();
|
||||
this->loadDefaultHotkeySettings();
|
||||
break;
|
||||
case 8:
|
||||
loadDefaultInterfaceEmulationSettings();
|
||||
this->loadDefaultInterfaceEmulationSettings();
|
||||
break;
|
||||
case 9:
|
||||
loadDefaultInterfaceRomBrowserSettings();
|
||||
this->loadDefaultInterfaceRomBrowserSettings();
|
||||
break;
|
||||
case 10:
|
||||
this->loadDefaultInterfaceLogWindowSettings();
|
||||
break;
|
||||
case 11:
|
||||
this->loadDefaultInterfaceStyleSettings();
|
||||
break;
|
||||
case 12:
|
||||
this->loadDefaultInterfaceMiscSettings();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -139,34 +172,43 @@ void SettingsDialog::reloadSettings(int stackedWidgetIndex)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
loadCoreSettings();
|
||||
this->loadCoreSettings();
|
||||
break;
|
||||
case 1:
|
||||
loadGameSettings();
|
||||
this->loadGameSettings();
|
||||
break;
|
||||
case 2:
|
||||
loadGameCoreSettings();
|
||||
this->loadGameCoreSettings();
|
||||
break;
|
||||
case 3:
|
||||
loadGamePluginSettings();
|
||||
this->loadGamePluginSettings();
|
||||
break;
|
||||
case 4:
|
||||
loadPluginSettings();
|
||||
this->loadPluginSettings();
|
||||
break;
|
||||
case 5:
|
||||
loadDirectorySettings();
|
||||
this->loadDirectorySettings();
|
||||
break;
|
||||
case 6:
|
||||
load64DDSettings();
|
||||
this->load64DDSettings();
|
||||
break;
|
||||
case 7:
|
||||
loadHotkeySettings();
|
||||
this->loadHotkeySettings();
|
||||
break;
|
||||
case 8:
|
||||
loadInterfaceEmulationSettings();
|
||||
this->loadInterfaceEmulationSettings();
|
||||
break;
|
||||
case 9:
|
||||
loadInterfaceRomBrowserSettings();
|
||||
this->loadInterfaceRomBrowserSettings();
|
||||
break;
|
||||
case 10:
|
||||
this->loadInterfaceLogWindowSettings();
|
||||
break;
|
||||
case 11:
|
||||
this->loadInterfaceStyleSettings();
|
||||
break;
|
||||
case 12:
|
||||
this->loadInterfaceMiscSettings();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -191,7 +233,7 @@ void SettingsDialog::loadCoreSettings(void)
|
||||
|
||||
this->coreCpuEmulatorComboBox->setCurrentIndex(cpuEmulator);
|
||||
this->coreRandomizeTimingCheckBox->setChecked(randomizeInterrupt);
|
||||
this->coreDebuggerCheckBox->setChecked(debugger);
|
||||
//this->coreDebuggerCheckBox->setChecked(debugger);
|
||||
|
||||
this->coreOverrideGameSettingsGroup->setChecked(overrideGameSettings);
|
||||
|
||||
@@ -282,7 +324,7 @@ void SettingsDialog::loadGamePluginSettings(void)
|
||||
|
||||
void SettingsDialog::loadPluginSettings(void)
|
||||
{
|
||||
this->commonPluginSettings(0);
|
||||
this->commonPluginSettings(SettingsDialogAction::LoadSettings);
|
||||
}
|
||||
|
||||
void SettingsDialog::loadDirectorySettings(void)
|
||||
@@ -331,7 +373,7 @@ void SettingsDialog::load64DDSettings(void)
|
||||
|
||||
void SettingsDialog::loadHotkeySettings(void)
|
||||
{
|
||||
this->commonHotkeySettings(0);
|
||||
this->commonHotkeySettings(SettingsDialogAction::LoadSettings);
|
||||
}
|
||||
|
||||
void SettingsDialog::loadInterfaceEmulationSettings(void)
|
||||
@@ -351,6 +393,26 @@ void SettingsDialog::loadInterfaceRomBrowserSettings(void)
|
||||
this->romSearchLimitSpinBox->setValue(CoreSettingsGetIntValue(SettingsID::RomBrowser_MaxItems));
|
||||
}
|
||||
|
||||
void SettingsDialog::loadInterfaceLogWindowSettings(void)
|
||||
{
|
||||
this->showVerboseLogMessagesCheckBox->setChecked(CoreSettingsGetBoolValue(SettingsID::GUI_ShowVerboseLogMessages));
|
||||
}
|
||||
|
||||
void SettingsDialog::loadInterfaceStyleSettings(void)
|
||||
{
|
||||
this->commonInterfaceStyleSettings(SettingsDialogAction::LoadSettings);
|
||||
}
|
||||
|
||||
void SettingsDialog::loadInterfaceMiscSettings(void)
|
||||
{
|
||||
#ifdef UPDATER
|
||||
this->checkForUpdatesCheckBox->setChecked(CoreSettingsGetBoolValue(SettingsID::GUI_CheckForUpdates));
|
||||
#endif // UPDATER
|
||||
#ifdef DISCORD_RPC
|
||||
this->discordRpcCheckBox->setChecked(CoreSettingsGetBoolValue(SettingsID::GUI_DiscordRpc));
|
||||
#endif // DISCORD_RPC
|
||||
}
|
||||
|
||||
void SettingsDialog::loadDefaultCoreSettings(void)
|
||||
{
|
||||
bool disableExtraMem = false;
|
||||
@@ -371,7 +433,7 @@ void SettingsDialog::loadDefaultCoreSettings(void)
|
||||
|
||||
this->coreCpuEmulatorComboBox->setCurrentIndex(cpuEmulator);
|
||||
this->coreRandomizeTimingCheckBox->setChecked(randomizeInterrupt);
|
||||
this->coreDebuggerCheckBox->setChecked(debugger);
|
||||
//this->coreDebuggerCheckBox->setChecked(debugger);
|
||||
|
||||
this->coreOverrideGameSettingsGroup->setChecked(overrideGameSettings);
|
||||
|
||||
@@ -425,7 +487,7 @@ void SettingsDialog::loadDefaultGamePluginSettings(void)
|
||||
|
||||
void SettingsDialog::loadDefaultPluginSettings(void)
|
||||
{
|
||||
this->commonPluginSettings(1);
|
||||
this->commonPluginSettings(SettingsDialogAction::LoadDefaultSettings);
|
||||
}
|
||||
|
||||
void SettingsDialog::loadDefaultDirectorySettings(void)
|
||||
@@ -448,7 +510,7 @@ void SettingsDialog::loadDefault64DDSettings(void)
|
||||
|
||||
void SettingsDialog::loadDefaultHotkeySettings(void)
|
||||
{
|
||||
this->commonHotkeySettings(1);
|
||||
this->commonHotkeySettings(SettingsDialogAction::LoadDefaultSettings);
|
||||
}
|
||||
|
||||
void SettingsDialog::loadDefaultInterfaceEmulationSettings(void)
|
||||
@@ -468,6 +530,26 @@ void SettingsDialog::loadDefaultInterfaceRomBrowserSettings(void)
|
||||
this->romSearchLimitSpinBox->setValue(CoreSettingsGetDefaultIntValue(SettingsID::RomBrowser_MaxItems));
|
||||
}
|
||||
|
||||
void SettingsDialog::loadDefaultInterfaceLogWindowSettings(void)
|
||||
{
|
||||
this->showVerboseLogMessagesCheckBox->setChecked(CoreSettingsGetDefaultBoolValue(SettingsID::GUI_ShowVerboseLogMessages));
|
||||
}
|
||||
|
||||
void SettingsDialog::loadDefaultInterfaceStyleSettings(void)
|
||||
{
|
||||
this->commonInterfaceStyleSettings(SettingsDialogAction::LoadDefaultSettings);
|
||||
}
|
||||
|
||||
void SettingsDialog::loadDefaultInterfaceMiscSettings(void)
|
||||
{
|
||||
#ifdef UPDATER
|
||||
this->checkForUpdatesCheckBox->setChecked(CoreSettingsGetDefaultBoolValue(SettingsID::GUI_CheckForUpdates));
|
||||
#endif // UPDATER
|
||||
#ifdef DISCORD_RPC
|
||||
this->discordRpcCheckBox->setChecked(CoreSettingsGetDefaultBoolValue(SettingsID::GUI_DiscordRpc));
|
||||
#endif // DISCORD_RPC
|
||||
}
|
||||
|
||||
void SettingsDialog::saveSettings(void)
|
||||
{
|
||||
this->saveCoreSettings();
|
||||
@@ -485,6 +567,9 @@ void SettingsDialog::saveSettings(void)
|
||||
this->saveHotkeySettings();
|
||||
this->saveInterfaceEmulationSettings();
|
||||
this->saveInterfaceRomBrowserSettings();
|
||||
this->saveInterfaceLogWindowSettings();
|
||||
this->saveInterfaceStyleSettings();
|
||||
this->saveInterfaceMiscSettings();
|
||||
}
|
||||
|
||||
void SettingsDialog::saveCoreSettings(void)
|
||||
@@ -494,12 +579,12 @@ void SettingsDialog::saveCoreSettings(void)
|
||||
int cpuEmulator = this->coreCpuEmulatorComboBox->currentIndex();
|
||||
int siDmaDuration = this->coreSiDmaDurationSpinBox->value();
|
||||
bool randomizeInterrupt = this->coreRandomizeTimingCheckBox->isChecked();
|
||||
bool debugger = this->coreDebuggerCheckBox->isChecked();
|
||||
//bool debugger = this->coreDebuggerCheckBox->isChecked();
|
||||
bool overrideGameSettings = this->coreOverrideGameSettingsGroup->isChecked();
|
||||
|
||||
CoreSettingsSetValue(SettingsID::CoreOverlay_CPU_Emulator, cpuEmulator);
|
||||
CoreSettingsSetValue(SettingsID::CoreOverlay_RandomizeInterrupt, randomizeInterrupt);
|
||||
CoreSettingsSetValue(SettingsID::CoreOverlay_EnableDebugger, debugger);
|
||||
//CoreSettingsSetValue(SettingsID::CoreOverlay_EnableDebugger, debugger);
|
||||
CoreSettingsSetValue(SettingsID::Core_OverrideGameSpecificSettings, overrideGameSettings);
|
||||
|
||||
if (!overrideGameSettings)
|
||||
@@ -623,7 +708,7 @@ void SettingsDialog::save64DDSettings(void)
|
||||
|
||||
void SettingsDialog::saveHotkeySettings(void)
|
||||
{
|
||||
this->commonHotkeySettings(2);
|
||||
this->commonHotkeySettings(SettingsDialogAction::SaveSettings);
|
||||
}
|
||||
|
||||
void SettingsDialog::saveInterfaceEmulationSettings(void)
|
||||
@@ -643,47 +728,123 @@ void SettingsDialog::saveInterfaceRomBrowserSettings(void)
|
||||
CoreSettingsSetValue(SettingsID::RomBrowser_MaxItems, this->romSearchLimitSpinBox->value());
|
||||
}
|
||||
|
||||
void SettingsDialog::commonHotkeySettings(int action)
|
||||
void SettingsDialog::saveInterfaceLogWindowSettings(void)
|
||||
{
|
||||
struct
|
||||
CoreSettingsSetValue(SettingsID::GUI_ShowVerboseLogMessages, this->showVerboseLogMessagesCheckBox->isChecked());
|
||||
}
|
||||
|
||||
void SettingsDialog::saveInterfaceStyleSettings(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
CoreSettingsSetValue(SettingsID::GUI_Style, this->styleComboBox->currentData().toString().toStdString());
|
||||
CoreSettingsSetValue(SettingsID::GUI_IconTheme, this->iconThemeComboBox->currentText().toStdString());
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
void SettingsDialog::saveInterfaceMiscSettings(void)
|
||||
{
|
||||
#ifdef UPDATER
|
||||
CoreSettingsSetValue(SettingsID::GUI_CheckForUpdates, this->checkForUpdatesCheckBox->isChecked());
|
||||
#endif // UPDATER
|
||||
#ifdef DISCORD_RPC
|
||||
CoreSettingsSetValue(SettingsID::GUI_DiscordRpc, this->discordRpcCheckBox->isChecked());
|
||||
#endif // DISCORD_RPC
|
||||
}
|
||||
|
||||
void SettingsDialog::commonHotkeySettings(SettingsDialogAction action)
|
||||
{
|
||||
struct keybinding
|
||||
{
|
||||
KeybindButton* button;
|
||||
SettingsID settingId;
|
||||
} keybindings[] =
|
||||
};
|
||||
|
||||
std::vector<keybinding> keybindings;
|
||||
|
||||
std::vector<keybinding> keybindings_System =
|
||||
{
|
||||
{ this->openRomKeyButton, SettingsID::KeyBinding_OpenROM },
|
||||
{ this->openComboKeyButton, SettingsID::KeyBinding_OpenCombo },
|
||||
{ this->startEmuKeyButton, SettingsID::KeyBinding_StartEmulation },
|
||||
{ this->endEmuKeyButton, SettingsID::KeyBinding_EndEmulation },
|
||||
{ this->startRomKeyButton, SettingsID::KeyBinding_StartROM },
|
||||
{ this->startComboKeyButton, SettingsID::KeyBinding_StartCombo },
|
||||
{ this->shutdownKeyButton, SettingsID::KeyBinding_Shutdown },
|
||||
{ this->refreshRomListKeyButton, SettingsID::KeyBinding_RefreshROMList },
|
||||
{ this->exitKeyButton, SettingsID::KeyBinding_Exit },
|
||||
{ this->softResetKeyButton, SettingsID::KeyBinding_SoftReset },
|
||||
{ this->hardResetKeyButton, SettingsID::KeyBinding_HardReset },
|
||||
{ this->pauseKeyButton, SettingsID::KeyBinding_Resume },
|
||||
{ this->generateBitmapKeyButton, SettingsID::KeyBinding_GenerateBitmap },
|
||||
{ this->generateBitmapKeyButton, SettingsID::KeyBinding_Screenshot },
|
||||
{ this->limitFPSKeyButton, SettingsID::KeyBinding_LimitFPS },
|
||||
{ this->swapDiskKeyButton, SettingsID::KeyBinding_SwapDisk },
|
||||
{ this->saveStateKeyButton, SettingsID::KeyBinding_SaveState },
|
||||
{ this->saveAsKeyButton, SettingsID::KeyBinding_SaveAs },
|
||||
{ this->loadStateKeyButton, SettingsID::KeyBinding_LoadState },
|
||||
{ this->loadKeyButton, SettingsID::KeyBinding_Load },
|
||||
{ this->cheatsKeyButton, SettingsID::KeyBinding_Cheats },
|
||||
{ this->gsButtonKeyButton, SettingsID::KeyBinding_GSButton },
|
||||
{ this->fullscreenKeyButton, SettingsID::KeyBinding_Fullscreen },
|
||||
};
|
||||
|
||||
std::vector<keybinding> keybindings_CurrentSaveState =
|
||||
{
|
||||
{ this->saveState0KeyButton, SettingsID::KeyBinding_SaveStateSlot0 },
|
||||
{ this->saveState1KeyButton, SettingsID::KeyBinding_SaveStateSlot1 },
|
||||
{ this->saveState2KeyButton, SettingsID::KeyBinding_SaveStateSlot2 },
|
||||
{ this->saveState3KeyButton, SettingsID::KeyBinding_SaveStateSlot3 },
|
||||
{ this->saveState4KeyButton, SettingsID::KeyBinding_SaveStateSlot4 },
|
||||
{ this->saveState5KeyButton, SettingsID::KeyBinding_SaveStateSlot5 },
|
||||
{ this->saveState6KeyButton, SettingsID::KeyBinding_SaveStateSlot6 },
|
||||
{ this->saveState7KeyButton, SettingsID::KeyBinding_SaveStateSlot7 },
|
||||
{ this->saveState8KeyButton, SettingsID::KeyBinding_SaveStateSlot8 },
|
||||
{ this->saveState9KeyButton, SettingsID::KeyBinding_SaveStateSlot9 },
|
||||
};
|
||||
|
||||
std::vector<keybinding> keybindings_Settings =
|
||||
{
|
||||
{ this->settingsKeyButton, SettingsID::KeyBinding_Settings },
|
||||
};
|
||||
|
||||
std::vector<keybinding> keybindings_View =
|
||||
{
|
||||
{ this->fullscreenKeyButton, SettingsID::KeyBinding_Fullscreen },
|
||||
};
|
||||
|
||||
|
||||
if (action == SettingsDialogAction::LoadDefaultSettings)
|
||||
{
|
||||
int index = this->keybindingsMenuTabWidget->currentIndex();
|
||||
switch (index)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
keybindings.insert(keybindings.end(), keybindings_System.begin(), keybindings_System.end());
|
||||
break;
|
||||
case 1:
|
||||
keybindings.insert(keybindings.end(), keybindings_CurrentSaveState.begin(), keybindings_CurrentSaveState.end());
|
||||
break;
|
||||
case 2:
|
||||
keybindings.insert(keybindings.end(), keybindings_Settings.begin(), keybindings_Settings.end());
|
||||
break;
|
||||
case 3:
|
||||
keybindings.insert(keybindings.end(), keybindings_View.begin(), keybindings_View.end());
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
keybindings.insert(keybindings.end(), keybindings_System.begin(), keybindings_System.end());
|
||||
keybindings.insert(keybindings.end(), keybindings_CurrentSaveState.begin(), keybindings_CurrentSaveState.end());
|
||||
keybindings.insert(keybindings.end(), keybindings_Settings.begin(), keybindings_Settings.end());
|
||||
keybindings.insert(keybindings.end(), keybindings_View.begin(), keybindings_View.end());
|
||||
}
|
||||
|
||||
switch (action)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case 0:
|
||||
case SettingsDialogAction::LoadSettings:
|
||||
this->removeDuplicateHotkeysCheckBox->setChecked(CoreSettingsGetBoolValue(SettingsID::KeyBinding_RemoveDuplicates));
|
||||
break;
|
||||
case 1:
|
||||
case SettingsDialogAction::LoadDefaultSettings:
|
||||
this->removeDuplicateHotkeysCheckBox->setChecked(CoreSettingsGetDefaultBoolValue(SettingsID::KeyBinding_RemoveDuplicates));
|
||||
break;
|
||||
case 2:
|
||||
case SettingsDialogAction::SaveSettings:
|
||||
CoreSettingsSetValue(SettingsID::KeyBinding_RemoveDuplicates, this->removeDuplicateHotkeysCheckBox->isChecked());
|
||||
break;
|
||||
}
|
||||
@@ -693,22 +854,22 @@ void SettingsDialog::commonHotkeySettings(int action)
|
||||
switch (action)
|
||||
{
|
||||
default:
|
||||
case -1:
|
||||
case SettingsDialogAction::ConnectSignals:
|
||||
connect(keybinding.button, &KeybindButton::on_KeybindButton_KeybindingChanged, this, &SettingsDialog::on_KeybindButton_KeybindingChanged);
|
||||
case 0:
|
||||
case SettingsDialogAction::LoadSettings:
|
||||
keybinding.button->setText(QString::fromStdString(CoreSettingsGetStringValue(keybinding.settingId)));
|
||||
break;
|
||||
case 1:
|
||||
case SettingsDialogAction::LoadDefaultSettings:
|
||||
keybinding.button->setText(QString::fromStdString(CoreSettingsGetDefaultStringValue(keybinding.settingId)));
|
||||
break;
|
||||
case 2:
|
||||
case SettingsDialogAction::SaveSettings:
|
||||
CoreSettingsSetValue(keybinding.settingId, keybinding.button->text().toStdString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::commonPluginSettings(int action)
|
||||
void SettingsDialog::commonPluginSettings(SettingsDialogAction action)
|
||||
{
|
||||
QComboBox *comboBoxArray[] = {this->rspPluginsComboBox, this->videoPluginsComboBox,
|
||||
this->audioPluginsComboBox, this->inputPluginsComboBox};
|
||||
@@ -731,7 +892,7 @@ void SettingsDialog::commonPluginSettings(int action)
|
||||
index = ((int)p.Type - 1);
|
||||
comboBox = comboBoxArray[index];
|
||||
|
||||
pluginFileName = action == 0 ?
|
||||
pluginFileName = action == SettingsDialogAction::LoadSettings ?
|
||||
CoreSettingsGetStringValue(settingsIdArray[index]) :
|
||||
CoreSettingsGetDefaultStringValue(settingsIdArray[index]);
|
||||
|
||||
@@ -755,11 +916,79 @@ void SettingsDialog::commonPluginSettings(int action)
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::commonInterfaceStyleSettings(SettingsDialogAction action)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
this->styleComboBox->clear();
|
||||
this->styleComboBox->addItem("None", "");
|
||||
|
||||
QString currentStyle = action == SettingsDialogAction::LoadSettings ?
|
||||
QString::fromStdString(CoreSettingsGetStringValue(SettingsID::GUI_Style)) :
|
||||
QString::fromStdString(CoreSettingsGetDefaultStringValue(SettingsID::GUI_Style));
|
||||
|
||||
QString directory;
|
||||
directory = QString::fromStdString(CoreGetSharedDataDirectory().string());
|
||||
directory += "\\Styles\\";
|
||||
|
||||
QStringList filter;
|
||||
filter << "*.qss";
|
||||
|
||||
bool styleFound = false;
|
||||
QDirIterator stylesDirectoryIter(directory, filter, QDir::Files, QDirIterator::NoIteratorFlags);
|
||||
while (stylesDirectoryIter.hasNext())
|
||||
{
|
||||
QString filePath = stylesDirectoryIter.next();
|
||||
QFileInfo fileInfo(filePath);
|
||||
|
||||
this->styleComboBox->addItem(fileInfo.baseName(), filePath);
|
||||
if (filePath == currentStyle)
|
||||
{
|
||||
styleFound = true;
|
||||
this->styleComboBox->setCurrentText(fileInfo.baseName());
|
||||
}
|
||||
}
|
||||
|
||||
if (currentStyle.isEmpty())
|
||||
{
|
||||
this->styleComboBox->setCurrentText("None");
|
||||
styleFound = true;
|
||||
}
|
||||
|
||||
if (!styleFound)
|
||||
{
|
||||
this->styleComboBox->addItem("", "");
|
||||
this->styleComboBox->setCurrentText("");
|
||||
}
|
||||
|
||||
QString currentIconTheme = action == SettingsDialogAction::LoadSettings ?
|
||||
QString::fromStdString(CoreSettingsGetStringValue(SettingsID::GUI_IconTheme)) :
|
||||
QString::fromStdString(CoreSettingsGetDefaultStringValue(SettingsID::GUI_IconTheme));
|
||||
this->iconThemeComboBox->setCurrentText(currentIconTheme);
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
void SettingsDialog::setIconsForEmulationInfoText(void)
|
||||
{
|
||||
QLabel* labels[] = {
|
||||
this->infoIconLabel_0, this->infoIconLabel_1, this->infoIconLabel_2,
|
||||
this->infoIconLabel_3, this->infoIconLabel_4, this->infoIconLabel_5,
|
||||
this->infoIconLabel_6, this->infoIconLabel_7
|
||||
};
|
||||
|
||||
QIcon infoIcon = QIcon::fromTheme("information-line");
|
||||
QPixmap infoIconPixmap = infoIcon.pixmap(16, 16);
|
||||
|
||||
for (QLabel* label : labels)
|
||||
{
|
||||
label->setPixmap(infoIconPixmap);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::hideEmulationInfoText(void)
|
||||
{
|
||||
QHBoxLayout *layouts[] = {this->emulationInfoLayout_0, this->emulationInfoLayout_1,
|
||||
this->emulationInfoLayout_2, this->emulationInfoLayout_3,
|
||||
this->emulationInfoLayout_9, this->emulationInfoLayout_13};
|
||||
this->emulationInfoLayout_9};
|
||||
|
||||
for (const auto &layout : layouts)
|
||||
{
|
||||
@@ -797,6 +1026,40 @@ void SettingsDialog::chooseIPLRom(QLineEdit *lineEdit)
|
||||
lineEdit->setText(file);
|
||||
}
|
||||
|
||||
bool SettingsDialog::applyPluginSettings(void)
|
||||
{
|
||||
// attempt to apply plugin settings when emulation
|
||||
// isn't running, when it fails, show the user the error and
|
||||
// don't allow the user to save invalid settings
|
||||
if (!CoreIsEmulationPaused() && !CoreIsEmulationRunning())
|
||||
{
|
||||
if (!CoreApplyPluginSettings())
|
||||
{
|
||||
QMessageBox msgBox(this);
|
||||
msgBox.setIcon(QMessageBox::Icon::Critical);
|
||||
msgBox.setWindowTitle("Error");
|
||||
msgBox.setText("CoreApplyPluginSettings() Failed");
|
||||
msgBox.setDetailedText(QString::fromStdString(CoreGetError()));
|
||||
msgBox.addButton(QMessageBox::Ok);
|
||||
msgBox.exec();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SettingsDialog::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
if (this->applyPluginSettings())
|
||||
{
|
||||
event->accept();
|
||||
}
|
||||
else
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::on_buttonBox_clicked(QAbstractButton *button)
|
||||
{
|
||||
QPushButton *pushButton = (QPushButton *)button;
|
||||
@@ -812,22 +1075,9 @@ void SettingsDialog::on_buttonBox_clicked(QAbstractButton *button)
|
||||
this->saveSettings();
|
||||
}
|
||||
|
||||
// attempt to apply plugin settings when emulation
|
||||
// isn't running, when it fails, show the user the error and
|
||||
// don't allow the user to save invalid settings
|
||||
if (!CoreIsEmulationPaused() && !CoreIsEmulationRunning())
|
||||
if (!this->applyPluginSettings())
|
||||
{
|
||||
if (!CoreApplyPluginSettings())
|
||||
{
|
||||
QMessageBox msgBox(this);
|
||||
msgBox.setIcon(QMessageBox::Icon::Critical);
|
||||
msgBox.setWindowTitle("Error");
|
||||
msgBox.setText("CoreApplyPluginSettings() Failed");
|
||||
msgBox.setDetailedText(QString::fromStdString(CoreGetError()));
|
||||
msgBox.addButton(QMessageBox::Ok);
|
||||
msgBox.exec();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -900,10 +1150,9 @@ void SettingsDialog::on_KeybindButton_KeybindingChanged(KeybindButton* button)
|
||||
|
||||
KeybindButton* keybindButtons[] =
|
||||
{
|
||||
this->openRomKeyButton,
|
||||
this->openComboKeyButton,
|
||||
this->startEmuKeyButton,
|
||||
this->endEmuKeyButton,
|
||||
this->startRomKeyButton,
|
||||
this->startComboKeyButton,
|
||||
this->shutdownKeyButton,
|
||||
this->refreshRomListKeyButton,
|
||||
this->exitKeyButton,
|
||||
this->softResetKeyButton,
|
||||
@@ -911,15 +1160,24 @@ void SettingsDialog::on_KeybindButton_KeybindingChanged(KeybindButton* button)
|
||||
this->pauseKeyButton,
|
||||
this->generateBitmapKeyButton,
|
||||
this->limitFPSKeyButton,
|
||||
this->swapDiskKeyButton,
|
||||
this->saveStateKeyButton,
|
||||
this->saveAsKeyButton,
|
||||
this->loadStateKeyButton,
|
||||
this->loadKeyButton,
|
||||
this->cheatsKeyButton,
|
||||
this->gsButtonKeyButton,
|
||||
this->fullscreenKeyButton,
|
||||
this->saveState0KeyButton,
|
||||
this->saveState1KeyButton,
|
||||
this->saveState2KeyButton,
|
||||
this->saveState3KeyButton,
|
||||
this->saveState4KeyButton,
|
||||
this->saveState5KeyButton,
|
||||
this->saveState6KeyButton,
|
||||
this->saveState7KeyButton,
|
||||
this->saveState8KeyButton,
|
||||
this->saveState9KeyButton,
|
||||
this->settingsKeyButton,
|
||||
this->fullscreenKeyButton,
|
||||
};
|
||||
|
||||
for (KeybindButton* keybindButton : keybindButtons)
|
||||
|
||||
@@ -37,6 +37,14 @@ class SettingsDialog : public QDialog, private Ui::SettingsDialog
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
enum class SettingsDialogAction
|
||||
{
|
||||
ConnectSignals = 0,
|
||||
LoadSettings,
|
||||
LoadDefaultSettings,
|
||||
SaveSettings
|
||||
};
|
||||
|
||||
bool romOpened = false;
|
||||
|
||||
CoreRomSettings currentGameSettings;
|
||||
@@ -61,6 +69,9 @@ class SettingsDialog : public QDialog, private Ui::SettingsDialog
|
||||
void loadHotkeySettings(void);
|
||||
void loadInterfaceEmulationSettings(void);
|
||||
void loadInterfaceRomBrowserSettings(void);
|
||||
void loadInterfaceLogWindowSettings(void);
|
||||
void loadInterfaceStyleSettings(void);
|
||||
void loadInterfaceMiscSettings(void);
|
||||
|
||||
void loadDefaultCoreSettings(void);
|
||||
void loadDefaultGameSettings(void);
|
||||
@@ -72,6 +83,9 @@ class SettingsDialog : public QDialog, private Ui::SettingsDialog
|
||||
void loadDefaultHotkeySettings(void);
|
||||
void loadDefaultInterfaceEmulationSettings(void);
|
||||
void loadDefaultInterfaceRomBrowserSettings(void);
|
||||
void loadDefaultInterfaceLogWindowSettings(void);
|
||||
void loadDefaultInterfaceStyleSettings(void);
|
||||
void loadDefaultInterfaceMiscSettings(void);
|
||||
|
||||
void saveSettings(void);
|
||||
void saveCoreSettings(void);
|
||||
@@ -84,15 +98,25 @@ class SettingsDialog : public QDialog, private Ui::SettingsDialog
|
||||
void saveHotkeySettings(void);
|
||||
void saveInterfaceEmulationSettings(void);
|
||||
void saveInterfaceRomBrowserSettings(void);
|
||||
void saveInterfaceLogWindowSettings(void);
|
||||
void saveInterfaceStyleSettings(void);
|
||||
void saveInterfaceMiscSettings(void);
|
||||
|
||||
void commonHotkeySettings(int);
|
||||
void commonPluginSettings(int);
|
||||
void commonHotkeySettings(SettingsDialogAction);
|
||||
void commonPluginSettings(SettingsDialogAction);
|
||||
void commonInterfaceStyleSettings(SettingsDialogAction);
|
||||
|
||||
void setIconsForEmulationInfoText(void);
|
||||
void hideEmulationInfoText(void);
|
||||
|
||||
void chooseDirectory(QLineEdit *);
|
||||
void chooseIPLRom(QLineEdit *);
|
||||
|
||||
bool applyPluginSettings(void);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent* event) Q_DECL_OVERRIDE;
|
||||
|
||||
private slots:
|
||||
void on_buttonBox_clicked(QAbstractButton *);
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="newPrefix">
|
||||
<file>Resource/Info.ico</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||