Compare commits

...

19 Commits

Author SHA1 Message Date
Rosalie Wanders 453f663973 Package: v0.9.0 2026-06-14 19:54:27 +02:00
Rosalie Wanders f76e7472fd 3rdParty: revert to using GL_RGBA in mupen64plus-video-GLideN64
For some reason when using GL_RGB, it seems to corrupt memory and cause
a crash, valgrind says the following:

==29295== Invalid write of size 1
==29295==    at 0x20BC10E6: convert_ubyte (format_utils.c:996)
==29295==    by 0x20BDE59B: _mesa_format_convert (format_utils.c:452)
==29295==    by 0x20CA072D: read_rgba_pixels (readpix.c:609)
==29295==    by 0x20CA072D: _mesa_readpixels (readpix.c:923)
==29295==    by 0x20CA6DCA: st_ReadPixels (st_cb_readpixels.c:577)
==29295==    by 0x20CA120B: read_pixels (readpix.c:1218)
==29295==    by 0x20CA120B: _mesa_ReadnPixelsARB (readpix.c:1235)
==29295==    by 0x20CA1564: _mesa_ReadPixels (readpix.c:1250)
==29295==    by 0x5741BCF4: opengl::GlReadPixelsCommand::commandToExecute() (opengl_WrappedFunctions.h:682)
==29295==    by 0x5740EB75: opengl::OpenGlCommand::performCommandSingleThreaded() (opengl_Command.cpp:13)
==29295==    by 0x574117B1: opengl::FunctionWrapper::executeCommand(std::shared_ptr<opengl::OpenGlCommand>) (opengl_Wrapper.cpp:30)
==29295==    by 0x57412548: opengl::FunctionWrapper::wrReadPixels(int, int, int, int, unsigned int, unsigned int, void*) (opengl_Wrapper.cpp:316)
==29295==    by 0x57507C74: DisplayWindowMupen64plus::_readScreen2(void*, int*, int*, int) (mupen64plus_DisplayWindow.cpp:263)
==29295==    by 0x573B69D3: DisplayWindow::readScreen2(void*, int*, int*, int) (DisplayWindow.cpp:209)

valgrind leads me to believe this might be a mesa issue where it writes
out of bounds of the provided buffer, this issue does not occur when
using GL_RGBA, nor does it appear when using an older mesa version in
the AppImage.

Reverting https://github.com/gonetz/GLideN64/pull/2856 fixes the issue.
Fixes https://github.com/Rosalie241/RMG/issues/498
2026-06-14 19:48:39 +02:00
Rosalie Wanders ff9b9a2040 Package: force pulseaudio for AppImage in AppRun 2026-06-13 21:50:53 +02:00
Rosalie Wanders 99bb81d9b9 Package: add libpulse to AppImage in Create.sh 2026-06-13 21:50:53 +02:00
Rosalie Wanders fe67ba053e RMG-Audio: retrieve SDL error when SDL_Init() fails 2026-06-13 19:15:39 +02:00
Rosalie Wanders 6ebbba6fc5 ci: use actions/upload-artifact@v7 2026-06-13 19:14:34 +02:00
Rosalie Wanders 21d0b55a35 ci: update SDL to release-3.4.10 2026-06-13 19:00:55 +02:00
Rosalie Wanders 6ef6432a15 ci: use hendrikmuhs/ccache-action@v1.2.23
It seems the v1.2 tag isn't being updated anymore.
2026-06-13 19:00:43 +02:00
Rosalie Wanders 02e2518be2 3rdParty: update LZMA SDK to v26.01 2026-06-13 18:55:42 +02:00
Rosalie Wanders 2da7750640 3rdParty: update mupen64plus-core 2026-06-13 18:53:48 +02:00
Rosalie Wanders 4c50859481 README: add Netplay section 2026-06-13 18:51:09 +02:00
Rosalie Wanders 2867fc627b RMG-Core: remove Netplay_DispatcherUrl setting 2026-06-13 18:51:09 +02:00
Rosalie Wanders 47df34da6b RMG: remove support for the dispatcher server 2026-06-13 18:51:09 +02:00
Rosalie Wanders 7e4e402f27 RMG-Core: fix minizip include in Archive.cpp 2026-02-24 08:25:28 +01:00
Rosalie Wanders 8ee3410680 3rdParty: fix minizip includes for mupen64plus-core 2026-02-24 08:25:14 +01:00
Rosalie Wanders e9167db9ff Package: add vcs-browser url to metainfo.xml 2026-01-23 07:10:23 +01:00
Rosalie Wanders 94f5fd9d82 Package: use 'and' instead of '&amp;' in desktop file 2026-01-23 07:06:11 +01:00
Rosalie Wanders 969d63f182 Package: v0.8.9 2026-01-23 06:53:42 +01:00
Rosalie Wanders c7a4e6c47a README: remove obsolete support link 2026-01-21 10:05:15 +01:00
45 changed files with 869 additions and 652 deletions
+6 -6
View File
@@ -20,7 +20,7 @@ jobs:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: hendrikmuhs/ccache-action@v1.2
- uses: hendrikmuhs/ccache-action@v1.2.23
with:
key: linux-${{ matrix.architecture }}-${{ matrix.features }}-${{ matrix.configuration }}
- name: Install Packages
@@ -54,7 +54,7 @@ jobs:
run: |
export sdl_dir="$(pwd)/../SDL3"
git clone https://github.com/libsdl-org/SDL.git "$sdl_dir" -b release-3.2.28 --depth=1
git clone https://github.com/libsdl-org/SDL.git "$sdl_dir" -b release-3.4.10 --depth=1
mkdir -p "$sdl_dir/build"
cmake -S "$sdl_dir" -B "$sdl_dir/build" \
@@ -94,7 +94,7 @@ jobs:
shell: bash
- name: Upload RMG (AppImage)
if: ${{ matrix.features == 'ON' && matrix.architecture == 'x86_64' && matrix.configuration == 'Release' }}
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v7
with:
name: RMG-Portable-Linux64-${{ env.GIT_REVISION }}
path: Bin/*.AppImage
@@ -112,7 +112,7 @@ jobs:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: hendrikmuhs/ccache-action@v1.2
- uses: hendrikmuhs/ccache-action@v1.2.23
with:
key: windows-${{ matrix.features }}-${{ matrix.configuration }}
- uses: msys2/setup-msys2@v2
@@ -167,13 +167,13 @@ jobs:
shell: msys2 {0}
- name: Upload RMG (Portable)
if: ${{ matrix.features == 'ON' && matrix.configuration == 'Release' }}
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v7
with:
name: RMG-Portable-Windows64-${{ env.GIT_REVISION }}
path: Bin/Release/*
- name: Upload RMG (Installer)
if: ${{ matrix.features == 'ON' && matrix.configuration == 'Release' }}
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v7
with:
name: RMG-Setup-Windows64-${{ env.GIT_REVISION }}
path: Bin/*.exe
+8
View File
@@ -3,6 +3,14 @@
[ -f "$APPIMAGE_QT_THEME" ] && set -- "$@" "-stylesheet" "$APPIMAGE_QT_THEME"
cur_dir="$(readlink -f "$(dirname "$0")")"
# force pulseaudio to fix audio issues
# else we get the following error:
# Failed to initialize SDL audio subsystem: Failed loading libjack.so.0:
# /tmp/.mount_RMG-PoJFjkog/shared/lib/libc.so.6: version `GLIBC_ABI_GNU2_TLS' not found
# (required by /usr/lib64/pipewire-0.3/jack/libjack.so.0)
# see https://github.com/Rosalie241/RMG/issues/494 for more details
export SDL_AUDIODRIVER=pulseaudio
exec "$cur_dir/bin/RMG" \
--lib-path="$cur_dir/shared/lib/RMG" \
--core-path="$cur_dir/shared/lib/RMG/Core" \
+1
View File
@@ -64,6 +64,7 @@ $XVFB_RUN "$script_dir/lib4bin" --dst-dir "$bin_dir" \
"$lib_dir"/libGL* \
"$lib_dir"/libEGL* \
"$lib_dir"/libvulkan* \
"$lib_dir"/libpulse* \
"$lib_dir"/dri/* \
"$lib_dir"/libssl.so* \
"$lib_dir"/qt6/plugins/iconengines/* \
+1 -1
View File
@@ -1,6 +1,6 @@
# Maintainer: Rosalie Wanders <rosalie@mailbox.org>
pkgname=rmg
pkgver=0.8.8
pkgver=0.9.0
pkgrel=1
pkgdesc="Rosalie's Mupen GUI"
arch=('x86_64' 'aarch64')
+1 -1
View File
@@ -1,5 +1,5 @@
Name: RMG
Version: 0.8.8
Version: 0.9.0
Release: %autorelease
Summary: Rosalie's Mupen GUI
+1 -1
View File
@@ -1,7 +1,7 @@
[Desktop Entry]
Type=Application
Name=Rosalie's Mupen GUI
Comment=An easy to use &amp; cross-platform mupen64plus front-end written in C++ & Qt
Comment=An easy to use and cross-platform mupen64plus front-end written in C++ & Qt
Exec=RMG %f
TryExec=RMG
Icon=com.github.Rosalie241.RMG
@@ -29,6 +29,32 @@
</screenshot>
</screenshots>
<releases>
<release version="v0.9.0" date="2026-06-14" type="stable">
<description>
<p>Changes:</p>
<ul>
<li>Fix build issues with zlib v1.3.1</li>
<li>Fix audio not working when using the AppImage (thank you Samueru-sama)</li>
<li>Fix screenshots causing a crash on Linux</li>
<li>Remove dispatcher server support</li>
<li>Update mupen64plus-core and LZMA SDK</li>
</ul>
</description>
</release>
<release version="v0.8.9" date="2026-01-23" type="stable">
<description>
<p>Changes:</p>
<ul>
<li>Fix AppImage icon not working since v0.7.1 (thank you Samueru-sama)</li>
<li>Fix desktop file causing a crash on Budgie (thank you jpleatherland)</li>
<li>Fix memory pak from player 2, 3 and 4 not saving correctly</li>
<li>Fix Star Wars - Rogue Squadron having missing geometry when using GLideN64</li>
<li>Remove translations from the configuration GUI of GLideN64</li>
<li>Add plugin settings shortcuts to the toolbar</li>
<li>Update mupen64plus-video-GLideN64, SDL_net and SDL_GameControllerDB</li>
</ul>
</description>
</release>
<release version="v0.8.8" date="2025-11-16" type="stable">
<description>
<p>Changes:</p>
@@ -1024,6 +1050,7 @@
</releases>
<url type="homepage">https://github.com/Rosalie241/RMG</url>
<url type="bugtracker">https://github.com/Rosalie241/RMG/issues</url>
<url type="vcs-browser">https://github.com/Rosalie241/RMG</url>
<categories>
<category>Game</category>
<category>Emulator</category>
+36 -4
View File
@@ -7,7 +7,7 @@ It offers a simple-to-use user interface.
## Download
#### Windows
You can download Rosalie's Mupen GUI on ![Github Releases](https://github.com/Rosalie241/RMG/releases)
You can download Rosalie's Mupen GUI on [Github Releases](https://github.com/Rosalie241/RMG/releases)
#### Linux
You can download Rosalie's Mupen GUI on
@@ -16,11 +16,43 @@ You can download Rosalie's Mupen GUI on
* [Arch User Repository](https://aur.archlinux.org/packages/rmg)
* [Fedora COPR](https://copr.fedorainfracloud.org/coprs/rosalie/RMG/)
## Netplay
You can use netplay with the following methods:
### Port Forwarding
1) Download [rmg-netplay-server](https://github.com/Rosalie241/rmg-netplay-server/releases/latest)
2) Port forward the ports stated in the [rmg-netplay-server README](https://github.com/Rosalie241/rmg-netplay-server)
3) Create a JSON file with something similar to the following contents, but using your public IP instead of a local one:
```
{
"some-server-name": "127.0.0.1"
}
```
If you want to add multiple servers instead:
```
{
"some-server-name": "127.0.0.1",
"some-server-name-2": "127.0.0.1"
}
```
4) Store the JSON file or upload it somewhere
5) Enter the JSON file path or URL in the "Server list URL" text box in the RMG settings dialog
6) The specified servers in the JSON file should appear in the RMG GUI
### Tunneling Software
1) Download [rmg-netplay-server](https://github.com/Rosalie241/rmg-netplay-server/releases/latest)
2) Download [Radmin VPN](https://www.radmin-vpn.com/)
3) Run and create or join a network in Radmin VPN
4) The host should run [rmg-netplay-server](https://github.com/Rosalie241/rmg-netplay-server)
5) The server should show up as `local-server` within the RMG GUI
## Support
You can ask for help or report issues on
* [Github](https://github.com/Rosalie241/RMG/issues/new)
* [Discord](https://discord.gg/k9GuyJ2PpF)
You can ask for help or report issues on [Github](https://github.com/Rosalie241/RMG/issues/new)
## License
+23 -29
View File
@@ -1,5 +1,5 @@
/* 7zArcIn.c -- 7z Input functions
2023-09-07 : Igor Pavlov : Public domain */
: Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -289,9 +289,9 @@ static SRes WaitId(CSzData *sd, UInt32 id)
}
}
static SRes RememberBitVector(CSzData *sd, UInt32 numItems, const Byte **v)
static SRes RememberBitVector(CSzData *sd, size_t numItems, const Byte **v)
{
const UInt32 numBytes = (numItems + 7) >> 3;
const size_t numBytes = (numItems + 7) >> 3;
if (numBytes > sd->Size)
return SZ_ERROR_ARCHIVE;
*v = sd->Data;
@@ -317,11 +317,11 @@ static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems)
return sum;
}
static Z7_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAllocPtr alloc)
static Z7_NO_INLINE SRes ReadBitVector(CSzData *sd, size_t numItems, Byte **v, ISzAllocPtr alloc)
{
Byte allAreDefined;
Byte *v2;
const UInt32 numBytes = (numItems + 7) >> 3;
const size_t numBytes = (numItems + 7) >> 3;
*v = NULL;
SZ_READ_BYTE(allAreDefined)
if (numBytes == 0)
@@ -345,9 +345,9 @@ static Z7_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, I
return SZ_OK;
}
static Z7_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc)
static Z7_NO_INLINE SRes ReadUi32s(CSzData *sd2, size_t numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc)
{
UInt32 i;
size_t i;
CSzData sd;
UInt32 *vals;
const Byte *defs;
@@ -366,7 +366,7 @@ static Z7_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *c
return SZ_OK;
}
static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc)
static SRes ReadBitUi32s(CSzData *sd, size_t numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc)
{
SzBitUi32s_Free(crcs, alloc);
RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc))
@@ -1027,42 +1027,39 @@ static SRes SzReadAndDecodePackedStreams(
return SZ_OK;
}
// (size & 1) == 0
// (data) is aligned for 2-bytes
static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size_t *offsets)
{
size_t pos = 0;
const Byte *p, *lim;
*offsets++ = 0;
if (numFiles == 0)
return (size == 0) ? SZ_OK : SZ_ERROR_ARCHIVE;
if (size < 2)
return SZ_ERROR_ARCHIVE;
if (data[size - 2] != 0 || data[size - 1] != 0)
lim = data + size;
if (*(const UInt16 *)(const void *)(lim - 2))
return SZ_ERROR_ARCHIVE;
p = data;
do
{
const Byte *p;
if (pos == size)
if (p >= lim)
return SZ_ERROR_ARCHIVE;
for (p = data + pos;
#ifdef _WIN32
*(const UInt16 *)(const void *)p != 0
#else
p[0] != 0 || p[1] != 0
#endif
; p += 2);
pos = (size_t)(p - data) + 2;
*offsets++ = (pos >> 1);
for (; *(const UInt16 *)(const void *)p; p += 2);
p += 2;
*offsets++ = (size_t)(p - data) >> 1;
}
while (--numFiles);
return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;
return (p == lim) ? SZ_OK : SZ_ERROR_ARCHIVE;
}
static Z7_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
static Z7_NO_INLINE SRes ReadTime(CSzBitUi64s *p, size_t num,
CSzData *sd2,
const CBuf *tempBufs, UInt32 numTempBufs,
ISzAllocPtr alloc)
{
CSzData sd;
UInt32 i;
size_t i;
CNtfsFileTime *vals;
Byte *defs;
Byte external;
@@ -1215,6 +1212,7 @@ static SRes SzReadHeader2(
{
namesSize = (size_t)size - 1;
namesData = sd->Data;
SKIP_DATA(sd, namesSize)
}
else
{
@@ -1226,15 +1224,11 @@ static SRes SzReadHeader2(
namesSize = (tempBufs)[index].size;
}
if ((namesSize & 1) != 0)
if (namesSize & 1)
return SZ_ERROR_ARCHIVE;
MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain)
MY_ALLOC_ZE_AND_CPY(p->FileNames, namesSize, namesData, allocMain)
RINOK(SzReadFileNames(p->FileNames, namesSize, numFiles, p->FileNameOffsets))
if (external == 0)
{
SKIP_DATA(sd, namesSize)
}
break;
}
case k7zIdEmptyStream:
+1 -2
View File
@@ -1,12 +1,11 @@
/* 7zFile.h -- File IO
2023-03-05 : Igor Pavlov : Public domain */
: Igor Pavlov : Public domain */
#ifndef ZIP7_INC_FILE_H
#define ZIP7_INC_FILE_H
#ifdef _WIN32
#define USE_WINDOWS_FILE
// #include <windows.h>
#endif
#ifdef USE_WINDOWS_FILE
+4 -2
View File
@@ -1,5 +1,5 @@
/* 7zTypes.h -- Basic types
2024-01-24 : Igor Pavlov : Public domain */
: Igor Pavlov : Public domain */
#ifndef ZIP7_7Z_TYPES_H
#define ZIP7_7Z_TYPES_H
@@ -46,8 +46,9 @@ typedef int SRes;
#ifdef _MSC_VER
#define MY_ALIGN_IN_STRUCT(n) __declspec(align(n))
#if _MSC_VER > 1200
#define MY_ALIGN(n) __declspec(align(n))
#define MY_ALIGN(n) MY_ALIGN_IN_STRUCT(n)
#else
#define MY_ALIGN(n)
#endif
@@ -58,6 +59,7 @@ typedef int SRes;
#define MY_ALIGN(n) alignas(n)
*/
#define MY_ALIGN(n) __attribute__ ((aligned(n)))
#define MY_ALIGN_IN_STRUCT(n) MY_ALIGN(n)
#endif
+4 -4
View File
@@ -1,7 +1,7 @@
#define MY_VER_MAJOR 25
#define MY_VER_MAJOR 26
#define MY_VER_MINOR 1
#define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "25.01"
#define MY_VERSION_NUMBERS "26.01"
#define MY_VERSION MY_VERSION_NUMBERS
#ifdef MY_CPU_NAME
@@ -10,12 +10,12 @@
#define MY_VERSION_CPU MY_VERSION
#endif
#define MY_DATE "2025-08-03"
#define MY_DATE "2026-04-27"
#undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov"
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2025 Igor Pavlov"
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2026 Igor Pavlov"
#ifdef USE_COPYRIGHT_CR
#define MY_COPYRIGHT MY_COPYRIGHT_CR
+8 -2
View File
@@ -1,11 +1,17 @@
/* 7zWindows.h -- StdAfx
2023-04-02 : Igor Pavlov : Public domain */
/* 7zWindows.h -- Windows.h and related code
Igor Pavlov : Public domain */
#ifndef ZIP7_INC_7Z_WINDOWS_H
#define ZIP7_INC_7Z_WINDOWS_H
#ifdef _WIN32
#if defined(_MSC_VER) && _MSC_VER >= 1950 && !defined(__clang__) // VS2026
// <Windows.h> and some another windows files need that option
// VS2026: wtypesbase.h: warning C4865: 'tagCLSCTX': the underlying type will change from 'int' to 'unsigned int' when '/Zc:enumTypes' is specified on the command line
#pragma warning(disable : 4865)
#endif
#if defined(__clang__)
# pragma clang diagnostic push
#endif
+1 -1
View File
@@ -106,7 +106,7 @@ DEL_OBJ_EXE = -$(RM) $(O)\*.o $(O)\$(PROG).exe $(O)\$(PROG).dll
endif
LIB2 = -lOle32 -loleaut32 -luuid -ladvapi32 -lUser32 -lShell32
LIB2 = -lole32 -loleaut32 -luuid -ladvapi32 -luser32 -lshell32
CFLAGS_EXTRA = -DUNICODE -D_UNICODE
# -Wno-delete-non-virtual-dtor
+208 -39
View File
@@ -1,5 +1,5 @@
/* Alloc.c -- Memory allocation functions
2024-02-18 : Igor Pavlov : Public domain */
: Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -24,8 +24,6 @@
#endif
// #define SZ_ALLOC_DEBUG
/* #define SZ_ALLOC_DEBUG */
/* use SZ_ALLOC_DEBUG to debug alloc/free operations */
#ifdef SZ_ALLOC_DEBUG
@@ -34,9 +32,10 @@
static int g_allocCount = 0;
#ifdef _WIN32
static int g_allocCountMid = 0;
#ifdef Z7_LARGE_PAGES
static int g_allocCountBig = 0;
#endif
#endif
#define CONVERT_INT_TO_STR(charType, tempSize) \
char temp[tempSize]; unsigned i = 0; \
@@ -140,8 +139,10 @@ static void PrintAddr(void *p)
#else
#ifdef _WIN32
#ifdef Z7_LARGE_PAGES
#define PRINT_ALLOC(name, cnt, size, ptr)
#endif
#endif
#define PRINT_FREE(name, cnt, ptr)
#define Print(s)
#define PrintLn()
@@ -245,6 +246,7 @@ void MidFree(void *address)
}
#ifdef Z7_LARGE_PAGES
// #pragma message("Z7_LARGE_PAGES")
#ifdef MEM_LARGE_PAGES
#define MY_MEM_LARGE_PAGES MEM_LARGE_PAGES
@@ -253,32 +255,14 @@ void MidFree(void *address)
#endif
extern
SIZE_T g_LargePageSize;
SIZE_T g_LargePageSize = 0;
typedef SIZE_T (WINAPI *Func_GetLargePageMinimum)(VOID);
void SetLargePageSize(void)
{
SIZE_T size;
#ifdef Z7_USE_DYN_GetLargePageMinimum
Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
const
Func_GetLargePageMinimum fn =
(Func_GetLargePageMinimum) Z7_CAST_FUNC_C GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
"GetLargePageMinimum");
if (!fn)
return;
size = fn();
#else
size = GetLargePageMinimum();
#endif
if (size == 0 || (size & (size - 1)) != 0)
return;
g_LargePageSize = size;
}
#endif // Z7_LARGE_PAGES
size_t g_LargePageSize;
size_t g_LargePageSize = 0;
extern
size_t g_LargePageThresholdMin;
size_t g_LargePageThresholdMin = 0;
extern
UInt32 g_LargePageFlags;
UInt32 g_LargePageFlags = 0;
void *BigAlloc(size_t size)
{
@@ -289,12 +273,10 @@ void *BigAlloc(size_t size)
#ifdef Z7_LARGE_PAGES
{
SIZE_T ps = g_LargePageSize;
if (ps != 0 && ps <= (1 << 30) && size > (ps / 2))
const size_t ps = g_LargePageSize - 1;
if (ps < (1u << 30) && size > g_LargePageThresholdMin)
{
size_t size2;
ps--;
size2 = (size + ps) & ~ps;
const size_t size2 = (size + ps) & ~ps;
if (size2 >= size)
{
void *p = VirtualAlloc(NULL, size2, MEM_COMMIT | MY_MEM_LARGE_PAGES, PAGE_READWRITE);
@@ -303,6 +285,8 @@ void *BigAlloc(size_t size)
PRINT_ALLOC("Alloc-BM ", g_allocCountMid, size2, p)
return p;
}
if (g_LargePageFlags & Z7_LARGE_PAGES_FLAG_FAIL_STOP)
return p;
}
}
}
@@ -317,6 +301,7 @@ void BigFree(void *address)
MidFree(address);
}
#endif // Z7_LARGE_PAGES
#endif // _WIN32
@@ -327,9 +312,12 @@ const ISzAlloc g_Alloc = { SzAlloc, SzFree };
#ifdef _WIN32
static void *SzMidAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p) return MidAlloc(size); }
static void SzMidFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p) MidFree(address); }
const ISzAlloc g_MidAlloc = { SzMidAlloc, SzMidFree };
#endif
#if defined(Z7_LARGE_PAGES)
static void *SzBigAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p) return BigAlloc(size); }
static void SzBigFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p) BigFree(address); }
const ISzAlloc g_MidAlloc = { SzMidAlloc, SzMidFree };
const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
#endif
@@ -371,10 +359,16 @@ typedef
#endif
#if !defined(_WIN32) \
&& (defined(Z7_ALLOC_NO_OFFSET_ALLOCATOR) \
|| defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L))
#ifndef _WIN32
#include <unistd.h> // for _POSIX_ADVISORY_INFO : for some linux
#if (defined(Z7_ALLOC_NO_OFFSET_ALLOCATOR) \
|| defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) \
|| defined(_POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO >= 200112L) \
|| defined(__APPLE__) \
/* || defined(__linux__) */)
#define USE_posix_memalign
// #pragma message("USE_posix_memalign")
#endif
#endif
#ifndef USE_posix_memalign
@@ -488,6 +482,181 @@ static void SzAlignedFree(ISzAllocPtr pp, void *address)
#endif
}
#ifndef _WIN32
#ifdef Z7_LARGE_PAGES
#if 0 // 1 for debug
#include <stdio.h>
#include <string.h> // for strerror()
#define PRF(x) x
#else
#define PRF(x)
#endif
#ifdef USE_posix_memalign
/* madvise():
glibc <= 2.19 : _BSD_SOURCE
glibc > 2.19 : _DEFAULT_SOURCE
*/
/* && (defined(_DEFAULT_SOURCE) || defined(_BSD_SOURCE)) */
#if 1 && !defined(Z7_NO_MADVISE) && \
(defined(__linux__) || defined(__unix__) || defined(__APPLE__))
#include <sys/mman.h> // for madvise
// #pragma message("sys/mman.h")
#if (defined(MADV_HUGEPAGE) && defined(MADV_NOHUGEPAGE))
#define Z7_USE_BIG_ALLOC_MADVISE
// #pragma message("Z7_USE_BIG_ALLOC_MADVISE")
#endif
#endif
#endif // USE_posix_memalign
#ifdef Z7_USE_BIG_ALLOC_MADVISE
#define LARGE_PAGE_SIZE_DEFAULT (1 << 21)
#else
#define LARGE_PAGE_SIZE_DEFAULT 0
#endif
extern
size_t g_LargePageSize;
size_t g_LargePageSize = LARGE_PAGE_SIZE_DEFAULT;
extern
size_t g_LargePageThresholdMin;
size_t g_LargePageThresholdMin = LARGE_PAGE_SIZE_DEFAULT / 2;
extern
UInt32 g_LargePageFlags;
UInt32 g_LargePageFlags = 0;
void *BigAlloc(size_t size)
{
if (size == 0)
return NULL;
#ifdef USE_posix_memalign
{
const size_t pageSize = g_LargePageSize;
void *buf = NULL; // on Linux (and other systems), posix_memalign() does not modify memptr on failure (POSIX.1-2008 TC2).
PRF(printf("\nBigAlloc 0x%08x=%5uMB", (unsigned)(size), (unsigned)(size >> 20));)
if (pageSize && size > g_LargePageThresholdMin)
{
int res;
const size_t mask = pageSize - 1;
/* we can allocate aligned size, so data at the end of buffer also will use huge page
if (size2 for madvise() is not aligned for huge page size)
{ Last data block will use small pages. It reduces memory allocation,
but last data block with small pages can work slower.
It's useful, if we have very large HUGE_PAGE: 32MB or 512MB. }
*/
size_t size2 = (size + mask) & ~mask;
if (size2 < size || (size & mask) <= g_LargePageThresholdMin)
size2 = size;
res = posix_memalign(&buf, pageSize, size2);
PRF(printf(" posix_memalign size=0x%08x=%5uMB align=%u",
(unsigned)(size2), (unsigned)(size2 >> 20), (unsigned)pageSize);)
PRF(printf(" buf=%p", (void *)buf);)
if (res == 0)
{
#ifdef Z7_USE_BIG_ALLOC_MADVISE
if ((g_LargePageFlags & Z7_LARGE_PAGES_FLAG_NO_MADVISE) == 0)
{
// Advise the kernel to use huge pages for this memory range
// MADV_HUGEPAGE / MADV_NOHUGEPAGE : since Linux 2.6.38
// madvise() only operates on whole pages, therefore addr must be page-aligned (4KB/8KB/16KB/64KB).
// The value of size is rounded up to a multiple of page size.
PRF(printf(" madvise g_LargePageFlags=%x", (unsigned)g_LargePageFlags);)
res = madvise(buf, size2, (g_LargePageFlags & Z7_LARGE_PAGES_FLAG_NO_HUGEPAGE) ? MADV_NOHUGEPAGE : MADV_HUGEPAGE);
if (res)
{
PRF(printf("\nERROR res=%d, errno=%d=%s\n", res, (int)errno, strerror(errno));)
if (g_LargePageFlags & Z7_LARGE_PAGES_FLAG_FAIL_STOP)
{
free(buf);
return NULL;
}
}
}
#endif // Z7_USE_BIG_ALLOC_MADVISE
PRF(printf("\n");)
return buf;
}
PRF(printf("\nERROR res=%d=%s\n", res, strerror(res));)
if (g_LargePageFlags & Z7_LARGE_PAGES_FLAG_FAIL_STOP)
return NULL;
// (res == ENOMEM) "Out of memory" is possible, if pageSize is too big.
// so we do second attempt with smaller alignment
}
}
#endif // !USE_posix_memalign
PRF(printf(" z7_AlignedAlloc size=0x%08x=%5uMB\n", (unsigned)(size), (unsigned)(size >> 20));)
return z7_AlignedAlloc(size);
}
void BigFree(void *address)
{
z7_AlignedFree(address);
}
#endif // Z7_LARGE_PAGES
#endif // !_WIN32
#ifdef Z7_LARGE_PAGES
void z7_LargePage_Set(UInt32 flags, size_t pageSize, size_t threshold)
{
g_LargePageFlags = flags;
#ifdef _WIN32
if ((flags & Z7_LARGE_PAGES_FLAG_USE_HUGEPAGE) == 0)
{
g_LargePageSize = 0;
g_LargePageThresholdMin = 0;
}
else
{
if ((flags & Z7_LARGE_PAGES_FLAG_DIRECT_PAGE_SIZE) == 0)
{
#ifdef Z7_USE_DYN_GetLargePageMinimum
Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
typedef SIZE_T (WINAPI *Func_GetLargePageMinimum)(VOID);
const
Func_GetLargePageMinimum fn =
(Func_GetLargePageMinimum) Z7_CAST_FUNC_C GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
"GetLargePageMinimum");
if (fn)
pageSize = fn();
else
pageSize = 0;
#else
pageSize = GetLargePageMinimum();
#endif
if (pageSize & (pageSize - 1))
pageSize = 0;
}
g_LargePageSize = pageSize;
if ((flags & Z7_LARGE_PAGES_FLAG_DIRECT_THRESHOLD) == 0)
threshold = pageSize / 2;
g_LargePageThresholdMin = threshold;
}
#else // !_WIN32
if (flags & Z7_LARGE_PAGES_FLAG_NO_PAGECODE)
{
g_LargePageSize = 0;
g_LargePageThresholdMin = 0;
}
else
{
if ((flags & Z7_LARGE_PAGES_FLAG_DIRECT_PAGE_SIZE) == 0)
pageSize = LARGE_PAGE_SIZE_DEFAULT;
g_LargePageSize = pageSize;
if ((flags & Z7_LARGE_PAGES_FLAG_DIRECT_THRESHOLD) == 0)
threshold = pageSize / 2;
g_LargePageThresholdMin = threshold;
}
// PRF(printf("\ng_LargePageSize=%x g_LargePageThresholdMin = %x g_LargePageFlags = %x", (unsigned)g_LargePageSize, (unsigned)g_LargePageThresholdMin, (unsigned)g_LargePageFlags);)
#endif // !_WIN32
}
#endif // Z7_LARGE_PAGES
const ISzAlloc g_AlignedAlloc = { SzAlignedAlloc, SzAlignedFree };
+27 -27
View File
@@ -1,5 +1,5 @@
/* Alloc.h -- Memory allocation functions
2024-01-22 : Igor Pavlov : Public domain */
: Igor Pavlov : Public domain */
#ifndef ZIP7_INC_ALLOC_H
#define ZIP7_INC_ALLOC_H
@@ -25,40 +25,40 @@ void *MyRealloc(void *address, size_t size);
void *z7_AlignedAlloc(size_t size);
void z7_AlignedFree(void *p);
extern const ISzAlloc g_Alloc;
extern const ISzAlloc g_AlignedAlloc;
#ifdef _WIN32
void *MidAlloc(size_t size);
void MidFree(void *address);
extern const ISzAlloc g_MidAlloc;
#else
#define MidAlloc(size) z7_AlignedAlloc(size)
#define MidFree(address) z7_AlignedFree(address)
#define g_MidAlloc g_AlignedAlloc
#endif
#ifdef Z7_LARGE_PAGES
void SetLargePageSize(void);
#endif
void *MidAlloc(size_t size);
void MidFree(void *address);
void *BigAlloc(size_t size);
void BigFree(void *address);
/* #define Z7_BIG_ALLOC_IS_ZERO_FILLED */
#define Z7_LARGE_PAGES_FLAG_USE_HUGEPAGE (1 << 0) // PAGE_ALIGNED / MADV_HUGEPAGE
#define Z7_LARGE_PAGES_FLAG_NO_PAGECODE (1 << 1) // no PAGE_ALIGNED / no madvise
#define Z7_LARGE_PAGES_FLAG_NO_MADVISE (1 << 2) // PAGE_ALIGNED / no madvise : for THP=always
#define Z7_LARGE_PAGES_FLAG_NO_HUGEPAGE (1 << 3) // PAGE_ALIGNED / MADV_NOHUGEPAGE
#define Z7_LARGE_PAGES_FLAG_FAIL_STOP (1 << 15) // for benchmarks
#define Z7_LARGE_PAGES_FLAG_DIRECT_PAGE_SIZE (1 << 16)
#define Z7_LARGE_PAGES_FLAG_DIRECT_THRESHOLD (1 << 17)
void z7_LargePage_Set(UInt32 flags, size_t pageSize, size_t threshold);
void *BigAlloc(size_t size);
void BigFree(void *address);
extern const ISzAlloc g_BigAlloc;
#else
#define MidAlloc(size) z7_AlignedAlloc(size)
#define MidFree(address) z7_AlignedFree(address)
#define BigAlloc(size) z7_AlignedAlloc(size)
#define BigFree(address) z7_AlignedFree(address)
#define BigAlloc(size) MidAlloc(size)
#define BigFree(address) MidFree(address)
#define g_BigAlloc g_MidAlloc
#endif
extern const ISzAlloc g_Alloc;
#ifdef _WIN32
extern const ISzAlloc g_BigAlloc;
extern const ISzAlloc g_MidAlloc;
#else
#define g_BigAlloc g_AlignedAlloc
#define g_MidAlloc g_AlignedAlloc
#endif
extern const ISzAlloc g_AlignedAlloc;
typedef struct
{
+7 -1
View File
@@ -54,6 +54,12 @@
#pragma GCC diagnostic ignored "-Wexcess-padding"
#endif
#if defined(Z7_APPLE_CLANG_VERSION) && __clang_major__ >= 21
// warning: function MyAlloc might be an allocator wrapper
// clang in xcode: clang 21.0.0
#pragma GCC diagnostic ignored "-Wallocator-wrappers"
#endif
#if __clang_major__ >= 16
#pragma GCC diagnostic ignored "-Wunsafe-buffer-usage"
#endif
@@ -72,7 +78,7 @@
#endif // __clang__
#if defined(_WIN32) && defined(__clang__) && __clang_major__ >= 16
#if defined(__clang__) && __clang_major__ >= 16
// #pragma GCC diagnostic ignored "-Wcast-function-type-strict"
#define Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION \
_Pragma("GCC diagnostic ignored \"-Wcast-function-type-strict\"")
+2 -2
View File
@@ -859,7 +859,7 @@ BoolInt CPU_IsSupported_AES (void) { return APPLE_CRYPTO_SUPPORT_VAL; }
#if defined(__GLIBC__) && (__GLIBC__ * 100 + __GLIBC_MINOR__ >= 216)
#define Z7_GETAUXV_AVAILABLE
#else
#elif !defined(__QNXNTO__)
// #pragma message("=== is not NEW GLIBC === ")
#if defined __has_include
#if __has_include (<sys/auxv.h>)
@@ -877,7 +877,7 @@ BoolInt CPU_IsSupported_AES (void) { return APPLE_CRYPTO_SUPPORT_VAL; }
#ifdef USE_HWCAP
#if defined(__FreeBSD__)
#if defined(__FreeBSD__) || defined(__OpenBSD__)
static unsigned long MY_getauxval(int aux)
{
unsigned long val;
+20 -2
View File
@@ -31,7 +31,12 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#define MY_CPU_NAME "x32"
#define MY_CPU_SIZEOF_POINTER 4
#else
#define MY_CPU_NAME "x64"
#if defined(__APX_EGPR__) || defined(__EGPR__)
#define MY_CPU_NAME "x64-apx"
#define MY_CPU_AMD64_APX
#else
#define MY_CPU_NAME "x64"
#endif
#define MY_CPU_SIZEOF_POINTER 8
#endif
#define MY_CPU_64BIT
@@ -249,11 +254,12 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#endif
// _LITTLE_ENDIAN macro can be defined for big-endian platform with some compilers
#if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM_LE) \
|| defined(MY_CPU_ARM64_LE) \
|| defined(MY_CPU_IA64_LE) \
|| defined(_LITTLE_ENDIAN) \
|| defined(__LITTLE_ENDIAN__) \
|| defined(__ARMEL__) \
|| defined(__THUMBEL__) \
@@ -596,8 +602,20 @@ problem-4 : performace:
#define SetBe32a(p, v) { *(UInt32 *)(void *)(p) = (v); }
#define SetBe16a(p, v) { *(UInt16 *)(void *)(p) = (v); }
// gcc and clang for powerpc can transform load byte access to load reverse word access.
// sp we can use byte access instead of word access. Z7_BSWAP64 cab be slow
#if 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_64BIT)
#define GetUi64a(p) Z7_BSWAP64 (*(const UInt64 *)(const void *)(p))
#else
#define GetUi64a(p) GetUi64(p)
#endif
#if 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED)
#define GetUi32a(p) Z7_BSWAP32 (*(const UInt32 *)(const void *)(p))
#else
#define GetUi32a(p) GetUi32(p)
#endif
#define GetUi16a(p) GetUi16(p)
#define SetUi32a(p, v) SetUi32(p, v)
#define SetUi16a(p, v) SetUi16(p, v)
+2 -3
View File
@@ -2351,10 +2351,9 @@ static void LzmaEnc_Construct(CLzmaEnc *p)
CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc)
{
void *p;
p = ISzAlloc_Alloc(alloc, sizeof(CLzmaEnc));
CLzmaEncHandle p = (CLzmaEncHandle)ISzAlloc_Alloc(alloc, sizeof(CLzmaEnc));
if (p)
LzmaEnc_Construct((CLzmaEnc *)p);
LzmaEnc_Construct(p);
return p;
}
+7 -7
View File
@@ -1,5 +1,5 @@
/* Precomp.h -- precompilation file
2024-01-25 : Igor Pavlov : Public domain */
: Igor Pavlov : Public domain */
#ifndef ZIP7_INC_PRECOMP_H
#define ZIP7_INC_PRECOMP_H
@@ -40,18 +40,18 @@
#endif
*/
#ifndef Z7_LARGE_PAGES
#if !defined(Z7_NO_LARGE_PAGES) && !defined(UNDER_CE)
#define Z7_LARGE_PAGES 1
#endif
#endif
#ifdef _WIN32
/*
this "Precomp.h" file must be included before <windows.h>,
if we want to define _WIN32_WINNT before <windows.h>.
*/
#ifndef Z7_LARGE_PAGES
#ifndef Z7_NO_LARGE_PAGES
#define Z7_LARGE_PAGES 1
#endif
#endif
#ifndef Z7_LONG_PATH
#ifndef Z7_NO_LONG_PATH
#define Z7_LONG_PATH 1
+1 -1
View File
@@ -1,2 +1,2 @@
# LZMA SDK v25.01
# LZMA SDK v26.01
Downloaded from https://www.7-zip.org/sdk.html
+18 -4
View File
@@ -153,6 +153,17 @@ static void PrintProcess_Info()
#endif
#endif
/* if we send (stackSize=0) to CreateThread(), it will
use default value PE::SizeOfStackReserve from exe file.
PE::SizeOfStackReserve == 1 MiB in exe file with default linker options.
Windows aligns specified value to the next 64 KB range. */
static const unsigned k_StackSize_ReserveSize =
#ifdef UNDER_CE
1 << 17;
#else
1 << 20;
#endif
WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
{
/* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
@@ -160,12 +171,15 @@ WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
#ifdef USE_THREADS_CreateThread
DWORD threadId;
*p = CreateThread(NULL, 0, func, param, 0, &threadId);
*p = CreateThread(NULL, k_StackSize_ReserveSize, func, param, STACK_SIZE_PARAM_IS_A_RESERVATION, &threadId);
#else
#define CALL_beginthreadex(func2, param2, flags, threadIdPtr) \
((HANDLE)(_beginthreadex(NULL, k_StackSize_ReserveSize, func2, param2, (flags) | STACK_SIZE_PARAM_IS_A_RESERVATION, threadIdPtr)))
unsigned threadId;
*p = (HANDLE)(_beginthreadex(NULL, 0, func, param, 0, &threadId));
*p = CALL_beginthreadex(func, param, 0, &threadId);
#if 0 // 1 : for debug
{
@@ -223,7 +237,7 @@ WRes Thread_Create_With_Affinity(CThread *p, THREAD_FUNC_TYPE func, LPVOID param
HANDLE h;
WRes wres;
unsigned threadId;
h = (HANDLE)(_beginthreadex(NULL, 0, func, param, CREATE_SUSPENDED, &threadId));
h = CALL_beginthreadex(func, param, CREATE_SUSPENDED, &threadId);
*p = h;
wres = HandleToWRes(h);
if (h)
@@ -272,7 +286,7 @@ WRes Thread_Create_With_Group(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, u
HANDLE h;
WRes wres;
unsigned threadId;
h = (HANDLE)(_beginthreadex(NULL, 0, func, param, CREATE_SUSPENDED, &threadId));
h = CALL_beginthreadex(func, param, CREATE_SUSPENDED, &threadId);
*p = h;
wres = HandleToWRes(h);
if (h)
+345 -32
View File
@@ -1,15 +1,16 @@
/* 7zMain.c - Test application for 7z Decoder
2024-02-28 : Igor Pavlov : Public domain */
/* 7zMain.c - 7z archive decoding program
: Igor Pavlov : Public domain */
#include "Precomp.h"
#include <stdio.h>
#include <string.h>
#include "../../7zFile.h"
#ifndef USE_WINDOWS_FILE
/* for mkdir */
#ifdef _WIN32
#include <direct.h>
#include <direct.h> // for _mkdir()
#else
#include <stdlib.h>
#include <time.h>
@@ -23,7 +24,14 @@
#endif
#endif
#include "../../7zFile.h"
#ifdef _WIN32
// for _isatty()
#include "../../7zWindows.h"
#include <io.h>
#else
#include <unistd.h> // for isatty()
#endif
#include "../../7z.h"
#include "../../7zAlloc.h"
#include "../../7zBuf.h"
@@ -44,6 +52,25 @@ static void Print(const char *s)
}
static Z7_FORCE_INLINE BoolInt MY_IS_TERMINAL(FILE *x)
{
#ifdef _WIN32
const int fd = _fileno(x);
HANDLE h;
DWORD st;
if (fd < 0)
return False;
if (!_isatty(fd))
return False;
h = (HANDLE)(_get_osfhandle(fd));
if (h == NULL || h == INVALID_HANDLE_VALUE)
return False;
return GetConsoleMode(h, &st) != 0;
#else
return isatty(fileno(x)) != 0;
#endif
}
static int Buf_EnsureSize(CBuf *dest, size_t size)
{
if (dest->size >= size)
@@ -196,6 +223,206 @@ static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
#endif
}
#ifdef _WIN32
static Z7_FORCE_INLINE unsigned MyCharLower_Ascii(unsigned c)
{
if (c >= 'A' && c <= 'Z')
return (unsigned)(c + 0x20);
return c;
}
static Z7_FORCE_INLINE
BoolInt IsString1PrefixedByString2_NoCase_Ascii(const UInt16 *s1, const char *s2)
{
for (;;)
{
wchar_t c1;
const char c2 = *s2++; if (c2 == 0) return True;
c1 = *s1++;
if (c1 != (unsigned char)c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii((unsigned char)c2))
return False;
}
}
static const unsigned g_ReservedWithNum_Index = 4;
static const char * const g_ReservedNames[] =
{
"CON", "PRN", "AUX", "NUL",
"COM", "LPT"
};
static Z7_FORCE_INLINE
BoolInt IsReservedFsName(const UInt16 *name, size_t sLen)
{
unsigned i;
for (i = 0; i < Z7_ARRAY_SIZE(g_ReservedNames); i++)
{
const char *reservedName = g_ReservedNames[i];
size_t len = strlen(reservedName);
if (sLen < len)
continue;
if (!IsString1PrefixedByString2_NoCase_Ascii(name, reservedName))
continue;
if (i >= g_ReservedWithNum_Index)
{
if ((unsigned)((unsigned)name[len] - (unsigned)'0') > 9)
continue;
len++;
}
for (;;)
{
unsigned c;
if (len >= sLen)
return True;
c = name[len++];
if (c == 0 || c == '.')
return True;
if (c != ' ')
break;
}
}
return False;
}
static Z7_FORCE_INLINE
void Correct_FileName_for_FS(UInt16 *s, size_t size)
{
while (size)
{
const unsigned c = s[--size];
if (c != '.' && c != ' ')
break;
s[size] = '_';
}
}
#endif // _WIN32
// in: (s) uses WCHAR_PATH_SEPARATOR path separators
static Z7_FORCE_INLINE
void NormalizesPathParts_and_Dots(UInt16 *dest, const UInt16 *s, BoolInt isDir)
{
UInt16 * const destStart = dest;
size_t len;
// remove absolute path prefixes
for (; *s == WCHAR_PATH_SEPARATOR; s++)
{}
len = 0;
for (;;)
{
const unsigned c = s[len];
if (c != 0 && c != WCHAR_PATH_SEPARATOR)
{
len++;
continue;
}
{
if (len == 0
|| (len == 1 && s[len - 1] == '.')
|| (len == 2 && s[len - 1] == '.' && s[len - 2] == '.'))
{
if (c == 0)
{
if (!isDir)
{
*dest++ = '_';
// if (len == 2) *dest++ = '_'; // for ".." -> "__"
}
break;
}
}
else
{
#ifdef _WIN32
if (IsReservedFsName(s, len))
*dest++ = '_';
#endif
memcpy(dest, s, sizeof(s[0]) * len);
#ifdef _WIN32
Correct_FileName_for_FS(dest, len);
#endif
dest += len;
if (c == 0)
break;
*dest++ = WCHAR_PATH_SEPARATOR;
}
s += len + 1;
len = 0;
}
}
if (dest != destStart && dest[-1] == WCHAR_PATH_SEPARATOR)
{
if (isDir)
dest--;
else
*dest++ = '_';
}
if (dest == destStart)
*dest++ = '_';
*dest = 0;
}
#if WCHAR_PATH_SEPARATOR != L'/'
#ifdef _WIN32
// WSL scheme
#define WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT ((unsigned)((unsigned)(0xF000) + (unsigned)'\\'))
#else
#define WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT '_'
#endif
static Z7_FORCE_INLINE
void Normalize_Path_from_7z_to_FS(UInt16 *s)
{
// Normalize_Path_from_7z_to_FS(s);
for (;; s++)
{
unsigned c = *s;
if (c == 0)
break;
if (c == '/') // separator inside 7z archive
c = WCHAR_PATH_SEPARATOR;
else if (c == WCHAR_PATH_SEPARATOR)
c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT;
#ifdef _WIN32
else if (c < 0x20 || c == ':' || c == '*' || c == '?' || c == '<' || c == '>' || c == '|' || c == '"')
c = '_';
else
continue;
*s = (UInt16)c;
#endif
}
}
#endif
// this function changes both strings: (dest) and (s),
// but length of (s) string will not changed.
// dest[] must provide additional space: size(dest) >= len(len) * 2 + 2
// in: (s) uses slash path separators (/)
// out: (s) : temporary string
// out: (dest) uses WCHAR_PATH_SEPARATOR path separator
static Z7_FORCE_INLINE
void NormalizePath_for_FS(UInt16 *dest, UInt16 *s, BoolInt isDir)
{
#if WCHAR_PATH_SEPARATOR != L'/'
Normalize_Path_from_7z_to_FS(s);
#endif
NormalizesPathParts_and_Dots(dest, s , isDir);
}
#ifdef _WIN32
#ifndef USE_WINDOWS_FILE
static UINT g_FileCodePage = CP_ACP;
@@ -205,6 +432,38 @@ static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
#define MY_FILE_CODE_PAGE_PARAM
#endif
#ifdef USE_WINDOWS_FILE
static WRes My_DeleteFileAlways(const UInt16 *path)
{
const DWORD attrib = GetFileAttributesW(path);
if (// attrib != INVALID_FILE_ATTRIBUTES &&
(attrib & FILE_ATTRIBUTE_DIRECTORY) == 0 &&
(attrib & FILE_ATTRIBUTE_READONLY))
{
if (!SetFileAttributes(path, attrib & ~(DWORD)FILE_ATTRIBUTE_READONLY))
return GetLastError();
}
if (DeleteFileW(path))
return 0;
return GetLastError();
}
#else
static WRes My_DeleteFileAlways(const UInt16 *path)
{
CBuf buf;
WRes res;
Buf_Init(&buf);
RINOK_WRes(Utf16_To_Char(&buf, path MY_FILE_CODE_PAGE_PARAM))
res = remove((const char *)buf.data) == 0 ? 0 : errno;
Buf_Free(&buf, &g_Alloc);
return res;
}
#endif
static WRes MyCreateDir(const UInt16 *name)
{
#ifdef USE_WINDOWS_FILE
@@ -216,7 +475,7 @@ static WRes MyCreateDir(const UInt16 *name)
CBuf buf;
WRes res;
Buf_Init(&buf);
RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM))
RINOK_WRes(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM))
res =
#ifdef _WIN32
@@ -247,12 +506,51 @@ static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name)
}
static SRes PrintString(const UInt16 *s)
static Z7_FORCE_INLINE BoolInt IsDangerousTerminalChar(wchar_t c)
{
// if (c < 0) return False; // it's not expected case
if (c < 0x20) return True;
if (c < 0x7F) return False;
if (c < 0x9F + 1) return True;
// Unicode Bidirectional (BiDi) control characters:
if (c < 0x202A) return False;
if (c < 0x202E + 1) return True;
if (c < 0x2066) return False;
if (c < 0x2069 + 1) return True;
return False;
}
// (size(dest) >= len(src) + 3), if (isDir == True)
// s[] uses slash path separator (/)
static SRes PrintPath(const UInt16 *s, UInt16 *dest, BoolInt isDir, BoolInt isTerminalMode)
{
CBuf buf;
SRes res;
size_t i;
for (i = 0;; i++)
{
UInt16 c = s[i];
if (c == 0)
break;
if (isTerminalMode ? IsDangerousTerminalChar(c) :
(c == '\n'
#ifdef _WIN32
|| c == '\r'
#endif
))
c = '_';
dest[i] = c;
}
if (i == 0)
dest[i++] = '_';
if (isDir && dest[i - 1] != '/')
dest[i++] = '/';
dest[i] = 0;
Buf_Init(&buf);
res = Utf16_To_Char(&buf, s
res = Utf16_To_Char(&buf, dest
#ifndef MY_USE_UTF8
, CP_OEMCP
#endif
@@ -499,7 +797,7 @@ static void PrintError_WRes(const char *message, WRes wres)
Print(s);
}
// sprintf(buffer + strlen(buffer), "\nSystem error code: %d", (unsigned)wres);
#ifdef _WIN32
#ifdef USE_WINDOWS_FILE // _WIN32
{
char *s = NULL;
if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
@@ -540,8 +838,6 @@ static void GetAttribString(UInt32 wa, BoolInt isDir, char *s)
}
// #define NUM_PARENTS_MAX 128
int Z7_CDECL main(int numargs, char *args[])
{
ISzAlloc allocImp;
@@ -552,8 +848,9 @@ int Z7_CDECL main(int numargs, char *args[])
CSzArEx db;
SRes res;
UInt16 *temp = NULL;
UInt16 *temp2 = NULL;
size_t tempSize = 0;
// UInt32 parents[NUM_PARENTS_MAX];
const BoolInt isTerminalMode = MY_IS_TERMINAL(stdout);
Print("\n7z Decoder " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n");
@@ -669,12 +966,15 @@ int Z7_CDECL main(int numargs, char *args[])
{
SzFree(NULL, temp);
tempSize = len;
temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0]));
// temp2 requires additional space for "_" additions for "COM1" and empty names,
// and up to 2 additional characters for PrintPath().
temp = (UInt16 *)SzAlloc(NULL, (tempSize * 3 + 16) * sizeof(temp[0]));
if (!temp)
{
res = SZ_ERROR_MEM;
break;
}
temp2 = temp + tempSize;
}
SzArEx_GetFileNameUtf16(&db, i, temp);
@@ -712,25 +1012,19 @@ int Z7_CDECL main(int numargs, char *args[])
Print(" ");
Print(s);
Print(" ");
res = PrintString(temp);
res = PrintPath(temp, temp2, isDir, isTerminalMode);
if (res != SZ_OK)
break;
if (isDir)
Print("/");
PrintLF();
continue;
}
Print(testCommand ?
"T ":
"- ");
res = PrintString(temp);
Print(testCommand ? "T ": "- ");
res = PrintPath(temp, temp2, isDir, isTerminalMode);
if (res != SZ_OK)
break;
if (isDir)
Print("/");
else
if (!isDir)
{
res = SzArEx_Extract(&db, &lookStream.vt, i,
&blockIndex, &outBuffer, &outBufferSize,
@@ -745,11 +1039,16 @@ int Z7_CDECL main(int numargs, char *args[])
CSzFile outFile;
size_t processedSize;
size_t j;
UInt16 *name = (UInt16 *)temp;
UInt16 *name = (UInt16 *)temp2;
const UInt16 *destPath = (const UInt16 *)name;
// memset(temp2, 0, (tempSize) * sizeof(temp[0])); // for debug
NormalizePath_for_FS(temp2, temp, isDir);
// PrintLF(); PrintPath(temp2, temp, isDir, isTerminalMode); // for debuf
for (j = 0; name[j] != 0; j++)
if (name[j] == '/')
if (name[j] == CHAR_PATH_SEPARATOR)
{
if (fullPaths)
{
@@ -769,12 +1068,26 @@ int Z7_CDECL main(int numargs, char *args[])
}
else
{
const WRes wres = OutFile_OpenUtf16(&outFile, destPath);
if (wres != 0)
{
PrintError_WRes("cannot open output file", wres);
res = SZ_ERROR_FAIL;
break;
// const WRes wres =
My_DeleteFileAlways(destPath);
/*
if (wres && wres != ERROR_FILE_NOT_FOUND)
{
PrintError_WRes("cannot delete output file", wres);
res = SZ_ERROR_FAIL;
break;
}
*/
}
{
const WRes wres = OutFile_OpenUtf16(&outFile, destPath);
if (wres)
{
PrintError_WRes("cannot open output file", wres);
res = SZ_ERROR_FAIL;
break;
}
}
}
@@ -846,7 +1159,7 @@ int Z7_CDECL main(int numargs, char *args[])
UInt32 attrib = db.Attribs.Vals[i];
/* p7zip stores posix attributes in high 16 bits and adds 0x8000 as marker.
We remove posix bits, if we detect posix mode field */
if ((attrib & 0xF0000000) != 0)
if (attrib & 0xF0000000)
attrib &= 0x7FFF;
SetFileAttributesW((LPCWSTR)destPath, attrib);
}
+3 -3
View File
@@ -279,7 +279,7 @@ SRes Xz_StateCoder_Bc_SetFromMethod_Func(IStateCoder *p, UInt64 id,
decoder = (CXzBcFilterState *)ISzAlloc_Alloc(alloc, sizeof(CXzBcFilterState));
if (!decoder)
return SZ_ERROR_MEM;
decoder->buf = ISzAlloc_Alloc(alloc, BRA_BUF_SIZE);
decoder->buf = (Byte *)ISzAlloc_Alloc(alloc, BRA_BUF_SIZE);
if (!decoder->buf)
{
ISzAlloc_Free(alloc, decoder);
@@ -1243,7 +1243,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
UInt32 digest32[XZ_CHECK_SIZE_MAX / 4];
p->state = XZ_STATE_BLOCK_HEADER;
p->pos = 0;
if (XzCheck_Final(&p->check, (void *)digest32) && memcmp(digest32, p->buf, checkSize) != 0)
if (XzCheck_Final(&p->check, (Byte *)(void *)digest32) && memcmp(digest32, p->buf, checkSize) != 0)
return SZ_ERROR_CRC;
if (p->decodeOnlyOneBlock)
{
@@ -1292,7 +1292,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
p->state = XZ_STATE_STREAM_INDEX_CRC;
p->indexSize += 4;
p->pos = 0;
Sha256_Final(&p->sha, (void *)digest32);
Sha256_Final(&p->sha, (Byte *)(void *)digest32);
if (memcmp(digest32, p->shaDigest32, SHA256_DIGEST_SIZE) != 0)
return SZ_ERROR_CRC;
}
+1 -1
View File
@@ -313,7 +313,7 @@ LDLIBS += $(ZLIB_LDLIBS)
ifeq ($(origin MINIZIP_CFLAGS) $(origin MINIZIP_LDLIBS), undefined undefined)
ifeq ($(shell $(PKG_CONFIG) --modversion minizip 2>/dev/null),)
CFLAGS += -DNOCRYPT -DNOUNCRYPT -I$(SUBDIR)/minizip
CFLAGS += -DNOCRYPT -DNOUNCRYPT -I$(SUBDIR)
MINIZIP_SOURCE = \
$(SUBDIR)/minizip/ioapi.c \
$(SUBDIR)/minizip/zip.c \
+18 -18
View File
@@ -372,22 +372,22 @@ static const struct r4300_idec r4300_op_table[] = {
/* TLB opcodes table
* 176-239
*/
RESERVED, TLBR, TLBWI, RESERVED,
RESERVED, RESERVED, TLBWR, RESERVED,
TLBP, RESERVED, RESERVED, RESERVED,
RESERVED, RESERVED, RESERVED, RESERVED,
RESERVED, RESERVED, RESERVED, RESERVED,
RESERVED, RESERVED, RESERVED, RESERVED,
ERET, RESERVED, RESERVED, RESERVED,
RESERVED, RESERVED, RESERVED, RESERVED,
RESERVED, RESERVED, RESERVED, RESERVED,
RESERVED, RESERVED, RESERVED, RESERVED,
RESERVED, RESERVED, RESERVED, RESERVED,
RESERVED, RESERVED, RESERVED, RESERVED,
RESERVED, RESERVED, RESERVED, RESERVED,
RESERVED, RESERVED, RESERVED, RESERVED,
RESERVED, RESERVED, RESERVED, RESERVED,
RESERVED, RESERVED, RESERVED, RESERVED,
NOP, TLBR, TLBWI, NOP,
NOP, NOP, TLBWR, NOP,
TLBP, NOP, NOP, NOP,
NOP, NOP, NOP, NOP,
NOP, NOP, NOP, NOP,
NOP, NOP, NOP, NOP,
ERET, NOP, NOP, NOP,
NOP, NOP, NOP, NOP,
NOP, NOP, NOP, NOP,
NOP, NOP, NOP, NOP,
NOP, NOP, NOP, NOP,
NOP, NOP, NOP, NOP,
NOP, NOP, NOP, NOP,
NOP, NOP, NOP, NOP,
NOP, NOP, NOP, NOP,
NOP, NOP, NOP, NOP,
/* COP1 opcodes table
* 240-247
*/
@@ -430,7 +430,7 @@ static const struct r4300_idec r4300_op_table[] = {
/* Pseudo opcodes
* 336
*/
NOP
NOP
};
#define E_INV { 0, 0, 0x00 }
@@ -459,7 +459,7 @@ struct r4300_op_escape {
static const struct r4300_op_escape r4300_escapes_table[] = {
/* 000000 - special */
E_SPECIAL, E_SPECIAL, E_SPECIAL, E_SPECIAL,
E_SPECIAL, E_SPECIAL, E_SPECIAL, E_SPECIAL,
/* 000001 - regimm */
E_REGIMM, E_REGIMM, E_REGIMM, E_REGIMM,
@@ -1089,16 +1089,17 @@ DECLARE_INSTRUCTION(TLBR)
DECLARE_R4300
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
int index;
index = cp0_regs[CP0_INDEX_REG] & UINT32_C(0x1F);
cp0_regs[CP0_PAGEMASK_REG] = r4300->cp0.tlb.entries[index].mask << 13;
cp0_regs[CP0_ENTRYHI_REG] = ((r4300->cp0.tlb.entries[index].vpn2 << 13) | r4300->cp0.tlb.entries[index].asid);
cp0_regs[CP0_ENTRYLO0_REG] = (r4300->cp0.tlb.entries[index].pfn_even << 6) | (r4300->cp0.tlb.entries[index].c_even << 3)
| (r4300->cp0.tlb.entries[index].d_even << 2) | (r4300->cp0.tlb.entries[index].v_even << 1)
| r4300->cp0.tlb.entries[index].g;
cp0_regs[CP0_ENTRYLO1_REG] = (r4300->cp0.tlb.entries[index].pfn_odd << 6) | (r4300->cp0.tlb.entries[index].c_odd << 3)
| (r4300->cp0.tlb.entries[index].d_odd << 2) | (r4300->cp0.tlb.entries[index].v_odd << 1)
| r4300->cp0.tlb.entries[index].g;
int index = cp0_regs[CP0_INDEX_REG] & UINT32_C(0x3F);
if (index < CP0_REGS_COUNT) {
cp0_regs[CP0_PAGEMASK_REG] = r4300->cp0.tlb.entries[index].mask << 13;
cp0_regs[CP0_ENTRYHI_REG] = ((r4300->cp0.tlb.entries[index].vpn2 << 13) | r4300->cp0.tlb.entries[index].asid);
cp0_regs[CP0_ENTRYLO0_REG] = (r4300->cp0.tlb.entries[index].pfn_even << 6) | (r4300->cp0.tlb.entries[index].c_even << 3)
| (r4300->cp0.tlb.entries[index].d_even << 2) | (r4300->cp0.tlb.entries[index].v_even << 1)
| r4300->cp0.tlb.entries[index].g;
cp0_regs[CP0_ENTRYLO1_REG] = (r4300->cp0.tlb.entries[index].pfn_odd << 6) | (r4300->cp0.tlb.entries[index].c_odd << 3)
| (r4300->cp0.tlb.entries[index].d_odd << 2) | (r4300->cp0.tlb.entries[index].v_odd << 1)
| r4300->cp0.tlb.entries[index].g;
}
ADD_TO_PC(1);
}
@@ -1220,8 +1221,12 @@ DECLARE_INSTRUCTION(TLBWR)
DECLARE_R4300
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_update_count(r4300);
cp0_regs[CP0_RANDOM_REG] = (cp0_regs[CP0_COUNT_REG]/r4300->cp0.count_per_op % (32 - cp0_regs[CP0_WIRED_REG]))
if (cp0_regs[CP0_WIRED_REG] >= 32) {
cp0_regs[CP0_RANDOM_REG] = cp0_regs[CP0_COUNT_REG]/r4300->cp0.count_per_op % 64;
} else {
cp0_regs[CP0_RANDOM_REG] = (cp0_regs[CP0_COUNT_REG]/r4300->cp0.count_per_op % (32 - cp0_regs[CP0_WIRED_REG]))
+ cp0_regs[CP0_WIRED_REG];
}
TLBWrite(r4300, cp0_regs[CP0_RANDOM_REG]);
ADD_TO_PC(1);
}
@@ -1231,7 +1236,9 @@ DECLARE_INSTRUCTION(TLBWI)
DECLARE_R4300
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
TLBWrite(r4300, cp0_regs[CP0_INDEX_REG] & UINT32_C(0x3F));
int index = cp0_regs[CP0_INDEX_REG] & UINT32_C(0x3F);
if (index < CP0_REGS_COUNT)
TLBWrite(r4300, index);
ADD_TO_PC(1);
}
@@ -1247,8 +1254,12 @@ DECLARE_INSTRUCTION(MFC0)
{
case CP0_RANDOM_REG:
cp0_update_count(r4300);
cp0_regs[CP0_RANDOM_REG] = (cp0_regs[CP0_COUNT_REG]/r4300->cp0.count_per_op % (32 - cp0_regs[CP0_WIRED_REG]))
+ cp0_regs[CP0_WIRED_REG];
if (cp0_regs[CP0_WIRED_REG] >= 32) {
cp0_regs[CP0_RANDOM_REG] = cp0_regs[CP0_COUNT_REG]/r4300->cp0.count_per_op % 64;
} else {
cp0_regs[CP0_RANDOM_REG] = (cp0_regs[CP0_COUNT_REG]/r4300->cp0.count_per_op % (32 - cp0_regs[CP0_WIRED_REG]))
+ cp0_regs[CP0_WIRED_REG];
}
rrt = SE32(cp0_regs[rfs]);
break;
case CP0_COUNT_REG:
@@ -1282,8 +1293,12 @@ DECLARE_INSTRUCTION(DMFC0)
{
case CP0_RANDOM_REG:
cp0_update_count(r4300);
cp0_regs[CP0_RANDOM_REG] = (cp0_regs[CP0_COUNT_REG]/r4300->cp0.count_per_op % (32 - cp0_regs[CP0_WIRED_REG]))
+ cp0_regs[CP0_WIRED_REG];
if (cp0_regs[CP0_WIRED_REG] >= 32) {
cp0_regs[CP0_RANDOM_REG] = cp0_regs[CP0_COUNT_REG]/r4300->cp0.count_per_op % 64;
} else {
cp0_regs[CP0_RANDOM_REG] = (cp0_regs[CP0_COUNT_REG]/r4300->cp0.count_per_op % (32 - cp0_regs[CP0_WIRED_REG]))
+ cp0_regs[CP0_WIRED_REG];
}
rrt = cp0_regs[rfs];
break;
case CP0_COUNT_REG:
@@ -1323,11 +1338,6 @@ DECLARE_INSTRUCTION(MTC0)
{
case CP0_INDEX_REG:
cp0_regs[CP0_INDEX_REG] = rrt32 & UINT32_C(0x8000003F);
if ((cp0_regs[CP0_INDEX_REG] & UINT32_C(0x3F)) > UINT32_C(31))
{
DebugMessage(M64MSG_ERROR, "MTC0 instruction writing Index register with TLB index > 31");
*r4300_stop(r4300)=1;
}
break;
case CP0_RANDOM_REG:
break;
@@ -1399,7 +1409,7 @@ DECLARE_INSTRUCTION(MTC0)
case CP0_PREVID_REG:
break;
case CP0_CONFIG_REG:
cp0_regs[CP0_CONFIG_REG] = (rrt32 & UINT32_C(0x0000000F))
cp0_regs[CP0_CONFIG_REG] = (rrt32 & UINT32_C(0x0000000F))
| (cp0_regs[CP0_CONFIG_REG] & UINT32_C(0x00008000))
| (cp0_regs[CP0_CONFIG_REG] & UINT32_C(0x7FFFFFFF));
break;
@@ -446,23 +446,32 @@ void InterpretOpcode(struct r4300_core* r4300)
case 5: /* Coprocessor 0 opcode 5: DMTC0 */
MTC0(r4300, op);
break;
case 16: /* Coprocessor 0 opcode 16: TLB */
case 2:
case 3:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15: /* Coprocessor 0 opcodes 2..3, 6..15: Reserved Instructions */
RESERVED(r4300, op);
break;
default: /* Coprocessor 0 opcode 16..31: TLB */
switch (op & 0x3F) {
case 1: TLBR(r4300, op); break;
case 2: TLBWI(r4300, op); break;
case 6: TLBWR(r4300, op); break;
case 8: TLBP(r4300, op); break;
case 24: ERET(r4300, op); break;
default: /* TLB sub-opcodes 0, 3..5, 7, 9..23, 25..63:
Reserved Instructions */
RESERVED(r4300, op);
default: /* TLB sub-opcodes 0, 3..5, 7, 9..23, 25..63: undefined */
NOP(r4300, 0);
break;
} /* switch (op & 0x3F) for Coprocessor 0 TLB opcodes */
break;
default: /* Coprocessor 0 opcodes 2..3, 5..15, 17..31:
Reserved Instructions */
RESERVED(r4300, op);
break;
} /* switch ((op >> 21) & 0x1F) for the Coprocessor 0 prefix */
break;
case 17: /* Coprocessor 1 prefix */
@@ -110,7 +110,7 @@ static void dma_pi_write(struct pi_controller* pi)
if (length >= 0x7f && (length & 1))
length += 1;
if (length <= 0x80)
length -= dram_addr & 0x7;
length = length >= (dram_addr & 0x7) ? length - (dram_addr & 0x7) : 0;
unsigned int cycles = handler->dma_write(opaque, dram, dram_addr, cart_addr, length);
post_framebuffer_write(&pi->dp->fb, dram_addr, length);
+2 -2
View File
@@ -36,8 +36,8 @@
#include <string.h>
#include <sys/types.h>
#include <zlib.h>
#include <unzip.h>
#include <zip.h>
#include <minizip/unzip.h>
#include <minizip/zip.h>
#define M64P_CORE_PROTOTYPES 1
#include "api/callbacks.h"
@@ -252,6 +252,11 @@ void DisplayWindowMupen64plus::_readScreen2(void * _dest, int * _width, int * _h
if (_dest == nullptr)
return;
u8 *pBufferData = (u8*)malloc((*_width)*(*_height) * 4);
if (pBufferData == nullptr)
return;
u8 *pDest = (u8*)_dest;
#if !defined(OS_ANDROID) && !defined(OS_IOS)
GLint oldMode;
glGetIntegerv(GL_READ_BUFFER, &oldMode);
@@ -260,7 +265,7 @@ void DisplayWindowMupen64plus::_readScreen2(void * _dest, int * _width, int * _h
glReadBuffer(GL_FRONT);
else
glReadBuffer(GL_BACK);
glReadPixels(0, m_heightOffset, m_screenWidth, m_screenHeight, GL_RGB, GL_UNSIGNED_BYTE, _dest);
glReadPixels(0, m_heightOffset, m_screenWidth, m_screenHeight, GL_RGBA, GL_UNSIGNED_BYTE, pBufferData);
if (graphics::BufferAttachmentParam(oldMode) == graphics::bufferAttachment::COLOR_ATTACHMENT0) {
FrameBuffer * pBuffer = frameBufferList().getCurrent();
if (pBuffer != nullptr)
@@ -268,11 +273,8 @@ void DisplayWindowMupen64plus::_readScreen2(void * _dest, int * _width, int * _h
}
glReadBuffer(oldMode);
#else
u8 *pBufferData = (u8*)malloc((*_width)*(*_height) * 4);
if (pBufferData == nullptr)
return;
u8 *pDest = (u8*)_dest;
glReadPixels(0, m_heightOffset, m_screenWidth, m_screenHeight, GL_RGBA, GL_UNSIGNED_BYTE, pBufferData);
#endif
//Convert RGBA to RGB
for (s32 y = 0; y < *_height; ++y) {
@@ -287,7 +289,6 @@ void DisplayWindowMupen64plus::_readScreen2(void * _dest, int * _width, int * _h
}
free(pBufferData);
#endif
}
graphics::ObjectHandle DisplayWindowMupen64plus::_getDefaultFramebuffer()
+1 -1
View File
@@ -88,7 +88,7 @@ static void sdl_init_audio_device(struct sdl_backend* sdl_backend)
{
if (!SDL_Init(SDL_INIT_AUDIO))
{
DebugMessage(M64MSG_ERROR, "Failed to initialize SDL audio subsystem.");
DebugMessage(M64MSG_ERROR, "Failed to initialize SDL audio subsystem: %s", SDL_GetError());
sdl_backend->error = 1;
return;
}
+1 -1
View File
@@ -28,7 +28,7 @@
#include <3rdParty/lzma/7z.h>
// minizip includes
#include <unzip.h>
#include <minizip/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,
-3
View File
@@ -170,9 +170,6 @@ static l_Setting get_setting(SettingsID settingId)
case SettingsID::Netplay_ServerJsonUrl:
setting = {SETTING_SECTION_NETPLAY, "ServerJsonUrl", std::string("")};
break;
case SettingsID::Netplay_DispatcherUrl:
setting = {SETTING_SECTION_NETPLAY, "DispatcherUrl", std::string("https://dispatch.gopher64.com")};
break;
case SettingsID::Netplay_SelectedServer:
setting = {SETTING_SECTION_NETPLAY, "SelectedServer", std::string("")};
break;
-1
View File
@@ -45,7 +45,6 @@ enum class SettingsID
// Netplay Settings
Netplay_Nickname,
Netplay_ServerJsonUrl,
Netplay_DispatcherUrl,
Netplay_SelectedServer,
// Core Plugin Settings
@@ -41,7 +41,6 @@ CreateNetplaySessionDialog::CreateNetplaySessionDialog(QWidget *parent, QWebSock
this->webSocket = webSocket;
connect(this->webSocket, &QWebSocket::textMessageReceived, this, &CreateNetplaySessionDialog::on_webSocket_textMessageReceived);
connect(this->webSocket, &QWebSocket::pong, this, &CreateNetplaySessionDialog::on_webSocket_pong);
connect(this->webSocket, &QWebSocket::connected, this, &CreateNetplaySessionDialog::on_webSocket_connected);
// prepare broadcast
broadcastSocket.bind(QHostAddress(QHostAddress::AnyIPv4), 0);
@@ -104,18 +103,6 @@ CreateNetplaySessionDialog::CreateNetplaySessionDialog(QWidget *parent, QWebSock
networkAccessManager->get(QNetworkRequest(QUrl(serverUrl)));
}
}
QString dispatcherUrl = QString::fromStdString(CoreSettingsGetStringValue(SettingsID::Netplay_DispatcherUrl));
if (!dispatcherUrl.isEmpty() && QUrl(dispatcherUrl).isValid())
{
this->dispatcherUrl = dispatcherUrl;
QNetworkAccessManager* networkAccessManager = new QNetworkAccessManager(this);
connect(networkAccessManager, &QNetworkAccessManager::finished, this, &CreateNetplaySessionDialog::on_dispatcherRegionListDownload_Finished);
networkAccessManager->setTransferTimeout(15000);
networkAccessManager->get(NetplayCommon::GetNetworkRequest(this->dispatcherUrl + "/getRegions"));
}
}
CreateNetplaySessionDialog::~CreateNetplaySessionDialog(void)
@@ -254,18 +241,7 @@ void CreateNetplaySessionDialog::on_webSocket_textMessageReceived(QString messag
void CreateNetplaySessionDialog::on_webSocket_pong(quint64 elapsedTime, const QByteArray&)
{
if (!NetplayCommon::IsServerDispatcher(this->serverComboBox))
{
this->pingLineEdit->setText(QString::number(elapsedTime) + " ms");
}
}
void CreateNetplaySessionDialog::on_webSocket_connected()
{
if (NetplayCommon::IsServerDispatcher(this->serverComboBox))
{
this->createSession();
}
this->pingLineEdit->setText(QString::number(elapsedTime) + " ms");
}
void CreateNetplaySessionDialog::on_broadcastSocket_readyRead()
@@ -296,49 +272,6 @@ void CreateNetplaySessionDialog::on_jsonServerListDownload_Finished(QNetworkRepl
reply->deleteLater();
}
void CreateNetplaySessionDialog::on_dispatcherRegionListDownload_Finished(QNetworkReply* reply)
{
if (reply->error())
{
QtMessageBox::Error(this, "Server Error", "Failed to retrieve region list: " + reply->errorString());
reply->deleteLater();
return;
}
NetplayCommon::AddServers(this->serverComboBox,
QJsonDocument::fromJson(reply->readAll()), true);
reply->deleteLater();
}
void CreateNetplaySessionDialog::on_dispatcherServerCreate_Finished(QNetworkReply* reply)
{
if (reply->error())
{
QtMessageBox::Error(this, "Server Error", "Failed to create server: " + reply->errorString());
reply->deleteLater();
this->toggleUI(true, this->validate());
return;
}
QJsonDocument jsonDocument = QJsonDocument::fromJson(reply->readAll());
QJsonObject jsonObject = jsonDocument.object();
if (jsonObject.empty() || jsonObject.keys().empty())
{
QtMessageBox::Error(this, "Server Error", "Failed to create server: " + jsonDocument.toJson());
reply->deleteLater();
this->toggleUI(true, this->validate());
return;
}
// first item should be an address
QString address = jsonObject[jsonObject.keys().at(0)].toString();
this->webSocket->open(QUrl(address));
reply->deleteLater();
}
void CreateNetplaySessionDialog::on_serverComboBox_currentIndexChanged(int index)
{
if (index == -1)
@@ -346,23 +279,18 @@ void CreateNetplaySessionDialog::on_serverComboBox_currentIndexChanged(int index
return;
}
bool dispatcher = NetplayCommon::IsServerDispatcher(this->serverComboBox, index);
if (this->pingTimerId != -1)
{
this->killTimer(this->pingTimerId);
this->pingTimerId = -1;
}
this->pingLineEdit->setText(dispatcher ? "N/A" : "Calculating...");
this->pingLineEdit->setText("Calculating...");
if (!dispatcher)
{
this->pingTimerId = this->startTimer(2000);
this->pingTimerId = this->startTimer(2000);
QString address = NetplayCommon::GetServerData(this->serverComboBox, index);
this->webSocket->open(QUrl(address));
}
QString address = NetplayCommon::GetServerData(this->serverComboBox, index);
this->webSocket->open(QUrl(address));
}
void CreateNetplaySessionDialog::on_nickNameLineEdit_textChanged(void)
@@ -387,7 +315,7 @@ void CreateNetplaySessionDialog::on_romListWidget_OnRomChanged(bool valid)
void CreateNetplaySessionDialog::accept()
{
if (!NetplayCommon::IsServerDispatcher(this->serverComboBox) && !this->webSocket->isValid())
if (!this->webSocket->isValid())
{
QtMessageBox::Error(this, "Server Error", "Connection Failed");
return;
@@ -407,26 +335,5 @@ void CreateNetplaySessionDialog::accept()
// disable create button while we're processing the request
this->toggleUI(false, false);
if (NetplayCommon::IsServerDispatcher(this->serverComboBox))
{
QNetworkAccessManager* networkAccessManager = new QNetworkAccessManager(this);
connect(networkAccessManager, &QNetworkAccessManager::finished, this, &CreateNetplaySessionDialog::on_dispatcherServerCreate_Finished);
networkAccessManager->setTransferTimeout(120000);
QUrl url(this->dispatcherUrl + "/createServer");
QUrlQuery urlQuery;
urlQuery.addQueryItem("region", NetplayCommon::GetServerData(this->serverComboBox));
url.setQuery(urlQuery);
networkAccessManager->get(NetplayCommon::GetNetworkRequest(url));
// creating a server can take a while,
// so show a loading screen
this->romListWidget->ShowLoading();
}
else
{
this->createSession();
}
this->createSession();
}
@@ -48,8 +48,6 @@ class CreateNetplaySessionDialog : public QDialog, private Ui::CreateNetplaySess
QString sessionMD5;
QString sessionGoodName;
QString dispatcherUrl;
QString getGameName(QString goodName, QString file);
bool validate(void);
@@ -65,12 +63,9 @@ class CreateNetplaySessionDialog : public QDialog, private Ui::CreateNetplaySess
private slots:
void on_webSocket_textMessageReceived(QString message);
void on_webSocket_pong(quint64 elapsedTime, const QByteArray&);
void on_webSocket_connected(void);
void on_broadcastSocket_readyRead(void);
void on_jsonServerListDownload_Finished(QNetworkReply* reply);
void on_dispatcherRegionListDownload_Finished(QNetworkReply* reply);
void on_dispatcherServerCreate_Finished(QNetworkReply* reply);
void on_serverComboBox_currentIndexChanged(int index);
@@ -23,9 +23,6 @@
using namespace NetplayCommon;
// register type with qt
Q_DECLARE_METATYPE(NetplayServerData);
void NetplayCommon::AddCommonJson(QJsonObject& json)
{
QCryptographicHash hash = QCryptographicHash(QCryptographicHash::Sha256);
@@ -87,36 +84,14 @@ QList<QString> NetplayCommon::GetPluginNames(QString md5QString)
return pluginNames;
}
void NetplayCommon::AddServers(QComboBox* comboBox, const QJsonDocument& document, bool dispatcher)
void NetplayCommon::AddServers(QComboBox* comboBox, const QJsonDocument& document)
{
if (dispatcher)
{
QJsonArray jsonServers = document.array();
QJsonObject jsonObject = document.object();
QStringList jsonServers = jsonObject.keys();
for (int i = 0; i < jsonServers.size(); i++)
{
comboBox->addItem(jsonServers.at(i).toString(),
QVariant::fromValue<NetplayServerData>(
{
dispatcher,
jsonServers.at(i).toString()
}));
}
}
else
for (int i = 0; i < jsonServers.size(); i++)
{
QJsonObject jsonObject = document.object();
QStringList jsonServers = jsonObject.keys();
for (int i = 0; i < jsonServers.size(); i++)
{
comboBox->addItem(jsonServers.at(i),
QVariant::fromValue<NetplayServerData>(
{
dispatcher,
jsonObject.value(jsonServers.at(i)).toString()
}));
}
comboBox->addItem(jsonServers.at(i), jsonObject.value(jsonServers.at(i)).toString());
}
NetplayCommon::RestoreSelectedServer(comboBox);
@@ -137,16 +112,6 @@ void NetplayCommon::RestoreSelectedServer(QComboBox* comboBox)
}
}
bool NetplayCommon::IsServerDispatcher(QComboBox* comboBox, int index)
{
if (index == -1)
{
index = comboBox->currentIndex();
}
return comboBox->itemData(index).value<NetplayServerData>().Dispatcher;
}
QString NetplayCommon::GetServerData(QComboBox* comboBox, int index)
{
if (index == -1)
@@ -154,7 +119,7 @@ QString NetplayCommon::GetServerData(QComboBox* comboBox, int index)
index = comboBox->currentIndex();
}
return comboBox->itemData(index).value<NetplayServerData>().Data;
return comboBox->itemData(index).toString();
}
QNetworkRequest NetplayCommon::GetNetworkRequest(QUrl url)
@@ -22,12 +22,6 @@
namespace NetplayCommon
{
struct NetplayServerData
{
bool Dispatcher;
QString Data;
};
#define NETPLAYCOMMON_SESSION_REGEX "[a-zA-Z0-9 ]+"
#define NETPLAYCOMMON_NICKNAME_REGEX "[a-zA-Z0-9]+"
#define NETPLAYCOMMON_PASSWORD_REGEX "[a-zA-Z0-9,.\\/<>?;:[\\]{}\\-=_+`~!@#$%^&*()]+"
@@ -39,14 +33,11 @@ namespace NetplayCommon
QList<QString> GetPluginNames(QString md5QString);
// Adds servers from json to combobox
void AddServers(QComboBox* comboBox, const QJsonDocument& document, bool dispatcher = false);
void AddServers(QComboBox* comboBox, const QJsonDocument& document);
// Restores previously selected server
void RestoreSelectedServer(QComboBox* comboBox);
// Returns whether server from comboBox is dispatcher
bool IsServerDispatcher(QComboBox* comboBox, int index = -1);
// Returns server data from comboBox
QString GetServerData(QComboBox* comboBox, int index = -1);
@@ -71,11 +71,6 @@ NetplaySessionBrowserDialog::NetplaySessionBrowserDialog(QWidget *parent, QWebSo
this->nickNameLineEdit->setValidator(new QRegularExpressionValidator(re, this));
this->nickNameLineEdit->setText(QString::fromStdString(CoreSettingsGetStringValue(SettingsID::Netplay_Nickname)));
// configure dispatcher network access manager
this->dispatcherNetworkAccessManager = new QNetworkAccessManager(this);
this->dispatcherNetworkAccessManager->setTransferTimeout(15000);
connect(this->dispatcherNetworkAccessManager, &QNetworkAccessManager::finished, this, &NetplaySessionBrowserDialog::on_dispatcherRetrieveServers_Finished);
// request server list
QString serverUrl = QString::fromStdString(CoreSettingsGetStringValue(SettingsID::Netplay_ServerJsonUrl));
if (!serverUrl.isEmpty())
@@ -102,18 +97,6 @@ NetplaySessionBrowserDialog::NetplaySessionBrowserDialog(QWidget *parent, QWebSo
}
}
QString dispatcherUrl = QString::fromStdString(CoreSettingsGetStringValue(SettingsID::Netplay_DispatcherUrl));
if (!dispatcherUrl.isEmpty() && QUrl(dispatcherUrl).isValid())
{
this->dispatcherUrl = dispatcherUrl;
QNetworkAccessManager* networkAccessManager = new QNetworkAccessManager(this);
connect(networkAccessManager, &QNetworkAccessManager::finished, this, &NetplaySessionBrowserDialog::on_dispatcherRegionListDownload_Finished);
networkAccessManager->setTransferTimeout(15000);
networkAccessManager->get(NetplayCommon::GetNetworkRequest(this->dispatcherUrl + "/getRegions"));
}
this->validateJoinButton();
}
@@ -215,14 +198,7 @@ void NetplaySessionBrowserDialog::refreshSessions(void)
// disable join and refresh button while refreshing
this->toggleUI(false, false, false);
if (NetplayCommon::IsServerDispatcher(this->serverComboBox))
{
this->on_serverComboBox_currentIndexChanged(this->serverComboBox->currentIndex());
}
else
{
this->on_webSocket_connected();
}
this->on_webSocket_connected();
}
void NetplaySessionBrowserDialog::joinSession(void)
@@ -241,31 +217,6 @@ void NetplaySessionBrowserDialog::joinSession(void)
this->webSocket->sendTextMessage(QJsonDocument(json).toJson());
}
void NetplaySessionBrowserDialog::resetDispatcherState(void)
{
if (this->dispatcherTimerId != -1)
{
this->killTimer(this->dispatcherTimerId);
this->dispatcherTimerId = -1;
}
if (this->dispatcherTimeoutTimerId != -1)
{
this->killTimer(this->dispatcherTimeoutTimerId);
this->dispatcherTimeoutTimerId = -1;
}
if (this->dispatcherNetworkReply != nullptr)
{
this->dispatcherNetworkReply->abort();
this->dispatcherNetworkReply = nullptr;
}
this->dispatcherMoveThroughList = false;
this->dispatcherJoinSession = false;
this->dispatcherAddressListIndex = false;
}
void NetplaySessionBrowserDialog::timerEvent(QTimerEvent *event)
{
if (event->timerId() == this->pingTimerId)
@@ -275,44 +226,6 @@ void NetplaySessionBrowserDialog::timerEvent(QTimerEvent *event)
this->webSocket->ping();
}
}
else if (event->timerId() == this->dispatcherTimerId)
{
if (this->dispatcherMoveThroughList)
{
this->dispatcherAddressListIndex++;
if (this->dispatcherAddressListIndex < this->dispatcherAddressList.size())
{
QString address = this->dispatcherAddressList.at(this->dispatcherAddressListIndex);
this->webSocket->open(QUrl(address));
this->dispatcherMoveThroughList = false;
// start socket timeout
if (this->dispatcherTimeoutTimerId != -1)
{
this->killTimer(this->dispatcherTimeoutTimerId);
this->dispatcherTimeoutTimerId = -1;
}
this->dispatcherTimeoutTimerId = this->startTimer(15000);
}
else
{
this->sessionBrowserWidget->RefreshDone();
this->resetDispatcherState();
}
}
}
else if (event->timerId() == this->dispatcherTimeoutTimerId)
{
this->webSocket->close();
this->dispatcherMoveThroughList = true;
this->killTimer(this->dispatcherTimeoutTimerId);
this->dispatcherTimeoutTimerId = -1;
}
}
void NetplaySessionBrowserDialog::on_webSocket_connected(void)
@@ -323,20 +236,8 @@ void NetplaySessionBrowserDialog::on_webSocket_connected(void)
return;
}
bool dispatcher = NetplayCommon::IsServerDispatcher(this->serverComboBox);
if (dispatcher && this->dispatcherJoinSession)
{
this->joinSession();
this->dispatcherJoinSession = false;
return;
}
// clear sessions when we're not using the dispatcher server
if (!dispatcher)
{
this->sessionBrowserWidget->StartRefresh();
}
// clear sessions
this->sessionBrowserWidget->StartRefresh();
// request session list from server
QJsonObject json;
@@ -353,8 +254,6 @@ void NetplaySessionBrowserDialog::on_webSocket_textMessageReceived(QString messa
QString type = json.value("type").toString();
bool dispatcher = NetplayCommon::IsServerDispatcher(this->serverComboBox);
if (type == "reply_get_rooms")
{
if (json.value("accept").toInt() == 0)
@@ -377,10 +276,7 @@ void NetplaySessionBrowserDialog::on_webSocket_textMessageReceived(QString messa
}
// we're done refreshing the sessions
if (!dispatcher)
{
this->sessionBrowserWidget->RefreshDone();
}
this->sessionBrowserWidget->RefreshDone();
}
else
{
@@ -401,27 +297,16 @@ void NetplaySessionBrowserDialog::on_webSocket_textMessageReceived(QString messa
this->toggleUI(true, this->validate());
}
}
if (dispatcher)
{
this->dispatcherMoveThroughList = true;
}
}
void NetplaySessionBrowserDialog::on_webSocket_pong(quint64 elapsedTime, const QByteArray&)
{
if (!NetplayCommon::IsServerDispatcher(this->serverComboBox))
{
this->pingLineEdit->setText(QString::number(elapsedTime) + " ms");
}
this->pingLineEdit->setText(QString::number(elapsedTime) + " ms");
}
void NetplaySessionBrowserDialog::on_webSocket_disconnected()
{
if (!NetplayCommon::IsServerDispatcher(this->serverComboBox))
{
this->sessionBrowserWidget->Reset();
}
this->sessionBrowserWidget->Reset();
}
void NetplaySessionBrowserDialog::on_broadcastSocket_readyRead(void)
@@ -453,61 +338,6 @@ void NetplaySessionBrowserDialog::on_jsonServerListDownload_Finished(QNetworkRep
reply->deleteLater();
}
void NetplaySessionBrowserDialog::on_dispatcherRegionListDownload_Finished(QNetworkReply* reply)
{
if (reply->error())
{
this->sessionBrowserWidget->Reset();
QtMessageBox::Error(this, "Server Error", "Failed to retrieve region list: " + reply->errorString());
reply->deleteLater();
return;
}
NetplayCommon::AddServers(this->serverComboBox,
QJsonDocument::fromJson(reply->readAll()), true);
reply->deleteLater();
}
void NetplaySessionBrowserDialog::on_dispatcherRetrieveServers_Finished(QNetworkReply* reply)
{
// don't show an error when the request has been aborted
if (reply->error() == QNetworkReply::OperationCanceledError)
{
reply->deleteLater();
return;
}
if (reply->error())
{
this->sessionBrowserWidget->Reset();
QtMessageBox::Error(this, "Server Error", "Failed to retrieve server list: " + reply->errorString());
reply->deleteLater();
return;
}
QJsonDocument jsonDocument = QJsonDocument::fromJson(reply->readAll());
QJsonObject jsonObject = jsonDocument.object();
QStringList jsonKeys = jsonObject.keys();
this->sessionBrowserWidget->StartRefresh();
this->resetDispatcherState();
// we only care about the addresses
this->dispatcherAddressList.clear();
for (int i = 0; i < jsonKeys.size(); i++)
{
QString address = jsonObject[jsonKeys.at(i)].toString();
this->dispatcherAddressList.append(address);
}
this->dispatcherAddressListIndex = -1;
this->dispatcherMoveThroughList = true;
this->dispatcherTimerId = this->startTimer(250);
reply->deleteLater();
}
void NetplaySessionBrowserDialog::on_serverComboBox_currentIndexChanged(int index)
{
if (index == -1)
@@ -518,47 +348,19 @@ void NetplaySessionBrowserDialog::on_serverComboBox_currentIndexChanged(int inde
// disable join and refresh button while refreshing
this->toggleUI(false, false, false);
bool dispatcher = NetplayCommon::IsServerDispatcher(this->serverComboBox, index);
if (this->pingTimerId != -1)
{
this->killTimer(this->pingTimerId);
this->pingTimerId = -1;
}
this->resetDispatcherState();
this->pingLineEdit->setText(dispatcher ? "N/A" : "Calculating...");
this->pingLineEdit->setText("Calculating...");
this->sessionBrowserWidget->StartRefresh();
if (dispatcher)
{
QString region = NetplayCommon::GetServerData(this->serverComboBox, index);
this->pingTimerId = this->startTimer(2000);
QUrl url(this->dispatcherUrl + "/getServers");
QUrlQuery urlQuery;
urlQuery.addQueryItem("region", region);
url.setQuery(urlQuery);
QNetworkRequest networkRequest = NetplayCommon::GetNetworkRequest(url);
// sadly we have to force HTTP/1 here due to a Qt bug,
// we abort the connection which sadly in Qt6 causes an error and eventually segfault,
// so to workaround this, force HTTP/1 until it's fixed in Qt6
//
// thank you MapLibre devs for figuring out this issue:
// https://github.com/maplibre/maplibre-native/issues/3644
networkRequest.setAttribute(QNetworkRequest::Http2AllowedAttribute, false);
this->dispatcherNetworkReply = this->dispatcherNetworkAccessManager->get(networkRequest);
}
else
{
this->pingTimerId = this->startTimer(2000);
QString address = NetplayCommon::GetServerData(this->serverComboBox, index);
this->webSocket->open(QUrl(address));
}
QString address = NetplayCommon::GetServerData(this->serverComboBox, index);
this->webSocket->open(QUrl(address));
}
void NetplaySessionBrowserDialog::on_sessionBrowserWidget_OnSessionChanged(bool valid)
@@ -589,8 +391,7 @@ void NetplaySessionBrowserDialog::on_buttonBox_clicked(QAbstractButton* button)
void NetplaySessionBrowserDialog::accept()
{
if (!NetplayCommon::IsServerDispatcher(this->serverComboBox) &&
!this->webSocket->isValid())
if (!this->webSocket->isValid())
{
QtMessageBox::Error(this, "Server Error", "Connection Failed");
return;
@@ -666,13 +467,5 @@ void NetplaySessionBrowserDialog::accept()
this->sessionData = sessionData;
if (NetplayCommon::IsServerDispatcher(this->serverComboBox))
{
this->dispatcherJoinSession = true;
this->webSocket->open(sessionData.Address);
}
else
{
this->joinSession();
}
this->joinSession();
}
@@ -48,17 +48,6 @@ class NetplaySessionBrowserDialog : public QDialog, private Ui::NetplaySessionBr
QMap<QString, CoreRomSettings> romData;
int pingTimerId = -1;
int dispatcherTimerId = -1;
int dispatcherTimeoutTimerId = -1;
bool dispatcherMoveThroughList = false;
bool dispatcherJoinSession = false;
QNetworkAccessManager* dispatcherNetworkAccessManager = nullptr;
QNetworkReply* dispatcherNetworkReply = nullptr;
QString dispatcherUrl;
QStringList dispatcherAddressList;
int dispatcherAddressListIndex = 0;
QString showROMDialog(QString name, QString md5);
@@ -84,9 +73,6 @@ class NetplaySessionBrowserDialog : public QDialog, private Ui::NetplaySessionBr
void on_broadcastSocket_readyRead(void);
void on_jsonServerListDownload_Finished(QNetworkReply* reply);
void on_dispatcherRegionListDownload_Finished(QNetworkReply* reply);
void on_dispatcherRetrieveServers_Finished(QNetworkReply* reply);
void on_serverComboBox_currentIndexChanged(int index);
void on_sessionBrowserWidget_OnSessionChanged(bool valid);
void on_sessionBrowserWidget_OnRefreshDone(void);
@@ -526,7 +526,6 @@ void SettingsDialog::loadInterfaceNetplaySettings(void)
this->netplayNicknameLineEdit->setText(QString::fromStdString(CoreSettingsGetStringValue(SettingsID::Netplay_Nickname)));
this->netplayServerUrlLineEdit->setText(QString::fromStdString(CoreSettingsGetStringValue(SettingsID::Netplay_ServerJsonUrl)));
this->netplayDispatcherUrlLineEdit->setText(QString::fromStdString(CoreSettingsGetStringValue(SettingsID::Netplay_DispatcherUrl)));
}
void SettingsDialog::loadDefaultCoreSettings(void)
@@ -680,7 +679,6 @@ void SettingsDialog::loadDefaultInterfaceNetplaySettings(void)
{
this->netplayNicknameLineEdit->setText(QString::fromStdString(CoreSettingsGetDefaultStringValue(SettingsID::Netplay_Nickname)));
this->netplayServerUrlLineEdit->setText(QString::fromStdString(CoreSettingsGetDefaultStringValue(SettingsID::Netplay_ServerJsonUrl)));
this->netplayDispatcherUrlLineEdit->setText(QString::fromStdString(CoreSettingsGetDefaultStringValue(SettingsID::Netplay_DispatcherUrl)));
}
void SettingsDialog::saveSettings(void)
@@ -916,7 +914,6 @@ void SettingsDialog::saveInterfaceNetplaySettings(void)
{
CoreSettingsSetValue(SettingsID::Netplay_Nickname, this->netplayNicknameLineEdit->text().toStdString());
CoreSettingsSetValue(SettingsID::Netplay_ServerJsonUrl, this->netplayServerUrlLineEdit->text().toStdString());
CoreSettingsSetValue(SettingsID::Netplay_DispatcherUrl, this->netplayDispatcherUrlLineEdit->text().toStdString());
}
void SettingsDialog::commonHotkeySettings(SettingsDialogAction action)
@@ -665,27 +665,6 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_21">
<item>
<widget class="QLabel" name="label_18">
<property name="text">
<string>Dispatcher URL</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="netplayDispatcherUrlLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_19">
<property name="orientation">
+1 -1
View File
@@ -1 +1 @@
v0.8.8
v0.9.0