Compare commits
77 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d3280ff811 | |||
| cc8c1adaac | |||
| dd2b9bec13 | |||
| 34a29271a7 | |||
| d72c5196de | |||
| a08647ea88 | |||
| 549eca9158 | |||
| d7e72287dd | |||
| 2af19a57ca | |||
| 33d9edcbd7 | |||
| 3c52f25706 | |||
| 4e89dc5cb8 | |||
| e01521f8f1 | |||
| bcd84abb3a | |||
| 3e12c8c928 | |||
| ef50bd90b7 | |||
| c49352be17 | |||
| aa30a6b9b5 | |||
| cabfcc9f75 | |||
| 56e4206765 | |||
| d95677402b | |||
| cd26941059 | |||
| b09e73bc2b | |||
| a2b094131e | |||
| 09a7bf63d1 | |||
| 94651bab91 | |||
| 9b589c50e1 | |||
| f7f41d330d | |||
| 5d29531a20 | |||
| ba015b6698 | |||
| 30c31cab40 | |||
| 7e79aa0fff | |||
| 6b49544ac2 | |||
| 93c7ef1de8 | |||
| 98ab96db6a | |||
| c891528f1e | |||
| 2b11653a44 | |||
| c66a2f34bc | |||
| 8976401695 | |||
| 11f9d9d9a0 | |||
| 01ca2c66b6 | |||
| 919a5623e8 | |||
| 5a4f938502 | |||
| 8ca95bc89b | |||
| 2cb20cc209 | |||
| 6420a636d1 | |||
| a4111f2efa | |||
| 972e88b74f | |||
| d4adca5af8 | |||
| 8bc0c6ce67 | |||
| f2d89bd1c9 | |||
| a96bc6e748 | |||
| 0b38302556 | |||
| 7147dfa858 | |||
| 9702d048a4 | |||
| 1e1e8cc455 | |||
| e6b561e240 | |||
| b5cec10f97 | |||
| 74c4fff060 | |||
| f1b8401ecb | |||
| e9ebc5ecd0 | |||
| 8814d5a9a6 | |||
| 4a21907fee | |||
| be03f352dd | |||
| e7b0147eb4 | |||
| 4227469427 | |||
| 802fd2ca12 | |||
| b5990826df | |||
| e063e8745f | |||
| 25978727d8 | |||
| e4dc4fd1b5 | |||
| e1464d2d30 | |||
| 8350b7bfe7 | |||
| a15f6c85e3 | |||
| e01fed88ee | |||
| b66dbd7544 | |||
| d42f770e06 |
@@ -15,9 +15,10 @@ jobs:
|
||||
- name: Prepare Environment
|
||||
run: |
|
||||
echo "GIT_REVISION=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
||||
- name: Build RMG
|
||||
run: bash ./Source/Script/Build.sh Release
|
||||
- name: Upload RMG
|
||||
- name: Build RMG (Portable)
|
||||
run: ./Source/Script/Build.sh Release
|
||||
shell: bash
|
||||
- name: Upload RMG (Portable)
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: RMG-Portable-Linux64-${{ env.GIT_REVISION }}
|
||||
@@ -29,6 +30,7 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
path-type: inherit
|
||||
update: true
|
||||
install: >-
|
||||
make
|
||||
@@ -52,17 +54,17 @@ jobs:
|
||||
$env:revision = git rev-parse --short HEAD
|
||||
echo "GIT_REVISION=$env:revision" >> $env:GITHUB_ENV
|
||||
shell: pwsh
|
||||
- name: Build RMG
|
||||
- name: Build RMG (Portable)
|
||||
run: ./Source/Script/Build.sh Release
|
||||
shell: msys2 {0}
|
||||
- name: Create Installer
|
||||
run: .\Build\Release\Source\Installer\CreateInstaller.bat
|
||||
- name: Upload RMG
|
||||
- name: Upload RMG (Portable)
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: RMG-Portable-Windows64-${{ env.GIT_REVISION }}
|
||||
path: Bin/Release/*
|
||||
- name: Upload Installer
|
||||
- name: Upload RMG (Installer)
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: RMG-Setup-Windows64-${{ env.GIT_REVISION }}
|
||||
|
||||
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
@@ -3,6 +3,9 @@
|
||||
#
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
option(PORTABLE_INSTALL "Portable Installation" ON)
|
||||
option(NO_GIT_CLONE "Disables git clone usage for 3rdParty dependencies" OFF)
|
||||
|
||||
project(RMG)
|
||||
|
||||
find_package(Git REQUIRED)
|
||||
@@ -14,13 +17,48 @@ execute_process(
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
set(CMAKE_INSTALL_PREFIX "")
|
||||
set(INSTALL_PATH Bin/${CMAKE_BUILD_TYPE})
|
||||
if (FLATPAK_BUILD AND (WIN32 OR MSYS))
|
||||
message(ERROR "FLATPAK_BUILD is not supported on windows, disabling FLATPAK_BUILD!")
|
||||
set(FLATPAK_BUILD OFF)
|
||||
endif()
|
||||
|
||||
if(FLATPAK_BUILD)
|
||||
set(NO_GIT_CLONE ON)
|
||||
set(PORTABLE_INSTALL OFF)
|
||||
endif(FLATPAK_BUILD)
|
||||
|
||||
if (NOT PORTABLE_INSTALL AND (WIN32 OR MSYS))
|
||||
message(WARNING "Not-Portable build not supported on windows, re-enabling PORTABLE_INSTALL!")
|
||||
set(PORTABLE_INSTALL ON)
|
||||
endif()
|
||||
|
||||
if (PORTABLE_INSTALL)
|
||||
set(CMAKE_INSTALL_PREFIX "")
|
||||
set(INSTALL_PATH "Bin/${CMAKE_BUILD_TYPE}")
|
||||
set(RMG_INSTALL_PATH "${INSTALL_PATH}")
|
||||
set(CORE_INSTALL_PATH "${INSTALL_PATH}/Core")
|
||||
set(PLUGIN_INSTALL_PATH "${INSTALL_PATH}/Plugin")
|
||||
set(DATA_INSTALL_PATH "${INSTALL_PATH}/Data")
|
||||
set(INSTALL_DESKTOP_FILE OFF)
|
||||
else()
|
||||
set(RMG_INSTALL_PATH "bin")
|
||||
set(CORE_INSTALL_PATH "lib/RMG/Core")
|
||||
set(PLUGIN_INSTALL_PATH "lib/RMG/Plugin")
|
||||
set(DATA_INSTALL_PATH "share/RMG")
|
||||
set(INSTALL_DESKTOP_FILE ON)
|
||||
set(APPDATA_INSTALL_PATH "share/metainfo/")
|
||||
set(DESKTOP_INSTALL_PATH "share/applications")
|
||||
set(ICON_INSTALL_PATH "share/icons/hicolor/scalable/apps/")
|
||||
endif()
|
||||
|
||||
add_subdirectory(Source/RMG-Core)
|
||||
add_subdirectory(Source/RMG)
|
||||
add_subdirectory(Source/RMG-Audio)
|
||||
install(TARGETS RMG
|
||||
DESTINATION ${INSTALL_PATH}
|
||||
DESTINATION ${RMG_INSTALL_PATH}
|
||||
)
|
||||
install(TARGETS RMG-Audio
|
||||
DESTINATION ${PLUGIN_INSTALL_PATH}/Audio
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
@@ -33,23 +71,41 @@ endif()
|
||||
|
||||
add_subdirectory(Source/3rdParty)
|
||||
install(FILES ${MUPEN64PLUSCORE_LIB}
|
||||
DESTINATION ${INSTALL_PATH}/Core
|
||||
DESTINATION ${CORE_INSTALL_PATH}
|
||||
)
|
||||
install(FILES ${MUPEN64PLUSCORE_INI} ${MUPEN64PLUSCORE_CHT} Data/font.ttf
|
||||
DESTINATION ${INSTALL_PATH}/Data
|
||||
install(FILES ${MUPEN64PLUSCORE_INI} ${MUPEN64PLUSCORE_CHT} Data/font.ttf Data/stylesheet.qss
|
||||
DESTINATION ${DATA_INSTALL_PATH}
|
||||
)
|
||||
install(FILES Config/stylesheet.qss
|
||||
DESTINATION ${INSTALL_PATH}/Config
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_RSP_HLE}
|
||||
DESTINATION ${PLUGIN_INSTALL_PATH}/RSP
|
||||
)
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_AUDIO}
|
||||
DESTINATION ${INSTALL_PATH}/Plugin/Audio
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_RSP_PARALLEL}
|
||||
DESTINATION ${PLUGIN_INSTALL_PATH}/RSP
|
||||
)
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_RSP}
|
||||
DESTINATION ${INSTALL_PATH}/Plugin/RSP
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_INPUT_QT}
|
||||
DESTINATION ${PLUGIN_INSTALL_PATH}/Input
|
||||
)
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_INPUT}
|
||||
DESTINATION ${INSTALL_PATH}/Plugin/Input
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_INPUT_RAPHNET}
|
||||
DESTINATION ${PLUGIN_INSTALL_PATH}/Input
|
||||
)
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_GFX}
|
||||
DESTINATION ${INSTALL_PATH}/Plugin/GFX
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_INPUT_GCA}
|
||||
DESTINATION ${PLUGIN_INSTALL_PATH}/Input
|
||||
)
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_GFX_GLIDEN64}
|
||||
DESTINATION ${PLUGIN_INSTALL_PATH}/GFX
|
||||
)
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_GFX_PARALLEL}
|
||||
DESTINATION ${PLUGIN_INSTALL_PATH}/GFX
|
||||
)
|
||||
|
||||
if (INSTALL_DESKTOP_FILE)
|
||||
install(FILES Package/com.github.Rosalie241.RMG.desktop
|
||||
DESTINATION ${DESKTOP_INSTALL_PATH}
|
||||
)
|
||||
install(FILES Package/com.github.Rosalie241.RMG.svg
|
||||
DESTINATION ${ICON_INSTALL_PATH}
|
||||
)
|
||||
install(FILES Package/com.github.Rosalie241.RMG.appdata.xml
|
||||
DESTINATION ${APPDATA_INSTALL_PATH}
|
||||
)
|
||||
endif(INSTALL_DESKTOP_FILE)
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# Maintainer: Rosalie Wanders <rosalie@mailbox.org>
|
||||
_pkgname=rmg
|
||||
pkgname=${_pkgname}-git
|
||||
pkgver=git
|
||||
pkgrel=1
|
||||
pkgdesc="Rosalie's Mupen GUI"
|
||||
arch=('x86_64')
|
||||
url="https://github.com/Rosalie241/${_pkgname}"
|
||||
license=('GPLv3')
|
||||
|
||||
provides=("$_pkgname")
|
||||
conflicts=("$_pkgname")
|
||||
|
||||
depends=("hidapi" "libsamplerate" "minizip" "sdl2" "zlib" "freetype2" "qt5-base" "qt5-svg")
|
||||
makedepends=("git" "pkg-config" "nasm" "cmake" "rustup")
|
||||
|
||||
source=("git+https://github.com/Rosalie241/${_pkgname}.git")
|
||||
sha256sums=('SKIP')
|
||||
|
||||
pkgver()
|
||||
{
|
||||
cd "$_pkgname"
|
||||
|
||||
git describe --tags --always | sed -e 's|^v||;s|-|.|g'
|
||||
}
|
||||
|
||||
prepare()
|
||||
{
|
||||
cd "$srcdir/${_pkgname}"
|
||||
|
||||
mkdir -p build
|
||||
}
|
||||
|
||||
build()
|
||||
{
|
||||
cd "$srcdir/${_pkgname}/build"
|
||||
|
||||
cmake -S "$srcdir/${_pkgname}" -B "$srcdir/${_pkgname}/build" \
|
||||
-DCMAKE_BUILD_TYPE="Release" \
|
||||
-DPORTABLE_INSTALL="OFF" \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-G "Unix Makefiles"
|
||||
make
|
||||
}
|
||||
|
||||
package()
|
||||
{
|
||||
cd "$srcdir/${_pkgname}/build"
|
||||
|
||||
make install DESTDIR="$pkgdir"
|
||||
}
|
||||
|
After Width: | Height: | Size: 206 KiB |
|
After Width: | Height: | Size: 119 KiB |
|
After Width: | Height: | Size: 52 KiB |
@@ -0,0 +1,54 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<component type="desktop">
|
||||
<!--Created with jdAppdataEdit 2.1-->
|
||||
<id>com.github.Rosalie241.RMG</id>
|
||||
<name>Rosalie's Mupen GUI</name>
|
||||
<summary>An easy to use & cross-platform mupen64plus front-end written in C++ & Qt</summary>
|
||||
<developer_name>Rosalie</developer_name>
|
||||
<launchable type="desktop-id">com.github.Rosalie241.RMG.desktop</launchable>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-3.0-only</project_license>
|
||||
<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>
|
||||
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/RomBrowser.png</image>
|
||||
</screenshot>
|
||||
<screenshot type="default">
|
||||
<caption>During A Game</caption>
|
||||
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/InGame.png</image>
|
||||
</screenshot>
|
||||
<screenshot type="default">
|
||||
<caption>Settings</caption>
|
||||
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/Settings.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<description/>
|
||||
<releases>
|
||||
<release version="v0.1.2" date="2022-01-21" type="stable"/>
|
||||
<release version="v0.1.1" date="2022-01-19" type="stable"/>
|
||||
<release version="v0.1.0" date="2022-01-07" type="stable"/>
|
||||
<release version="v0.0.9" date="2021-12-25" type="stable"/>
|
||||
<release version="v0.0.8" date="2021-12-24" type="stable"/>
|
||||
<release version="v0.0.7" date="2021-12-23" type="stable"/>
|
||||
<release version="v0.0.6" date="2021-10-18" type="stable"/>
|
||||
<release version="v0.0.5" date="2021-10-17" type="stable"/>
|
||||
<release version="v0.0.4" date="2021-10-06" type="stable"/>
|
||||
<release version="v0.0.3" date="2021-10-04" type="stable"/>
|
||||
<release version="v0.0.2" date="2021-09-26" type="stable"/>
|
||||
</releases>
|
||||
<url type="homepage">https://github.com/Rosalie241/RMG</url>
|
||||
<url type="bugtracker">https://github.com/Rosalie241/RMG/issues</url>
|
||||
<categories>
|
||||
<category>Game</category>
|
||||
</categories>
|
||||
<recommends>
|
||||
<control>pointing</control>
|
||||
<control>keyboard</control>
|
||||
</recommends>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<keywords>
|
||||
<keyword>mupen64plus</keyword>
|
||||
<keyword>RMG</keyword>
|
||||
</keywords>
|
||||
</component>
|
||||
@@ -0,0 +1,8 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Rosalie's Mupen GUI
|
||||
Comment=An easy to use & cross-platform mupen64plus front-end written in C++ & Qt
|
||||
Exec=RMG
|
||||
Icon=com.github.Rosalie241.RMG
|
||||
Terminal=false
|
||||
Categories=Game;
|
||||
|
After Width: | Height: | Size: 54 KiB |
@@ -18,18 +18,21 @@ It offers a simple-to-use user interface.
|
||||
## Building
|
||||
|
||||
#### Linux
|
||||
**NOTE:** installation is **not** supported on linux at the moment, only running it portable will work
|
||||
* Portable
|
||||
```
|
||||
# for debian based distros
|
||||
sudo apt-get -y install cmake libhidapi-dev libsamplerate0-dev libminizip-dev libsdl2-dev libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev pkg-config zlib1g-dev binutils-dev libspeexdsp-dev qt5-default build-essential nasm git zip
|
||||
# for arch based distros
|
||||
sudo pacman -S base-devel git hidapi libsamplerate minizip sdl2 freetype2 pkg-config zlib qt5 nasm
|
||||
# building
|
||||
./Source/Script/Build.sh Release
|
||||
```
|
||||
|
||||
When it's done building, executables can be found in `Bin/Release`
|
||||
|
||||
* Installation/Packaging
|
||||
```
|
||||
mkdir build && cd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE="Release" -DPORTABLE_INSTALL="OFF" -G "Unix Makefiles"
|
||||
make install
|
||||
```
|
||||
|
||||
#### Windows
|
||||
* Download & Install [MSYS2](https://www.msys2.org/)
|
||||
```
|
||||
|
||||
@@ -5,23 +5,60 @@ 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 "0")
|
||||
else()
|
||||
# disabled because build failure
|
||||
set(BUILD_INPUT_GCA "0")
|
||||
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)
|
||||
|
||||
if(NOT NO_GIT_CLONE)
|
||||
set(MUPEN64PLUSCORE_URL "https://github.com/mupen64plus/mupen64plus-core")
|
||||
set(MUPEN64PLUSCORE_TAG "57828d930280554c7400bb2bcf1e46c7f2ee8373")
|
||||
|
||||
set(MUPEN64PLUS_RSP_HLE_URL "https://github.com/mupen64plus/mupen64plus-rsp-hle")
|
||||
set(MUPEN64PLUS_RSP_HLE_TAG "88093cb43499eff53d343653cddcae2132af17ef")
|
||||
|
||||
set(MUPEN64PLUS_RSP_PARALLEL_URL "https://github.com/loganmc10/parallel-rsp")
|
||||
set(MUPEN64PLUS_RSP_PARALLEL_TAG "a9646b27c2ef399e5917735b4d84ebe93edcce39")
|
||||
|
||||
set(MUPEN64PLUS_INPUT_QT_URL "https://github.com/Rosalie241/mupen64plus-input-qt")
|
||||
set(MUPEN64PLUS_INPUT_QT_TAG "e6cacb7fe6513cac4b30f7171d8ca7d1cd5fdb81")
|
||||
|
||||
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 "d440611d3639fa974c7d52bd0ed2079d16428d5e")
|
||||
|
||||
set(MUPEN64PLUS_GFX_GLIDEN64_URL "https://github.com/gonetz/GLideN64")
|
||||
set(MUPEN64PLUS_GFX_GLIDEN64_TAG "8343fd05c9a01ce2d73f7e32bb8355036759a05b")
|
||||
|
||||
set(MUPEN64PLUS_GFX_PARALLEL_URL "https://github.com/loganmc10/parallel-rdp-standalone")
|
||||
set(MUPEN64PLUS_GFX_PARALLEL_TAG "2efeaf014bad03ec26e081c22d8ca3566003b1ea")
|
||||
endif(NOT NO_GIT_CLONE)
|
||||
|
||||
ExternalProject_Add(mupen64plus-core
|
||||
SOURCE_DIR mupen64plus-core/
|
||||
|
||||
CONFIGURE_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
GIT_REPOSITORY https://github.com/mupen64plus/mupen64plus-core
|
||||
GIT_TAG 57828d930280554c7400bb2bcf1e46c7f2ee8373
|
||||
GIT_REPOSITORY ${MUPEN64PLUSCORE_URL}
|
||||
GIT_TAG ${MUPEN64PLUSCORE_TAG}
|
||||
|
||||
BUILD_COMMAND make all OSD=0 NEW_DYNAREC=1 TARGET=${CORE_FILE} DEBUG=$<CONFIG:Debug> KEYBINDINGS=0
|
||||
BUILD_IN_SOURCE False
|
||||
@@ -33,32 +70,14 @@ ExternalProject_Add(mupen64plus-core
|
||||
|
||||
set(APIDIR "${CMAKE_BINARY_DIR}/Source/3rdParty/mupen64plus-core/src/api")
|
||||
|
||||
ExternalProject_Add(mupen64plus-audio-sdl
|
||||
SOURCE_DIR mupen64plus-audio-sdl2/
|
||||
|
||||
CONFIGURE_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
GIT_REPOSITORY https://github.com/Rosalie241/mupen64plus-audio-sdl2
|
||||
GIT_TAG cc6aca5a13b0b8ca7a2f9f5fa472ed3bb7f817db
|
||||
|
||||
BUILD_COMMAND make all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug>
|
||||
BUILD_IN_SOURCE False
|
||||
|
||||
BINARY_DIR ${THIRDPARTY_DIR}/mupen64plus-audio-sdl2/projects/unix
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-audio-sdl2/projects/unix/mupen64plus-audio-sdl2.${SO_EXT}
|
||||
DEPENDS mupen64plus-core
|
||||
)
|
||||
|
||||
ExternalProject_Add(mupen64plus-rsp-hle
|
||||
SOURCE_DIR mupen64plus-rsp-hle/
|
||||
|
||||
CONFIGURE_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
GIT_REPOSITORY https://github.com/mupen64plus/mupen64plus-rsp-hle
|
||||
GIT_TAG 88093cb43499eff53d343653cddcae2132af17ef
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_RSP_HLE_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_RSP_HLE_TAG}
|
||||
|
||||
BUILD_COMMAND make all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug>
|
||||
BUILD_IN_SOURCE False
|
||||
@@ -69,14 +88,29 @@ ExternalProject_Add(mupen64plus-rsp-hle
|
||||
DEPENDS mupen64plus-core
|
||||
)
|
||||
|
||||
ExternalProject_Add(mupen64plus-rsp-parallel
|
||||
SOURCE_DIR mupen64plus-rsp-parallel
|
||||
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_RSP_PARALLEL_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_RSP_PARALLEL_TAG}
|
||||
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
BUILD_IN_SOURCE True
|
||||
CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-rsp-parallel/mupen64plus-rsp-parallel.${SO_EXT}
|
||||
DEPENDS mupen64plus-core
|
||||
)
|
||||
|
||||
ExternalProject_Add(mupen64plus-input-qt
|
||||
SOURCE_DIR mupen64plus-input-qt
|
||||
|
||||
CMAKE_ARGS -DAPIDIR=${APIDIR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
GIT_REPOSITORY https://github.com/Rosalie241/mupen64plus-input-qt
|
||||
GIT_TAG e6cacb7fe6513cac4b30f7171d8ca7d1cd5fdb81
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_INPUT_QT_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_INPUT_QT_TAG}
|
||||
|
||||
BUILD_COMMAND make all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug>
|
||||
BUILD_IN_SOURCE True
|
||||
@@ -85,6 +119,42 @@ ExternalProject_Add(mupen64plus-input-qt
|
||||
DEPENDS mupen64plus-core
|
||||
)
|
||||
|
||||
ExternalProject_Add(mupen64plus-input-raphnetraw
|
||||
SOURCE_DIR mupen64plus-input-raphnetraw/
|
||||
|
||||
CONFIGURE_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_INPUT_RAPHNET_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_INPUT_RAPHNET_TAG}
|
||||
|
||||
BUILD_COMMAND make all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug>
|
||||
BUILD_IN_SOURCE False
|
||||
|
||||
BINARY_DIR ${THIRDPARTY_DIR}/mupen64plus-input-raphnetraw/projects/unix
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-input-raphnetraw/projects/unix/mupen64plus-input-raphnetraw.${SO_EXT}
|
||||
DEPENDS mupen64plus-core
|
||||
)
|
||||
|
||||
if (${BUILD_INPUT_GCA} STREQUAL "1")
|
||||
ExternalProject_Add(mupen64plus-input-gca
|
||||
SOURCE_DIR mupen64plus-input-gca/
|
||||
|
||||
CONFIGURE_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_INPUT_GCA_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_INPUT_GCA_TAG}
|
||||
|
||||
BUILD_COMMAND cargo build --release
|
||||
BUILD_IN_SOURCE True
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-input-gca/target/release/${GCA_LIB}
|
||||
DEPENDS mupen64plus-core
|
||||
)
|
||||
endif()
|
||||
|
||||
set(GLIDEN64_DIR "${THIRDPARTY_DIR}/mupen64plus-video-GLideN64")
|
||||
set(GLIDEN64_BUILD_DIR "${GLIDEN64_DIR}/projects/cmake")
|
||||
if (MSYS)
|
||||
@@ -101,13 +171,13 @@ endforeach()
|
||||
ExternalProject_Add(mupen64plus-video-GLideN64
|
||||
SOURCE_DIR mupen64plus-video-GLideN64
|
||||
|
||||
GIT_REPOSITORY https://github.com/gonetz/GLideN64
|
||||
GIT_TAG 8343fd05c9a01ce2d73f7e32bb8355036759a05b
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_GFX_GLIDEN64_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_GFX_GLIDEN64_TAG}
|
||||
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
BUILD_IN_SOURCE False
|
||||
CMAKE_ARGS -DMUPENPLUSAPI=1 -DMUPENPLUSAPI_GLIDENUI=1 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -Wno-dev
|
||||
CMAKE_ARGS -DMUPENPLUSAPI=1 -DMUPENPLUSAPI_GLIDENUI=1 -DUSE_SYSTEM_LIBS=ON -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
|
||||
SOURCE_SUBDIR ./src/
|
||||
BINARY_DIR ${GLIDEN64_BUILD_DIR}
|
||||
@@ -117,19 +187,45 @@ ExternalProject_Add(mupen64plus-video-GLideN64
|
||||
BUILD_BYPRODUCTS ${GLIDENUI_TRANSLATIONS}
|
||||
)
|
||||
|
||||
ExternalProject_Add(mupen64plus-video-parallel
|
||||
SOURCE_DIR mupen64plus-video-parallel
|
||||
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_GFX_PARALLEL_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_GFX_PARALLEL_TAG}
|
||||
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
BUILD_IN_SOURCE True
|
||||
CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-video-parallel/mupen64plus-video-parallel.${SO_EXT}
|
||||
DEPENDS mupen64plus-core
|
||||
)
|
||||
|
||||
ExternalProject_Get_property(mupen64plus-core BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUSCORE_LIB ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
set(MUPEN64PLUSCORE_INI ${M64P_CORE_DIR}/data/mupen64plus.ini PARENT_SCOPE)
|
||||
set(MUPEN64PLUSCORE_CHT ${M64P_CORE_DIR}/data/mupencheat.txt PARENT_SCOPE)
|
||||
|
||||
ExternalProject_Get_property(mupen64plus-audio-sdl BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_AUDIO ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
|
||||
ExternalProject_Get_property(mupen64plus-rsp-hle BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_RSP ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
set(MUPEN64PLUS_PLUGIN_RSP_HLE ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
|
||||
ExternalProject_Get_property(mupen64plus-rsp-parallel BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_RSP_PARALLEL ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
|
||||
ExternalProject_Get_property(mupen64plus-input-qt BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_INPUT ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
set(MUPEN64PLUS_PLUGIN_INPUT_QT ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
|
||||
ExternalProject_Get_property(mupen64plus-input-raphnetraw BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_INPUT_RAPHNET ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
|
||||
if (${BUILD_INPUT_GCA} STREQUAL "1")
|
||||
ExternalProject_Get_property(mupen64plus-input-gca BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_INPUT_GCA ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
ExternalProject_Get_property(mupen64plus-video-GLideN64 BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_GFX ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
set(MUPEN64PLUS_PLUGIN_GFX_GLIDEN64 ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
|
||||
ExternalProject_Get_property(mupen64plus-video-parallel BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_GFX_PARALLEL ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# RMG-Audio CMakeLists.txt
|
||||
#
|
||||
project(RMG-Audio)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
|
||||
find_package(Qt5 COMPONENTS Gui Widgets Core REQUIRED)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(SDL2 REQUIRED sdl2)
|
||||
|
||||
set(RMG_AUDIO_SOURCES
|
||||
UserInterface/MainDialog.cpp
|
||||
UserInterface/MainDialog.ui
|
||||
UserInterface/UIResources.qrc
|
||||
main.cpp
|
||||
)
|
||||
|
||||
add_library(RMG-Audio SHARED ${RMG_AUDIO_SOURCES})
|
||||
|
||||
set_target_properties(RMG-Audio PROPERTIES PREFIX "")
|
||||
|
||||
target_link_libraries(RMG-Audio
|
||||
RMG-Core
|
||||
${SDL2_LIBRARIES}
|
||||
Qt5::Gui Qt5::Widgets
|
||||
)
|
||||
|
||||
target_include_directories(RMG-Audio PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${SDL2_INCLUDE_DIRS}
|
||||
)
|
||||
@@ -0,0 +1,2 @@
|
||||
# Rosalie's Mupen GUI - Audio Plugin
|
||||
This is a simple SDL2 audio plugin, based on https://github.com/m64p/mupen64plus-audio-sdl2
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "MainDialog.hpp"
|
||||
#include <RMG-Core/Core.hpp>
|
||||
|
||||
using namespace UserInterface;
|
||||
|
||||
MainDialog::MainDialog(QWidget* parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
|
||||
{
|
||||
this->setupUi(this);
|
||||
this->setWindowIcon(QIcon(":Resource/RMG.png"));
|
||||
this->volumeSlider->setValue(CoreSettingsGetIntValue(SettingsID::Audio_Volume));
|
||||
this->mutedCheckbox->setChecked(CoreSettingsGetBoolValue(SettingsID::Audio_Muted));
|
||||
}
|
||||
|
||||
MainDialog::~MainDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void MainDialog::on_volumeSlider_valueChanged(int value)
|
||||
{
|
||||
this->volumeLabel->setText(QString::number(value) + "%");
|
||||
}
|
||||
|
||||
void MainDialog::on_buttonBox_clicked(QAbstractButton* button)
|
||||
{
|
||||
QPushButton *pushButton = (QPushButton *)button;
|
||||
QPushButton *okButton = this->buttonBox->button(QDialogButtonBox::Ok);
|
||||
|
||||
int volume = this->volumeSlider->value();
|
||||
bool muted = this->mutedCheckbox->isChecked();
|
||||
|
||||
if (pushButton == okButton)
|
||||
{
|
||||
CoreSettingsSetValue(SettingsID::Audio_Volume, volume);
|
||||
CoreSettingsSetValue(SettingsID::Audio_Muted, muted);
|
||||
CoreSettingsSave();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef MAINWINDOW_HPP
|
||||
#define MAINWINDOW_HPP
|
||||
|
||||
#include <QDialog>
|
||||
#include <QAbstractButton>
|
||||
|
||||
#include "ui_MainDialog.h"
|
||||
|
||||
namespace UserInterface
|
||||
{
|
||||
class MainDialog : public QDialog, private Ui::MainDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainDialog(QWidget *parent);
|
||||
~MainDialog(void);
|
||||
|
||||
private slots:
|
||||
void on_volumeSlider_valueChanged(int value);
|
||||
void on_buttonBox_clicked(QAbstractButton* button);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MAINWINDOW_HPP
|
||||
@@ -0,0 +1,131 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainDialog</class>
|
||||
<widget class="QDialog" name="MainDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>330</width>
|
||||
<height>476</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Rosalie's Mupen GUI - Audio Plugin</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QSlider" name="volumeSlider">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QLabel" name="volumeLabel">
|
||||
<property name="text">
|
||||
<string>0%</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="mutedCheckbox">
|
||||
<property name="text">
|
||||
<string>Muted</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>MainDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>MainDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
|
After Width: | Height: | Size: 48 KiB |
@@ -0,0 +1,5 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file>Resource/RMG.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#define CORE_PLUGIN 1
|
||||
#define M64P_PLUGIN_PROTOTYPES 1
|
||||
#define AUDIO_PLUGIN_API_VERSION 0x020100
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_audio.h>
|
||||
|
||||
#include <UserInterface/MainDialog.hpp>
|
||||
|
||||
#include <RMG-Core/Core.hpp>
|
||||
|
||||
//
|
||||
// Local variables
|
||||
//
|
||||
|
||||
static SDL_AudioDeviceID l_SDLDevice;
|
||||
static SDL_AudioSpec* l_HardwareSpec = nullptr;
|
||||
|
||||
static bool l_PluginInit = false;
|
||||
static int l_GameFreq = 0;
|
||||
static AUDIO_INFO l_AudioInfo;
|
||||
static bool l_VolIsMuted = false;
|
||||
static bool l_Paused = false;
|
||||
static bool l_FastForward = false;
|
||||
static int l_VolSDL = SDL_MIX_MAXVOLUME;
|
||||
static SDL_AudioStream* l_AudioStream = nullptr;
|
||||
|
||||
static uint8_t l_PrimaryBuffer[0x40000];
|
||||
static uint8_t l_OutputBuffer[0x40000];
|
||||
static uint8_t l_MixBuffer[0x40000];
|
||||
|
||||
//
|
||||
// Local Functions
|
||||
//
|
||||
|
||||
static void load_settings(void)
|
||||
{
|
||||
l_VolIsMuted = CoreSettingsGetBoolValue(SettingsID::Audio_Muted);
|
||||
l_VolSDL = SDL_MIX_MAXVOLUME * CoreSettingsGetIntValue(SettingsID::Audio_Volume) / 100;
|
||||
l_FastForward = false;
|
||||
}
|
||||
|
||||
//
|
||||
// Basic Plugin Functions
|
||||
//
|
||||
|
||||
EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, void (*DebugCallback)(void *, int, const char *))
|
||||
{
|
||||
if (l_PluginInit)
|
||||
{
|
||||
return M64ERR_ALREADY_INIT;
|
||||
}
|
||||
|
||||
if (SDL_Init(SDL_INIT_AUDIO) < 0)
|
||||
{
|
||||
return M64ERR_SYSTEM_FAIL;
|
||||
}
|
||||
|
||||
if (!CoreInit(CoreLibHandle))
|
||||
{
|
||||
return M64ERR_SYSTEM_FAIL;
|
||||
}
|
||||
|
||||
load_settings();
|
||||
|
||||
l_PluginInit = true;
|
||||
return M64ERR_SUCCESS;
|
||||
}
|
||||
|
||||
EXPORT m64p_error CALL PluginShutdown(void)
|
||||
{
|
||||
if (!l_PluginInit)
|
||||
{
|
||||
return M64ERR_NOT_INIT;
|
||||
}
|
||||
|
||||
if (l_HardwareSpec != nullptr)\
|
||||
{
|
||||
free(l_HardwareSpec);
|
||||
l_HardwareSpec = NULL;
|
||||
}
|
||||
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
l_PluginInit = false;
|
||||
return M64ERR_SUCCESS;
|
||||
}
|
||||
|
||||
EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *pluginType, int *pluginVersion,
|
||||
int *apiVersion, const char **pluginNamePtr, int *capabilities)
|
||||
{
|
||||
if (pluginType != nullptr)
|
||||
{
|
||||
*pluginType = M64PLUGIN_AUDIO;
|
||||
}
|
||||
|
||||
if (pluginVersion != nullptr)
|
||||
{
|
||||
*pluginVersion = 0x010000;
|
||||
}
|
||||
|
||||
if (apiVersion != nullptr)
|
||||
{
|
||||
*apiVersion = AUDIO_PLUGIN_API_VERSION;
|
||||
}
|
||||
|
||||
if (pluginNamePtr != nullptr)
|
||||
{
|
||||
*pluginNamePtr = "Rosalie's Mupen GUI - Audio Plugin";
|
||||
}
|
||||
|
||||
if (capabilities != nullptr)
|
||||
{
|
||||
*capabilities = 0;
|
||||
}
|
||||
|
||||
return M64ERR_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Custom Plugin Functions
|
||||
//
|
||||
|
||||
EXPORT m64p_error CALL PluginConfig(void)
|
||||
{
|
||||
if (!l_PluginInit)
|
||||
{
|
||||
return M64ERR_NOT_INIT;
|
||||
}
|
||||
|
||||
UserInterface::MainDialog dialog(nullptr);
|
||||
dialog.exec();
|
||||
|
||||
// reload settings
|
||||
load_settings();
|
||||
|
||||
return M64ERR_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Audio Plugin Functions
|
||||
//
|
||||
|
||||
EXPORT void CALL AiDacrateChanged( int SystemType )
|
||||
{
|
||||
if (!l_PluginInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (SystemType)
|
||||
{
|
||||
case SYSTEM_NTSC:
|
||||
l_GameFreq = 48681812 / (*l_AudioInfo.AI_DACRATE_REG + 1);
|
||||
break;
|
||||
case SYSTEM_PAL:
|
||||
l_GameFreq = 49656530 / (*l_AudioInfo.AI_DACRATE_REG + 1);
|
||||
break;
|
||||
case SYSTEM_MPAL:
|
||||
l_GameFreq = 48628316 / (*l_AudioInfo.AI_DACRATE_REG + 1);
|
||||
break;
|
||||
}
|
||||
SDL_FreeAudioStream(l_AudioStream);
|
||||
l_AudioStream = SDL_NewAudioStream(AUDIO_S16SYS, 2, l_GameFreq, l_HardwareSpec->format, 2, l_HardwareSpec->freq);
|
||||
}
|
||||
|
||||
EXPORT void CALL AiLenChanged( void )
|
||||
{
|
||||
if (!l_PluginInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int LenReg = *l_AudioInfo.AI_LEN_REG;
|
||||
unsigned char *p = l_AudioInfo.RDRAM + (*l_AudioInfo.AI_DRAM_ADDR_REG & 0xFFFFFF);
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for ( i = 0 ; i < LenReg ; i += 4 )
|
||||
{
|
||||
// Left channel
|
||||
l_PrimaryBuffer[ i ] = p[ i + 2 ];
|
||||
l_PrimaryBuffer[ i + 1 ] = p[ i + 3 ];
|
||||
|
||||
// Right channel
|
||||
l_PrimaryBuffer[ i + 2 ] = p[ i ];
|
||||
l_PrimaryBuffer[ i + 3 ] = p[ i + 1 ];
|
||||
}
|
||||
|
||||
if (!l_VolIsMuted && !l_FastForward)
|
||||
{
|
||||
unsigned int audio_queued = SDL_GetQueuedAudioSize(l_SDLDevice);
|
||||
unsigned int acceptable_latency = (l_HardwareSpec->freq * 0.2) * 4;
|
||||
unsigned int min_latency = (l_HardwareSpec->freq * 0.02) * 4;
|
||||
|
||||
if (!l_Paused && audio_queued < min_latency)
|
||||
{
|
||||
SDL_PauseAudioDevice(l_SDLDevice, 1);
|
||||
l_Paused = true;
|
||||
}
|
||||
else if (l_Paused && audio_queued >= (min_latency * 2))
|
||||
{
|
||||
SDL_PauseAudioDevice(l_SDLDevice, 0);
|
||||
l_Paused = true;
|
||||
}
|
||||
|
||||
if (audio_queued < acceptable_latency)
|
||||
{
|
||||
SDL_AudioStreamPut(l_AudioStream, l_PrimaryBuffer, LenReg);
|
||||
}
|
||||
|
||||
int output_length = SDL_AudioStreamGet(l_AudioStream, l_OutputBuffer, sizeof(l_OutputBuffer));
|
||||
if (output_length > 0)
|
||||
{
|
||||
SDL_memset(l_MixBuffer, 0, output_length);
|
||||
SDL_MixAudioFormat(l_MixBuffer, l_OutputBuffer, l_HardwareSpec->format, output_length, l_VolSDL);
|
||||
SDL_QueueAudio(l_SDLDevice, l_MixBuffer, output_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT int CALL InitiateAudio( AUDIO_INFO Audio_Info )
|
||||
{
|
||||
if (!l_PluginInit)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
l_GameFreq = 33600;
|
||||
l_AudioInfo = Audio_Info;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
EXPORT int CALL RomOpen(void)
|
||||
{
|
||||
if (!l_PluginInit)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_AudioSpec *desired, *obtained;
|
||||
if (l_HardwareSpec != nullptr)
|
||||
{
|
||||
free(l_HardwareSpec);
|
||||
}
|
||||
desired = (SDL_AudioSpec*)malloc(sizeof(SDL_AudioSpec));
|
||||
obtained = (SDL_AudioSpec*)malloc(sizeof(SDL_AudioSpec));
|
||||
desired->freq = 44100;
|
||||
desired->format = AUDIO_S16SYS;
|
||||
desired->channels = 2;
|
||||
desired->samples = 1024;
|
||||
desired->callback = nullptr;
|
||||
desired->userdata = nullptr;
|
||||
|
||||
const char *dev_name = SDL_GetAudioDeviceName(-1, 0);
|
||||
l_SDLDevice = SDL_OpenAudioDevice(dev_name, 0, desired, obtained, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
|
||||
free(desired);
|
||||
l_HardwareSpec = obtained;
|
||||
SDL_PauseAudioDevice(l_SDLDevice, 0);
|
||||
l_Paused = 0;
|
||||
l_AudioStream = SDL_NewAudioStream(AUDIO_S16SYS, 2, l_GameFreq, l_HardwareSpec->format, 2, l_HardwareSpec->freq);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
EXPORT void CALL RomClosed( void )
|
||||
{
|
||||
if (!l_PluginInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_ClearQueuedAudio(l_SDLDevice);
|
||||
SDL_CloseAudioDevice(l_SDLDevice);
|
||||
|
||||
if (l_HardwareSpec != nullptr)
|
||||
{
|
||||
free(l_HardwareSpec);
|
||||
l_HardwareSpec = nullptr;
|
||||
}
|
||||
|
||||
SDL_FreeAudioStream(l_AudioStream);
|
||||
l_AudioStream = nullptr;
|
||||
}
|
||||
|
||||
EXPORT void CALL ProcessAList(void)
|
||||
{
|
||||
}
|
||||
|
||||
EXPORT void CALL SetSpeedFactor(int percentage)
|
||||
{
|
||||
if (percentage > 100)
|
||||
{
|
||||
l_FastForward = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_FastForward = false;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT void CALL VolumeMute(void)
|
||||
{
|
||||
if (!l_PluginInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
l_VolIsMuted = !l_VolIsMuted;
|
||||
}
|
||||
|
||||
EXPORT void CALL VolumeUp(void)
|
||||
{
|
||||
}
|
||||
|
||||
EXPORT void CALL VolumeDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
EXPORT int CALL VolumeGetLevel(void)
|
||||
{
|
||||
return l_VolIsMuted ? 0 : 100;
|
||||
}
|
||||
|
||||
EXPORT void CALL VolumeSetLevel(int level)
|
||||
{
|
||||
if (level < 0)
|
||||
{
|
||||
level = 0;
|
||||
}
|
||||
else if (level > 100)
|
||||
{
|
||||
level = 100;
|
||||
}
|
||||
|
||||
l_VolSDL = SDL_MIX_MAXVOLUME * level / 100;
|
||||
}
|
||||
|
||||
EXPORT const char * CALL VolumeGetString(void)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
@@ -4,11 +4,14 @@
|
||||
project(RMG-Core)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(SDL2 REQUIRED sdl2)
|
||||
pkg_check_modules(MINIZIP REQUIRED minizip)
|
||||
|
||||
configure_file(Config.hpp.in Config.hpp)
|
||||
|
||||
set(RMG_CORE_SOURCES
|
||||
m64p/Api.cpp
|
||||
m64p/CoreApi.cpp
|
||||
@@ -17,8 +20,9 @@ set(RMG_CORE_SOURCES
|
||||
Settings/Settings.cpp
|
||||
SpeedLimiter.cpp
|
||||
RomSettings.cpp
|
||||
RomHeader.cpp
|
||||
Directories.cpp
|
||||
Screenshot.cpp
|
||||
RomHeader.cpp
|
||||
Emulation.cpp
|
||||
SaveState.cpp
|
||||
Callback.cpp
|
||||
@@ -41,12 +45,20 @@ else()
|
||||
)
|
||||
endif()
|
||||
|
||||
if (PORTABLE_INSTALL)
|
||||
add_definitions(-DPORTABLE_INSTALL)
|
||||
endif(PORTABLE_INSTALL)
|
||||
|
||||
add_library(RMG-Core STATIC ${RMG_CORE_SOURCES})
|
||||
|
||||
if(UNIX)
|
||||
target_link_libraries(RMG-Core dl)
|
||||
endif(UNIX)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(RMG-Core wsock32 ws2_32)
|
||||
endif(WIN32)
|
||||
|
||||
target_link_libraries(RMG-Core
|
||||
${MINIZIP_LIBRARIES}
|
||||
)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef CORE_CONFIG_HPP
|
||||
#define CORE_CONFIG_HPP
|
||||
|
||||
#ifndef PORTABLE_INSTALL
|
||||
#define CORE_INSTAlL_PREFIX "${CMAKE_INSTALL_PREFIX}"
|
||||
#endif // PORTABLE_INSTALL
|
||||
|
||||
#endif // CORE_CONFIG_HPP
|
||||
@@ -27,7 +27,7 @@ static osal_dynlib_lib_handle l_CoreLibHandle;
|
||||
|
||||
std::string find_core_lib(void)
|
||||
{
|
||||
for (const auto& entry : std::filesystem::recursive_directory_iterator("Core"))
|
||||
for (const auto& entry : std::filesystem::recursive_directory_iterator(CoreGetCoreDirectory()))
|
||||
{
|
||||
std::string path = entry.path().string();
|
||||
if (path.ends_with(OSAL_DYNLIB_LIB_EXT_STR))
|
||||
@@ -110,7 +110,7 @@ bool CoreInit(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
m64p_ret = m64p::Core.Startup(FRONTEND_API_VERSION, "Config", "Data", nullptr, CoreDebugCallback, nullptr, CoreStateCallback);
|
||||
m64p_ret = m64p::Core.Startup(FRONTEND_API_VERSION, CoreGetUserConfigDirectory().c_str(), CoreGetSharedDataDirectory().c_str(), nullptr, CoreDebugCallback, nullptr, CoreStateCallback);
|
||||
if (m64p_ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "CoreInit M64P::Core.Startup() Failed: ";
|
||||
@@ -130,7 +130,7 @@ bool CoreInit(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = CoreApplyPluginSettings();
|
||||
ret = CoreCreateDirectories();
|
||||
if (!ret)
|
||||
{
|
||||
return false;
|
||||
@@ -139,6 +139,30 @@ bool CoreInit(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CoreInit(m64p_dynlib_handle handle)
|
||||
{
|
||||
std::string error;
|
||||
bool ret = false;
|
||||
|
||||
ret = m64p::Core.Hook(handle);
|
||||
if (!ret)
|
||||
{
|
||||
error = m64p::Core.GetLastError();
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = m64p::Config.Hook(handle);
|
||||
if (!ret)
|
||||
{
|
||||
error = m64p::Config.GetLastError();
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CoreShutdown(void)
|
||||
{
|
||||
CorePluginsShutdown();
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "Settings/Settings.hpp"
|
||||
#include "SpeedLimiter.hpp"
|
||||
#include "RomSettings.hpp"
|
||||
#include "Directories.hpp"
|
||||
#include "Screenshot.hpp"
|
||||
#include "Emulation.hpp"
|
||||
#include "SaveState.hpp"
|
||||
@@ -22,11 +23,27 @@
|
||||
#include "Error.hpp"
|
||||
#include "Video.hpp"
|
||||
#include "Key.hpp"
|
||||
#include "Rom.hpp"
|
||||
#ifdef CORE_PLUGIN
|
||||
#include "m64p/api/m64p_common.h"
|
||||
#include "m64p/api/m64p_custom.h"
|
||||
#include "m64p/api/m64p_types.h"
|
||||
#include "m64p/api/m64p_config.h"
|
||||
#include "m64p/api/m64p_plugin.h"
|
||||
#include "m64p/api/version.h"
|
||||
#endif // CORE_PLUGIN
|
||||
|
||||
|
||||
// initializes the core library,
|
||||
// returns false when failed
|
||||
bool CoreInit(void);
|
||||
|
||||
#ifdef CORE_PLUGIN
|
||||
// initializes the core library for plugins,
|
||||
// returns false when failed
|
||||
bool CoreInit(m64p_dynlib_handle handle);
|
||||
#endif // CORE_PLUGIN
|
||||
|
||||
// shuts down the core library
|
||||
void CoreShutdown(void);
|
||||
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "Directories.hpp"
|
||||
#include "Config.hpp"
|
||||
#include "Error.hpp"
|
||||
#include "Core.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <filesystem>
|
||||
|
||||
//
|
||||
// Local Functions
|
||||
//
|
||||
|
||||
static std::string get_var_directory(std::string var, std::string append, std::string fallbackVar, std::string fallbackAppend)
|
||||
{
|
||||
std::string directory;
|
||||
|
||||
const char* env = std::getenv(var.c_str());
|
||||
if (env == nullptr)
|
||||
{
|
||||
env = std::getenv(fallbackVar.c_str());
|
||||
if (env == nullptr)
|
||||
{
|
||||
std::cerr << "get_var_directory: fallbackVar: $" << fallbackVar << " cannot be nullptr!" << std::endl;
|
||||
std::terminate();
|
||||
}
|
||||
directory = env;
|
||||
directory += fallbackAppend;
|
||||
}
|
||||
else
|
||||
{
|
||||
directory = env;
|
||||
directory += append;
|
||||
}
|
||||
|
||||
return directory;
|
||||
}
|
||||
|
||||
//
|
||||
// Exported Functions
|
||||
//
|
||||
|
||||
bool CoreCreateDirectories(void)
|
||||
{
|
||||
std::string error;
|
||||
|
||||
std::string directories[] =
|
||||
{
|
||||
#ifdef PORTABLE_INSTALL
|
||||
CoreGetCoreDirectory(),
|
||||
CoreGetPluginDirectory(),
|
||||
CoreGetSharedDataDirectory(),
|
||||
#endif // PORTABLE_INSTALL
|
||||
CoreGetUserConfigDirectory(),
|
||||
CoreGetUserDataDirectory(),
|
||||
CoreGetUserCacheDirectory(),
|
||||
CoreGetSaveDirectory(),
|
||||
CoreGetSaveStateDirectory()
|
||||
};
|
||||
|
||||
for (const auto& dir : directories)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::filesystem::create_directories(dir);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
error = "CoreCreateDirectories Failed: cannot create the '";
|
||||
error += dir;
|
||||
error += "' directory!";
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string CoreGetCoreDirectory(void)
|
||||
{
|
||||
std::string directory;
|
||||
#ifdef PORTABLE_INSTALL
|
||||
directory = "Core";
|
||||
#else // Not Portable
|
||||
directory = CORE_INSTAlL_PREFIX;
|
||||
directory += "/lib/RMG/Core";
|
||||
#endif // PORTABLE_INSTALL
|
||||
return directory;
|
||||
}
|
||||
|
||||
std::string CoreGetPluginDirectory(void)
|
||||
{
|
||||
std::string directory;
|
||||
#ifdef PORTABLE_INSTALL
|
||||
directory = "Plugin";
|
||||
#else // Not Portable
|
||||
directory = CORE_INSTAlL_PREFIX;
|
||||
directory += "/lib/RMG/Plugin";
|
||||
#endif // PORTABLE_INSTALL
|
||||
return directory;
|
||||
}
|
||||
|
||||
std::string CoreGetUserConfigDirectory(void)
|
||||
{
|
||||
std::string directory;
|
||||
#ifdef PORTABLE_INSTALL
|
||||
directory = "Config";
|
||||
#else // Not Portable
|
||||
directory = get_var_directory("XDG_CONFIG_HOME", "/RMG", "HOME", "/.config/RMG");
|
||||
#endif // PORTABLE_INSTALL
|
||||
return directory;
|
||||
}
|
||||
|
||||
std::string CoreGetDefaultUserDataDirectory(void)
|
||||
{
|
||||
std::string directory;
|
||||
#ifdef PORTABLE_INSTALL
|
||||
directory = "Data";
|
||||
#else // Not Portable
|
||||
directory = get_var_directory("XDG_DATA_HOME", "/RMG", "HOME", "/.local/share/RMG");
|
||||
#endif // PORTABLE_INSTALL
|
||||
return directory;
|
||||
}
|
||||
|
||||
std::string CoreGetDefaultUserCacheDirectory(void)
|
||||
{
|
||||
std::string directory;
|
||||
#ifdef PORTABLE_INSTALL
|
||||
directory = "Cache";
|
||||
#else // Not Portable
|
||||
directory = get_var_directory("XDG_CACHE_HOME", "/RMG", "HOME", "/.cache/RMG");
|
||||
#endif // PORTABLE_INSTALL
|
||||
return directory;
|
||||
}
|
||||
|
||||
std::string CoreGetDefaultSaveDirectory(void)
|
||||
{
|
||||
std::string directory;
|
||||
#ifdef PORTABLE_INSTALL
|
||||
directory = "Save/Game";
|
||||
#else
|
||||
directory = CoreGetUserDataDirectory();
|
||||
directory += "/Save/Game";
|
||||
#endif // PORTABLE_INSTALL
|
||||
return directory;
|
||||
}
|
||||
|
||||
std::string CoreGetDefaultSaveStateDirectory(void)
|
||||
{
|
||||
std::string directory;
|
||||
#ifdef PORTABLE_INSTALL
|
||||
directory = "Save/State";
|
||||
#else
|
||||
directory = CoreGetUserDataDirectory();
|
||||
directory += "/Save/State";
|
||||
#endif // PORTABLE_INSTALL
|
||||
return directory;
|
||||
}
|
||||
|
||||
std::string CoreGetUserDataDirectory(void)
|
||||
{
|
||||
return CoreSettingsGetStringValue(SettingsID::Core_UserDataDirOverride);
|
||||
}
|
||||
|
||||
std::string CoreGetUserCacheDirectory(void)
|
||||
{
|
||||
return CoreSettingsGetStringValue(SettingsID::Core_UserCacheDirOverride);
|
||||
}
|
||||
|
||||
std::string CoreGetSharedDataDirectory(void)
|
||||
{
|
||||
std::string directory;
|
||||
#ifdef PORTABLE_INSTALL
|
||||
directory = "Data";
|
||||
#else // Not Portable
|
||||
directory = CORE_INSTAlL_PREFIX;
|
||||
directory += "/share/RMG";
|
||||
#endif // PORTABLE_INSTALL
|
||||
return directory;
|
||||
}
|
||||
|
||||
std::string CoreGetSaveDirectory(void)
|
||||
{
|
||||
return CoreSettingsGetStringValue(SettingsID::Core_SaveSRAMPath);
|
||||
}
|
||||
|
||||
std::string CoreGetSaveStateDirectory(void)
|
||||
{
|
||||
return CoreSettingsGetStringValue(SettingsID::Core_SaveStatePath);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef DIRECTORIES_HPP
|
||||
#define DIRECTORIES_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
// tries to create the needed directories,
|
||||
// returns false when failed
|
||||
bool CoreCreateDirectories(void);
|
||||
|
||||
// returns the core directory where
|
||||
// the mupen64plus library should be
|
||||
// located
|
||||
std::string CoreGetCoreDirectory(void);
|
||||
|
||||
// returns the plugin directory where
|
||||
// plugins should be located
|
||||
std::string CoreGetPluginDirectory(void);
|
||||
|
||||
// returns the default user data directory where
|
||||
// data files should be located
|
||||
std::string CoreGetDefaultUserDataDirectory(void);
|
||||
|
||||
// returns the default user cache directory where
|
||||
// cache files should be located
|
||||
std::string CoreGetDefaultUserCacheDirectory(void);
|
||||
|
||||
// returns the default save directory where
|
||||
// game saves should be located
|
||||
std::string CoreGetDefaultSaveDirectory(void);
|
||||
|
||||
// returns the default save state directory where
|
||||
// save states should be located
|
||||
std::string CoreGetDefaultSaveStateDirectory(void);
|
||||
|
||||
// returns the user config directory where
|
||||
// configuration files should be located
|
||||
std::string CoreGetUserConfigDirectory(void);
|
||||
|
||||
// returns the user data directory where
|
||||
// data files should be located
|
||||
std::string CoreGetUserDataDirectory(void);
|
||||
|
||||
// returns the user cache directory where
|
||||
// cache files should be located
|
||||
std::string CoreGetUserCacheDirectory(void);
|
||||
|
||||
// returns the shared data directory where
|
||||
// shared data files should be located
|
||||
std::string CoreGetSharedDataDirectory(void);
|
||||
|
||||
// returns the save directory where
|
||||
// game saves should be located
|
||||
std::string CoreGetSaveDirectory(void);
|
||||
|
||||
// returns the save state directory where
|
||||
// save states should be located
|
||||
std::string CoreGetSaveStateDirectory(void);
|
||||
|
||||
#endif // DIRECTORIES_HPP
|
||||
@@ -49,16 +49,22 @@ bool CoreStartEmulation(std::string n64rom, std::string n64ddrom)
|
||||
|
||||
if (!CoreApplyRomPluginSettings())
|
||||
{
|
||||
CoreApplyPluginSettings();
|
||||
CoreCloseRom();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CoreArePluginsReady())
|
||||
{
|
||||
CoreApplyPluginSettings();
|
||||
CoreCloseRom();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CoreAttachPlugins())
|
||||
{
|
||||
CoreApplyPluginSettings();
|
||||
CoreCloseRom();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "Plugins.hpp"
|
||||
#include "Directories.hpp"
|
||||
#include "Error.hpp"
|
||||
#include "Emulation.hpp"
|
||||
#include "RomSettings.hpp"
|
||||
#include "Settings/Settings.hpp"
|
||||
|
||||
@@ -71,6 +73,138 @@ std::string get_plugin_name(m64p::PluginApi* plugin, std::string filename)
|
||||
return std::string(name);
|
||||
}
|
||||
|
||||
std::string get_plugin_type_name(CorePluginType type)
|
||||
{
|
||||
std::string name;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
default:
|
||||
name = "Unknown";
|
||||
break;
|
||||
case CorePluginType::Rsp:
|
||||
name = "Rsp";
|
||||
break;
|
||||
case CorePluginType::Gfx:
|
||||
name = "Gfx";
|
||||
break;
|
||||
case CorePluginType::Audio:
|
||||
name = "Audio";
|
||||
break;
|
||||
case CorePluginType::Input:
|
||||
name = "Input";
|
||||
break;
|
||||
case CorePluginType::Invalid:
|
||||
name = "Invalid";
|
||||
break;
|
||||
}
|
||||
|
||||
return name + " Plugin";
|
||||
}
|
||||
|
||||
bool apply_plugin_settings(std::string pluginSettings[4])
|
||||
{
|
||||
std::string error;
|
||||
std::string settingValue;
|
||||
m64p::PluginApi* plugin;
|
||||
CorePluginType pluginType;
|
||||
osal_dynlib_lib_handle handle;
|
||||
m64p_error ret;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
settingValue = pluginSettings[i];
|
||||
if (settingValue.empty() ||
|
||||
!std::filesystem::is_regular_file(settingValue))
|
||||
{ // skip invalid setting value
|
||||
continue;
|
||||
}
|
||||
|
||||
pluginType = (CorePluginType)(i + 1);
|
||||
|
||||
if (settingValue != l_PluginFiles[i])
|
||||
{
|
||||
plugin = &l_Plugins[i];
|
||||
|
||||
// shutdown plugin when hooked
|
||||
if (plugin->IsHooked())
|
||||
{
|
||||
ret = plugin->Shutdown();
|
||||
if (ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "apply_plugin_settings (";
|
||||
error += get_plugin_type_name(pluginType);
|
||||
error += ")->Shutdown() Failed: ";
|
||||
error += m64p::Core.ErrorMessage(ret);
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// reset plugin
|
||||
plugin->Unhook();
|
||||
}
|
||||
|
||||
// attempt to open the library
|
||||
handle = osal_dynlib_open(settingValue.c_str());
|
||||
if (handle == nullptr)
|
||||
{
|
||||
error = "apply_plugin_settings osal_dynlib_open Failed: ";
|
||||
error += osal_dynlib_strerror();
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// attempt to hook the library
|
||||
if (!plugin->Hook(handle))
|
||||
{
|
||||
error = "apply_plugin_settings (";
|
||||
error += get_plugin_type_name(pluginType);
|
||||
error += ")->Hook() Failed: ";
|
||||
error += plugin->GetLastError();
|
||||
CoreSetError(error);
|
||||
plugin->Unhook();
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure the plugin type is the expected type
|
||||
if (get_plugin_type(plugin) != pluginType)
|
||||
{
|
||||
error = "apply_plugin_settings plugin type ";
|
||||
error += get_plugin_type_name(get_plugin_type(plugin));
|
||||
error += " doesn't match expected type ";
|
||||
error += get_plugin_type_name(pluginType);
|
||||
error += "!";
|
||||
CoreSetError(error);
|
||||
plugin->Unhook();
|
||||
return false;
|
||||
}
|
||||
|
||||
// attempt to start plugin
|
||||
ret = plugin->Startup(m64p::Core.GetHandle(), nullptr, nullptr);
|
||||
if (ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "apply_plugin_settings (";
|
||||
error += get_plugin_type_name(pluginType);
|
||||
error += ")->Startup() Failed: ";
|
||||
error += m64p::Core.ErrorMessage(ret);
|
||||
CoreSetError(error);
|
||||
plugin->Shutdown();
|
||||
plugin->Unhook();
|
||||
// force a re-load next time,
|
||||
// because this plugin isn't
|
||||
// the one we've stored in
|
||||
// l_PluginFiles[i]
|
||||
l_PluginFiles[i].clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
l_PluginFiles[i] = settingValue;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Exported Functions
|
||||
//
|
||||
@@ -83,7 +217,7 @@ std::vector<CorePlugin> CoreGetAllPlugins(void)
|
||||
osal_dynlib_lib_handle handle;
|
||||
m64p::PluginApi plugin;
|
||||
|
||||
for (const auto& entry : std::filesystem::recursive_directory_iterator("Plugin"))
|
||||
for (const auto& entry : std::filesystem::recursive_directory_iterator(CoreGetPluginDirectory()))
|
||||
{
|
||||
std::string path = entry.path().string();
|
||||
if (!entry.is_directory() &&
|
||||
@@ -116,170 +250,35 @@ std::vector<CorePlugin> CoreGetAllPlugins(void)
|
||||
|
||||
bool CoreApplyPluginSettings(void)
|
||||
{
|
||||
std::string error;
|
||||
std::string settingValue;
|
||||
m64p::PluginApi* plugin;
|
||||
osal_dynlib_lib_handle handle;
|
||||
m64p_error ret;
|
||||
|
||||
SettingsID settings[] =
|
||||
std::string settings[] =
|
||||
{
|
||||
SettingsID::Core_RSP_Plugin,
|
||||
SettingsID::Core_GFX_Plugin,
|
||||
SettingsID::Core_AUDIO_Plugin,
|
||||
SettingsID::Core_INPUT_Plugin
|
||||
CoreSettingsGetStringValue(SettingsID::Core_RSP_Plugin),
|
||||
CoreSettingsGetStringValue(SettingsID::Core_GFX_Plugin),
|
||||
CoreSettingsGetStringValue(SettingsID::Core_AUDIO_Plugin),
|
||||
CoreSettingsGetStringValue(SettingsID::Core_INPUT_Plugin)
|
||||
};
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
settingValue = CoreSettingsGetStringValue(settings[i]);
|
||||
if (settingValue.empty() ||
|
||||
!std::filesystem::is_regular_file(settingValue))
|
||||
{ // skip invalid setting value
|
||||
continue;
|
||||
}
|
||||
|
||||
if (settingValue != l_PluginFiles[i])
|
||||
{
|
||||
plugin = &l_Plugins[i];
|
||||
|
||||
// shutdown plugin when hooked
|
||||
if (plugin->IsHooked())
|
||||
{
|
||||
ret = plugin->Shutdown();
|
||||
if (ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "CoreApplyPluginSettings m64p::PluginApi.Shutdown() Failed: ";
|
||||
error += m64p::Core.ErrorMessage(ret);
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// reset plugin
|
||||
plugin->Unhook();
|
||||
}
|
||||
|
||||
// attempt to open the library
|
||||
handle = osal_dynlib_open(settingValue.c_str());
|
||||
if (handle == nullptr)
|
||||
{
|
||||
error = "CoreApplyPluginSettings osal_dynlib_open Failed: ";
|
||||
error += osal_dynlib_strerror();
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// attempt to hook the library
|
||||
if (!plugin->Hook(handle))
|
||||
{
|
||||
error = "CoreApplyPluginSettings m64p::PluginApi.Hook() Failed: ";
|
||||
error += plugin->GetLastError();
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// attempt to start plugin
|
||||
ret = plugin->Startup(m64p::Core.GetHandle(), nullptr, nullptr);
|
||||
if (ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "CoreApplyPluginSettings m64p::PluginApi.Startup() Failed: ";
|
||||
error += m64p::Core.ErrorMessage(ret);
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
l_PluginFiles[i] = settingValue;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return apply_plugin_settings(settings);
|
||||
}
|
||||
|
||||
bool CoreApplyRomPluginSettings(void)
|
||||
{
|
||||
std::string error;
|
||||
std::string settingValue;
|
||||
m64p::PluginApi* plugin;
|
||||
osal_dynlib_lib_handle handle;
|
||||
m64p_error ret;
|
||||
CoreRomSettings romSettings;
|
||||
|
||||
SettingsID settings[] =
|
||||
{
|
||||
SettingsID::Game_RSP_Plugin,
|
||||
SettingsID::Game_GFX_Plugin,
|
||||
SettingsID::Game_AUDIO_Plugin,
|
||||
SettingsID::Game_INPUT_Plugin
|
||||
};
|
||||
CoreRomSettings romSettings;
|
||||
|
||||
if (!CoreGetCurrentDefaultRomSettings(romSettings))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
std::string settings[] =
|
||||
{
|
||||
settingValue = CoreSettingsGetStringValue(settings[i], romSettings.MD5);
|
||||
if (settingValue.empty() ||
|
||||
!std::filesystem::is_regular_file(settingValue))
|
||||
{ // skip invalid setting value
|
||||
continue;
|
||||
}
|
||||
CoreSettingsGetStringValue(SettingsID::Game_RSP_Plugin, romSettings.MD5),
|
||||
CoreSettingsGetStringValue(SettingsID::Game_GFX_Plugin, romSettings.MD5),
|
||||
CoreSettingsGetStringValue(SettingsID::Game_AUDIO_Plugin, romSettings.MD5),
|
||||
CoreSettingsGetStringValue(SettingsID::Game_INPUT_Plugin, romSettings.MD5)
|
||||
};
|
||||
|
||||
if (settingValue != l_PluginFiles[i])
|
||||
{
|
||||
plugin = &l_Plugins[i];
|
||||
|
||||
// shutdown plugin when hooked
|
||||
if (plugin->IsHooked())
|
||||
{
|
||||
ret = plugin->Shutdown();
|
||||
if (ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "CoreApplyPluginSettings m64p::PluginApi.Shutdown() Failed: ";
|
||||
error += m64p::Core.ErrorMessage(ret);
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// reset plugin
|
||||
plugin->Unhook();
|
||||
}
|
||||
|
||||
// attempt to open the library
|
||||
handle = osal_dynlib_open(settingValue.c_str());
|
||||
if (handle == nullptr)
|
||||
{
|
||||
error = "CoreApplyPluginSettings osal_dynlib_open Failed: ";
|
||||
error += osal_dynlib_strerror();
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// attempt to hook the library
|
||||
if (!plugin->Hook(handle))
|
||||
{
|
||||
error = "CoreApplyPluginSettings m64p::PluginApi.Hook() Failed: ";
|
||||
error += plugin->GetLastError();
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// attempt to start plugin
|
||||
ret = plugin->Startup(m64p::Core.GetHandle(), nullptr, nullptr);
|
||||
if (ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "CoreApplyPluginSettings m64p::PluginApi.Startup() Failed: ";
|
||||
error += m64p::Core.ErrorMessage(ret);
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
l_PluginFiles[i] = settingValue;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return apply_plugin_settings(settings);
|
||||
}
|
||||
|
||||
bool CoreArePluginsReady(void)
|
||||
@@ -291,7 +290,9 @@ bool CoreArePluginsReady(void)
|
||||
if (!l_Plugins[i].IsHooked())
|
||||
{
|
||||
error = "CoreArePluginsReady Failed: ";
|
||||
error += "PluginApi::IsHooked returned false!";
|
||||
error += "(";
|
||||
error += get_plugin_type_name((CorePluginType)(i + 1));
|
||||
error += ")->IsHooked returned false!";
|
||||
CoreSetError(error);
|
||||
return false;
|
||||
}
|
||||
@@ -309,23 +310,44 @@ bool CorePluginsOpenConfig(CorePluginType type)
|
||||
{
|
||||
std::string error;
|
||||
m64p_error ret;
|
||||
bool resumeEmulation = false;
|
||||
|
||||
if (!CorePluginsHasConfig(type))
|
||||
{
|
||||
error = "CorePluginsOpenConfig Failed: ";
|
||||
error += "plugin with given type doesn't have config function!";
|
||||
error += get_plugin_type_name(type);
|
||||
error += " doesn't have config function!";
|
||||
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();
|
||||
}
|
||||
|
||||
ret = get_plugin(type)->Config();
|
||||
if (ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "CorePluginsOpenConfig m64p::PluginApi.Config() Failed: ";
|
||||
error = "CorePluginsOpenConfig (";
|
||||
error += get_plugin_type_name(type);
|
||||
error += ")->Config() Failed: ";
|
||||
error += m64p::Core.ErrorMessage(ret);
|
||||
CoreSetError(error);
|
||||
}
|
||||
|
||||
// try to resume emulation when needed
|
||||
if (resumeEmulation)
|
||||
{
|
||||
CoreResumeEmulation();
|
||||
}
|
||||
|
||||
return ret == M64ERR_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -346,7 +368,9 @@ bool CoreAttachPlugins(void)
|
||||
ret = m64p::Core.AttachPlugin(plugin_types[i], get_plugin((CorePluginType)plugin_types[i])->GetHandle());
|
||||
if (ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "CoreAttachPlugins m64p::Core.AttachPlugin() Failed: ";
|
||||
error = "CoreAttachPlugins m64p::Core.AttachPlugin(";
|
||||
error += get_plugin_type_name((CorePluginType)plugin_types[i]);
|
||||
error += ") Failed: ";
|
||||
error += m64p::Core.ErrorMessage(ret);
|
||||
CoreSetError(error);
|
||||
break;
|
||||
@@ -366,7 +390,9 @@ bool CoreDetachPlugins(void)
|
||||
ret = m64p::Core.DetachPlugin((m64p_plugin_type)(i + 1));
|
||||
if (ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "CoreDetachPlugins m64p::Core.DetachPlugin() Failed: ";
|
||||
error = "CoreDetachPlugins m64p::Core.DetachPlugin(";
|
||||
error += get_plugin_type_name((CorePluginType)(i + 1));
|
||||
error += ") Failed: ";
|
||||
error += m64p::Core.ErrorMessage(ret);
|
||||
CoreSetError(error);
|
||||
break;
|
||||
@@ -392,7 +418,9 @@ bool CorePluginsShutdown(void)
|
||||
ret = plugin->Shutdown();
|
||||
if (ret != M64ERR_SUCCESS)
|
||||
{
|
||||
error = "CorePluginsShutdown m64p::PluginApi.Shutdown() Failed: ";
|
||||
error = "CorePluginsShutdown (";
|
||||
error += get_plugin_type_name((CorePluginType)(i + 1));
|
||||
error += ")->Shutdown() Failed: ";
|
||||
error += m64p::Core.ErrorMessage(ret);
|
||||
CoreSetError(error);
|
||||
break;
|
||||
|
||||
@@ -214,17 +214,6 @@ static bool read_raw_file(std::string file, char** buf, int* size)
|
||||
// read file
|
||||
fileStream.read(fileStreamBuf, fileStreamLen);
|
||||
|
||||
// make sure that we've read the entire file
|
||||
if (fileStream.tellg() != fileStreamLen)
|
||||
{
|
||||
error = "read_raw_file Failed: ";
|
||||
error += "failed to read entire file!";
|
||||
CoreSetError(error);
|
||||
free(fileStreamBuf);
|
||||
fileStream.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
*buf = fileStreamBuf;
|
||||
*size = fileStreamLen;
|
||||
|
||||
|
||||
@@ -13,6 +13,12 @@
|
||||
#include "Error.hpp"
|
||||
#include "Rom.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#else // Unix
|
||||
#include <arpa/inet.h>
|
||||
#endif // _WIN32
|
||||
|
||||
//
|
||||
// Exported Functions
|
||||
//
|
||||
@@ -32,8 +38,8 @@ bool CoreGetCurrentRomHeader(CoreRomHeader& header)
|
||||
return false;
|
||||
}
|
||||
|
||||
header.CRC1 = m64p_header.CRC1;
|
||||
header.CRC2 = m64p_header.CRC2;
|
||||
header.CRC1 = ntohl(m64p_header.CRC1);
|
||||
header.CRC2 = ntohl(m64p_header.CRC2);
|
||||
header.Name = std::string((char*)m64p_header.Name);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
#include "Settings.hpp"
|
||||
|
||||
#include "Directories.hpp"
|
||||
#include "m64p/Api.hpp"
|
||||
#include "Error.hpp"
|
||||
#include "m64p/api/m64p_types.h"
|
||||
@@ -64,6 +65,12 @@ struct l_DynamicValue
|
||||
valueType = M64TYPE_STRING;
|
||||
}
|
||||
|
||||
l_DynamicValue(std::string value)
|
||||
{
|
||||
stringValue = value;
|
||||
valueType = M64TYPE_STRING;
|
||||
}
|
||||
|
||||
l_DynamicValue(std::vector<int> value)
|
||||
{
|
||||
intListValue = value;
|
||||
@@ -79,14 +86,14 @@ struct l_DynamicValue
|
||||
}
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct l_Setting
|
||||
{
|
||||
std::string Section;
|
||||
std::string Key;
|
||||
l_DynamicValue DefaultValue;
|
||||
std::string Description;
|
||||
bool ForceUseSet;
|
||||
} l_Setting;
|
||||
std::string Description = "";
|
||||
bool ForceUseSetOnce = false;
|
||||
};
|
||||
|
||||
//
|
||||
// Local Variables
|
||||
@@ -104,7 +111,9 @@ static std::vector<std::string> l_sectionList;
|
||||
#define SETTING_SECTION_OVERLAY SETTING_SECTION_CORE " Overlay"
|
||||
#define SETTING_SECTION_KEYBIND SETTING_SECTION_GUI " KeyBindings"
|
||||
#define SETTING_SECTION_ROMBROWSER SETTING_SECTION_GUI " RomBrowser"
|
||||
#define SETTING_SECTION_SETTINGS SETTING_SECTION_CORE " Settings"
|
||||
#define SETTING_SECTION_M64P "Core"
|
||||
#define SETTING_SECTION_AUDIO SETTING_SECTION_GUI " - Audio Plugin"
|
||||
|
||||
// retrieves l_Setting from settingId
|
||||
static l_Setting get_setting(SettingsID settingId)
|
||||
@@ -118,222 +127,239 @@ static l_Setting get_setting(SettingsID settingId)
|
||||
break;
|
||||
|
||||
case SettingsID::GUI_SettingsDialogWidth:
|
||||
setting = {SETTING_SECTION_GUI, "SettingsDialogWidth", 0, "", false};
|
||||
setting = {SETTING_SECTION_GUI, "SettingsDialogWidth", 0};
|
||||
break;
|
||||
case SettingsID::GUI_SettingsDialogHeight:
|
||||
setting = {SETTING_SECTION_GUI, "SettingsDialogHeight", 0, "", false};
|
||||
setting = {SETTING_SECTION_GUI, "SettingsDialogHeight", 0};
|
||||
break;
|
||||
case SettingsID::GUI_AllowManualResizing:
|
||||
setting = {SETTING_SECTION_GUI, "AllowManualResizing", true, "", false};
|
||||
setting = {SETTING_SECTION_GUI, "AllowManualResizing", true};
|
||||
break;
|
||||
case SettingsID::GUI_HideCursorInEmulation:
|
||||
setting = {SETTING_SECTION_GUI, "HideCursorInEmulation", false, "", false};
|
||||
setting = {SETTING_SECTION_GUI, "HideCursorInEmulation", false};
|
||||
break;
|
||||
case SettingsID::GUI_StatusbarMessageDuration:
|
||||
setting = {SETTING_SECTION_GUI, "StatusbarMessageDuration", 3, "", false};
|
||||
setting = {SETTING_SECTION_GUI, "StatusbarMessageDuration", 3};
|
||||
break;
|
||||
case SettingsID::GUI_PauseEmulationOnFocusLoss:
|
||||
setting = {SETTING_SECTION_GUI, "PauseEmulationOnFocusLoss", true};
|
||||
break;
|
||||
case SettingsID::GUI_ResumeEmulationOnFocus:
|
||||
setting = {SETTING_SECTION_GUI, "ResumeEmulationOnFocus", true};
|
||||
break;
|
||||
|
||||
case SettingsID::Core_GFX_Plugin:
|
||||
setting = {SETTING_SECTION_CORE, "GFX_Plugin",
|
||||
#ifdef _WIN32
|
||||
"Plugin\\GFX\\mupen64plus-video-GLideN64.dll",
|
||||
CoreGetPluginDirectory() + "\\GFX\\mupen64plus-video-GLideN64.dll",
|
||||
#else
|
||||
"Plugin/GFX/mupen64plus-video-GLideN64.so",
|
||||
CoreGetPluginDirectory() + "/GFX/mupen64plus-video-GLideN64.so",
|
||||
#endif // _WIN32
|
||||
"", false};
|
||||
};
|
||||
break;
|
||||
case SettingsID::Core_AUDIO_Plugin:
|
||||
setting = {SETTING_SECTION_CORE, "AUDIO_Plugin",
|
||||
#ifdef _WIN32
|
||||
"Plugin\\Audio\\mupen64plus-audio-sdl2.dll",
|
||||
CoreGetPluginDirectory() + "\\Audio\\RMG-Audio.dll",
|
||||
#else
|
||||
"Plugin/Audio/mupen64plus-audio-sdl2.so",
|
||||
CoreGetPluginDirectory() + "/Audio/RMG-Audio.so",
|
||||
#endif // _WIN32
|
||||
"", false};
|
||||
};
|
||||
break;
|
||||
case SettingsID::Core_INPUT_Plugin:
|
||||
setting = {SETTING_SECTION_CORE, "INPUT_Plugin",
|
||||
#ifdef _WIN32
|
||||
"Plugin\\Input\\libmupen64plus-input-qt.dll",
|
||||
CoreGetPluginDirectory() + "\\Input\\libmupen64plus-input-qt.dll",
|
||||
#else
|
||||
"Plugin/Input/libmupen64plus-input-qt.so",
|
||||
CoreGetPluginDirectory() + "/Input/libmupen64plus-input-qt.so",
|
||||
#endif // _WIN32
|
||||
"", false};
|
||||
};
|
||||
break;
|
||||
case SettingsID::Core_RSP_Plugin:
|
||||
setting = {SETTING_SECTION_CORE, "RSP_Plugin",
|
||||
#ifdef _WIN32
|
||||
"Plugin\\RSP\\mupen64plus-rsp-hle.dll",
|
||||
CoreGetPluginDirectory() + "\\RSP\\mupen64plus-rsp-hle.dll",
|
||||
#else
|
||||
"Plugin/RSP/mupen64plus-rsp-hle.so",
|
||||
CoreGetPluginDirectory() + "/RSP/mupen64plus-rsp-hle.so",
|
||||
#endif // _WIN32
|
||||
"", false};
|
||||
};
|
||||
break;
|
||||
|
||||
case SettingsID::Core_OverrideUserDirs:
|
||||
setting = {SETTING_SECTION_CORE, "OverrideUserDirectories", true, "", false};
|
||||
setting = {SETTING_SECTION_CORE, "OverrideUserDirectories", true};
|
||||
break;
|
||||
case SettingsID::Core_UserDataDirOverride:
|
||||
setting = {SETTING_SECTION_CORE, "UserDataDirectory", "Data", "", false};
|
||||
setting = {SETTING_SECTION_CORE, "UserDataDirectory", CoreGetDefaultUserDataDirectory()};
|
||||
break;
|
||||
case SettingsID::Core_UserCacheDirOverride:
|
||||
setting = {SETTING_SECTION_CORE, "UserCacheDirectory", "Cache", "", false};
|
||||
setting = {SETTING_SECTION_CORE, "UserCacheDirectory", CoreGetDefaultUserCacheDirectory()};
|
||||
break;
|
||||
|
||||
case SettingsID::Core_OverrideGameSpecificSettings:
|
||||
setting = {SETTING_SECTION_CORE, "OverrideGameSpecificSettings", false, "", false};
|
||||
setting = {SETTING_SECTION_CORE, "OverrideGameSpecificSettings", false};
|
||||
break;
|
||||
|
||||
case SettingsID::Core_RandomizeInterrupt:
|
||||
setting = {SETTING_SECTION_OVERLAY, "RandomizeInterrupt", true, "", false};
|
||||
setting = {SETTING_SECTION_OVERLAY, "RandomizeInterrupt", true};
|
||||
break;
|
||||
case SettingsID::Core_CPU_Emulator:
|
||||
setting = {SETTING_SECTION_OVERLAY, "CPU_Emulator", 2, "", false};
|
||||
setting = {SETTING_SECTION_OVERLAY, "CPU_Emulator", 2};
|
||||
break;
|
||||
case SettingsID::Core_DisableExtraMem:
|
||||
setting = {SETTING_SECTION_OVERLAY, "DisableExtraMem", false, "", false};
|
||||
setting = {SETTING_SECTION_OVERLAY, "DisableExtraMem", false};
|
||||
break;
|
||||
case SettingsID::Core_EnableDebugger:
|
||||
setting = {SETTING_SECTION_OVERLAY, "EnableDebugger", false, "", false};
|
||||
setting = {SETTING_SECTION_OVERLAY, "EnableDebugger", false};
|
||||
break;
|
||||
case SettingsID::Core_CountPerOp:
|
||||
setting = {SETTING_SECTION_OVERLAY, "CountPerOp", 0, "", false};
|
||||
setting = {SETTING_SECTION_OVERLAY, "CountPerOp", 0};
|
||||
break;
|
||||
case SettingsID::Core_SiDmaDuration:
|
||||
setting = {SETTING_SECTION_OVERLAY, "SiDmaDuration", -1, "", false};
|
||||
setting = {SETTING_SECTION_OVERLAY, "SiDmaDuration", -1};
|
||||
break;
|
||||
|
||||
case SettingsID::Core_ScreenshotPath:
|
||||
setting = {SETTING_SECTION_M64P, "ScreenshotPath", "Screenshots", "", true};
|
||||
break;
|
||||
case SettingsID::Core_SaveStatePath:
|
||||
setting = {SETTING_SECTION_M64P, "SaveStatePath", "Save/State", "", true};
|
||||
setting = {SETTING_SECTION_M64P, "SaveStatePath", CoreGetDefaultSaveStateDirectory(), "", true};
|
||||
break;
|
||||
case SettingsID::Core_SaveSRAMPath:
|
||||
setting = {SETTING_SECTION_M64P, "SaveSRAMPath", "Save/Game", "", true};
|
||||
setting = {SETTING_SECTION_M64P, "SaveSRAMPath", CoreGetDefaultSaveDirectory(), "", true};
|
||||
break;
|
||||
case SettingsID::Core_SharedDataPath:
|
||||
setting = {SETTING_SECTION_M64P, "SharedDataPath", "Data", "", true};
|
||||
setting = {SETTING_SECTION_M64P, "SharedDataPath", CoreGetSharedDataDirectory(), "", true};
|
||||
break;
|
||||
|
||||
case SettingsID::Core_64DD_RomFile:
|
||||
setting = {SETTING_SECTION_CORE, "64DD_RomFile", "", "", false};
|
||||
setting = {SETTING_SECTION_CORE, "64DD_RomFile", ""};
|
||||
break;
|
||||
|
||||
case SettingsID::Game_DisableExtraMem:
|
||||
setting = {"", "DisableExtraMem", false, "", false};
|
||||
setting = {"", "DisableExtraMem", false};
|
||||
break;
|
||||
case SettingsID::Game_SaveType:
|
||||
setting = {"", "SaveType", 0, "", false};
|
||||
setting = {"", "SaveType", 0};
|
||||
break;
|
||||
case SettingsID::Game_CountPerOp:
|
||||
setting = {"", "CountPerOp", 2, "", false};
|
||||
setting = {"", "CountPerOp", 2};
|
||||
break;
|
||||
case SettingsID::Game_SiDmaDuration:
|
||||
setting = {"", "SiDmaDuration", 2304, "", false};
|
||||
setting = {"", "SiDmaDuration", 2304};
|
||||
break;
|
||||
|
||||
case SettingsID::Game_OverrideCoreSettings:
|
||||
setting = {"", "OverrideCoreSettings", false, "", false};
|
||||
setting = {"", "OverrideCoreSettings", false};
|
||||
break;
|
||||
case SettingsID::Game_CPU_Emulator:
|
||||
setting = {"", "CPU_Emulator", 2, "", false};
|
||||
setting = {"", "CPU_Emulator", 2};
|
||||
break;
|
||||
case SettingsID::Game_RandomizeInterrupt:
|
||||
setting = {"", "RandomizeInterrupt", true, "", false};
|
||||
setting = {"", "RandomizeInterrupt", true};
|
||||
break;
|
||||
|
||||
case SettingsID::Game_GFX_Plugin:
|
||||
setting = {"", "GFX_Plugin", "", "", false};
|
||||
setting = {"", "GFX_Plugin", ""};
|
||||
break;
|
||||
case SettingsID::Game_AUDIO_Plugin:
|
||||
setting = {"", "AUDIO_Plugin", "", "", false};
|
||||
setting = {"", "AUDIO_Plugin", ""};
|
||||
break;
|
||||
case SettingsID::Game_INPUT_Plugin:
|
||||
setting = {"", "INPUT_Plugin", "", "", false};
|
||||
setting = {"", "INPUT_Plugin", ""};
|
||||
break;
|
||||
case SettingsID::Game_RSP_Plugin:
|
||||
setting = {"", "RSP_Plugin", "", "", false};
|
||||
setting = {"", "RSP_Plugin", ""};
|
||||
break;
|
||||
|
||||
case SettingsID::KeyBinding_OpenROM:
|
||||
setting = {SETTING_SECTION_KEYBIND, "OpenROM", "Ctrl+O", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "OpenROM", "Ctrl+O"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_OpenCombo:
|
||||
setting = {SETTING_SECTION_KEYBIND, "OpenCombo", "Ctrl+Shift+O", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "OpenCombo", "Ctrl+Shift+O"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_StartEmulation:
|
||||
setting = {SETTING_SECTION_KEYBIND, "StartEmulation", "F11", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "StartEmulation", "F11"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_EndEmulation:
|
||||
setting = {SETTING_SECTION_KEYBIND, "EndEmulation", "F12", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "EndEmulation", "F12"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_RefreshROMList:
|
||||
setting = {SETTING_SECTION_KEYBIND, "RefreshROMList", "F5", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "RefreshROMList", "F5"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_Exit:
|
||||
setting = {SETTING_SECTION_KEYBIND, "Exit", "Alt+F4", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "Exit", "Alt+F4"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_SoftReset:
|
||||
setting = {SETTING_SECTION_KEYBIND, "SoftReset", "F1", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "SoftReset", "F1"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_HardReset:
|
||||
setting = {SETTING_SECTION_KEYBIND, "HardReset", "Shift+F1", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "HardReset", "Shift+F1"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_Resume:
|
||||
setting = {SETTING_SECTION_KEYBIND, "Resume", "F2", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "Resume", "F2"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_GenerateBitmap:
|
||||
setting = {SETTING_SECTION_KEYBIND, "GenerateBitmap", "F3", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "GenerateBitmap", "F3"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_LimitFPS:
|
||||
setting = {SETTING_SECTION_KEYBIND, "LimitFPS", "F4", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "LimitFPS", "F4"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_SwapDisk:
|
||||
setting = {SETTING_SECTION_KEYBIND, "SwapDisk", "Ctrl+D", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "SwapDisk", "Ctrl+D"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_SaveState:
|
||||
setting = {SETTING_SECTION_KEYBIND, "SaveState", "F5", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "SaveState", "F5"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_SaveAs:
|
||||
setting = {SETTING_SECTION_KEYBIND, "SaveAs", "Ctrl+S", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "SaveAs", "Ctrl+S"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_LoadState:
|
||||
setting = {SETTING_SECTION_KEYBIND, "LoadState", "F7", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "LoadState", "F7"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_Load:
|
||||
setting = {SETTING_SECTION_KEYBIND, "Load", "Ctrl+L", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "Load", "Ctrl+L"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_Cheats:
|
||||
setting = {SETTING_SECTION_KEYBIND, "Cheats", "Ctrl+C", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "Cheats", "Ctrl+C"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_GSButton:
|
||||
setting = {SETTING_SECTION_KEYBIND, "GSButton", "F9", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "GSButton", "F9"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_Fullscreen:
|
||||
setting = {SETTING_SECTION_KEYBIND, "Fullscreen", "Alt+Return", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "Fullscreen", "Alt+Return"};
|
||||
break;
|
||||
case SettingsID::KeyBinding_Settings:
|
||||
setting = {SETTING_SECTION_KEYBIND, "Settings", "Ctrl+T", "", false};
|
||||
setting = {SETTING_SECTION_KEYBIND, "Settings", "Ctrl+T"};
|
||||
break;
|
||||
|
||||
case SettingsID::RomBrowser_Directory:
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "Directory", "", "", false};
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "Directory", ""};
|
||||
break;
|
||||
case SettingsID::RomBrowser_Geometry:
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "Geometry", "", "", false};
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "Geometry", ""};
|
||||
break;
|
||||
case SettingsID::RomBrowser_Recursive:
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "Recursive", true, "", false};
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "Recursive", true};
|
||||
break;
|
||||
case SettingsID::RomBrowser_MaxItems:
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "MaxItems", 50, "", false};
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "MaxItems", 50};
|
||||
break;
|
||||
case SettingsID::RomBrowser_Columns:
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "Columns", std::vector<int>({0, 1, 2}), "", false};
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "Columns", std::vector<int>({0, 1, 2})};
|
||||
break;
|
||||
case SettingsID::RomBrowser_ColumnSizes:
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "ColumnSizes", std::vector<int>({0, 250, 1, 100, 2, 100}), "", false};
|
||||
setting = {SETTING_SECTION_ROMBROWSER, "ColumnSizes", std::vector<int>({0, 250, 1, 100, 2, 100})};
|
||||
break;
|
||||
|
||||
case SettingsID::Settings_HasForceUsedSetOnce:
|
||||
setting = {SETTING_SECTION_SETTINGS, "HasForceUsedSetOnce", false};
|
||||
break;
|
||||
|
||||
case SettingsID::Audio_Volume:
|
||||
setting = {SETTING_SECTION_AUDIO, "Volume", 100};
|
||||
break;
|
||||
case SettingsID::Audio_Muted:
|
||||
setting = {SETTING_SECTION_AUDIO, "Muted", false};
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -509,7 +535,9 @@ bool CoreSettingsSave(void)
|
||||
bool CoreSettingsSetupDefaults(void)
|
||||
{
|
||||
l_Setting setting;
|
||||
bool ret;
|
||||
bool ret, hasForceUsedSetOnce;
|
||||
|
||||
hasForceUsedSetOnce = CoreSettingsGetBoolValue(SettingsID::Settings_HasForceUsedSetOnce);
|
||||
|
||||
for (int i = 0; i < (int)SettingsID::Invalid; i++)
|
||||
{
|
||||
@@ -524,11 +552,11 @@ bool CoreSettingsSetupDefaults(void)
|
||||
{
|
||||
case M64TYPE_STRING:
|
||||
{
|
||||
if (setting.ForceUseSet)
|
||||
if (setting.ForceUseSetOnce && !hasForceUsedSetOnce)
|
||||
{
|
||||
ret = config_option_set(setting.Section, setting.Key, M64TYPE_STRING, (void*)setting.DefaultValue.stringValue.c_str());
|
||||
}
|
||||
else
|
||||
else if (!setting.ForceUseSetOnce)
|
||||
{
|
||||
ret = config_option_default_set(setting.Section, setting.Key, M64TYPE_STRING, (void*)setting.DefaultValue.stringValue.c_str(), setting.Description.c_str());
|
||||
}
|
||||
@@ -550,6 +578,11 @@ bool CoreSettingsSetupDefaults(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasForceUsedSetOnce)
|
||||
{
|
||||
CoreSettingsSetValue(SettingsID::Settings_HasForceUsedSetOnce, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ enum class SettingsID
|
||||
GUI_AllowManualResizing,
|
||||
GUI_HideCursorInEmulation,
|
||||
GUI_StatusbarMessageDuration,
|
||||
GUI_PauseEmulationOnFocusLoss,
|
||||
GUI_ResumeEmulationOnFocus,
|
||||
|
||||
// Core Plugin Settings
|
||||
Core_GFX_Plugin,
|
||||
@@ -86,6 +88,13 @@ enum class SettingsID
|
||||
RomBrowser_Columns,
|
||||
RomBrowser_ColumnSizes,
|
||||
|
||||
// Settings Settings
|
||||
Settings_HasForceUsedSetOnce,
|
||||
|
||||
// Audio Plugin Settings
|
||||
Audio_Volume,
|
||||
Audio_Muted,
|
||||
|
||||
Invalid
|
||||
};
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ set(RMG_SOURCES
|
||||
UserInterface/Dialog/SettingsDialog.cpp
|
||||
UserInterface/Dialog/SettingsDialog.ui
|
||||
UserInterface/Dialog/SettingsDialog.qrc
|
||||
UserInterface/Dialog/RomInfoDialog.cpp
|
||||
UserInterface/Dialog/RomInfoDialog.ui
|
||||
UserInterface/NoFocusDelegate.cpp
|
||||
UserInterface/EventFilter.cpp
|
||||
UserInterface/UIResources.rc
|
||||
|
||||
@@ -6,6 +6,5 @@
|
||||
#define WINDOW_WIDGET_SIZE_H 480
|
||||
|
||||
#define APP_URL_HOMEPAGE "https://github.com/Rosalie241/RMG"
|
||||
#define APP_STYLESHEET_FILE "Config/stylesheet.qss"
|
||||
|
||||
#endif // CONFIG_HPP
|
||||
|
||||
@@ -23,12 +23,7 @@ RomSearcherThread::RomSearcherThread(QObject *parent) : QThread(parent)
|
||||
|
||||
RomSearcherThread::~RomSearcherThread(void)
|
||||
{
|
||||
// kill the thread when we're running
|
||||
if (this->isRunning())
|
||||
{
|
||||
this->terminate();
|
||||
this->wait();
|
||||
}
|
||||
this->Stop();
|
||||
}
|
||||
|
||||
void RomSearcherThread::SetDirectory(QString directory)
|
||||
@@ -46,8 +41,18 @@ void RomSearcherThread::SetMaximumFiles(int value)
|
||||
this->rom_Search_MaxItems = value;
|
||||
}
|
||||
|
||||
void RomSearcherThread::Stop(void)
|
||||
{
|
||||
this->rom_Search_Stop = true;
|
||||
while (this->isRunning())
|
||||
{
|
||||
this->wait();
|
||||
}
|
||||
}
|
||||
|
||||
void RomSearcherThread::run(void)
|
||||
{
|
||||
this->rom_Search_Stop = false;
|
||||
this->rom_Search(this->rom_Directory);
|
||||
return;
|
||||
}
|
||||
@@ -95,6 +100,11 @@ void RomSearcherThread::rom_Search(QString directory)
|
||||
|
||||
emit this->on_Rom_Found(file, header, settings);
|
||||
}
|
||||
|
||||
if (this->rom_Search_Stop)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ class RomSearcherThread : public QThread
|
||||
void SetDirectory(QString);
|
||||
void SetRecursive(bool);
|
||||
void SetMaximumFiles(int);
|
||||
void Stop(void);
|
||||
|
||||
void run(void) override;
|
||||
|
||||
@@ -35,6 +36,7 @@ class RomSearcherThread : public QThread
|
||||
QString rom_Directory;
|
||||
bool rom_Search_Recursive;
|
||||
int rom_Search_MaxItems;
|
||||
bool rom_Search_Stop = false;
|
||||
|
||||
void rom_Search(QString);
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "RomInfoDialog.hpp"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QFileInfo>
|
||||
|
||||
using namespace UserInterface::Dialog;
|
||||
|
||||
RomInfoDialog::RomInfoDialog(QString file, QWidget *parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint)
|
||||
{
|
||||
this->setupUi(this);
|
||||
|
||||
bool needCloseRom = false;
|
||||
|
||||
CoreRomHeader romHeader;
|
||||
CoreRomSettings romSettings;
|
||||
|
||||
// try to open ROM
|
||||
if (!CoreOpenRom(file.toStdString()))
|
||||
{
|
||||
this->showErrorMessage(parent, "CoreOpenRom() Failed", QString::fromStdString(CoreGetError()));
|
||||
return;
|
||||
}
|
||||
|
||||
// try to retrieve ROM header
|
||||
if (!CoreGetCurrentRomHeader(romHeader))
|
||||
{
|
||||
this->showErrorMessage(parent, "CoreGetCurrentRomHeader() Failed", QString::fromStdString(CoreGetError()));
|
||||
return;
|
||||
}
|
||||
|
||||
// try to retrieve ROM settings
|
||||
if (!CoreGetCurrentRomSettings(romSettings))
|
||||
{
|
||||
this->showErrorMessage(parent, "CoreGetCurrentRomSettings() Failed", QString::fromStdString(CoreGetError()));
|
||||
return;
|
||||
}
|
||||
|
||||
QFileInfo qFileInfo(file);
|
||||
|
||||
this->romNameLineEdit->setText(QString::fromStdString(romHeader.Name));
|
||||
this->md5LineEdit->setText(QString::fromStdString(romSettings.MD5));
|
||||
this->fileNameLineEdit->setText(qFileInfo.fileName());
|
||||
this->locationLineEdit->setText(qFileInfo.absolutePath());
|
||||
this->crc1LineEdit->setText(QString::number(romHeader.CRC1, 16).toUpper());
|
||||
this->crc2LineEdit->setText(QString::number(romHeader.CRC2, 16).toUpper());
|
||||
|
||||
if (!CoreCloseRom())
|
||||
{
|
||||
this->showErrorMessage(parent, "CoreCloseRom() Failed", QString::fromStdString(CoreGetError()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RomInfoDialog::~RomInfoDialog(void)
|
||||
{
|
||||
}
|
||||
|
||||
void RomInfoDialog::showErrorMessage(QWidget* parent, QString error, QString details)
|
||||
{
|
||||
QMessageBox msgBox(parent);
|
||||
msgBox.setIcon(QMessageBox::Icon::Critical);
|
||||
msgBox.setWindowTitle("Error");
|
||||
msgBox.setText(error);
|
||||
msgBox.setDetailedText(details);
|
||||
msgBox.addButton(QMessageBox::Ok);
|
||||
msgBox.exec();
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
||||
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef ROMINFODIALOG_HPP
|
||||
#define ROMINFODIALOG_HPP
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
|
||||
#include <RMG-Core/Core.hpp>
|
||||
|
||||
#include "ui_RomInfoDialog.h"
|
||||
|
||||
namespace UserInterface
|
||||
{
|
||||
namespace Dialog
|
||||
{
|
||||
class RomInfoDialog : public QDialog, private Ui::RomInfoDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
void showErrorMessage(QWidget* parent, QString error, QString details);
|
||||
|
||||
public:
|
||||
RomInfoDialog(QString file, QWidget *parent);
|
||||
~RomInfoDialog(void);
|
||||
};
|
||||
} // namespace Dialog
|
||||
} // namespace UserInterface
|
||||
|
||||
#endif // ROMINFODIALOG_HPP
|
||||
@@ -0,0 +1,251 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>RomInfoDialog</class>
|
||||
<widget class="QDialog" name="RomInfoDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>376</width>
|
||||
<height>456</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>ROM Information</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ROM Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="romNameLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>File Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="fileNameLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Location:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="locationLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>MD5:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="md5LineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>CRC1:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="crc1LineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>CRC2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="crc2LineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>161</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>RomInfoDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>RomInfoDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "SettingsDialog.hpp"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
using namespace UserInterface::Dialog;
|
||||
|
||||
@@ -17,12 +18,19 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent, Qt::WindowSyst
|
||||
{
|
||||
this->setupUi(this);
|
||||
|
||||
this->inGame = CoreIsEmulationRunning() || CoreIsEmulationPaused();
|
||||
if (inGame)
|
||||
this->romOpened = CoreHasRomOpen();
|
||||
if (romOpened)
|
||||
{
|
||||
CoreGetCurrentRomSettings(this->currentGameSettings);
|
||||
CoreGetCurrentDefaultRomSettings(this->defaultGameSettings);
|
||||
this->gameSection = this->currentGameSettings.MD5;
|
||||
|
||||
// no need to show emulation info text,
|
||||
// when we're not running/paused
|
||||
if (!CoreIsEmulationRunning() && !CoreIsEmulationPaused())
|
||||
{
|
||||
this->hideEmulationInfoText();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -55,6 +63,11 @@ SettingsDialog::~SettingsDialog(void)
|
||||
CoreSettingsSave();
|
||||
}
|
||||
|
||||
void SettingsDialog::ShowGameTab(void)
|
||||
{
|
||||
this->tabWidget->setCurrentIndex(1);
|
||||
}
|
||||
|
||||
int SettingsDialog::currentIndex(void)
|
||||
{
|
||||
int currentIndex = this->tabWidget->currentIndex();
|
||||
@@ -88,7 +101,7 @@ void SettingsDialog::restoreDefaults(int stackedWidgetIndex)
|
||||
loadDefaultGamePluginSettings();
|
||||
break;
|
||||
case 4:
|
||||
loadPluginSettings();
|
||||
loadDefaultPluginSettings();
|
||||
break;
|
||||
case 5:
|
||||
loadDefaultDirectorySettings();
|
||||
@@ -243,40 +256,7 @@ void SettingsDialog::loadGamePluginSettings(void)
|
||||
|
||||
void SettingsDialog::loadPluginSettings(void)
|
||||
{
|
||||
QComboBox *comboBoxArray[] = {this->rspPluginsComboBox, this->videoPluginsComboBox,
|
||||
this->audioPluginsComboBox, this->inputPluginsComboBox};
|
||||
SettingsID settingsIdArray[] = {SettingsID::Core_RSP_Plugin, SettingsID::Core_GFX_Plugin,
|
||||
SettingsID::Core_AUDIO_Plugin, SettingsID::Core_INPUT_Plugin};
|
||||
bool pluginFound[] = {false, false, false, false};
|
||||
|
||||
QComboBox *comboBox;
|
||||
std::string pluginFileName;
|
||||
int index = 0;
|
||||
|
||||
for (const auto &p : this->pluginList)
|
||||
{
|
||||
index = ((int)p.Type - 1);
|
||||
comboBox = comboBoxArray[index];
|
||||
pluginFileName = CoreSettingsGetStringValue(settingsIdArray[index]);
|
||||
|
||||
comboBox->addItem(QString::fromStdString(p.Name), QString::fromStdString(p.File));
|
||||
|
||||
if (pluginFileName == p.File)
|
||||
{
|
||||
comboBox->setCurrentText(QString::fromStdString(p.Name));
|
||||
pluginFound[index] = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
comboBox = comboBoxArray[i];
|
||||
if (!pluginFound[i])
|
||||
{
|
||||
comboBox->addItem("", "");
|
||||
comboBox->setCurrentText("");
|
||||
}
|
||||
}
|
||||
this->commonPluginSettings(0);
|
||||
}
|
||||
|
||||
void SettingsDialog::loadDirectorySettings(void)
|
||||
@@ -316,6 +296,8 @@ void SettingsDialog::loadHotkeySettings(void)
|
||||
void SettingsDialog::loadInterfaceSettings(void)
|
||||
{
|
||||
this->manualResizingCheckBox->setChecked(CoreSettingsGetBoolValue(SettingsID::GUI_AllowManualResizing));
|
||||
this->pauseEmulationOnFocusCheckbox->setChecked(CoreSettingsGetBoolValue(SettingsID::GUI_PauseEmulationOnFocusLoss));
|
||||
this->resumeEmulationOnFocusCheckBox->setChecked(CoreSettingsGetBoolValue(SettingsID::GUI_ResumeEmulationOnFocus));
|
||||
this->hideCursorCheckBox->setChecked(CoreSettingsGetBoolValue(SettingsID::GUI_HideCursorInEmulation));
|
||||
this->statusBarMessageDurationSpinBox->setValue(CoreSettingsGetIntValue(SettingsID::GUI_StatusbarMessageDuration));
|
||||
this->searchSubDirectoriesCheckbox->setChecked(CoreSettingsGetBoolValue(SettingsID::RomBrowser_Recursive));
|
||||
@@ -392,6 +374,11 @@ void SettingsDialog::loadDefaultGamePluginSettings(void)
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::loadDefaultPluginSettings(void)
|
||||
{
|
||||
this->commonPluginSettings(1);
|
||||
}
|
||||
|
||||
void SettingsDialog::loadDefaultDirectorySettings(void)
|
||||
{
|
||||
this->screenshotDirLineEdit->setText(QString::fromStdString(CoreSettingsGetDefaultStringValue(SettingsID::Core_ScreenshotPath)));
|
||||
@@ -411,6 +398,8 @@ void SettingsDialog::loadDefaultHotkeySettings(void)
|
||||
void SettingsDialog::loadDefaultInterfaceSettings(void)
|
||||
{
|
||||
this->manualResizingCheckBox->setChecked(CoreSettingsGetDefaultBoolValue(SettingsID::GUI_AllowManualResizing));
|
||||
this->pauseEmulationOnFocusCheckbox->setChecked(CoreSettingsGetDefaultBoolValue(SettingsID::GUI_PauseEmulationOnFocusLoss));
|
||||
this->resumeEmulationOnFocusCheckBox->setChecked(CoreSettingsGetDefaultBoolValue(SettingsID::GUI_ResumeEmulationOnFocus));
|
||||
this->hideCursorCheckBox->setChecked(CoreSettingsGetDefaultBoolValue(SettingsID::GUI_HideCursorInEmulation));
|
||||
this->statusBarMessageDurationSpinBox->setValue(CoreSettingsGetDefaultIntValue(SettingsID::GUI_StatusbarMessageDuration));
|
||||
this->searchSubDirectoriesCheckbox->setChecked(CoreSettingsGetDefaultBoolValue(SettingsID::RomBrowser_Recursive));
|
||||
@@ -420,7 +409,7 @@ void SettingsDialog::loadDefaultInterfaceSettings(void)
|
||||
void SettingsDialog::saveSettings(void)
|
||||
{
|
||||
this->saveCoreSettings();
|
||||
if (inGame)
|
||||
if (romOpened)
|
||||
{
|
||||
// clean 'game settings'
|
||||
CoreSettingsDeleteSection(this->gameSection);
|
||||
@@ -468,20 +457,14 @@ void SettingsDialog::saveGameSettings(void)
|
||||
int countPerOp = this->gameCounterFactorComboBox->currentIndex() + 1;
|
||||
int siDmaDuration = this->gameSiDmaDurationSpinBox->value();
|
||||
|
||||
if (this->defaultGameSettings.DisableExtraMem != disableExtraMem)
|
||||
if ((this->defaultGameSettings.DisableExtraMem != disableExtraMem) ||
|
||||
(this->defaultGameSettings.SaveType != saveType) ||
|
||||
(this->defaultGameSettings.CountPerOp != countPerOp) ||
|
||||
(this->defaultGameSettings.SiDMADuration != siDmaDuration))
|
||||
{
|
||||
CoreSettingsSetValue(SettingsID::Game_DisableExtraMem, this->gameSection, disableExtraMem);
|
||||
}
|
||||
if (this->defaultGameSettings.SaveType != saveType)
|
||||
{
|
||||
CoreSettingsSetValue(SettingsID::Game_SaveType, this->gameSection, saveType);
|
||||
}
|
||||
if (this->defaultGameSettings.CountPerOp != countPerOp)
|
||||
{
|
||||
CoreSettingsSetValue(SettingsID::Game_CountPerOp, this->gameSection, countPerOp);
|
||||
}
|
||||
if (this->defaultGameSettings.SiDMADuration != siDmaDuration)
|
||||
{
|
||||
CoreSettingsSetValue(SettingsID::Game_SiDmaDuration, this->gameSection, siDmaDuration);
|
||||
}
|
||||
}
|
||||
@@ -545,13 +528,6 @@ void SettingsDialog::savePluginSettings(void)
|
||||
|
||||
CoreSettingsSetValue(settingId, comboBox->currentData().toString().toStdString());
|
||||
}
|
||||
|
||||
// only apply plugin settings when
|
||||
// emulation isn't running
|
||||
if (!CoreIsEmulationPaused() && !CoreIsEmulationRunning())
|
||||
{
|
||||
CoreApplyPluginSettings();
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::saveDirectorySettings(void)
|
||||
@@ -575,6 +551,8 @@ void SettingsDialog::saveInterfaceSettings(void)
|
||||
{
|
||||
CoreSettingsSetValue(SettingsID::GUI_AllowManualResizing, this->manualResizingCheckBox->isChecked());
|
||||
CoreSettingsSetValue(SettingsID::GUI_HideCursorInEmulation, this->hideCursorCheckBox->isChecked());
|
||||
CoreSettingsSetValue(SettingsID::GUI_PauseEmulationOnFocusLoss, this->pauseEmulationOnFocusCheckbox->isChecked());
|
||||
CoreSettingsSetValue(SettingsID::GUI_ResumeEmulationOnFocus, this->resumeEmulationOnFocusCheckBox->isChecked());
|
||||
CoreSettingsSetValue(SettingsID::GUI_StatusbarMessageDuration, this->statusBarMessageDurationSpinBox->value());
|
||||
CoreSettingsSetValue(SettingsID::RomBrowser_Recursive, this->searchSubDirectoriesCheckbox->isChecked());
|
||||
CoreSettingsSetValue(SettingsID::RomBrowser_MaxItems, this->romSearchLimitSpinBox->value());
|
||||
@@ -628,9 +606,58 @@ void SettingsDialog::commonHotkeySettings(int action)
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::commonPluginSettings(int action)
|
||||
{
|
||||
QComboBox *comboBoxArray[] = {this->rspPluginsComboBox, this->videoPluginsComboBox,
|
||||
this->audioPluginsComboBox, this->inputPluginsComboBox};
|
||||
SettingsID settingsIdArray[] = {SettingsID::Core_RSP_Plugin, SettingsID::Core_GFX_Plugin,
|
||||
SettingsID::Core_AUDIO_Plugin, SettingsID::Core_INPUT_Plugin};
|
||||
bool pluginFound[] = {false, false, false, false};
|
||||
|
||||
QComboBox *comboBox;
|
||||
std::string pluginFileName;
|
||||
int index = 0;
|
||||
|
||||
// clear combobox items
|
||||
for (const auto& c : comboBoxArray)
|
||||
{
|
||||
c->clear();
|
||||
}
|
||||
|
||||
for (const auto &p : this->pluginList)
|
||||
{
|
||||
index = ((int)p.Type - 1);
|
||||
comboBox = comboBoxArray[index];
|
||||
|
||||
pluginFileName = action == 0 ?
|
||||
CoreSettingsGetStringValue(settingsIdArray[index]) :
|
||||
CoreSettingsGetDefaultStringValue(settingsIdArray[index]);
|
||||
|
||||
comboBox->addItem(QString::fromStdString(p.Name), QString::fromStdString(p.File));
|
||||
|
||||
if (pluginFileName == p.File)
|
||||
{
|
||||
comboBox->setCurrentText(QString::fromStdString(p.Name));
|
||||
pluginFound[index] = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
comboBox = comboBoxArray[i];
|
||||
if (!pluginFound[i])
|
||||
{
|
||||
comboBox->addItem("", "");
|
||||
comboBox->setCurrentText("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::hideEmulationInfoText(void)
|
||||
{
|
||||
QHBoxLayout *layouts[] = {this->emulationInfoLayout_0, this->emulationInfoLayout_1, this->emulationInfoLayout_2};
|
||||
QHBoxLayout *layouts[] = {this->emulationInfoLayout_0, this->emulationInfoLayout_1,
|
||||
this->emulationInfoLayout_2, this->emulationInfoLayout_9,
|
||||
this->emulationInfoLayout_13};
|
||||
|
||||
for (const auto &layout : layouts)
|
||||
{
|
||||
@@ -666,6 +693,33 @@ void SettingsDialog::on_buttonBox_clicked(QAbstractButton *button)
|
||||
QPushButton *cancelButton = this->buttonBox->button(QDialogButtonBox::Cancel);
|
||||
QPushButton *okButton = this->buttonBox->button(QDialogButtonBox::Ok);
|
||||
|
||||
|
||||
if (pushButton == cancelButton || pushButton == okButton)
|
||||
{
|
||||
if (pushButton == okButton)
|
||||
{
|
||||
this->saveSettings();
|
||||
}
|
||||
|
||||
// attempt to apply plugin settings when emulation
|
||||
// isn't running, when it fails, show the user the error and
|
||||
// don't allow the user to save invalid settings
|
||||
if (!CoreIsEmulationPaused() && !CoreIsEmulationRunning())
|
||||
{
|
||||
if (!CoreApplyPluginSettings())
|
||||
{
|
||||
QMessageBox msgBox(this);
|
||||
msgBox.setIcon(QMessageBox::Icon::Critical);
|
||||
msgBox.setWindowTitle("Error");
|
||||
msgBox.setText("CoreApplyPluginSettings() Failed");
|
||||
msgBox.setDetailedText(QString::fromStdString(CoreGetError()));
|
||||
msgBox.addButton(QMessageBox::Ok);
|
||||
msgBox.exec();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pushButton == defaultButton)
|
||||
{
|
||||
this->restoreDefaults(this->currentIndex());
|
||||
@@ -676,7 +730,6 @@ void SettingsDialog::on_buttonBox_clicked(QAbstractButton *button)
|
||||
}
|
||||
else if (pushButton == okButton)
|
||||
{
|
||||
this->saveSettings();
|
||||
this->accept();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class SettingsDialog : public QDialog, private Ui::SettingsDialog
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
bool inGame = false;
|
||||
bool romOpened = false;
|
||||
|
||||
CoreRomSettings currentGameSettings;
|
||||
CoreRomSettings defaultGameSettings;
|
||||
@@ -61,6 +61,7 @@ class SettingsDialog : public QDialog, private Ui::SettingsDialog
|
||||
void loadDefaultGameSettings(void);
|
||||
void loadDefaultGameCoreSettings(void);
|
||||
void loadDefaultGamePluginSettings(void);
|
||||
void loadDefaultPluginSettings(void);
|
||||
void loadDefaultDirectorySettings(void);
|
||||
void loadDefaultHotkeySettings(void);
|
||||
void loadDefaultInterfaceSettings(void);
|
||||
@@ -76,6 +77,7 @@ class SettingsDialog : public QDialog, private Ui::SettingsDialog
|
||||
void saveInterfaceSettings(void);
|
||||
|
||||
void commonHotkeySettings(int);
|
||||
void commonPluginSettings(int);
|
||||
|
||||
void hideEmulationInfoText(void);
|
||||
|
||||
@@ -94,6 +96,8 @@ class SettingsDialog : public QDialog, private Ui::SettingsDialog
|
||||
public:
|
||||
SettingsDialog(QWidget *parent);
|
||||
~SettingsDialog(void);
|
||||
|
||||
void ShowGameTab(void);
|
||||
};
|
||||
} // namespace Dialog
|
||||
} // namespace UserInterface
|
||||
|
||||
@@ -1588,6 +1588,20 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="pauseEmulationOnFocusCheckbox">
|
||||
<property name="text">
|
||||
<string>Pause Emulation On Focus Loss</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="resumeEmulationOnFocusCheckBox">
|
||||
<property name="text">
|
||||
<string>Resume Emulation On Focus Gain</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
|
||||
@@ -27,17 +27,6 @@ bool EventFilter::eventFilter(QObject *object, QEvent *event)
|
||||
case QEvent::Type::KeyRelease:
|
||||
emit this->on_EventFilter_KeyReleased((QKeyEvent *)event);
|
||||
return true;
|
||||
// it seems like Qt loses focus whenever you click on the menubar,
|
||||
// even when re-implementing QMenuBar's focusIn/Out, it wont work correctly.
|
||||
/*case QEvent::Type::FocusIn:
|
||||
lastFocusObject = object;
|
||||
std::cout << object << std::endl;
|
||||
emit this->on_EventFilter_FocusIn((QFocusEvent *)event);
|
||||
return true;
|
||||
case QEvent::Type::FocusOut:
|
||||
if (lastFocusObject == object)
|
||||
emit this->on_EventFilter_FocusOut((QFocusEvent *)event);
|
||||
return true;*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ MainWindow::~MainWindow()
|
||||
{
|
||||
}
|
||||
|
||||
bool MainWindow::Init(void)
|
||||
bool MainWindow::Init(QGuiApplication* app)
|
||||
{
|
||||
if (!CoreInit())
|
||||
{
|
||||
@@ -47,6 +47,11 @@ bool MainWindow::Init(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CoreApplyPluginSettings())
|
||||
{
|
||||
this->ui_MessageBox("Error", "CoreApplyPluginSettings() Failed", QString::fromStdString(CoreGetError()));
|
||||
}
|
||||
|
||||
this->ui_Init();
|
||||
this->ui_Setup();
|
||||
|
||||
@@ -73,6 +78,7 @@ bool MainWindow::Init(void)
|
||||
}
|
||||
|
||||
connect(coreCallBacks, &CoreCallbacks::OnCoreDebugCallback, this, &MainWindow::on_Core_DebugCallback);
|
||||
connect(app, &QGuiApplication::applicationStateChanged, this, &MainWindow::on_QGuiApplication_applicationStateChanged);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -86,6 +92,8 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
this->on_Action_File_EndEmulation();
|
||||
|
||||
this->ui_Widget_RomBrowser->StopRefreshRomList();
|
||||
|
||||
this->coreCallBacks->Stop();
|
||||
|
||||
while (this->emulationThread->isRunning())
|
||||
@@ -119,8 +127,16 @@ void MainWindow::ui_Init(void)
|
||||
this->ui_Widget_RomBrowser->SetDirectory(dir);
|
||||
this->ui_Widget_RomBrowser->RefreshRomList();
|
||||
|
||||
connect(this->ui_Widget_RomBrowser, &Widget::RomBrowserWidget::on_RomBrowser_Select, this,
|
||||
&MainWindow::on_RomBrowser_Selected);
|
||||
connect(this->ui_Widget_RomBrowser, &Widget::RomBrowserWidget::on_RomBrowser_PlayGame, this,
|
||||
&MainWindow::on_RomBrowser_PlayGame);
|
||||
connect(this->ui_Widget_RomBrowser, &Widget::RomBrowserWidget::on_RomBrowser_PlayGameWithDisk, this,
|
||||
&MainWindow::on_RomBrowser_PlayGameWithDisk);
|
||||
connect(this->ui_Widget_RomBrowser, &Widget::RomBrowserWidget::on_RomBrowser_EditGameSettings, this,
|
||||
&MainWindow::on_RomBrowser_EditGameSettings);
|
||||
connect(this->ui_Widget_RomBrowser, &Widget::RomBrowserWidget::on_RomBrowser_ChooseRomDirectory, this,
|
||||
&MainWindow::on_Action_File_ChooseDirectory);
|
||||
connect(this->ui_Widget_RomBrowser, &Widget::RomBrowserWidget::on_RomBrowser_RomInformation, this,
|
||||
&MainWindow::on_RomBrowser_RomInformation);
|
||||
connect(this->ui_Widget_RomBrowser, &Widget::RomBrowserWidget::on_RomBrowser_FileDropped, this,
|
||||
&MainWindow::on_EventFilter_FileDropped);
|
||||
|
||||
@@ -130,10 +146,6 @@ void MainWindow::ui_Init(void)
|
||||
&MainWindow::on_EventFilter_KeyReleased);
|
||||
connect(this->ui_EventFilter, &EventFilter::on_EventFilter_FileDropped, this,
|
||||
&MainWindow::on_EventFilter_FileDropped);
|
||||
/*
|
||||
connect(this->ui_EventFilter, &EventFilter::on_EventFilter_FocusIn, this, &MainWindow::on_EventFilter_FocusIn);
|
||||
connect(this->ui_EventFilter, &EventFilter::on_EventFilter_FocusOut, this, &MainWindow::on_EventFilter_FocusOut);
|
||||
*/
|
||||
}
|
||||
|
||||
void MainWindow::ui_Setup(void)
|
||||
@@ -172,7 +184,11 @@ void MainWindow::ui_Setup(void)
|
||||
|
||||
void MainWindow::ui_Stylesheet_Setup(void)
|
||||
{
|
||||
QFile stylesheet(APP_STYLESHEET_FILE);
|
||||
QString stylesheetFile;
|
||||
stylesheetFile = QString::fromStdString(CoreGetSharedDataDirectory());
|
||||
stylesheetFile += "/stylesheet.qss";
|
||||
|
||||
QFile stylesheet(stylesheetFile);
|
||||
|
||||
if (!stylesheet.open(QIODevice::ReadOnly))
|
||||
{
|
||||
@@ -282,7 +298,6 @@ void MainWindow::menuBar_Setup(bool inEmulation, bool isPaused)
|
||||
this->menuBar_Menu = this->menuBar->addMenu("File");
|
||||
this->menuBar_Menu->addAction(this->action_File_OpenRom);
|
||||
this->menuBar_Menu->addAction(this->action_File_OpenCombo);
|
||||
this->menuBar_Menu->addAction(this->action_File_RomInfo);
|
||||
this->menuBar_Menu->addSeparator();
|
||||
this->menuBar_Menu->addAction(this->action_File_StartEmulation);
|
||||
this->menuBar_Menu->addAction(this->action_File_EndEmulation);
|
||||
@@ -460,7 +475,6 @@ void MainWindow::ui_Actions_Init(void)
|
||||
{
|
||||
this->action_File_OpenRom = new QAction(this);
|
||||
this->action_File_OpenCombo = new QAction(this);
|
||||
this->action_File_RomInfo = new QAction(this);
|
||||
this->action_File_StartEmulation = new QAction(this);
|
||||
this->action_File_EndEmulation = new QAction(this);
|
||||
this->action_File_Language = new QAction(this);
|
||||
@@ -504,7 +518,6 @@ void MainWindow::ui_Actions_Setup(bool inEmulation, bool isPaused)
|
||||
keyBinding = QString::fromStdString(CoreSettingsGetStringValue(SettingsID::KeyBinding_OpenCombo));
|
||||
this->action_File_OpenCombo->setText("Open Combo");
|
||||
this->action_File_OpenCombo->setShortcut(QKeySequence(keyBinding));
|
||||
this->action_File_RomInfo->setText("ROM Info....");
|
||||
keyBinding = QString::fromStdString(CoreSettingsGetStringValue(SettingsID::KeyBinding_StartEmulation));
|
||||
this->action_File_StartEmulation->setText("Start Emulation");
|
||||
this->action_File_StartEmulation->setShortcut(QKeySequence(keyBinding));
|
||||
@@ -733,32 +746,38 @@ void MainWindow::on_EventFilter_FileDropped(QDropEvent *event)
|
||||
this->emulationThread_Launch(file);
|
||||
}
|
||||
|
||||
/* TODO for some day
|
||||
void MainWindow::on_EventFilter_FocusIn(QFocusEvent *event)
|
||||
void MainWindow::on_QGuiApplication_applicationStateChanged(Qt::ApplicationState state)
|
||||
{
|
||||
std::cout << "MainWindow::on_EventFilter_FocusIn" << std::endl;
|
||||
if (g_Settings.GetBoolValue(SettingsID::GUI_ResumeEmulationOnFocus))
|
||||
bool isRunning = CoreIsEmulationRunning();
|
||||
bool isPaused = CoreIsEmulationPaused();
|
||||
|
||||
bool pauseOnFocusLoss = CoreSettingsGetBoolValue(SettingsID::GUI_PauseEmulationOnFocusLoss);
|
||||
bool resumeOnFocus = CoreSettingsGetBoolValue(SettingsID::GUI_ResumeEmulationOnFocus);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
if (CoreIsEmulationPaused())
|
||||
this->on_Action_System_Pause();
|
||||
default:
|
||||
break;
|
||||
|
||||
case Qt::ApplicationState::ApplicationInactive:
|
||||
{
|
||||
if (pauseOnFocusLoss && isRunning && !isPaused)
|
||||
{
|
||||
this->on_Action_System_Pause();
|
||||
this->ui_ManuallyPaused = false;
|
||||
}
|
||||
} break;
|
||||
|
||||
case Qt::ApplicationState::ApplicationActive:
|
||||
{
|
||||
if (resumeOnFocus && isPaused && !this->ui_ManuallyPaused)
|
||||
{
|
||||
this->on_Action_System_Pause();
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
QMainWindow::focusInEvent(event);
|
||||
}
|
||||
|
||||
void MainWindow::on_EventFilter_FocusOut(QFocusEvent *event)
|
||||
{
|
||||
std::cout << "MainWindow::on_EventFilter_FocusOut" << std::endl;
|
||||
if (g_Settings.GetBoolValue(SettingsID::GUI_PauseEmulationOnFocusLoss))
|
||||
{
|
||||
if (CoreIsEmulationRunning())
|
||||
this->on_Action_System_Pause();
|
||||
}
|
||||
|
||||
QMainWindow::focusOutEvent(event);
|
||||
}
|
||||
*/
|
||||
|
||||
void MainWindow::on_Action_File_OpenRom(void)
|
||||
{
|
||||
bool isRunning = CoreIsEmulationRunning();
|
||||
@@ -769,15 +788,11 @@ void MainWindow::on_Action_File_OpenRom(void)
|
||||
this->on_Action_System_Pause();
|
||||
}
|
||||
|
||||
QFileDialog dialog(this);
|
||||
int ret;
|
||||
QString dir;
|
||||
QString romFile;
|
||||
|
||||
dialog.setFileMode(QFileDialog::FileMode::ExistingFile);
|
||||
dialog.setNameFilter("N64 ROMs & Disks (*.n64 *.z64 *.v64 *.ndd *.d64 *.zip)");
|
||||
romFile = QFileDialog::getOpenFileName(this, "", "", "N64 ROMs & Disks (*.n64 *.z64 *.v64 *.ndd *.d64 *.zip)");
|
||||
|
||||
ret = dialog.exec();
|
||||
if (!ret)
|
||||
if (romFile.isEmpty())
|
||||
{
|
||||
if (isRunning && !isPaused)
|
||||
{
|
||||
@@ -791,7 +806,7 @@ void MainWindow::on_Action_File_OpenRom(void)
|
||||
this->ui_NoSwitchToRomBrowser = true;
|
||||
}
|
||||
|
||||
this->emulationThread_Launch(dialog.selectedFiles().first());
|
||||
this->emulationThread_Launch(romFile);
|
||||
}
|
||||
|
||||
void MainWindow::on_Action_File_OpenCombo(void)
|
||||
@@ -804,15 +819,11 @@ void MainWindow::on_Action_File_OpenCombo(void)
|
||||
this->on_Action_System_Pause();
|
||||
}
|
||||
|
||||
QFileDialog dialog(this);
|
||||
int ret;
|
||||
QString dir, cartRom, diskRom;
|
||||
QString cartRom, diskRom;
|
||||
|
||||
dialog.setFileMode(QFileDialog::FileMode::ExistingFile);
|
||||
dialog.setNameFilter("N64 ROMs (*.n64 *.z64 *.v64 *.zip)");
|
||||
|
||||
ret = dialog.exec();
|
||||
if (!ret)
|
||||
cartRom = QFileDialog::getOpenFileName(this, "", "", "N64 ROMs (*.n64 *.z64 *.v64 *.zip)");
|
||||
|
||||
if (cartRom.isEmpty())
|
||||
{
|
||||
if (isRunning && !isPaused)
|
||||
{
|
||||
@@ -821,11 +832,10 @@ void MainWindow::on_Action_File_OpenCombo(void)
|
||||
return;
|
||||
}
|
||||
|
||||
cartRom = dialog.selectedFiles().first();
|
||||
|
||||
dialog.setNameFilter("N64DD Disk Image (*.ndd *.d64)");
|
||||
ret = dialog.exec();
|
||||
if (!ret)
|
||||
diskRom = QFileDialog::getOpenFileName(this, "", "", "N64DD Disk Image (*.ndd *.d64)");
|
||||
|
||||
if (diskRom.isEmpty())
|
||||
{
|
||||
if (isRunning && !isPaused)
|
||||
{
|
||||
@@ -834,8 +844,6 @@ void MainWindow::on_Action_File_OpenCombo(void)
|
||||
return;
|
||||
}
|
||||
|
||||
diskRom = dialog.selectedFiles().first();
|
||||
|
||||
if (this->ui_Widgets->currentIndex() != 0)
|
||||
{
|
||||
this->ui_NoSwitchToRomBrowser = true;
|
||||
@@ -864,18 +872,12 @@ void MainWindow::on_Action_File_EndEmulation(void)
|
||||
|
||||
void MainWindow::on_Action_File_ChooseDirectory(void)
|
||||
{
|
||||
QFileDialog dialog;
|
||||
QString dir;
|
||||
int ret;
|
||||
|
||||
dialog.setFileMode(QFileDialog::Directory);
|
||||
dialog.setOption(QFileDialog::ShowDirsOnly, true);
|
||||
dialog.setWindowIcon(this->ui_Icon);
|
||||
dir = QFileDialog::getExistingDirectory(this);
|
||||
|
||||
ret = dialog.exec();
|
||||
if (ret)
|
||||
if (!dir.isEmpty())
|
||||
{
|
||||
dir = dialog.selectedFiles().first();
|
||||
CoreSettingsSetValue(SettingsID::RomBrowser_Directory, dir.toStdString());
|
||||
this->ui_Widget_RomBrowser->SetDirectory(dir);
|
||||
this->ui_Widget_RomBrowser->RefreshRomList();
|
||||
@@ -933,6 +935,7 @@ void MainWindow::on_Action_System_Pause(void)
|
||||
}
|
||||
|
||||
this->menuBar_Setup(true, !isPaused);
|
||||
this->ui_ManuallyPaused = true;
|
||||
}
|
||||
|
||||
void MainWindow::on_Action_System_GenerateBitmap(void)
|
||||
@@ -1129,11 +1132,75 @@ void MainWindow::on_Emulation_Finished(bool ret)
|
||||
this->ui_InEmulation(false, false);
|
||||
}
|
||||
|
||||
void MainWindow::on_RomBrowser_Selected(QString file)
|
||||
void MainWindow::on_RomBrowser_PlayGame(QString file)
|
||||
{
|
||||
this->emulationThread_Launch(file);
|
||||
}
|
||||
|
||||
void MainWindow::on_RomBrowser_PlayGameWithDisk(QString file)
|
||||
{
|
||||
QString diskRom;
|
||||
|
||||
diskRom = QFileDialog::getOpenFileName(this, "", "", "N64DD Disk Image (*.ndd *.d64)");
|
||||
|
||||
if (diskRom.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this->emulationThread_Launch(file, diskRom);
|
||||
}
|
||||
|
||||
void MainWindow::on_RomBrowser_EditGameSettings(QString file)
|
||||
{
|
||||
bool isRefreshingRomList = this->ui_Widget_RomBrowser->IsRefreshingRomList();
|
||||
if (isRefreshingRomList)
|
||||
{
|
||||
this->ui_Widget_RomBrowser->StopRefreshRomList();
|
||||
}
|
||||
|
||||
if (!CoreOpenRom(file.toStdString()))
|
||||
{
|
||||
this->ui_MessageBox("Error", "CoreOpenRom() Failed", QString::fromStdString(CoreGetError()));
|
||||
return;
|
||||
}
|
||||
|
||||
Dialog::SettingsDialog dialog(this);
|
||||
dialog.ShowGameTab();
|
||||
dialog.exec();
|
||||
|
||||
this->ui_InEmulation(false, false);
|
||||
|
||||
if (!CoreCloseRom())
|
||||
{
|
||||
this->ui_MessageBox("Error", "CoreCloseRom() Failed", QString::fromStdString(CoreGetError()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (isRefreshingRomList)
|
||||
{
|
||||
this->ui_Widget_RomBrowser->RefreshRomList();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_RomBrowser_RomInformation(QString file)
|
||||
{
|
||||
bool isRefreshingRomList = this->ui_Widget_RomBrowser->IsRefreshingRomList();
|
||||
|
||||
if (isRefreshingRomList)
|
||||
{
|
||||
this->ui_Widget_RomBrowser->StopRefreshRomList();
|
||||
}
|
||||
|
||||
Dialog::RomInfoDialog dialog(file, this);
|
||||
dialog.exec();
|
||||
|
||||
if (isRefreshingRomList)
|
||||
{
|
||||
this->ui_Widget_RomBrowser->RefreshRomList();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_VidExt_Init(void)
|
||||
{
|
||||
this->ui_VidExt_Geometry_Saved = false;
|
||||
@@ -1324,6 +1391,12 @@ void MainWindow::on_Core_DebugCallback(CoreDebugMessageType type, QString messag
|
||||
return;
|
||||
}
|
||||
|
||||
// drop IS64 messages
|
||||
if (message.startsWith("IS64:"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == CoreDebugMessageType::Error)
|
||||
{
|
||||
this->ui_MessageBox("Error", "Core Error", message);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "Thread/EmulationThread.hpp"
|
||||
#include "Dialog/SettingsDialog.hpp"
|
||||
#include "Dialog/RomInfoDialog.hpp"
|
||||
#include "EventFilter.hpp"
|
||||
#include "Widget/OGLWidget.hpp"
|
||||
#include "Widget/RomBrowserWidget.hpp"
|
||||
@@ -23,6 +24,7 @@
|
||||
#include <QOpenGLWidget>
|
||||
#include <QSettings>
|
||||
#include <QStackedWidget>
|
||||
#include <QGuiApplication>
|
||||
|
||||
namespace UserInterface
|
||||
{
|
||||
@@ -34,7 +36,7 @@ class MainWindow : public QMainWindow
|
||||
MainWindow(void);
|
||||
~MainWindow(void);
|
||||
|
||||
bool Init(void);
|
||||
bool Init(QGuiApplication*);
|
||||
void OpenROM(QString);
|
||||
|
||||
private:
|
||||
@@ -54,7 +56,6 @@ class MainWindow : public QMainWindow
|
||||
QMenu *menuBar_Menu;
|
||||
QAction *action_File_OpenRom;
|
||||
QAction *action_File_OpenCombo;
|
||||
QAction *action_File_RomInfo;
|
||||
QAction *action_File_StartEmulation;
|
||||
QAction *action_File_EndEmulation;
|
||||
QAction *action_File_Language;
|
||||
@@ -97,6 +98,7 @@ class MainWindow : public QMainWindow
|
||||
bool ui_VidExtForceSetMode;
|
||||
bool ui_RefreshRomListAfterEmulation = false;
|
||||
|
||||
bool ui_ManuallyPaused = true;
|
||||
|
||||
int ui_TimerId = 0;
|
||||
int ui_TimerTimeout = 0;
|
||||
@@ -133,6 +135,8 @@ class MainWindow : public QMainWindow
|
||||
void on_EventFilter_KeyReleased(QKeyEvent *);
|
||||
void on_EventFilter_FileDropped(QDropEvent *);
|
||||
|
||||
void on_QGuiApplication_applicationStateChanged(Qt::ApplicationState);
|
||||
|
||||
void on_Action_File_OpenRom(void);
|
||||
void on_Action_File_OpenCombo(void);
|
||||
void on_Action_File_EndEmulation(void);
|
||||
@@ -164,7 +168,10 @@ class MainWindow : public QMainWindow
|
||||
void on_Emulation_Started(void);
|
||||
void on_Emulation_Finished(bool);
|
||||
|
||||
void on_RomBrowser_Selected(QString);
|
||||
void on_RomBrowser_PlayGame(QString);
|
||||
void on_RomBrowser_PlayGameWithDisk(QString);
|
||||
void on_RomBrowser_EditGameSettings(QString);
|
||||
void on_RomBrowser_RomInformation(QString);
|
||||
|
||||
public slots:
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ void KeyBindButton::keyPressEvent(QKeyEvent * event)
|
||||
|
||||
void KeyBindButton::keyReleaseEvent(QKeyEvent *event)
|
||||
{
|
||||
this->setText(this->keySequence.toString());
|
||||
this->currentText = this->keySequence.toString();
|
||||
this->clearFocus();
|
||||
}
|
||||
|
||||
@@ -69,3 +69,14 @@ void KeyBindButton::mousePressEvent(QMouseEvent *event)
|
||||
this->setText("");
|
||||
}
|
||||
}
|
||||
|
||||
void KeyBindButton::focusInEvent(QFocusEvent *event)
|
||||
{
|
||||
currentText = this->text();
|
||||
this->setText("...");
|
||||
}
|
||||
|
||||
void KeyBindButton::focusOutEvent(QFocusEvent *event)
|
||||
{
|
||||
this->setText(this->currentText);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ class KeyBindButton : public QPushButton
|
||||
{
|
||||
private:
|
||||
QKeySequence keySequence;
|
||||
QString currentText;
|
||||
|
||||
public:
|
||||
KeyBindButton(QWidget *);
|
||||
@@ -23,6 +24,8 @@ private:
|
||||
void keyPressEvent(QKeyEvent *);
|
||||
void keyReleaseEvent(QKeyEvent *);
|
||||
void mousePressEvent(QMouseEvent *);
|
||||
void focusInEvent(QFocusEvent *event);
|
||||
void focusOutEvent(QFocusEvent *event);
|
||||
};
|
||||
} // namespace Widget
|
||||
} // namespace UserInterface
|
||||
|
||||
@@ -80,7 +80,7 @@ void RomBrowserWidget::StopRefreshRomList(void)
|
||||
{
|
||||
if (this->romSearcher_Thread->isRunning())
|
||||
{
|
||||
this->romSearcher_Thread->terminate();
|
||||
this->romSearcher_Thread->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,6 +148,17 @@ void RomBrowserWidget::contextMenu_Actions_Connect(void)
|
||||
connect(this->action_EditCheats, &QAction::triggered, this, &RomBrowserWidget::on_Action_EditCheats);
|
||||
}
|
||||
|
||||
void RomBrowserWidget::contextMenu_Actions_Update(void)
|
||||
{
|
||||
bool enabled = this->selectedIndexes().count() > 0;
|
||||
|
||||
this->action_PlayGame->setEnabled(enabled);
|
||||
this->action_PlayGameWithDisk->setEnabled(enabled);
|
||||
this->action_RomInformation->setEnabled(enabled);
|
||||
this->action_EditGameSettings->setEnabled(enabled);
|
||||
this->action_EditCheats->setEnabled(enabled);
|
||||
}
|
||||
|
||||
void RomBrowserWidget::model_Init(void)
|
||||
{
|
||||
this->model_Model = new QStandardItemModel(this);
|
||||
@@ -289,10 +300,13 @@ int RomBrowserWidget::column_GetSizeSettingIndex(int column)
|
||||
|
||||
void RomBrowserWidget::launchSelectedRom(void)
|
||||
{
|
||||
QModelIndex index = this->selectedIndexes().first();
|
||||
QString rom = this->model()->itemData(index).last().toString();
|
||||
emit this->on_RomBrowser_PlayGame(this->getCurrentRom());
|
||||
}
|
||||
|
||||
emit this->on_RomBrowser_Select(rom);
|
||||
QString RomBrowserWidget::getCurrentRom(void)
|
||||
{
|
||||
QModelIndex index = this->selectedIndexes().first();
|
||||
return this->model()->itemData(index).last().toString();
|
||||
}
|
||||
|
||||
void RomBrowserWidget::dragMoveEvent(QDragMoveEvent *event)
|
||||
@@ -316,6 +330,7 @@ void RomBrowserWidget::dropEvent(QDropEvent *event)
|
||||
|
||||
void RomBrowserWidget::customContextMenuRequested(QPoint position)
|
||||
{
|
||||
this->contextMenu_Actions_Update();
|
||||
this->contextMenu->popup(this->viewport()->mapToGlobal(position));
|
||||
}
|
||||
|
||||
@@ -344,6 +359,7 @@ void RomBrowserWidget::on_Action_PlayGame(void)
|
||||
|
||||
void RomBrowserWidget::on_Action_PlayGameWithDisk(void)
|
||||
{
|
||||
this->on_RomBrowser_PlayGameWithDisk(this->getCurrentRom());
|
||||
}
|
||||
|
||||
void RomBrowserWidget::on_Action_RefreshRomList(void)
|
||||
@@ -353,14 +369,17 @@ void RomBrowserWidget::on_Action_RefreshRomList(void)
|
||||
|
||||
void RomBrowserWidget::on_Action_ChooseRomDirectory(void)
|
||||
{
|
||||
this->on_RomBrowser_ChooseRomDirectory();
|
||||
}
|
||||
|
||||
void RomBrowserWidget::on_Action_RomInformation(void)
|
||||
{
|
||||
this->on_RomBrowser_RomInformation(this->getCurrentRom());
|
||||
}
|
||||
|
||||
void RomBrowserWidget::on_Action_EditGameSettings(void)
|
||||
{
|
||||
this->on_RomBrowser_EditGameSettings(this->getCurrentRom());
|
||||
}
|
||||
|
||||
void RomBrowserWidget::on_Action_EditCheats(void)
|
||||
|
||||
@@ -60,6 +60,7 @@ class RomBrowserWidget : public QTableView
|
||||
void contextMenu_Actions_Init(void);
|
||||
void contextMenu_Actions_Setup(void);
|
||||
void contextMenu_Actions_Connect(void);
|
||||
void contextMenu_Actions_Update(void);
|
||||
|
||||
QStandardItemModel *model_Model;
|
||||
std::vector<int> model_Columns;
|
||||
@@ -80,6 +81,8 @@ class RomBrowserWidget : public QTableView
|
||||
|
||||
void launchSelectedRom(void);
|
||||
|
||||
QString getCurrentRom(void);
|
||||
|
||||
protected:
|
||||
void dragMoveEvent(QDragMoveEvent *);
|
||||
void dragEnterEvent(QDragEnterEvent *);
|
||||
@@ -102,8 +105,12 @@ class RomBrowserWidget : public QTableView
|
||||
void on_RomBrowserThread_Received(QString file, CoreRomHeader header, CoreRomSettings settings);
|
||||
|
||||
signals:
|
||||
void on_RomBrowser_Select(QString);
|
||||
void on_RomBrowser_PlayGame(QString);
|
||||
void on_RomBrowser_PlayGameWithDisk(QString);
|
||||
void on_RomBrowser_FileDropped(QDropEvent *);
|
||||
void on_RomBrowser_EditGameSettings(QString);
|
||||
void on_RomBrowser_ChooseRomDirectory(void);
|
||||
void on_RomBrowser_RomInformation(QString);
|
||||
};
|
||||
} // namespace Widget
|
||||
} // namespace UserInterface
|
||||
|
||||
@@ -21,7 +21,7 @@ int main(int argc, char **argv)
|
||||
|
||||
QDir::setCurrent(app.applicationDirPath());
|
||||
|
||||
if (!window.Init())
|
||||
if (!window.Init(&app))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ then
|
||||
generator="MSYS Makefiles"
|
||||
fi
|
||||
|
||||
cmake -S "$toplvl_dir" -B "$build_dir" -DCMAKE_BUILD_TYPE="$build_config" -G "$generator"
|
||||
cmake -S "$toplvl_dir" -B "$build_dir" -DCMAKE_BUILD_TYPE="$build_config" -DPORTABLE_INSTALL=ON -G "$generator"
|
||||
|
||||
make install DESTDIR="$toplvl_dir" -j$threads
|
||||
|
||||
|
||||