Compare commits

...

72 commits

Author SHA1 Message Date
GhostlyDark
9ce1e45d64
README: Add missing libusb dependency (#379)
The mupen64plus-input-gca plugin can't run without libusb-1.0.dll being present, but is able to build fine without libusb being installed. If not installed, the dependency script silently fails to find/copy the DLL.
2025-06-23 17:58:21 +02:00
Rosalie Wanders
be738f0cb7 ci: use windows-2022 2025-06-09 16:01:11 +02:00
Rosalie Wanders
e882e0f22c RMG: add NETPLAY guard to QWebSocket in NetplayCommon.hpp 2025-06-09 15:59:54 +02:00
Rosalie Wanders
f7a1d0f952 RMG: add IPv4 resolver to NetplayCommon and use it 2025-06-09 15:35:46 +02:00
Logan McNaughton
6b8990fa1a
RMG: ensure that netplay only connects using IPv4 (#374) 2025-06-09 15:18:35 +02:00
Rosalie Wanders
a74cff50f8 Package: add vulkan-headers to makedepends of PKGBUILD 2025-05-20 09:35:34 +02:00
Rosalie Wanders
d4ac45a9c5 Package: v0.7.9 2025-05-19 23:59:01 +02:00
Rosalie Wanders
32aebfec1a RMG-Core: change default of RomBrowser_MaxItems to 2048 2025-05-19 23:51:06 +02:00
Rosalie Wanders
aee7da8068 RMG: hide RomBrowserSearchWidget by default 2025-05-19 23:47:36 +02:00
Rosalie Wanders
078361e2e6 RMG: use const reference for slots 2025-05-19 23:41:28 +02:00
Rosalie Wanders
e0cae9c1a9 RMG: disable action_View_Game{List,Grid} during emulation 2025-05-19 23:34:01 +02:00
Rosalie Wanders
c8d46ee919 RMG: showSearchLineEdit -> showSearchWidget 2025-05-19 23:23:47 +02:00
Rosalie Wanders
c5965b3940 RMG: introduce RomBrowserSearchWidget 2025-05-19 23:06:39 +02:00
Rosalie Wanders
affb0ee0ee RMG: change placeholder text of searchLineEdit in RomBrowserWidget.cpp 2025-05-19 23:06:39 +02:00
Rosalie Wanders
dd6ea4f22a RMG-Core: change casing of default KeyBinding_ViewSearch setting value 2025-05-19 23:06:39 +02:00
Rosalie Wanders
006a7c8eff RMG: re-add nullptr check in RomBrowserWidget::getCurrentData() 2025-05-18 19:32:59 +02:00
Rosalie Wanders
5f10f39ac0 3rdParty: update mupen64plus-rsp-hle 2025-05-18 19:19:12 +02:00
Rosalie Wanders
6e1df7fc79 3rdParty: update mupen64plus-video-GLideN64 2025-05-18 19:18:44 +02:00
Rosalie Wanders
5cab9282e7 3rdParty: allow cropping each side separately in mupen64plus-video-parallel 2025-05-18 19:17:12 +02:00
Rosalie Wanders
1c6d8a6f59 RMG: fix ROM browser index mapping 2025-05-18 19:02:29 +02:00
Rosalie Wanders
c43f43e634 RMG-Core: Keybinding_ViewLog -> KeyBinding_ViewLog 2025-05-06 01:28:09 +02:00
Rosalie Wanders
409aac2caa RMG-Core: remove unrequired include 2025-05-06 01:28:09 +02:00
Rosalie Wanders
21b187dacc RMG: implement search for the ROM browser 2025-05-06 01:28:09 +02:00
Rosalie Wanders
a110f48fad RMG-Core: add KeyBinding_ViewSearch setting 2025-05-06 00:48:47 +02:00
Rosalie Wanders
1f24d20054 RMG-Core: fix name having incorrect count in CoreGetCurrentRomHeader() 2025-05-03 16:38:56 +02:00
Rosalie Wanders
8e61b79ecf 3rdParty: update mupen64plus-core 2025-05-02 15:08:02 +02:00
Rosalie Wanders
f459c456de RMG-Core: use const reference for local functions in Settings.cpp 2025-05-02 14:36:19 +02:00
Rosalie Wanders
0813a6e3ea RMG-Core: fix compile error with newer minizip-ng versions 2025-04-24 00:59:31 +02:00
Rosalie Wanders
606eb976cb 3rdParty: apply netplay optimization patch to mupen64plus-core 2025-04-24 00:10:05 +02:00
Rosalie Wanders
443ff545ab 3rdParty: update mupen64plus-video-GLideN64 2025-03-31 13:29:08 +02:00
Rosalie Wanders
3c615c8459 Package: v0.7.8 2025-03-23 13:55:18 +01:00
Rosalie Wanders
7973b5d151 Package: update InputSettings.png 2025-03-23 13:51:45 +01:00
Rosalie Wanders
8f0cd29366 RMG-Input: remove unrequired includes 2025-03-23 13:14:33 +01:00
Rosalie Wanders
b39357efda 3rdParty: update rom size patch for mupen64plus-core 2025-03-23 13:14:24 +01:00
Rosalie Wanders
3e0efac610 RMG-Core: shutdown mupen64plus-core in CoreShutdown() 2025-03-22 18:47:23 +01:00
Rosalie Wanders
595427aa98 RMG-Input: also make other buttons consistent height wise 2025-03-20 00:06:07 +01:00
Rosalie Wanders
62c30a4b4d RMG-Core: mark result from split_string() const 2025-03-19 23:58:18 +01:00
Rosalie Wanders
13f7ede034 RMG-Core: remove more unrequired usage of std::vector<T>::at() 2025-03-19 23:48:03 +01:00
Rosalie Wanders
f89b73cec1 RMG-Core: slightly optimize get_cache_entry_iter() 2025-03-19 23:47:44 +01:00
Rosalie Wanders
30d1f17329 RMG-Input: make add/remove buttons have a consistent height 2025-03-19 23:34:07 +01:00
Rosalie Wanders
b8ad7d1dce RMG-Input: swap around Z-Trigger and Start button mapping UI elements 2025-03-19 22:23:06 +01:00
Rosalie Wanders
6552aa23ec RMG-Core: remove unrequired usage of std::vector<T>::at() 2025-03-19 22:11:49 +01:00
Rosalie Wanders
6d81b8cda3 RMG-Input: don't set window icon 2025-03-19 22:06:53 +01:00
Rosalie Wanders
f5de7e8320 RMG-Input: mark variable const in ControllerImageWidget.cpp 2025-03-19 22:04:05 +01:00
Rosalie Wanders
0d2b88037f RMG-Input: fix accuracy of stick movement in ControllerImageWidget.cpp 2025-03-19 22:00:58 +01:00
Rosalie Wanders
ac7b9bce27 RMG-Input: fix percentage for new image in ControllerImageWidget.cpp 2025-03-19 22:00:58 +01:00
Rosalie Wanders
d87bcc3a21 RMG-Input: remove unused image 2025-03-18 19:40:48 +01:00
Rosalie Wanders
7261903186 RMG-Input: center C letter in controller image 2025-03-18 19:37:01 +01:00
Rosalie Wanders
2e6263ea5c RMG: add new contributors to AboutDialog.ui 2025-03-18 12:02:59 +01:00
Rosalie Wanders
fa9a288e0a RMG-Input: fix typo in Controller_Pressed_DpadRight.svg 2025-03-18 11:57:07 +01:00
Jaffacakelover
7fced2d3eb
RMG-Input: introduce new controller image (#349) 2025-03-18 11:55:37 +01:00
Rosalie Wanders
9bc56e90ee RMG-Core: use std::runtime_error instead of std::terminate in Directories.cpp 2025-03-17 00:15:10 +01:00
Rosalie Wanders
64d4c41d1d RMG-Core: delete copy constructor of m64p api classes 2025-03-17 00:13:44 +01:00
Rosalie Wanders
c2197b3053 RMG-Core: use references instead of pointers in Plugins.cpp 2025-03-17 00:13:02 +01:00
Rosalie Wanders
3f7c1584a4 RMG-Core: use static_cast in CoreDebugCallback() 2025-03-13 22:36:08 +01:00
Rosalie Wanders
17dc26779e RMG-Core: fix casing in error message in Core.cpp 2025-03-13 22:14:40 +01:00
Rosalie Wanders
edc8c0bb98 Script: add UpdateCopyrightYear.sh 2025-03-13 22:08:38 +01:00
Rosalie Wanders
5bf5d0ed16 RMG-Audio: update copyright year 2025-03-13 22:07:12 +01:00
Rosalie Wanders
7114338cec RMG-Input: update copyright year 2025-03-13 22:07:12 +01:00
Rosalie Wanders
64d0a90b82 RMG: update copyright year 2025-03-13 22:07:12 +01:00
Rosalie Wanders
d6b0f024da RMG-Core: update copyright year 2025-03-13 22:07:12 +01:00
Rosalie Wanders
3b2668977d RMG-Core: use reinterpret_cast instead of c style cast in Archive.cpp 2025-03-10 12:55:32 +01:00
Rosalie Wanders
5aa7ee0fe3 RMG-Core: use correct include version in Archive.cpp 2025-03-09 22:12:22 +01:00
Rosalie Wanders
f0119ec75d RMG-Core: add and use CORE_DIR_MAX_LEN 2025-03-09 18:52:14 +01:00
Rosalie Wanders
249654a879 RMG-Core: remove usage of PATH_MAX in Archive.cpp and use our own define 2025-03-09 18:45:28 +01:00
Rosalie Wanders
950becc1b3 Package: add libhidapi-hidraw to AppImage 2025-03-09 16:16:39 +01:00
Rosalie Wanders
b3424f3fc5 RMG-Input: fix dialog not quitting when pressing esc 2025-03-09 13:47:23 +01:00
Rosalie Wanders
e0e19824a5 3rdParty: apply pending IS viewer bounds check PR to mupen64plus-core 2025-03-09 13:41:35 +01:00
Rosalie Wanders
b3b8c2d8b1 3rdParty: apply pending PR patch to mupen64plus-core 2025-03-09 00:50:26 +01:00
Samuel
d9cd714c2c
Package: remove --patch-rpath argument to lib4bin in Create.sh 2025-03-08 18:43:37 +01:00
Rosalie Wanders
fb85a42477 RMG: ensure rom count is not 0 in RomBrowserLoadingWidget.cpp 2025-03-08 18:13:39 +01:00
Rosalie Wanders
1458f3df0b RMG: support using file path for server json for netplay 2025-03-07 18:49:18 +01:00
273 changed files with 1477 additions and 1755 deletions

View file

@ -61,7 +61,7 @@ jobs:
path: Bin/*.AppImage
build-windows:
runs-on: windows-2019
runs-on: windows-2022
strategy:
matrix:
features: [ ON, OFF ]

View file

@ -53,11 +53,12 @@ mv "$bin_dir/usr/share" "$bin_dir/share"
mv "$bin_dir/usr" "$bin_dir/shared"
$XVFB_RUN "$script_dir/lib4bin" --dst-dir "$bin_dir" \
--hard-links --patch-rpath --strip \
--with-hooks --strace-mode --with-sharun \
--hard-links --strip --with-hooks \
--strace-mode --with-sharun \
"$bin_dir/shared/bin/RMG" \
"$lib_dir"/libSDL* \
"$lib_dir"/libspeexdsp* \
"$lib_dir"/libhidapi-hidraw* \
"$lib_dir"/libGL* \
"$lib_dir"/libEGL* \
"$lib_dir"/libvulkan* \

View file

@ -1,14 +1,14 @@
# Maintainer: Rosalie Wanders <rosalie@mailbox.org>
pkgname=rmg
pkgver=0.7.7
pkgrel=1
pkgver=0.7.9
pkgrel=2
pkgdesc="Rosalie's Mupen GUI"
arch=('x86_64' 'aarch64')
url="https://github.com/Rosalie241/$pkgname"
license=('GPL3')
depends=("hidapi" "libsamplerate" "speexdsp" "minizip" "sdl2" "sdl2_net" "zlib" "freetype2" "qt6-base" "qt6-svg" "qt6-websockets")
makedepends=("git" "nasm" "cmake")
makedepends=("git" "nasm" "cmake" "vulkan-headers")
source=("git+https://github.com/Rosalie241/$pkgname.git#tag=v$pkgver")
sha256sums=('SKIP')

View file

@ -1,5 +1,5 @@
Name: RMG
Version: 0.7.7
Version: 0.7.9
Release: %autorelease
Summary: Rosalie's Mupen GUI

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 135 KiB

View file

@ -29,6 +29,40 @@
</screenshot>
</screenshots>
<releases>
<release version="v0.7.9" date="2025-05-19" type="stable">
<description>
<p>Changes:</p>
<ul>
<li>Fix netplay allocating UDP packets during emulation</li>
<li>Fix 'Game List' and 'Game Grid' UI elements not being disabled during emulation</li>
<li>Fix compilation error with newer minizip-ng versions</li>
<li>Add search feature to the ROM browser</li>
<li>Add crop settings for each side in mupen64plus-video-parallel</li>
<li>Change default ROM search limit to 2048</li>
<li>Update mupen64plus-video-GLideN64 and mupen64plus-rsp-hle</li>
</ul>
</description>
</release>
<release version="v0.7.8" date="2025-03-23" type="stable">
<description>
<p>Changes:</p>
<ul>
<li>Fix ROM browser loading screen showing '[0/0]'</li>
<li>Fix configuration dialog of RMG-Input not closing when pressing escape</li>
<li>Fix AppImage not including libhidapi-hidraw</li>
<li>Fix AppImage not working on nvidia GPUs since v0.7.7 (thank you Samueru-sama)</li>
<li>Fix casing in error message in RMG-Core</li>
<li>Fix missing space for 'Start:' label in RMG-Input</li>
<li>Fix inconsistent height for UI elements in RMG-Input</li>
<li>Fix mupen64plus not being shutdown properly</li>
<li>Fix high memory requirement introduced in v0.7.1</li>
<li>Add bounds checking for some DMA operations</li>
<li>Add new controller image to RMG-Input (thank you Jaffacakelover)</li>
<li>Add support for using a local file path for the netplay server list URL</li>
<li>Swap Z-Trigger and Start UI elements in RMG-Input</li>
</ul>
</description>
</release>
<release version="v0.7.7" date="2025-03-05" type="stable">
<description>
<p>Changes:</p>

View file

@ -73,9 +73,9 @@ cmake --install "$build_dir" --prefix="/usr"
```
#### Windows
* Download & Install [MSYS2](https://www.msys2.org/)
* Download & Install [MSYS2](https://www.msys2.org/) (UCRT64)
```bash
pacman -S --needed make mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-hidapi mingw-w64-ucrt-x86_64-freetype mingw-w64-ucrt-x86_64-libpng mingw-w64-ucrt-x86_64-qt6 mingw-w64-ucrt-x86_64-SDL2 mingw-w64-ucrt-x86_64-SDL2_net mingw-w64-ucrt-x86_64-speexdsp mingw-w64-ucrt-x86_64-libsamplerate mingw-w64-ucrt-x86_64-nasm mingw-w64-ucrt-x86_64-minizip mingw-w64-ucrt-x86_64-vulkan-headers git
pacman -S --needed make mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-hidapi mingw-w64-ucrt-x86_64-freetype mingw-w64-ucrt-x86_64-libpng mingw-w64-ucrt-x86_64-qt6 mingw-w64-ucrt-x86_64-SDL2 mingw-w64-ucrt-x86_64-SDL2_net mingw-w64-ucrt-x86_64-speexdsp mingw-w64-ucrt-x86_64-libsamplerate mingw-w64-ucrt-x86_64-libusb mingw-w64-ucrt-x86_64-nasm mingw-w64-ucrt-x86_64-minizip mingw-w64-ucrt-x86_64-vulkan-headers git
./Source/Script/Build.sh Release
```

View file

@ -26,26 +26,20 @@ jobs:
arch: x64
- cc: Clang
arch: x86
name: Linux / ${{ matrix.cc }} / ${{ matrix.arch }}
runs-on: ubuntu-22.04
name: Linux / ${{ matrix.cc }} ${{ matrix.arch }}
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Get build dependencies and arrange the environment
run: |
export C_CLANG_SUFFIX="-15" C_GCC_SUFFIX="-12"
export BUILD_DEPS="libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev libpng-dev libsdl1.2-dev libsdl2-dev libvulkan-dev zlib1g-dev"
export BUILD_DEPS="libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev libpng-dev libsdl2-dev libvulkan-dev zlib1g-dev"
./.github/workflows/scripts/ci_install_ubuntu_deps.sh ${{ matrix.arch }} ${{ matrix.cc }}
- name: Build and related stuff, backup binaries
run: |
export C_CLANG_SUFFIX="-15" C_GCC_SUFFIX="-12"
export PATH="$(pwd)/.github/workflows/scripts:${PATH}"
export CONFIG_OVERRIDE="ACCURATE_FPU=1 NEW_DYNAREC=1 SDL_CONFIG="sdl-config""
export CONFIG_OVERRIDE="ACCURATE_FPU=1 NEW_DYNAREC=1"
ci_build.sh ${{ matrix.arch }} ${{ matrix.cc }}
export CONFIG_OVERRIDE="ACCURATE_FPU=1 NEW_DYNAREC=1 SDL_CONFIG="sdl2-config""
ci_build.sh ${{ matrix.arch }} ${{ matrix.cc }}
export CONFIG_OVERRIDE="ACCURATE_FPU=0 NEW_DYNAREC=0 SDL_CONFIG="sdl-config" POSTFIX="-old""
ci_build.sh ${{ matrix.arch }} ${{ matrix.cc }}
export CONFIG_OVERRIDE="ACCURATE_FPU=0 NEW_DYNAREC=0 SDL_CONFIG="sdl2-config" POSTFIX="-old""
export CONFIG_OVERRIDE="ACCURATE_FPU=0 NEW_DYNAREC=0 POSTFIX="-old""
ci_build.sh ${{ matrix.arch }} ${{ matrix.cc }} makepkg
- name: Upload artifact
if: matrix.cc == 'GCC'
@ -63,12 +57,24 @@ jobs:
arch: x64
cross: x86_64
env: MINGW64
gbc: 0
- cc: GCC
arch: x86
cross: i686
env: MINGW32
name: Windows / MSYS2 ${{ matrix.cc }} / ${{ matrix.arch }}
runs-on: windows-2022
gbc: 0
- cc: GCC
arch: x64
cross: ucrt-x86_64
env: UCRT64
gbc: 1
- cc: Clang
arch: x64
cross: clang-x86_64
env: CLANG64
gbc: 1
name: Windows ${{ matrix.arch }} / MSYS2 ${{ matrix.env }} ${{ matrix.cc }}
runs-on: windows-2025
defaults:
run:
shell: msys2 {0}
@ -82,7 +88,6 @@ jobs:
git
libtool
make
mingw-w64-${{ matrix.cross }}-gcc
mingw-w64-${{ matrix.cross }}-toolchain
mingw-w64-${{ matrix.cross }}-freetype
mingw-w64-${{ matrix.cross }}-libpng
@ -93,10 +98,11 @@ jobs:
mingw-w64-${{ matrix.cross }}-zlib
- name: Build and related stuff, backup binaries
run: |
if [[ ${{ matrix.gbc }} -eq 1 ]]; then pacman --noconfirm -S --needed mingw-w64-${{ matrix.cross }}-opencv; fi
export PATH="$(pwd)/.github/workflows/scripts:${PATH}"
export CONFIG_OVERRIDE="ACCURATE_FPU=1 NEW_DYNAREC=1"
export CONFIG_OVERRIDE="ACCURATE_FPU=1 NEW_DYNAREC=1 OPENCV=${{ matrix.gbc }}"
ci_build.sh ${{ matrix.arch }} ${{ matrix.cc }}
export CONFIG_OVERRIDE="ACCURATE_FPU=0 NEW_DYNAREC=0 POSTFIX="-old""
export CONFIG_OVERRIDE="ACCURATE_FPU=0 NEW_DYNAREC=0 OPENCV=${{ matrix.gbc }} POSTFIX="-old""
ci_build.sh ${{ matrix.arch }} ${{ matrix.cc }}
- name: Backup dependencies, etc...
run: |
@ -114,11 +120,11 @@ jobs:
include:
- toolset: v143
arch: x64
vs: 2022
vs: 2025
- toolset: v141_xp
arch: x86
vs: 2019
name: Windows / MSVC with ${{ matrix.toolset }} / ${{ matrix.arch }}
name: Windows ${{ matrix.arch }} / MSVC with ${{ matrix.toolset }}
runs-on: windows-${{ matrix.vs }}
defaults:
run:
@ -131,7 +137,7 @@ jobs:
set PATH=%CD%\.github\workflows\scripts;%PATH%
set TOOLSET=${{ matrix.toolset }}
call ci_msvc_build.cmd ${{ matrix.arch }}
ci_msvc_build.cmd ${{ matrix.arch }} newdyn
call ci_msvc_build.cmd ${{ matrix.arch }} newdyn
- name: Backup dependencies, etc...
run: |
.\.github\workflows\scripts\ci_backup_msvc_deps.cmd ${{ matrix.arch }} freetype.dll libpng16.dll SDL2.dll SDL2_net.dll zlib.dll

View file

@ -19,27 +19,21 @@ jobs:
arch: x64
- cc: Clang
arch: x86
name: Linux / ${{ matrix.cc }} / ${{ matrix.arch }}
runs-on: ubuntu-22.04
name: Linux / ${{ matrix.cc }} ${{ matrix.arch }}
runs-on: ubuntu-24.04
if: github.repository == 'mupen64plus/mupen64plus-core'
steps:
- uses: actions/checkout@v4
- name: Get build dependencies and arrange the environment
run: |
export C_CLANG_SUFFIX="-15" C_GCC_SUFFIX="-12"
export BUILD_DEPS="libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev libpng-dev libsdl1.2-dev libsdl2-dev libvulkan-dev zlib1g-dev"
export BUILD_DEPS="libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev libpng-dev libsdl2-dev libvulkan-dev zlib1g-dev"
./.github/workflows/scripts/ci_install_ubuntu_deps.sh ${{ matrix.arch }} ${{ matrix.cc }}
- name: Build and related stuff, backup binaries
run: |
export C_CLANG_SUFFIX="-15" C_GCC_SUFFIX="-12"
export PATH="$(pwd)/.github/workflows/scripts:${PATH}"
export CONFIG_OVERRIDE="ACCURATE_FPU=1 NEW_DYNAREC=1 SDL_CONFIG="sdl-config""
export CONFIG_OVERRIDE="ACCURATE_FPU=1 NEW_DYNAREC=1"
ci_build.sh ${{ matrix.arch }} ${{ matrix.cc }}
export CONFIG_OVERRIDE="ACCURATE_FPU=1 NEW_DYNAREC=1 SDL_CONFIG="sdl2-config""
ci_build.sh ${{ matrix.arch }} ${{ matrix.cc }}
export CONFIG_OVERRIDE="ACCURATE_FPU=0 NEW_DYNAREC=0 SDL_CONFIG="sdl-config" POSTFIX="-old""
ci_build.sh ${{ matrix.arch }} ${{ matrix.cc }}
export CONFIG_OVERRIDE="ACCURATE_FPU=0 NEW_DYNAREC=0 SDL_CONFIG="sdl2-config" POSTFIX="-old""
export CONFIG_OVERRIDE="ACCURATE_FPU=0 NEW_DYNAREC=0 POSTFIX="-old""
ci_build.sh ${{ matrix.arch }} ${{ matrix.cc }} makepkg
- name: Upload artifact
if: matrix.cc == 'GCC'
@ -57,12 +51,24 @@ jobs:
arch: x64
cross: x86_64
env: MINGW64
gbc: 0
- cc: GCC
arch: x86
cross: i686
env: MINGW32
name: Windows / MSYS2 ${{ matrix.cc }} / ${{ matrix.arch }}
runs-on: windows-2022
gbc: 0
- cc: GCC
arch: x64
cross: ucrt-x86_64
env: UCRT64
gbc: 1
- cc: Clang
arch: x64
cross: clang-x86_64
env: CLANG64
gbc: 1
name: Windows ${{ matrix.arch }} / MSYS2 ${{ matrix.env }} ${{ matrix.cc }}
runs-on: windows-2025
if: github.repository == 'mupen64plus/mupen64plus-core'
defaults:
run:
@ -77,7 +83,6 @@ jobs:
git
libtool
make
mingw-w64-${{ matrix.cross }}-gcc
mingw-w64-${{ matrix.cross }}-toolchain
mingw-w64-${{ matrix.cross }}-freetype
mingw-w64-${{ matrix.cross }}-libpng
@ -88,10 +93,11 @@ jobs:
mingw-w64-${{ matrix.cross }}-zlib
- name: Build and related stuff, backup binaries
run: |
if [[ ${{ matrix.gbc }} -eq 1 ]]; then pacman --noconfirm -S --needed mingw-w64-${{ matrix.cross }}-opencv; fi
export PATH="$(pwd)/.github/workflows/scripts:${PATH}"
export CONFIG_OVERRIDE="ACCURATE_FPU=1 NEW_DYNAREC=1"
export CONFIG_OVERRIDE="ACCURATE_FPU=1 NEW_DYNAREC=1 OPENCV=${{ matrix.gbc }}"
ci_build.sh ${{ matrix.arch }} ${{ matrix.cc }}
export CONFIG_OVERRIDE="ACCURATE_FPU=0 NEW_DYNAREC=0 POSTFIX="-old""
export CONFIG_OVERRIDE="ACCURATE_FPU=0 NEW_DYNAREC=0 OPENCV=${{ matrix.gbc }} POSTFIX="-old""
ci_build.sh ${{ matrix.arch }} ${{ matrix.cc }}
- name: Backup dependencies, etc...
run: |
@ -109,11 +115,11 @@ jobs:
include:
- toolset: v143
arch: x64
vs: 2022
vs: 2025
- toolset: v141_xp
arch: x86
vs: 2019
name: Windows / MSVC with ${{ matrix.toolset }} / ${{ matrix.arch }}
name: Windows ${{ matrix.arch }} / MSVC with ${{ matrix.toolset }}
runs-on: windows-${{ matrix.vs }}
if: github.repository == 'mupen64plus/mupen64plus-core'
defaults:
@ -127,7 +133,7 @@ jobs:
set PATH=%CD%\.github\workflows\scripts;%PATH%
set TOOLSET=${{ matrix.toolset }}
call ci_msvc_build.cmd ${{ matrix.arch }}
ci_msvc_build.cmd ${{ matrix.arch }} newdyn
call ci_msvc_build.cmd ${{ matrix.arch }} newdyn
- name: Backup dependencies, etc...
run: |
.\.github\workflows\scripts\ci_backup_msvc_deps.cmd ${{ matrix.arch }} freetype.dll libpng16.dll SDL2.dll SDL2_net.dll zlib.dll

View file

@ -37,7 +37,7 @@ export REPO="${PWD##*/}"
if [[ "${REPO}" == "" ]]; then exit 6; fi
export BIN_OS="$(uname -s | tr [A-Z] [a-z])"
if [[ ! -z ${MSYSTEM} ]]; then export BIN_OS="msys2"; fi
if [[ ! -z ${MSYSTEM} ]]; then export BIN_OS="msys2-$(echo "${MSYSTEM}" | tr [A-Z] [a-z])"; fi
export ENV_NAME="$(uname -s)"
export LDD="ldd"
export PKG_PATH="usr/local/lib/mupen64plus/"
@ -105,6 +105,7 @@ if [[ -z ${ARTIFACT} ]]; then
exit 5
else
cd pkg
if [[ -f "mupen64plus.desktop" ]]; then rm -f mupen64plus.desktop; fi
ls -gG "${PKG_PATH}${ARTIFACT}"
echo ""
${LDD} "${PKG_PATH}${ARTIFACT}" > ldd.log

View file

@ -1,12 +1,16 @@
#!/usr/bin/env bash
set -e +u
# NOTE: There is no native "libglew-dev:i386" in Ubuntu 22.04, we will use Debian ones...
# NOTE: There is no native "libglew-dev:i386" in Ubuntu 24.04, we will use Debian ones...
export GLEWVER="$(apt list libglew-dev | grep "amd64" | cut -d ' ' -f2)"
export PKGS="$(apt list libglew* | grep "${GLEWVER}" | cut -d '/' -f1)"
export DEBSOURCE="http://http.us.debian.org/debian/pool/main/g/glew/"
export PKGVER_LS="$(curl -sS ${DEBSOURCE} | grep "${GLEWVER}" | grep "amd64" | cut -d '_' -f2 | sort)"
export BUILDP1="$(echo "${GLEWVER}" | cut -d '-' -f1)"
export BUILDP2="$(echo "${GLEWVER}" | cut -d '-' -f2)"
export GLEWBUILD="${BUILDP1}"
if [[ "${GLEWBUILD}" != "${GLEWVER}" ]]; then export GLEWBUILD="${BUILDP1}-${BUILDP2:0:1}"; fi
export PKGVER_LS="$(curl -sS ${DEBSOURCE} | grep "${GLEWBUILD}" | grep "amd64" | cut -d '_' -f2 | sort)"
if [[ "${PKGVER_LS}" != "" ]]; then
for VER in ${PKGVER_LS}; do export PKGVER="${VER}"; done
cd /tmp

View file

@ -4,7 +4,7 @@ set -e +u
if [[ ${#} -lt 2 ]]; then exit 9; fi
unset ARCH_DEP CC_DEP
export BUILD_DEPS_I386="crossbuild-essential-i386 g++${C_GCC_SUFFIX}-i686-linux-gnu gcc${C_GCC_SUFFIX}-i686-linux-gnu libc6-i386"
export BUILD_DEPS_I386="crossbuild-essential-i386 g++${C_GCC_SUFFIX}-i686-linux-gnu gcc${C_GCC_SUFFIX}-i686-linux-gnu"
export HOTFIX_I386="libatomic1:i386 libgcc-s1:i386 libstdc++6:i386 ${HOTFIX_I386}"
export ENV_ARGS="$(echo "${*}" | tr [A-Z] [a-z])"
@ -17,7 +17,7 @@ for ARG in ${ENV_ARGS}; do
export CC_DEP="g++${C_GCC_SUFFIX} gcc${C_GCC_SUFFIX}"
;;
multilib )
export BUILD_DEPS_I386="g++${C_GCC_SUFFIX}-multilib gcc${C_GCC_SUFFIX}-multilib libc6-dev-i386"
export BUILD_DEPS_I386="g++${C_GCC_SUFFIX}-multilib gcc${C_GCC_SUFFIX}-multilib"
;;
x64 )
export ARCH_DEP="x64"
@ -31,9 +31,9 @@ done
if [[ -z ${ARCH_DEP} ]]; then exit 8; fi
if [[ -z ${CC_DEP} ]]; then exit 7; fi
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
if [[ "${ARCH_DEP}" == "x86" ]]; then sudo dpkg --add-architecture i386; fi
sudo apt-get update
sudo apt-mark hold grub-common grub-efi-amd64-bin python3 python3-apt shim-signed
sudo apt-get -y install build-essential git nasm pkg-config ${CC_DEP} ${BUILD_DEPS}
if [[ "${ARCH_DEP}" == "x86" ]]; then
if [[ "${BUILD_DEPS}" != "" ]]; then

View file

@ -6,7 +6,7 @@
[subrepo]
remote = git@github.com:mupen64plus/mupen64plus-core.git
branch = master
commit = e170c409fb006aa38fd02031b5eefab6886ec125
parent = 37839b0178b42b57a38a040bbf4e1f410e6952a1
commit = c5b1e72be0d2b33c18be48c989e726ac176e7872
parent = c8048741165583eaced380e84945764e924df6bf
method = merge
cmdver = 0.4.6
cmdver = 0.4.9

View file

@ -339,11 +339,11 @@ LDLIBS += $(LIBPNG_LDLIBS)
ifeq ($(OPENCV), 1)
# OpenCV lib
ifeq ($(origin OPENCV_CFLAGS) $(origin OPENCV_LDLIBS), undefined undefined)
ifeq ($(shell $(PKG_CONFIG) --modversion opencv 2>/dev/null),)
$(error No OpenCV development libraries found!)
ifeq ($(shell $(PKG_CONFIG) --modversion opencv4 2>/dev/null),)
$(error No OpenCV 4 development libraries found!)
endif
OPENCV_CFLAGS += $(shell $(PKG_CONFIG) --cflags opencv)
OPENCV_LDLIBS += $(shell $(PKG_CONFIG) --libs opencv)
OPENCV_CFLAGS += $(shell $(PKG_CONFIG) --cflags opencv4)
OPENCV_LDLIBS += $(shell $(PKG_CONFIG) --libs opencv4)
endif
CFLAGS += $(OPENCV_CFLAGS)
LDLIBS += $(OPENCV_LDLIBS)

View file

@ -131,6 +131,9 @@ EXPORT m64p_error CALL CoreShutdown(void)
release_mem_base(g_mem_base);
g_mem_base = NULL;
/* deallocate rom memory */
release_mem_rom();
l_CoreInit = 0;
return M64ERR_SUCCESS;
}

View file

@ -281,7 +281,7 @@ static db_addr_t
db_disasm_insn ( struct r4k_dis_t * state,
int insn,
db_addr_t loc,
bool altfmt )
unsigned char altfmt)
{
char * rel;
InstFmt i;

View file

@ -24,11 +24,9 @@
#if defined(WIN32)
typedef unsigned int uint32_t;
typedef unsigned char bool;
#define false 0
#define true 1
#else
#include <stdbool.h>
#include <stdint.h>
#endif

View file

@ -26,6 +26,8 @@
#include "main/rom.h"
#include "device/r4300/r4300_core.h"
#include <stdint.h>
#include <string.h>
@ -129,10 +131,10 @@ void init_cart(struct cart* cart,
init_flashram(&cart->flashram,
flashram_type,
flashram_storage, iflashram_storage);
flashram_storage, iflashram_storage, r4300->rdram);
init_sram(&cart->sram,
sram_storage, isram_storage);
sram_storage, isram_storage, r4300->rdram);
if (ROM_SETTINGS.savetype == SAVETYPE_SRAM)
cart->use_flashram = -1;

View file

@ -28,6 +28,7 @@
#include "device/memory/memory.h"
#include "device/r4300/r4300_core.h"
#include "device/rcp/pi/pi_controller.h"
#include "device/rdram/rdram.h"
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
@ -101,7 +102,7 @@ unsigned int cart_rom_dma_write(void* opaque, uint8_t* dram, uint32_t dram_addr,
if (cart_addr + length < cart_rom->rom_size)
{
for(i = 0; i < length; ++i) {
for(i = 0; i < length && (dram_addr+i) < cart_rom->r4300->rdram->dram_size; ++i) {
dram[(dram_addr+i)^S8] = mem[(cart_addr+i)^S8];
}
}
@ -111,10 +112,10 @@ unsigned int cart_rom_dma_write(void* opaque, uint8_t* dram, uint32_t dram_addr,
? 0
: cart_rom->rom_size - cart_addr;
for (i = 0; i < diff; ++i) {
for (i = 0; i < diff && (dram_addr+i) < cart_rom->r4300->rdram->dram_size; ++i) {
dram[(dram_addr+i)^S8] = mem[(cart_addr+i)^S8];
}
for (; i < length; ++i) {
for (; i < length && (dram_addr+i) < cart_rom->r4300->rdram->dram_size; ++i) {
dram[(dram_addr+i)^S8] = 0;
}
}

View file

@ -28,6 +28,7 @@
#include "api/m64p_types.h"
#include "backends/api/storage_backend.h"
#include "device/memory/memory.h"
#include "device/rdram/rdram.h"
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
@ -122,12 +123,13 @@ static void flashram_command(struct flashram* flashram, uint32_t command)
void init_flashram(struct flashram* flashram,
uint32_t flashram_id,
void* storage, const struct storage_backend_interface* istorage)
void* storage, const struct storage_backend_interface* istorage, struct rdram* rdram)
{
flashram->silicon_id[0] = FLASHRAM_TYPE_ID;
flashram->silicon_id[1] = flashram_id;
flashram->storage = storage;
flashram->istorage = istorage;
flashram->rdram = rdram;
}
void poweron_flashram(struct flashram* flashram)
@ -207,7 +209,7 @@ unsigned int flashram_dma_write(void* opaque, uint8_t* dram, uint32_t dram_addr,
}
/* do actual DMA */
for(i = 0; i < length; ++i) {
for(i = 0; i < length && (dram_addr+i) < flashram->rdram->dram_size; ++i) {
dram[(dram_addr+i)^S8] = mem[(cart_addr+i)^S8];
}
}

View file

@ -61,12 +61,13 @@ struct flashram
void* storage;
const struct storage_backend_interface* istorage;
struct rdram* rdram;
};
void init_flashram(struct flashram* flashram,
uint32_t flashram_id,
void* storage,
const struct storage_backend_interface* istorage);
const struct storage_backend_interface* istorage, struct rdram* rdram);
void poweron_flashram(struct flashram* flashram);

View file

@ -55,8 +55,10 @@ void write_is_viewer(void* opaque, uint32_t address, uint32_t value, uint32_t ma
{
if (word > 0)
{
/* make sure we don't overflow the buffer */
if (is_viewer->buffer_pos + word > IS_BUFFER_SIZE)
/* make sure we don't overflow the integer or the buffer */
if (is_viewer->buffer_pos > IS_BUFFER_SIZE
|| word > IS_BUFFER_SIZE
|| is_viewer->buffer_pos + word > IS_BUFFER_SIZE)
{
/* reset buffer */
memset(is_viewer->output_buffer, 0, IS_BUFFER_SIZE);

View file

@ -27,6 +27,7 @@
#include "backends/api/storage_backend.h"
#include "device/memory/memory.h"
#include "device/rdram/rdram.h"
#define SRAM_ADDR_MASK UINT32_C(0x0000ffff)
@ -36,10 +37,11 @@ void format_sram(uint8_t* mem)
}
void init_sram(struct sram* sram,
void* storage, const struct storage_backend_interface* istorage)
void* storage, const struct storage_backend_interface* istorage, struct rdram* rdram)
{
sram->storage = storage;
sram->istorage = istorage;
sram->rdram = rdram;
}
unsigned int sram_dma_read(void* opaque, const uint8_t* dram, uint32_t dram_addr, uint32_t cart_addr, uint32_t length)
@ -50,7 +52,7 @@ unsigned int sram_dma_read(void* opaque, const uint8_t* dram, uint32_t dram_addr
cart_addr &= SRAM_ADDR_MASK;
for (i = 0; i < length; ++i) {
for (i = 0; i < length && (cart_addr+i) < SRAM_SIZE; ++i) {
mem[(cart_addr+i)^S8] = dram[(dram_addr+i)^S8];
}
@ -67,7 +69,7 @@ unsigned int sram_dma_write(void* opaque, uint8_t* dram, uint32_t dram_addr, uin
cart_addr &= SRAM_ADDR_MASK;
for (i = 0; i < length; ++i) {
for (i = 0; i < length && (dram_addr+i) < sram->rdram->dram_size; ++i) {
dram[(dram_addr+i)^S8] = mem[(cart_addr+i)^S8];
}

View file

@ -32,12 +32,13 @@ struct sram
{
void* storage;
const struct storage_backend_interface* istorage;
struct rdram* rdram;
};
void format_sram(uint8_t* sram);
void init_sram(struct sram* sram,
void* storage, const struct storage_backend_interface* istorage);
void* storage, const struct storage_backend_interface* istorage, struct rdram* rdram);
unsigned int sram_dma_read(void* opaque, const uint8_t* dram, uint32_t dram_addr, uint32_t cart_addr, uint32_t length);
unsigned int sram_dma_write(void* opaque, uint8_t* dram, uint32_t dram_addr, uint32_t cart_addr, uint32_t length);

View file

@ -58,7 +58,7 @@ static void get_pi_dma_handler(struct cart* cart, struct dd_controller* dd, uint
if (address >= MM_CART_ROM) {
if (address >= MM_CART_DOM3) {
/* 0x1fd00000 - 0xffffffff : dom3 addr2, cart rom */
/* 0x1fd00000 - 0x7fffffff : dom3 addr2, cart rom */
RW(cart, cart_dom3);
}
else {

View file

@ -222,12 +222,11 @@ enum { MB_RDRAM_DRAM_ALIGNMENT_REQUIREMENT = 64 * 1024 };
enum {
MB_RDRAM_DRAM = 0,
MB_CART_ROM = MB_RDRAM_DRAM + RDRAM_MAX_SIZE,
MB_RSP_MEM = MB_CART_ROM + CART_ROM_MAX_SIZE,
MB_RSP_MEM = MB_RDRAM_DRAM + RDRAM_MAX_SIZE,
MB_DD_ROM = MB_RSP_MEM + SP_MEM_SIZE,
MB_PIF_MEM = MB_DD_ROM + DD_ROM_MAX_SIZE,
MB_MAX_SIZE = MB_PIF_MEM + PIF_ROM_SIZE + PIF_RAM_SIZE,
MB_MAX_SIZE_FULL = 0x120000000,
MB_MAX_SIZE_FULL = 0x20000000
};
/* Use LSB of mem_base pointer to encode mem_base mode
@ -237,6 +236,9 @@ enum {
#define MEM_BASE_PTR(mem_base) ((void*)((uintptr_t)(mem_base) & ~0x1))
#define SET_MEM_BASE_MODE(mem_base) (mem_base = (void*)((uintptr_t)(mem_base) | 0x1))
static void* mem_rom = NULL;
static uint32_t mem_rom_size = 0;
void* init_mem_base(void)
{
void* mem_base;
@ -277,13 +279,42 @@ void release_mem_base(void* mem_base)
free(MEM_BASE_PTR(mem_base));
}
void* init_mem_rom(uint32_t size)
{
if (size > mem_rom_size) {
mem_rom = realloc(mem_rom, size);
if (mem_rom == NULL)
mem_rom_size = 0;
else
mem_rom_size = size;
}
return mem_rom;
}
void release_mem_rom(void)
{
if (mem_rom != NULL) {
free(mem_rom);
mem_rom = NULL;
}
mem_rom_size = 0;
}
uint32_t* mem_base_u32(void* mem_base, uint32_t address)
{
uint32_t* mem;
if (MEM_BASE_MODE(mem_base) == 0) {
/* In full mem base mode, use simple pointer arithmetic */
mem = (uint32_t*)((uint8_t*)mem_base + address);
/* In full mem base mode, use simple pointer arithmetic
* except for the rom, which is dynamically allocated
*/
if (address >= MM_CART_ROM && (address & UINT32_C(0xfff00000)) != MM_PIF_MEM) {
mem = (uint32_t*)((uint8_t*)mem_rom + (address - MM_CART_ROM));
} else {
mem = (uint32_t*)((uint8_t*)mem_base + address);
}
}
else {
/* In compressed mem base mode, select appropriate mem_base offset */
@ -296,10 +327,10 @@ uint32_t* mem_base_u32(void* mem_base, uint32_t address)
if ((address & UINT32_C(0xfff00000)) == MM_PIF_MEM) {
mem = (uint32_t*)((uint8_t*)mem_base + (address - MM_PIF_MEM + MB_PIF_MEM));
} else {
mem = (uint32_t*)((uint8_t*)mem_base + (address - MM_CART_ROM + MB_CART_ROM));
mem = (uint32_t*)((uint8_t*)mem_rom + (address - MM_CART_ROM));
}
}
else if ((address & UINT32_C(0xfe000000)) == MM_DD_ROM) {
else if ((address & UINT32_C(0xfe000000)) == MM_DD_ROM) {
mem = (uint32_t*)((uint8_t*)mem_base + (address - MM_DD_ROM + MB_DD_ROM));
}
else if ((address & UINT32_C(0xffffe000)) == MM_RSP_MEM) {

View file

@ -91,6 +91,8 @@ void apply_mem_mapping(struct memory* mem, const struct mem_mapping* mapping);
void* init_mem_base(void);
void release_mem_base(void* mem_base);
void* init_mem_rom(uint32_t size);
void release_mem_rom(void);
uint32_t* mem_base_u32(void* mem_base, uint32_t address);
void read_with_bp_checks(void* opaque, uint32_t address, uint32_t* value);

View file

@ -4274,7 +4274,7 @@ static void loop_preload(signed char pre[],signed char entry[])
// Generate address for load/store instruction
static void address_generation(int i,struct regstat *i_regs,signed char entry[])
{
if(i>=4069) return;
if(i>=MAXBLOCK) return;
if(itype[i]==LOAD||itype[i]==LOADLR||itype[i]==STORE||itype[i]==STORELR||itype[i]==C1LS) {
int ra=0;
int agr=AGEN1+(i&1);
@ -4381,7 +4381,7 @@ static void address_generation(int i,struct regstat *i_regs,signed char entry[])
}
}
// Preload constants for next instruction
if(i+1>=4096) return;
if(i+1>=MAXBLOCK) return;
if(itype[i+1]==LOAD||itype[i+1]==LOADLR||itype[i+1]==STORE||itype[i+1]==STORELR||itype[i+1]==C1LS) {
int agr,ra;
#if (NEW_DYNAREC!=NEW_DYNAREC_X86) && (NEW_DYNAREC!=NEW_DYNAREC_X64)

View file

@ -153,7 +153,7 @@ void read_pi_regs(void* opaque, uint32_t address, uint32_t* value)
struct pi_controller* pi = (struct pi_controller*)opaque;
uint32_t reg = pi_reg(address);
if (reg < PI_REGS_COUNT)
if (reg < PI_REGS_COUNT)
*value = pi->regs[reg];
if (reg == PI_WR_LEN_REG || reg == PI_RD_LEN_REG)

View file

@ -104,7 +104,7 @@ void read_vi_regs(void* opaque, uint32_t address, uint32_t* value)
/* update current field */
vi->regs[VI_CURRENT_REG] = (vi->regs[VI_CURRENT_REG] & (~1)) | vi->field;
}
if (reg < VI_REGS_COUNT)
{
*value = vi->regs[reg];

View file

@ -21,7 +21,6 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <SDL.h>
#include <SDL_syswm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View file

@ -50,6 +50,13 @@ static uint8_t l_plugin[4];
static uint8_t l_buffer_target;
static uint8_t l_player_lag[4];
//UDP packets
static UDPpacket *l_request_input_packet;
static UDPpacket *l_send_input_packet;
static UDPpacket *l_process_packet;
static UDPpacket *l_check_sync_packet;
static const int32_t l_check_sync_packet_size = (CP0_REGS_COUNT * 4) + 5;
//UDP packet formats
#define UDP_SEND_KEY_INFO 0
#define UDP_RECEIVE_KEY_INFO 1
@ -115,6 +122,31 @@ m64p_error netplay_start(const char* host, int port)
return M64ERR_SYSTEM_FAIL;
}
l_request_input_packet = SDLNet_AllocPacket(12);
l_send_input_packet = SDLNet_AllocPacket(11);
l_process_packet = SDLNet_AllocPacket(512);
l_check_sync_packet = SDLNet_AllocPacket(l_check_sync_packet_size);
if (l_request_input_packet == NULL ||
l_send_input_packet == NULL ||
l_process_packet == NULL ||
l_check_sync_packet == NULL)
{
DebugMessage(M64MSG_ERROR, "Netplay: could not allocate UDP packets");
SDLNet_UDP_Close(l_udpSocket);
l_udpSocket = NULL;
SDLNet_TCP_Close(l_tcpSocket);
l_tcpSocket = NULL;
SDLNet_FreePacket(l_request_input_packet);
l_request_input_packet = NULL;
SDLNet_FreePacket(l_send_input_packet);
l_send_input_packet = NULL;
SDLNet_FreePacket(l_process_packet);
l_process_packet = NULL;
SDLNet_FreePacket(l_check_sync_packet);
l_check_sync_packet = NULL;
return M64ERR_NO_MEMORY;
}
for (int i = 0; i < 4; ++i)
{
l_netplay_control[i] = -1;
@ -165,6 +197,16 @@ m64p_error netplay_stop()
l_tcpSocket = NULL;
l_udpSocket = NULL;
l_udpChannel = -1;
SDLNet_FreePacket(l_request_input_packet);
SDLNet_FreePacket(l_send_input_packet);
SDLNet_FreePacket(l_process_packet);
SDLNet_FreePacket(l_check_sync_packet);
l_request_input_packet = NULL;
l_send_input_packet = NULL;
l_process_packet = NULL;
l_check_sync_packet = NULL;
l_netplay_is_init = 0;
SDLNet_Quit();
return M64ERR_SUCCESS;
@ -191,16 +233,14 @@ static uint8_t buffer_size(uint8_t control_id)
static void netplay_request_input(uint8_t control_id)
{
UDPpacket *packet = SDLNet_AllocPacket(12);
packet->data[0] = UDP_REQUEST_KEY_INFO;
packet->data[1] = control_id; //The player we need input for
SDLNet_Write32(l_reg_id, &packet->data[2]); //our registration ID
SDLNet_Write32(l_cin_compats[control_id].netplay_count, &packet->data[6]); //the current event count
packet->data[10] = l_spectator; //whether we are a spectator
packet->data[11] = buffer_size(control_id); //our local buffer size
packet->len = 12;
SDLNet_UDP_Send(l_udpSocket, l_udpChannel, packet);
SDLNet_FreePacket(packet);
l_request_input_packet->data[0] = UDP_REQUEST_KEY_INFO;
l_request_input_packet->data[1] = control_id; //The player we need input for
SDLNet_Write32(l_reg_id, &l_request_input_packet->data[2]); //our registration ID
SDLNet_Write32(l_cin_compats[control_id].netplay_count, &l_request_input_packet->data[6]); //the current event count
l_request_input_packet->data[10] = l_spectator; //whether we are a spectator
l_request_input_packet->data[11] = buffer_size(control_id); //our local buffer size
l_request_input_packet->len = 12;
SDLNet_UDP_Send(l_udpSocket, l_udpChannel, l_request_input_packet);
}
static int check_valid(uint8_t control_id, uint32_t count)
@ -240,21 +280,20 @@ static int netplay_require_response(void* opaque)
static void netplay_process()
{
//In this function we process data we have received from the server
UDPpacket *packet = SDLNet_AllocPacket(512);
uint32_t curr, count, keys;
uint8_t plugin, player, current_status;
while (SDLNet_UDP_Recv(l_udpSocket, packet) == 1)
while (SDLNet_UDP_Recv(l_udpSocket, l_process_packet) == 1)
{
switch (packet->data[0])
switch (l_process_packet->data[0])
{
case UDP_RECEIVE_KEY_INFO:
case UDP_RECEIVE_KEY_INFO_GRATUITOUS:
player = packet->data[1];
player = l_process_packet->data[1];
//current_status is a status update from the server
//it will let us know if another player has disconnected, or the games have desynced
current_status = packet->data[2];
if (packet->data[0] == UDP_RECEIVE_KEY_INFO)
l_player_lag[player] = packet->data[3];
current_status = l_process_packet->data[2];
if (l_process_packet->data[0] == UDP_RECEIVE_KEY_INFO)
l_player_lag[player] = l_process_packet->data[3];
if (current_status != l_status)
{
if (((current_status & 0x1) ^ (l_status & 0x1)) != 0)
@ -269,9 +308,9 @@ static void netplay_process()
curr = 5;
//this loop processes input data from the server, inserting new events into the linked list for each player
//it skips events that we have already recorded, or if we receive data for an event that has already happened
for (uint8_t i = 0; i < packet->data[4]; ++i)
for (uint8_t i = 0; i < l_process_packet->data[4]; ++i)
{
count = SDLNet_Read32(&packet->data[curr]);
count = SDLNet_Read32(&l_process_packet->data[curr]);
curr += 4;
if (((count - l_cin_compats[player].netplay_count) > (UINT32_MAX / 2)) || (check_valid(player, count))) //event doesn't need to be recorded
@ -280,9 +319,9 @@ static void netplay_process()
continue;
}
keys = SDLNet_Read32(&packet->data[curr]);
keys = SDLNet_Read32(&l_process_packet->data[curr]);
curr += 4;
plugin = packet->data[curr];
plugin = l_process_packet->data[curr];
curr += 1;
//insert new event at beginning of linked list
@ -299,7 +338,6 @@ static void netplay_process()
break;
}
}
SDLNet_FreePacket(packet);
}
static int netplay_ensure_valid(uint8_t control_id)
@ -383,15 +421,13 @@ static uint32_t netplay_get_input(uint8_t control_id)
static void netplay_send_input(uint8_t control_id, uint32_t keys)
{
UDPpacket *packet = SDLNet_AllocPacket(11);
packet->data[0] = UDP_SEND_KEY_INFO;
packet->data[1] = control_id; //player number
SDLNet_Write32(l_cin_compats[control_id].netplay_count, &packet->data[2]); // current event count
SDLNet_Write32(keys, &packet->data[6]); //key data
packet->data[10] = l_plugin[control_id]; //current plugin
packet->len = 11;
SDLNet_UDP_Send(l_udpSocket, l_udpChannel, packet);
SDLNet_FreePacket(packet);
l_send_input_packet->data[0] = UDP_SEND_KEY_INFO;
l_send_input_packet->data[1] = control_id; //player number
SDLNet_Write32(l_cin_compats[control_id].netplay_count, &l_send_input_packet->data[2]); // current event count
SDLNet_Write32(keys, &l_send_input_packet->data[6]); //key data
l_send_input_packet->data[10] = l_plugin[control_id]; //current plugin
l_send_input_packet->len = 11;
SDLNet_UDP_Send(l_udpSocket, l_udpChannel, l_send_input_packet);
}
uint8_t netplay_register_player(uint8_t player, uint8_t plugin, uint8_t rawdata, uint32_t reg_id)
@ -541,22 +577,20 @@ void netplay_check_sync(struct cp0* cp0)
if (!netplay_is_init())
return;
const uint32_t* cp0_regs = r4300_cp0_regs(cp0);
if (l_vi_counter % 600 == 0)
{
uint32_t packet_len = (CP0_REGS_COUNT * 4) + 5;
UDPpacket *packet = SDLNet_AllocPacket(packet_len);
packet->data[0] = UDP_SYNC_DATA;
SDLNet_Write32(l_vi_counter, &packet->data[1]); //current VI count
const uint32_t* cp0_regs = r4300_cp0_regs(cp0);
l_check_sync_packet->data[0] = UDP_SYNC_DATA;
SDLNet_Write32(l_vi_counter, &l_check_sync_packet->data[1]); //current VI count
for (int i = 0; i < CP0_REGS_COUNT; ++i)
{
SDLNet_Write32(cp0_regs[i], &packet->data[(i * 4) + 5]);
SDLNet_Write32(cp0_regs[i], &l_check_sync_packet->data[(i * 4) + 5]);
}
packet->len = packet_len;
SDLNet_UDP_Send(l_udpSocket, l_udpChannel, packet);
SDLNet_FreePacket(packet);
l_check_sync_packet->len = l_check_sync_packet_size;
SDLNet_UDP_Send(l_udpSocket, l_udpChannel, l_check_sync_packet);
}
++l_vi_counter;
}

View file

@ -152,6 +152,10 @@ m64p_error open_rom(const unsigned char* romimage, unsigned int size)
return M64ERR_INPUT_INVALID;
}
/* ensure mem_base has enough memory allocated */
if (init_mem_rom(size) == NULL)
return M64ERR_NO_MEMORY;
/* Clear Byte-swapped flag, since ROM is now deleted. */
g_RomWordsLittleEndian = 0;
/* allocate new buffer for ROM and copy into this buffer */

View file

@ -26,18 +26,16 @@ jobs:
arch: x64
- cc: Clang
arch: x86
name: Linux / ${{ matrix.cc }} / ${{ matrix.arch }}
runs-on: ubuntu-22.04
name: Linux / ${{ matrix.cc }} ${{ matrix.arch }}
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Get build dependencies and arrange the environment
run: |
git clone --depth 1 https://github.com/mupen64plus/mupen64plus-core.git ../mupen64plus-core
export C_CLANG_SUFFIX="-15" C_GCC_SUFFIX="-12"
./../mupen64plus-core/.github/workflows/scripts/ci_install_ubuntu_deps.sh ${{ matrix.arch }} ${{ matrix.cc }}
- name: Build and related stuff, backup binaries
run: |
export C_CLANG_SUFFIX="-15" C_GCC_SUFFIX="-12"
./../mupen64plus-core/.github/workflows/scripts/ci_build.sh ${{ matrix.arch }} ${{ matrix.cc }} makepkg
- name: Upload artifact
if: matrix.cc == 'GCC'
@ -59,8 +57,16 @@ jobs:
arch: x86
cross: i686
env: MINGW32
name: Windows / MSYS2 ${{ matrix.cc }} / ${{ matrix.arch }}
runs-on: windows-2022
- cc: GCC
arch: x64
cross: ucrt-x86_64
env: UCRT64
- cc: Clang
arch: x64
cross: clang-x86_64
env: CLANG64
name: Windows ${{ matrix.arch }} / MSYS2 ${{ matrix.env }} ${{ matrix.cc }}
runs-on: windows-2025
defaults:
run:
shell: msys2 {0}
@ -74,7 +80,6 @@ jobs:
git
libtool
make
mingw-w64-${{ matrix.cross }}-gcc
mingw-w64-${{ matrix.cross }}-toolchain
mingw-w64-${{ matrix.cross }}-ntldd
- name: Build and related stuff, backup binaries
@ -97,11 +102,11 @@ jobs:
include:
- toolset: v143
arch: x64
vs: 2022
vs: 2025
- toolset: v141_xp
arch: x86
vs: 2019
name: Windows / MSVC with ${{ matrix.toolset }} / ${{ matrix.arch }}
name: Windows ${{ matrix.arch }} / MSVC with ${{ matrix.toolset }}
runs-on: windows-${{ matrix.vs }}
defaults:
run:

View file

@ -19,19 +19,17 @@ jobs:
arch: x64
- cc: Clang
arch: x86
name: Linux / ${{ matrix.cc }} / ${{ matrix.arch }}
runs-on: ubuntu-22.04
name: Linux / ${{ matrix.cc }} ${{ matrix.arch }}
runs-on: ubuntu-24.04
if: github.repository == 'mupen64plus/mupen64plus-rsp-hle'
steps:
- uses: actions/checkout@v4
- name: Get build dependencies and arrange the environment
run: |
git clone --depth 1 https://github.com/mupen64plus/mupen64plus-core.git ../mupen64plus-core
export C_CLANG_SUFFIX="-15" C_GCC_SUFFIX="-12"
./../mupen64plus-core/.github/workflows/scripts/ci_install_ubuntu_deps.sh ${{ matrix.arch }} ${{ matrix.cc }}
- name: Build and related stuff, backup binaries
run: |
export C_CLANG_SUFFIX="-15" C_GCC_SUFFIX="-12"
./../mupen64plus-core/.github/workflows/scripts/ci_build.sh ${{ matrix.arch }} ${{ matrix.cc }} makepkg
- name: Upload artifact
if: matrix.cc == 'GCC'
@ -53,8 +51,16 @@ jobs:
arch: x86
cross: i686
env: MINGW32
name: Windows / MSYS2 ${{ matrix.cc }} / ${{ matrix.arch }}
runs-on: windows-2022
- cc: GCC
arch: x64
cross: ucrt-x86_64
env: UCRT64
- cc: Clang
arch: x64
cross: clang-x86_64
env: CLANG64
name: Windows ${{ matrix.arch }} / MSYS2 ${{ matrix.env }} ${{ matrix.cc }}
runs-on: windows-2025
if: github.repository == 'mupen64plus/mupen64plus-rsp-hle'
defaults:
run:
@ -69,7 +75,6 @@ jobs:
git
libtool
make
mingw-w64-${{ matrix.cross }}-gcc
mingw-w64-${{ matrix.cross }}-toolchain
mingw-w64-${{ matrix.cross }}-ntldd
- name: Build and related stuff, backup binaries
@ -92,11 +97,11 @@ jobs:
include:
- toolset: v143
arch: x64
vs: 2022
vs: 2025
- toolset: v141_xp
arch: x86
vs: 2019
name: Windows / MSVC with ${{ matrix.toolset }} / ${{ matrix.arch }}
name: Windows ${{ matrix.arch }} / MSVC with ${{ matrix.toolset }}
runs-on: windows-${{ matrix.vs }}
if: github.repository == 'mupen64plus/mupen64plus-rsp-hle'
defaults:

View file

@ -1,2 +1,5 @@
/projects/unix/_obj*/
/projects/unix/mupen64plus-rsp-hle*.so
/projects/unix/mupen64plus-rsp-hle*.dll
/projects/msvc/Win32/
/projects/msvc/x64/

View file

@ -6,7 +6,7 @@
[subrepo]
remote = git@github.com:/mupen64plus/mupen64plus-rsp-hle.git
branch = master
commit = 47f8e92e9a8bb9e49195ecfb03e9df0b63add242
parent = 23120150f9ddbef13a0690f004c364bb334addfc
commit = 80efbed3d737a32114956e149905c304944ebd61
parent = 6e1df7fc792cbdee30d31366af395e72a6cde813
method = merge
cmdver = 0.4.6

View file

@ -475,7 +475,7 @@ static void ReorderSubBlock(int16_t *dst, const int16_t *src, const unsigned int
unsigned int i;
/* source and destination sublocks cannot overlap */
assert(labs(dst - src) > SUBBLOCK_SIZE);
assert(labs(dst - src) >= SUBBLOCK_SIZE);
for (i = 0; i < SUBBLOCK_SIZE; ++i)
dst[i] = src[table[i]];

View file

@ -6,7 +6,7 @@
[subrepo]
remote = git@github.com:/gonetz/GLideN64.git
branch = master
commit = 42129aadb16e0fb0e9c265ee134dbc7f9c4022e6
parent = 2c32dfd552dbfa5c2293b00fa22c4a08dd8c4eaf
commit = 55c436c706224eae6cd1395b88e083105b7d7834
parent = 5cab9282e7a7f1407cde18b6e5d1630f3c156042
method = merge
cmdver = 0.4.6

View file

@ -204,7 +204,7 @@ void GBIInfo::_makeCurrent(MicrocodeInfo * _pCurrent)
RDP_Init();
G_TRI1 = G_TRI2 = G_TRIX = G_QUAD = -1; // For correct work of gSPFlushTriangles()
G_TRI1 = G_TRI2 = G_TRIX = G_QUAD = G_TRISTRIP = G_TRIFAN = -1; // For correct work of gSPFlushTriangles()
gSP.clipRatio = 1U;
switch (m_pCurrent->type) {

View file

@ -53,6 +53,7 @@ void _loadSettings(GlSettings & settings)
config.generalEmulation.enableLegacyBlending = settings.value("enableLegacyBlending", config.generalEmulation.enableLegacyBlending).toInt(); //ini only
config.generalEmulation.enableHybridFilter = settings.value("enableHybridFilter", config.generalEmulation.enableHybridFilter).toInt(); //ini only
config.generalEmulation.enableFragmentDepthWrite = settings.value("enableFragmentDepthWrite", config.generalEmulation.enableFragmentDepthWrite).toInt(); //ini only
config.generalEmulation.hacks |= settings.value("hacks", config.generalEmulation.hacks).toInt(); //ini only
config.generalEmulation.enableCustomSettings = settings.value("enableCustomSettings", config.generalEmulation.enableCustomSettings).toInt();
settings.endGroup();

View file

@ -58,6 +58,7 @@ void _loadSettings(QSettings & settings)
config.generalEmulation.enableLegacyBlending = settings.value("enableLegacyBlending", config.generalEmulation.enableLegacyBlending).toInt(); //ini only
config.generalEmulation.enableHybridFilter = settings.value("enableHybridFilter", config.generalEmulation.enableHybridFilter).toInt(); //ini only
config.generalEmulation.enableFragmentDepthWrite = settings.value("enableFragmentDepthWrite", config.generalEmulation.enableFragmentDepthWrite).toInt(); //ini only
config.generalEmulation.hacks |= settings.value("hacks", config.generalEmulation.hacks).toInt(); //ini only
config.generalEmulation.enableCustomSettings = settings.value("enableCustomSettings", config.generalEmulation.enableCustomSettings).toInt();
settings.endGroup();

View file

@ -193,7 +193,7 @@ void GLInfo::init() {
eglImage = (Utils::isEGLExtensionSupported("EGL_KHR_image_base") || Utils::isEGLExtensionSupported("EGL_KHR_image"));
ext_fetch_arm = Utils::isExtensionSupported(*this, "GL_ARM_shader_framebuffer_fetch") && !ext_fetch;
dual_source_blending = !isGLESX || (Utils::isExtensionSupported(*this, "GL_EXT_blend_func_extended") && !isAnyAdreno);
dual_source_blending = !isGLESX || ((!isGLES2) && (Utils::isExtensionSupported(*this, "GL_EXT_blend_func_extended") && !isAnyAdreno));
anisotropic_filtering = Utils::isExtensionSupported(*this, "GL_EXT_texture_filter_anisotropic");
#ifdef OS_ANDROID

View file

@ -17,8 +17,9 @@ namespace graphics {
struct CachedTexture;
struct FrameBuffer;
#define VERTBUFF_SIZE 256U
#define ELEMBUFF_SIZE 1024U
constexpr u32 VERTBUFF_SIZE = 256U;
constexpr u32 VERTBUFF_MASK = VERTBUFF_SIZE - 1;
constexpr u32 ELEMBUFF_SIZE = 1024U;
constexpr f32 SCREEN_SIZE_DIM = 640.0f;
constexpr u32 MIPMAP_TILE_WIDTH = 256u;
@ -136,7 +137,7 @@ public:
bool isRejected(u32 _v0, u32 _v1, u32 _v2) const;
SPVertex & getVertex(u32 _v) { return triangles.vertices[_v]; }
SPVertex & getVertex(u32 _v) { return triangles.vertices[_v&VERTBUFF_MASK]; }
SPVertex * getVertexPtr(u32 _v) { return triangles.vertices.data() + _v; }

View file

@ -12,6 +12,7 @@
#include <iomanip>
#include <fstream>
#include <ctime>
#include <chrono>
#ifndef MUPENPLUSAPI // zilmar spec

View file

@ -43,6 +43,8 @@ void gSPFlushTriangles()
(RSP.nextCmd != G_TRI1) &&
(RSP.nextCmd != G_TRI2) &&
(RSP.nextCmd != G_TRIX) &&
(RSP.nextCmd != G_TRISTRIP) &&
(RSP.nextCmd != G_TRIFAN) &&
(RSP.nextCmd != G_QUAD)
) {
dwnd().getDrawer().drawTriangles();
@ -1566,6 +1568,11 @@ bool gSPCullVertices( u32 v0, u32 vn )
// Aidyn Chronicles - The First Mage seems to pass parameters in reverse order.
std::swap(v0, vn);
}
if (vn >= VERTBUFF_SIZE)
// Wrong input. DL is wrong, let's cull it.
return true;
u32 clip = 0;
GraphicsDrawer & drawer = dwnd().getDrawer();
for (u32 i = v0; i <= vn; ++i) {

View file

@ -396,6 +396,8 @@ void Config_LoadCustomConfig()
if (result == M64ERR_SUCCESS) config.generalEmulation.enableLegacyBlending = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "generalEmulation\\enableFragmentDepthWrite", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.generalEmulation.enableFragmentDepthWrite = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "generalEmulation\\hacks", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.generalEmulation.hacks |= atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "graphics2D\\correctTexrectCoords", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.graphics2D.correctTexrectCoords = atoi(value);

View file

@ -170,7 +170,9 @@ struct Vertices7
u8 v[7];
inline bool valid(u8 i) const
{ return v[i] < 64; }
{
return v[i] < 64;
}
};
static inline Vertices7 unpackVertices7(u32 w0, u32 w1)
@ -186,8 +188,15 @@ static inline Vertices7 unpackVertices7(u32 w0, u32 w1)
return v;
}
struct DeferFlush
{
~DeferFlush()
{ gSPFlushTriangles(); }
};
static void F3DEX3_TriStrip(u32 w0, u32 w1)
{
DeferFlush flush;
Vertices7 vertices = unpackVertices7(w0, w1);
// *v1 - v2 - v3, v3 - v2 - v4, v3 - v4 - v5, v5 - v4 - v6, v5 - v6 - v7
if (!vertices.valid(0) || !vertices.valid(1) || !vertices.valid(2)) return;
@ -208,6 +217,7 @@ static void F3DEX3_TriStrip(u32 w0, u32 w1)
static void F3DEX3_TriFan(u32 w0, u32 w1)
{
DeferFlush flush;
Vertices7 vertices = unpackVertices7(w0, w1);
// *v1 - v2 - v3, v1 - v3 - v4, v1 - v4 - v5, v1 - v5 - v6, v1 - v6 - v7
if (!vertices.valid(0) || !vertices.valid(1) || !vertices.valid(2)) return;
@ -220,7 +230,7 @@ static void F3DEX3_TriFan(u32 w0, u32 w1)
gSPTriangle(vertices.v[0], vertices.v[3], vertices.v[4]);
if (!vertices.valid(5)) return;
gSPTriangle(vertices.v[0], vertices.v[3], vertices.v[5]);
gSPTriangle(vertices.v[0], vertices.v[4], vertices.v[5]);
if (!vertices.valid(6)) return;
gSPTriangle(vertices.v[0], vertices.v[5], vertices.v[6]);

View file

@ -6,7 +6,7 @@
[subrepo]
remote = git@github.com:/Rosalie241/parallel-rdp-standalone.git
branch = RMG
commit = 74a9badf728fcb6a01ceb2ca9668aae5d1f1157c
parent = cb2948ec7404a7ee91e08fd5c3acb65c41629856
commit = 7d1281997ff5a03378c9dd51fefb164cdb4e7877
parent = fddf5eb4a7e99767c4095b34f542098670cdc78b
method = merge
cmdver = 0.4.6

View file

@ -61,17 +61,15 @@ MainDialog::MainDialog(QWidget* parent) : QDialog(parent)
}
this->resolutionUpscaleComboBox->setCurrentIndex(comboBoxIndex);
// set deinterlacer combobox
this->deinterlacerComboBox->setCurrentIndex(ConfigGetParamBool(configVideoParallel, KEY_DEINTERLACE) ? 1 : 0);
// set downscaling combobox
this->downscalerComboBox->setCurrentIndex(ConfigGetParamInt(configVideoParallel, KEY_DOWNSCALE));
// set cropOverscan combobox
this->cropOverscanSpinBox->setValue(ConfigGetParamInt(configVideoParallel, KEY_OVERSCANCROP));
// set verticalStretch combobox
this->verticalStretchSpinBox->setValue(ConfigGetParamInt(configVideoParallel, KEY_VERTICAL_STRETCH));
this->overscanGroupBox->setChecked(ConfigGetParamBool(configVideoParallel, KEY_OVERSCANCROPENABLE));
this->overscanLeftSpinBox->setValue(ConfigGetParamInt(configVideoParallel, KEY_OVERSCANCROPLEFT));
this->overscanRightSpinBox->setValue(ConfigGetParamInt(configVideoParallel, KEY_OVERSCANCROPRIGHT));
this->overscanTopSpinBox->setValue(ConfigGetParamInt(configVideoParallel, KEY_OVERSCANCROPTOP));
this->overscanBottomSpinBox->setValue(ConfigGetParamInt(configVideoParallel, KEY_OVERSCANCROPBOTTOM));
this->superSampledDitherCheckBox->setChecked(ConfigGetParamBool(configVideoParallel, KEY_SSDITHER));
this->viAaCheckBox->setChecked(ConfigGetParamBool(configVideoParallel, KEY_AA));
@ -127,8 +125,16 @@ void MainDialog::on_buttonBox_clicked(QAbstractButton* button)
ConfigSetParameter(configVideoParallel, KEY_DOWNSCALE, M64TYPE_INT, &downscalingValue);
// cropOverscan
int cropOverscanValue = this->cropOverscanSpinBox->value();
ConfigSetParameter(configVideoParallel, KEY_OVERSCANCROP, M64TYPE_INT, &cropOverscanValue);
int overscanEnabled = this->overscanGroupBox->isChecked();
int overscanLeft = this->overscanLeftSpinBox->value();
int overscanRight = this->overscanRightSpinBox->value();
int overscanTop = this->overscanTopSpinBox->value();
int overscanBottom = this->overscanBottomSpinBox->value();
ConfigSetParameter(configVideoParallel, KEY_OVERSCANCROPENABLE, M64TYPE_BOOL, &overscanEnabled);
ConfigSetParameter(configVideoParallel, KEY_OVERSCANCROPLEFT, M64TYPE_INT, &overscanLeft);
ConfigSetParameter(configVideoParallel, KEY_OVERSCANCROPRIGHT, M64TYPE_INT, &overscanRight);
ConfigSetParameter(configVideoParallel, KEY_OVERSCANCROPTOP, M64TYPE_INT, &overscanTop);
ConfigSetParameter(configVideoParallel, KEY_OVERSCANCROPBOTTOM, M64TYPE_INT, &overscanBottom);
// verticalStretch
int verticalStretchValue = this->verticalStretchSpinBox->value();
@ -167,8 +173,12 @@ void MainDialog::on_buttonBox_clicked(QAbstractButton* button)
this->resolutionUpscaleComboBox->setCurrentText("None");
this->deinterlacerComboBox->setCurrentIndex(0);
this->downscalerComboBox->setCurrentIndex(0);
this->cropOverscanSpinBox->setValue(0);
this->verticalStretchSpinBox->setValue(0);
this->overscanGroupBox->setChecked(false);
this->overscanLeftSpinBox->setValue(0);
this->overscanRightSpinBox->setValue(0);
this->overscanTopSpinBox->setValue(0);
this->overscanBottomSpinBox->setValue(0);
this->superSampledDitherCheckBox->setChecked(true);
this->viAaCheckBox->setChecked(true);

View file

@ -201,27 +201,6 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Crop overscan</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="cropOverscanSpinBox">
<property name="suffix">
<string> px</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<property name="bottomMargin">
@ -358,6 +337,53 @@
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="overscanGroupBox">
<property name="title">
<string>Overscan</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QSpinBox" name="overscanTopSpinBox">
<property name="minimum">
<number>-99</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QSpinBox" name="overscanLeftSpinBox">
<property name="minimum">
<number>-99</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="overscanRightSpinBox">
<property name="minimum">
<number>-99</number>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="overscanBottomSpinBox">
<property name="minimum">
<number>-99</number>
</property>
</widget>
</item>
</layout>
<zorder>overscanBottomSpinBox</zorder>
<zorder>overscanRightSpinBox</zorder>
<zorder>overscanLeftSpinBox</zorder>
<zorder>overscanTopSpinBox</zorder>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">

View file

@ -181,7 +181,11 @@ EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle _CoreLibHandle, void *Co
ConfigSetDefaultBool(configVideoParallel, KEY_DEINTERLACE, 0, "Deinterlacing method. False=Bob, True=Weave");
ConfigSetDefaultBool(configVideoParallel, KEY_SSREADBACKS, 0, "Enable superscaling of readbacks when upsampling");
ConfigSetDefaultBool(configVideoParallel, KEY_SSDITHER, 1, "Enable superscaling of dithering when upsampling");
ConfigSetDefaultInt(configVideoParallel, KEY_OVERSCANCROP, 0, "Amount of overscan pixels to crop on all sides");
ConfigSetDefaultInt(configVideoParallel, KEY_OVERSCANCROPLEFT, 0, "Amount of overscan pixels to crop on the left side");
ConfigSetDefaultInt(configVideoParallel, KEY_OVERSCANCROPRIGHT, 0, "Amount of overscan pixels to crop on the right side");
ConfigSetDefaultInt(configVideoParallel, KEY_OVERSCANCROPTOP, 0, "Amount of overscan pixels to crop on the top side");
ConfigSetDefaultInt(configVideoParallel, KEY_OVERSCANCROPBOTTOM, 0, "Amount of overscan pixels to crop on the bottom side");
ConfigSetDefaultBool(configVideoParallel, KEY_OVERSCANCROPENABLE, 0, "Whether to enable overscan");
ConfigSetDefaultInt(configVideoParallel, KEY_VERTICAL_STRETCH, 0, "Amount of pixels to stretch by vertically. Can fix PAL ports that didn't fill the PAL resolution of 288p (use value of 24 in that case).");
ConfigSetDefaultBool(configVideoParallel, KEY_AA, 1, "VI anti-aliasing, smooths polygon edges.");
ConfigSetDefaultBool(configVideoParallel, KEY_DIVOT, 1, "Allow VI divot filter, cleans up stray black pixels.");
@ -307,7 +311,11 @@ EXPORT int CALL RomOpen(void)
vk_native_tex_rect = ConfigGetParamBool(configVideoParallel, KEY_NATIVETEXTRECT);
vk_interlacing = ConfigGetParamBool(configVideoParallel, KEY_DEINTERLACE);
vk_downscaling_steps = ConfigGetParamInt(configVideoParallel, KEY_DOWNSCALE);
vk_overscan = ConfigGetParamInt(configVideoParallel, KEY_OVERSCANCROP);
vk_overscan_left = ConfigGetParamInt(configVideoParallel, KEY_OVERSCANCROPLEFT);
vk_overscan_right = ConfigGetParamInt(configVideoParallel, KEY_OVERSCANCROPRIGHT);
vk_overscan_top = ConfigGetParamInt(configVideoParallel, KEY_OVERSCANCROPTOP);
vk_overscan_bottom = ConfigGetParamInt(configVideoParallel, KEY_OVERSCANCROPBOTTOM);
vk_overscan_enable = ConfigGetParamBool(configVideoParallel, KEY_OVERSCANCROPENABLE);
vk_vertical_stretch = ConfigGetParamInt(configVideoParallel, KEY_VERTICAL_STRETCH);
m64p_error netplay_init = ConfigReceiveNetplayConfig(NULL, 0);

View file

@ -35,7 +35,11 @@ extern ptr_ConfigSetParameter ConfigSetParameter;
#define KEY_WIDESCREEN "WidescreenStretch"
#define KEY_SSDITHER "SuperscaledDither"
#define KEY_SSREADBACKS "SuperscaledReads"
#define KEY_OVERSCANCROP "CropOverscan"
#define KEY_OVERSCANCROPLEFT "CropOverscanLeft"
#define KEY_OVERSCANCROPRIGHT "CropOverscanRight"
#define KEY_OVERSCANCROPTOP "CropOverscanTop"
#define KEY_OVERSCANCROPBOTTOM "CropOverscanBottom"
#define KEY_OVERSCANCROPENABLE "CropOverscanEnable"
#define KEY_VERTICAL_STRETCH "VerticalStretch"
#define KEY_DIVOT "Divot"
#define KEY_GAMMADITHER "GammaDither"

View file

@ -19,9 +19,13 @@ static std::unique_ptr<MupenWSIPlatform> wsi_platform;
int32_t vk_rescaling;
bool vk_ssreadbacks;
bool vk_ssdither;
unsigned vk_overscan;
unsigned vk_vertical_stretch;
unsigned vk_downscaling_steps;
uint32_t vk_overscan_left;
uint32_t vk_overscan_right;
uint32_t vk_overscan_top;
uint32_t vk_overscan_bottom;
bool vk_overscan_enable;
uint32_t vk_vertical_stretch;
uint32_t vk_downscaling_steps;
bool vk_native_texture_lod;
bool vk_native_tex_rect;
bool vk_divot_filter, vk_gamma_dither;
@ -180,7 +184,11 @@ static void render_frame(Vulkan::Device &device)
opts.blend_previous_frame = vk_interlacing;
opts.upscale_deinterlacing = !vk_interlacing;
opts.downscale_steps = vk_downscaling_steps;
opts.crop_overscan_pixels = vk_overscan;
opts.crop_rect.left = vk_overscan_left;
opts.crop_rect.right = vk_overscan_right;
opts.crop_rect.top = vk_overscan_top;
opts.crop_rect.bottom = vk_overscan_bottom;
opts.crop_rect.enable = vk_overscan_enable;
if (vk_vertical_stretch) {
opts.crop_rect.top = vk_vertical_stretch;
opts.crop_rect.bottom = vk_vertical_stretch;

View file

@ -13,9 +13,13 @@ extern "C"
extern bool vk_ssreadbacks;
extern bool vk_ssdither;
extern unsigned vk_overscan;
extern unsigned vk_vertical_stretch;
extern unsigned vk_downscaling_steps;
extern uint32_t vk_overscan_left;
extern uint32_t vk_overscan_right;
extern uint32_t vk_overscan_top;
extern uint32_t vk_overscan_bottom;
extern bool vk_overscan_enable;
extern uint32_t vk_vertical_stretch;
extern uint32_t vk_downscaling_steps;
extern bool vk_native_texture_lod;
extern bool vk_native_tex_rect;
extern bool vk_divot_filter, vk_gamma_dither;

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.
@ -9,6 +9,8 @@
*/
#define CORE_INTERNAL
#include "Archive.hpp"
#include "Directories.hpp"
#include "Library.hpp"
#include "String.hpp"
#include "Error.hpp"
@ -27,7 +29,12 @@
// minizip includes
#include <unzip.h>
#ifndef ZNGLIB_H_
/* sadly older minizip-ng versions didn't include zlib.h automatically,
* so i.e voidpf would be undefined, in newer minizip-ng versions,
* including zlib.h will cause an error */
#include <zlib.h>
#endif
//
// Local Defines
@ -155,11 +162,11 @@ CORE_EXPORT bool CoreReadZipFile(std::filesystem::path file, std::filesystem::pa
for (uint64_t i = 0; i < zipInfo.number_entry; i++)
{
unz_file_info fileInfo;
char fileName[PATH_MAX];
char fileName[CORE_DIR_MAX_LEN];
// if we can't retrieve file info,
// skip the file
if (unzGetCurrentFileInfo(zipFile, &fileInfo, fileName, PATH_MAX, nullptr, 0, nullptr, 0) != UNZ_OK)
if (unzGetCurrentFileInfo(zipFile, &fileInfo, fileName, CORE_DIR_MAX_LEN, nullptr, 0, nullptr, 0) != UNZ_OK)
{
continue;
}
@ -319,7 +326,7 @@ CORE_EXPORT bool CoreRead7zipFile(std::filesystem::path file, std::filesystem::p
for (uint32_t i = 0; i < db.NumFiles; i++)
{
size_t filename_size = 0;
uint16_t fileName[PATH_MAX];
uint16_t fileName[CORE_DIR_MAX_LEN];
// skip directories
if (SzArEx_IsDir(&db, i))
@ -329,7 +336,7 @@ CORE_EXPORT bool CoreRead7zipFile(std::filesystem::path file, std::filesystem::p
// skip when filename size exceeds our buffer size
filename_size = SzArEx_GetFileNameUtf16(&db, i, nullptr);
if (filename_size > PATH_MAX)
if (filename_size > CORE_DIR_MAX_LEN)
{
continue;
}
@ -342,7 +349,7 @@ CORE_EXPORT bool CoreRead7zipFile(std::filesystem::path file, std::filesystem::p
// so we have to catch the exception and do nothing
try
{
fileNamePath = (char16_t*)fileName;
fileNamePath = reinterpret_cast<char16_t*>(fileName);
}
catch (...)
{
@ -474,10 +481,10 @@ CORE_EXPORT bool CoreUnzip(std::filesystem::path file, std::filesystem::path pat
for (uint64_t i = 0; i < zipInfo.number_entry; i++)
{
unz_file_info fileInfo;
char fileName[PATH_MAX];
char fileName[CORE_DIR_MAX_LEN];
// ensure we can retrieve the current file info
if (unzGetCurrentFileInfo(zipFile, &fileInfo, fileName, PATH_MAX, nullptr, 0, nullptr, 0) != UNZ_OK)
if (unzGetCurrentFileInfo(zipFile, &fileInfo, fileName, CORE_DIR_MAX_LEN, nullptr, 0, nullptr, 0) != UNZ_OK)
{
unzClose(zipFile);
error = "CoreUnzip: unzGetCurrentFileInfo Failed!";

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.
@ -24,7 +24,6 @@
// Local Defines
//
#define MAX_FILENAME_LEN 4096
#define ROMHEADER_NAME_LEN 256
#define GOODNAME_LEN 256
#define MD5_LEN 33
@ -79,7 +78,7 @@ static std::filesystem::path get_cache_file_name(void)
static std::vector<l_CacheEntry>::iterator get_cache_entry_iter(const std::filesystem::path& file, bool checkFileTime = true)
{
CoreFileTime fileTime = CoreGetFileTime(file);
CoreFileTime fileTime = (checkFileTime ? CoreGetFileTime(file) : 0);
auto predicate = [file, fileTime, checkFileTime](const auto& entry)
{
@ -87,7 +86,7 @@ static std::vector<l_CacheEntry>::iterator get_cache_entry_iter(const std::files
(!checkFileTime || entry.fileTime == fileTime);
};
return std::find_if(l_CacheEntries.begin(), l_CacheEntries.end(), predicate);
return std::find_if(l_CacheEntries.begin(), l_CacheEntries.end(), predicate);
}
static void add_cache_entry(const std::filesystem::path& file, CoreRomType type,
@ -152,7 +151,7 @@ CORE_EXPORT void CoreReadRomHeaderAndSettingsCache(void)
{
std::ifstream inputStream;
char magicBuf[sizeof(CACHE_FILE_MAGIC)];
wchar_t fileNameBuf[MAX_FILENAME_LEN];
wchar_t fileNameBuf[CORE_DIR_MAX_LEN];
char headerNameBuf[ROMHEADER_NAME_LEN];
char gameIDBuf[GAMEID_LEN];
char regionBuf[REGION_LEN];
@ -261,7 +260,7 @@ CORE_EXPORT void CoreReadRomHeaderAndSettingsCache(void)
CORE_EXPORT bool CoreSaveRomHeaderAndSettingsCache(void)
{
std::ofstream outputStream;
wchar_t fileNameBuf[MAX_FILENAME_LEN];
wchar_t fileNameBuf[CORE_DIR_MAX_LEN];
char headerNameBuf[ROMHEADER_NAME_LEN];
char gameIDBuf[GAMEID_LEN];
char regionBuf[REGION_LEN];
@ -306,7 +305,7 @@ CORE_EXPORT bool CoreSaveRomHeaderAndSettingsCache(void)
memset(md5Buf, 0, sizeof(md5Buf));
// copy strings into buffers
wcsncpy(fileNameBuf, cacheEntry.fileName.wstring().c_str(), MAX_FILENAME_LEN);
wcsncpy(fileNameBuf, cacheEntry.fileName.wstring().c_str(), CORE_DIR_MAX_LEN);
strncpy(headerNameBuf, cacheEntry.header.Name.c_str(), sizeof(headerNameBuf));
strncpy(gameIDBuf, cacheEntry.header.GameID.c_str(), sizeof(gameIDBuf));
strncpy(regionBuf, cacheEntry.header.Region.c_str(), sizeof(regionBuf));

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.
@ -42,7 +42,7 @@ static std::vector<l_DebugCallbackMessage> l_PendingCallbacks;
void CoreDebugCallback(void* context, int level, const char* message)
{
std::string contextString((const char*)context);
std::string contextString(static_cast<char*>(context));
std::string messageString(message);
if (!l_SetupCallbacks)

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.
@ -188,7 +188,7 @@ static std::string join_split_string(const std::vector<std::string>& splitStr, c
continue;
}
element = splitStr.at(i);
element = splitStr[i];
joinedString += element;
// when not at the last element,
@ -208,7 +208,7 @@ static bool parse_cheat(const std::vector<std::string>& lines, int startIndex, C
std::string line;
for (size_t i = startIndex; i < lines.size(); i++)
{
line = lines.at(i);
line = lines[i];
// Parse metadata
// $Cheat Name
@ -240,7 +240,7 @@ static bool parse_cheat(const std::vector<std::string>& lines, int startIndex, C
break;
}
std::vector<std::string> splitLine = split_string(line, ' ');
const std::vector<std::string> splitLine = split_string(line, ' ');
// skip invalid lines
if (splitLine.size() < 2)
@ -253,8 +253,8 @@ static bool parse_cheat(const std::vector<std::string>& lines, int startIndex, C
return false;
}
std::string address = splitLine.at(0);
std::string value = splitLine.at(1);
std::string address = splitLine[0];
std::string value = splitLine[1];
if (splitLine.size() == 2 && address.size() == 8 && (value.size() == 4 || value.size() == 9))
{ // cheat code
@ -265,7 +265,7 @@ static bool parse_cheat(const std::vector<std::string>& lines, int startIndex, C
// so strip the old value
if (value.size() == 9)
{
if (value.at(4) == ':')
if (value[4] == ':')
{
value.erase(4, 5);
}
@ -347,7 +347,7 @@ static bool parse_cheat_file(const std::vector<std::string>& lines, CoreCheatFil
for (size_t index = 0; index < lines.size(); index++)
{
line = lines.at(index);
line = lines[index];
if (!readHeader && line.starts_with("[") && line.ends_with("]"))
{
@ -364,7 +364,7 @@ static bool parse_cheat_file(const std::vector<std::string>& lines, CoreCheatFil
else
{ // CRC1 & CRC2 & CountryCode
// validate header
if (line.size() != 22 || line.at(8) != '-' || line.at(17) != '-' || line.at(18) != 'C' || line.at(19) != ':')
if (line.size() != 22 || line[8] != '-' || line[17] != '-' || line[18] != 'C' || line[19] != ':')
{
error = "parse_cheat_file Failed: ";
error += "invalid header: \"";
@ -374,9 +374,10 @@ static bool parse_cheat_file(const std::vector<std::string>& lines, CoreCheatFil
return false;
}
std::string crc1 = split_string(line, '-').at(0);
std::string crc2 = split_string(line, '-').at(1);
std::string countryCode = split_string(line, ':').at(1);
const std::vector<std::string> splitCrcString = split_string(line, '-');
const std::string crc1 = splitCrcString[0];
const std::string crc2 = splitCrcString[1];
const std::string countryCode = split_string(line, ':')[1];
cheatFile.CRC1 = std::strtoll(crc1.c_str(), nullptr, 16);
cheatFile.CRC2 = std::strtoll(crc2.c_str(), nullptr, 16);

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.
@ -138,7 +138,7 @@ CORE_EXPORT bool CoreInit(void)
CoreStateCallback);
if (m64p_ret != M64ERR_SUCCESS)
{
error = "CoreInit M64P::Core.Startup() Failed: ";
error = "CoreInit m64p::Core.Startup() Failed: ";
error += m64p::Core.ErrorMessage(m64p_ret);
CoreSetError(error);
return false;
@ -196,6 +196,8 @@ CORE_EXPORT void CoreShutdown(void)
CoreDiscordRpcShutdown();
#endif // DISCORD_RPC
m64p::Core.Shutdown();
m64p::Core.Unhook();
m64p::Config.Unhook();

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.
@ -17,7 +17,7 @@
#include "m64p/Api.hpp"
#include <filesystem>
#include <iostream>
#include <stdexcept>
#include <optional>
#include <cstdlib>
#include <cstdio>
@ -58,15 +58,14 @@ static std::filesystem::path get_exe_directory(void)
if (GetModuleFileNameW(nullptr, buffer, MAX_PATH) == 0)
{
MessageBoxA(nullptr, "get_exe_directory: GetModuleFileNameW() Failed!", "Error", MB_OK | MB_ICONERROR);
std::terminate();
throw std::runtime_error("get_exe_directory: GetModuleFileNameW() failed");
}
directory = std::filesystem::path(buffer).parent_path();
#else // _WIN32
directory = std::filesystem::canonical("/proc/self/exe", errorCode).parent_path();
if (errorCode)
{
std::cerr << "get_exe_directory: std::filesystem::canonical(\"/proc/self/exe\") failed: " << errorCode.message() << std::endl;
std::terminate();
throw std::runtime_error("get_exe_directory: std::filesystem::canonical(\"/proc/self/exe\") failed: " + errorCode.message());
}
#endif // _WIN32
return directory.make_preferred();
@ -112,8 +111,7 @@ static std::filesystem::path get_var_directory(std::string var, std::string appe
env = std::getenv(fallbackVar.c_str());
if (env == nullptr)
{
std::cerr << "get_var_directory: fallbackVar: $" << fallbackVar << " cannot be nullptr!" << std::endl;
std::terminate();
throw std::runtime_error("get_var_directory: fallbackVar: $" + fallbackVar + " cannot be non-existent");
}
directory = env;
directory += fallbackAppend;

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.
@ -17,6 +17,7 @@
#else // Unix
#define CORE_DIR_SEPERATOR_STR "/"
#endif // _WIN32
#define CORE_DIR_MAX_LEN 4096
// tries to create the needed directories,
// returns false when failed

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.
@ -24,6 +24,7 @@
#include <filesystem>
#include <algorithm>
#include <stdexcept>
#include <cstring>
#include <array>
@ -39,24 +40,23 @@ static char l_PluginContext[4][20];
// Local Functions
//
static m64p::PluginApi* get_plugin(CorePluginType type)
static m64p::PluginApi& get_plugin(CorePluginType type)
{
if (type == CorePluginType::Invalid ||
static_cast<int>(type) < 0 ||
if (static_cast<int>(type) < 1 ||
static_cast<int>(type) > 4)
{
return nullptr;
throw std::runtime_error("get_plugin: called with invalid type");
}
return &l_Plugins[static_cast<int>(type) - 1];
return l_Plugins[static_cast<int>(type) - 1];
}
static CorePluginType get_plugin_type(m64p::PluginApi* plugin)
static CorePluginType get_plugin_type(m64p::PluginApi& plugin)
{
m64p_error ret;
m64p_plugin_type m64p_type = M64PLUGIN_NULL;
ret = plugin->GetVersion(&m64p_type, nullptr, nullptr, nullptr, nullptr);
ret = plugin.GetVersion(&m64p_type, nullptr, nullptr, nullptr, nullptr);
if (ret != M64ERR_SUCCESS)
{
return CorePluginType::Invalid;
@ -71,12 +71,12 @@ static CorePluginType get_plugin_type(m64p::PluginApi* plugin)
return static_cast<CorePluginType>(m64p_type);
}
static std::string get_plugin_name(m64p::PluginApi* plugin, const std::string& filename)
static std::string get_plugin_name(m64p::PluginApi& plugin, const std::string& filename)
{
m64p_error ret;
const char* name = nullptr;
ret = plugin->GetVersion(nullptr, nullptr, nullptr, &name, nullptr);
ret = plugin.GetVersion(nullptr, nullptr, nullptr, &name, nullptr);
if (ret != M64ERR_SUCCESS ||
name == nullptr)
{
@ -190,7 +190,6 @@ static bool apply_plugin_settings(const std::array<std::string, 4>& pluginSettin
{
std::string error;
std::string settingValue;
m64p::PluginApi* plugin;
CorePluginType pluginType;
CoreLibraryHandle handle;
m64p_error ret;
@ -209,12 +208,12 @@ static bool apply_plugin_settings(const std::array<std::string, 4>& pluginSettin
if (settingValue != l_PluginFiles[i])
{
plugin = &l_Plugins[i];
m64p::PluginApi& plugin = l_Plugins[i];
// shutdown plugin when hooked
if (plugin->IsHooked())
if (plugin.IsHooked())
{
ret = plugin->Shutdown();
ret = plugin.Shutdown();
if (ret != M64ERR_SUCCESS)
{
error = "apply_plugin_settings (";
@ -226,7 +225,7 @@ static bool apply_plugin_settings(const std::array<std::string, 4>& pluginSettin
}
// reset plugin
plugin->Unhook();
plugin.Unhook();
}
// ensure library file exists
@ -250,14 +249,14 @@ static bool apply_plugin_settings(const std::array<std::string, 4>& pluginSettin
}
// attempt to hook the library
if (!plugin->Hook(handle))
if (!plugin.Hook(handle))
{
error = "apply_plugin_settings (";
error += get_plugin_type_name(pluginType);
error += ")->Hook() Failed: ";
error += plugin->GetLastError();
error += plugin.GetLastError();
CoreSetError(error);
plugin->Unhook();
plugin.Unhook();
return false;
}
@ -270,12 +269,12 @@ static bool apply_plugin_settings(const std::array<std::string, 4>& pluginSettin
error += get_plugin_type_name(pluginType);
error += "!";
CoreSetError(error);
plugin->Unhook();
plugin.Unhook();
return false;
}
// attempt to start plugin
ret = plugin->Startup(m64p::Core.GetHandle(), l_PluginContext[i], CoreDebugCallback);
ret = plugin.Startup(m64p::Core.GetHandle(), l_PluginContext[i], CoreDebugCallback);
if (ret != M64ERR_SUCCESS)
{
error = "apply_plugin_settings (";
@ -283,8 +282,8 @@ static bool apply_plugin_settings(const std::array<std::string, 4>& pluginSettin
error += ")->Startup() Failed: ";
error += m64p::Core.ErrorMessage(ret);
CoreSetError(error);
plugin->Shutdown();
plugin->Unhook();
plugin.Shutdown();
plugin.Unhook();
// force a re-load next time,
// because this plugin isn't
// the one we've stored in
@ -308,7 +307,7 @@ static bool open_plugin_config(CorePluginType type, void* parent, bool romConfig
std::string error;
m64p_error ret;
bool resumeEmulation = false;
m64p::PluginApi* plugin;
m64p::PluginApi& plugin = get_plugin(type);
std::string functionName;
CoreRomHeader romHeader;
CoreRomSettings romSettings;
@ -350,27 +349,17 @@ static bool open_plugin_config(CorePluginType type, void* parent, bool romConfig
}
}
plugin = get_plugin(type);
if (plugin == nullptr)
{
error = "open_plugin_config Failed: ";
error += get_plugin_type_name(type);
error += " isn't a valid plugin type!";
CoreSetError(error);
return false;
}
// check if the plugin has the ConfigWithRomConfig
// or Config function, the ConfigWithRomConfig function
// has priority
if (plugin->ConfigWithRomConfig != nullptr)
if (plugin.ConfigWithRomConfig != nullptr)
{
ret = plugin->ConfigWithRomConfig(parent, romConfig ? 1 : 0, &romHeader, &romSettings);
ret = plugin.ConfigWithRomConfig(parent, romConfig ? 1 : 0, &romHeader, &romSettings);
functionName = "Config2";
}
else
{
ret = plugin->Config(parent);
ret = plugin.Config(parent);
functionName = "Config";
}
@ -419,8 +408,8 @@ CORE_EXPORT std::vector<CorePlugin> CoreGetAllPlugins(void)
continue;
}
plugin_name = get_plugin_name(&plugin, entry.path().filename().string());
plugin_type = get_plugin_type(&plugin);
plugin_name = get_plugin_name(plugin, entry.path().filename().string());
plugin_type = get_plugin_type(plugin);
plugin.Unhook();
CoreCloseLibrary(handle);
@ -499,20 +488,10 @@ CORE_EXPORT bool CoreArePluginsReady(void)
CORE_EXPORT bool CorePluginsHasConfig(CorePluginType type)
{
std::string error;
m64p::PluginApi* plugin;
m64p::PluginApi& plugin = get_plugin(type);
plugin = get_plugin(type);
if (plugin == nullptr)
{
error = "CorePluginsHasConfig Failed: ";
error += get_plugin_type_name(type);
error += " isn't a valid plugin type!";
CoreSetError(error);
return false;
}
return plugin->Config != nullptr ||
plugin->ConfigWithRomConfig != nullptr;
return plugin.Config != nullptr ||
plugin.ConfigWithRomConfig != nullptr;
}
CORE_EXPORT bool CorePluginsOpenConfig(CorePluginType type, void* parent)
@ -522,11 +501,9 @@ CORE_EXPORT bool CorePluginsOpenConfig(CorePluginType type, void* parent)
CORE_EXPORT bool CorePluginsHasROMConfig(CorePluginType type)
{
m64p::PluginApi* plugin;
m64p::PluginApi& plugin = get_plugin(type);
plugin = get_plugin(type);
return plugin->ConfigWithRomConfig != nullptr;
return plugin.ConfigWithRomConfig != nullptr;
}
CORE_EXPORT bool CorePluginsOpenROMConfig(CorePluginType type, void* parent, std::filesystem::path file)
@ -553,11 +530,11 @@ CORE_EXPORT bool CoreAttachPlugins(void)
for (int i = 0; i < static_cast<int>(CorePluginType::Count); i++)
{
ret = m64p::Core.AttachPlugin(plugin_types[i], get_plugin(static_cast<CorePluginType>(plugin_types[i]))->GetHandle());
ret = m64p::Core.AttachPlugin(plugin_types[i], get_plugin(static_cast<CorePluginType>(plugin_types[i])).GetHandle());
if (ret != M64ERR_SUCCESS)
{
error = "CoreAttachPlugins m64p::Core.AttachPlugin(";
error += get_plugin_type_name((CorePluginType)plugin_types[i]);
error += get_plugin_type_name(static_cast<CorePluginType>(plugin_types[i]));
error += ") Failed: ";
error += m64p::Core.ErrorMessage(ret);
CoreSetError(error);

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.
@ -24,6 +24,26 @@
// Local Functions
//
static std::string get_name_from_headername(uint8_t name[20])
{
std::string safeName;
size_t count = 0;
// count characters from internal
// ROM name, the maximum is 20 so
// we can hardcode that safely
for (; count < 20; count++)
{
if (name[count] == '\0')
{
break;
}
}
safeName = std::string(reinterpret_cast<char*>(name), count);
return CoreConvertStringEncoding(safeName, CoreStringEncoding::Shift_JIS);
}
static std::string get_gameid_from_header(m64p_rom_header header)
{
std::string gameID;
@ -171,7 +191,7 @@ CORE_EXPORT bool CoreGetCurrentRomHeader(CoreRomHeader& header)
header.CRC1 = ntohl(m64p_header.CRC1);
header.CRC2 = ntohl(m64p_header.CRC2);
header.CountryCode = m64p_header.Country_code;
header.Name = CoreConvertStringEncoding(std::string(reinterpret_cast<char*>(m64p_header.Name), 20), CoreStringEncoding::Shift_JIS);
header.Name = get_name_from_headername(m64p_header.Name);
header.GameID = get_gameid_from_header(m64p_header);
header.Region = get_region_from_countrycode(static_cast<char>(header.CountryCode));
header.SystemType = get_systemtype_from_countrycode(header.CountryCode);

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

View file

@ -1,6 +1,6 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
* Copyright (C) 2020-2025 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.

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