mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-08-01 11:48:36 +02:00
Compare commits
82
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1dfdd454b | ||
|
|
eee577e694 | ||
|
|
e791f43899 | ||
|
|
ee4a83b0c9 | ||
|
|
94ad591d4f | ||
|
|
bd0982ed4c | ||
|
|
8e9be7411c | ||
|
|
1528e962d2 | ||
|
|
d9822b8ad8 | ||
|
|
2fc8ae44be | ||
|
|
66c0771d12 | ||
|
|
8f49597082 | ||
|
|
d3a8bfe747 | ||
|
|
30962c8d08 | ||
|
|
899a4873d4 | ||
|
|
fc3c4df695 | ||
|
|
baca4179f0 | ||
|
|
3dbe303ee4 | ||
|
|
99cfbb49c1 | ||
|
|
b2fa00844e | ||
|
|
7887919e74 | ||
|
|
470e995c6c | ||
|
|
86d76bbf59 | ||
|
|
45fa6a8bb5 | ||
|
|
223c2cba9a | ||
|
|
562c32cd15 | ||
|
|
876a0bfbd7 | ||
|
|
81558dc9c4 | ||
|
|
2d62078b04 | ||
|
|
474ad59818 | ||
|
|
d75c8b1edc | ||
|
|
d89b4b6fa1 | ||
|
|
afb875f2c6 | ||
|
|
f24d44d470 | ||
|
|
4918b0aa09 | ||
|
|
a50ed4d05a | ||
|
|
19d08ba94f | ||
|
|
a80b3144bb | ||
|
|
9f0206966b | ||
|
|
dcae14398a | ||
|
|
14164e6592 | ||
|
|
873977d0b8 | ||
|
|
78319ef0ba | ||
|
|
d1beb6be9a | ||
|
|
5df1662c1b | ||
|
|
45b8338f6d | ||
|
|
92914cee40 | ||
|
|
44079ebbe2 | ||
|
|
8d2d9ebb1d | ||
|
|
4f62bff866 | ||
|
|
8510ec29ba | ||
|
|
cde272055f | ||
|
|
5e3ad282a8 | ||
|
|
091b3a8694 | ||
|
|
42ce97aca5 | ||
|
|
a4df5c300e | ||
|
|
4bf51e735a | ||
|
|
d7e7c8164c | ||
|
|
eb5e3fcd13 | ||
|
|
8f8968cbb1 | ||
|
|
ac83e93426 | ||
|
|
78d0cf4a4f | ||
|
|
2444c6090b | ||
|
|
7e49bc5a50 | ||
|
|
457719d0cc | ||
|
|
c3e63d5a0e | ||
|
|
8c1b3f8ce3 | ||
|
|
55b37b794c | ||
|
|
1aca396e34 | ||
|
|
cb000a5101 | ||
|
|
1ae2a96747 | ||
|
|
6834086c37 | ||
|
|
b33b493c6e | ||
|
|
437fe1e442 | ||
|
|
2a348dcff9 | ||
|
|
2821986fb2 | ||
|
|
1a13f9707b | ||
|
|
ff1b47942c | ||
|
|
13e4973b48 | ||
|
|
fd46054fb7 | ||
|
|
f618f39bee | ||
|
|
603486ad2f |
@@ -6,6 +6,9 @@ updates:
|
||||
schedule:
|
||||
# Check for updates to GitHub Actions every week
|
||||
interval: "weekly"
|
||||
commit-message:
|
||||
# Prefix all commit messages with "Deps/gha: "
|
||||
prefix: "Deps/gha"
|
||||
groups:
|
||||
ci-deps:
|
||||
patterns:
|
||||
|
||||
@@ -92,7 +92,7 @@ jobs:
|
||||
run: echo "timestamp=$(date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: ccache cache files
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: .ccache
|
||||
key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
|
||||
@@ -114,7 +114,7 @@ jobs:
|
||||
|
||||
- name: Cache Dependencies
|
||||
id: cache-deps
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/deps
|
||||
key: ${{ inputs.os }} ${{ inputs.platform }} deps ${{ hashFiles('.github/workflows/scripts/linux/build-dependencies-qt.sh', '.github/workflows/scripts/common/*.patch') }}
|
||||
|
||||
@@ -99,7 +99,7 @@ jobs:
|
||||
|
||||
- name: Cache Dependencies
|
||||
id: cache-deps
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/deps
|
||||
key: ${{ inputs.os }} ${{ inputs.arch }} deps ${{ hashFiles('.github/workflows/scripts/macos/*', '.github/workflows/scripts/common/*.patch') }}
|
||||
@@ -120,7 +120,7 @@ jobs:
|
||||
run: echo "timestamp=$(date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache ccache cache
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: .ccache
|
||||
key: ${{ inputs.os }} ${{ inputs.arch }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
|
||||
@@ -176,7 +176,7 @@ jobs:
|
||||
|
||||
- name: Sign the Application
|
||||
if: ${{ inputs.sign_and_notarize == true && env.SIGN_KEY }}
|
||||
uses: indygreg/apple-code-sign-action@44d0985b7f4363198e80b6fea63ac3e9dd3e9957
|
||||
uses: indygreg/apple-code-sign-action@5e7a4a01fe4dffe948ef3bcf1f4538d963cb0c72
|
||||
with:
|
||||
input_path: 'PCSX2.app'
|
||||
p12_file: cert.p12
|
||||
|
||||
@@ -23,11 +23,11 @@ QTAPNG=1.3.0
|
||||
|
||||
FFMPEG=8.1
|
||||
LIBBACKTRACE=ad106d5fdd5d960bd33fae1c48a351af567fd075
|
||||
LIBJPEGTURBO=3.1.4.1
|
||||
LIBJPEGTURBO=3.2.0
|
||||
LIBPNG=1.6.58
|
||||
LIBWEBP=1.6.0
|
||||
NVENC=13.0.19.0
|
||||
SDL=SDL3-3.4.10
|
||||
SDL=SDL3-3.4.12
|
||||
LZ4=1.10.0
|
||||
VULKAN=1.4.328.1
|
||||
ZSTD=1.5.7
|
||||
@@ -57,10 +57,10 @@ f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG
|
||||
|
||||
b072aed6871998cce9b36e7774033105ca29e33632be5b6347f3206898e0756a ffmpeg-$FFMPEG.tar.xz
|
||||
96e5c2d7f2c482a60d5804da48a2eb9a0db0719b2c65dcc169fbfdcf37f3a45d libbacktrace-$LIBBACKTRACE.tar.gz
|
||||
ecae8008e2cc9ade2f2c1bb9d5e6d4fb73e7c433866a056bd82980741571a022 libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
6f30092cef9fb839779646608f4ee14ae3cbac989c47fa05e841b0841f09878e libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
28eb403f51f0f7405249132cecfe82ea5c0ef97f1b32c5a65828814ae0d34775 libpng-$LIBPNG.tar.xz
|
||||
e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWEBP.tar.gz
|
||||
12b34280415ec8418c864408b93d008a20a6530687ee613d60bfbd20411f2785 $SDL.tar.gz
|
||||
f07b958a9ac5020fb7a44cadb957f658b2149c3c8abb4f63145fac9303249db7 $SDL.tar.gz
|
||||
eee7dea22ed502868017971c86c63c4ed1e6085de0baebfdcc3d3322f00f3eb0 libpng-$LIBPNG-apng.patch.gz
|
||||
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
|
||||
13da39edb3a40ed9713ae390ca89faa2f1202c9dda869ef306a8d4383e242bee nv-codec-headers-$NVENC.tar.gz
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://libsdl.org/release/SDL3-3.4.10.tar.gz",
|
||||
"sha256": "12b34280415ec8418c864408b93d008a20a6530687ee613d60bfbd20411f2785"
|
||||
"url": "https://libsdl.org/release/SDL3-3.4.12.tar.gz",
|
||||
"sha256": "f07b958a9ac5020fb7a44cadb957f658b2149c3c8abb4f63145fac9303249db7"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
|
||||
@@ -3,7 +3,7 @@ Version=1.0
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Name=PCSX2
|
||||
StartupWMClass=PCSX2
|
||||
StartupWMClass=pcsx2-qt
|
||||
GenericName=PlayStation 2 Emulator
|
||||
Comment=Sony PlayStation 2 emulator
|
||||
Exec=pcsx2-qt
|
||||
|
||||
@@ -47,12 +47,12 @@ QT=6.11.1
|
||||
QTAPNG=1.3.0
|
||||
|
||||
FREETYPE=2.14.3
|
||||
SDL=SDL3-3.4.10
|
||||
SDL=SDL3-3.4.12
|
||||
HARFBUZZ=14.2.0
|
||||
ZSTD=1.5.7
|
||||
LZ4=1.10.0
|
||||
LIBPNG=1.6.58
|
||||
LIBJPEGTURBO=3.1.4.1
|
||||
LIBJPEGTURBO=3.2.0
|
||||
LIBWEBP=1.6.0
|
||||
FFMPEG=8.1
|
||||
MOLTENVK=1.4.1
|
||||
@@ -93,14 +93,14 @@ b2bf6c6845ac175ed7f819145483ba4676f617aaa6a5012c8efee63c8bbac413 qtimageformats
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
|
||||
36bc4f1cc413335368ee656c42afca65c5a3987e8768cc28cf11ba775e785a5f freetype-$FREETYPE.tar.xz
|
||||
12b34280415ec8418c864408b93d008a20a6530687ee613d60bfbd20411f2785 $SDL.tar.gz
|
||||
f07b958a9ac5020fb7a44cadb957f658b2149c3c8abb4f63145fac9303249db7 $SDL.tar.gz
|
||||
c652d5d94971031654ab3989891a490a895d3e3f2b71171c62692b28e94b1b93 harfbuzz-$HARFBUZZ.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
|
||||
28eb403f51f0f7405249132cecfe82ea5c0ef97f1b32c5a65828814ae0d34775 libpng-$LIBPNG.tar.xz
|
||||
e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWEBP.tar.gz
|
||||
eee7dea22ed502868017971c86c63c4ed1e6085de0baebfdcc3d3322f00f3eb0 libpng-$LIBPNG-apng.patch.gz
|
||||
ecae8008e2cc9ade2f2c1bb9d5e6d4fb73e7c433866a056bd82980741571a022 libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
6f30092cef9fb839779646608f4ee14ae3cbac989c47fa05e841b0841f09878e libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
b072aed6871998cce9b36e7774033105ca29e33632be5b6347f3206898e0756a ffmpeg-$FFMPEG.tar.xz
|
||||
9985f141902a17de818e264d17c1ce334b748e499ee02fcb4703e4dc0038f89c MoltenVK-$MOLTENVK.tar.gz
|
||||
51dbf24fe72e43dd7cb9a289d3cab47112010f1a2ed69b6fc8ac0dff31991ed2 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
|
||||
|
||||
@@ -24,12 +24,12 @@ QT=6.11.1
|
||||
QTAPNG=1.3.0
|
||||
|
||||
FREETYPE=2.14.3
|
||||
SDL=SDL3-3.4.10
|
||||
SDL=SDL3-3.4.12
|
||||
HARFBUZZ=14.2.0
|
||||
ZSTD=1.5.7
|
||||
LZ4=1.10.0
|
||||
LIBPNG=1.6.58
|
||||
LIBJPEGTURBO=3.1.4.1
|
||||
LIBJPEGTURBO=3.2.0
|
||||
LIBWEBP=1.6.0
|
||||
FFMPEG=8.1
|
||||
MOLTENVK=1.4.1
|
||||
@@ -69,14 +69,14 @@ b2bf6c6845ac175ed7f819145483ba4676f617aaa6a5012c8efee63c8bbac413 qtimageformats
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
|
||||
36bc4f1cc413335368ee656c42afca65c5a3987e8768cc28cf11ba775e785a5f freetype-$FREETYPE.tar.xz
|
||||
12b34280415ec8418c864408b93d008a20a6530687ee613d60bfbd20411f2785 $SDL.tar.gz
|
||||
f07b958a9ac5020fb7a44cadb957f658b2149c3c8abb4f63145fac9303249db7 $SDL.tar.gz
|
||||
c652d5d94971031654ab3989891a490a895d3e3f2b71171c62692b28e94b1b93 harfbuzz-$HARFBUZZ.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
|
||||
28eb403f51f0f7405249132cecfe82ea5c0ef97f1b32c5a65828814ae0d34775 libpng-$LIBPNG.tar.xz
|
||||
e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWEBP.tar.gz
|
||||
eee7dea22ed502868017971c86c63c4ed1e6085de0baebfdcc3d3322f00f3eb0 libpng-$LIBPNG-apng.patch.gz
|
||||
ecae8008e2cc9ade2f2c1bb9d5e6d4fb73e7c433866a056bd82980741571a022 libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
6f30092cef9fb839779646608f4ee14ae3cbac989c47fa05e841b0841f09878e libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
b072aed6871998cce9b36e7774033105ca29e33632be5b6347f3206898e0756a ffmpeg-$FFMPEG.tar.xz
|
||||
9985f141902a17de818e264d17c1ce334b748e499ee02fcb4703e4dc0038f89c v$MOLTENVK.tar.gz
|
||||
51dbf24fe72e43dd7cb9a289d3cab47112010f1a2ed69b6fc8ac0dff31991ed2 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
|
||||
|
||||
Regular → Executable
+4
-4
@@ -60,8 +60,8 @@ set QTAPNG=1.3.0
|
||||
|
||||
set FREETYPE=2.14.3
|
||||
set HARFBUZZ=14.2.0
|
||||
set SDL=SDL3-3.4.10
|
||||
set LIBJPEGTURBO=3.1.4.1
|
||||
set SDL=SDL3-3.4.12
|
||||
set LIBJPEGTURBO=3.2.0
|
||||
set LIBPNG=1658
|
||||
set LIBPNGLONG=1.6.58
|
||||
set LZ4=1.10.0
|
||||
@@ -92,9 +92,9 @@ call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects
|
||||
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip bb2f83255706b1c92d731541c7cefaf98bb5b93e8f76d16f6deda05225ff20ee || goto error
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1658.zip b32f170855dbbe3e6d9e645af40b538137041773672c3ba3e02db5816c82d376 || goto error
|
||||
call :downloadfile "lpng%LIBPNG%-apng.patch.gz" https://download.sourceforge.net/libpng-apng/libpng-%LIBPNGLONG%-apng.patch.gz eee7dea22ed502868017971c86c63c4ed1e6085de0baebfdcc3d3322f00f3eb0 || goto error
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" ecae8008e2cc9ade2f2c1bb9d5e6d4fb73e7c433866a056bd82980741571a022 || goto error
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 6f30092cef9fb839779646608f4ee14ae3cbac989c47fa05e841b0841f09878e || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" be8dafef3ecc956e736cfd1c242c10737f3ad589a866f25ba437b7f2f6d5ced2 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 3d4de8967a49c0451e775a0c1e9022092c19fdef41ba38a83fcf031c5a6496e2 || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/refs/tags/v%LZ4%.zip" 3224b4c80f351f194984526ef396f6079bd6332dd9825c72ac0d7a37b3cdc565 || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://github.com/madler/zlib/releases/download/v%ZLIB%/zlib%ZLIBSHORT%.zip" e8bf55f3017aa181690990cb58a994e77885da140609fc8f94abe9b65d2cae28 || goto error
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 7897bc5d620580d9b7cd3539c44b59d78f3657d33663fe97a145e07b4ebd69a4 || goto error
|
||||
|
||||
Regular → Executable
+4
-5
@@ -77,8 +77,8 @@ set LIBX264=b35605ace3ddf7c1a5d67a2eb553f034aef41d55
|
||||
|
||||
set FREETYPE=2.14.3
|
||||
set HARFBUZZ=14.2.0
|
||||
set SDL=SDL3-3.4.10
|
||||
set LIBJPEGTURBO=3.1.4.1
|
||||
set SDL=SDL3-3.4.12
|
||||
set LIBJPEGTURBO=3.2.0
|
||||
set LIBPNG=1658
|
||||
set LIBPNGLONG=1.6.58
|
||||
set LZ4=1.10.0
|
||||
@@ -120,9 +120,9 @@ call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects
|
||||
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip bb2f83255706b1c92d731541c7cefaf98bb5b93e8f76d16f6deda05225ff20ee || goto error
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1658.zip b32f170855dbbe3e6d9e645af40b538137041773672c3ba3e02db5816c82d376 || goto error
|
||||
call :downloadfile "lpng%LIBPNG%-apng.patch.gz" https://download.sourceforge.net/libpng-apng/libpng-%LIBPNGLONG%-apng.patch.gz eee7dea22ed502868017971c86c63c4ed1e6085de0baebfdcc3d3322f00f3eb0 || goto error
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" ecae8008e2cc9ade2f2c1bb9d5e6d4fb73e7c433866a056bd82980741571a022 || goto error
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 6f30092cef9fb839779646608f4ee14ae3cbac989c47fa05e841b0841f09878e || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" be8dafef3ecc956e736cfd1c242c10737f3ad589a866f25ba437b7f2f6d5ced2 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 3d4de8967a49c0451e775a0c1e9022092c19fdef41ba38a83fcf031c5a6496e2 || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/refs/tags/v%LZ4%.zip" 3224b4c80f351f194984526ef396f6079bd6332dd9825c72ac0d7a37b3cdc565 || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://github.com/madler/zlib/releases/download/v%ZLIB%/zlib%ZLIBSHORT%.zip" e8bf55f3017aa181690990cb58a994e77885da140609fc8f94abe9b65d2cae28 || goto error
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 7897bc5d620580d9b7cd3539c44b59d78f3657d33663fe97a145e07b4ebd69a4 || goto error
|
||||
@@ -471,7 +471,6 @@ echo "Building PlutoVG..."
|
||||
rmdir /S /Q "plutovg-%PLUTOVG%"
|
||||
%SEVENZIP% x "plutovg-%PLUTOVG%.zip" || goto error
|
||||
cd "plutovg-%PLUTOVG%" || goto error
|
||||
%PATCH% -p1 < "%SCRIPTDIR%\plutovg-workaround-msvc-ice.patch" || goto error
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DPLUTOVG_BUILD_EXAMPLES=OFF -B build -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
diff --git a/source/plutovg-font.c b/source/plutovg-font.c
|
||||
index 0ad89b1..110de7f 100644
|
||||
--- a/source/plutovg-font.c
|
||||
+++ b/source/plutovg-font.c
|
||||
@@ -836,7 +836,8 @@ int plutovg_font_face_cache_load_file(plutovg_font_face_cache_t* cache, const ch
|
||||
size_t family_index = 0;
|
||||
if(unicode_family_name) {
|
||||
const stbtt_uint8* family_name = unicode_family_name;
|
||||
- while(family_length) {
|
||||
+ //while(family_length) {
|
||||
+ for (int i = family_length; i > 0; i -= 2) {
|
||||
stbtt_uint16 ch = family_name[0] * 256 + family_name[1];
|
||||
if(ch < 0x80) {
|
||||
entry->family[family_index++] = ch;
|
||||
@@ -853,7 +854,8 @@ int plutovg_font_face_cache_load_file(plutovg_font_face_cache_t* cache, const ch
|
||||
entry->family[family_index++] = (0x80 + ((c) & 0x3f));
|
||||
|
||||
family_name += 2;
|
||||
- family_length -= 2;
|
||||
+ //family_length -= 2;
|
||||
+ i -= 2;
|
||||
} else {
|
||||
entry->family[family_index++] = (0xe0 + (ch >> 12));
|
||||
entry->family[family_index++] = (0x80 + ((ch >> 6) & 0x3f));
|
||||
@@ -861,7 +863,7 @@ int plutovg_font_face_cache_load_file(plutovg_font_face_cache_t* cache, const ch
|
||||
}
|
||||
|
||||
family_name += 2;
|
||||
- family_length -= 2;
|
||||
+ //family_length -= 2;
|
||||
}
|
||||
|
||||
entry->family[family_index] = '\0';
|
||||
@@ -902,7 +904,8 @@ int plutovg_font_face_cache_load_file(plutovg_font_face_cache_t* cache, const ch
|
||||
};
|
||||
|
||||
const stbtt_uint8* family_name = roman_family_name;
|
||||
- while(family_length) {
|
||||
+ //while(family_length) {
|
||||
+ for (int i2 = family_length; i2 > 0; i2--) {
|
||||
stbtt_uint16 ch = MAC_ROMAN_TABLE[family_name[0]];
|
||||
if(ch < 0x80) {
|
||||
entry->family[family_index++] = ch;
|
||||
@@ -916,7 +919,7 @@ int plutovg_font_face_cache_load_file(plutovg_font_face_cache_t* cache, const ch
|
||||
}
|
||||
|
||||
family_name += 1;
|
||||
- family_length -= 1;
|
||||
+ //family_length -= 1;
|
||||
}
|
||||
|
||||
entry->family[family_index] = '\0';
|
||||
@@ -122,7 +122,7 @@ jobs:
|
||||
|
||||
- name: Cache Dependencies
|
||||
id: cache-deps
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: deps
|
||||
key: ${{ inputs.os }} ${{ inputs.platform }} deps ${{ hashFiles('.github/workflows/scripts/windows/build-dependencies.bat', '.github/workflows/scripts/common/*.patch') }}
|
||||
|
||||
@@ -63,6 +63,9 @@ oprofile_data/
|
||||
*.kdev4
|
||||
/.kdev4*
|
||||
|
||||
# Kate Projects
|
||||
.kateproject*
|
||||
|
||||
# Resources and docs in /bin are tracked
|
||||
/bin/**/*.dll
|
||||
/bin/**/*.dmp
|
||||
|
||||
Vendored
+2
@@ -361,6 +361,8 @@ enum cpuinfo_uarch {
|
||||
cpuinfo_uarch_raptor_cove = 0x0010020F,
|
||||
/** Intel Redwood Cove microarchitecture (Granite Rapids). */
|
||||
cpuinfo_uarch_redwood_cove = 0x00100210,
|
||||
/** Intel Coyote Cove microarchitecture. */
|
||||
cpuinfo_uarch_coyote_cove = 0x00100211,
|
||||
|
||||
/** Pentium 4 with Willamette, Northwood, or Foster cores. */
|
||||
cpuinfo_uarch_willamette = 0x00100300,
|
||||
|
||||
Vendored
+3
@@ -1,3 +1,6 @@
|
||||
/* for syscall() */
|
||||
#define _DEFAULT_SOURCE
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
Vendored
+2
@@ -36,6 +36,7 @@ enum cpuinfo_arm_chipset_vendor {
|
||||
cpuinfo_arm_chipset_vendor_texas_instruments,
|
||||
cpuinfo_arm_chipset_vendor_unisoc,
|
||||
cpuinfo_arm_chipset_vendor_wondermedia,
|
||||
cpuinfo_arm_chipset_vendor_google,
|
||||
cpuinfo_arm_chipset_vendor_max,
|
||||
};
|
||||
|
||||
@@ -73,6 +74,7 @@ enum cpuinfo_arm_chipset_series {
|
||||
cpuinfo_arm_chipset_series_unisoc_t,
|
||||
cpuinfo_arm_chipset_series_unisoc_ums,
|
||||
cpuinfo_arm_chipset_series_wondermedia_wm,
|
||||
cpuinfo_arm_chipset_series_google_tensor,
|
||||
cpuinfo_arm_chipset_series_max,
|
||||
};
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -366,7 +366,7 @@ CPUINFO_INTERNAL struct cpuinfo_arm_chipset cpuinfo_arm_android_decode_chipset_f
|
||||
CPUINFO_INTERNAL struct cpuinfo_arm_chipset cpuinfo_arm_android_decode_chipset_from_ro_hardware_chipname(
|
||||
const char ro_hardware_chipname[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]);
|
||||
CPUINFO_INTERNAL struct cpuinfo_arm_chipset cpuinfo_arm_android_decode_chipset_from_ro_soc_model(
|
||||
const char ro_soc_model[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]);
|
||||
const char soc_model[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]);
|
||||
#else
|
||||
CPUINFO_INTERNAL struct cpuinfo_arm_chipset cpuinfo_arm_linux_decode_chipset_from_proc_cpuinfo_revision(
|
||||
const char proc_cpuinfo_revision[restrict static CPUINFO_REVISION_VALUE_MAX]);
|
||||
|
||||
+61
-10
@@ -3492,9 +3492,20 @@ struct cpuinfo_arm_chipset cpuinfo_arm_android_decode_chipset_from_ro_chipname(
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Decodes chipset name from ro.soc.model Android system property.
|
||||
*
|
||||
* @param[in] soc_model - ro.soc.model value.
|
||||
*
|
||||
* @returns Decoded chipset name. If chipset could not be decoded, the resulting
|
||||
* structure would use `unknown` vendor and series identifiers.
|
||||
*/
|
||||
struct cpuinfo_arm_chipset cpuinfo_arm_android_decode_chipset_from_ro_soc_model(
|
||||
const char soc_model[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]) {
|
||||
struct cpuinfo_arm_chipset chipset;
|
||||
struct cpuinfo_arm_chipset chipset = {
|
||||
.vendor = cpuinfo_arm_chipset_vendor_unknown,
|
||||
.series = cpuinfo_arm_chipset_series_unknown,
|
||||
};
|
||||
const size_t soc_model_length = strnlen(soc_model, CPUINFO_BUILD_PROP_VALUE_MAX);
|
||||
const char* soc_model_end = soc_model + soc_model_length;
|
||||
|
||||
@@ -3516,10 +3527,28 @@ struct cpuinfo_arm_chipset cpuinfo_arm_android_decode_chipset_from_ro_soc_model(
|
||||
return chipset;
|
||||
}
|
||||
|
||||
return (struct cpuinfo_arm_chipset){
|
||||
.vendor = cpuinfo_arm_chipset_vendor_unknown,
|
||||
.series = cpuinfo_arm_chipset_series_unknown,
|
||||
};
|
||||
if (soc_model[0] != '\0') {
|
||||
if (strncmp(soc_model, "Tensor", 6) == 0) {
|
||||
chipset.vendor = cpuinfo_arm_chipset_vendor_google;
|
||||
chipset.series = cpuinfo_arm_chipset_series_google_tensor;
|
||||
const char* suffix_start = soc_model + 6;
|
||||
while (*suffix_start == ' ') {
|
||||
suffix_start++;
|
||||
}
|
||||
const size_t suffix_length = strnlen(suffix_start, CPUINFO_ARM_CHIPSET_SUFFIX_MAX);
|
||||
if (suffix_length > 0) {
|
||||
strncpy(chipset.suffix, suffix_start, suffix_length);
|
||||
}
|
||||
return chipset;
|
||||
} else if (strncmp(soc_model, "GS201", 5) == 0) {
|
||||
chipset.vendor = cpuinfo_arm_chipset_vendor_google;
|
||||
chipset.series = cpuinfo_arm_chipset_series_google_tensor;
|
||||
strncpy(chipset.suffix, "G2", 2);
|
||||
return chipset;
|
||||
}
|
||||
}
|
||||
|
||||
return chipset;
|
||||
}
|
||||
#endif /* __ANDROID__ */
|
||||
|
||||
@@ -3858,6 +3887,7 @@ static const char* chipset_vendor_string[cpuinfo_arm_chipset_vendor_max] = {
|
||||
[cpuinfo_arm_chipset_vendor_texas_instruments] = "Texas Instruments",
|
||||
[cpuinfo_arm_chipset_vendor_unisoc] = "Unisoc",
|
||||
[cpuinfo_arm_chipset_vendor_wondermedia] = "WonderMedia",
|
||||
[cpuinfo_arm_chipset_vendor_google] = "Google",
|
||||
};
|
||||
|
||||
/* Map from ARM chipset series ID to its string representation */
|
||||
@@ -3895,6 +3925,7 @@ static const char* chipset_series_string[cpuinfo_arm_chipset_series_max] = {
|
||||
[cpuinfo_arm_chipset_series_unisoc_t] = "T",
|
||||
[cpuinfo_arm_chipset_series_unisoc_ums] = "UMS",
|
||||
[cpuinfo_arm_chipset_series_wondermedia_wm] = "WM",
|
||||
[cpuinfo_arm_chipset_series_google_tensor] = "Tensor",
|
||||
};
|
||||
|
||||
/* Convert chipset name represented by cpuinfo_arm_chipset structure to a string
|
||||
@@ -3913,14 +3944,35 @@ void cpuinfo_arm_chipset_to_string(
|
||||
const char* vendor_string = chipset_vendor_string[vendor];
|
||||
const char* series_string = chipset_series_string[series];
|
||||
const uint32_t model = chipset->model;
|
||||
const size_t suffix_length = strnlen(chipset->suffix, CPUINFO_ARM_CHIPSET_SUFFIX_MAX);
|
||||
if (model == 0) {
|
||||
if (series == cpuinfo_arm_chipset_series_unknown) {
|
||||
strncpy(name, vendor_string, CPUINFO_ARM_CHIPSET_NAME_MAX);
|
||||
if (suffix_length > 0) {
|
||||
if (series == cpuinfo_arm_chipset_series_unknown) {
|
||||
snprintf(
|
||||
name,
|
||||
CPUINFO_ARM_CHIPSET_NAME_MAX,
|
||||
"%s %.*s",
|
||||
vendor_string,
|
||||
(int)suffix_length,
|
||||
chipset->suffix);
|
||||
} else {
|
||||
snprintf(
|
||||
name,
|
||||
CPUINFO_ARM_CHIPSET_NAME_MAX,
|
||||
"%s %s %.*s",
|
||||
vendor_string,
|
||||
series_string,
|
||||
(int)suffix_length,
|
||||
chipset->suffix);
|
||||
}
|
||||
} else {
|
||||
snprintf(name, CPUINFO_ARM_CHIPSET_NAME_MAX, "%s %s", vendor_string, series_string);
|
||||
if (series == cpuinfo_arm_chipset_series_unknown) {
|
||||
strncpy(name, vendor_string, CPUINFO_ARM_CHIPSET_NAME_MAX);
|
||||
} else {
|
||||
snprintf(name, CPUINFO_ARM_CHIPSET_NAME_MAX, "%s %s", vendor_string, series_string);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const size_t suffix_length = strnlen(chipset->suffix, CPUINFO_ARM_CHIPSET_SUFFIX_MAX);
|
||||
snprintf(
|
||||
name,
|
||||
CPUINFO_ARM_CHIPSET_NAME_MAX,
|
||||
@@ -4051,7 +4103,6 @@ static enum cpuinfo_arm_chipset_vendor disambiguate_chipset_vendor(
|
||||
(vendor_a == cpuinfo_arm_chipset_vendor_spreadtrum && vendor_b == cpuinfo_arm_chipset_vendor_unisoc)) {
|
||||
return cpuinfo_arm_chipset_vendor_unisoc;
|
||||
}
|
||||
|
||||
return cpuinfo_arm_chipset_vendor_unknown;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -256,12 +256,12 @@ void cpuinfo_arm_linux_init(void) {
|
||||
}
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
struct cpuinfo_android_properties android_properties;
|
||||
struct cpuinfo_android_properties android_properties = {0};
|
||||
cpuinfo_arm_android_parse_properties(&android_properties);
|
||||
#else
|
||||
char proc_cpuinfo_hardware[CPUINFO_HARDWARE_VALUE_MAX];
|
||||
char proc_cpuinfo_hardware[CPUINFO_HARDWARE_VALUE_MAX] = {0};
|
||||
#endif
|
||||
char proc_cpuinfo_revision[CPUINFO_REVISION_VALUE_MAX];
|
||||
char proc_cpuinfo_revision[CPUINFO_REVISION_VALUE_MAX] = {0};
|
||||
|
||||
if (!cpuinfo_arm_linux_parse_proc_cpuinfo(
|
||||
#if defined(__ANDROID__)
|
||||
|
||||
Vendored
+49
@@ -11,6 +11,11 @@ void cpuinfo_arm_decode_vendor_uarch(
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
enum cpuinfo_vendor vendor[RESTRICT_STATIC 1],
|
||||
enum cpuinfo_uarch uarch[RESTRICT_STATIC 1]) {
|
||||
/* Ensure the out-parameters are always initialized, including for
|
||||
* implementers that are not handled in the switch below. */
|
||||
*vendor = cpuinfo_vendor_unknown;
|
||||
*uarch = cpuinfo_uarch_unknown;
|
||||
|
||||
switch (midr_get_implementer(midr)) {
|
||||
case 'A':
|
||||
*vendor = cpuinfo_vendor_arm;
|
||||
@@ -438,6 +443,50 @@ void cpuinfo_arm_decode_vendor_uarch(
|
||||
midr_get_part(midr));
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
*vendor = cpuinfo_vendor_apple;
|
||||
switch (midr_get_part(midr)) {
|
||||
case 0x022:
|
||||
case 0x024:
|
||||
case 0x028:
|
||||
*uarch = cpuinfo_uarch_icestorm;
|
||||
break;
|
||||
case 0x023:
|
||||
case 0x025:
|
||||
case 0x029:
|
||||
*uarch = cpuinfo_uarch_firestorm;
|
||||
break;
|
||||
case 0x032:
|
||||
case 0x034:
|
||||
case 0x038:
|
||||
*uarch = cpuinfo_uarch_blizzard;
|
||||
break;
|
||||
case 0x033:
|
||||
case 0x035:
|
||||
case 0x039:
|
||||
*uarch = cpuinfo_uarch_avalanche;
|
||||
break;
|
||||
case 0x042:
|
||||
case 0x044:
|
||||
case 0x048:
|
||||
*uarch = cpuinfo_uarch_coll_sawtooth;
|
||||
break;
|
||||
case 0x043:
|
||||
case 0x045:
|
||||
case 0x049:
|
||||
*uarch = cpuinfo_uarch_coll_everest;
|
||||
break;
|
||||
case 0x052:
|
||||
*uarch = cpuinfo_uarch_donan_sawtooth;
|
||||
break;
|
||||
case 0x053:
|
||||
*uarch = cpuinfo_uarch_donan_everest;
|
||||
break;
|
||||
default:
|
||||
cpuinfo_log_warning(
|
||||
"unknown Apple CPU part 0x%03" PRIx32 " ignored", midr_get_part(midr));
|
||||
}
|
||||
break;
|
||||
#if CPUINFO_ARCH_ARM
|
||||
case 'V':
|
||||
*vendor = cpuinfo_vendor_marvell;
|
||||
|
||||
Vendored
+9
@@ -307,6 +307,15 @@ static bool transform_token(char* token_start, char* token_end, struct parser_st
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
/*
|
||||
* Erase everything starting with "with" on AMD
|
||||
* processors, e.g. "AMD Ryzen 5 PRO 6650U with Radeon
|
||||
* Graphics"
|
||||
*/
|
||||
if (erase_matching(token_start, token_length, "with")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Remember to erase "Dual Core" in "AMD Athlon(tm) 64
|
||||
* X2 Dual Core Processor 3800+" */
|
||||
if (memcmp(token_start, "Dual", token_length) == 0) {
|
||||
|
||||
Vendored
+7
@@ -270,8 +270,15 @@ enum cpuinfo_uarch cpuinfo_x86_decode_uarch(
|
||||
return cpuinfo_uarch_prescott;
|
||||
}
|
||||
break;
|
||||
case 0x12:
|
||||
switch (model_info->model) {
|
||||
case 0x01: // Nova Lake P-core (Coyote Cove)
|
||||
return cpuinfo_uarch_coyote_cove;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case cpuinfo_vendor_amd:
|
||||
switch (model_info->family) {
|
||||
#if CPUINFO_ARCH_X86
|
||||
|
||||
-2
@@ -265,8 +265,6 @@ BOOL CALLBACK cpuinfo_x86_windows_init(PINIT_ONCE init_once, PVOID parameter, PV
|
||||
* APIC order */
|
||||
const uint32_t core_id = cores_count++;
|
||||
uint32_t smt_id = 0;
|
||||
/* Reconstruct core part of APIC ID */
|
||||
const uint32_t core_apic_id = (core_id & core_bits_mask) << x86_processor.topology.core_bits_offset;
|
||||
/* Iterate processor groups and set the core & SMT parts of APIC
|
||||
* ID */
|
||||
for (uint32_t i = 0; i < core_info->Processor.GroupCount; i++) {
|
||||
|
||||
Vendored
+3
-3
@@ -1,7 +1,7 @@
|
||||
#define MY_VER_MAJOR 26
|
||||
#define MY_VER_MINOR 1
|
||||
#define MY_VER_MINOR 2
|
||||
#define MY_VER_BUILD 0
|
||||
#define MY_VERSION_NUMBERS "26.01"
|
||||
#define MY_VERSION_NUMBERS "26.02"
|
||||
#define MY_VERSION MY_VERSION_NUMBERS
|
||||
|
||||
#ifdef MY_CPU_NAME
|
||||
@@ -10,7 +10,7 @@
|
||||
#define MY_VERSION_CPU MY_VERSION
|
||||
#endif
|
||||
|
||||
#define MY_DATE "2026-04-27"
|
||||
#define MY_DATE "2026-06-25"
|
||||
#undef MY_COPYRIGHT
|
||||
#undef MY_VERSION_COPYRIGHT_DATE
|
||||
#define MY_AUTHOR_NAME "Igor Pavlov"
|
||||
|
||||
Vendored
+5
@@ -76,6 +76,11 @@
|
||||
#pragma GCC diagnostic ignored "-Wreserved-identifier"
|
||||
#endif
|
||||
|
||||
#if __clang_major__ >= 22
|
||||
// for "StdAfx.h" and "Precomp.h"
|
||||
#pragma GCC diagnostic ignored "-Wshadow-header"
|
||||
#endif
|
||||
|
||||
#endif // __clang__
|
||||
|
||||
#if defined(__clang__) && __clang_major__ >= 16
|
||||
|
||||
Vendored
+680
@@ -0,0 +1,680 @@
|
||||
ISTORY of the LZMA SDK
|
||||
-----------------------
|
||||
|
||||
26.02 2026-06-25
|
||||
-------------------------
|
||||
- Some bugs and vulnerabilities were fixed.
|
||||
|
||||
|
||||
26.01 2026-04-27
|
||||
-------------------------
|
||||
- linux version of 7-Zip can use huge pages (2 MB pages). It can increase compression
|
||||
speed for 10% for 7z/xz/LZMA/LZMA2 compression.
|
||||
- new -spo[d|c|r] switch specifies the path generation mode for the output directory
|
||||
for archive extraction. The output directory path is generated from the path specified
|
||||
in the -o{dir_path} switch and the name of the archive being unpacked.
|
||||
-spod : for Linux/Posix/macOS: -o{dir_path} specifies the direct path to the output directory.
|
||||
The asterisk (*) character in {dir_path} will not be replaced by the archive name.
|
||||
-spoc : 7-Zip will concatenate the path specified in -o{dir_path} with the archive name
|
||||
to form the final path to the output directory.
|
||||
-spor : 7-Zip will replace asterisk (*) character in the path specified in the -o{dir_path}
|
||||
with the archive name. This is the default option.
|
||||
- The 7zdec.exe program (a lightweight 7z archive decoder) has been modified for security purposes.
|
||||
Now 7zdec.exe extracts files only to the current folder and its subfolders.
|
||||
- some bugs were fixed.
|
||||
|
||||
|
||||
|
||||
26.00 2026-02-12
|
||||
-------------------------
|
||||
- some bugs were fixed.
|
||||
|
||||
|
||||
25.01 2025-08-03
|
||||
-------------------------
|
||||
- The code for handling symbolic links has been changed
|
||||
to provide greater security when extracting files from archives.
|
||||
Command line switch -snld20 can be used to bypass default security
|
||||
checks when creating symbolic links.
|
||||
|
||||
|
||||
25.00 2025-07-05
|
||||
-------------------------
|
||||
- 7-Zip for Windows can now use more than 64 CPU threads for compression
|
||||
to zip/7z/xz archives and for the 7-Zip benchmark.
|
||||
If there are more than one processor group in Windows (on systems with more than
|
||||
64 cpu threads), 7-Zip distributes running CPU threads across different processor groups.
|
||||
- fixed some bugs and vulnerabilities.
|
||||
|
||||
|
||||
24.09 2024-11-29
|
||||
-------------------------
|
||||
- The default dictionary size values for LZMA/LZMA2 compression methods were increased:
|
||||
dictionary size compression level
|
||||
v24.08 v24.09 v24.09
|
||||
32-bit 64-bit
|
||||
8 MB 16 MB 16 MB -mx4
|
||||
16 MB 32 MB 32 MB -mx5 : Normal
|
||||
32 MB 64 MB 64 MB -mx6
|
||||
32 MB 64 MB 128 MB -mx7 : Maximum
|
||||
64 MB 64 MB 256 MB -mx8
|
||||
64 MB 64 MB 256 MB -mx9 : Ultra
|
||||
The default dictionary size values for 32-bit versions of LZMA/LZMA2 don't exceed 64 MB.
|
||||
- If an archive update operation uses a temporary archive folder and
|
||||
the archive is moved to the destination folder, 7-Zip shows the progress of moving
|
||||
the archive file, as this operation can take a long time if the archive is large.
|
||||
- Some bugs were fixed.
|
||||
|
||||
|
||||
24.07 2024-06-19
|
||||
-------------------------
|
||||
- Changes in files:
|
||||
Asm/x86/Sha256Opt.asm
|
||||
Now it uses "READONLY" flag for constant array segment.
|
||||
It fixes an issue where ".rodata" section in 7-Zip for x86/x64 Linux had a "WRITE" attribute.
|
||||
|
||||
|
||||
24.05 2024-05-14
|
||||
-------------------------
|
||||
- New switch -myv={MMNN} to set decoder compatibility version for 7z archive creating.
|
||||
{MMNN} is 4-digit number that represents the version of 7-Zip without a dot.
|
||||
If -myv={MMNN} switch is specified, 7-Zip will only use compression methods that can
|
||||
be decoded by the specified version {MMNN} of 7-Zip and newer versions.
|
||||
If -myv={MMNN} switch is not specified, -myv=2300 is used, and 7-Zip will only
|
||||
use compression methods that can be decoded by 7-Zip 23.00 and newer versions.
|
||||
- New switch -myfa={FilterID} to allow 7-Zip to use the specified filter method for 7z archive creating.
|
||||
- New switch -myfd={FilterID} to disallow 7-Zip to use the specified filter method for 7z archive creating.
|
||||
|
||||
|
||||
24.03 2024-03-23
|
||||
-------------------------
|
||||
- 7-Zip now can use new RISCV filter for compression to 7z and xz archives.
|
||||
RISCV filter can increase compression ratio for data containing executable
|
||||
files compiled for RISC-V architecture.
|
||||
- The speed for LZMA and LZMA2 decompression in ARM64 version for Windows
|
||||
was increased by 20%-60%.
|
||||
It uses arm64 assembler code, and clang-cl is required for arm64 assembler code compiling.
|
||||
- -slmu switch : to show timestamps as UTC instead of LOCAL TIME.
|
||||
- -slsl switch : in console 7-Zip for Windows : to show file paths with
|
||||
linux path separator slash '/' instead of backslash separator '\'.
|
||||
- 7-Zip supports .sha256 files that use backslash path separator '\'.
|
||||
- Some bugs were fixed.
|
||||
|
||||
|
||||
24.01 2024-01-31
|
||||
-------------------------
|
||||
- 7-Zip uses file C/Precomp.h that is included to all c and c++ files.
|
||||
CPP/Common/Common.h also includes C/Precomp.h.
|
||||
C/Precomp.h defines the following macros (if _WIN32 is defined):
|
||||
Z7_LARGE_PAGES 1
|
||||
Z7_LONG_PATH 1
|
||||
Z7_WIN32_WINNT_MIN 0x0500 (or higher)
|
||||
_WIN32_WINNT 0x0500 (or higher)
|
||||
WINVER _WIN32_WINNT
|
||||
UNICODE 1
|
||||
_UNICODE 1
|
||||
if _WIN32_WINNT is defined already, C/Precomp.h doesn't redefine it.
|
||||
|
||||
- Speed optimizations for hash caclulation: CRC-32, CRC-64.
|
||||
- The bug was fixed: 7-Zip for Linux could fail for multivolume creation in some cases.
|
||||
- 7zr.exe for arm64 is included to LZMA SDK package.
|
||||
- Some bugs were fixed.
|
||||
|
||||
|
||||
23.01 2023-06-20
|
||||
-------------------------
|
||||
- 7-Zip now can use new ARM64 filter for compression to 7z and xz archives.
|
||||
ARM64 filter can increase compression ratio for data containing executable
|
||||
files compiled for ARM64 (AArch64) architecture.
|
||||
Also 7-Zip now parses executable files (that have exe and dll filename extensions)
|
||||
before compressing, and it selects appropriate filter for each parsed file:
|
||||
- BCJ or BCJ2 filter for x86 executable files,
|
||||
- ARM64 filter for ARM64 executable files.
|
||||
Previous versions by default used x86 filter BCJ or BCJ2 for all exe/dll files.
|
||||
- Default section size for BCJ2 filter was changed from 64 MiB to 240 MiB.
|
||||
It can increase compression ratio for executable files larger than 64 MiB.
|
||||
- Some optimizations in filters code: BCJ, BCJ2, Swap* and opthers.
|
||||
- If 7-Zip uses BCJ2 filter for big datasets compressing, it can use additional temp
|
||||
files in system's TEMP folder. 7-Zip uses temp file for additional compressed
|
||||
data stream, if size of such compressed stream is larger than predefined limit:
|
||||
16 MiB in 32-bit version, 4 GiB in 64-bit version.
|
||||
- When new 7-Zip creates multivolume archive, 7-Zip keeps in open state
|
||||
only volumes that still can be changed. Previous versions kept all volumes
|
||||
in open state until the end of the archive creation.
|
||||
- 7-Zip for Linux and macOS now can reduce the number of simultaneously open files,
|
||||
when 7-Zip opens, extracts or creates multivolume archive. It allows to avoid
|
||||
the failures for cases with big number of volumes, bacause there is a limitation
|
||||
for number of open files allowed for a single program in Linux and macOS.
|
||||
- Some bugs were fixed.
|
||||
- Source code changes:
|
||||
- All external macros for compiling C/C++ code of 7-Zip now have Z7_ prefix.
|
||||
- 7-Zip COM interfaces now use new macros that allow to declare and implement COM interface.
|
||||
- The code has been modified to compile with the maximum diagnostic warning level:
|
||||
-Wall in MSVC and -Weverything in CLANG.
|
||||
And some warning types are disabled in 2 files:
|
||||
- C/Compiler.h for C/C++ code warnings.
|
||||
- CPP/Common/Common.h for C++ code warnings.
|
||||
- Linux/macOS versions of 7-Zip: IUnknown interface in new code doesn't use
|
||||
virtual destructor that was used in previous 7-Zip and p7zip:
|
||||
// virtual ~IUnknown() {}
|
||||
So 7-Zip's dynamically linked shared libraries (codecs) are not compatible
|
||||
between new 7-Zip for Linux/macOS and old 7-Zip (and p7zip).
|
||||
|
||||
|
||||
21.07 2021-12-26
|
||||
-------------------------
|
||||
- New switches: -spm and -im!{file_path} to exclude directories from processing
|
||||
for specified paths that don't contain path separator character at the end of path.
|
||||
- The sorting order of files in archives was slightly changed to be more consistent
|
||||
for cases where the name of some directory is the same as the prefix part of the name
|
||||
of another directory or file.
|
||||
|
||||
|
||||
21.06 2021-11-24
|
||||
-------------------------
|
||||
- Bug in LZMA encoder in file LzmaEnc.c was fixed:
|
||||
LzmaEnc_MemEncode(), LzmaEncode() and LzmaCompress() could work incorrectly,
|
||||
if size value for output buffer is smaller than size required for all compressed data.
|
||||
LzmaEnc_Encode() could work incorrectly,
|
||||
if callback ISeqOutStream::Write() doesn't write all compressed data.
|
||||
NCompress::NLzma::CEncoder::Code() could work incorrectly,
|
||||
if callback ISequentialOutStream::Write() returns error code.
|
||||
- Bug in versions 21.00-21.05 was fixed:
|
||||
7-Zip didn't set attributes of directories during archive extracting.
|
||||
|
||||
|
||||
21.04 beta 2021-11-02
|
||||
-------------------------
|
||||
- 7-Zip now reduces the number of working CPU threads for compression,
|
||||
if RAM size is not enough for compression with big LZMA2 dictionary.
|
||||
- 7-Zip now can create and check "file.sha256" text files that contain the list
|
||||
of file names and SHA-256 checksums in format compatible with sha256sum program.
|
||||
|
||||
|
||||
21.03 beta 2021-07-20
|
||||
-------------------------
|
||||
- The maximum dictionary size for LZMA/LZMA2 compressing was increased to 4 GB (3840 MiB).
|
||||
- Minor speed optimizations in LZMA/LZMA2 compressing.
|
||||
|
||||
|
||||
21.02 alpha 2021-05-06
|
||||
-------------------------
|
||||
- The command line version of 7-Zip for macOS was released.
|
||||
- The speed for LZMA and LZMA2 decompression in arm64 versions for macOS and Linux
|
||||
was increased by 20%-60%.
|
||||
|
||||
|
||||
21.01 alpha 2021-03-09
|
||||
-------------------------
|
||||
- The command line version of 7-Zip for Linux was released.
|
||||
- The improvements for speed of ARM64 version using hardware CPU instructions
|
||||
for AES, CRC-32, SHA-1 and SHA-256.
|
||||
- Some bugs were fixed.
|
||||
|
||||
|
||||
20.02 alpha 2020-08-08
|
||||
-------------------------
|
||||
- The default number of LZMA2 chunks per solid block in 7z archive was increased to 64.
|
||||
It allows to increase the compression speed for big 7z archives, if there is a big number
|
||||
of CPU cores and threads.
|
||||
- The speed of PPMd compressing/decompressing was increased for 7z archives.
|
||||
- The new -ssp switch. If the switch -ssp is specified, 7-Zip doesn't allow the system
|
||||
to modify "Last Access Time" property of source files for archiving and hashing operations.
|
||||
- Some bugs were fixed.
|
||||
|
||||
|
||||
20.00 alpha 2020-02-06
|
||||
-------------------------
|
||||
- 7-Zip now supports new optional match finders for LZMA/LZMA2 compression: bt5 and hc5,
|
||||
that can work faster than bt4 and hc4 match finders for the data with big redundancy.
|
||||
- The compression ratio was improved for Fast and Fastest compression levels with the
|
||||
following default settings:
|
||||
- Fastest level (-mx1) : hc5 match finder with 256 KB dictionary.
|
||||
- Fast level (-mx3) : hc5 match finder with 4 MB dictionary.
|
||||
- Minor speed optimizations in multithreaded LZMA/LZMA2 compression for Normal/Maximum/Ultra
|
||||
compression levels.
|
||||
|
||||
|
||||
19.00 2019-02-21
|
||||
-------------------------
|
||||
- Encryption strength for 7z archives was increased:
|
||||
the size of random initialization vector was increased from 64-bit to 128-bit,
|
||||
and the pseudo-random number generator was improved.
|
||||
- The bug in 7zIn.c code was fixed.
|
||||
|
||||
|
||||
18.06 2018-12-30
|
||||
-------------------------
|
||||
- The speed for LZMA/LZMA2 compressing was increased by 3-10%,
|
||||
and there are minor changes in compression ratio.
|
||||
- Some bugs were fixed.
|
||||
- The bug in 7-Zip 18.02-18.05 was fixed:
|
||||
There was memory leak in multithreading xz decoder - XzDecMt_Decode(),
|
||||
if xz stream contains only one block.
|
||||
- The changes for MSVS compiler makefiles:
|
||||
- the makefiles now use "PLATFORM" macroname with values (x64, x86, arm64)
|
||||
instead of "CPU" macroname with values (AMD64, ARM64).
|
||||
- the makefiles by default now use static version of the run-time library.
|
||||
|
||||
|
||||
18.05 2018-04-30
|
||||
-------------------------
|
||||
- The speed for LZMA/LZMA2 compressing was increased
|
||||
by 8% for fastest/fast compression levels and
|
||||
by 3% for normal/maximum compression levels.
|
||||
- Previous versions of 7-Zip could work incorrectly in "Large memory pages" mode in
|
||||
Windows 10 because of some BUG with "Large Pages" in Windows 10.
|
||||
Now 7-Zip doesn't use "Large Pages" on Windows 10 up to revision 1709 (16299).
|
||||
- The BUG was fixed in Lzma2Enc.c
|
||||
Lzma2Enc_Encode2() function worked incorretly,
|
||||
if (inStream == NULL) and the number of block threads is more than 1.
|
||||
|
||||
|
||||
18.03 beta 2018-03-04
|
||||
-------------------------
|
||||
- Asm\x86\LzmaDecOpt.asm: new optimized LZMA decoder written in asm
|
||||
for x64 with about 30% higher speed than main version of LZMA decoder written in C.
|
||||
- The speed for single-thread LZMA/LZMA2 decoder written in C was increased by 3%.
|
||||
- 7-Zip now can use multi-threading for 7z/LZMA2 decoding,
|
||||
if there are multiple independent data chunks in LZMA2 stream.
|
||||
- 7-Zip now can use multi-threading for xz decoding,
|
||||
if there are multiple blocks in xz stream.
|
||||
|
||||
|
||||
18.01 2019-01-28
|
||||
-------------------------
|
||||
- The BUG in 17.01 - 18.00 beta was fixed:
|
||||
XzDec.c : random block unpacking and XzUnpacker_IsBlockFinished()
|
||||
didn't work correctly for xz archives without checksum (CRC).
|
||||
|
||||
|
||||
18.00 beta 2019-01-10
|
||||
-------------------------
|
||||
- The BUG in xz encoder was fixed:
|
||||
There was memory leak of 16 KB for each file compressed with
|
||||
xz compression method, if additional filter was used.
|
||||
|
||||
|
||||
17.01 beta 2017-08-28
|
||||
-------------------------
|
||||
- Minor speed optimization for LZMA2 (xz and 7z) multi-threading compression.
|
||||
7-Zip now uses additional memory buffers for multi-block LZMA2 compression.
|
||||
CPU utilization was slightly improved.
|
||||
- 7-zip now creates multi-block xz archives by default. Block size can be
|
||||
specified with -ms[Size]{m|g} switch.
|
||||
- xz decoder now can unpack random block from multi-block xz archives.
|
||||
- 7-Zip command line: @listfile now doesn't work after -- switch.
|
||||
Use -i@listfile before -- switch instead.
|
||||
- The BUGs were fixed:
|
||||
7-Zip 17.00 beta crashed for commands that write anti-item to 7z archive.
|
||||
|
||||
|
||||
17.00 beta 2017-04-29
|
||||
-------------------------
|
||||
- NewHandler.h / NewHandler.cpp:
|
||||
now it redefines operator new() only for old MSVC compilers (_MSC_VER < 1900).
|
||||
- C/7zTypes.h : the names of variables in interface structures were changed (vt).
|
||||
- Some bugs were fixed. 7-Zip could crash in some cases.
|
||||
- Some internal changes in code.
|
||||
|
||||
|
||||
16.04 2016-10-04
|
||||
-------------------------
|
||||
- The bug was fixed in DllSecur.c.
|
||||
|
||||
|
||||
16.03 2016-09-28
|
||||
-------------------------
|
||||
- SFX modules now use some protection against DLL preloading attack.
|
||||
- Some bugs in 7z code were fixed.
|
||||
|
||||
|
||||
16.02 2016-05-21
|
||||
-------------------------
|
||||
- The BUG in 16.00 - 16.01 was fixed:
|
||||
Split Handler (SplitHandler.cpp) returned incorrect
|
||||
total size value (kpidSize) for split archives.
|
||||
|
||||
|
||||
16.01 2016-05-19
|
||||
-------------------------
|
||||
- Some internal changes to reduce the number of compiler warnings.
|
||||
|
||||
|
||||
16.00 2016-05-10
|
||||
-------------------------
|
||||
- Some bugs were fixed.
|
||||
|
||||
|
||||
15.12 2015-11-19
|
||||
-------------------------
|
||||
- The BUG in C version of 7z decoder was fixed:
|
||||
7zDec.c : SzDecodeLzma2()
|
||||
7z decoder could mistakenly report about decoding error for some 7z archives
|
||||
that use LZMA2 compression method.
|
||||
The probability to get that mistaken decoding error report was about
|
||||
one error per 16384 solid blocks for solid blocks larger than 16 KB (compressed size).
|
||||
- The BUG (in 9.26-15.11) in C version of 7z decoder was fixed:
|
||||
7zArcIn.c : SzReadHeader2()
|
||||
7z decoder worked incorrectly for 7z archives that contain
|
||||
empty solid blocks, that can be placed to 7z archive, if some file is
|
||||
unavailable for reading during archive creation.
|
||||
|
||||
|
||||
15.09 beta 2015-10-16
|
||||
-------------------------
|
||||
- The BUG in LZMA / LZMA2 encoding code was fixed.
|
||||
The BUG in LzFind.c::MatchFinder_ReadBlock() function.
|
||||
If input data size is larger than (4 GiB - dictionary_size),
|
||||
the following code worked incorrectly:
|
||||
- LZMA : LzmaEnc_MemEncode(), LzmaEncode() : LZMA encoding functions
|
||||
for compressing from memory to memory.
|
||||
That BUG is not related to LZMA encoder version that works via streams.
|
||||
- LZMA2 : multi-threaded version of LZMA2 encoder worked incorrectly, if
|
||||
default value of chunk size (CLzma2EncProps::blockSize) is changed
|
||||
to value larger than (4 GiB - dictionary_size).
|
||||
|
||||
|
||||
9.38 beta 2015-01-03
|
||||
-------------------------
|
||||
- The BUG in 9.31-9.37 was fixed:
|
||||
IArchiveGetRawProps interface was disabled for 7z archives.
|
||||
- The BUG in 9.26-9.36 was fixed:
|
||||
Some code in CPP\7zip\Archive\7z\ worked correctly only under Windows.
|
||||
|
||||
|
||||
9.36 beta 2014-12-26
|
||||
-------------------------
|
||||
- The BUG in command line version was fixed:
|
||||
7-Zip created temporary archive in current folder during update archive
|
||||
operation, if -w{Path} switch was not specified.
|
||||
The fixed 7-Zip creates temporary archive in folder that contains updated archive.
|
||||
- The BUG in 9.33-9.35 was fixed:
|
||||
7-Zip silently ignored file reading errors during 7z or gz archive creation,
|
||||
and the created archive contained only part of file that was read before error.
|
||||
The fixed 7-Zip stops archive creation and it reports about error.
|
||||
|
||||
|
||||
9.35 beta 2014-12-07
|
||||
-------------------------
|
||||
- 7zr.exe now support AES encryption.
|
||||
- SFX mudules were added to LZMA SDK
|
||||
- Some bugs were fixed.
|
||||
|
||||
|
||||
9.21 beta 2011-04-11
|
||||
-------------------------
|
||||
- New class FString for file names at file systems.
|
||||
- Speed optimization in CRC code for big-endian CPUs.
|
||||
- The BUG in Lzma2Dec.c was fixed:
|
||||
Lzma2Decode function didn't work.
|
||||
|
||||
|
||||
9.18 beta 2010-11-02
|
||||
-------------------------
|
||||
- New small SFX module for installers (SfxSetup).
|
||||
|
||||
|
||||
9.12 beta 2010-03-24
|
||||
-------------------------
|
||||
- The BUG in LZMA SDK 9.* was fixed: LZMA2 codec didn't work,
|
||||
if more than 10 threads were used (or more than 20 threads in some modes).
|
||||
|
||||
|
||||
9.11 beta 2010-03-15
|
||||
-------------------------
|
||||
- PPMd compression method support
|
||||
|
||||
|
||||
9.09 2009-12-12
|
||||
-------------------------
|
||||
- The bug was fixed:
|
||||
Utf16_To_Utf8 funstions in UTFConvert.cpp and 7zMain.c
|
||||
incorrectly converted surrogate characters (the code >= 0x10000) to UTF-8.
|
||||
- Some bugs were fixed
|
||||
|
||||
|
||||
9.06 2009-08-17
|
||||
-------------------------
|
||||
- Some changes in ANSI-C 7z Decoder interfaces.
|
||||
|
||||
|
||||
9.04 2009-05-30
|
||||
-------------------------
|
||||
- LZMA2 compression method support
|
||||
- xz format support
|
||||
|
||||
|
||||
4.65 2009-02-03
|
||||
-------------------------
|
||||
- Some minor fixes
|
||||
|
||||
|
||||
4.63 2008-12-31
|
||||
-------------------------
|
||||
- Some minor fixes
|
||||
|
||||
|
||||
4.61 beta 2008-11-23
|
||||
-------------------------
|
||||
- The bug in ANSI-C LZMA Decoder was fixed:
|
||||
If encoded stream was corrupted, decoder could access memory
|
||||
outside of allocated range.
|
||||
- Some changes in ANSI-C 7z Decoder interfaces.
|
||||
- LZMA SDK is placed in the public domain.
|
||||
|
||||
|
||||
4.60 beta 2008-08-19
|
||||
-------------------------
|
||||
- Some minor fixes.
|
||||
|
||||
|
||||
4.59 beta 2008-08-13
|
||||
-------------------------
|
||||
- The bug was fixed:
|
||||
LZMA Encoder in fast compression mode could access memory outside of
|
||||
allocated range in some rare cases.
|
||||
|
||||
|
||||
4.58 beta 2008-05-05
|
||||
-------------------------
|
||||
- ANSI-C LZMA Decoder was rewritten for speed optimizations.
|
||||
- ANSI-C LZMA Encoder was included to LZMA SDK.
|
||||
- C++ LZMA code now is just wrapper over ANSI-C code.
|
||||
|
||||
|
||||
4.57 2007-12-12
|
||||
-------------------------
|
||||
- Speed optimizations in Ñ++ LZMA Decoder.
|
||||
- Small changes for more compatibility with some C/C++ compilers.
|
||||
|
||||
|
||||
4.49 beta 2007-07-05
|
||||
-------------------------
|
||||
- .7z ANSI-C Decoder:
|
||||
- now it supports BCJ and BCJ2 filters
|
||||
- now it supports files larger than 4 GB.
|
||||
- now it supports "Last Write Time" field for files.
|
||||
- C++ code for .7z archives compressing/decompressing from 7-zip
|
||||
was included to LZMA SDK.
|
||||
|
||||
|
||||
4.43 2006-06-04
|
||||
-------------------------
|
||||
- Small changes for more compatibility with some C/C++ compilers.
|
||||
|
||||
|
||||
4.42 2006-05-15
|
||||
-------------------------
|
||||
- Small changes in .h files in ANSI-C version.
|
||||
|
||||
|
||||
4.39 beta 2006-04-14
|
||||
-------------------------
|
||||
- The bug in versions 4.33b:4.38b was fixed:
|
||||
C++ version of LZMA encoder could not correctly compress
|
||||
files larger than 2 GB with HC4 match finder (-mfhc4).
|
||||
|
||||
|
||||
4.37 beta 2005-04-06
|
||||
-------------------------
|
||||
- Fixes in C++ code: code could no be compiled if _NO_EXCEPTIONS was defined.
|
||||
|
||||
|
||||
4.35 beta 2005-03-02
|
||||
-------------------------
|
||||
- The bug was fixed in C++ version of LZMA Decoder:
|
||||
If encoded stream was corrupted, decoder could access memory
|
||||
outside of allocated range.
|
||||
|
||||
|
||||
4.34 beta 2006-02-27
|
||||
-------------------------
|
||||
- Compressing speed and memory requirements for compressing were increased
|
||||
- LZMA now can use only these match finders: HC4, BT2, BT3, BT4
|
||||
|
||||
|
||||
4.32 2005-12-09
|
||||
-------------------------
|
||||
- Java version of LZMA SDK was included
|
||||
|
||||
|
||||
4.30 2005-11-20
|
||||
-------------------------
|
||||
- Compression ratio was improved in -a2 mode
|
||||
- Speed optimizations for compressing in -a2 mode
|
||||
- -fb switch now supports values up to 273
|
||||
- The bug in 7z_C (7zIn.c) was fixed:
|
||||
It used Alloc/Free functions from different memory pools.
|
||||
So if program used two memory pools, it worked incorrectly.
|
||||
- 7z_C: .7z format supporting was improved
|
||||
- LZMA# SDK (C#.NET version) was included
|
||||
|
||||
|
||||
4.27 (Updated) 2005-09-21
|
||||
-------------------------
|
||||
- Some GUIDs/interfaces in C++ were changed.
|
||||
IStream.h:
|
||||
ISequentialInStream::Read now works as old ReadPart
|
||||
ISequentialOutStream::Write now works as old WritePart
|
||||
|
||||
|
||||
4.27 2005-08-07
|
||||
-------------------------
|
||||
- The bug in LzmaDecodeSize.c was fixed:
|
||||
if _LZMA_IN_CB and _LZMA_OUT_READ were defined,
|
||||
decompressing worked incorrectly.
|
||||
|
||||
|
||||
4.26 2005-08-05
|
||||
-------------------------
|
||||
- Fixes in 7z_C code and LzmaTest.c:
|
||||
previous versions could work incorrectly,
|
||||
if malloc(0) returns 0
|
||||
|
||||
|
||||
4.23 2005-06-29
|
||||
-------------------------
|
||||
- Small fixes in C++ code
|
||||
|
||||
|
||||
4.22 2005-06-10
|
||||
-------------------------
|
||||
- Small fixes
|
||||
|
||||
|
||||
4.21 2005-06-08
|
||||
-------------------------
|
||||
- Interfaces for ANSI-C LZMA Decoder (LzmaDecode.c) were changed
|
||||
- New additional version of ANSI-C LZMA Decoder with zlib-like interface:
|
||||
- LzmaStateDecode.h
|
||||
- LzmaStateDecode.c
|
||||
- LzmaStateTest.c
|
||||
- ANSI-C LZMA Decoder now can decompress files larger than 4 GB
|
||||
|
||||
|
||||
4.17 2005-04-18
|
||||
-------------------------
|
||||
- New example for RAM->RAM compressing/decompressing:
|
||||
LZMA + BCJ (filter for x86 code):
|
||||
- LzmaRam.h
|
||||
- LzmaRam.cpp
|
||||
- LzmaRamDecode.h
|
||||
- LzmaRamDecode.c
|
||||
- -f86 switch for lzma.exe
|
||||
|
||||
|
||||
4.16 2005-03-29
|
||||
-------------------------
|
||||
- The bug was fixed in LzmaDecode.c (ANSI-C LZMA Decoder):
|
||||
If _LZMA_OUT_READ was defined, and if encoded stream was corrupted,
|
||||
decoder could access memory outside of allocated range.
|
||||
- Speed optimization of ANSI-C LZMA Decoder (now it's about 20% faster).
|
||||
Old version of LZMA Decoder now is in file LzmaDecodeSize.c.
|
||||
LzmaDecodeSize.c can provide slightly smaller code than LzmaDecode.c
|
||||
- Small speed optimization in LZMA C++ code
|
||||
- filter for SPARC's code was added
|
||||
- Simplified version of .7z ANSI-C Decoder was included
|
||||
|
||||
|
||||
4.06 2004-09-05
|
||||
-------------------------
|
||||
- The bug in v4.05 was fixed:
|
||||
LZMA-Encoder didn't release output stream in some cases.
|
||||
|
||||
|
||||
4.05 2004-08-25
|
||||
-------------------------
|
||||
- Source code of filters for x86, IA-64, ARM, ARM-Thumb
|
||||
and PowerPC code was included to SDK
|
||||
- Some internal minor changes
|
||||
|
||||
|
||||
4.04 2004-07-28
|
||||
-------------------------
|
||||
- More compatibility with some C++ compilers
|
||||
|
||||
|
||||
4.03 2004-06-18
|
||||
-------------------------
|
||||
- "Benchmark" command was added. It measures compressing
|
||||
and decompressing speed and shows rating values.
|
||||
Also it checks hardware errors.
|
||||
|
||||
|
||||
4.02 2004-06-10
|
||||
-------------------------
|
||||
- C++ LZMA Encoder/Decoder code now is more portable
|
||||
and it can be compiled by GCC on Linux.
|
||||
|
||||
|
||||
4.01 2004-02-15
|
||||
-------------------------
|
||||
- Some detection of data corruption was enabled.
|
||||
LzmaDecode.c / RangeDecoderReadByte
|
||||
.....
|
||||
{
|
||||
rd->ExtraBytes = 1;
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
|
||||
4.00 2004-02-13
|
||||
-------------------------
|
||||
- Original version of LZMA SDK
|
||||
|
||||
|
||||
|
||||
HISTORY of the LZMA
|
||||
-------------------
|
||||
2001-2008: Improvements to LZMA compressing/decompressing code,
|
||||
keeping compatibility with original LZMA format
|
||||
1996-2001: Development of LZMA compression format
|
||||
|
||||
Some milestones:
|
||||
|
||||
2001-08-30: LZMA compression was added to 7-Zip
|
||||
1999-01-02: First version of 7-Zip was released
|
||||
|
||||
|
||||
End of document
|
||||
Vendored
+287
-366
File diff suppressed because it is too large
Load Diff
Vendored
+3
-3
@@ -1,5 +1,5 @@
|
||||
/* DllSecur.c -- DLL loading security
|
||||
2023-12-03 : Igor Pavlov : Public domain */
|
||||
: Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
@@ -67,7 +67,7 @@ void LoadSecurityDlls(void)
|
||||
// at Vista (ver 6.0) : CoCreateInstance(CLSID_ShellLink, ...) doesn't work after SetDefaultDllDirectories() : Check it ???
|
||||
IF_NON_VISTA_SET_DLL_DIRS_AND_RETURN
|
||||
{
|
||||
wchar_t buf[MAX_PATH + 100];
|
||||
WCHAR buf[MAX_PATH + 100];
|
||||
const char *dll;
|
||||
unsigned pos = GetSystemDirectoryW(buf, MAX_PATH + 2);
|
||||
if (pos == 0 || pos > MAX_PATH)
|
||||
@@ -76,7 +76,7 @@ void LoadSecurityDlls(void)
|
||||
buf[pos++] = '\\';
|
||||
for (dll = g_Dlls; *dll != 0;)
|
||||
{
|
||||
wchar_t *dest = &buf[pos];
|
||||
WCHAR *dest = &buf[pos];
|
||||
for (;;)
|
||||
{
|
||||
const char c = *dll++;
|
||||
|
||||
Vendored
+2
-2
@@ -1,5 +1,5 @@
|
||||
/* MtDec.c -- Multi-thread Decoder
|
||||
2024-02-20 : Igor Pavlov : Public domain */
|
||||
: Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#define PRF(x)
|
||||
#endif
|
||||
|
||||
#define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d))
|
||||
#define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d);)
|
||||
|
||||
void MtProgress_Init(CMtProgress *p, ICompressProgressPtr progress)
|
||||
{
|
||||
|
||||
Vendored
+17
-30
@@ -25,8 +25,8 @@
|
||||
#define PRF(x)
|
||||
#endif
|
||||
|
||||
#define PRF_STR(s) PRF(printf("\n" s "\n"))
|
||||
#define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d))
|
||||
#define PRF_STR(s) PRF(printf("\n" s "\n");)
|
||||
#define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d);)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -574,7 +574,7 @@ static SRes MixCoder_ResetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 m
|
||||
output (status) can be :
|
||||
CODER_STATUS_NOT_FINISHED
|
||||
CODER_STATUS_FINISHED_WITH_MARK
|
||||
CODER_STATUS_NEEDS_MORE_INPUT - not implemented still
|
||||
CODER_STATUS_NEEDS_MORE_INPUT
|
||||
*/
|
||||
|
||||
static SRes MixCoder_Code(CMixCoder *p,
|
||||
@@ -582,8 +582,8 @@ static SRes MixCoder_Code(CMixCoder *p,
|
||||
const Byte *src, SizeT *srcLen, int srcWasFinished,
|
||||
ECoderFinishMode finishMode)
|
||||
{
|
||||
SizeT destLenOrig = *destLen;
|
||||
SizeT srcLenOrig = *srcLen;
|
||||
const SizeT destLenOrig = *destLen;
|
||||
const SizeT srcLenOrig = *srcLen;
|
||||
|
||||
*destLen = 0;
|
||||
*srcLen = 0;
|
||||
@@ -597,39 +597,26 @@ static SRes MixCoder_Code(CMixCoder *p,
|
||||
if (p->outBuf)
|
||||
{
|
||||
SRes res;
|
||||
SizeT destLen2, srcLen2;
|
||||
SizeT destLen2;
|
||||
int wasFinished;
|
||||
|
||||
PRF_STR("------- MixCoder Single ----------")
|
||||
|
||||
srcLen2 = srcLenOrig;
|
||||
destLen2 = destLenOrig;
|
||||
|
||||
if (p->numCoders != 1)
|
||||
{
|
||||
if (destLen2 < p->outWritten)
|
||||
return SZ_ERROR_FAIL;
|
||||
destLen2 -= p->outWritten;
|
||||
}
|
||||
*srcLen = srcLenOrig;
|
||||
{
|
||||
IStateCoder *coder = &p->coders[0];
|
||||
res = coder->Code2(coder->p, NULL, &destLen2, src, &srcLen2, srcWasFinished, finishMode,
|
||||
// &wasFinished,
|
||||
&p->status);
|
||||
wasFinished = (p->status == CODER_STATUS_FINISHED_WITH_MARK);
|
||||
res = coder->Code2(coder->p, NULL, &destLen2, src, srcLen, srcWasFinished, finishMode, &p->status);
|
||||
}
|
||||
|
||||
p->res = res;
|
||||
|
||||
/*
|
||||
if (wasFinished)
|
||||
p->status = CODER_STATUS_FINISHED_WITH_MARK;
|
||||
else
|
||||
{
|
||||
if (res == SZ_OK)
|
||||
if (destLen2 != destLenOrig)
|
||||
p->status = CODER_STATUS_NEEDS_MORE_INPUT;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
*srcLen = srcLen2;
|
||||
src += srcLen2;
|
||||
p->outWritten += destLen2;
|
||||
wasFinished = (p->status == CODER_STATUS_FINISHED_WITH_MARK);
|
||||
|
||||
if (res != SZ_OK || srcWasFinished || wasFinished)
|
||||
p->wasFinished = True;
|
||||
@@ -1016,8 +1003,8 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
||||
const Byte *src, SizeT *srcLen, int srcFinished,
|
||||
ECoderFinishMode finishMode, ECoderStatus *status)
|
||||
{
|
||||
SizeT destLenOrig = *destLen;
|
||||
SizeT srcLenOrig = *srcLen;
|
||||
const SizeT destLenOrig = *destLen;
|
||||
const SizeT srcLenOrig = *srcLen;
|
||||
*destLen = 0;
|
||||
*srcLen = 0;
|
||||
*status = CODER_STATUS_NOT_SPECIFIED;
|
||||
|
||||
Vendored
+4
-3
@@ -1,12 +1,13 @@
|
||||
Copyright 2015-2023 The Khronos Group Inc.
|
||||
Copyright 2015-2026 The Khronos Group Inc.
|
||||
|
||||
Files in this repository fall under one of these licenses:
|
||||
|
||||
- `Apache-2.0`
|
||||
- `MIT`
|
||||
|
||||
Note: With the exception of `parse_dependency.py` the files using `MIT` license
|
||||
also fall under `Apache-2.0`. Example:
|
||||
Note: With the exception of `parse_dependency.py`, which is based on an
|
||||
external file, files using the `MIT` license also fall under `Apache-2.0`.
|
||||
Example:
|
||||
|
||||
```
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
+1
-2
@@ -2,8 +2,7 @@
|
||||
* Copyright 2015-2023 The Khronos Group Inc.
|
||||
* Copyright 2015-2023 Valve Corporation
|
||||
* Copyright 2015-2023 LunarG, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
+1
-2
@@ -2,8 +2,7 @@
|
||||
* Copyright 2015-2023 The Khronos Group Inc.
|
||||
* Copyright 2015-2023 Valve Corporation
|
||||
* Copyright 2015-2023 LunarG, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
+1
-2
@@ -3,8 +3,7 @@
|
||||
//
|
||||
/*
|
||||
** Copyright 2014-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
|
||||
|
||||
+1
-2
@@ -3,8 +3,7 @@
|
||||
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
#include "vk_platform.h"
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
+994
-43
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
** Copyright 2015-2026 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
** SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
+131
-370
File diff suppressed because it is too large
Load Diff
@@ -1901,6 +1901,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
060000005e040000120b00000f050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
050000005e040000130b000022050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
060000005e040000120b000011050000,Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
050000005e040000130b000023050000,Xbox Series X Controller,a:b0,b:b1,x:b3,y:b4,back:b10,guide:b12,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,misc1:b15,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,platform:Linux,
|
||||
03000000450c00002043000010010000,XEOX SL6556 BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
05000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,
|
||||
03000000c0160000e105000001010000,XinMo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,
|
||||
|
||||
@@ -198,7 +198,7 @@ struct PS_OUTPUT
|
||||
|
||||
#if PS_RETURN_COLOR
|
||||
#if PS_DATE == 1 || PS_DATE == 2
|
||||
float c : SV_Target;
|
||||
float c0 : SV_Target;
|
||||
#else
|
||||
|
||||
float4 c0 : SV_Target0;
|
||||
@@ -2014,11 +2014,6 @@ VS_OUTPUT vs_main_expand(uint vid : SV_VertexID)
|
||||
vtx.inv_cov = is_near_corner ? 0.0f : 1.0f; // Full coverage at near corner, otherwise none.
|
||||
|
||||
vtx.interior = 0;
|
||||
|
||||
#if !VS_IIP
|
||||
// Get the provoking vertex color (first vertex in DX)
|
||||
vtx.c = i0 == 0 ? vtx.c : (i1 == 0 ? other.c : opposite.c);
|
||||
#endif
|
||||
}
|
||||
|
||||
return vtx;
|
||||
|
||||
@@ -455,11 +455,6 @@ void main()
|
||||
VSout.inv_cov = is_near_corner ? 0.0f : 1.0f; // Full coverage at near corner, otherwise none.
|
||||
|
||||
VSout.interior = 0;
|
||||
|
||||
#if !VS_IIP
|
||||
// Get the provoking vertex color (last vertex in GL)
|
||||
vtx.c = i0 == 2 ? vtx.c : (i1 == 2 ? other.c : opposite.c);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -450,11 +450,6 @@ void main()
|
||||
vsOut.inv_cov = is_near_corner ? 0.0f : 1.0f; // Full coverage at near corner, otherwise none.
|
||||
|
||||
vsOut.interior = 0;
|
||||
|
||||
#if !VS_IIP
|
||||
// Get the provoking vertex color (last vertex in VK)
|
||||
vtx.c = i0 == 2 ? vtx.c : (i1 == 2 ? other.c : opposite.c);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,6 +34,34 @@ Value MemoryInterface::Read(u32 address, bool* valid)
|
||||
return Value(0);
|
||||
}
|
||||
|
||||
std::optional<std::string> MemoryInterface::ReadString(u32 address, u32 max_size, ReadStringFlags flags)
|
||||
{
|
||||
std::string string;
|
||||
|
||||
for (u32 i = 0; i < max_size; i++)
|
||||
{
|
||||
bool valid;
|
||||
char c = Read8(address + i, &valid);
|
||||
if (!valid)
|
||||
return std::nullopt;
|
||||
|
||||
if (c == '\0')
|
||||
return string;
|
||||
else if (!(flags & ALLOW_NON_PRINTABLE_CHARACTERS) && (c < ' ' || c > '~'))
|
||||
return std::nullopt;
|
||||
|
||||
string += c;
|
||||
}
|
||||
|
||||
if (flags & ALLOW_LONG_STRINGS)
|
||||
{
|
||||
string += '~';
|
||||
return string;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
template <MemoryAccessType Value>
|
||||
bool MemoryInterface::Write(u32 address, Value value)
|
||||
{
|
||||
@@ -62,6 +90,17 @@ bool MemoryInterface::Write(u32 address, Value value)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MemoryInterface::WriteString(u32 address, std::string_view string)
|
||||
{
|
||||
if (!WriteBytes(address, string.data(), static_cast<u32>(string.size())))
|
||||
return false;
|
||||
|
||||
if (!Write8(address + static_cast<u32>(string.size()), '\0'))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemoryInterface::IdempotentWrite8(u32 address, u8 value)
|
||||
{
|
||||
bool valid;
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
#include "Pcsx2Types.h"
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
template <typename Value>
|
||||
@@ -31,16 +34,27 @@ public:
|
||||
template <MemoryAccessType Value>
|
||||
Value Read(u32 address, bool* valid = nullptr);
|
||||
|
||||
enum ReadStringFlags
|
||||
{
|
||||
NO_FLAGS = 0,
|
||||
ALLOW_LONG_STRINGS = 1 << 0,
|
||||
ALLOW_NON_PRINTABLE_CHARACTERS = 1 << 1
|
||||
};
|
||||
|
||||
std::optional<std::string> ReadString(u32 address, u32 max_size = 256, ReadStringFlags flags = NO_FLAGS);
|
||||
|
||||
virtual bool Write8(u32 address, u8 value) = 0;
|
||||
virtual bool Write16(u32 address, u16 value) = 0;
|
||||
virtual bool Write32(u32 address, u32 value) = 0;
|
||||
virtual bool Write64(u32 address, u64 value) = 0;
|
||||
virtual bool Write128(u32 address, u128 value) = 0;
|
||||
virtual bool WriteBytes(u32 address, void* src, u32 size) = 0;
|
||||
virtual bool WriteBytes(u32 address, const void* src, u32 size) = 0;
|
||||
|
||||
template <MemoryAccessType Value>
|
||||
bool Write(u32 address, Value value);
|
||||
|
||||
bool WriteString(u32 address, std::string_view string);
|
||||
|
||||
bool IdempotentWrite8(u32 address, u8 value);
|
||||
bool IdempotentWrite16(u32 address, u16 value);
|
||||
bool IdempotentWrite32(u32 address, u32 value);
|
||||
@@ -51,5 +65,5 @@ public:
|
||||
template <MemoryAccessType Value>
|
||||
bool IdempotentWrite(u32 address, Value value);
|
||||
|
||||
virtual bool CompareBytes(u32 address, void* src, u32 size) = 0;
|
||||
virtual bool CompareBytes(u32 address, const void* src, u32 size) = 0;
|
||||
};
|
||||
|
||||
+102
-30
@@ -17,7 +17,7 @@ struct RapidYAMLContext
|
||||
Error* error = nullptr;
|
||||
};
|
||||
|
||||
std::optional<ryml::Tree> ParseYAMLFromString(ryml::csubstr yaml, ryml::csubstr file_name, Error* error)
|
||||
std::optional<ryml::Tree> ParseYAMLFromString(ryml::csubstr yaml, ryml::csubstr file_name, Error* error, bool resolve_anchors)
|
||||
{
|
||||
RapidYAMLContext context;
|
||||
context.error = error;
|
||||
@@ -28,63 +28,135 @@ std::optional<ryml::Tree> ParseYAMLFromString(ryml::csubstr yaml, ryml::csubstr
|
||||
callbacks.set_user_data(static_cast<void*>(&context));
|
||||
|
||||
callbacks.set_error_basic([](ryml::csubstr msg, const ryml::ErrorDataBasic& errdata, void* user_data) {
|
||||
std::string description;
|
||||
auto callback = [&description](ryml::csubstr string) {
|
||||
description.append(string.str, string.len);
|
||||
};
|
||||
ryml::err_basic_format(std::move(callback), msg, errdata);
|
||||
RapidYAMLContext* context = static_cast<RapidYAMLContext*>(user_data);
|
||||
// This scope needs to stay, so all objects destruct before std::longjump
|
||||
{
|
||||
std::string description;
|
||||
auto callback = [&description](ryml::csubstr string) {
|
||||
description.append(string.str, string.len);
|
||||
};
|
||||
ryml::err_basic_format(std::move(callback), msg, errdata);
|
||||
|
||||
// We might have already returned, so don't try to recover.
|
||||
pxFailRel(description.c_str());
|
||||
std::abort();
|
||||
if (context != nullptr)
|
||||
{
|
||||
Error::SetString(context->error, std::move(description));
|
||||
}
|
||||
else
|
||||
{
|
||||
pxFailRel(description.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (context != nullptr)
|
||||
{
|
||||
std::longjmp(context->env, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::terminate();
|
||||
}
|
||||
});
|
||||
|
||||
callbacks.set_error_parse([](ryml::csubstr msg, const ryml::ErrorDataParse& errdata, void* user_data) {
|
||||
RapidYAMLContext* context = static_cast<RapidYAMLContext*>(user_data);
|
||||
// This scope needs to stay, so all objects destruct before std::longjump
|
||||
{
|
||||
std::string description;
|
||||
auto callback = [&description](ryml::csubstr string) {
|
||||
description.append(string.str, string.len);
|
||||
};
|
||||
ryml::err_parse_format(std::move(callback), msg, errdata);
|
||||
|
||||
std::string description;
|
||||
auto callback = [&description](ryml::csubstr string) {
|
||||
description.append(string.str, string.len);
|
||||
};
|
||||
ryml::err_parse_format(std::move(callback), msg, errdata);
|
||||
if (context != nullptr)
|
||||
{
|
||||
Error::SetString(context->error, std::move(description));
|
||||
}
|
||||
else
|
||||
{
|
||||
pxFailRel(description.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
Error::SetString(context->error, std::move(description));
|
||||
std::longjmp(context->env, 1);
|
||||
if (context != nullptr)
|
||||
{
|
||||
std::longjmp(context->env, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::terminate();
|
||||
}
|
||||
});
|
||||
|
||||
callbacks.set_error_visit([](ryml::csubstr msg, const ryml::ErrorDataVisit& errdata, void* user_data) {
|
||||
std::string description;
|
||||
auto callback = [&description](ryml::csubstr string) {
|
||||
description.append(string.str, string.len);
|
||||
};
|
||||
ryml::err_visit_format(std::move(callback), msg, errdata);
|
||||
RapidYAMLContext* context = static_cast<RapidYAMLContext*>(user_data);
|
||||
// This scope needs to stay, so all objects destruct before std::longjump
|
||||
{
|
||||
std::string description;
|
||||
auto callback = [&description](ryml::csubstr string) {
|
||||
description.append(string.str, string.len);
|
||||
};
|
||||
ryml::err_visit_format(std::move(callback), msg, errdata);
|
||||
|
||||
// We've probably already returned, so don't try to recover.
|
||||
pxFailRel(description.c_str());
|
||||
std::abort();
|
||||
if (context != nullptr)
|
||||
{
|
||||
Error::SetString(context->error, std::move(description));
|
||||
}
|
||||
else
|
||||
{
|
||||
pxFailRel(description.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (context != nullptr)
|
||||
{
|
||||
std::longjmp(context->env, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::terminate();
|
||||
}
|
||||
});
|
||||
#else
|
||||
callbacks.m_user_data = static_cast<void*>(&context);
|
||||
callbacks.m_error = [](const char* msg, size_t msg_len, ryml::Location location, void* user_data) {
|
||||
RapidYAMLContext* context = static_cast<RapidYAMLContext*>(user_data);
|
||||
|
||||
Error::SetString(context->error, std::string(msg, msg_len));
|
||||
std::longjmp(context->env, 1);
|
||||
if (RapidYAMLContext* context = static_cast<RapidYAMLContext*>(user_data))
|
||||
{
|
||||
Error::SetString(context->error, std::string(msg, msg_len));
|
||||
std::longjmp(context->env, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string description(msg, msg_len);
|
||||
pxFailRel(description.c_str());
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
ryml::EventHandlerTree event_handler(callbacks);
|
||||
ryml::Parser parser(&event_handler);
|
||||
|
||||
ryml::Tree tree;
|
||||
ryml::Tree tree(callbacks);
|
||||
|
||||
// The only options RapidYAML provides for recovering from errors are
|
||||
// throwing an exception or using setjmp/longjmp. Since we have exceptions
|
||||
// disabled we have to use the latter option.
|
||||
if (setjmp(context.env))
|
||||
if (setjmp(context.env) != 0)
|
||||
return std::nullopt;
|
||||
|
||||
ryml::parse_in_arena(&parser, file_name, yaml, &tree);
|
||||
if (resolve_anchors)
|
||||
{
|
||||
tree.resolve();
|
||||
}
|
||||
|
||||
// Callbacks passed to ryml::Tree are used for value parsing errors later,
|
||||
// so we need to clear the context before it goes out of scope.
|
||||
#if RYML_VERSION_MAJOR > 0 || RYML_VERSION_MINOR >= 11
|
||||
callbacks.set_user_data(nullptr);
|
||||
#else
|
||||
callbacks.m_user_data = nullptr;
|
||||
#endif
|
||||
tree.callbacks(callbacks);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
+3
-1
@@ -14,4 +14,6 @@
|
||||
/// parsing errors (as is recommended by the documentation for cases where
|
||||
/// exceptions are disabled). The file_name parameter is only used for error
|
||||
/// messages, which are returned via the error parameter.
|
||||
std::optional<ryml::Tree> ParseYAMLFromString(ryml::csubstr yaml, ryml::csubstr file_name, Error* error);
|
||||
/// If resolve_anchors is set to true, YAML anchors and aliases will be resolved.
|
||||
/// It's a potentially slow operation, so it's opt-in.
|
||||
std::optional<ryml::Tree> ParseYAMLFromString(ryml::csubstr yaml, ryml::csubstr file_name, Error* error, bool resolve_anchors = false);
|
||||
|
||||
@@ -196,6 +196,7 @@ target_sources(pcsx2-qt PRIVATE
|
||||
Debugger/ModuleModel.h
|
||||
Debugger/ModuleView.cpp
|
||||
Debugger/ModuleView.h
|
||||
Debugger/NavigationHistoryStack.h
|
||||
Debugger/RegisterView.cpp
|
||||
Debugger/RegisterView.h
|
||||
Debugger/RegisterView.ui
|
||||
|
||||
@@ -206,6 +206,29 @@ void DebuggerView::updateStyleSheet()
|
||||
setStyleSheet(stylesheet);
|
||||
}
|
||||
|
||||
bool DebuggerView::supportsNavigation()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DebuggerView::canNavigateBack()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DebuggerView::canNavigateForward()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void DebuggerView::navigateBack()
|
||||
{
|
||||
}
|
||||
|
||||
void DebuggerView::navigateForward()
|
||||
{
|
||||
}
|
||||
|
||||
void DebuggerView::goToInDisassembler(u32 address, bool switch_to_tab)
|
||||
{
|
||||
DebuggerEvents::GoToAddress event;
|
||||
@@ -268,7 +291,7 @@ std::vector<QAction*> DebuggerView::createEventActionsImplementation(
|
||||
if (lhs->displayNameWithoutSuffix() == rhs->displayNameWithoutSuffix())
|
||||
return lhs->displayNameSuffixNumber() < rhs->displayNameSuffixNumber();
|
||||
|
||||
return lhs->displayNameWithoutSuffix() < rhs->displayNameWithoutSuffix();
|
||||
return QtHost::LocaleSensitiveCompare(lhs->displayNameWithoutSuffix(), rhs->displayNameWithoutSuffix()) < 0;
|
||||
});
|
||||
|
||||
QMenu* submenu = nullptr;
|
||||
|
||||
@@ -153,6 +153,12 @@ public:
|
||||
|
||||
void updateStyleSheet();
|
||||
|
||||
virtual bool supportsNavigation();
|
||||
virtual bool canNavigateBack();
|
||||
virtual bool canNavigateForward();
|
||||
virtual void navigateBack();
|
||||
virtual void navigateForward();
|
||||
|
||||
static void goToInDisassembler(u32 address, bool switch_to_tab);
|
||||
static void goToInMemoryView(u32 address, bool switch_to_tab);
|
||||
|
||||
|
||||
@@ -115,6 +115,28 @@ DebuggerWindow::DebuggerWindow(QWidget* parent)
|
||||
|
||||
setMenuWidget(m_dock_manager->createMenuBar(menu_bar));
|
||||
|
||||
connect(m_dock_manager, &DockManager::focusedViewForNavigationChanged,
|
||||
this, &DebuggerWindow::updateNavigationButtons);
|
||||
|
||||
m_ui.actionNavigateBack->setEnabled(false);
|
||||
m_ui.actionNavigateForward->setEnabled(false);
|
||||
|
||||
connect(m_ui.actionNavigateBack, &QAction::triggered, this, [this]() {
|
||||
DebuggerView* view = m_dock_manager->focusedViewForNavigation();
|
||||
if (!view)
|
||||
return;
|
||||
|
||||
view->navigateBack();
|
||||
});
|
||||
|
||||
connect(m_ui.actionNavigateForward, &QAction::triggered, this, [this]() {
|
||||
DebuggerView* view = m_dock_manager->focusedViewForNavigation();
|
||||
if (!view)
|
||||
return;
|
||||
|
||||
view->navigateForward();
|
||||
});
|
||||
|
||||
updateTheme();
|
||||
|
||||
Host::RunOnCPUThread([]() {
|
||||
@@ -307,6 +329,21 @@ void DebuggerWindow::updateFromSettings()
|
||||
}
|
||||
}
|
||||
|
||||
void DebuggerWindow::updateNavigationButtons()
|
||||
{
|
||||
DebuggerView* view = m_dock_manager->focusedViewForNavigation();
|
||||
if (view)
|
||||
{
|
||||
m_ui.actionNavigateBack->setEnabled(view->canNavigateBack());
|
||||
m_ui.actionNavigateForward->setEnabled(view->canNavigateForward());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui.actionNavigateBack->setEnabled(false);
|
||||
m_ui.actionNavigateForward->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void DebuggerWindow::onVMStarting()
|
||||
{
|
||||
m_ui.actionRun->setEnabled(true);
|
||||
|
||||
@@ -40,7 +40,9 @@ public:
|
||||
|
||||
void updateFromSettings();
|
||||
|
||||
public slots:
|
||||
void updateNavigationButtons();
|
||||
|
||||
private slots:
|
||||
void onVMStarting();
|
||||
void onVMPaused();
|
||||
void onVMResumed();
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1000</width>
|
||||
<height>750</height>
|
||||
<width>1322</width>
|
||||
<height>974</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -23,8 +23,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1000</width>
|
||||
<height>21</height>
|
||||
<width>1322</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
@@ -58,6 +58,9 @@
|
||||
</property>
|
||||
<addaction name="actionOnTop"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionNavigateBack"/>
|
||||
<addaction name="actionNavigateForward"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionIncreaseFontSize"/>
|
||||
<addaction name="actionDecreaseFontSize"/>
|
||||
<addaction name="actionResetFontSize"/>
|
||||
@@ -82,12 +85,25 @@
|
||||
<addaction name="menuWindows"/>
|
||||
<addaction name="menuLayouts"/>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="toolBarNavigation">
|
||||
<property name="windowTitle">
|
||||
<string>Navigation</string>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<addaction name="actionNavigateBack"/>
|
||||
<addaction name="actionNavigateForward"/>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="toolBarDebug">
|
||||
<property name="windowTitle">
|
||||
<string>Debug</string>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
||||
<enum>Qt::ToolButtonStyle::ToolButtonTextBesideIcon</enum>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
@@ -105,7 +121,7 @@
|
||||
<string>File</string>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
||||
<enum>Qt::ToolButtonStyle::ToolButtonTextBesideIcon</enum>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
@@ -122,7 +138,7 @@
|
||||
<string>System</string>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
||||
<enum>Qt::ToolButtonStyle::ToolButtonTextBesideIcon</enum>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
@@ -138,7 +154,7 @@
|
||||
<string>View</string>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
||||
<enum>Qt::ToolButtonStyle::ToolButtonTextBesideIcon</enum>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
@@ -237,7 +253,7 @@
|
||||
<string>Shut Down</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
<enum>QAction::MenuRole::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionReset">
|
||||
@@ -248,7 +264,7 @@
|
||||
<string>Reset</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
<enum>QAction::MenuRole::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionClose">
|
||||
@@ -259,7 +275,7 @@
|
||||
<string>Close</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
<enum>QAction::MenuRole::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionIncreaseFontSize">
|
||||
@@ -270,7 +286,7 @@
|
||||
<string>Increase Font Size</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
<enum>QAction::MenuRole::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDecreaseFontSize">
|
||||
@@ -284,7 +300,7 @@
|
||||
<string>Ctrl+-</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
<enum>QAction::MenuRole::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionResetFontSize">
|
||||
@@ -295,7 +311,7 @@
|
||||
<string>Reset Font Size</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
<enum>QAction::MenuRole::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSettings">
|
||||
@@ -306,7 +322,7 @@
|
||||
<string>Settings</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
<enum>QAction::MenuRole::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGameSettings">
|
||||
@@ -317,7 +333,7 @@
|
||||
<string>Game Settings</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
<enum>QAction::MenuRole::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionToolsDummy">
|
||||
@@ -330,6 +346,37 @@
|
||||
<string/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionNavigateBack">
|
||||
<property name="icon">
|
||||
<iconset theme="arrow-left-line"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Navigate Back</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Navigate Back</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Alt+Left</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::MenuRole::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionNavigateForward">
|
||||
<property name="icon">
|
||||
<iconset theme="arrow-right-line"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Navigate Forward</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Alt+Right</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::MenuRole::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
||||
@@ -76,7 +76,11 @@ bool DisassemblyView::fromJson(const JsonValueWrapper& json)
|
||||
|
||||
auto start_address = json.value().FindMember("startAddress");
|
||||
if (start_address != json.value().MemberEnd() && start_address->value.IsUint())
|
||||
{
|
||||
m_visibleStart = start_address->value.GetUint() & ~3;
|
||||
m_navigation_history.clear();
|
||||
m_navigation_history.pushInstantly(m_visibleStart);
|
||||
}
|
||||
|
||||
auto go_to_pc_on_pause = json.value().FindMember("goToPCOnPause");
|
||||
if (go_to_pc_on_pause != json.value().MemberEnd() && go_to_pc_on_pause->value.IsBool())
|
||||
@@ -388,6 +392,41 @@ QString DisassemblyView::GetLineDisasm(u32 address)
|
||||
return QString("%1 %2").arg(lineInfo.name.c_str()).arg(lineInfo.params.c_str());
|
||||
};
|
||||
|
||||
bool DisassemblyView::supportsNavigation()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DisassemblyView::canNavigateBack()
|
||||
{
|
||||
return m_navigation_history.canGoBack();
|
||||
}
|
||||
|
||||
bool DisassemblyView::canNavigateForward()
|
||||
{
|
||||
return m_navigation_history.canGoForward();
|
||||
}
|
||||
|
||||
void DisassemblyView::navigateBack()
|
||||
{
|
||||
std::optional<u32> address = m_navigation_history.back();
|
||||
if (!address.has_value())
|
||||
return;
|
||||
|
||||
m_visibleStart = *address;
|
||||
update();
|
||||
}
|
||||
|
||||
void DisassemblyView::navigateForward()
|
||||
{
|
||||
std::optional<u32> address = m_navigation_history.forward();
|
||||
if (!address.has_value())
|
||||
return;
|
||||
|
||||
m_visibleStart = *address;
|
||||
update();
|
||||
}
|
||||
|
||||
// Here we go!
|
||||
void DisassemblyView::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
@@ -629,19 +668,21 @@ void DisassemblyView::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
|
||||
void DisassemblyView::wheelEvent(QWheelEvent* event)
|
||||
{
|
||||
if (event->angleDelta().y() < 0) // todo: max address bounds check?
|
||||
{
|
||||
if (event->angleDelta().y() < 0)
|
||||
m_visibleStart += 4;
|
||||
}
|
||||
else if (event->angleDelta().y() && m_visibleStart > 0)
|
||||
{
|
||||
m_visibleStart -= 4;
|
||||
}
|
||||
|
||||
m_navigation_history.pushWithDelay(m_visibleStart);
|
||||
update();
|
||||
}
|
||||
|
||||
void DisassemblyView::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
// Alt is used for the global navigation shortcuts.
|
||||
if (event->modifiers() & Qt::AltModifier)
|
||||
return;
|
||||
|
||||
switch (event->key())
|
||||
{
|
||||
case Qt::Key_Up:
|
||||
@@ -653,15 +694,19 @@ void DisassemblyView::keyPressEvent(QKeyEvent* event)
|
||||
// Auto scroll
|
||||
if (m_visibleStart > m_selectedAddressStart)
|
||||
m_visibleStart -= 4;
|
||||
|
||||
m_navigation_history.pushWithDelay(m_visibleStart);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Qt::Key_PageUp:
|
||||
{
|
||||
m_selectedAddressStart -= m_visibleRows * 4;
|
||||
m_selectedAddressEnd = m_selectedAddressStart;
|
||||
m_visibleStart -= m_visibleRows * 4;
|
||||
|
||||
m_navigation_history.pushWithDelay(m_visibleStart);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Down:
|
||||
{
|
||||
m_selectedAddressEnd += 4;
|
||||
@@ -673,6 +718,7 @@ void DisassemblyView::keyPressEvent(QKeyEvent* event)
|
||||
if (m_visibleStart + ((m_visibleRows - 1) * 4) < m_selectedAddressEnd)
|
||||
m_visibleStart += 4;
|
||||
|
||||
m_navigation_history.pushWithDelay(m_visibleStart);
|
||||
break;
|
||||
}
|
||||
case Qt::Key_PageDown:
|
||||
@@ -680,6 +726,7 @@ void DisassemblyView::keyPressEvent(QKeyEvent* event)
|
||||
m_selectedAddressStart += m_visibleRows * 4;
|
||||
m_selectedAddressEnd = m_selectedAddressStart;
|
||||
m_visibleStart += m_visibleRows * 4;
|
||||
m_navigation_history.pushWithDelay(m_visibleStart);
|
||||
break;
|
||||
}
|
||||
case Qt::Key_G:
|
||||
@@ -1014,6 +1061,8 @@ void DisassemblyView::gotoAddress(u32 address, bool should_set_focus)
|
||||
m_selectedAddressStart = destAddress;
|
||||
m_selectedAddressEnd = destAddress;
|
||||
|
||||
m_navigation_history.pushInstantly(m_visibleStart);
|
||||
|
||||
update();
|
||||
if (should_set_focus)
|
||||
setFocus();
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
|
||||
#include "ui_DisassemblyView.h"
|
||||
|
||||
#include "DebuggerView.h"
|
||||
#include "Debugger/DebuggerView.h"
|
||||
#include "Debugger/NavigationHistoryStack.h"
|
||||
|
||||
#include "pcsx2/DebugTools/DisassemblyManager.h"
|
||||
|
||||
@@ -26,6 +27,12 @@ public:
|
||||
// Required for the breakpoint list (ugh wtf)
|
||||
QString GetLineDisasm(u32 address);
|
||||
|
||||
bool supportsNavigation() override;
|
||||
bool canNavigateBack() override;
|
||||
bool canNavigateForward() override;
|
||||
void navigateBack() override;
|
||||
void navigateForward() override;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
void mousePressEvent(QMouseEvent* event) override;
|
||||
@@ -68,7 +75,7 @@ public slots:
|
||||
private:
|
||||
Ui::DisassemblyView m_ui;
|
||||
|
||||
u32 m_visibleStart = 0x100000; // The address of the first instruction shown.
|
||||
u32 m_visibleStart = STARTING_ADDRESS; // The address of the first instruction shown.
|
||||
u32 m_visibleRows;
|
||||
u32 m_selectedAddressStart = 0;
|
||||
u32 m_selectedAddressEnd = 0;
|
||||
@@ -81,6 +88,8 @@ private:
|
||||
bool m_goToProgramCounterOnPause = true;
|
||||
DisassemblyManager m_disassemblyManager;
|
||||
|
||||
NavigationHistoryStack<u32> m_navigation_history{STARTING_ADDRESS};
|
||||
|
||||
QString GetDisassemblyTitleLine();
|
||||
QColor GetDisassemblyTitleLineColor();
|
||||
inline QString DisassemblyStringFromAddress(u32 address, QFont font, u32 pc, bool selected);
|
||||
@@ -96,4 +105,6 @@ private:
|
||||
void setInstructions(u32 start, u32 end, u32 value);
|
||||
bool AddressCanRestore(u32 start, u32 end);
|
||||
bool FunctionCanRestore(u32 address);
|
||||
|
||||
static constexpr u32 STARTING_ADDRESS = 0x100000;
|
||||
};
|
||||
|
||||
@@ -339,15 +339,28 @@ void DockManager::createToolsMenu(QMenu* menu)
|
||||
if (m_current_layout == DockLayout::INVALID_INDEX || !g_debugger_window)
|
||||
return;
|
||||
|
||||
for (QToolBar* widget : g_debugger_window->findChildren<QToolBar*>())
|
||||
std::vector<QToolBar*> toolbars;
|
||||
for (QToolBar* toolbar : g_debugger_window->findChildren<QToolBar*>())
|
||||
toolbars.emplace_back(toolbar);
|
||||
|
||||
std::sort(toolbars.begin(), toolbars.end(), [](QToolBar* lhs, QToolBar* rhs) {
|
||||
return QtHost::LocaleSensitiveCompare(lhs->windowTitle(), rhs->windowTitle()) < 0;
|
||||
});
|
||||
|
||||
for (QToolBar* toolbar : toolbars)
|
||||
{
|
||||
QAction* action = menu->addAction(widget->windowTitle());
|
||||
action->setText(widget->windowTitle());
|
||||
QAction* action = menu->addAction(toolbar->windowTitle());
|
||||
action->setText(toolbar->windowTitle());
|
||||
action->setCheckable(true);
|
||||
action->setChecked(widget->isVisible());
|
||||
connect(action, &QAction::triggered, this, [widget]() {
|
||||
widget->setVisible(!widget->isVisible());
|
||||
action->setChecked(toolbar->isVisible());
|
||||
|
||||
connect(action, &QAction::triggered, this, [toolbar = QPointer<QToolBar>(toolbar)]() {
|
||||
if (!toolbar)
|
||||
return;
|
||||
|
||||
toolbar->setVisible(!toolbar->isVisible());
|
||||
});
|
||||
|
||||
menu->addAction(action);
|
||||
}
|
||||
}
|
||||
@@ -383,7 +396,7 @@ void DockManager::createWindowsMenu(QMenu* menu)
|
||||
if (lhs->displayNameWithoutSuffix() == rhs->displayNameWithoutSuffix())
|
||||
return lhs->displayNameSuffixNumber() < rhs->displayNameSuffixNumber();
|
||||
|
||||
return lhs->displayNameWithoutSuffix() < rhs->displayNameWithoutSuffix();
|
||||
return QtHost::LocaleSensitiveCompare(lhs->displayNameWithoutSuffix(), rhs->displayNameWithoutSuffix()) < 0;
|
||||
});
|
||||
|
||||
for (DebuggerView* widget : add_another_widgets)
|
||||
@@ -472,7 +485,7 @@ void DockManager::createWindowsMenu(QMenu* menu)
|
||||
if (lhs.display_name == rhs.display_name)
|
||||
return lhs.suffix_number < rhs.suffix_number;
|
||||
|
||||
return lhs.display_name < rhs.display_name;
|
||||
return QtHost::LocaleSensitiveCompare(lhs.display_name, rhs.display_name) < 0;
|
||||
});
|
||||
|
||||
for (const DebuggerViewToggle& toggle : toggles)
|
||||
@@ -862,6 +875,24 @@ std::optional<BreakPointCpu> DockManager::cpu()
|
||||
return m_layouts.at(m_current_layout).cpu();
|
||||
}
|
||||
|
||||
DebuggerView* DockManager::focusedViewForNavigation()
|
||||
{
|
||||
if (!m_focused_view_for_navigation)
|
||||
return nullptr;
|
||||
|
||||
return m_focused_view_for_navigation;
|
||||
}
|
||||
|
||||
void DockManager::onFocusedDockWidgetChanged(KDDockWidgets::QtWidgets::DockWidget* widget)
|
||||
{
|
||||
DebuggerView* view = qobject_cast<DebuggerView*>(widget->widget());
|
||||
if (view && view->supportsNavigation() && view != m_focused_view_for_navigation)
|
||||
{
|
||||
m_focused_view_for_navigation = view;
|
||||
emit focusedViewForNavigationChanged();
|
||||
}
|
||||
}
|
||||
|
||||
KDDockWidgets::Core::DockWidget* DockManager::dockWidgetFactory(const QString& name)
|
||||
{
|
||||
if (!g_debugger_window)
|
||||
|
||||
@@ -98,6 +98,14 @@ public:
|
||||
|
||||
std::optional<BreakPointCpu> cpu();
|
||||
|
||||
/// Returns the last focused view that supports back/forward navigation.
|
||||
DebuggerView* focusedViewForNavigation();
|
||||
|
||||
void onFocusedDockWidgetChanged(KDDockWidgets::QtWidgets::DockWidget* widget);
|
||||
|
||||
Q_SIGNALS:
|
||||
void focusedViewForNavigationChanged();
|
||||
|
||||
private:
|
||||
static KDDockWidgets::Core::DockWidget* dockWidgetFactory(const QString& name);
|
||||
static bool dragAboutToStart(KDDockWidgets::Core::Draggable* draggable);
|
||||
@@ -108,4 +116,6 @@ private:
|
||||
DockMenuBar* m_menu_bar = nullptr;
|
||||
|
||||
bool m_layout_locked = true;
|
||||
|
||||
QPointer<DebuggerView> m_focused_view_for_navigation;
|
||||
};
|
||||
|
||||
@@ -82,6 +82,7 @@ const std::vector<DockTables::DefaultDockLayout> DockTables::DEFAULT_DOCK_LAYOUT
|
||||
{"MemorySearchView", DefaultDockGroup::TOP_LEFT},
|
||||
},
|
||||
.toolbars = {
|
||||
"toolBarNavigation",
|
||||
"toolBarDebug",
|
||||
"toolBarFile",
|
||||
},
|
||||
@@ -113,6 +114,7 @@ const std::vector<DockTables::DefaultDockLayout> DockTables::DEFAULT_DOCK_LAYOUT
|
||||
{"MemorySearchView", DefaultDockGroup::TOP_LEFT},
|
||||
},
|
||||
.toolbars = {
|
||||
"toolBarNavigation",
|
||||
"toolBarDebug",
|
||||
"toolBarFile",
|
||||
},
|
||||
|
||||
@@ -82,6 +82,7 @@ DockWidget::DockWidget(
|
||||
: KDDockWidgets::QtWidgets::DockWidget(unique_name, options, layout_saver_options, window_flags)
|
||||
{
|
||||
connect(this, &DockWidget::isOpenChanged, this, &DockWidget::openStateChanged);
|
||||
connect(this, &DockWidget::isFocusedChanged, this, &DockWidget::focusStateChanged);
|
||||
}
|
||||
|
||||
void DockWidget::openStateChanged(bool open)
|
||||
@@ -95,6 +96,12 @@ void DockWidget::openStateChanged(bool open)
|
||||
g_debugger_window->dockManager().destroyDebuggerView(uniqueName());
|
||||
}
|
||||
|
||||
void DockWidget::focusStateChanged(bool focused)
|
||||
{
|
||||
if (focused && g_debugger_window)
|
||||
g_debugger_window->dockManager().onFocusedDockWidgetChanged(this);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
|
||||
DockTitleBar::DockTitleBar(KDDockWidgets::Core::TitleBar* controller, KDDockWidgets::Core::View* parent)
|
||||
|
||||
@@ -63,6 +63,7 @@ public:
|
||||
|
||||
protected:
|
||||
void openStateChanged(bool open);
|
||||
void focusStateChanged(bool focused);
|
||||
};
|
||||
|
||||
class DockTitleBar : public KDDockWidgets::QtWidgets::TitleBar
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
<height>150</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>600</width>
|
||||
<height>300</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string/>
|
||||
</property>
|
||||
@@ -19,7 +25,7 @@
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="nameLabel">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>nameEditor</cstring>
|
||||
@@ -29,7 +35,7 @@
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="cpuLabel">
|
||||
<property name="text">
|
||||
<string>Target</string>
|
||||
<string>Target:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>cpuEditor</cstring>
|
||||
@@ -39,7 +45,7 @@
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="initialStateLabel">
|
||||
<property name="text">
|
||||
<string>Initial State</string>
|
||||
<string>Initial State:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>initialStateEditor</cstring>
|
||||
|
||||
@@ -19,9 +19,11 @@ using namespace QtUtils;
|
||||
/*
|
||||
MemoryViewTable
|
||||
*/
|
||||
void MemoryViewTable::UpdateStartAddress(u32 start)
|
||||
void MemoryViewTable::UpdateStartAddress(u32 start, NavigationHistoryOperation history_operation)
|
||||
{
|
||||
startAddress = start & ~0xF;
|
||||
navigation_history.push(startAddress, history_operation);
|
||||
parent->update();
|
||||
}
|
||||
|
||||
void MemoryViewTable::UpdateSelectedAddress(u32 selected, bool page)
|
||||
@@ -41,6 +43,13 @@ void MemoryViewTable::UpdateSelectedAddress(u32 selected, bool page)
|
||||
else
|
||||
startAddress += 0x10;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
navigation_history.pushWithDelay(startAddress);
|
||||
parent->update();
|
||||
}
|
||||
|
||||
void MemoryViewTable::DrawTable(QPainter& painter, const QPalette& palette, s32 height, DebugInterface& cpu)
|
||||
@@ -684,7 +693,7 @@ MemoryView::MemoryView(const DebuggerViewParameters& parameters)
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(this, &MemoryView::customContextMenuRequested, this, &MemoryView::openContextMenu);
|
||||
|
||||
m_table.UpdateStartAddress(0x100000);
|
||||
m_table.UpdateStartAddress(0x100000, NavigationHistoryOperation::INSTANT_PUSH);
|
||||
|
||||
receiveEvent<DebuggerEvents::Refresh>([this](const DebuggerEvents::Refresh& event) -> bool {
|
||||
update();
|
||||
@@ -723,7 +732,10 @@ bool MemoryView::fromJson(const JsonValueWrapper& json)
|
||||
|
||||
auto start_address = json.value().FindMember("startAddress");
|
||||
if (start_address != json.value().MemberEnd() && start_address->value.IsUint())
|
||||
m_table.UpdateStartAddress(start_address->value.GetUint());
|
||||
{
|
||||
m_table.navigation_history.clear();
|
||||
m_table.UpdateStartAddress(start_address->value.GetUint(), NavigationHistoryOperation::INSTANT_PUSH);
|
||||
}
|
||||
|
||||
auto view_type = json.value().FindMember("viewType");
|
||||
if (view_type != json.value().MemberEnd() && view_type->value.IsInt())
|
||||
@@ -746,6 +758,40 @@ bool MemoryView::fromJson(const JsonValueWrapper& json)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemoryView::supportsNavigation()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemoryView::canNavigateBack()
|
||||
{
|
||||
return m_table.navigation_history.canGoBack();
|
||||
}
|
||||
|
||||
bool MemoryView::canNavigateForward()
|
||||
{
|
||||
return m_table.navigation_history.canGoForward();
|
||||
}
|
||||
|
||||
void MemoryView::navigateBack()
|
||||
{
|
||||
std::optional<u32> address = m_table.navigation_history.back();
|
||||
if (!address.has_value())
|
||||
return;
|
||||
|
||||
m_table.UpdateStartAddress(*address, NavigationHistoryOperation::NO_PUSH);
|
||||
}
|
||||
|
||||
void MemoryView::navigateForward()
|
||||
{
|
||||
std::optional<u32> address = m_table.navigation_history.forward();
|
||||
if (!address.has_value())
|
||||
return;
|
||||
|
||||
m_table.UpdateStartAddress(*address, NavigationHistoryOperation::NO_PUSH);
|
||||
}
|
||||
|
||||
|
||||
void MemoryView::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
QPainter painter(this);
|
||||
@@ -928,17 +974,20 @@ void MemoryView::wheelEvent(QWheelEvent* event)
|
||||
{
|
||||
if (event->angleDelta().y() < 0)
|
||||
{
|
||||
m_table.UpdateStartAddress(m_table.startAddress + 0x10);
|
||||
m_table.UpdateStartAddress(m_table.startAddress + 0x10, NavigationHistoryOperation::DELAYED_PUSH);
|
||||
}
|
||||
else if (event->angleDelta().y() > 0)
|
||||
{
|
||||
m_table.UpdateStartAddress(m_table.startAddress - 0x10);
|
||||
m_table.UpdateStartAddress(m_table.startAddress - 0x10, NavigationHistoryOperation::DELAYED_PUSH);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
void MemoryView::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
// Alt is used for the global navigation shortcuts.
|
||||
if (event->modifiers() & Qt::AltModifier)
|
||||
return;
|
||||
|
||||
if (!m_table.KeyPress(event->key(), event->text().size() ? event->text()[0] : '\0', cpu()))
|
||||
{
|
||||
switch (event->key())
|
||||
@@ -960,9 +1009,8 @@ void MemoryView::keyPressEvent(QKeyEvent* event)
|
||||
|
||||
void MemoryView::gotoAddress(u32 address)
|
||||
{
|
||||
m_table.UpdateStartAddress(address & ~0xF);
|
||||
m_table.UpdateStartAddress(address & ~0xF, NavigationHistoryOperation::INSTANT_PUSH);
|
||||
m_table.selectedAddress = address;
|
||||
update();
|
||||
setFocus();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "ui_MemoryView.h"
|
||||
|
||||
#include "Debugger/DebuggerView.h"
|
||||
#include "Debugger/NavigationHistoryStack.h"
|
||||
|
||||
#include "DebugTools/DebugInterface.h"
|
||||
#include "DebugTools/DisassemblyManager.h"
|
||||
@@ -93,7 +94,9 @@ public:
|
||||
u32 selectedAddress = 0;
|
||||
s32 selectedIndex = 0;
|
||||
|
||||
void UpdateStartAddress(u32 start);
|
||||
NavigationHistoryStack<u32> navigation_history;
|
||||
|
||||
void UpdateStartAddress(u32 start, NavigationHistoryOperation history_operation);
|
||||
void UpdateSelectedAddress(u32 selected, bool page = false);
|
||||
void DrawTable(QPainter& painter, const QPalette& palette, s32 height, DebugInterface& cpu);
|
||||
void SelectAt(QPoint pos);
|
||||
@@ -136,6 +139,12 @@ public:
|
||||
void toJson(JsonValueWrapper& json) override;
|
||||
bool fromJson(const JsonValueWrapper& json) override;
|
||||
|
||||
bool supportsNavigation() override;
|
||||
bool canNavigateBack() override;
|
||||
bool canNavigateForward() override;
|
||||
void navigateBack() override;
|
||||
void navigateForward() override;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
void mousePressEvent(QMouseEvent* event) override;
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Debugger/DebuggerWindow.h"
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
#include <deque>
|
||||
|
||||
enum class NavigationHistoryOperation
|
||||
{
|
||||
INSTANT_PUSH,
|
||||
DELAYED_PUSH,
|
||||
NO_PUSH
|
||||
};
|
||||
|
||||
/// Data structure for storing navigation history, to be used for the back and
|
||||
/// forward buttons.
|
||||
template <typename Element>
|
||||
class NavigationHistoryStack
|
||||
{
|
||||
public:
|
||||
NavigationHistoryStack()
|
||||
: m_position(m_elements.end())
|
||||
{
|
||||
m_timer.setInterval(DELAY_MILLISECONDS);
|
||||
|
||||
QObject::connect(&m_timer, &QTimer::timeout, [this]() {
|
||||
pushInstantly(std::move(m_pending));
|
||||
m_timer.stop();
|
||||
});
|
||||
}
|
||||
|
||||
NavigationHistoryStack(Element element)
|
||||
: NavigationHistoryStack()
|
||||
{
|
||||
pushInstantly(std::move(element));
|
||||
}
|
||||
|
||||
NavigationHistoryStack(const NavigationHistoryStack<Element>&) = delete;
|
||||
NavigationHistoryStack<Element>& operator=(const NavigationHistoryStack<Element>&) = delete;
|
||||
|
||||
NavigationHistoryStack(NavigationHistoryStack<Element>&&) = delete;
|
||||
NavigationHistoryStack<Element>& operator=(NavigationHistoryStack<Element>&&) = delete;
|
||||
|
||||
/// Push an element onto the stack.
|
||||
void push(Element element, NavigationHistoryOperation operation)
|
||||
{
|
||||
switch (operation)
|
||||
{
|
||||
case NavigationHistoryOperation::INSTANT_PUSH:
|
||||
pushInstantly(std::move(element));
|
||||
break;
|
||||
case NavigationHistoryOperation::DELAYED_PUSH:
|
||||
pushWithDelay(std::move(element));
|
||||
break;
|
||||
case NavigationHistoryOperation::NO_PUSH:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// Wait a second, and then push an element onto the stack. If another
|
||||
/// element is pushed, then that will take priority. This is useful if we're
|
||||
/// storing a scroll position, and don't want the stack to be spammed with
|
||||
/// new values when the user scrolls, for example.
|
||||
void pushWithDelay(Element element)
|
||||
{
|
||||
m_pending = std::move(element);
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
/// Push an element onto the stack instantly.
|
||||
void pushInstantly(Element element)
|
||||
{
|
||||
m_timer.stop();
|
||||
|
||||
if (m_position != m_elements.end() && element == *(m_position - 1))
|
||||
return;
|
||||
|
||||
updateNavigationButtons();
|
||||
|
||||
m_elements.erase(m_position, m_elements.end());
|
||||
m_elements.push_back(std::move(element));
|
||||
|
||||
if (m_elements.size() > MAX_ELEMENTS)
|
||||
m_elements.pop_front();
|
||||
|
||||
m_position = m_elements.end();
|
||||
}
|
||||
|
||||
/// Should to user have an option to go back?
|
||||
bool canGoBack() const
|
||||
{
|
||||
return m_elements.begin() != m_elements.end() && m_position > m_elements.begin() + 1;
|
||||
}
|
||||
|
||||
/// Should the user have an option to go forward?
|
||||
bool canGoForward() const
|
||||
{
|
||||
return m_position != m_elements.end();
|
||||
}
|
||||
|
||||
// Retrieve the current element.
|
||||
std::optional<Element> current() const
|
||||
{
|
||||
if (m_position == m_elements.begin())
|
||||
return std::nullopt;
|
||||
|
||||
return *(m_position - 1);
|
||||
}
|
||||
|
||||
/// Go back one.
|
||||
std::optional<Element> back()
|
||||
{
|
||||
updateNavigationButtons();
|
||||
|
||||
if (!canGoBack())
|
||||
return std::nullopt;
|
||||
|
||||
m_position--;
|
||||
return *(m_position - 1);
|
||||
}
|
||||
|
||||
/// Go forward one.
|
||||
std::optional<Element> forward()
|
||||
{
|
||||
updateNavigationButtons();
|
||||
|
||||
if (!canGoForward())
|
||||
return std::nullopt;
|
||||
|
||||
Element element = *m_position;
|
||||
m_position++;
|
||||
return element;
|
||||
}
|
||||
|
||||
/// Remove all elements.
|
||||
void clear()
|
||||
{
|
||||
m_elements.clear();
|
||||
m_position = m_elements.end();
|
||||
m_timer.stop();
|
||||
}
|
||||
|
||||
private:
|
||||
void updateNavigationButtons()
|
||||
{
|
||||
QTimer::singleShot(0, []() {
|
||||
if (g_debugger_window)
|
||||
g_debugger_window->updateNavigationButtons();
|
||||
});
|
||||
}
|
||||
|
||||
std::deque<Element> m_elements;
|
||||
std::deque<Element>::iterator m_position;
|
||||
|
||||
QTimer m_timer;
|
||||
Element m_pending;
|
||||
|
||||
static constexpr int DELAY_MILLISECONDS = 1000;
|
||||
static constexpr size_t MAX_ELEMENTS = 1000;
|
||||
};
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "Debugger/SymbolTree/SymbolTreeModel.h"
|
||||
#include "Debugger/SymbolTree/TypeString.h"
|
||||
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include <QtWidgets/QCheckBox>
|
||||
#include <QtWidgets/QComboBox>
|
||||
#include <QtWidgets/QDoubleSpinBox>
|
||||
@@ -44,12 +46,28 @@ QWidget* SymbolTreeValueDelegate::createEditor(QWidget* parent, const QStyleOpti
|
||||
const ccc::ast::Node& physical_type = *logical_type->physical_type(database).first;
|
||||
QVariant value = node->readValueAsVariant(physical_type, m_cpu, database);
|
||||
|
||||
const ccc::ast::Node& type = *logical_type->physical_type(database).first;
|
||||
switch (type.descriptor)
|
||||
switch (physical_type.descriptor)
|
||||
{
|
||||
case ccc::ast::ARRAY:
|
||||
{
|
||||
const ccc::ast::Array& array = physical_type.as<ccc::ast::Array>();
|
||||
const ccc::ast::Node& element_type = *array.element_type->physical_type(database).first;;
|
||||
|
||||
if (array.element_count > 0 &&
|
||||
element_type.name == "char" &&
|
||||
node->location.type == SymbolTreeLocation::MEMORY &&
|
||||
!value.isNull())
|
||||
{
|
||||
QLineEdit* editor = new QLineEdit(parent);
|
||||
editor->setText(value.toString());
|
||||
result = editor;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ccc::ast::BUILTIN:
|
||||
{
|
||||
const ccc::ast::BuiltIn& builtin = type.as<ccc::ast::BuiltIn>();
|
||||
const ccc::ast::BuiltIn& builtin = physical_type.as<ccc::ast::BuiltIn>();
|
||||
|
||||
switch (builtin.bclass)
|
||||
{
|
||||
@@ -111,7 +129,7 @@ QWidget* SymbolTreeValueDelegate::createEditor(QWidget* parent, const QStyleOpti
|
||||
}
|
||||
case ccc::ast::ENUM:
|
||||
{
|
||||
const ccc::ast::Enum& enumeration = type.as<ccc::ast::Enum>();
|
||||
const ccc::ast::Enum& enumeration = physical_type.as<ccc::ast::Enum>();
|
||||
|
||||
QComboBox* combo_box = new QComboBox(parent);
|
||||
bool named = false;
|
||||
@@ -186,12 +204,30 @@ void SymbolTreeValueDelegate::setModelData(QWidget* editor, QAbstractItemModel*
|
||||
if (!logical_type)
|
||||
return;
|
||||
|
||||
const ccc::ast::Node& type = *logical_type->physical_type(database).first;
|
||||
switch (type.descriptor)
|
||||
const ccc::ast::Node& physical_type = *logical_type->physical_type(database).first;
|
||||
|
||||
switch (physical_type.descriptor)
|
||||
{
|
||||
case ccc::ast::ARRAY:
|
||||
{
|
||||
const ccc::ast::Array& array = physical_type.as<ccc::ast::Array>();
|
||||
const ccc::ast::Node& element_type = *array.element_type->physical_type(database).first;
|
||||
|
||||
QLineEdit* line_edit = qobject_cast<QLineEdit*>(editor);
|
||||
|
||||
if (array.element_count > 0 &&
|
||||
element_type.name == "char" &&
|
||||
node->location.type == SymbolTreeLocation::MEMORY &&
|
||||
line_edit)
|
||||
{
|
||||
value = line_edit->text();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ccc::ast::BUILTIN:
|
||||
{
|
||||
const ccc::ast::BuiltIn& builtin = type.as<ccc::ast::BuiltIn>();
|
||||
const ccc::ast::BuiltIn& builtin = physical_type.as<ccc::ast::BuiltIn>();
|
||||
|
||||
switch (builtin.bclass)
|
||||
{
|
||||
|
||||
@@ -67,7 +67,7 @@ bool SymbolTreeNode::writeToVM(
|
||||
if (logical_type)
|
||||
{
|
||||
const ccc::ast::Node& physical_type = *logical_type->physical_type(database).first;
|
||||
writeValueFromVariant(m_value, physical_type, cpu);
|
||||
writeValueFromVariant(m_value, physical_type, cpu, database);
|
||||
}
|
||||
|
||||
data_changed |= updateDisplayString(cpu, database, display_options);
|
||||
@@ -76,10 +76,29 @@ bool SymbolTreeNode::writeToVM(
|
||||
return data_changed;
|
||||
}
|
||||
|
||||
QVariant SymbolTreeNode::readValueAsVariant(const ccc::ast::Node& physical_type, DebugInterface& cpu, const ccc::SymbolDatabase& database) const
|
||||
QVariant SymbolTreeNode::readValueAsVariant(
|
||||
const ccc::ast::Node& physical_type,
|
||||
DebugInterface& cpu,
|
||||
const ccc::SymbolDatabase& database) const
|
||||
{
|
||||
switch (physical_type.descriptor)
|
||||
{
|
||||
case ccc::ast::ARRAY:
|
||||
{
|
||||
const ccc::ast::Array& array = physical_type.as<ccc::ast::Array>();
|
||||
const ccc::ast::Node& element_type = *array.element_type->physical_type(database).first;
|
||||
|
||||
if (array.element_count > 0 &&
|
||||
element_type.name == "char" &&
|
||||
location.type == SymbolTreeLocation::MEMORY)
|
||||
{
|
||||
std::optional<std::string> string = cpu.ReadString(location.address, 256);
|
||||
if (string.has_value())
|
||||
return QString::fromStdString(*string);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ccc::ast::BUILTIN:
|
||||
{
|
||||
const ccc::ast::BuiltIn& builtIn = physical_type.as<ccc::ast::BuiltIn>();
|
||||
@@ -134,10 +153,36 @@ QVariant SymbolTreeNode::readValueAsVariant(const ccc::ast::Node& physical_type,
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool SymbolTreeNode::writeValueFromVariant(QVariant value, const ccc::ast::Node& physical_type, DebugInterface& cpu) const
|
||||
bool SymbolTreeNode::writeValueFromVariant(
|
||||
QVariant value,
|
||||
const ccc::ast::Node& physical_type,
|
||||
DebugInterface& cpu,
|
||||
const ccc::SymbolDatabase& database) const
|
||||
{
|
||||
if (value.isNull())
|
||||
return false;
|
||||
|
||||
switch (physical_type.descriptor)
|
||||
{
|
||||
case ccc::ast::ARRAY:
|
||||
{
|
||||
const ccc::ast::Array& array = physical_type.as<ccc::ast::Array>();
|
||||
const ccc::ast::Node& element_type = *array.element_type->physical_type(database).first;
|
||||
|
||||
if (array.element_count > 0 &&
|
||||
element_type.name == "char" &&
|
||||
location.type == SymbolTreeLocation::MEMORY)
|
||||
{
|
||||
QByteArray byte_array = value.toString().toLatin1();
|
||||
std::string_view view(
|
||||
byte_array.data(),
|
||||
std::min(static_cast<s32>(byte_array.size()), array.element_count - 1));
|
||||
cpu.WriteString(location.address, view);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
case ccc::ast::BUILTIN:
|
||||
{
|
||||
const ccc::ast::BuiltIn& built_in = physical_type.as<ccc::ast::BuiltIn>();
|
||||
@@ -191,6 +236,7 @@ bool SymbolTreeNode::writeValueFromVariant(QVariant value, const ccc::ast::Node&
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ccc::ast::ENUM:
|
||||
@@ -266,11 +312,14 @@ QString SymbolTreeNode::generateDisplayString(
|
||||
const ccc::ast::Array& array = physical_type.as<ccc::ast::Array>();
|
||||
const ccc::ast::Node& element_type = *array.element_type->physical_type(database).first;
|
||||
|
||||
if (element_type.name == "char" && location.type == SymbolTreeLocation::MEMORY)
|
||||
if (array.element_count > 0 &&
|
||||
element_type.name == "char" &&
|
||||
location.type == SymbolTreeLocation::MEMORY)
|
||||
{
|
||||
char* string = cpu.stringFromPointer(location.address);
|
||||
if (string)
|
||||
return QString("\"%1\"").arg(string);
|
||||
std::optional<std::string> string = cpu.ReadString(
|
||||
location.address, 256, MemoryInterface::ALLOW_LONG_STRINGS);
|
||||
if (string.has_value())
|
||||
return QString("\"%1\"").arg(*string);
|
||||
}
|
||||
|
||||
QString result;
|
||||
@@ -412,9 +461,10 @@ QString SymbolTreeNode::generateDisplayString(
|
||||
|
||||
if (pointer_or_reference.is_pointer && value_type.name == "char")
|
||||
{
|
||||
const char* string = cpu.stringFromPointer(address);
|
||||
if (string)
|
||||
result += QString(" \"%1\"").arg(string);
|
||||
std::optional<std::string> string = cpu.ReadString(
|
||||
address, 256, MemoryInterface::ALLOW_LONG_STRINGS);
|
||||
if (string.has_value())
|
||||
result += QString(" \"%1\"").arg(*string);
|
||||
}
|
||||
else if (depth == 0)
|
||||
{
|
||||
|
||||
@@ -62,11 +62,20 @@ public:
|
||||
const ccc::SymbolDatabase& database,
|
||||
const SymbolTreeDisplayOptions& display_options);
|
||||
|
||||
QVariant readValueAsVariant(const ccc::ast::Node& physical_type, DebugInterface& cpu, const ccc::SymbolDatabase& database) const;
|
||||
bool writeValueFromVariant(QVariant value, const ccc::ast::Node& physical_type, DebugInterface& cpu) const;
|
||||
QVariant readValueAsVariant(
|
||||
const ccc::ast::Node& physical_type,
|
||||
DebugInterface& cpu,
|
||||
const ccc::SymbolDatabase& database) const;
|
||||
|
||||
bool writeValueFromVariant(
|
||||
QVariant value,
|
||||
const ccc::ast::Node& physical_type,
|
||||
DebugInterface& cpu,
|
||||
const ccc::SymbolDatabase& database) const;
|
||||
|
||||
bool updateDisplayString(
|
||||
DebugInterface& cpu, const ccc::SymbolDatabase& database, const SymbolTreeDisplayOptions& display);
|
||||
|
||||
QString generateDisplayString(
|
||||
const ccc::ast::Node& physical_type,
|
||||
DebugInterface& cpu,
|
||||
|
||||
@@ -216,7 +216,7 @@ void LogWindow::createUi()
|
||||
m_newline_on_enter = state == Qt::CheckState::Checked;
|
||||
});
|
||||
|
||||
m_input_hbox = new QHBoxLayout(this);
|
||||
m_input_hbox = new QHBoxLayout;
|
||||
m_input_hbox->addWidget(m_line_input, 1);
|
||||
m_input_hbox->addWidget(m_local_echo_checkbox);
|
||||
m_input_hbox->addWidget(m_newline_on_enter_checkbox);
|
||||
|
||||
@@ -4,10 +4,12 @@
|
||||
#include "QtUtils.h"
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QLocale>
|
||||
#include <QtCore/QtGlobal>
|
||||
#include <QtCore/QMetaObject>
|
||||
#include <QtCore/QStandardPaths>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QDesktopServices>
|
||||
#include <QtGui/QIcon>
|
||||
@@ -15,6 +17,7 @@
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtWidgets/QComboBox>
|
||||
#include <QtWidgets/QDialog>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <QtWidgets/QHeaderView>
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <QtWidgets/QInputDialog>
|
||||
@@ -27,21 +30,35 @@
|
||||
#include <QtWidgets/QTableView>
|
||||
#include <QtWidgets/QTreeView>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#include <QtGui/private/qtx11extras_p.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdlib>
|
||||
#include <map>
|
||||
|
||||
#include "common/CocoaTools.h"
|
||||
#include "common/Console.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/Path.h"
|
||||
#include "common/StringUtil.h"
|
||||
#include "pcsx2/Config.h"
|
||||
#include "QtHost.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include "common/RedtapeWindows.h"
|
||||
#include "common/RedtapeWilCom.h"
|
||||
#include <Shlobj.h>
|
||||
#include <shobjidl.h>
|
||||
#include <comdef.h>
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#endif
|
||||
|
||||
namespace QtUtils
|
||||
@@ -549,4 +566,453 @@ namespace QtUtils
|
||||
const QString flag_path = QStringLiteral("%1/icons/flags/%2.svg").arg(QtHost::GetResourcesBasePath()).arg(country_code.toLower());
|
||||
return QIcon(flag_path);
|
||||
}
|
||||
|
||||
bool IsRunningInFlatpak()
|
||||
{
|
||||
// Checks for the existence of the `.flatpak-info` file which seems to be always present inside flatpak sandboxes.
|
||||
return FileSystem::FileExists("/.flatpak-info");
|
||||
}
|
||||
|
||||
bool IsRunningInAppImage()
|
||||
{
|
||||
// The AppImage runtime sets APPIMAGE environment variable so we can check for that.
|
||||
return std::getenv("APPIMAGE") != nullptr;
|
||||
}
|
||||
|
||||
void CreateShortcut(QWidget* parent, const std::string& name, const std::string& game_path,
|
||||
std::vector<std::string> passed_cli_args, const std::string& custom_args,
|
||||
const std::string& icon_path, bool is_desktop, bool prompt_for_destination)
|
||||
{
|
||||
const auto tr_msg = [](const char* str) {
|
||||
return QCoreApplication::translate("CreateShortcut", str);
|
||||
};
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (name.empty())
|
||||
{
|
||||
Console.Error("Cannot create shortcuts without a name.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Sanitize filename
|
||||
const std::string clean_name = Path::SanitizeFileName(name);
|
||||
std::string clean_path = game_path.empty() ? std::string() : Path::ToNativePath(Path::RealPath(game_path));
|
||||
if (!Path::IsValidFileName(clean_name))
|
||||
{
|
||||
QMessageBox::critical(parent, tr_msg("Failed to create shortcut"), tr_msg("Filename contains illegal character."), QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get path to Desktop or per-user Start Menu\Programs directory
|
||||
// https://superuser.com/questions/1489874/how-can-i-get-the-real-path-of-desktop-in-windows-explorer/1789849#1789849
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath
|
||||
// https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid
|
||||
std::string link_file;
|
||||
if (wil::unique_cotaskmem_string directory; SUCCEEDED(SHGetKnownFolderPath(is_desktop ? FOLDERID_Desktop : FOLDERID_Programs, 0, NULL, &directory)))
|
||||
{
|
||||
std::string directory_utf8 = StringUtil::WideStringToUTF8String(directory.get());
|
||||
|
||||
if (is_desktop)
|
||||
link_file = Path::ToNativePath(fmt::format("{}/{}.lnk", directory_utf8, clean_name));
|
||||
else
|
||||
{
|
||||
const std::string pcsx2_start_menu_dir = Path::ToNativePath(fmt::format("{}/PCSX2", directory_utf8));
|
||||
if (!FileSystem::EnsureDirectoryExists(pcsx2_start_menu_dir.c_str(), false))
|
||||
{
|
||||
QMessageBox::critical(parent, tr_msg("Failed to create shortcut"), tr_msg("Could not create start menu directory."), QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
link_file = Path::ToNativePath(fmt::format("{}/{}.lnk", pcsx2_start_menu_dir, clean_name));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(parent, tr_msg("Failed to create shortcut"), is_desktop ? tr_msg("'Desktop' directory not found") : tr_msg("User's 'Start Menu\\Programs' directory not found"), QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the same shortcut already exists
|
||||
if (prompt_for_destination && FileSystem::FileExists(link_file.c_str()))
|
||||
{
|
||||
QMessageBox::critical(parent, tr_msg("Failed to create shortcut"), tr_msg("A shortcut with the same name already exists."), QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
// Shortcut CmdLine Args
|
||||
bool lossless = true;
|
||||
for (std::string& arg : passed_cli_args)
|
||||
lossless &= EscapeShortcutCommandLine(&arg);
|
||||
if (!clean_path.empty())
|
||||
lossless &= EscapeShortcutCommandLine(&clean_path);
|
||||
|
||||
if (!lossless)
|
||||
{
|
||||
QMessageBox::critical(parent, tr_msg("Failed to create shortcut"), tr_msg("File path contains invalid character(s)."), QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string final_args = StringUtil::JoinString(passed_cli_args.begin(), passed_cli_args.end(), " ");
|
||||
if (!custom_args.empty())
|
||||
{
|
||||
if (!final_args.empty())
|
||||
final_args += ' ';
|
||||
final_args += custom_args;
|
||||
}
|
||||
if (!clean_path.empty())
|
||||
{
|
||||
if (!final_args.empty())
|
||||
final_args += ' ';
|
||||
final_args += fmt::format("-- {}", clean_path);
|
||||
}
|
||||
|
||||
Console.WriteLnFmt("Creating a shortcut '{}' with arguments '{}'", link_file, final_args);
|
||||
|
||||
const auto str_error = [](HRESULT hr) -> std::string {
|
||||
_com_error err(hr);
|
||||
const TCHAR* errMsg = err.ErrorMessage();
|
||||
return fmt::format("{} [{}]", StringUtil::WideStringToUTF8String(errMsg), hr);
|
||||
};
|
||||
|
||||
// Construct the shortcut
|
||||
// https://stackoverflow.com/questions/3906974/how-to-programmatically-create-a-shortcut-using-win32
|
||||
HRESULT res = CoInitialize(NULL);
|
||||
if (FAILED(res))
|
||||
{
|
||||
Console.ErrorFmt("Failed to create shortcut: CoInitialize failed ({})", str_error(res));
|
||||
QMessageBox::critical(parent, tr_msg("Failed to create shortcut"), tr_msg("CoInitialize failed (%1)").arg(QString::fromStdString(str_error(res))), QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
wil::unique_couninitialize_call co_cleanup;
|
||||
|
||||
const auto report_error = [&](const QString& reason) {
|
||||
Console.ErrorFmt("Failed to create shortcut: {}", reason.toStdString());
|
||||
QMessageBox::critical(parent, tr_msg("Failed to create shortcut"), reason, QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
|
||||
};
|
||||
|
||||
wil::com_ptr_nothrow<IShellLink> pShellLink = wil::CoCreateInstanceNoThrow<IShellLink>(CLSID_ShellLink);
|
||||
wil::com_ptr_nothrow<IPersistFile> pPersistFile;
|
||||
|
||||
if (!pShellLink)
|
||||
{
|
||||
report_error(tr_msg("CoCreateInstance failed"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Set path to the executable
|
||||
const std::wstring target_file = StringUtil::UTF8StringToWideString(FileSystem::GetProgramPath());
|
||||
res = pShellLink->SetPath(target_file.c_str());
|
||||
if (FAILED(res))
|
||||
{
|
||||
report_error(tr_msg("SetPath failed (%1)").arg(QString::fromStdString(str_error(res))));
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the working directory
|
||||
const std::wstring working_dir = StringUtil::UTF8StringToWideString(Path::GetDirectory(FileSystem::GetProgramPath()));
|
||||
res = pShellLink->SetWorkingDirectory(working_dir.c_str());
|
||||
if (FAILED(res))
|
||||
{
|
||||
report_error(tr_msg("SetWorkingDirectory failed (%1)").arg(QString::fromStdString(str_error(res))));
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the description (shown as the shortcut's tooltip)
|
||||
const std::wstring description = tr_msg("PlayStation 2 Emulator").toStdWString();
|
||||
res = pShellLink->SetDescription(description.c_str());
|
||||
if (FAILED(res))
|
||||
{
|
||||
report_error(tr_msg("SetDescription failed (%1)").arg(QString::fromStdString(str_error(res))));
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the launch arguments
|
||||
if (!final_args.empty())
|
||||
{
|
||||
const std::wstring target_cli_args = StringUtil::UTF8StringToWideString(final_args);
|
||||
res = pShellLink->SetArguments(target_cli_args.c_str());
|
||||
if (FAILED(res))
|
||||
{
|
||||
report_error(tr_msg("SetArguments failed (%1)").arg(QString::fromStdString(str_error(res))));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the icon
|
||||
std::string final_icon_path;
|
||||
if (!icon_path.empty())
|
||||
{
|
||||
final_icon_path = Path::ToNativePath(icon_path);
|
||||
if (!FileSystem::FileExists(final_icon_path.c_str()))
|
||||
{
|
||||
QMessageBox::critical(parent, tr_msg("Failed to create shortcut"), tr_msg("The selected icon file does not exist."), QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
final_icon_path = Path::ToNativePath(Path::Combine(Path::GetDirectory(FileSystem::GetProgramPath()), "resources/icons/AppIconLarge.ico"));
|
||||
}
|
||||
|
||||
const std::wstring w_icon_path = StringUtil::UTF8StringToWideString(final_icon_path);
|
||||
res = pShellLink->SetIconLocation(w_icon_path.c_str(), 0);
|
||||
if (FAILED(res))
|
||||
{
|
||||
report_error(tr_msg("SetIconLocation failed (%1)").arg(QString::fromStdString(str_error(res))));
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the IPersistFile object to save the shell link
|
||||
res = pShellLink.query_to(&pPersistFile);
|
||||
if (FAILED(res))
|
||||
{
|
||||
report_error(tr_msg("QueryInterface failed (%1)").arg(QString::fromStdString(str_error(res))));
|
||||
return;
|
||||
}
|
||||
|
||||
// Save shortcut link to disk
|
||||
const std::wstring w_link_file = StringUtil::UTF8StringToWideString(link_file);
|
||||
res = pPersistFile->Save(w_link_file.c_str(), TRUE);
|
||||
if (FAILED(res))
|
||||
{
|
||||
report_error(tr_msg("Failed to save the shortcut (%1)").arg(QString::fromStdString(str_error(res))));
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (name.empty())
|
||||
{
|
||||
QMessageBox::critical(parent, tr_msg("Failed to create shortcut"), tr_msg("Cannot create a shortcut without a title."), QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
const bool is_flatpak = IsRunningInFlatpak();
|
||||
|
||||
// Sanitize filename and game path
|
||||
const std::string clean_name = Path::SanitizeFileName(name);
|
||||
std::string clean_path = game_path.empty() ? std::string() : Path::Canonicalize(Path::RealPath(game_path));
|
||||
if (!Path::IsValidFileName(clean_name))
|
||||
{
|
||||
QMessageBox::critical(parent, tr_msg("Failed to create shortcut"), tr_msg("Filename contains illegal character."), QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the executable path
|
||||
std::string executable_path = FileSystem::GetPackagePath();
|
||||
if (executable_path.empty())
|
||||
{
|
||||
QMessageBox::critical(parent, tr_msg("Failed to create shortcut"), tr_msg("Executable path is empty."), QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the destination directory
|
||||
const QString link_dir = QStandardPaths::writableLocation(is_desktop ? QStandardPaths::DesktopLocation : QStandardPaths::ApplicationsLocation);
|
||||
if (link_dir.isEmpty())
|
||||
{
|
||||
QMessageBox::critical(parent, tr_msg("Failed to create shortcut"), tr_msg("Could not determine the shortcut destination directory."), QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
|
||||
return;
|
||||
}
|
||||
const std::string link_path = fmt::format("{}/{}.desktop", link_dir.toStdString(), clean_name);
|
||||
|
||||
std::string icon_name;
|
||||
if (!icon_path.empty())
|
||||
{
|
||||
if (!FileSystem::FileExists(icon_path.c_str()))
|
||||
{
|
||||
QMessageBox::critical(parent, tr_msg("Failed to create shortcut"), tr_msg("The selected icon file does not exist."), QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
|
||||
return;
|
||||
}
|
||||
icon_name = icon_path;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_flatpak) // Flatpak
|
||||
{
|
||||
executable_path = "flatpak run net.pcsx2.PCSX2";
|
||||
icon_name = "net.pcsx2.PCSX2";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy PCSX2 icon
|
||||
icon_name = "PCSX2";
|
||||
const std::string icon_dest = fmt::format("{}/icons/hicolor/512x512/apps/", QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation).toStdString());
|
||||
const std::string icon_path_dest = fmt::format("{}/{}.png", icon_dest, icon_name);
|
||||
if (FileSystem::EnsureDirectoryExists(icon_dest.c_str(), true))
|
||||
FileSystem::CopyFilePath(Path::Combine(EmuFolders::Resources, "icons/AppIconLarge.png").c_str(), icon_path_dest.c_str(), true);
|
||||
}
|
||||
}
|
||||
|
||||
// Shortcut CmdLine Args
|
||||
bool lossless = true;
|
||||
for (std::string& arg : passed_cli_args)
|
||||
lossless &= EscapeShortcutCommandLine(&arg);
|
||||
if (!is_flatpak)
|
||||
lossless &= EscapeShortcutCommandLine(&executable_path);
|
||||
if (!clean_path.empty())
|
||||
lossless &= EscapeShortcutCommandLine(&clean_path);
|
||||
|
||||
if (!lossless)
|
||||
{
|
||||
QMessageBox::critical(parent, tr_msg("Failed to create shortcut"), tr_msg("File path contains invalid character(s)."), QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string cmdline = StringUtil::JoinString(passed_cli_args.begin(), passed_cli_args.end(), " ");
|
||||
|
||||
// Assembling the .desktop file
|
||||
std::string final_args = executable_path;
|
||||
if (!cmdline.empty())
|
||||
final_args += fmt::format(" {}", cmdline);
|
||||
if (!custom_args.empty())
|
||||
final_args += fmt::format(" {}", custom_args);
|
||||
if (!clean_path.empty())
|
||||
final_args += fmt::format(" -- {}", clean_path);
|
||||
std::string file_content =
|
||||
"[Desktop Entry]\n"
|
||||
"Version=1.0\n"
|
||||
"Type=Application\n"
|
||||
"Terminal=false\n"
|
||||
"StartupWMClass=pcsx2-qt\n"
|
||||
"Exec=" +
|
||||
final_args + "\n" +
|
||||
"Name=" +
|
||||
name + "\n" +
|
||||
"GenericName=PlayStation 2 Emulator\n"
|
||||
"Icon=" +
|
||||
icon_name + "\n" +
|
||||
"Comment=Sony PlayStation 2 Emulator\n"
|
||||
"Keywords=game;emulator;\n"
|
||||
"Categories=Game;Emulator;\n";
|
||||
std::string_view sv(file_content);
|
||||
|
||||
QString final_path = QString::fromStdString(link_path);
|
||||
if (prompt_for_destination)
|
||||
{
|
||||
const QString filter(tr_msg("Desktop Shortcut Files (*.desktop)"));
|
||||
final_path = QDir::toNativeSeparators(QFileDialog::getSaveFileName(parent, tr_msg("Select Shortcut Save Destination"), final_path, filter));
|
||||
if (final_path.isEmpty())
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::string link_dir(Path::GetDirectory(link_path));
|
||||
if (!link_dir.empty() && !FileSystem::EnsureDirectoryExists(link_dir.c_str(), true))
|
||||
{
|
||||
QMessageBox::critical(parent, tr_msg("Failed to create shortcut"), tr_msg("Could not create the shortcut directory."), QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Write to .desktop file
|
||||
if (!FileSystem::WriteStringToFile(final_path.toStdString().c_str(), sv))
|
||||
{
|
||||
QMessageBox::critical(parent, tr_msg("Failed to create shortcut"), tr_msg("Failed to create .desktop file"), QMessageBox::StandardButton::Ok, QMessageBox::StandardButton::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
if (chmod(final_path.toStdString().c_str(), S_IRWXU) != 0) // enables user to execute file
|
||||
Console.ErrorFmt("Failed to change file permissions for .desktop file: {} ({})", strerror(errno), errno);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool EscapeShortcutCommandLine(std::string* arg)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (!arg->empty() && arg->find_first_of(" \t\n\v\"") == std::string::npos)
|
||||
return true;
|
||||
|
||||
std::string temp;
|
||||
temp.reserve(arg->length() + 10);
|
||||
temp += '"';
|
||||
|
||||
for (auto it = arg->begin();; ++it)
|
||||
{
|
||||
int backslash_count = 0;
|
||||
while (it != arg->end() && *it == '\\')
|
||||
{
|
||||
++it;
|
||||
++backslash_count;
|
||||
}
|
||||
|
||||
if (it == arg->end())
|
||||
{
|
||||
temp.append(backslash_count * 2, '\\');
|
||||
break;
|
||||
}
|
||||
|
||||
if (*it == '"')
|
||||
{
|
||||
temp.append(backslash_count * 2 + 1, '\\');
|
||||
temp += '"';
|
||||
}
|
||||
else
|
||||
{
|
||||
temp.append(backslash_count, '\\');
|
||||
temp += *it;
|
||||
}
|
||||
}
|
||||
|
||||
temp += '"';
|
||||
*arg = std::move(temp);
|
||||
return true;
|
||||
#else
|
||||
const char* carg = arg->c_str();
|
||||
const char* cend = carg + arg->size();
|
||||
const char* RESERVED_CHARS = " \t\n\\\"'\\\\><~|%&;$*?#()`"
|
||||
"\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0d\x0e\x0f"
|
||||
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f";
|
||||
const char* next = carg + std::strcspn(carg, RESERVED_CHARS);
|
||||
|
||||
if (next == cend)
|
||||
return true; // No escaping needed, don't modify
|
||||
|
||||
bool lossless = true;
|
||||
std::string temp = "\"";
|
||||
const char* NOT_VALID_IN_QUOTE = "%`$\"\\\n"
|
||||
"\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0d\x0e\x0f"
|
||||
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f";
|
||||
|
||||
while (true)
|
||||
{
|
||||
next = carg + std::strcspn(carg, NOT_VALID_IN_QUOTE);
|
||||
temp.append(carg, next);
|
||||
carg = next;
|
||||
|
||||
if (carg == cend)
|
||||
break;
|
||||
|
||||
switch (*carg)
|
||||
{
|
||||
case '"':
|
||||
case '`':
|
||||
temp.push_back('\\');
|
||||
temp.push_back(*carg);
|
||||
break;
|
||||
case '\\':
|
||||
temp.append("\\\\\\\\");
|
||||
break;
|
||||
case '$':
|
||||
temp.push_back('\\');
|
||||
temp.push_back('\\');
|
||||
temp.push_back(*carg);
|
||||
break;
|
||||
case '%':
|
||||
temp.push_back('%');
|
||||
temp.push_back(*carg);
|
||||
break;
|
||||
default:
|
||||
temp.push_back(' ');
|
||||
lossless = false;
|
||||
break;
|
||||
}
|
||||
++carg;
|
||||
}
|
||||
|
||||
temp.push_back('"');
|
||||
*arg = std::move(temp);
|
||||
return lossless;
|
||||
#endif
|
||||
}
|
||||
} // namespace QtUtils
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
#include <QtGui/QScreen>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "common/Console.h"
|
||||
|
||||
@@ -209,4 +211,19 @@ namespace QtUtils
|
||||
/// Gets a flag icon for a given language code
|
||||
/// Returns an empty QIcon if no flag is available for the language
|
||||
QIcon GetFlagIconForLanguage(const QString& language_code);
|
||||
|
||||
/// Returns true if PCSX2 is running inside a Flatpak sandbox.
|
||||
bool IsRunningInFlatpak();
|
||||
|
||||
/// Returns true if PCSX2 is running from an AppImage.
|
||||
bool IsRunningInAppImage();
|
||||
|
||||
/// Creates a desktop or launcher (Start Menu / applications) shortcuts
|
||||
void CreateShortcut(QWidget* parent, const std::string& name, const std::string& game_path,
|
||||
std::vector<std::string> passed_cli_args, const std::string& custom_args,
|
||||
const std::string& icon_path, bool is_desktop, bool prompt_for_destination = true);
|
||||
|
||||
/// Escapes the given string for use as a shortcut command line argument.
|
||||
/// Returns whether the escaping operation was lossless.
|
||||
bool EscapeShortcutCommandLine(std::string* arg);
|
||||
} // namespace QtUtils
|
||||
|
||||
@@ -262,20 +262,14 @@ void EmulationSettingsWidget::onOptimalFramePacingChanged()
|
||||
const QSignalBlocker sb(m_ui.maxFrameLatency);
|
||||
|
||||
std::optional<int> value;
|
||||
bool optimal = false;
|
||||
if (m_ui.optimalFramePacing->checkState() != Qt::PartiallyChecked)
|
||||
{
|
||||
optimal = m_ui.optimalFramePacing->isChecked();
|
||||
value = optimal ? 0 : DEFAULT_FRAME_LATENCY;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = dialog()->getEffectiveIntValue("EmuCore/GS", "VsyncQueueSize", DEFAULT_FRAME_LATENCY);
|
||||
optimal = (value == 0);
|
||||
}
|
||||
value = m_ui.optimalFramePacing->isChecked() ? 0 : DEFAULT_FRAME_LATENCY;
|
||||
|
||||
const int latency = value.value_or(Host::GetBaseIntSettingValue("EmuCore/GS", "VsyncQueueSize", DEFAULT_FRAME_LATENCY));
|
||||
const bool optimal = (latency == 0);
|
||||
|
||||
m_ui.maxFrameLatency->setMinimum(optimal ? 0 : 1);
|
||||
m_ui.maxFrameLatency->setValue(optimal ? 0 : DEFAULT_FRAME_LATENCY);
|
||||
m_ui.maxFrameLatency->setValue(latency);
|
||||
m_ui.maxFrameLatency->setEnabled(!dialog()->isPerGameSettings() && !m_ui.optimalFramePacing->isChecked());
|
||||
|
||||
dialog()->setIntSettingValue("EmuCore/GS", "VsyncQueueSize", value);
|
||||
@@ -300,7 +294,7 @@ void EmulationSettingsWidget::updateOptimalFramePacing()
|
||||
}
|
||||
|
||||
m_ui.maxFrameLatency->setMinimum(optimal ? 0 : 1);
|
||||
m_ui.maxFrameLatency->setValue(optimal ? 0 : value);
|
||||
m_ui.maxFrameLatency->setValue(value);
|
||||
}
|
||||
|
||||
void EmulationSettingsWidget::updateUseVSyncForTimingEnabled()
|
||||
|
||||
@@ -19,7 +19,7 @@ FolderSettingsWidget::FolderSettingsWidget(SettingsWindow* settings_dialog, QWid
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.organizeSnapshotsByGame, "EmuCore/GS", "OrganizeScreenshotsByGame", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.organizeVideoDumpByGame, "EmuCore/GS", "OrganizeVideoCaptureByGame", false);
|
||||
SettingWidgetBinder::BindWidgetToFolderSetting(sif, m_ui.saveStates, m_ui.saveStatesBrowse, m_ui.saveStatesOpen, m_ui.saveStatesReset,
|
||||
"Folders", "SaveStates", Path::Combine(EmuFolders::DataRoot, "sstates"));
|
||||
"Folders", "Savestates", Path::Combine(EmuFolders::DataRoot, "sstates"));
|
||||
SettingWidgetBinder::BindWidgetToFolderSetting(sif, m_ui.videoDumpingDirectory, m_ui.videoDumpingDirectoryBrowse, m_ui.videoDumpingDirectoryOpen, m_ui.videoDumpingDirectoryReset,
|
||||
"Folders", "Videos", Path::Combine(EmuFolders::DataRoot, "videos"));
|
||||
dialog()->registerWidgetHelp(m_ui.organizeSnapshotsByGame, tr("Save Snapshots in Game-Specific Folders"), tr("Unchecked"),
|
||||
|
||||
@@ -365,7 +365,6 @@
|
||||
<tabstop>gsDumpCompression</tabstop>
|
||||
<tabstop>texturePreloading</tabstop>
|
||||
<tabstop>exclusiveFullscreenControl</tabstop>
|
||||
<tabstop>rov</tabstop>
|
||||
<tabstop>extendedUpscales</tabstop>
|
||||
<tabstop>spinGPUDuringReadbacks</tabstop>
|
||||
<tabstop>spinCPUDuringReadbacks</tabstop>
|
||||
|
||||
@@ -173,7 +173,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog,
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_upscaling.textureOffsetY, "EmuCore/GS", "UserHacks_TCOffsetY", 0);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_upscaling.alignSprite, "EmuCore/GS", "UserHacks_align_sprite_X", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_upscaling.mergeSprite, "EmuCore/GS", "UserHacks_merge_pp_sprite", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_upscaling.forceEvenSpritePosition, "EmuCore/GS", "UserHacks_forceEvenSpritePosition", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_upscaling.forceEvenSpritePosition, "EmuCore/GS", "UserHacks_ForceEvenSpritePosition", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_upscaling.nativePaletteDraw, "EmuCore/GS", "UserHacks_NativePaletteDraw", false);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user