mirror of
https://github.com/Rosalie241/RMG.git
synced 2026-07-11 09:34:00 +02:00
Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bfbbbdda7b | |||
| 67a885b43b | |||
| a49fe03fc2 | |||
| a7b07dc0f9 | |||
| f9a767f8ae | |||
| 42a4786a25 | |||
| b166eac200 | |||
| c06316f4aa | |||
| 09d96d9e4d | |||
| 66703970b6 | |||
| 0d3314a39b | |||
| 748492cc68 | |||
| e18ad31c53 | |||
| 0dd297f0f8 | |||
| 0da4becd46 | |||
| d284911d4a | |||
| e772eb3906 | |||
| 577ee4c3e0 | |||
| c534df8303 | |||
| a36c8f7de8 | |||
| dfb5f1b687 | |||
| d8eea015fd | |||
| f17b7eb2c9 | |||
| 33146626a9 | |||
| 78e12f774d | |||
| 689d8debb1 | |||
| 8be1ed8af5 | |||
| 0fabdb3f3a | |||
| 7a64e7e479 | |||
| 8c1589d7cd | |||
| 5a74b137f2 | |||
| 52ba182610 | |||
| b07eb79609 | |||
| 4e3915f527 | |||
| 9f620f276d | |||
| e3787b5ccf | |||
| 3d81a052c6 | |||
| 6353be1599 | |||
| bc6ee4877b | |||
| 6b38cc3740 | |||
| 9285fb9fdf | |||
| f5c609413a | |||
| a304f11b1d | |||
| e10ac1086f | |||
| 4533ed61ac |
@@ -18,7 +18,7 @@ jobs:
|
||||
sudo add-apt-repository ppa:okirby/qt6-backports --yes
|
||||
sudo apt-get -qq update
|
||||
sudo apt-get upgrade
|
||||
sudo apt-get -y install cmake ninja-build libhidapi-dev libsamplerate0-dev libspeex-dev libminizip-dev libsdl2-dev libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev pkg-config zlib1g-dev binutils-dev libspeexdsp-dev qt6-base-dev libqt6svg6-dev build-essential nasm git zip appstream
|
||||
sudo apt-get -y install cmake ninja-build libusb-1.0-0-dev libhidapi-dev libsamplerate0-dev libspeex-dev libminizip-dev libsdl2-dev libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev pkg-config zlib1g-dev binutils-dev libspeexdsp-dev qt6-base-dev libqt6svg6-dev build-essential nasm git zip appstream
|
||||
- name: Prepare Environment
|
||||
run: |
|
||||
echo "GIT_REVISION=$(git describe --tags --always)" >> $GITHUB_ENV
|
||||
@@ -66,6 +66,7 @@ jobs:
|
||||
mingw-w64-x86_64-SDL2
|
||||
mingw-w64-x86_64-qt6
|
||||
mingw-w64-x86_64-SDL2
|
||||
mingw-w64-x86_64-libusb
|
||||
mingw-w64-x86_64-hidapi
|
||||
mingw-w64-x86_64-speexdsp
|
||||
mingw-w64-x86_64-libsamplerate
|
||||
|
||||
+2
-1
@@ -76,6 +76,7 @@ else()
|
||||
endif()
|
||||
|
||||
add_subdirectory(Source/3rdParty)
|
||||
add_subdirectory(Source/3rdParty/7-Zip)
|
||||
|
||||
add_subdirectory(Source/RMG-Core)
|
||||
add_subdirectory(Source/RMG)
|
||||
@@ -125,7 +126,7 @@ install(FILES ${MUPEN64PLUS_PLUGIN_RSP_PARALLEL}
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_INPUT_RAPHNET}
|
||||
DESTINATION ${PLUGIN_INSTALL_PATH}/Input
|
||||
)
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_INPUT_GCA}
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_INPUT_GCN}
|
||||
DESTINATION ${PLUGIN_INSTALL_PATH}/Input
|
||||
)
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_GFX_ANGRYLION}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
[1FBAF161-2C1C54F1-C:41]
|
||||
Name=1080 Snowboarding (JU) (M2)
|
||||
|
||||
$Enable All Levels & Boarders
|
||||
80255089 00FF
|
||||
8025508B 0005
|
||||
81255096 FCFF
|
||||
80255098 0007
|
||||
|
||||
$Have All\Contest First Place Done
|
||||
80244098 0007
|
||||
|
||||
$Have All\Match Levels Completed
|
||||
8025508A 0005
|
||||
|
||||
$Have All\Trick Attacks Done
|
||||
81255096 FCFF
|
||||
|
||||
$Infinite Damage All Players & Levels
|
||||
803F4C3C 0024
|
||||
807F4C3C 0024
|
||||
|
||||
$Infinite Lives & Continues
|
||||
8026B1CB 0003
|
||||
|
||||
$Always First Place (Player 1)
|
||||
81267B88 2400
|
||||
Note=The game will still show you in 2nd when you are behind. But when you cross the finish line, you will win!
|
||||
|
||||
$Open Level Character Select
|
||||
Note=With these codes, you have to press the buttons listed below when you are viewing a certain boarders stats. Highlight Akari Hayami's stats, and then hold down the C-Left button and then press the A button to be the Crystal Boarder. Highlight Kensuke Kimachi's stats, and then hold down the C-Up button and then press the A button to be the Metal Boarder. Hightlight Rob Haywood's stats, and then hold down the C-Right button and then press the A button to be the Panda Boarder
|
||||
8125508A 00??
|
||||
01 Easy Level
|
||||
02 Easy & Normal Level
|
||||
03 Easy Normal & Hard Levels
|
||||
04 Easy Normal Hard Levels & Crystal Boarder
|
||||
05 Easy Normal Hard Levels & Crystal & Metal Boarders
|
||||
|
||||
$Play As
|
||||
800200E7 00??
|
||||
00 Dion Blaster
|
||||
01 Kensuke Kimachi
|
||||
02 Akari Hayami
|
||||
03 Ricky Winterborn
|
||||
04 Rob Haywood
|
||||
05 Silver Boarder
|
||||
06 Gold Boarder
|
||||
07 Panda Boarder
|
||||
|
||||
$Freeze Timer In\Match Race
|
||||
D1267B20 05E1
|
||||
81267B20 1000
|
||||
|
||||
$Freeze Timer In\Time Attack
|
||||
D12660CC 05E1
|
||||
812660CC 1000
|
||||
|
||||
$Freeze Timer In\Trick Attack
|
||||
D1266138 05E1
|
||||
81266138 1000
|
||||
|
||||
$Freeze Timer In\Contest
|
||||
D126628C 05E1
|
||||
8126628C 1000
|
||||
@@ -0,0 +1,55 @@
|
||||
[58FD3F25-D92EAA8D-C:50]
|
||||
Name=1080 Snowboarding (E) (M4)
|
||||
|
||||
$Enable All Levels & Boarders
|
||||
80250AB9 00FF
|
||||
80250ABB 0005
|
||||
81250AC6 FCFF
|
||||
80250AC8 0007
|
||||
|
||||
$Infinite Damage All Players and Levels
|
||||
803F4C00 0024
|
||||
807F4C00 0024
|
||||
|
||||
$Infinite Lives & Continues
|
||||
802648A4 0003
|
||||
|
||||
$Open Level Character Select
|
||||
Note=With these codes, you have to press the buttons listed below when you are viewing a certain boarders stats. Highlight Akari Hayami's stats, and then hold down the C-Left button and then press the A button to be the Crystal Boarder. Highlight Kensuke Kimachi's stats, and then hold down the C-Up button and then press the A button to be the Metal Boarder. Hightlight Rob Haywood's stats, and then hold down the C-Right button and then press the A button to be the Panda Boarder
|
||||
8125508A 00??
|
||||
01 Easy Level
|
||||
02 Easy & Normal Level
|
||||
03 Easy Normal & Hard Levels
|
||||
04 Easy Normal Hard Levels & Crystal Boarder
|
||||
05 Easy Normal Hard Levels & Crystal & Metal Boarders
|
||||
|
||||
$Play As
|
||||
8001A0E7 00??
|
||||
00 Dion Blaster
|
||||
01 Kensuke Kimachi
|
||||
02 Akari Hayami
|
||||
03 Ricky Winterborn
|
||||
04 Rob Haywood
|
||||
05 Silver Boarder
|
||||
06 Gold Boarder
|
||||
07 Panda Boarder
|
||||
|
||||
$Always First Place (Player 1)
|
||||
812679BC 2400
|
||||
Note=The game will still show you in 2nd when you are behind. But when you cross the finish line, you will win!
|
||||
|
||||
$Freeze Timer In\Match Race
|
||||
D1267954 05E1
|
||||
81267954 1000
|
||||
|
||||
$Freeze Timer In\Time Attack
|
||||
D1265D4C 05E1
|
||||
81265D4C 1000
|
||||
|
||||
$Freeze Timer In\Trick Attack
|
||||
D1265DB8 05E1
|
||||
81265DB8 1000
|
||||
|
||||
$Freeze Timer In\Contest
|
||||
D1265F48 05E1
|
||||
81265F48 1000
|
||||
@@ -1,14 +1,14 @@
|
||||
# Maintainer: Rosalie Wanders <rosalie@mailbox.org>
|
||||
pkgname=rmg
|
||||
pkgver=0.3.8
|
||||
pkgver=0.3.9
|
||||
pkgrel=1
|
||||
pkgdesc="Rosalie's Mupen GUI"
|
||||
arch=('x86_64')
|
||||
url="https://github.com/Rosalie241/$pkgname"
|
||||
license=('GPL3')
|
||||
|
||||
depends=("hidapi" "libsamplerate" "minizip" "sdl2" "zlib" "freetype2" "qt6-base" "qt6-svg" "xdg-user-dirs")
|
||||
makedepends=("git" "nasm" "cmake" "cargo" "ninja")
|
||||
depends=("hidapi" "libsamplerate" "speexdsp" "minizip" "sdl2" "zlib" "freetype2" "qt6-base" "qt6-svg" "xdg-user-dirs")
|
||||
makedepends=("git" "nasm" "cmake" "ninja")
|
||||
|
||||
source=("git+https://github.com/Rosalie241/$pkgname.git#tag=v$pkgver")
|
||||
sha256sums=('SKIP')
|
||||
@@ -24,6 +24,7 @@ build()
|
||||
-DCMAKE_BUILD_TYPE="Release" \
|
||||
-DPORTABLE_INSTALL="OFF" \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DNO_RUST="ON" \
|
||||
-G "Ninja"
|
||||
|
||||
cmake --build "$srcdir/$pkgname/build"
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 318 KiB After Width: | Height: | Size: 302 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 121 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 85 KiB |
@@ -1,4 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<!-- Copyright 2022 Rosalie Wanders -->
|
||||
<component type="desktop">
|
||||
<!--Created with jdAppdataEdit 2.1-->
|
||||
<id>com.github.Rosalie241.RMG</id>
|
||||
@@ -11,27 +12,55 @@
|
||||
<description><p>Rosalie's Mupen GUI is an easy to use yet customizable mupen64plus front-end, allowing you to easily play N64 games.</p></description>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<caption>The Rom Browser</caption>
|
||||
<caption>01 - The Rom Browser</caption>
|
||||
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/RomBrowser.png</image>
|
||||
</screenshot>
|
||||
<screenshot type="default">
|
||||
<caption>During A Game</caption>
|
||||
<caption>02 - During A Game</caption>
|
||||
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/InGame.png</image>
|
||||
</screenshot>
|
||||
<screenshot type="default">
|
||||
<caption>Cheats</caption>
|
||||
<caption>03 - Cheats</caption>
|
||||
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/Cheats.png</image>
|
||||
</screenshot>
|
||||
<screenshot type="default">
|
||||
<caption>Settings</caption>
|
||||
<caption>04 - Settings</caption>
|
||||
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/Settings.png</image>
|
||||
</screenshot>
|
||||
<screenshot type="default">
|
||||
<caption>Input Settings</caption>
|
||||
<caption>05 - Input Settings</caption>
|
||||
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/InputSettings.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<releases>
|
||||
<release version="v0.4.0" date="2023-05-04" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix updater on windows always installing the desktop icon</li>
|
||||
<li>Fix updater on windows not re-launching RMG after installation</li>
|
||||
<li>Fix the speed limiter toggle and speed factor options not working on linux on some systems</li>
|
||||
<li>Fix the 1080 Snowboarding cheats (thank you Gent)</li>
|
||||
<li>Add support for moving the toolbar (changes to the docked position are persistent across application runs)</li>
|
||||
<li>Update GLideN64 and mupen64plus-input-gca</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.3.9" date="2023-04-06" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix "Don't check for updates again" checkbox appearing when requesting an update check through Help -> Check For Updates</li>
|
||||
<li>Add game format, file name, file extension, file size, game I.D. and game region columns to the list view of the ROM browser which can be toggled in the "Show/Hide Columns" menu of the context menu in the list view of the ROM browser (thank you RetraCarteR)</li>
|
||||
<li>Add "Reset Column Sizes" to context menu of the list view of the ROM browser (thank you RetraCarteR)</li>
|
||||
<li>Add "Analog Stick Sensitivity" setting to RMG-Input (thank you JaxonWasTaken)</li>
|
||||
<li>Add "Save Filename Format" setting to the Core tab of the settings dialog</li>
|
||||
<li>Add "Edit Game Input Settings" to the context menu of the ROM browser</li>
|
||||
<li>Add support for 7z files</li>
|
||||
<li>Add progress status to the loading screen in the ROM browser when loading takes more than 5 seconds</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.3.8" date="2023-02-24" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
|
||||
@@ -17,7 +17,9 @@ You can download Rosalie's Mupen GUI on
|
||||
|
||||
## Support
|
||||
|
||||
Join the [Rosalie's Mupen GUI Discord Server](https://discord.gg/k9GuyJ2PpF) for support
|
||||
You can ask for help or report issues on
|
||||
* [Github](https://github.com/Rosalie241/RMG/issues/new)
|
||||
* [Discord](https://discord.gg/k9GuyJ2PpF)
|
||||
|
||||
## License
|
||||
|
||||
|
||||
Vendored
+40
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# 7-Zip CMakeLists.txt
|
||||
#
|
||||
project(7Zip)
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
set(7ZIP_SOURCES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/Bcj2.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/Bra.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/Bra86.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/BraIA64.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/CpuArch.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/Delta.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/Lzma2Dec.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/LzmaDec.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/Ppmd7.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/Ppmd7Dec.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/7zCrc.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/7zCrcOpt.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/Sha256.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/Sha256Opt.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/7zAlloc.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/7zArcIn.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/7zBuf.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/7zBuf2.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/7zDec.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/7zFile.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/C/7zStream.c
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${7ZIP_SOURCES}
|
||||
COMMAND ${CMAKE_COMMAND} -E tar "xvz" "${CMAKE_CURRENT_SOURCE_DIR}/lzma2201.tar.gz"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
add_definitions(-D_7ZIP_PPMD_SUPPPORT -DNDEBUG -D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE)
|
||||
|
||||
add_library(7Zip STATIC ${7ZIP_SOURCES})
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
# 7-Zip SDK v22.01
|
||||
Downloaded from https://www.7-zip.org/sdk.html
|
||||
BIN
Binary file not shown.
Vendored
+20
-35
@@ -5,22 +5,12 @@ include(ExternalProject)
|
||||
|
||||
set(THIRDPARTY_DIR ${CMAKE_BINARY_DIR}/Source/3rdParty)
|
||||
|
||||
find_program(RUST_CARGO cargo)
|
||||
if(${RUST_CARGO} STREQUAL "RUST_CARGO-NOTFOUND")
|
||||
message(WARNING "mupen64plus-input-gca will not be built due to not having cargo installed")
|
||||
set(BUILD_INPUT_GCA OFF)
|
||||
else()
|
||||
set(BUILD_INPUT_GCA ON)
|
||||
endif()
|
||||
|
||||
set(M64P_CORE_DIR ${THIRDPARTY_DIR}/mupen64plus-core)
|
||||
if(WIN32)
|
||||
set(SO_EXT "dll")
|
||||
set(GCA_LIB "mupen64plus_input_gca.${SO_EXT}")
|
||||
set(CORE_FILE "mupen64plus.dll")
|
||||
else(WIN32)
|
||||
set(SO_EXT "so")
|
||||
set(GCA_LIB "libmupen64plus_input_gca.${SO_EXT}")
|
||||
set(CORE_FILE "libmupen64plus.so")
|
||||
endif(WIN32)
|
||||
|
||||
@@ -37,7 +27,7 @@ endif(USE_CCACHE)
|
||||
|
||||
if(NOT NO_GIT_CLONE)
|
||||
set(MUPEN64PLUSCORE_URL "https://github.com/mupen64plus/mupen64plus-core")
|
||||
set(MUPEN64PLUSCORE_TAG "7ee312cb282a7794c62d5d284bf93151c585dd1f")
|
||||
set(MUPEN64PLUSCORE_TAG "d4f3e12db0609158c7b4e0beef2bb950aad0ccb9")
|
||||
|
||||
set(MUPEN64PLUS_RSP_CXD4_URL "https://github.com/mupen64plus/mupen64plus-rsp-cxd4")
|
||||
set(MUPEN64PLUS_RSP_CXD4_TAG "39f79201baa15890c4cbae92f2215a634cc3ee6d")
|
||||
@@ -46,19 +36,19 @@ if(NOT NO_GIT_CLONE)
|
||||
set(MUPEN64PLUS_RSP_HLE_TAG "88093cb43499eff53d343653cddcae2132af17ef")
|
||||
|
||||
set(MUPEN64PLUS_RSP_PARALLEL_URL "https://github.com/Rosalie241/parallel-rsp")
|
||||
set(MUPEN64PLUS_RSP_PARALLEL_TAG "cfeea3a0f89ba5bc4265acb75778e1267ed1e424")
|
||||
set(MUPEN64PLUS_RSP_PARALLEL_TAG "dbecbe3a120e428436c5972fa7b872cfc2c9db3e")
|
||||
|
||||
set(MUPEN64PLUS_INPUT_RAPHNET_URL "https://github.com/raphnet/mupen64plus-input-raphnetraw")
|
||||
set(MUPEN64PLUS_INPUT_RAPHNET_TAG "86112413e98a8648edb11d199673cc24d5799af8")
|
||||
|
||||
set(MUPEN64PLUS_INPUT_GCA_URL "https://github.com/amatho/mupen64plus-input-gca")
|
||||
set(MUPEN64PLUS_INPUT_GCA_TAG "21639fb13dfa797a7c0949ffd9bbda9a3456fc69")
|
||||
set(MUPEN64PLUS_INPUT_GCN_URL "https://github.com/Rosalie241/mupen64plus-input-gcn")
|
||||
set(MUPEN64PLUS_INPUT_GCN_TAG "e220115fa8ad223be783c822a251d7e0f873ed4c")
|
||||
|
||||
set(MUPEN64PLUS_GFX_ANGRYLION_URL "https://github.com/Rosalie241/angrylion-rdp-plus")
|
||||
set(MUPEN64PLUS_GFX_ANGRYLION_TAG "158e74d4ec1c818289cd19c3a05e498c3ceff758")
|
||||
set(MUPEN64PLUS_GFX_ANGRYLION_TAG "670abbc972bd430fa77291b0967dd73128314317")
|
||||
|
||||
set(MUPEN64PLUS_GFX_GLIDEN64_URL "https://github.com/Rosalie241/GLideN64")
|
||||
set(MUPEN64PLUS_GFX_GLIDEN64_TAG "937e2a082c63b917654ff59cfc0b5125ad525dce")
|
||||
set(MUPEN64PLUS_GFX_GLIDEN64_URL "https://github.com/gonetz/GLideN64")
|
||||
set(MUPEN64PLUS_GFX_GLIDEN64_TAG "0fee30d010d1feda7d343654871b3dfd05ccab70")
|
||||
|
||||
set(MUPEN64PLUS_GFX_PARALLEL_URL "https://github.com/Rosalie241/parallel-rdp-standalone")
|
||||
set(MUPEN64PLUS_GFX_PARALLEL_TAG "2c2226517c4c8929e08ec944654867e26efe0cf5")
|
||||
@@ -70,7 +60,7 @@ if(NOT NO_GIT_CLONE)
|
||||
set(IMGUI_TAG "d7c8516a4b848c0291e3d75b627c0843f515f591")
|
||||
|
||||
set(SDL_GAMECONTROLLERDB_URL "https://github.com/gabomdq/SDL_GameControllerDB")
|
||||
set(SDL_GAMECONTROLLERDB_TAG "0562b00eaf5c0308c49d329b79263d2dae1c3a85")
|
||||
set(SDL_GAMECONTROLLERDB_TAG "b7e5701da82fc97beeede64d3818ef0f4d015aba")
|
||||
endif(NOT NO_GIT_CLONE)
|
||||
|
||||
ExternalProject_Add(mupen64plus-core
|
||||
@@ -161,23 +151,20 @@ ExternalProject_Add(mupen64plus-input-raphnetraw
|
||||
DEPENDS mupen64plus-core
|
||||
)
|
||||
|
||||
if (BUILD_INPUT_GCA)
|
||||
ExternalProject_Add(mupen64plus-input-gca
|
||||
SOURCE_DIR mupen64plus-input-gca/
|
||||
ExternalProject_Add(mupen64plus-input-gcn
|
||||
SOURCE_DIR mupen64plus-input-gcn
|
||||
|
||||
CONFIGURE_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_INPUT_GCN_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_INPUT_GCN_TAG}
|
||||
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_INPUT_GCA_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_INPUT_GCA_TAG}
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
BUILD_COMMAND cargo build --release --features "m64p_compat"
|
||||
BUILD_IN_SOURCE True
|
||||
BUILD_IN_SOURCE True
|
||||
CMAKE_ARGS ${CMAKE_CONFIGURE_ARGS}
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-input-gca/target/release/${GCA_LIB}
|
||||
DEPENDS mupen64plus-core
|
||||
)
|
||||
endif(BUILD_INPUT_GCA)
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-input-gcn/mupen64plus-input-gcn.${SO_EXT}
|
||||
DEPENDS mupen64plus-core
|
||||
)
|
||||
|
||||
set(GLIDEN64_DIR "${THIRDPARTY_DIR}/mupen64plus-video-GLideN64")
|
||||
set(GLIDEN64_BUILD_DIR "${GLIDEN64_DIR}/projects/cmake")
|
||||
@@ -326,10 +313,8 @@ set(MUPEN64PLUS_PLUGIN_RSP_PARALLEL ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
ExternalProject_Get_property(mupen64plus-input-raphnetraw BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_INPUT_RAPHNET ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
|
||||
if (BUILD_INPUT_GCA)
|
||||
ExternalProject_Get_property(mupen64plus-input-gca BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_INPUT_GCA ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
endif(BUILD_INPUT_GCA)
|
||||
ExternalProject_Get_property(mupen64plus-input-gcn BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_INPUT_GCN ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
|
||||
ExternalProject_Get_property(mupen64plus-video-angrylion-plus BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_GFX_ANGRYLION ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
|
||||
@@ -55,5 +55,5 @@ Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
||||
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
|
||||
|
||||
[Run]
|
||||
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
|
||||
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ endif(WIN32)
|
||||
|
||||
target_link_libraries(RMG-Core
|
||||
${MINIZIP_LIBRARIES}
|
||||
7Zip
|
||||
)
|
||||
|
||||
if (DISCORD_RPC)
|
||||
|
||||
@@ -36,11 +36,13 @@
|
||||
#define ROMHEADER_NAME_LEN 256
|
||||
#define GOODNAME_LEN 256
|
||||
#define MD5_LEN 33
|
||||
#define GAMEID_LEN 5
|
||||
#define REGION_LEN 18
|
||||
|
||||
#ifdef _WIN32
|
||||
#define CACHE_FILE_MAGIC "RMGCoreHeaderAndSettingsCacheWindows_05"
|
||||
#define CACHE_FILE_MAGIC "RMGCoreHeaderAndSettingsCacheWindows_06"
|
||||
#else // Linux
|
||||
#define CACHE_FILE_MAGIC "RMGCoreHeaderAndSettingsCacheLinux_05"
|
||||
#define CACHE_FILE_MAGIC "RMGCoreHeaderAndSettingsCacheLinux_06"
|
||||
#endif // _WIN32
|
||||
#define CACHE_FILE_ITEMS_MAX 10000
|
||||
|
||||
@@ -103,6 +105,8 @@ void CoreReadRomHeaderAndSettingsCache(void)
|
||||
char magicBuf[sizeof(CACHE_FILE_MAGIC)];
|
||||
wchar_t fileNameBuf[MAX_FILENAME_LEN];
|
||||
char headerNameBuf[ROMHEADER_NAME_LEN];
|
||||
char gameIDBuf[GAMEID_LEN];
|
||||
char regionBuf[REGION_LEN];
|
||||
char goodNameBuf[GOODNAME_LEN];
|
||||
char md5Buf[MD5_LEN];
|
||||
uint32_t size;
|
||||
@@ -131,6 +135,8 @@ void CoreReadRomHeaderAndSettingsCache(void)
|
||||
size = 0;
|
||||
memset(fileNameBuf, 0, sizeof(fileNameBuf));
|
||||
memset(headerNameBuf, 0, sizeof(headerNameBuf));
|
||||
memset(gameIDBuf, 0, sizeof(gameIDBuf));
|
||||
memset(regionBuf, 0, sizeof(regionBuf));
|
||||
memset(goodNameBuf, 0, sizeof(goodNameBuf));
|
||||
memset(md5Buf, 0, sizeof(md5Buf));
|
||||
|
||||
@@ -144,7 +150,13 @@ void CoreReadRomHeaderAndSettingsCache(void)
|
||||
// header
|
||||
FREAD(size);
|
||||
FREAD_STR(headerNameBuf, size);
|
||||
FREAD(size);
|
||||
FREAD_STR(gameIDBuf, size);
|
||||
FREAD(size);
|
||||
FREAD_STR(regionBuf, size);
|
||||
cacheEntry.header.Name = std::string(headerNameBuf);
|
||||
cacheEntry.header.GameID = std::string(gameIDBuf);
|
||||
cacheEntry.header.Region = std::string(regionBuf);
|
||||
FREAD(cacheEntry.header.CRC1);
|
||||
FREAD(cacheEntry.header.CRC2);
|
||||
// (partial) settings
|
||||
@@ -169,6 +181,8 @@ bool CoreSaveRomHeaderAndSettingsCache(void)
|
||||
std::ofstream outputStream;
|
||||
wchar_t fileNameBuf[MAX_FILENAME_LEN];
|
||||
char headerNameBuf[ROMHEADER_NAME_LEN];
|
||||
char gameIDBuf[GAMEID_LEN];
|
||||
char regionBuf[REGION_LEN];
|
||||
char goodNameBuf[GOODNAME_LEN];
|
||||
char md5Buf[MD5_LEN];
|
||||
uint32_t size;
|
||||
@@ -200,12 +214,16 @@ bool CoreSaveRomHeaderAndSettingsCache(void)
|
||||
size = 0;
|
||||
memset(fileNameBuf, 0, sizeof(fileNameBuf));
|
||||
memset(headerNameBuf, 0, sizeof(headerNameBuf));
|
||||
memset(gameIDBuf, 0, sizeof(gameIDBuf));
|
||||
memset(regionBuf, 0, sizeof(regionBuf));
|
||||
memset(goodNameBuf, 0, sizeof(goodNameBuf));
|
||||
memset(md5Buf, 0, sizeof(md5Buf));
|
||||
|
||||
// copy strings into buffers
|
||||
wcsncpy(fileNameBuf, cacheEntry.fileName.wstring().c_str(), MAX_FILENAME_LEN);
|
||||
strncpy(headerNameBuf, cacheEntry.header.Name.c_str(), sizeof(headerNameBuf));
|
||||
strncpy(gameIDBuf, cacheEntry.header.GameID.c_str(), sizeof(gameIDBuf));
|
||||
strncpy(regionBuf, cacheEntry.header.Region.c_str(), sizeof(regionBuf));
|
||||
strncpy(goodNameBuf, cacheEntry.settings.GoodName.c_str(), sizeof(goodNameBuf));
|
||||
strncpy(md5Buf, cacheEntry.settings.MD5.c_str(), sizeof(md5Buf));
|
||||
|
||||
@@ -220,6 +238,12 @@ bool CoreSaveRomHeaderAndSettingsCache(void)
|
||||
size = cacheEntry.header.Name.size();
|
||||
FWRITE(size);
|
||||
FWRITE_STR(headerNameBuf, size);
|
||||
size = cacheEntry.header.GameID.size();
|
||||
FWRITE(size);
|
||||
FWRITE_STR(gameIDBuf, size);
|
||||
size = cacheEntry.header.Region.size();
|
||||
FWRITE(size);
|
||||
FWRITE_STR(regionBuf, size);
|
||||
FWRITE(cacheEntry.header.CRC1);
|
||||
FWRITE(cacheEntry.header.CRC2);
|
||||
// (partial) settings
|
||||
|
||||
@@ -54,6 +54,7 @@ static void apply_coresettings_overlay(void)
|
||||
CoreSettingsSetValue(SettingsID::Core_CountPerOp, CoreSettingsGetIntValue(SettingsID::CoreOverlay_CountPerOp));
|
||||
CoreSettingsSetValue(SettingsID::Core_CountPerOpDenomPot, CoreSettingsGetIntValue(SettingsID::CoreOverlay_CountPerOpDenomPot));
|
||||
CoreSettingsSetValue(SettingsID::Core_SiDmaDuration, CoreSettingsGetIntValue(SettingsID::CoreOverlay_SiDmaDuration));
|
||||
CoreSettingsSetValue(SettingsID::Core_SaveFileNameFormat, CoreSettingsGetIntValue(SettingsID::CoreOverLay_SaveFileNameFormat));
|
||||
}
|
||||
|
||||
static void apply_game_coresettings_overlay(void)
|
||||
|
||||
+91
-38
@@ -285,6 +285,78 @@ bool apply_plugin_settings(std::string pluginSettings[4])
|
||||
return true;
|
||||
}
|
||||
|
||||
bool open_plugin_config(CorePluginType type, bool romConfig)
|
||||
{
|
||||
std::string error;
|
||||
m64p_error ret;
|
||||
bool resumeEmulation = false;
|
||||
m64p::PluginApi* plugin;
|
||||
std::string functionName;
|
||||
|
||||
if (!romConfig && !CorePluginsHasConfig(type))
|
||||
{
|
||||
error = "open_plugin_config Failed: ";
|
||||
error += get_plugin_type_name(type);
|
||||
error += " doesn't have the config or config2 function!";
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
else if (romConfig && !CorePluginsHasROMConfig(type))
|
||||
{
|
||||
error = "open_plugin_config Failed: ";
|
||||
error += get_plugin_type_name(type);
|
||||
error += " doesn't support ROM specific configuration!";
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// try to pause emulation,
|
||||
// when emulation is running
|
||||
// and try to resume afterwards
|
||||
if (CoreIsEmulationRunning())
|
||||
{
|
||||
// only resume emulation
|
||||
// after running the config function
|
||||
// when pausing succeeds
|
||||
resumeEmulation = CorePauseEmulation();
|
||||
}
|
||||
|
||||
plugin = get_plugin(type);
|
||||
|
||||
// check if the plugin has the Config2
|
||||
// or Config function, the Config2 function
|
||||
// has priority
|
||||
if (plugin->Config2 != nullptr)
|
||||
{
|
||||
ret = plugin->Config2(romConfig ? 1 : 0);
|
||||
functionName = "Config2";
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = plugin->Config();
|
||||
functionName = "Config";
|
||||
}
|
||||
|
||||
if (ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "CorePluginsOpenConfig (";
|
||||
error += get_plugin_type_name(type);
|
||||
error += ")->";
|
||||
error += functionName;
|
||||
error += "() Failed: ";
|
||||
error += m64p::Core.ErrorMessage(ret);
|
||||
CoreSetError(error);
|
||||
}
|
||||
|
||||
// try to resume emulation when needed
|
||||
if (resumeEmulation)
|
||||
{
|
||||
CoreResumeEmulation();
|
||||
}
|
||||
|
||||
return ret == M64ERR_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Exported Functions
|
||||
//
|
||||
@@ -384,52 +456,33 @@ bool CoreArePluginsReady(void)
|
||||
|
||||
bool CorePluginsHasConfig(CorePluginType type)
|
||||
{
|
||||
return get_plugin(type)->Config != nullptr;
|
||||
m64p::PluginApi* plugin;
|
||||
|
||||
plugin = get_plugin(type);
|
||||
|
||||
return plugin->Config != nullptr ||
|
||||
plugin->Config2 != nullptr;
|
||||
}
|
||||
|
||||
bool CorePluginsOpenConfig(CorePluginType type)
|
||||
{
|
||||
std::string error;
|
||||
m64p_error ret;
|
||||
bool resumeEmulation = false;
|
||||
return open_plugin_config(type, false);
|
||||
}
|
||||
|
||||
if (!CorePluginsHasConfig(type))
|
||||
{
|
||||
error = "CorePluginsOpenConfig Failed: ";
|
||||
error += get_plugin_type_name(type);
|
||||
error += " doesn't have config function!";
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
bool CorePluginsHasROMConfig(CorePluginType type)
|
||||
{
|
||||
m64p::PluginApi* plugin;
|
||||
|
||||
// try to pause emulation,
|
||||
// when emulation is running
|
||||
// and try to resume afterwards
|
||||
if (CoreIsEmulationRunning())
|
||||
{
|
||||
// only resume emulation
|
||||
// after running the config function
|
||||
// when pausing succeeds
|
||||
resumeEmulation = CorePauseEmulation();
|
||||
}
|
||||
plugin = get_plugin(type);
|
||||
|
||||
ret = get_plugin(type)->Config();
|
||||
if (ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "CorePluginsOpenConfig (";
|
||||
error += get_plugin_type_name(type);
|
||||
error += ")->Config() Failed: ";
|
||||
error += m64p::Core.ErrorMessage(ret);
|
||||
CoreSetError(error);
|
||||
}
|
||||
return plugin->Config2 != nullptr &&
|
||||
plugin->Config2HasRomConfig != nullptr &&
|
||||
plugin->Config2HasRomConfig() > 0;
|
||||
}
|
||||
|
||||
// try to resume emulation when needed
|
||||
if (resumeEmulation)
|
||||
{
|
||||
CoreResumeEmulation();
|
||||
}
|
||||
|
||||
return ret == M64ERR_SUCCESS;
|
||||
bool CorePluginsOpenROMConfig(CorePluginType type)
|
||||
{
|
||||
return open_plugin_config(type, true);
|
||||
}
|
||||
|
||||
bool CoreAttachPlugins(void)
|
||||
|
||||
@@ -52,6 +52,14 @@ bool CorePluginsHasConfig(CorePluginType type);
|
||||
// used plugin of given type
|
||||
bool CorePluginsOpenConfig(CorePluginType type);
|
||||
|
||||
// returns wether the currently used plugin
|
||||
// of the given type has a ROM config GUI
|
||||
bool CorePluginsHasROMConfig(CorePluginType type);
|
||||
|
||||
// opens the ROM config GUI for the currently
|
||||
// used plugin of given type
|
||||
bool CorePluginsOpenROMConfig(CorePluginType type);
|
||||
|
||||
// attaches all used plugins
|
||||
bool CoreAttachPlugins(void);
|
||||
|
||||
|
||||
+174
-5
@@ -16,6 +16,16 @@
|
||||
#include "Cheats.hpp"
|
||||
#include "osal/osal_files.hpp"
|
||||
|
||||
// 7-Zip includes
|
||||
#include "../3rdParty/7-Zip/C/7zTypes.h"
|
||||
#include "../3rdParty/7-Zip/C/7z.h"
|
||||
#include "../3rdParty/7-Zip/C/7zAlloc.h"
|
||||
#include "../3rdParty/7-Zip/C/7zBuf.h"
|
||||
#include "../3rdParty/7-Zip/C/7zCrc.h"
|
||||
#include "../3rdParty/7-Zip/C/7zFile.h"
|
||||
#include "../3rdParty/7-Zip/C/7zVersion.h"
|
||||
|
||||
#include <string>
|
||||
#include <unzip.h>
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
@@ -140,7 +150,7 @@ static bool read_zip_file(std::filesystem::path file, std::filesystem::path* ext
|
||||
filefuncs.zclose_file = zlib_filefunc_close;
|
||||
filefuncs.zerror_file = zlib_filefunc_testerror;
|
||||
filefuncs.opaque = nullptr;
|
||||
|
||||
|
||||
zipFile = unzOpen2_64((const void*)&file, &filefuncs);
|
||||
if (zipFile == nullptr)
|
||||
{
|
||||
@@ -293,6 +303,155 @@ static bool read_zip_file(std::filesystem::path file, std::filesystem::path* ext
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool read_7zip_file(std::filesystem::path file, std::filesystem::path* extractedFileName, bool* isDisk, char** buf, int* size)
|
||||
{
|
||||
std::string error;
|
||||
|
||||
const ISzAlloc alloc = { SzAlloc, SzFree };
|
||||
const size_t bufSize = ((size_t)1 << 18);
|
||||
|
||||
ISzAlloc allocImp;
|
||||
ISzAlloc allocTempImp;
|
||||
|
||||
CFileInStream archiveStream;
|
||||
CLookToRead2 lookStream;
|
||||
CSzArEx db;
|
||||
SRes res;
|
||||
|
||||
// initialize allocator
|
||||
allocImp = alloc;
|
||||
allocTempImp = alloc;
|
||||
|
||||
// try to open file
|
||||
#ifdef _WIN32
|
||||
WRes wres = InFile_OpenW(&archiveStream.file, file.wstring().c_str());
|
||||
#else
|
||||
WRes wres = InFile_Open(&archiveStream.file, file.string().c_str());
|
||||
#endif // _WIN32
|
||||
if (wres != 0)
|
||||
{
|
||||
error = "read_7zip_file Failed: InFile_Open Failed: ";
|
||||
error += std::to_string(wres);
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// create vtables for streams
|
||||
FileInStream_CreateVTable(&archiveStream);
|
||||
archiveStream.wres = 0;
|
||||
LookToRead2_CreateVTable(&lookStream, 0);
|
||||
lookStream.buf = nullptr;
|
||||
|
||||
// allocate memory look reader
|
||||
lookStream.buf = (Byte*)ISzAlloc_Alloc(&allocImp, bufSize);
|
||||
if (lookStream.buf == nullptr)
|
||||
{
|
||||
error = "read_7zip_file Failed: ISzAlloc_Alloc Failed!";
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// initialize look reader
|
||||
lookStream.bufSize = bufSize;
|
||||
lookStream.realStream = &archiveStream.vt;
|
||||
LookToRead2_Init(&lookStream);
|
||||
|
||||
// initialize CRC table
|
||||
CrcGenerateTable();
|
||||
|
||||
// initialize archive
|
||||
SzArEx_Init(&db);
|
||||
|
||||
// try to open file
|
||||
res = SzArEx_Open(&db, &lookStream.vt, &allocImp, &allocTempImp);
|
||||
if (res != SZ_OK)
|
||||
{
|
||||
error = "read_7zip_file Failed: SzArEx_Open Failed: ";
|
||||
error += std::to_string(res);
|
||||
CoreSetError(error);
|
||||
SzArEx_Free(&db, &allocImp);
|
||||
ISzAlloc_Free(&allocImp, lookStream.buf);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < db.NumFiles; i++)
|
||||
{
|
||||
size_t filename_size = 0;
|
||||
uint16_t fileName[PATH_MAX];
|
||||
|
||||
// skip directories
|
||||
if (SzArEx_IsDir(&db, i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip when filename size exceeds our buffer size
|
||||
filename_size = SzArEx_GetFileNameUtf16(&db, i, nullptr);
|
||||
if (filename_size > PATH_MAX)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
SzArEx_GetFileNameUtf16(&db, i, fileName);
|
||||
|
||||
std::filesystem::path fileNamePath((char16_t*)fileName);
|
||||
std::string fileExtension = fileNamePath.has_extension() ? fileNamePath.extension().string() : "";
|
||||
fileExtension = to_lower_str(fileExtension);
|
||||
if (fileExtension == ".z64" ||
|
||||
fileExtension == ".v64" ||
|
||||
fileExtension == ".n64" ||
|
||||
fileExtension == ".ndd" ||
|
||||
fileExtension == ".d64")
|
||||
{
|
||||
uint32_t blockIndex = 0xFFFFFFFF;
|
||||
uint8_t* outBuffer = nullptr;
|
||||
size_t outBufferSize = 0;
|
||||
size_t offset = 0;
|
||||
size_t outSizeProcessed = 0;
|
||||
|
||||
res = SzArEx_Extract(&db, &lookStream.vt, i,
|
||||
&blockIndex, &outBuffer, &outBufferSize,
|
||||
&offset, &outSizeProcessed,
|
||||
&allocImp, &allocTempImp);
|
||||
if (res != SZ_OK)
|
||||
{
|
||||
error = "read_7zip_file Failed: SzArEx_Extract Failed: ";
|
||||
error += std::to_string(res);
|
||||
CoreSetError(error);
|
||||
|
||||
SzArEx_Free(&db, &allocImp);
|
||||
ISzAlloc_Free(&allocImp, lookStream.buf);
|
||||
File_Close(&archiveStream.file);
|
||||
ISzAlloc_Free(&allocImp, outBuffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
*size = outSizeProcessed;
|
||||
// we have to memcpy it into buf, otherwise
|
||||
// the free() in CoreOpenRom() crashes
|
||||
*buf = (char*)malloc(outSizeProcessed);
|
||||
memcpy(*buf, (outBuffer + offset), outSizeProcessed);
|
||||
*extractedFileName = fileNamePath;
|
||||
*isDisk = (fileExtension == ".ndd" || fileExtension == ".d64");
|
||||
|
||||
SzArEx_Free(&db, &allocImp);
|
||||
ISzAlloc_Free(&allocImp, lookStream.buf);
|
||||
File_Close(&archiveStream.file);
|
||||
ISzAlloc_Free(&allocImp, outBuffer);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup
|
||||
SzArEx_Free(&db, &allocImp);
|
||||
ISzAlloc_Free(&allocImp, lookStream.buf);
|
||||
File_Close(&archiveStream.file);
|
||||
|
||||
error = "read_7zip_file Failed: no valid ROMs found in 7zip!";
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool read_raw_file(std::filesystem::path file, char** buf, int* size)
|
||||
{
|
||||
std::string error;
|
||||
@@ -362,7 +521,6 @@ static bool write_file(std::filesystem::path file, char* buf, int size)
|
||||
|
||||
// write buffer to file
|
||||
fileStream.write(buf, size);
|
||||
|
||||
fileStream.close();
|
||||
return true;
|
||||
}
|
||||
@@ -395,14 +553,25 @@ bool CoreOpenRom(std::filesystem::path file)
|
||||
file_extension = file.has_extension() ? file.extension().string() : "";
|
||||
file_extension = to_lower_str(file_extension);
|
||||
|
||||
if (file_extension == ".zip")
|
||||
if (file_extension == ".zip" ||
|
||||
file_extension == ".7z")
|
||||
{
|
||||
std::filesystem::path extracted_file;
|
||||
bool is_disk = false;
|
||||
|
||||
if (!read_zip_file(file, &extracted_file, &is_disk, &buf, &buf_size))
|
||||
if (file_extension == ".zip")
|
||||
{
|
||||
return false;
|
||||
if (!read_zip_file(file, &extracted_file, &is_disk, &buf, &buf_size))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!read_7zip_file(file, &extracted_file, &is_disk, &buf, &buf_size))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_disk)
|
||||
|
||||
@@ -21,6 +21,97 @@
|
||||
#include "Error.hpp"
|
||||
#include "Rom.hpp"
|
||||
|
||||
//
|
||||
// Local Functions
|
||||
//
|
||||
|
||||
static std::string get_gameid_from_header(m64p_rom_header header)
|
||||
{
|
||||
std::string gameID;
|
||||
|
||||
if (header.Manufacturer_ID == 0)
|
||||
{
|
||||
return "????";
|
||||
}
|
||||
|
||||
gameID.push_back(char(ntohl(header.Manufacturer_ID)));
|
||||
gameID.push_back(char(header.Cartridge_ID % 256));
|
||||
gameID.push_back(char(header.Cartridge_ID / 256));
|
||||
gameID.push_back(char(header.Country_code));
|
||||
|
||||
return gameID;
|
||||
}
|
||||
|
||||
static std::string get_region_from_countrycode(char countryCode)
|
||||
{
|
||||
std::string region;
|
||||
|
||||
switch (countryCode)
|
||||
{
|
||||
case 'A':
|
||||
region = "Region-Free";
|
||||
break;
|
||||
case 'B':
|
||||
region = "Brazil";
|
||||
break;
|
||||
case 'C':
|
||||
region = "China";
|
||||
break;
|
||||
case 'D':
|
||||
region = "Germany";
|
||||
break;
|
||||
case 'E':
|
||||
region = "North America";
|
||||
break;
|
||||
case 'F':
|
||||
region = "France";
|
||||
break;
|
||||
case 'G':
|
||||
region = "Gateway 64 (NTSC)";
|
||||
break;
|
||||
case 'H':
|
||||
region = "Netherlands";
|
||||
break;
|
||||
case 'I':
|
||||
region = "Italy";
|
||||
break;
|
||||
case 'J':
|
||||
region = "Japan";
|
||||
break;
|
||||
case 'K':
|
||||
region = "Korea";
|
||||
break;
|
||||
case 'L':
|
||||
region = "Gateway 64 (PAL)";
|
||||
break;
|
||||
case 'N':
|
||||
region = "Canada";
|
||||
break;
|
||||
case 'P':
|
||||
case 'X':
|
||||
region = "Europe/Australia";
|
||||
break;
|
||||
case 'S':
|
||||
region = "Spain";
|
||||
break;
|
||||
case 'U':
|
||||
region = "Australia";
|
||||
break;
|
||||
case 'W':
|
||||
region = "Scandanavia";
|
||||
break;
|
||||
case 'Y':
|
||||
case 'Z':
|
||||
region = "Europe";
|
||||
break;
|
||||
default:
|
||||
region = "Unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
//
|
||||
// Exported Functions
|
||||
//
|
||||
@@ -49,6 +140,8 @@ bool CoreGetCurrentRomHeader(CoreRomHeader& header)
|
||||
header.CRC2 = ntohl(m64p_header.CRC2);
|
||||
header.CountryCode = m64p_header.Country_code;
|
||||
header.Name = CoreConvertStringEncoding((char*)m64p_header.Name, CoreStringEncoding::Shift_JIS);
|
||||
|
||||
header.GameID = get_gameid_from_header(m64p_header);
|
||||
header.Region = get_region_from_countrycode((char)header.CountryCode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ struct CoreRomHeader
|
||||
uint32_t CRC2;
|
||||
uint32_t CountryCode;
|
||||
std::string Name;
|
||||
std::string GameID;
|
||||
std::string Region;
|
||||
};
|
||||
|
||||
// retrieves the currently opened ROM header
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "RomHeader.hpp"
|
||||
#include "Error.hpp"
|
||||
|
||||
#include "Settings/Settings.hpp"
|
||||
#include "m64p/Api.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -122,28 +123,37 @@ bool CoreGetSaveStatePath(int slot, std::filesystem::path& path)
|
||||
}
|
||||
|
||||
// else use new filename
|
||||
if (romSettings.GoodName.find("(unknown rom)") == std::string::npos)
|
||||
{
|
||||
if (romSettings.GoodName.size() < 32)
|
||||
{
|
||||
saveStatePath += romSettings.GoodName;
|
||||
}
|
||||
else
|
||||
{
|
||||
saveStatePath += romSettings.GoodName.substr(0, 32);
|
||||
}
|
||||
}
|
||||
else if (!romHeader.Name.empty())
|
||||
int format = CoreSettingsGetIntValue(SettingsID::Core_SaveFileNameFormat);
|
||||
if (format == 0)
|
||||
{
|
||||
saveStatePath += romHeader.Name;
|
||||
saveStatePath += saveStateExtension;
|
||||
}
|
||||
else
|
||||
{
|
||||
saveStatePath += "unknown";
|
||||
if (romSettings.GoodName.find("(unknown rom)") == std::string::npos)
|
||||
{
|
||||
if (romSettings.GoodName.size() < 32)
|
||||
{
|
||||
saveStatePath += romSettings.GoodName;
|
||||
}
|
||||
else
|
||||
{
|
||||
saveStatePath += romSettings.GoodName.substr(0, 32);
|
||||
}
|
||||
}
|
||||
else if (!romHeader.Name.empty())
|
||||
{
|
||||
saveStatePath += romHeader.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
saveStatePath += "unknown";
|
||||
}
|
||||
saveStatePath += "-";
|
||||
saveStatePath += romSettings.MD5.substr(0, 8);
|
||||
saveStatePath += saveStateExtension;
|
||||
}
|
||||
saveStatePath += "-";
|
||||
saveStatePath += romSettings.MD5.substr(0, 8);
|
||||
saveStatePath += saveStateExtension;
|
||||
|
||||
// retrieve filename from path
|
||||
saveStateFileName = saveStatePath.filename().string();
|
||||
|
||||
@@ -183,6 +183,9 @@ static l_Setting get_setting(SettingsID settingId)
|
||||
case SettingsID::GUI_Toolbar:
|
||||
setting = {SETTING_SECTION_GUI, "Toolbar", true};
|
||||
break;
|
||||
case SettingsID::GUI_ToolbarArea:
|
||||
setting = {SETTING_SECTION_GUI, "ToolbarArea", 0};
|
||||
break;
|
||||
case SettingsID::GUI_StatusBar:
|
||||
setting = {SETTING_SECTION_GUI, "StatusBar", true};
|
||||
break;
|
||||
@@ -277,6 +280,9 @@ static l_Setting get_setting(SettingsID settingId)
|
||||
case SettingsID::Core_SiDmaDuration:
|
||||
setting = {SETTING_SECTION_M64P, "SiDmaDuration", -1};
|
||||
break;
|
||||
case SettingsID::Core_SaveFileNameFormat:
|
||||
setting = {SETTING_SECTION_M64P, "SaveFilenameFormat", 1};
|
||||
break;
|
||||
|
||||
case SettingsID::CoreOverlay_RandomizeInterrupt:
|
||||
setting = {SETTING_SECTION_OVERLAY, "RandomizeInterrupt", true};
|
||||
@@ -299,6 +305,9 @@ static l_Setting get_setting(SettingsID settingId)
|
||||
case SettingsID::CoreOverlay_SiDmaDuration:
|
||||
setting = {SETTING_SECTION_OVERLAY, "SiDmaDuration", -1};
|
||||
break;
|
||||
case SettingsID::CoreOverLay_SaveFileNameFormat:
|
||||
setting = {SETTING_SECTION_OVERLAY, "SaveFilenameFormat", 1};
|
||||
break;
|
||||
|
||||
case SettingsID::Core_ScreenshotPath:
|
||||
setting = {SETTING_SECTION_M64P, "ScreenshotPath", CoreGetDefaultScreenshotDirectory(), "", true};
|
||||
@@ -545,13 +554,13 @@ static l_Setting get_setting(SettingsID settingId)
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "MaxItems", 250};
|
||||
break;
|
||||
case SettingsID::RomBrowser_ColumnVisibility:
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "ColumnVisibility", std::vector<int>({1, 1, 1})};
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "ColumnVisibility", std::vector<int>({1, 1, 1, 0, 0, 0, 0, 0, 0})};
|
||||
break;
|
||||
case SettingsID::RomBrowser_ColumnOrder:
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "ColumnOrder", std::vector<int>({0, 1, 2})};
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "ColumnOrder", std::vector<int>({0, 1, 2, 3, 4, 5, 6, 7, 8})};
|
||||
break;
|
||||
case SettingsID::RomBrowser_ColumnSizes:
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "ColumnSizes", std::vector<int>({-1, -1, -1})};
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "ColumnSizes", std::vector<int>({-1, -1, -1, -1, -1, -1, -1, -1, -1})};
|
||||
break;
|
||||
case SettingsID::RomBrowser_SortAfterSearch:
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "SortAfterSearch", true};
|
||||
@@ -631,6 +640,9 @@ static l_Setting get_setting(SettingsID settingId)
|
||||
case SettingsID::Input_Deadzone:
|
||||
setting = {"", "Deadzone"};
|
||||
break;
|
||||
case SettingsID::Input_Sensitivity:
|
||||
setting = {"", "Sensitivity"};
|
||||
break;
|
||||
case SettingsID::Input_Pak:
|
||||
setting = {"", "Pak"};
|
||||
break;
|
||||
|
||||
@@ -20,6 +20,7 @@ enum class SettingsID
|
||||
GUI_OnScreenDisplayOpacity,
|
||||
GUI_OnScreenDisplayDuration,
|
||||
GUI_Toolbar,
|
||||
GUI_ToolbarArea,
|
||||
GUI_StatusBar,
|
||||
GUI_Theme,
|
||||
GUI_IconTheme,
|
||||
@@ -64,6 +65,7 @@ enum class SettingsID
|
||||
Core_CountPerOp,
|
||||
Core_CountPerOpDenomPot,
|
||||
Core_SiDmaDuration,
|
||||
Core_SaveFileNameFormat,
|
||||
|
||||
// (mupen64plus) Overlay Core Settings
|
||||
CoreOverlay_RandomizeInterrupt,
|
||||
@@ -73,6 +75,7 @@ enum class SettingsID
|
||||
CoreOverlay_CountPerOp,
|
||||
CoreOverlay_CountPerOpDenomPot,
|
||||
CoreOverlay_SiDmaDuration,
|
||||
CoreOverLay_SaveFileNameFormat,
|
||||
|
||||
// (mupen64plus) Core Directory Settings
|
||||
Core_ScreenshotPath,
|
||||
@@ -186,6 +189,7 @@ enum class SettingsID
|
||||
Input_DeviceName,
|
||||
Input_DeviceNum,
|
||||
Input_Deadzone,
|
||||
Input_Sensitivity,
|
||||
Input_Pak,
|
||||
Input_GameboyRom,
|
||||
Input_GameboySave,
|
||||
|
||||
@@ -28,6 +28,8 @@ bool PluginApi::Hook(m64p_dynlib_handle handle)
|
||||
HOOK_FUNC(handle, Plugin, Startup);
|
||||
HOOK_FUNC(handle, Plugin, Shutdown);
|
||||
HOOK_FUNC_OPT(handle, Plugin, Config);
|
||||
HOOK_FUNC_OPT(handle, Plugin, Config2);
|
||||
HOOK_FUNC_OPT(handle, Plugin, Config2HasRomConfig);
|
||||
HOOK_FUNC(handle, Plugin, GetVersion);
|
||||
|
||||
this->handle = handle;
|
||||
@@ -40,6 +42,8 @@ bool PluginApi::Unhook(void)
|
||||
UNHOOK_FUNC(Plugin, Startup);
|
||||
UNHOOK_FUNC(Plugin, Shutdown);
|
||||
UNHOOK_FUNC(Plugin, Config);
|
||||
UNHOOK_FUNC(Plugin, Config2);
|
||||
UNHOOK_FUNC(Plugin, Config2HasRomConfig);
|
||||
UNHOOK_FUNC(Plugin, GetVersion);
|
||||
|
||||
this->handle = nullptr;
|
||||
|
||||
@@ -34,6 +34,8 @@ class PluginApi
|
||||
ptr_PluginStartup Startup;
|
||||
ptr_PluginShutdown Shutdown;
|
||||
ptr_PluginConfig Config;
|
||||
ptr_PluginConfig2 Config2;
|
||||
ptr_PluginConfig2HasRomConfig Config2HasRomConfig;
|
||||
ptr_PluginGetVersion GetVersion;
|
||||
|
||||
private:
|
||||
|
||||
@@ -21,6 +21,29 @@ typedef m64p_error (*ptr_PluginConfig)(void);
|
||||
EXPORT m64p_error CALL PluginConfig(void);
|
||||
#endif
|
||||
|
||||
/* PluginConfig2(int romConfig)
|
||||
*
|
||||
* This optional function opens a configuration GUI for the plugin
|
||||
* https://github.com/mupen64plus/mupen64plus-core/pull/774
|
||||
*
|
||||
* romConfig argument determines if it should open the ROM specific config
|
||||
*/
|
||||
typedef m64p_error (*ptr_PluginConfig2)(int);
|
||||
#if defined(M64P_PLUGIN_PROTOTYPES) || defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT m64p_error CALL PluginConfig2(int);
|
||||
#endif
|
||||
|
||||
/* PluginConfig2HasRomConfig(void)
|
||||
*
|
||||
* This optional function returns wether the plugin supports ROM specific config
|
||||
* using PluginConfig2
|
||||
*
|
||||
*/
|
||||
typedef int (*ptr_PluginConfig2HasRomConfig)(void);
|
||||
#if defined(M64P_PLUGIN_PROTOTYPES) || defined(M64P_CORE_PROTOTYPES)
|
||||
EXPORT int CALL PluginConfig2HasRomConfig(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
using namespace UserInterface;
|
||||
|
||||
MainDialog::MainDialog(QWidget* parent, Thread::SDLThread* sdlThread) : QDialog(parent)
|
||||
MainDialog::MainDialog(QWidget* parent, Thread::SDLThread* sdlThread, bool romConfig) : QDialog(parent)
|
||||
{
|
||||
this->setupUi(this);
|
||||
this->setWindowIcon(QIcon(":Resource/RMG.png"));
|
||||
@@ -41,6 +41,7 @@ MainDialog::MainDialog(QWidget* parent, Thread::SDLThread* sdlThread) : QDialog(
|
||||
for (int i = 0; i < this->tabWidget->count(); i++)
|
||||
{
|
||||
Widget::ControllerWidget* widget = new Widget::ControllerWidget(this, this->eventFilter);
|
||||
widget->SetOnlyLoadGameProfile(romConfig);
|
||||
widget->SetSettingsSection("Player " + QString::number(i + 1), "Rosalie's Mupen GUI - Input Plugin Profile " + QString::number(i));
|
||||
widget->LoadSettings();
|
||||
this->tabWidget->widget(i)->layout()->addWidget(widget);
|
||||
|
||||
@@ -59,7 +59,7 @@ private:
|
||||
void closeInputDevice();
|
||||
|
||||
public:
|
||||
MainDialog(QWidget *parent, Thread::SDLThread*);
|
||||
MainDialog(QWidget *parent, Thread::SDLThread*, bool);
|
||||
~MainDialog(void);
|
||||
|
||||
public slots:
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
#include "ControllerImageWidget.hpp"
|
||||
|
||||
#include <QSvgRenderer>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <QPainter>
|
||||
#include <QResizeEvent>
|
||||
|
||||
@@ -62,6 +62,15 @@ void ControllerImageWidget::SetDeadzone(int value)
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerImageWidget::SetSensitivity(int value)
|
||||
{
|
||||
if (this->sensitivityValue != value)
|
||||
{
|
||||
this->sensitivityValue = value;
|
||||
this->needImageUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerImageWidget::ClearControllerState()
|
||||
{
|
||||
// reset button state
|
||||
@@ -153,27 +162,35 @@ void ControllerImageWidget::paintEvent(QPaintEvent *event)
|
||||
renderer.setAspectRatioMode(Qt::AspectRatioMode::KeepAspectRatio);
|
||||
|
||||
QRectF rectF = renderer.viewBoxF();
|
||||
double offsetx = 0, offsety = 0;
|
||||
const int width = rectF.width();
|
||||
const int height = rectF.height();
|
||||
// we'll move the analog stick by a percentage
|
||||
// of the total width/height from the image
|
||||
const double maxOffsety = ((double)(height * 0.12265f) / 2);
|
||||
const double maxOffsetx = maxOffsety;
|
||||
const double dist = sqrt(pow(this->xAxisState, 2) + pow(this->yAxisState, 2));
|
||||
const double absoluteMaxOffset = ((double)(height * 0.12265f) / 2);
|
||||
// slope as in line gradient
|
||||
const double offsetSlope = absoluteMaxOffset / 100;
|
||||
// take sensitivity into account
|
||||
const double sensitivityFactor = this->sensitivityValue / 100.0;
|
||||
const double sensitivityAdjustedMaxOffset = absoluteMaxOffset * std::min(sensitivityFactor, 1.0);
|
||||
double offsetDeadzone = this->deadzoneValue * sensitivityFactor * offsetSlope;
|
||||
int offsetx = this->xAxisState * sensitivityFactor * offsetSlope;
|
||||
int offsety = this->yAxisState * sensitivityFactor * offsetSlope;
|
||||
const double offsetDist = sqrt(pow(offsetx, 2) + pow(offsety, 2));
|
||||
|
||||
// take deadzone into account
|
||||
if (dist > this->deadzoneValue)
|
||||
// deadzone grows with sensitivity such that the deadzone
|
||||
// is always a percentage of the real stick range
|
||||
if (offsetDist <= offsetDeadzone)
|
||||
{
|
||||
offsetx = (maxOffsetx / 100 * this->xAxisState);
|
||||
offsety = (maxOffsety / 100 * this->yAxisState);
|
||||
offsetx = 0;
|
||||
offsety = 0;
|
||||
}
|
||||
|
||||
// take circle range into account
|
||||
if (dist > 100)
|
||||
if (offsetDist > sensitivityAdjustedMaxOffset)
|
||||
{
|
||||
offsetx = (maxOffsetx / 100 * (this->xAxisState / dist * 100));
|
||||
offsety = (maxOffsety / 100 * (this->yAxisState / dist * 100));
|
||||
offsetx = (offsetx / offsetDist) * sensitivityAdjustedMaxOffset;
|
||||
offsety = (offsety / offsetDist) * sensitivityAdjustedMaxOffset;
|
||||
}
|
||||
|
||||
// adjust rect with offset
|
||||
|
||||
@@ -31,6 +31,8 @@ private:
|
||||
int yAxisState = 0;
|
||||
// deadzone value, 0-100
|
||||
int deadzoneValue = 0;
|
||||
// sensitivity value, 25-175
|
||||
int sensitivityValue = 100;
|
||||
|
||||
bool needImageUpdate = false;
|
||||
public:
|
||||
@@ -41,6 +43,7 @@ public:
|
||||
void SetXAxisState(int xAxis);
|
||||
void SetYAxisState(int yAxis);
|
||||
void SetDeadzone(int value);
|
||||
void SetSensitivity(int value);
|
||||
|
||||
void ClearControllerState();
|
||||
void UpdateImage();
|
||||
|
||||
@@ -323,6 +323,7 @@ void ControllerWidget::setPluggedIn(bool value)
|
||||
this->analogStickDownButton, this->analogStickDownAddButton, this->analogStickDownRemoveButton,
|
||||
this->analogStickLeftButton, this->analogStickLeftAddButton, this->analogStickLeftRemoveButton,
|
||||
this->analogStickRightButton, this->analogStickRightAddButton, this->analogStickRightRemoveButton,
|
||||
this->analogStickSensitivitySlider,
|
||||
// cbuttons
|
||||
this->cButtonsGroupBox,
|
||||
this->cbuttonUpButton, this->cbuttonUpAddButton, this->cbuttonUpRemoveButton,
|
||||
@@ -354,6 +355,67 @@ void ControllerWidget::setPluggedIn(bool value)
|
||||
this->ClearControllerImage();
|
||||
}
|
||||
|
||||
bool ControllerWidget::hasAnyGameSettingChanged(void)
|
||||
{
|
||||
std::string section = this->getCurrentSettingsSection().toStdString();
|
||||
// fallback to main section
|
||||
if (!CoreSettingsSectionExists(section))
|
||||
{
|
||||
section = this->settingsSection.toStdString();
|
||||
}
|
||||
|
||||
// retrieve data from settings
|
||||
bool settingsIsPluggedIn = CoreSettingsGetBoolValue(SettingsID::Input_PluggedIn, section);
|
||||
int settingsDeadZone = CoreSettingsGetIntValue(SettingsID::Input_Deadzone, section);
|
||||
int settingsAnalogSensitivity = 100;
|
||||
// account for profiles before v0.3.9
|
||||
if (CoreSettingsKeyExists(section, "Sensitivity"))
|
||||
{
|
||||
settingsAnalogSensitivity = CoreSettingsGetIntValue(SettingsID::Input_Sensitivity, section);
|
||||
}
|
||||
|
||||
// retrieve current data
|
||||
bool currentIsPluggedIn = this->inputDeviceComboBox->currentText() != "None";
|
||||
int currentDeadZone = this->deadZoneSlider->value();
|
||||
int currentAnalogSensitivity = this->analogStickSensitivitySlider->value();
|
||||
|
||||
// compare data
|
||||
if (settingsIsPluggedIn != currentIsPluggedIn ||
|
||||
settingsDeadZone != currentDeadZone ||
|
||||
settingsAnalogSensitivity != currentAnalogSensitivity)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// compare button mappings with settings
|
||||
for (auto& buttonSetting : this->buttonSettingMappings)
|
||||
{
|
||||
// retrieve data from settings
|
||||
std::vector<int> settingsTypes = CoreSettingsGetIntListValue(buttonSetting.inputTypeSettingsId, section);
|
||||
std::vector<std::string> settingsNames = CoreSettingsGetStringListValue(buttonSetting.nameSettingsId, section);
|
||||
std::vector<int> settingsData = CoreSettingsGetIntListValue(buttonSetting.dataSettingsId, section);
|
||||
std::vector<int> settingsExtraData = CoreSettingsGetIntListValue(buttonSetting.extraDataSettingsId, section);
|
||||
|
||||
// retrieve current data
|
||||
std::vector<int> currentTypes = buttonSetting.button->GetInputType();
|
||||
std::vector<std::string> currentNames = buttonSetting.button->GetInputText();
|
||||
std::vector<int> currentData = buttonSetting.button->GetInputData();
|
||||
std::vector<int> currentExtraData = buttonSetting.button->GetExtraInputData();
|
||||
|
||||
// compare data
|
||||
if (settingsTypes != currentTypes ||
|
||||
settingsNames != currentNames ||
|
||||
settingsData != currentData ||
|
||||
settingsExtraData != currentExtraData)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// no differences found
|
||||
return false;
|
||||
}
|
||||
|
||||
void ControllerWidget::showErrorMessage(QString text, QString details)
|
||||
{
|
||||
QMessageBox msgBox(this);
|
||||
@@ -509,6 +571,16 @@ void ControllerWidget::on_deadZoneSlider_valueChanged(int value)
|
||||
this->controllerImageWidget->SetDeadzone(value);
|
||||
}
|
||||
|
||||
void ControllerWidget::on_analogStickSensitivitySlider_valueChanged(int value)
|
||||
{
|
||||
QString title = tr("Analog Stick Sensitivity: ");
|
||||
title += QString::number(value);
|
||||
title += "%";
|
||||
|
||||
this->analogStickSensitivityGroupBox->setTitle(title);
|
||||
this->controllerImageWidget->SetSensitivity(value);
|
||||
}
|
||||
|
||||
void ControllerWidget::on_profileComboBox_currentIndexChanged(int value)
|
||||
{
|
||||
// save profile when switching profile
|
||||
@@ -622,7 +694,7 @@ void ControllerWidget::on_removeProfileButton_clicked()
|
||||
{
|
||||
bool ret;
|
||||
|
||||
if (this->profileComboBox->currentIndex() == 0)
|
||||
if (this->profileComboBox->currentData().toString() == this->settingsSection)
|
||||
{
|
||||
QMessageBox messageBox(this);
|
||||
messageBox.setIcon(QMessageBox::Icon::Warning);
|
||||
@@ -678,6 +750,13 @@ void ControllerWidget::on_removeProfileButton_clicked()
|
||||
this->previousProfileComboBoxIndex = -1;
|
||||
this->profileComboBox->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
// force a re-load when
|
||||
// we're only loading the game profile
|
||||
if (this->onlyLoadGameProfile)
|
||||
{
|
||||
this->LoadSettings(this->settingsSection);
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerWidget::on_resetButton_clicked()
|
||||
@@ -1093,10 +1172,21 @@ bool ControllerWidget::IsPluggedIn()
|
||||
return this->inputDeviceComboBox->currentData().toInt() != (int)InputDeviceType::None;
|
||||
}
|
||||
|
||||
void ControllerWidget::SetOnlyLoadGameProfile(bool value)
|
||||
{
|
||||
this->onlyLoadGameProfile = value;
|
||||
|
||||
// update UI element
|
||||
this->addProfileButton->setDisabled(value);
|
||||
}
|
||||
|
||||
void ControllerWidget::SetSettingsSection(QString profile, QString section)
|
||||
{
|
||||
this->settingsSection = section;
|
||||
this->profileComboBox->addItem(profile, section);
|
||||
if (!this->onlyLoadGameProfile)
|
||||
{
|
||||
this->profileComboBox->addItem(profile, section);
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerWidget::SetInitialized(bool value)
|
||||
@@ -1145,41 +1235,53 @@ void ControllerWidget::LoadSettings()
|
||||
// if a game specific section exists,
|
||||
// select it in the profile combobox
|
||||
// and use it to load the settings
|
||||
if (CoreSettingsSectionExists(this->gameSection.toStdString()))
|
||||
if (CoreSettingsSectionExists(this->gameSection.toStdString()) ||
|
||||
this->onlyLoadGameProfile)
|
||||
{
|
||||
// check if the key 'UseGameProfile' exists,
|
||||
// if it doesn't then use the profile,
|
||||
// else check if it's true and use it
|
||||
if (!CoreSettingsKeyExists(this->gameSection.toStdString(), "UseGameProfile") ||
|
||||
// else check if it's true and use it,
|
||||
// or if we're only loading the game profile
|
||||
if (this->onlyLoadGameProfile ||
|
||||
!CoreSettingsKeyExists(this->gameSection.toStdString(), "UseGameProfile") ||
|
||||
CoreSettingsGetBoolValue(SettingsID::Input_UseGameProfile, this->gameSection.toStdString()))
|
||||
{
|
||||
this->profileComboBox->setCurrentText(internalName);
|
||||
section = this->gameSection;
|
||||
|
||||
// only use game section if it exists
|
||||
if (CoreSettingsSectionExists(this->gameSection.toStdString()))
|
||||
{
|
||||
section = this->gameSection;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clear profiles list
|
||||
profiles.clear();
|
||||
|
||||
// try to add all the user's profiles
|
||||
userProfiles = CoreSettingsGetStringListValue(SettingsID::Input_Profiles);
|
||||
for (const std::string& profile : userProfiles)
|
||||
// try to add all the user's profiles when we're not only loading the
|
||||
// game profile
|
||||
if (!this->onlyLoadGameProfile)
|
||||
{
|
||||
QString profileSection = this->getUserProfileSectionName(QString::fromStdString(profile));
|
||||
// clear profiles list
|
||||
profiles.clear();
|
||||
|
||||
// ensure the profile section exists,
|
||||
// if it does, add it when it doesn't
|
||||
// exist yet
|
||||
if (CoreSettingsSectionExists(profileSection.toStdString()))
|
||||
userProfiles = CoreSettingsGetStringListValue(SettingsID::Input_Profiles);
|
||||
for (const std::string& profile : userProfiles)
|
||||
{
|
||||
// add to profiles list
|
||||
this->profiles.push_back(profileSection);
|
||||
QString profileSection = this->getUserProfileSectionName(QString::fromStdString(profile));
|
||||
|
||||
int index = this->profileComboBox->findData(profileSection);
|
||||
if (index == -1)
|
||||
// ensure the profile section exists,
|
||||
// if it does, add it when it doesn't
|
||||
// exist yet
|
||||
if (CoreSettingsSectionExists(profileSection.toStdString()))
|
||||
{
|
||||
this->profileComboBox->addItem(QString::fromStdString(profile), profileSection);
|
||||
// add to profiles list
|
||||
this->profiles.push_back(profileSection);
|
||||
|
||||
int index = this->profileComboBox->findData(profileSection);
|
||||
if (index == -1)
|
||||
{
|
||||
this->profileComboBox->addItem(QString::fromStdString(profile), profileSection);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1219,7 +1321,7 @@ void ControllerWidget::LoadSettings(QString sectionQString, bool loadUserProfile
|
||||
// if it does, see if that profile exists, then load
|
||||
// that instead
|
||||
useProfile = CoreSettingsGetStringValue(SettingsID::Input_UseProfile, section);
|
||||
if (loadUserProfile && !useProfile.empty())
|
||||
if (!this->onlyLoadGameProfile && loadUserProfile && !useProfile.empty())
|
||||
{
|
||||
QString profileSection = this->getUserProfileSectionName(QString::fromStdString(useProfile));
|
||||
|
||||
@@ -1232,6 +1334,16 @@ void ControllerWidget::LoadSettings(QString sectionQString, bool loadUserProfile
|
||||
}
|
||||
}
|
||||
|
||||
// keep backwards compatibility with versions before v0.3.9
|
||||
if (CoreSettingsKeyExists(section, "Sensitivity"))
|
||||
{
|
||||
this->analogStickSensitivitySlider->setValue(CoreSettingsGetIntValue(SettingsID::Input_Sensitivity, section));
|
||||
}
|
||||
else
|
||||
{
|
||||
this->analogStickSensitivitySlider->setValue(100);
|
||||
}
|
||||
|
||||
this->deadZoneSlider->setValue(CoreSettingsGetIntValue(SettingsID::Input_Deadzone, section));
|
||||
this->optionsDialogSettings.RemoveDuplicateMappings = CoreSettingsGetBoolValue(SettingsID::Input_RemoveDuplicateMappings, section);
|
||||
this->optionsDialogSettings.ControllerPak = CoreSettingsGetIntValue(SettingsID::Input_Pak, section);
|
||||
@@ -1309,6 +1421,7 @@ void ControllerWidget::SaveDefaultSettings()
|
||||
CoreSettingsSetValue(SettingsID::Input_DeviceName, section, std::string("None"));
|
||||
CoreSettingsSetValue(SettingsID::Input_DeviceNum, section, (int)InputDeviceType::None);
|
||||
CoreSettingsSetValue(SettingsID::Input_Deadzone, section, 9);
|
||||
CoreSettingsSetValue(SettingsID::Input_Sensitivity, section, 100);
|
||||
CoreSettingsSetValue(SettingsID::Input_Pak, section, 0);
|
||||
CoreSettingsSetValue(SettingsID::Input_RemoveDuplicateMappings, section, true);
|
||||
CoreSettingsSetValue(SettingsID::Input_FilterEventsForButtons, section, true);
|
||||
@@ -1330,6 +1443,14 @@ void ControllerWidget::SaveSettings()
|
||||
return;
|
||||
}
|
||||
|
||||
// when we're only loading the game profile,
|
||||
// we should only save when anything has changed
|
||||
if (this->onlyLoadGameProfile &&
|
||||
!this->hasAnyGameSettingChanged())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this->SaveSettings(this->getCurrentSettingsSection());
|
||||
|
||||
// delete all removed profile sections
|
||||
@@ -1393,6 +1514,7 @@ void ControllerWidget::SaveSettings(QString section)
|
||||
CoreSettingsSetValue(SettingsID::Input_DeviceName, sectionStr, deviceName.toStdString());
|
||||
CoreSettingsSetValue(SettingsID::Input_DeviceNum, sectionStr, deviceNum);
|
||||
CoreSettingsSetValue(SettingsID::Input_Deadzone, sectionStr, this->deadZoneSlider->value());
|
||||
CoreSettingsSetValue(SettingsID::Input_Sensitivity, sectionStr, this->analogStickSensitivitySlider->value());
|
||||
CoreSettingsSetValue(SettingsID::Input_Pak, sectionStr, this->optionsDialogSettings.ControllerPak);
|
||||
CoreSettingsSetValue(SettingsID::Input_GameboyRom, sectionStr, this->optionsDialogSettings.GameboyRom);
|
||||
CoreSettingsSetValue(SettingsID::Input_GameboySave, sectionStr, this->optionsDialogSettings.GameboySave);
|
||||
@@ -1425,6 +1547,14 @@ void ControllerWidget::RevertSettings()
|
||||
CoreSettingsRevertSection(section.toStdString());
|
||||
}
|
||||
|
||||
// don't compare profiles,
|
||||
// when we're only loading
|
||||
// the game profile
|
||||
if (this->onlyLoadGameProfile)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// delete all sections for added & removed profiles,
|
||||
// which aren't in the base profile section list
|
||||
sections.clear();
|
||||
|
||||
@@ -95,6 +95,8 @@ private:
|
||||
|
||||
void setPluggedIn(bool value);
|
||||
|
||||
bool hasAnyGameSettingChanged(void);
|
||||
|
||||
void showErrorMessage(QString text, QString details = "");
|
||||
|
||||
SDL_JoystickID currentJoystickId = -1;
|
||||
@@ -102,6 +104,8 @@ private:
|
||||
|
||||
int previousProfileComboBoxIndex = -1;
|
||||
|
||||
bool onlyLoadGameProfile = false;
|
||||
|
||||
public:
|
||||
ControllerWidget(QWidget* parent, EventFilter* eventFilter);
|
||||
~ControllerWidget();
|
||||
@@ -116,6 +120,8 @@ public:
|
||||
void GetCurrentInputDevice(QString& deviceName, int& deviceNum, bool ignoreDeviceNotFound = false);
|
||||
bool IsPluggedIn();
|
||||
|
||||
void SetOnlyLoadGameProfile(bool value);
|
||||
|
||||
void SetSettingsSection(QString profile, QString section);
|
||||
void SetInitialized(bool value);
|
||||
|
||||
@@ -138,6 +144,7 @@ public:
|
||||
|
||||
private slots:
|
||||
void on_deadZoneSlider_valueChanged(int value);
|
||||
void on_analogStickSensitivitySlider_valueChanged(int value);
|
||||
|
||||
void on_profileComboBox_currentIndexChanged(int value);
|
||||
|
||||
|
||||
@@ -601,6 +601,43 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="analogStickSensitivityGroupBox">
|
||||
<property name="title">
|
||||
<string>Analog Stick Sensitivity: 100%</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_15">
|
||||
<item>
|
||||
<widget class="QSlider" name="analogStickSensitivitySlider">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>25</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>175</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>15</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
|
||||
+29
-12
@@ -21,7 +21,7 @@
|
||||
#include <QApplication>
|
||||
#include <SDL.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
|
||||
//
|
||||
@@ -60,6 +60,7 @@ struct InputProfile
|
||||
{
|
||||
bool PluggedIn = false;
|
||||
int DeadzoneValue = 0;
|
||||
int SensitivityValue = 100;
|
||||
|
||||
N64ControllerPak ControllerPak = N64ControllerPak::None;
|
||||
|
||||
@@ -223,6 +224,16 @@ static void load_settings(void)
|
||||
profile->GameboyRom = CoreSettingsGetStringValue(SettingsID::Input_GameboyRom, section);
|
||||
profile->GameboySave = CoreSettingsGetStringValue(SettingsID::Input_GameboySave, section);
|
||||
|
||||
// keep compatibility with profiles before version v0.3.9
|
||||
if (CoreSettingsKeyExists(section, "Sensitivity"))
|
||||
{
|
||||
profile->SensitivityValue = CoreSettingsGetIntValue(SettingsID::Input_Sensitivity, section);
|
||||
}
|
||||
else
|
||||
{
|
||||
profile->SensitivityValue = 100;
|
||||
}
|
||||
|
||||
// load inputmapping settings
|
||||
load_inputmapping_settings(&profile->Button_A, section, SettingsID::Input_A_Name, SettingsID::Input_A_InputType, SettingsID::Input_A_Data, SettingsID::Input_A_ExtraData);
|
||||
load_inputmapping_settings(&profile->Button_B, section, SettingsID::Input_B_Name, SettingsID::Input_B_InputType, SettingsID::Input_B_Data, SettingsID::Input_B_ExtraData);
|
||||
@@ -406,7 +417,7 @@ static void close_controllers(void)
|
||||
for (int i = 0; i < NUM_CONTROLLERS; i++)
|
||||
{
|
||||
InputProfile* profile = &l_InputProfiles[i];
|
||||
|
||||
|
||||
profile->InputDevice.CloseDevice();
|
||||
}
|
||||
}
|
||||
@@ -537,16 +548,17 @@ static double simulate_deadzone(const double n64InputAxis, const double maxAxis,
|
||||
return axisAbsolute;
|
||||
}
|
||||
|
||||
// Credit: MerryMage
|
||||
static void simulate_octagon(const double inputX, const double inputY, const double deadzoneFactor, int& outputX, int& outputY)
|
||||
// Credit: MerryMage & fzurita
|
||||
static void simulate_octagon(const double inputX, const double inputY, const double deadzoneFactor, const double sensitivityFactor, int& outputX, int& outputY)
|
||||
{
|
||||
const double maxAxis = N64_AXIS_PEAK;
|
||||
const double maxDiagonal = MAX_DIAGONAL_VALUE;
|
||||
const int deadzone = (int)(deadzoneFactor * N64_AXIS_PEAK);
|
||||
// don't increase emulated range at higher than 100% sensitivity
|
||||
const double maxAxis = N64_AXIS_PEAK * std::min(sensitivityFactor, 1.0);
|
||||
const double maxDiagonal = MAX_DIAGONAL_VALUE * std::min(sensitivityFactor, 1.0);
|
||||
const int deadzone = (int)(deadzoneFactor * N64_AXIS_PEAK * sensitivityFactor);
|
||||
const double axisRange = maxAxis - deadzone;
|
||||
// scale to [-maxAxis, maxAxis]
|
||||
double ax = inputX * maxAxis;
|
||||
double ay = inputY * maxAxis;
|
||||
double ax = std::min(inputX * sensitivityFactor, 1.0) * maxAxis;
|
||||
double ay = std::min(inputY * sensitivityFactor, 1.0) * maxAxis;
|
||||
|
||||
// check whether (ax, ay) is within the circle of radius MAX_AXIS
|
||||
double len = std::sqrt(ax*ax + ay*ay);
|
||||
@@ -719,7 +731,7 @@ EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *pluginType, int *plugi
|
||||
// Custom Plugin Functions
|
||||
//
|
||||
|
||||
EXPORT m64p_error CALL PluginConfig()
|
||||
EXPORT m64p_error CALL PluginConfig2(int romConfig)
|
||||
{
|
||||
if (l_SDLThread == nullptr)
|
||||
{
|
||||
@@ -731,7 +743,7 @@ EXPORT m64p_error CALL PluginConfig()
|
||||
|
||||
l_SDLThread->SetAction(SDLThreadAction::SDLPumpEvents);
|
||||
|
||||
UserInterface::MainDialog dialog(nullptr, l_SDLThread);
|
||||
UserInterface::MainDialog dialog(nullptr, l_SDLThread, romConfig);
|
||||
dialog.exec();
|
||||
|
||||
l_SDLThread->SetAction(SDLThreadAction::None);
|
||||
@@ -742,7 +754,6 @@ EXPORT m64p_error CALL PluginConfig()
|
||||
QThread::msleep(5);
|
||||
}
|
||||
|
||||
|
||||
// reload settings
|
||||
load_settings();
|
||||
|
||||
@@ -758,6 +769,11 @@ EXPORT m64p_error CALL PluginConfig()
|
||||
return M64ERR_SUCCESS;
|
||||
}
|
||||
|
||||
EXPORT int CALL PluginConfig2HasRomConfig(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Input Plugin Functions
|
||||
//
|
||||
@@ -879,6 +895,7 @@ EXPORT void CALL GetKeys(int Control, BUTTONS* Keys)
|
||||
inputX, // inputX
|
||||
inputY, // inputY
|
||||
profile->DeadzoneValue / 100.0, // deadzoneFactor
|
||||
profile->SensitivityValue / 100.0, // sensitivityFactor
|
||||
octagonX, // outputX
|
||||
octagonY // outputY
|
||||
);
|
||||
|
||||
@@ -70,6 +70,7 @@ void RomSearcherThread::searchDirectory(QString directory)
|
||||
filter << "*.NDD";
|
||||
filter << "*.D64";
|
||||
filter << "*.ZIP";
|
||||
filter << "*.7Z";
|
||||
|
||||
QDirIterator::IteratorFlag flag = this->recursive ?
|
||||
QDirIterator::Subdirectories :
|
||||
@@ -82,9 +83,16 @@ void RomSearcherThread::searchDirectory(QString directory)
|
||||
bool ret;
|
||||
int count = 0;
|
||||
|
||||
QList<QString> roms;
|
||||
while (romDirIt.hasNext())
|
||||
{
|
||||
QString file = romDirIt.next();
|
||||
roms.push_back(romDirIt.next());
|
||||
}
|
||||
|
||||
int romAmount = std::min(this->maxItems, (int)roms.size());
|
||||
for (int i = 0; i < romAmount; i++)
|
||||
{
|
||||
QString file = roms.at(i);
|
||||
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
@@ -111,12 +119,7 @@ void RomSearcherThread::searchDirectory(QString directory)
|
||||
|
||||
if (ret)
|
||||
{
|
||||
if (count++ >= this->maxItems)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
emit this->RomFound(file, type, header, settings);
|
||||
emit this->RomFound(file, type, header, settings, (i + 1), romAmount);
|
||||
}
|
||||
|
||||
if (this->stop)
|
||||
|
||||
@@ -40,7 +40,7 @@ class RomSearcherThread : public QThread
|
||||
void searchDirectory(QString);
|
||||
|
||||
signals:
|
||||
void RomFound(QString file, CoreRomType type, CoreRomHeader header, CoreRomSettings settings);
|
||||
void RomFound(QString file, CoreRomType type, CoreRomHeader header, CoreRomSettings settings, int index, int count);
|
||||
void Finished(bool canceled);
|
||||
};
|
||||
} // namespace Thread
|
||||
|
||||
@@ -66,7 +66,7 @@ void InstallUpdateDialog::install(void)
|
||||
" echo == Attemping to kill PID " + appPid + outputToLogLine,
|
||||
" taskkill /F /PID:" + appPid + outputToLogLine,
|
||||
" echo == Attemping to start \'" + fullFilePath + "\'" + outputToLogLine,
|
||||
" \"" + fullFilePath + "\" /CLOSEAPPLICATIONS /NOCANCEL /SILENT /DIR=\"" + appPath + "\"" + outputToLogLine,
|
||||
" \"" + fullFilePath + "\" /CLOSEAPPLICATIONS /NOCANCEL /MERGETASKS=\"!desktopicon\" /SILENT /DIR=\"" + appPath + "\"" + outputToLogLine,
|
||||
")",
|
||||
"IF NOT ERRORLEVEL 0 (",
|
||||
" start \"\" cmd /c \"echo Rosalie's Mupen GUI failed to update, check the updater.log file in the Cache directory for more information && pause\"",
|
||||
|
||||
@@ -30,7 +30,8 @@ RomInfoDialog::RomInfoDialog(QString file, CoreRomHeader romHeader, CoreRomSetti
|
||||
this->locationLineEdit->setCursorPosition(0);
|
||||
this->crc1LineEdit->setText(QString::number(romHeader.CRC1, 16).toUpper());
|
||||
this->crc2LineEdit->setText(QString::number(romHeader.CRC2, 16).toUpper());
|
||||
this->countryCodeLineEdit->setText(QString((char)romHeader.CountryCode));
|
||||
this->gameIDLineEdit->setText(QString::fromStdString(romHeader.GameID));
|
||||
this->gameRegionLineEdit->setText(QString::fromStdString(romHeader.Region));
|
||||
}
|
||||
|
||||
RomInfoDialog::~RomInfoDialog(void)
|
||||
|
||||
@@ -199,12 +199,36 @@
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Country Code</string>
|
||||
<string>Game I.D.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="countryCodeLineEdit">
|
||||
<widget class="QLineEdit" name="gameIDLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Game Region</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="gameRegionLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
|
||||
@@ -214,6 +214,7 @@ void SettingsDialog::loadCoreSettings(void)
|
||||
bool disableExtraMem = false;
|
||||
int counterFactor = 0;
|
||||
int cpuEmulator = 0;
|
||||
int saveFilenameFormat = 0;
|
||||
int siDmaDuration = -1;
|
||||
bool randomizeInterrupt = true;
|
||||
bool debugger = false;
|
||||
@@ -222,12 +223,14 @@ void SettingsDialog::loadCoreSettings(void)
|
||||
disableExtraMem = CoreSettingsGetBoolValue(SettingsID::CoreOverlay_DisableExtraMem);
|
||||
counterFactor = CoreSettingsGetIntValue(SettingsID::CoreOverlay_CountPerOp);
|
||||
cpuEmulator = CoreSettingsGetIntValue(SettingsID::CoreOverlay_CPU_Emulator);
|
||||
saveFilenameFormat = CoreSettingsGetIntValue(SettingsID::CoreOverLay_SaveFileNameFormat);
|
||||
siDmaDuration = CoreSettingsGetIntValue(SettingsID::CoreOverlay_SiDmaDuration);
|
||||
randomizeInterrupt = CoreSettingsGetBoolValue(SettingsID::CoreOverlay_RandomizeInterrupt);
|
||||
debugger = CoreSettingsGetBoolValue(SettingsID::CoreOverlay_EnableDebugger);
|
||||
overrideGameSettings = CoreSettingsGetBoolValue(SettingsID::Core_OverrideGameSpecificSettings);
|
||||
|
||||
this->coreCpuEmulatorComboBox->setCurrentIndex(cpuEmulator);
|
||||
this->coreSaveFilenameFormatComboBox->setCurrentIndex(saveFilenameFormat);
|
||||
this->coreRandomizeTimingCheckBox->setChecked(randomizeInterrupt);
|
||||
//this->coreDebuggerCheckBox->setChecked(debugger);
|
||||
|
||||
@@ -437,6 +440,7 @@ void SettingsDialog::loadDefaultCoreSettings(void)
|
||||
bool disableExtraMem = false;
|
||||
int counterFactor = 0;
|
||||
int cpuEmulator = 0;
|
||||
int saveFilenameFormat = 0;
|
||||
int siDmaDuration = -1;
|
||||
bool randomizeInterrupt = true;
|
||||
bool debugger = false;
|
||||
@@ -446,11 +450,13 @@ void SettingsDialog::loadDefaultCoreSettings(void)
|
||||
counterFactor = CoreSettingsGetDefaultIntValue(SettingsID::CoreOverlay_CountPerOp);
|
||||
cpuEmulator = CoreSettingsGetDefaultIntValue(SettingsID::CoreOverlay_CPU_Emulator);
|
||||
siDmaDuration = CoreSettingsGetDefaultIntValue(SettingsID::CoreOverlay_SiDmaDuration);
|
||||
saveFilenameFormat = CoreSettingsGetDefaultIntValue(SettingsID::CoreOverLay_SaveFileNameFormat);
|
||||
randomizeInterrupt = CoreSettingsGetDefaultBoolValue(SettingsID::CoreOverlay_RandomizeInterrupt);
|
||||
debugger = CoreSettingsGetDefaultBoolValue(SettingsID::CoreOverlay_EnableDebugger);
|
||||
overrideGameSettings = CoreSettingsGetDefaultBoolValue(SettingsID::Core_OverrideGameSpecificSettings);
|
||||
|
||||
this->coreCpuEmulatorComboBox->setCurrentIndex(cpuEmulator);
|
||||
this->coreSaveFilenameFormatComboBox->setCurrentIndex(saveFilenameFormat);
|
||||
this->coreRandomizeTimingCheckBox->setChecked(randomizeInterrupt);
|
||||
//this->coreDebuggerCheckBox->setChecked(debugger);
|
||||
|
||||
@@ -603,12 +609,14 @@ void SettingsDialog::saveCoreSettings(void)
|
||||
bool disableExtraMem = (this->coreMemorySizeComboBox->currentIndex() == 0);
|
||||
int counterFactor = this->coreCounterFactorComboBox->currentIndex() + 1;
|
||||
int cpuEmulator = this->coreCpuEmulatorComboBox->currentIndex();
|
||||
int saveFilenameFormat = this->coreSaveFilenameFormatComboBox->currentIndex();
|
||||
int siDmaDuration = this->coreSiDmaDurationSpinBox->value();
|
||||
bool randomizeInterrupt = this->coreRandomizeTimingCheckBox->isChecked();
|
||||
//bool debugger = this->coreDebuggerCheckBox->isChecked();
|
||||
bool overrideGameSettings = this->coreOverrideGameSettingsGroup->isChecked();
|
||||
|
||||
CoreSettingsSetValue(SettingsID::CoreOverlay_CPU_Emulator, cpuEmulator);
|
||||
CoreSettingsSetValue(SettingsID::CoreOverLay_SaveFileNameFormat, saveFilenameFormat);
|
||||
CoreSettingsSetValue(SettingsID::CoreOverlay_RandomizeInterrupt, randomizeInterrupt);
|
||||
//CoreSettingsSetValue(SettingsID::CoreOverlay_EnableDebugger, debugger);
|
||||
CoreSettingsSetValue(SettingsID::Core_OverrideGameSpecificSettings, overrideGameSettings);
|
||||
|
||||
@@ -1500,7 +1500,7 @@
|
||||
<attribute name="title">
|
||||
<string>Core</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_19">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_17">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_43">
|
||||
<item>
|
||||
@@ -1531,6 +1531,31 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_46">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_25">
|
||||
<property name="text">
|
||||
<string>Save Filename Format</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="coreSaveFilenameFormatComboBox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Internal ROM Name</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Automatic</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="coreOverrideGameSettingsGroup">
|
||||
<property name="enabled">
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
using namespace UserInterface::Dialog;
|
||||
|
||||
UpdateDialog::UpdateDialog(QWidget *parent, QJsonObject jsonObject) : QDialog(parent)
|
||||
UpdateDialog::UpdateDialog(QWidget *parent, QJsonObject jsonObject, bool forced) : QDialog(parent)
|
||||
{
|
||||
this->setupUi(this);
|
||||
|
||||
@@ -35,6 +35,10 @@ UpdateDialog::UpdateDialog(QWidget *parent, QJsonObject jsonObject) : QDialog(pa
|
||||
// change ok button text to 'Update'
|
||||
QPushButton* button = this->buttonBox->button(QDialogButtonBox::Ok);
|
||||
button->setText("Update");
|
||||
|
||||
// don't show the 'Don't check for updates again' checkbox,
|
||||
// when the user requested we check for updates
|
||||
this->disableUpdateCheckCheckBox->setHidden(forced);
|
||||
}
|
||||
|
||||
UpdateDialog::~UpdateDialog(void)
|
||||
|
||||
@@ -36,7 +36,7 @@ class UpdateDialog : public QDialog, private Ui::UpdateDialog
|
||||
#endif // _WIN32
|
||||
|
||||
public:
|
||||
UpdateDialog(QWidget *parent, QJsonObject jsonObject);
|
||||
UpdateDialog(QWidget *parent, QJsonObject jsonObject, bool forced);
|
||||
~UpdateDialog(void);
|
||||
|
||||
QString GetFileName(void);
|
||||
|
||||
@@ -128,9 +128,13 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
||||
if (!this->ui_QuitAfterEmulation &&
|
||||
!this->emulationThread->isRunning())
|
||||
{
|
||||
this->storeGeometry();
|
||||
this->storeGeometry();
|
||||
}
|
||||
|
||||
// store toolbar location to settings
|
||||
Qt::ToolBarArea toolbarArea = this->toolBarArea(this->toolBar);
|
||||
CoreSettingsSetValue(SettingsID::GUI_ToolbarArea, this->getToolbarSettingAreaFromArea(toolbarArea));
|
||||
|
||||
this->ui_NoSwitchToRomBrowser = true;
|
||||
this->on_Action_System_Shutdown();
|
||||
|
||||
@@ -169,6 +173,8 @@ void MainWindow::initializeUI(void)
|
||||
&MainWindow::on_RomBrowser_PlayGameWith);
|
||||
connect(this->ui_Widget_RomBrowser, &Widget::RomBrowserWidget::EditGameSettings, this,
|
||||
&MainWindow::on_RomBrowser_EditGameSettings);
|
||||
connect(this->ui_Widget_RomBrowser, &Widget::RomBrowserWidget::EditGameInputSettings, this,
|
||||
&MainWindow::on_RomBrowser_EditGameInputSettings);
|
||||
connect(this->ui_Widget_RomBrowser, &Widget::RomBrowserWidget::Cheats, this,
|
||||
&MainWindow::on_RomBrowser_Cheats);
|
||||
connect(this->ui_Widget_RomBrowser, &Widget::RomBrowserWidget::ChangeRomDirectory, this,
|
||||
@@ -220,6 +226,15 @@ void MainWindow::configureUI(QApplication* app, bool showUI)
|
||||
this->statusBar()->setVisible(this->ui_ShowStatusbar);
|
||||
this->statusBar()->addPermanentWidget(this->ui_StatusBar_Label, 1);
|
||||
|
||||
// set toolbar position according to setting
|
||||
int toolbarAreaSetting = CoreSettingsGetIntValue(SettingsID::GUI_ToolbarArea);
|
||||
Qt::ToolBarArea toolbarArea = this->getToolbarAreaFromSettingArea(toolbarAreaSetting);
|
||||
if (this->toolBarArea(this->toolBar) != toolbarArea)
|
||||
{
|
||||
this->removeToolBar(this->toolBar);
|
||||
this->addToolBar(toolbarArea, this->toolBar);
|
||||
}
|
||||
|
||||
this->ui_TimerTimeout = CoreSettingsGetIntValue(SettingsID::GUI_StatusbarMessageDuration);
|
||||
|
||||
this->ui_Widgets->addWidget(this->ui_Widget_RomBrowser);
|
||||
@@ -745,6 +760,41 @@ QString MainWindow::getSaveStateSlotText(QAction* action, int slot)
|
||||
return saveStateSlotText;
|
||||
}
|
||||
|
||||
int MainWindow::getToolbarSettingAreaFromArea(Qt::ToolBarArea area)
|
||||
{
|
||||
switch (area)
|
||||
{
|
||||
case Qt::ToolBarArea::TopToolBarArea:
|
||||
return 0;
|
||||
case Qt::ToolBarArea::BottomToolBarArea:
|
||||
return 1;
|
||||
case Qt::ToolBarArea::LeftToolBarArea:
|
||||
return 2;
|
||||
case Qt::ToolBarArea::RightToolBarArea:
|
||||
return 3;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Qt::ToolBarArea MainWindow::getToolbarAreaFromSettingArea(int value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
return Qt::ToolBarArea::TopToolBarArea;
|
||||
case 1:
|
||||
return Qt::ToolBarArea::BottomToolBarArea;
|
||||
case 2:
|
||||
return Qt::ToolBarArea::LeftToolBarArea;
|
||||
case 3:
|
||||
return Qt::ToolBarArea::RightToolBarArea;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::configureActions(void)
|
||||
{
|
||||
// configure actions list
|
||||
@@ -1092,7 +1142,7 @@ void MainWindow::on_networkAccessManager_Finished(QNetworkReply* reply)
|
||||
|
||||
int ret = 0;
|
||||
|
||||
Dialog::UpdateDialog updateDialog(this, jsonObject);
|
||||
Dialog::UpdateDialog updateDialog(this, jsonObject, !this->ui_SilentUpdateCheck);
|
||||
ret = updateDialog.exec();
|
||||
if (ret != QDialog::Accepted)
|
||||
{
|
||||
@@ -1131,7 +1181,7 @@ void MainWindow::on_Action_System_OpenRom(void)
|
||||
|
||||
QString romFile;
|
||||
|
||||
romFile = QFileDialog::getOpenFileName(this, "", "", "N64 ROMs & Disks (*.n64 *.z64 *.v64 *.ndd *.d64 *.zip)");
|
||||
romFile = QFileDialog::getOpenFileName(this, "", "", "N64 ROMs & Disks (*.n64 *.z64 *.v64 *.ndd *.d64 *.zip *.7z)");
|
||||
|
||||
if (romFile.isEmpty())
|
||||
{
|
||||
@@ -1162,7 +1212,7 @@ void MainWindow::on_Action_System_OpenCombo(void)
|
||||
|
||||
QString cartRom, diskRom;
|
||||
|
||||
cartRom = QFileDialog::getOpenFileName(this, "", "", "N64 ROMs (*.n64 *.z64 *.v64 *.zip)");
|
||||
cartRom = QFileDialog::getOpenFileName(this, "", "", "N64 ROMs (*.n64 *.z64 *.v64 *.zip *.7z)");
|
||||
|
||||
if (cartRom.isEmpty())
|
||||
{
|
||||
@@ -1671,7 +1721,7 @@ void MainWindow::on_RomBrowser_PlayGameWith(CoreRomType type, QString file)
|
||||
}
|
||||
else
|
||||
{ // disk
|
||||
mainRom = QFileDialog::getOpenFileName(this, "", "", "N64 ROMs (*.n64 *.z64 *.v64 *.zip)");
|
||||
mainRom = QFileDialog::getOpenFileName(this, "", "", "N64 ROMs (*.n64 *.z64 *.v64 *.zip *.7z)");
|
||||
otherRom = file;
|
||||
}
|
||||
|
||||
@@ -1774,6 +1824,34 @@ void MainWindow::on_RomBrowser_EditGameSettings(QString file)
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_RomBrowser_EditGameInputSettings(QString file)
|
||||
{
|
||||
bool isRefreshingRomList = this->ui_Widget_RomBrowser->IsRefreshingRomList();
|
||||
if (isRefreshingRomList)
|
||||
{
|
||||
this->ui_Widget_RomBrowser->StopRefreshRomList();
|
||||
}
|
||||
|
||||
if (!CoreOpenRom(file.toStdU32String()))
|
||||
{
|
||||
this->showErrorMessage("CoreOpenRom() Failed", QString::fromStdString(CoreGetError()));
|
||||
return;
|
||||
}
|
||||
|
||||
CorePluginsOpenROMConfig(CorePluginType::Input);
|
||||
|
||||
if (!CoreCloseRom())
|
||||
{
|
||||
this->showErrorMessage("CoreCloseRom() Failed", QString::fromStdString(CoreGetError()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (isRefreshingRomList)
|
||||
{
|
||||
this->ui_Widget_RomBrowser->RefreshRomList();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_RomBrowser_Cheats(QString file)
|
||||
{
|
||||
bool isRefreshingRomList = this->ui_Widget_RomBrowser->IsRefreshingRomList();
|
||||
@@ -1910,7 +1988,24 @@ void MainWindow::on_VidExt_ResizeWindow(int width, int height)
|
||||
|
||||
if (!this->toolBar->isHidden())
|
||||
{
|
||||
height += this->toolBar->height();
|
||||
Qt::ToolBarArea area = this->toolBarArea(this->toolBar);
|
||||
|
||||
// dont resize when toolbar is floating
|
||||
if (this->toolBar->isFloating())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (area == Qt::ToolBarArea::TopToolBarArea ||
|
||||
area == Qt::ToolBarArea::BottomToolBarArea)
|
||||
{
|
||||
height += this->toolBar->height();
|
||||
}
|
||||
else if (area == Qt::ToolBarArea::LeftToolBarArea ||
|
||||
area == Qt::ToolBarArea::RightToolBarArea)
|
||||
{
|
||||
width += this->toolBar->width();
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->statusBar()->isHidden())
|
||||
|
||||
@@ -119,6 +119,9 @@ class MainWindow : public QMainWindow, private Ui::MainWindow
|
||||
QString getSaveStateSlotDateTimeText(QAction* action);
|
||||
QString getSaveStateSlotText(QAction* action, int slot);
|
||||
|
||||
int getToolbarSettingAreaFromArea(Qt::ToolBarArea area);
|
||||
Qt::ToolBarArea getToolbarAreaFromSettingArea(int value);
|
||||
|
||||
void configureActions(void);
|
||||
void connectActionSignals(void);
|
||||
void updateActions(bool inEmulation, bool isPaused);
|
||||
@@ -189,6 +192,7 @@ class MainWindow : public QMainWindow, private Ui::MainWindow
|
||||
void on_RomBrowser_ChangeRomDirectory(void);
|
||||
void on_RomBrowser_RomInformation(QString file);
|
||||
void on_RomBrowser_EditGameSettings(QString file);
|
||||
void on_RomBrowser_EditGameInputSettings(QString file);
|
||||
void on_RomBrowser_Cheats(QString file);
|
||||
|
||||
public slots:
|
||||
|
||||
@@ -162,11 +162,14 @@
|
||||
<string>toolBar</string>
|
||||
</property>
|
||||
<property name="movable">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextUnderIcon</enum>
|
||||
</property>
|
||||
<property name="floatable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <QLabel>
|
||||
#include <QHBoxLayout>
|
||||
#include <QTimerEvent>
|
||||
|
||||
using namespace UserInterface::Widget;
|
||||
|
||||
@@ -36,6 +37,12 @@ void RomBrowserLoadingWidget::SetWidgetIndex(int index)
|
||||
this->widgetIndex = index;
|
||||
}
|
||||
|
||||
void RomBrowserLoadingWidget::SetCurrentRomIndex(int index, int count)
|
||||
{
|
||||
this->romIndex = index;
|
||||
this->romCount = count;
|
||||
}
|
||||
|
||||
void RomBrowserLoadingWidget::on_RomBrowserWidget_currentChanged(int index)
|
||||
{
|
||||
// start timer when it isnt running
|
||||
@@ -45,6 +52,12 @@ void RomBrowserLoadingWidget::on_RomBrowserWidget_currentChanged(int index)
|
||||
{
|
||||
if (this->loadingLabelTimerId == -1)
|
||||
{
|
||||
this->dotCount = 0;
|
||||
this->romIndex = 0;
|
||||
this->romCount = 0;
|
||||
this->elapsedTimeSinceLoading.start();
|
||||
// reset loading text
|
||||
this->updateLoadingText();
|
||||
this->loadingLabelTimerId = this->startTimer(1000);
|
||||
}
|
||||
}
|
||||
@@ -52,20 +65,52 @@ void RomBrowserLoadingWidget::on_RomBrowserWidget_currentChanged(int index)
|
||||
{
|
||||
if (this->loadingLabelTimerId != -1)
|
||||
{
|
||||
this->elapsedTimeSinceLoading.invalidate();
|
||||
this->killTimer(this->loadingLabelTimerId);
|
||||
this->loadingLabelTimerId = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RomBrowserLoadingWidget::timerEvent(QTimerEvent *event)
|
||||
void RomBrowserLoadingWidget::updateLoadingText()
|
||||
{
|
||||
if (this->loadingLabel->text().size() >= 10)
|
||||
QString loadingText = "Loading";
|
||||
|
||||
if (this->elapsedTimeSinceLoading.isValid() &&
|
||||
this->elapsedTimeSinceLoading.elapsed() >= 5000)
|
||||
{
|
||||
this->loadingLabel->setText("Loading");
|
||||
QString romCountString = QString::number(this->romCount);
|
||||
|
||||
loadingText += " [";
|
||||
loadingText += QString::number(this->romIndex).rightJustified(romCountString.size(), '0', false);
|
||||
loadingText += "/";
|
||||
loadingText += romCountString;
|
||||
loadingText += "]";
|
||||
}
|
||||
|
||||
if (dotCount <= 3)
|
||||
{
|
||||
for (int i = 0; i < dotCount; i++)
|
||||
{
|
||||
loadingText += ".";
|
||||
}
|
||||
|
||||
dotCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->loadingLabel->setText(this->loadingLabel->text() + ".");
|
||||
dotCount = 1;
|
||||
}
|
||||
|
||||
this->loadingLabel->setText(loadingText);
|
||||
}
|
||||
|
||||
void RomBrowserLoadingWidget::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
if (event->timerId() != this->loadingLabelTimerId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this->updateLoadingText();
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
namespace UserInterface
|
||||
{
|
||||
@@ -26,6 +27,8 @@ public:
|
||||
|
||||
void SetWidgetIndex(int index);
|
||||
|
||||
void SetCurrentRomIndex(int index, int count);
|
||||
|
||||
public slots:
|
||||
void on_RomBrowserWidget_currentChanged(int index);
|
||||
|
||||
@@ -33,6 +36,13 @@ private:
|
||||
QLabel* loadingLabel;
|
||||
int loadingLabelTimerId = -1;
|
||||
int widgetIndex = -1;
|
||||
int romIndex = 0;
|
||||
int romCount = 0;
|
||||
int dotCount = 0;
|
||||
|
||||
QElapsedTimer elapsedTimeSinceLoading;
|
||||
|
||||
void updateLoadingText();
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
@@ -105,14 +105,31 @@ RomBrowserWidget::RomBrowserWidget(QWidget *parent) : QStackedWidget(parent)
|
||||
connect(this->listViewWidget, &Widget::RomBrowserListViewWidget::ZoomIn, this, &RomBrowserWidget::on_ZoomIn);
|
||||
connect(this->listViewWidget, &Widget::RomBrowserListViewWidget::ZoomOut, this, &RomBrowserWidget::on_ZoomOut);
|
||||
|
||||
// TODO
|
||||
// set up list view's columns
|
||||
QStringList labels;
|
||||
labels << "Name";
|
||||
labels << "Internal Name";
|
||||
labels << "MD5";
|
||||
labels << "Format";
|
||||
labels << "File Name";
|
||||
labels << "File Ext.";
|
||||
labels << "File Size";
|
||||
labels << "I.D.";
|
||||
labels << "Region";
|
||||
this->listViewModel->setColumnCount(labels.size());
|
||||
this->listViewModel->setHorizontalHeaderLabels(labels);
|
||||
|
||||
// set full names of list view's columns
|
||||
this->columnNames << labels.at(0);
|
||||
this->columnNames << labels.at(1);
|
||||
this->columnNames << labels.at(2);
|
||||
this->columnNames << "Game Format";
|
||||
this->columnNames << labels.at(4);
|
||||
this->columnNames << "File Extension";
|
||||
this->columnNames << labels.at(6);
|
||||
this->columnNames << "Game I.D.";
|
||||
this->columnNames << "Game Region";
|
||||
|
||||
// configure grid view widget
|
||||
this->gridViewWidget = new Widget::RomBrowserGridViewWidget(this);
|
||||
this->gridViewModel = new QStandardItemModel(this);
|
||||
@@ -151,7 +168,9 @@ RomBrowserWidget::RomBrowserWidget(QWidget *parent) : QStackedWidget(parent)
|
||||
this->action_ChangeRomDirectory = new QAction(this);
|
||||
this->action_RomInformation = new QAction(this);
|
||||
this->action_EditGameSettings = new QAction(this);
|
||||
this->action_EditGameInputSettings = new QAction(this);
|
||||
this->action_EditCheats = new QAction(this);
|
||||
this->action_ResetColumnSizes = new QAction(this);
|
||||
this->action_SetCoverImage = new QAction(this);
|
||||
this->action_RemoveCoverImage = new QAction(this);
|
||||
|
||||
@@ -167,10 +186,12 @@ RomBrowserWidget::RomBrowserWidget(QWidget *parent) : QStackedWidget(parent)
|
||||
this->action_ChangeRomDirectory->setText("Change ROM Directory...");
|
||||
this->action_RomInformation->setText("ROM Information");
|
||||
this->action_EditGameSettings->setText("Edit Game Settings");
|
||||
this->action_EditGameInputSettings->setText("Edit Game Input Settings");
|
||||
this->action_EditCheats->setText("Edit Cheats");
|
||||
this->action_ResetColumnSizes->setText("Reset Column Sizes");
|
||||
this->menu_Columns->menuAction()->setText("Show/Hide Columns");
|
||||
this->action_SetCoverImage->setText("Set Cover Image...");
|
||||
this->action_RemoveCoverImage->setText("Remove Cover Image");
|
||||
this->menu_Columns->menuAction()->setText("Show/Hide Columns");
|
||||
connect(this->action_PlayGame, &QAction::triggered, this, &RomBrowserWidget::on_Action_PlayGame);
|
||||
connect(this->action_PlayGameWith, &QAction::triggered, this, &RomBrowserWidget::on_Action_PlayGameWith);
|
||||
connect(this->action_RefreshRomList, &QAction::triggered, this, &RomBrowserWidget::on_Action_RefreshRomList);
|
||||
@@ -178,7 +199,9 @@ RomBrowserWidget::RomBrowserWidget(QWidget *parent) : QStackedWidget(parent)
|
||||
connect(this->action_ChangeRomDirectory, &QAction::triggered, this, &RomBrowserWidget::on_Action_ChangeRomDirectory);
|
||||
connect(this->action_RomInformation, &QAction::triggered, this, &RomBrowserWidget::on_Action_RomInformation);
|
||||
connect(this->action_EditGameSettings, &QAction::triggered, this, &RomBrowserWidget::on_Action_EditGameSettings);
|
||||
connect(this->action_EditGameInputSettings, &QAction::triggered, this, &RomBrowserWidget::on_Action_EditGameInputSettings);
|
||||
connect(this->action_EditCheats, &QAction::triggered, this, &RomBrowserWidget::on_Action_EditCheats);
|
||||
connect(this->action_ResetColumnSizes, &QAction::triggered, this, &RomBrowserWidget::on_Action_ResetColumnSizes);
|
||||
connect(this->action_SetCoverImage, &QAction::triggered, this, &RomBrowserWidget::on_Action_SetCoverImage);
|
||||
connect(this->action_RemoveCoverImage, &QAction::triggered, this, &RomBrowserWidget::on_Action_RemoveCoverImage);
|
||||
|
||||
@@ -194,11 +217,13 @@ RomBrowserWidget::RomBrowserWidget(QWidget *parent) : QStackedWidget(parent)
|
||||
this->contextMenu->addAction(this->action_RomInformation);
|
||||
this->contextMenu->addSeparator();
|
||||
this->contextMenu->addAction(this->action_EditGameSettings);
|
||||
this->contextMenu->addAction(this->action_EditGameInputSettings);
|
||||
this->contextMenu->addAction(this->action_EditCheats);
|
||||
this->contextMenu->addSeparator();
|
||||
this->contextMenu->addAction(this->action_ResetColumnSizes);
|
||||
this->contextMenu->addMenu(this->menu_Columns);
|
||||
this->contextMenu->addAction(this->action_SetCoverImage);
|
||||
this->contextMenu->addAction(this->action_RemoveCoverImage);
|
||||
this->contextMenu->addMenu(this->menu_Columns);
|
||||
|
||||
// configure current view widget
|
||||
int currentView = CoreSettingsGetIntValue(SettingsID::RomBrowser_ViewMode);
|
||||
@@ -464,12 +489,14 @@ void RomBrowserWidget::customContextMenuRequested(QPoint position)
|
||||
this->action_PlayGameWith->setEnabled(hasSelection);
|
||||
this->action_RomInformation->setEnabled(hasSelection);
|
||||
this->action_EditGameSettings->setEnabled(hasSelection);
|
||||
this->action_EditGameInputSettings->setEnabled(hasSelection && CorePluginsHasROMConfig(CorePluginType::Input));
|
||||
this->action_EditCheats->setEnabled(hasSelection);
|
||||
this->action_ResetColumnSizes->setVisible(view == this->listViewWidget);
|
||||
this->menu_Columns->menuAction()->setVisible(view == this->listViewWidget);
|
||||
this->action_SetCoverImage->setEnabled(hasSelection);
|
||||
this->action_SetCoverImage->setVisible(view == this->gridViewWidget);
|
||||
this->action_RemoveCoverImage->setEnabled(hasSelection && !data.coverFile.isEmpty());
|
||||
this->action_RemoveCoverImage->setVisible(view == this->gridViewWidget);
|
||||
this->menu_Columns->menuAction()->setVisible(view == this->listViewWidget);
|
||||
|
||||
if (hasSelection && data.type == CoreRomType::Disk)
|
||||
{ // disk selected
|
||||
@@ -480,6 +507,11 @@ void RomBrowserWidget::customContextMenuRequested(QPoint position)
|
||||
this->action_PlayGameWith->setText("Play Game with Disk");
|
||||
}
|
||||
|
||||
if (view == this->listViewWidget)
|
||||
{ // list view
|
||||
this->generateColumnsMenu();
|
||||
}
|
||||
|
||||
if (view == this->gridViewWidget)
|
||||
{ // grid view
|
||||
if (data.coverFile.isEmpty())
|
||||
@@ -492,11 +524,6 @@ void RomBrowserWidget::customContextMenuRequested(QPoint position)
|
||||
}
|
||||
}
|
||||
|
||||
if (view == this->listViewWidget)
|
||||
{ // list view
|
||||
this->generateColumnsMenu();
|
||||
}
|
||||
|
||||
this->contextMenu->popup(this->mapToGlobal(position));
|
||||
}
|
||||
|
||||
@@ -508,7 +535,7 @@ void RomBrowserWidget::generateColumnsMenu(void)
|
||||
{
|
||||
int column = this->listViewWidget->horizontalHeader()->logicalIndex(i);
|
||||
|
||||
this->action_ColumnsMenuEntry = menu_Columns->addAction(this->listViewModel->horizontalHeaderItem(column)->text());
|
||||
this->action_ColumnsMenuEntry = menu_Columns->addAction(this->columnNames.at(column));
|
||||
this->action_ColumnsMenuEntry->setCheckable(true);
|
||||
this->action_ColumnsMenuEntry->setChecked(!this->listViewWidget->horizontalHeader()->isSectionHidden(column));
|
||||
connect(this->action_ColumnsMenuEntry, &QAction::toggled, [this, column](bool checked)
|
||||
@@ -526,33 +553,42 @@ void RomBrowserWidget::on_listViewWidget_sortIndicatorChanged(int logicalIndex,
|
||||
|
||||
void RomBrowserWidget::on_listViewWidget_sectionResized(int logicalIndex, int oldWidth, int newWidth)
|
||||
{
|
||||
std::vector<int> columnVisibility = CoreSettingsGetIntListValue(SettingsID::RomBrowser_ColumnVisibility);
|
||||
std::vector<int> columnSizes = CoreSettingsGetIntListValue(SettingsID::RomBrowser_ColumnSizes);
|
||||
|
||||
if (newWidth == 0)
|
||||
if (!this->listViewWidget->horizontalHeader()->stretchLastSection())
|
||||
{
|
||||
columnVisibility.at(logicalIndex) = 0;
|
||||
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnVisibility, columnVisibility);
|
||||
columnSizes.at(logicalIndex) = newWidth;
|
||||
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnSizes, columnSizes);
|
||||
}
|
||||
else
|
||||
{
|
||||
columnVisibility.at(logicalIndex) = 1;
|
||||
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnVisibility, columnVisibility);
|
||||
std::vector<int> columnVisibility = CoreSettingsGetIntListValue(SettingsID::RomBrowser_ColumnVisibility);
|
||||
|
||||
int lastVisibleColumn = -1;
|
||||
for (int i = 0; i < this->listViewModel->columnCount(); i++)
|
||||
if (newWidth == 0)
|
||||
{
|
||||
int column = this->listViewWidget->horizontalHeader()->logicalIndex(i);
|
||||
if (!this->listViewWidget->horizontalHeader()->isSectionHidden(column))
|
||||
{
|
||||
lastVisibleColumn = column;
|
||||
}
|
||||
columnVisibility.at(logicalIndex) = 0;
|
||||
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnVisibility, columnVisibility);
|
||||
}
|
||||
|
||||
if (!this->listViewWidget->horizontalHeader()->stretchLastSection() || logicalIndex != lastVisibleColumn)
|
||||
else
|
||||
{
|
||||
columnSizes.at(logicalIndex) = newWidth;
|
||||
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnSizes, columnSizes);
|
||||
columnVisibility.at(logicalIndex) = 1;
|
||||
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnVisibility, columnVisibility);
|
||||
|
||||
int lastVisibleColumn = -1;
|
||||
for (int i = 0; i < this->listViewModel->columnCount(); i++)
|
||||
{
|
||||
int column = this->listViewWidget->horizontalHeader()->logicalIndex(i);
|
||||
if (!this->listViewWidget->horizontalHeader()->isSectionHidden(column))
|
||||
{
|
||||
lastVisibleColumn = column;
|
||||
}
|
||||
}
|
||||
|
||||
if (logicalIndex != lastVisibleColumn)
|
||||
{
|
||||
columnSizes.at(logicalIndex) = newWidth;
|
||||
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnSizes, columnSizes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -603,9 +639,12 @@ void RomBrowserWidget::on_ZoomOut(void)
|
||||
view->setIconSize(view->iconSize() - QSize(10, 10));
|
||||
}
|
||||
|
||||
void RomBrowserWidget::on_RomBrowserThread_RomFound(QString file, CoreRomType type, CoreRomHeader header, CoreRomSettings settings)
|
||||
void RomBrowserWidget::on_RomBrowserThread_RomFound(QString file, CoreRomType type, CoreRomHeader header, CoreRomSettings settings, int index, int count)
|
||||
{
|
||||
QString name;
|
||||
QString gameFormat;
|
||||
float fileSize;
|
||||
QString fileSizeString;
|
||||
QString coverFile;
|
||||
QIcon coverIcon;
|
||||
QVariant itemData;
|
||||
@@ -622,6 +661,24 @@ void RomBrowserWidget::on_RomBrowserThread_RomFound(QString file, CoreRomType ty
|
||||
name = QFileInfo(file).fileName();
|
||||
}
|
||||
|
||||
// generate game format to use in UI
|
||||
if (type == CoreRomType::Disk)
|
||||
{
|
||||
gameFormat = "Disk";
|
||||
}
|
||||
else
|
||||
{
|
||||
gameFormat = "Cartridge";
|
||||
}
|
||||
|
||||
// generate file size to use in UI
|
||||
fileSize = QFileInfo(file).size()/1048576.0;
|
||||
fileSizeString = (QString::number(fileSize, 'f', 2)).append(" MB");
|
||||
if (fileSizeString.size() == 7)
|
||||
{
|
||||
fileSizeString = fileSizeString.prepend(" ");
|
||||
}
|
||||
|
||||
// retrieve cover image
|
||||
coverIcon = this->getCurrentCover(file, header, settings, coverFile);
|
||||
modelData.coverFile = coverFile;
|
||||
@@ -645,6 +702,36 @@ void RomBrowserWidget::on_RomBrowserThread_RomFound(QString file, CoreRomType ty
|
||||
listViewItem3->setText(QString::fromStdString(settings.MD5));
|
||||
listViewItem3->setData(itemData);
|
||||
listViewRow.append(listViewItem3);
|
||||
// game format
|
||||
QStandardItem* listViewItem4 = new QStandardItem();
|
||||
listViewItem4->setText(gameFormat);
|
||||
listViewItem4->setData(itemData);
|
||||
listViewRow.append(listViewItem4);
|
||||
// file name
|
||||
QStandardItem* listViewItem5 = new QStandardItem();
|
||||
listViewItem5->setText(QFileInfo(file).completeBaseName());
|
||||
listViewItem5->setData(itemData);
|
||||
listViewRow.append(listViewItem5);
|
||||
// file extension
|
||||
QStandardItem* listViewItem6 = new QStandardItem();
|
||||
listViewItem6->setText(((QFileInfo(file).suffix()).prepend(".")).toUpper());
|
||||
listViewItem6->setData(itemData);
|
||||
listViewRow.append(listViewItem6);
|
||||
// file size
|
||||
QStandardItem* listViewItem7 = new QStandardItem();
|
||||
listViewItem7->setText(fileSizeString);
|
||||
listViewItem7->setData(itemData);
|
||||
listViewRow.append(listViewItem7);
|
||||
// game i.d.
|
||||
QStandardItem* listViewItem8 = new QStandardItem();
|
||||
listViewItem8->setText(QString::fromStdString(header.GameID));
|
||||
listViewItem8->setData(itemData);
|
||||
listViewRow.append(listViewItem8);
|
||||
// region
|
||||
QStandardItem* listViewItem9 = new QStandardItem();
|
||||
listViewItem9->setText(QString::fromStdString(header.Region));
|
||||
listViewItem9->setData(itemData);
|
||||
listViewRow.append(listViewItem9);
|
||||
this->listViewModel->appendRow(listViewRow);
|
||||
|
||||
QStandardItem* gridViewItem = new QStandardItem();
|
||||
@@ -652,6 +739,9 @@ void RomBrowserWidget::on_RomBrowserThread_RomFound(QString file, CoreRomType ty
|
||||
gridViewItem->setText(name);
|
||||
gridViewItem->setData(itemData);
|
||||
this->gridViewModel->appendRow(gridViewItem);
|
||||
|
||||
// update loading widget
|
||||
this->loadingWidget->SetCurrentRomIndex(index, count);
|
||||
}
|
||||
|
||||
void RomBrowserWidget::on_RomBrowserThread_Finished(bool canceled)
|
||||
@@ -664,34 +754,13 @@ void RomBrowserWidget::on_RomBrowserThread_Finished(bool canceled)
|
||||
}
|
||||
|
||||
// retrieve column settings
|
||||
std::vector<int> columnVisibility = CoreSettingsGetIntListValue(SettingsID::RomBrowser_ColumnVisibility);
|
||||
std::vector<int> columnOrder = CoreSettingsGetIntListValue(SettingsID::RomBrowser_ColumnOrder);
|
||||
std::vector<int> columnSizes = CoreSettingsGetIntListValue(SettingsID::RomBrowser_ColumnSizes);
|
||||
std::vector<int> columnOrder = CoreSettingsGetIntListValue(SettingsID::RomBrowser_ColumnOrder);
|
||||
std::vector<int> columnVisibility = CoreSettingsGetIntListValue(SettingsID::RomBrowser_ColumnVisibility);
|
||||
|
||||
// temporarily disable stretching last column in list view
|
||||
this->listViewWidget->horizontalHeader()->setStretchLastSection(false);
|
||||
|
||||
// reset column visibility setting in config file if number of values is incorrect
|
||||
if (!columnVisibility.empty() &&
|
||||
columnVisibility.size() != this->listViewModel->columnCount())
|
||||
{
|
||||
columnVisibility.clear();
|
||||
columnVisibility.resize(this->listViewModel->columnCount(), 1);
|
||||
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnVisibility, columnVisibility);
|
||||
}
|
||||
|
||||
// reset column order setting in config file if number of values is incorrect
|
||||
if (!columnOrder.empty() &&
|
||||
columnOrder.size() != this->listViewModel->columnCount())
|
||||
{
|
||||
columnOrder.clear();
|
||||
for (int i = 0; i < this->listViewModel->columnCount(); i++)
|
||||
{
|
||||
columnOrder.push_back(i);
|
||||
}
|
||||
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnOrder, columnOrder);
|
||||
}
|
||||
|
||||
// reset column sizes setting in config file if number of values is incorrect
|
||||
if (!columnSizes.empty() &&
|
||||
columnSizes.size() != this->listViewModel->columnCount())
|
||||
@@ -701,21 +770,6 @@ void RomBrowserWidget::on_RomBrowserThread_Finished(bool canceled)
|
||||
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnSizes, columnSizes);
|
||||
}
|
||||
|
||||
// update list view's column visibilities
|
||||
for (int i = 0; i < columnVisibility.size(); i++)
|
||||
{
|
||||
if (columnVisibility.at(i) == 0)
|
||||
{
|
||||
this->listViewWidget->horizontalHeader()->setSectionHidden(i, true);
|
||||
}
|
||||
}
|
||||
|
||||
// update list view's column order
|
||||
for (int i = 0; i < columnOrder.size(); i++)
|
||||
{
|
||||
this->listViewWidget->horizontalHeader()->moveSection(this->listViewWidget->horizontalHeader()->visualIndex(i), columnOrder.at(i));
|
||||
}
|
||||
|
||||
// update list view's column sizes
|
||||
for (int i = 0; i < columnSizes.size(); i++)
|
||||
{
|
||||
@@ -733,6 +787,46 @@ void RomBrowserWidget::on_RomBrowserThread_Finished(bool canceled)
|
||||
// enable stretching last column in list view
|
||||
this->listViewWidget->horizontalHeader()->setStretchLastSection(true);
|
||||
|
||||
// reset column order setting in config file if number of values is incorrect
|
||||
if (!columnOrder.empty() &&
|
||||
columnOrder.size() != this->listViewModel->columnCount())
|
||||
{
|
||||
columnOrder.clear();
|
||||
for (int i = 0; i < this->listViewModel->columnCount(); i++)
|
||||
{
|
||||
columnOrder.push_back(i);
|
||||
}
|
||||
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnOrder, columnOrder);
|
||||
}
|
||||
|
||||
// update list view's column order
|
||||
for (int i = 0; i < columnOrder.size(); i++)
|
||||
{
|
||||
this->listViewWidget->horizontalHeader()->moveSection(this->listViewWidget->horizontalHeader()->visualIndex(i), columnOrder.at(i));
|
||||
}
|
||||
|
||||
// reset column visibility setting in config file if number of values is incorrect
|
||||
if (!columnVisibility.empty() &&
|
||||
columnVisibility.size() != this->listViewModel->columnCount())
|
||||
{
|
||||
columnVisibility.clear();
|
||||
columnVisibility.resize(this->listViewModel->columnCount(), 0);
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
columnVisibility.at(i) = 1;
|
||||
}
|
||||
CoreSettingsSetValue(SettingsID::RomBrowser_ColumnVisibility, columnVisibility);
|
||||
}
|
||||
|
||||
// update list view's column visibilities
|
||||
for (int i = 0; i < columnVisibility.size(); i++)
|
||||
{
|
||||
if (columnVisibility.at(i) == 0)
|
||||
{
|
||||
this->listViewWidget->horizontalHeader()->setSectionHidden(i, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!canceled)
|
||||
{
|
||||
if (this->listViewModel->rowCount() == 0)
|
||||
@@ -803,11 +897,38 @@ void RomBrowserWidget::on_Action_EditGameSettings(void)
|
||||
emit this->EditGameSettings(this->getCurrentRom());
|
||||
}
|
||||
|
||||
void RomBrowserWidget::on_Action_EditGameInputSettings(void)
|
||||
{
|
||||
emit this->EditGameInputSettings(this->getCurrentRom());
|
||||
}
|
||||
|
||||
void RomBrowserWidget::on_Action_EditCheats(void)
|
||||
{
|
||||
emit this->Cheats(this->getCurrentRom());
|
||||
}
|
||||
|
||||
void RomBrowserWidget::on_Action_ResetColumnSizes(void)
|
||||
{
|
||||
std::vector<int> columnVisibility = CoreSettingsGetIntListValue(SettingsID::RomBrowser_ColumnVisibility);
|
||||
this->listViewWidget->horizontalHeader()->setStretchLastSection(false);
|
||||
|
||||
for (int i = 0; i < this->listViewModel->columnCount(); i++)
|
||||
{
|
||||
this->listViewWidget->horizontalHeader()->setSectionHidden(i, false);
|
||||
}
|
||||
|
||||
this->listViewWidget->resizeColumnsToContents();
|
||||
this->listViewWidget->horizontalHeader()->setStretchLastSection(true);
|
||||
|
||||
for (int i = 0; i < columnVisibility.size(); i++)
|
||||
{
|
||||
if (columnVisibility.at(i) == 0)
|
||||
{
|
||||
this->listViewWidget->horizontalHeader()->setSectionHidden(i, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RomBrowserWidget::on_Action_SetCoverImage(void)
|
||||
{
|
||||
QString sourceFile;
|
||||
|
||||
@@ -72,6 +72,8 @@ class RomBrowserWidget : public QStackedWidget
|
||||
int listViewSortSection = 0;
|
||||
int listViewSortOrder = 0;
|
||||
|
||||
QStringList columnNames;
|
||||
|
||||
QMenu* contextMenu;
|
||||
QAction* action_PlayGame;
|
||||
QAction* action_PlayGameWith;
|
||||
@@ -80,7 +82,9 @@ class RomBrowserWidget : public QStackedWidget
|
||||
QAction* action_ChangeRomDirectory;
|
||||
QAction* action_RomInformation;
|
||||
QAction* action_EditGameSettings;
|
||||
QAction* action_EditGameInputSettings;
|
||||
QAction* action_EditCheats;
|
||||
QAction* action_ResetColumnSizes;
|
||||
QAction* action_SetCoverImage;
|
||||
QAction* action_RemoveCoverImage;
|
||||
|
||||
@@ -115,7 +119,7 @@ class RomBrowserWidget : public QStackedWidget
|
||||
void on_ZoomIn(void);
|
||||
void on_ZoomOut(void);
|
||||
|
||||
void on_RomBrowserThread_RomFound(QString file, CoreRomType type, CoreRomHeader header, CoreRomSettings settings);
|
||||
void on_RomBrowserThread_RomFound(QString file, CoreRomType type, CoreRomHeader header, CoreRomSettings settings, int index, int count);
|
||||
void on_RomBrowserThread_Finished(bool canceled);
|
||||
|
||||
void on_Action_PlayGame(void);
|
||||
@@ -125,7 +129,9 @@ class RomBrowserWidget : public QStackedWidget
|
||||
void on_Action_ChangeRomDirectory(void);
|
||||
void on_Action_RomInformation(void);
|
||||
void on_Action_EditGameSettings(void);
|
||||
void on_Action_EditGameInputSettings(void);
|
||||
void on_Action_EditCheats(void);
|
||||
void on_Action_ResetColumnSizes(void);
|
||||
void on_Action_SetCoverImage(void);
|
||||
void on_Action_RemoveCoverImage(void);
|
||||
|
||||
@@ -133,6 +139,7 @@ class RomBrowserWidget : public QStackedWidget
|
||||
void PlayGame(QString);
|
||||
void PlayGameWith(CoreRomType, QString);
|
||||
void EditGameSettings(QString);
|
||||
void EditGameInputSettings(QString);
|
||||
void Cheats(QString);
|
||||
void ChangeRomDirectory(void);
|
||||
void RomInformation(QString);
|
||||
|
||||
+12
-1
@@ -94,6 +94,15 @@ int main(int argc, char **argv)
|
||||
setenv("QT_QPA_PLATFORM", "xcb", 1);
|
||||
#endif // FORCE_XCB
|
||||
|
||||
#ifndef _WIN32
|
||||
// ensure the default OpenGL format
|
||||
// doesn't have vsync enabled by default,
|
||||
// only needed for linux (for now)
|
||||
QSurfaceFormat format = QSurfaceFormat::defaultFormat();
|
||||
format.setSwapInterval(0);
|
||||
QSurfaceFormat::setDefaultFormat(format);
|
||||
#endif
|
||||
|
||||
QApplication app(argc, argv);
|
||||
|
||||
UserInterface::MainWindow window;
|
||||
@@ -167,7 +176,6 @@ int main(int argc, char **argv)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
window.show();
|
||||
|
||||
QStringList args = parser.positionalArguments();
|
||||
if (!args.empty())
|
||||
@@ -175,5 +183,8 @@ int main(int argc, char **argv)
|
||||
window.OpenROM(args.at(0), parser.value(diskOption), parser.isSet(fullscreenOption), parser.isSet(quitAfterEmulationOption));
|
||||
}
|
||||
|
||||
// show window
|
||||
window.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user