mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-04-20 00:50:45 +00:00
Compare commits
313 commits
Author | SHA1 | Date | |
---|---|---|---|
|
1f7c4d6f8e | ||
|
90474b023b | ||
|
2188f0c55d | ||
|
fdf74efeaf | ||
|
13525df995 | ||
|
7c9eb023ff | ||
|
45c4d757d2 | ||
|
07205fb788 | ||
|
7ad261c047 | ||
|
7ec7abe60f | ||
|
40886da475 | ||
|
d2cb3cc79f | ||
|
0ea4ef02ca | ||
|
256eb79d53 | ||
|
a8080c05ed | ||
|
a114062d2e | ||
|
c76492b832 | ||
|
378fb29284 | ||
|
94b46e78e8 | ||
|
40513deff7 | ||
|
9cd4a8fd17 | ||
|
70112ffd94 | ||
|
afcf03e807 | ||
|
064b5c5ac0 | ||
|
1a1fe112bf | ||
|
d4026984bb | ||
|
96720e2ed2 | ||
|
f319bb0884 | ||
|
c63df9cab0 | ||
|
b74ab34610 | ||
|
053dcf7890 | ||
|
00384e4021 | ||
|
8e054bfc3e | ||
|
ccf195e726 | ||
|
3ee315c7da | ||
|
3c5383429f | ||
|
74ebea5b34 | ||
|
e8e0f678a9 | ||
|
c9d23fefbc | ||
|
cd7363a551 | ||
|
786adba3aa | ||
|
ccc7f276a1 | ||
|
0be9f16d3d | ||
|
3637f9a758 | ||
|
0474e4a4e9 | ||
|
27e711a3d6 | ||
|
79496131c1 | ||
|
87836a4639 | ||
|
75b245ca54 | ||
|
c0cf6d5d67 | ||
|
556cbf4fa1 | ||
|
c61e0d3266 | ||
|
c33e0ca848 | ||
|
9894b27791 | ||
|
a9a4202840 | ||
|
bb17105d53 | ||
|
84e4035922 | ||
|
643d8d7d2b | ||
|
76625d706e | ||
|
04ecdab2ba | ||
|
ec30ed21d8 | ||
|
159fac2993 | ||
|
47d8091125 | ||
|
500bf1b952 | ||
|
0d8cba6711 | ||
|
8aea22e6c6 | ||
|
60ba33dd40 | ||
|
839b91b0ee | ||
|
69409594bd | ||
|
04e7a303db | ||
|
ec60ebd7f8 | ||
|
0fbcbbcdff | ||
|
5d4a2facbd | ||
|
84cc99d559 | ||
|
d91c4253e8 | ||
|
3578d4353d | ||
|
d2efa1c9af | ||
|
989c30e31d | ||
|
27c412055e | ||
|
e3c8d26760 | ||
|
294d162b06 | ||
|
1ed01b3033 | ||
|
6d814f6c41 | ||
|
26624ab90f | ||
|
be2fa70e4d | ||
|
3e66c9d1fb | ||
|
e8984c25f3 | ||
|
f833e24da6 | ||
|
6755ecf590 | ||
|
7c768b7587 | ||
|
82ceca620b | ||
|
d0e8c83687 | ||
|
0bbbf27b23 | ||
|
c1689345f4 | ||
|
474dfcb524 | ||
|
eb5a9a15d8 | ||
|
853f832cbd | ||
|
049784f0df | ||
|
b57de78150 | ||
|
579af5515b | ||
|
cebdb35774 | ||
|
05eee80292 | ||
|
125bfbb175 | ||
|
ac62a89259 | ||
|
3cd8a93432 | ||
|
23a3ee0cc5 | ||
|
a4e23e6fd9 | ||
|
21f0b33379 | ||
|
4ce6f058e6 | ||
|
67aeeacccb | ||
|
8f6f3b1e3f | ||
|
4e46f83b32 | ||
|
5ca731d1f1 | ||
|
3ba7edd995 | ||
|
a33d6b091d | ||
|
3f74954db6 | ||
|
3d3e7e9c98 | ||
|
404450d186 | ||
|
b607eb4d42 | ||
|
ec18568bd7 | ||
|
4b18825805 | ||
|
aa43b2df8c | ||
|
971b2d1360 | ||
|
4fe0d0be6b | ||
|
39c81b8afc | ||
|
ae21db84d8 | ||
|
720223bcb0 | ||
|
c780c866e9 | ||
|
b55452f20c | ||
|
074c938c56 | ||
|
a7551dae26 | ||
|
29d95e3388 | ||
|
c27ce2a7bf | ||
|
9e07dc2485 | ||
|
1d6d17beb3 | ||
|
f995839e4b | ||
|
b23bfb6ee2 | ||
|
f7934b1936 | ||
|
43eeb49fad | ||
|
b8a6f2b760 | ||
|
42b578b2bb | ||
|
5030d9d046 | ||
|
5440d6b94a | ||
|
e71fce25a4 | ||
|
9e3de04388 | ||
|
33fd4579fb | ||
|
89719b4a27 | ||
|
1fdb0f81e6 | ||
|
50a0609af8 | ||
|
d6da3a5362 | ||
|
13bd293c17 | ||
|
fd4a7abc58 | ||
|
05b2b3928a | ||
|
4e22fc255d | ||
|
c6338f0c36 | ||
|
9029beb87d | ||
|
ded38bbf44 | ||
|
f7b9c8c518 | ||
|
dbcd1d0d6d | ||
|
b6f69da662 | ||
|
a4511bd7f0 | ||
|
54e32cb79d | ||
|
de20289cb1 | ||
|
1ca588ef5e | ||
|
726e4616db | ||
|
0a346113dd | ||
|
a21e1f27ed | ||
|
14a832c710 | ||
|
27d1a87ab0 | ||
|
9079f610d0 | ||
|
9e127cf71f | ||
|
49b4e97f5d | ||
|
4025b1aa46 | ||
|
f70ec69470 | ||
|
02e6784111 | ||
|
dfd2cb3700 | ||
|
7211e06c8c | ||
|
290c9ecabe | ||
|
8d03b22a2f | ||
|
c388d5b31d | ||
|
d3a98cf66b | ||
|
8c8488657c | ||
|
cdf1cba106 | ||
|
cbd1665239 | ||
|
c3d7def63d | ||
|
ea94f56f18 | ||
|
9d68b161bd | ||
|
4293f1e73a | ||
|
91103f907b | ||
|
8f0906704a | ||
|
9522e9e490 | ||
|
bc168a7bfa | ||
|
5a0def601a | ||
|
f931f9c8bc | ||
|
67052ec008 | ||
|
7a3ebc7e99 | ||
|
fdeabf515c | ||
|
60f0fdd969 | ||
|
661761f047 | ||
|
5d201fce9a | ||
|
6a3a081b4b | ||
|
5e8ffa3630 | ||
|
baa4d8153a | ||
|
032b66b062 | ||
|
d4b4266758 | ||
|
b95ce55edc | ||
|
af7b8f6c61 | ||
|
05499dd331 | ||
|
0c6c51f903 | ||
|
6b8cd8fdf9 | ||
|
1825aa9723 | ||
|
4cb319216f | ||
|
03d22045ad | ||
|
5518640473 | ||
|
37b0e7a1f3 | ||
|
65abf0188a | ||
|
94fc9a96ae | ||
|
5055774a3d | ||
|
9f6c455b45 | ||
|
808f748f4a | ||
|
58363c6696 | ||
|
c7f74a3fa6 | ||
|
3314fc941e | ||
|
5d21429c36 | ||
|
27b41be951 | ||
|
42d5958d98 | ||
|
6ff7413b65 | ||
|
e21e057b04 | ||
|
24888cc3c1 | ||
|
e87bcfb906 | ||
|
8b9f506a50 | ||
|
12fa246a6d | ||
|
e0ea452e9a | ||
|
ddda42244d | ||
|
f856be3512 | ||
|
3f4efa05a1 | ||
|
4981c8b972 | ||
|
53e93824ca | ||
|
9700eb6baf | ||
|
38843f0f33 | ||
|
c0eda78e43 | ||
|
0ea0dbf4ac | ||
|
ccc9027b1a | ||
|
0babeb62c1 | ||
|
d73f94d034 | ||
|
a09cbe20bd | ||
|
c3638d6c9a | ||
|
6fd9e0ecc4 | ||
|
03cb2be1e6 | ||
|
1f0b9904ea | ||
|
b64ae0ed6e | ||
|
b31d187166 | ||
|
af51dfbed4 | ||
|
67b2bc80ac | ||
|
be83c229e0 | ||
|
1b7ceada59 | ||
|
dce9415411 | ||
|
1f147f2fa8 | ||
|
f5eb462fc1 | ||
|
12f4384a5f | ||
|
61bba6c6fd | ||
|
19a119417c | ||
|
ba89fa6ca6 | ||
|
fc2d44f43c | ||
|
bc7567fd30 | ||
|
2ff7e8e6d0 | ||
|
d5dad22f8d | ||
|
b5fe2df7f8 | ||
|
d226454821 | ||
|
f116fb44eb | ||
|
db110ddc7e | ||
|
2c82f906e1 | ||
|
da8ee87f37 | ||
|
17603050b6 | ||
|
4f1e668eb7 | ||
|
d9de3ea0df | ||
|
e905ae1e09 | ||
|
4f52c04b3b | ||
|
07ee830712 | ||
|
b74d1a5247 | ||
|
c719a18d54 | ||
|
b134bb1770 | ||
|
993365cc6d | ||
|
c49a703467 | ||
|
b26be3ff5d | ||
|
8d5d86cbaf | ||
|
aae0524687 | ||
|
15a5f65fdf | ||
|
14db96211b | ||
|
091b3898c9 | ||
|
8c233f78c3 | ||
|
6408cc7099 | ||
|
e8eb810c01 | ||
|
39d2c7dbb4 | ||
|
219b1b93fb | ||
|
2c212ae0b2 | ||
|
5ace09caac | ||
|
667ddafd83 | ||
|
ea6b135631 | ||
|
4196a6104a | ||
|
711d07561c | ||
|
fa1132e247 | ||
|
473a4f3adc | ||
|
d443fdc092 | ||
|
dbba5b5fd5 | ||
|
45a84389db | ||
|
f2ea0b51b5 | ||
|
660412a525 | ||
|
98baf8223b | ||
|
8d3d318b95 | ||
|
5bcb204623 | ||
|
e21479cbd2 | ||
|
676e05ad1f |
245 changed files with 27242 additions and 7196 deletions
63
.github/workflows/linux.yml
vendored
63
.github/workflows/linux.yml
vendored
|
@ -1,63 +0,0 @@
|
|||
name: Testbuild for Linux
|
||||
run-name: testbuild_linux
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
pull_request:
|
||||
types:
|
||||
- edited
|
||||
- opened
|
||||
- synchronize
|
||||
concurrency:
|
||||
# Cancel concurrent workflows for the same PR or commit hash.
|
||||
group: ${{github.workflow}}-${{github.event_name == 'pull_request' && github.head_ref || github.sha}}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build_ubuntu_x86_64:
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- env: ubuntu
|
||||
steps:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install libgl1-mesa-dev libsdl2-dev libopenal-dev libcurl4-openssl-dev \
|
||||
libavformat-dev libswscale-dev libvulkan-dev build-essential
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: |
|
||||
sed -i 's|WITH_AVCODEC:=yes|WITH_AVCODEC:=no|g' Makefile
|
||||
# Public runners come with 2 CPUs.
|
||||
make -j2
|
||||
make -j2 ref_gles1
|
||||
- name: Create testbuild package
|
||||
run: |
|
||||
# Create release directory tree
|
||||
mkdir -p publish/quake2-linux-${{github.sha}}/misc/docs
|
||||
# Copy release assets
|
||||
cp -r release/* publish/quake2-linux-${{github.sha}}/
|
||||
# Copy misc assets
|
||||
cp -r stuff/yq2.cfg publish/quake2-linux-${{github.sha}}/misc/yq2.cfg
|
||||
cp -r stuff/mapfixes publish/quake2-linux-${{github.sha}}/misc
|
||||
cp LICENSE publish/quake2-linux-${{github.sha}}/misc/docs/LICENSE.txt
|
||||
cp README.md publish/quake2-linux-${{github.sha}}/misc/docs/README.txt
|
||||
cp doc/010_index.md publish/quake2-linux-${{github.sha}}/misc/docs/010_index.txt
|
||||
cp doc/020_installation.md publish/quake2-linux-${{github.sha}}/misc/docs/020_installation.txt
|
||||
cp doc/030_configuration.md publish/quake2-linux-${{github.sha}}/misc/docs/030_configuration.txt
|
||||
cp doc/040_cvarlist.md publish/quake2-linux-${{github.sha}}/misc/docs/040_cvarlist.txt
|
||||
cp doc/050_commands.md publish/quake2-linux-${{github.sha}}/misc/docs/050_commands.txt
|
||||
cp doc/060_multiplayer.md publish/quake2-linux-${{github.sha}}/misc/docs/060_multiplayer.txt
|
||||
cp doc/070_packaging.md publish/quake2-linux-${{github.sha}}/misc/docs/070_packaging.txt
|
||||
cp doc/080_contributing.md publish/quake2-linux-${{github.sha}}/misc/docs/080_contributing.txt
|
||||
cp doc/090_filelists.md publish/quake2-linux-${{github.sha}}/misc/docs/090_filelists.md
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: quake2-linux-${{github.sha}}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
63
.github/workflows/linux_aarch64.yml
vendored
Normal file
63
.github/workflows/linux_aarch64.yml
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
name: Testbuild for Linux (aarch64)
|
||||
run-name: testbuild_linux_aarch64
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
pull_request:
|
||||
types:
|
||||
- edited
|
||||
- opened
|
||||
- synchronize
|
||||
concurrency:
|
||||
# Cancel concurrent workflows for the same PR or commit hash.
|
||||
group: ${{github.workflow}}-${{github.event_name == 'pull_request' && github.head_ref || github.sha}}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build_ubuntu_aarch64:
|
||||
runs-on: ubuntu-22.04-arm
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- env: ubuntu
|
||||
steps:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install libgl1-mesa-dev libsdl2-dev libopenal-dev libcurl4-openssl-dev \
|
||||
libavformat-dev libswscale-dev libvulkan-dev build-essential
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: |
|
||||
sed -i 's|WITH_AVCODEC:=yes|WITH_AVCODEC:=no|g' Makefile
|
||||
# Public runners come with 4 CPUs.
|
||||
make -j4
|
||||
make -j4 ref_gles1
|
||||
- name: Create testbuild package
|
||||
run: |
|
||||
# Create release directory tree
|
||||
mkdir -p publish/quake2-linux_aarch64-${{github.sha}}/misc/docs
|
||||
# Copy release assets
|
||||
cp -r release/* publish/quake2-linux_aarch64-${{github.sha}}/
|
||||
# Copy misc assets
|
||||
cp -r stuff/yq2.cfg publish/quake2-linux_aarch64-${{github.sha}}/misc/yq2.cfg
|
||||
cp -r stuff/mapfixes publish/quake2-linux_aarch64-${{github.sha}}/misc
|
||||
cp LICENSE publish/quake2-linux_aarch64-${{github.sha}}/misc/docs/LICENSE.txt
|
||||
cp README.md publish/quake2-linux_aarch64-${{github.sha}}/misc/docs/README.txt
|
||||
cp doc/010_index.md publish/quake2-linux_aarch64-${{github.sha}}/misc/docs/010_index.txt
|
||||
cp doc/020_installation.md publish/quake2-linux_aarch64-${{github.sha}}/misc/docs/020_installation.txt
|
||||
cp doc/030_configuration.md publish/quake2-linux_aarch64-${{github.sha}}/misc/docs/030_configuration.txt
|
||||
cp doc/040_cvarlist.md publish/quake2-linux_aarch64-${{github.sha}}/misc/docs/040_cvarlist.txt
|
||||
cp doc/050_commands.md publish/quake2-linux_aarch64-${{github.sha}}/misc/docs/050_commands.txt
|
||||
cp doc/060_multiplayer.md publish/quake2-linux_aarch64-${{github.sha}}/misc/docs/060_multiplayer.txt
|
||||
cp doc/070_packaging.md publish/quake2-linux_aarch64-${{github.sha}}/misc/docs/070_packaging.txt
|
||||
cp doc/080_contributing.md publish/quake2-linux_aarch64-${{github.sha}}/misc/docs/080_contributing.txt
|
||||
cp doc/090_filelists.md publish/quake2-linux_aarch64-${{github.sha}}/misc/docs/090_filelists.md
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: quake2-linux_aarch64-${{github.sha}}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
63
.github/workflows/linux_x86_64.yml
vendored
Normal file
63
.github/workflows/linux_x86_64.yml
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
name: Testbuild for Linux (x86_64)
|
||||
run-name: testbuild_linux_x86_64
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
pull_request:
|
||||
types:
|
||||
- edited
|
||||
- opened
|
||||
- synchronize
|
||||
concurrency:
|
||||
# Cancel concurrent workflows for the same PR or commit hash.
|
||||
group: ${{github.workflow}}-${{github.event_name == 'pull_request' && github.head_ref || github.sha}}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build_ubuntu_x86_64:
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- env: ubuntu
|
||||
steps:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install libgl1-mesa-dev libsdl2-dev libopenal-dev libcurl4-openssl-dev \
|
||||
libavformat-dev libswscale-dev libvulkan-dev build-essential
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: |
|
||||
sed -i 's|WITH_AVCODEC:=yes|WITH_AVCODEC:=no|g' Makefile
|
||||
# Public runners come with 4 CPUs.
|
||||
make -j4
|
||||
make -j4 ref_gles1
|
||||
- name: Create testbuild package
|
||||
run: |
|
||||
# Create release directory tree
|
||||
mkdir -p publish/quake2-linux_x86_64-${{github.sha}}/misc/docs
|
||||
# Copy release assets
|
||||
cp -r release/* publish/quake2-linux_x86_64-${{github.sha}}/
|
||||
# Copy misc assets
|
||||
cp -r stuff/yq2.cfg publish/quake2-linux_x86_64-${{github.sha}}/misc/yq2.cfg
|
||||
cp -r stuff/mapfixes publish/quake2-linux_x86_64-${{github.sha}}/misc
|
||||
cp LICENSE publish/quake2-linux_x86_64-${{github.sha}}/misc/docs/LICENSE.txt
|
||||
cp README.md publish/quake2-linux_x86_64-${{github.sha}}/misc/docs/README.txt
|
||||
cp doc/010_index.md publish/quake2-linux_x86_64-${{github.sha}}/misc/docs/010_index.txt
|
||||
cp doc/020_installation.md publish/quake2-linux_x86_64-${{github.sha}}/misc/docs/020_installation.txt
|
||||
cp doc/030_configuration.md publish/quake2-linux_x86_64-${{github.sha}}/misc/docs/030_configuration.txt
|
||||
cp doc/040_cvarlist.md publish/quake2-linux_x86_64-${{github.sha}}/misc/docs/040_cvarlist.txt
|
||||
cp doc/050_commands.md publish/quake2-linux_x86_64-${{github.sha}}/misc/docs/050_commands.txt
|
||||
cp doc/060_multiplayer.md publish/quake2-linux_x86_64-${{github.sha}}/misc/docs/060_multiplayer.txt
|
||||
cp doc/070_packaging.md publish/quake2-linux_x86_64-${{github.sha}}/misc/docs/070_packaging.txt
|
||||
cp doc/080_contributing.md publish/quake2-linux_x86_64-${{github.sha}}/misc/docs/080_contributing.txt
|
||||
cp doc/090_filelists.md publish/quake2-linux_x86_64-${{github.sha}}/misc/docs/090_filelists.md
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: quake2-linux_x86_64-${{github.sha}}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
25
.github/workflows/macos.yml
vendored
25
.github/workflows/macos.yml
vendored
|
@ -54,6 +54,29 @@ jobs:
|
|||
cp doc/070_packaging.md publish/quake2-macos-${{github.sha}}/misc/docs/070_packaging.txt
|
||||
cp doc/080_contributing.md publish/quake2-macos-${{github.sha}}/misc/docs/080_contributing.txt
|
||||
cp doc/090_filelists.md publish/quake2-macos-${{github.sha}}/misc/docs/090_filelists.md
|
||||
- name: Create dmg package
|
||||
run: |
|
||||
rm -rf build/macos-dmg
|
||||
mkdir -p build/macos-dmg
|
||||
# start with app bundle template
|
||||
unzip stuff/osx/quake2-appbundle.zip -d build/macos-dmg
|
||||
# add files in root of disk image
|
||||
cp LICENSE README.md build/macos-dmg
|
||||
# copy all binaries to Resources dir
|
||||
cp -r release/* "build/macos-dmg/Quake 2.app/Contents/Resources"
|
||||
# dependency: libSDL2
|
||||
cp -R /opt/homebrew/opt/sdl2/lib/libSDL2-2.0.0.dylib "build/macos-dmg/Quake 2.app/Contents/Resources"
|
||||
install_name_tool -id "libSDL2-2.0.0.dylib" "build/macos-dmg/Quake 2.app/Contents/Resources/libSDL2-2.0.0.dylib"
|
||||
install_name_tool -change "/opt/homebrew/opt/sdl2/lib/libSDL2-2.0.0.dylib" "@executable_path/../Resources/libSDL2-2.0.0.dylib" "build/macos-dmg/Quake 2.app/Contents/Resources/quake2"
|
||||
install_name_tool -change "/opt/homebrew/opt/sdl2/lib/libSDL2-2.0.0.dylib" "@executable_path/../Resources/libSDL2-2.0.0.dylib" "build/macos-dmg/Quake 2.app/Contents/Resources/ref_gl1.dylib"
|
||||
install_name_tool -change "/opt/homebrew/opt/sdl2/lib/libSDL2-2.0.0.dylib" "@executable_path/../Resources/libSDL2-2.0.0.dylib" "build/macos-dmg/Quake 2.app/Contents/Resources/ref_gl3.dylib"
|
||||
install_name_tool -change "/opt/homebrew/opt/sdl2/lib/libSDL2-2.0.0.dylib" "@executable_path/../Resources/libSDL2-2.0.0.dylib" "build/macos-dmg/Quake 2.app/Contents/Resources/ref_gles3.dylib"
|
||||
install_name_tool -change "/opt/homebrew/opt/sdl2/lib/libSDL2-2.0.0.dylib" "@executable_path/../Resources/libSDL2-2.0.0.dylib" "build/macos-dmg/Quake 2.app/Contents/Resources/ref_gl4.dylib"
|
||||
install_name_tool -change "/opt/homebrew/opt/sdl2/lib/libSDL2-2.0.0.dylib" "@executable_path/../Resources/libSDL2-2.0.0.dylib" "build/macos-dmg/Quake 2.app/Contents/Resources/ref_soft.dylib"
|
||||
install_name_tool -change "/opt/homebrew/opt/sdl2/lib/libSDL2-2.0.0.dylib" "@executable_path/../Resources/libSDL2-2.0.0.dylib" "build/macos-dmg/Quake 2.app/Contents/Resources/ref_vk.dylib"
|
||||
# make disk image
|
||||
hdiutil create -srcfolder build/macos-dmg -layout SPUD -fs HFS+ -volname "Yamagi Quake II" "release/yquake2.dmg"
|
||||
cp release/yquake2.dmg publish/quake2-macos-${{github.sha}}/
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
|
@ -65,6 +88,7 @@ jobs:
|
|||
run: |
|
||||
# create archive
|
||||
mkdir yquake2remaster-${{matrix.env}}-${{github.ref_name}}
|
||||
mv publish/quake2-macos-${{github.sha}}/yquake2.dmg yquake2remaster-${{matrix.env}}-${{github.ref_name}}.dmg
|
||||
cp -rv publish/quake2-macos-${{github.sha}}/* yquake2remaster-${{matrix.env}}-${{github.ref_name}}
|
||||
zip -9r yquake2remaster-${{matrix.env}}-${{github.ref_name}}.zip yquake2remaster-${{matrix.env}}-${{github.ref_name}}
|
||||
- name: Upload Release Asset
|
||||
|
@ -73,3 +97,4 @@ jobs:
|
|||
with:
|
||||
files: |
|
||||
yquake2remaster-${{matrix.env}}-${{github.ref_name}}.zip
|
||||
yquake2remaster-${{matrix.env}}-${{github.ref_name}}.dmg
|
||||
|
|
8
.github/workflows/win32.yml
vendored
8
.github/workflows/win32.yml
vendored
|
@ -46,8 +46,8 @@ jobs:
|
|||
shell: msys2 {0}
|
||||
run: |
|
||||
sed -i 's|WITH_AVCODEC:=yes|WITH_AVCODEC:=no|g' Makefile
|
||||
# Public runners come with 2 CPUs.
|
||||
make -j2
|
||||
# Public runners come with 4 CPUs.
|
||||
make -j4
|
||||
- name: Create testbuild package
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
|
@ -70,8 +70,8 @@ jobs:
|
|||
cp doc/080_contributing.md publish/quake2-win32-${{github.sha}}/misc/docs/080_contributing.txt
|
||||
cp doc/090_filelists.md publish/quake2-win32-${{github.sha}}/misc/docs/090_filelists.md
|
||||
# SDL2
|
||||
wget -c https://github.com/libsdl-org/SDL/releases/download/release-2.30.7/SDL2-2.30.7-win32-x86.zip
|
||||
unzip -o SDL2-2.30.7-win32-x86.zip
|
||||
wget -c https://github.com/libsdl-org/SDL/releases/download/release-2.32.0/SDL2-2.32.0-win32-x86.zip
|
||||
unzip -o SDL2-2.32.0-win32-x86.zip
|
||||
cp SDL2.dll publish/quake2-win32-${{github.sha}}/
|
||||
# openal-soft
|
||||
wget -c https://github.com/kcat/openal-soft/releases/download/1.23.1/openal-soft-1.23.1-bin.zip
|
||||
|
|
29
.github/workflows/win64.yml
vendored
29
.github/workflows/win64.yml
vendored
|
@ -1,4 +1,4 @@
|
|||
name: Testbuild for Win64
|
||||
name: Testbuild for Win64 (SDL3)
|
||||
run-name: testbuild_win64
|
||||
on:
|
||||
push:
|
||||
|
@ -8,8 +8,9 @@ on:
|
|||
- "*"
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- opened
|
||||
- synchronize
|
||||
concurrency:
|
||||
# Cancel concurrent workflows for the same PR or commit hash.
|
||||
group: ${{github.workflow}}-${{github.event_name == 'pull_request' && github.head_ref || github.sha}}
|
||||
|
@ -37,17 +38,19 @@ jobs:
|
|||
mingw-w64-${{matrix.env}}-gcc
|
||||
mingw-w64-${{matrix.env}}-make
|
||||
mingw-w64-${{matrix.env}}-openal
|
||||
mingw-w64-${{matrix.env}}-SDL2
|
||||
mingw-w64-${{matrix.env}}-sdl3
|
||||
mingw-w64-${{matrix.env}}-vulkan-headers
|
||||
mingw-w64-${{matrix.env}}-wget
|
||||
mingw-w64-${{matrix.env}}-pkgconf
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: Build
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
# Public runners come with 2 CPUs.
|
||||
make -j2
|
||||
make -j2 ref_gles1
|
||||
sed -i 's|WITH_SDL3:=no|WITH_SDL3:=yes|g' Makefile
|
||||
# Public runners come with 4 CPUs.
|
||||
make -j4
|
||||
make -j4 ref_gles1
|
||||
- name: Create testbuild package
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
|
@ -69,10 +72,10 @@ jobs:
|
|||
cp doc/070_packaging.md publish/quake2-win64-${{github.sha}}/misc/docs/070_packaging.txt
|
||||
cp doc/080_contributing.md publish/quake2-win64-${{github.sha}}/misc/docs/080_contributing.txt
|
||||
cp doc/090_filelists.md publish/quake2-win64-${{github.sha}}/misc/docs/090_filelists.md
|
||||
# SDL2
|
||||
wget -c https://github.com/libsdl-org/SDL/releases/download/release-2.30.7/SDL2-2.30.7-win32-x64.zip
|
||||
unzip -o SDL2-2.30.7-win32-x64.zip
|
||||
cp SDL2.dll publish/quake2-win64-${{github.sha}}/
|
||||
# SDL3
|
||||
wget -c https://github.com/libsdl-org/SDL/releases/download/release-3.2.4/SDL3-3.2.4-win32-x64.zip
|
||||
unzip -o SDL3-3.2.4-win32-x64.zip
|
||||
cp SDL3.dll publish/quake2-win64-${{github.sha}}/
|
||||
# static ffmpeg
|
||||
wget -c https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2024-08-31-12-50/ffmpeg-n7.0.2-6-g7e69129d2f-win64-lgpl-shared-7.0.zip
|
||||
unzip -o ffmpeg-n7.0.2-6-g7e69129d2f-win64-lgpl-shared-7.0.zip
|
||||
|
@ -84,9 +87,9 @@ jobs:
|
|||
unzip -o openal-soft-1.23.1-bin.zip
|
||||
cp openal-soft-1.23.1-bin/bin/Win64/soft_oal.dll publish/quake2-win64-${{github.sha}}/openal32.dll
|
||||
# curl (releases use a custom build curl.dll)
|
||||
wget -c https://curl.se/windows/dl-8.9.1_1/curl-8.9.1_1-win64-mingw.zip
|
||||
unzip -o curl-8.9.1_1-win64-mingw.zip
|
||||
cp curl-8.9.1_1-win64-mingw/bin/libcurl-x64.dll publish/quake2-win64-${{github.sha}}/curl.dll
|
||||
wget -c -O curl-mingw-latest.zip "https://curl.se/windows/latest.cgi?p=win64-mingw.zip"
|
||||
unzip -o curl-mingw-latest.zip
|
||||
cp curl-*-win64-mingw/bin/libcurl-x64.dll publish/quake2-win64-${{github.sha}}/curl.dll
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ ! startsWith(github.ref, 'refs/tags/') }}
|
||||
|
|
180
.github/workflows/win_msvc.yml
vendored
Normal file
180
.github/workflows/win_msvc.yml
vendored
Normal file
|
@ -0,0 +1,180 @@
|
|||
name: Testbuild for x86 and x86_64 Windows with MSVC
|
||||
run-name: testbuild_windows
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
pull_request:
|
||||
types:
|
||||
- edited
|
||||
- opened
|
||||
- synchronize
|
||||
concurrency:
|
||||
# Cancel concurrent workflows for the same PR or commit hash.
|
||||
group: ${{github.workflow}}-${{github.event_name == 'pull_request' && github.head_ref || github.sha}}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build_win_x86_msvc:
|
||||
runs-on: windows-latest
|
||||
defaults:
|
||||
run:
|
||||
# use git bash for for all steps (unless specified otherwise per step)
|
||||
shell: bash
|
||||
strategy:
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
# Download and extract dhewm3-libs
|
||||
# as the repo will be cloned into the directory we're currently in (O_o)
|
||||
# go one directory up to D:\a\yquake2\ (or similar) and put the dhewm3libs there
|
||||
cd ..
|
||||
# https://github.com/dhewm/dhewm3-libs/archive/refs/heads/master.zip
|
||||
# for some reason the following downloads an empty file, so use the other URL I got from
|
||||
# "Copy Download Link" in Firefox (after downloading the file there) instead
|
||||
#curl -o dhewm3libs.zip https://github.com/dhewm/dhewm3-libs/archive/refs/heads/master.zip
|
||||
curl -o dhewm3libs.zip https://codeload.github.com/dhewm/dhewm3-libs/zip/refs/heads/master
|
||||
# only unpack the stuff needed (no x86_64 stuff, no docs from share/)
|
||||
unzip dhewm3libs.zip "dhewm3-libs-master/i686-w64-mingw32/**" -x "dhewm3-libs-master/i686-w64-mingw32/share/**"
|
||||
# vulkan
|
||||
curl -o vulkan_headers.zip https://codeload.github.com/KhronosGroup/Vulkan-Headers/zip/refs/heads/master
|
||||
unzip vulkan_headers.zip "Vulkan-Headers-master/include/**"
|
||||
cp -rv Vulkan-Headers-master/include/* dhewm3-libs-master/i686-w64-mingw32/include/
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: |
|
||||
# build with cmake and visual studio
|
||||
#echo $PWD # /d/a/dhewm3/dhewm3
|
||||
# NOTE: not setting -G "Visual Studio 17 2022" so it just uses the default VS version it can find
|
||||
cmake -A Win32 -DYQUAKE2LIBS="../dhewm3-libs-master/i686-w64-mingw32/" -S . -B build
|
||||
time cmake --build build/ --config RelWithDebInfo
|
||||
- name: Create testbuild package
|
||||
run: |
|
||||
# Create release directory tree
|
||||
export PKGDIR="yquake2-win32-$(git rev-parse --short HEAD)"
|
||||
echo "pkgname=$PKGDIR" >> $GITHUB_ENV
|
||||
mkdir -p publish/$PKGDIR/misc/docs
|
||||
mkdir -p publish/$PKGDIR/baseq2
|
||||
# debug symbols (*.pdb) are put in a separate zip
|
||||
mkdir -p debug-syms/$PKGDIR
|
||||
# Copy release assets
|
||||
cd build/release/RelWithDebInfo/
|
||||
cp *.exe *.dll ../../../publish/$PKGDIR/
|
||||
cp baseq2/*.dll ../../../publish/$PKGDIR/baseq2/
|
||||
cp *.pdb ../../../debug-syms/$PKGDIR/
|
||||
cp baseq2/*.pdb ../../../debug-syms/$PKGDIR/
|
||||
cd ../../..
|
||||
# Copy misc assets
|
||||
cp -r stuff/yq2.cfg publish/$PKGDIR/misc/yq2.cfg
|
||||
cp -r stuff/mapfixes publish/$PKGDIR/misc
|
||||
cp LICENSE publish/$PKGDIR/misc/docs/LICENSE.txt
|
||||
cp README.md publish/$PKGDIR/misc/docs/README.txt
|
||||
cp doc/010_index.md publish/$PKGDIR/misc/docs/010_index.txt
|
||||
cp doc/020_installation.md publish/$PKGDIR/misc/docs/020_installation.txt
|
||||
cp doc/030_configuration.md publish/$PKGDIR/misc/docs/030_configuration.txt
|
||||
cp doc/040_cvarlist.md publish/$PKGDIR/misc/docs/040_cvarlist.txt
|
||||
cp doc/050_commands.md publish/$PKGDIR/misc/docs/050_commands.txt
|
||||
cp doc/060_multiplayer.md publish/$PKGDIR/misc/docs/060_multiplayer.txt
|
||||
cp doc/070_packaging.md publish/$PKGDIR/misc/docs/070_packaging.txt
|
||||
cp doc/080_contributing.md publish/$PKGDIR/misc/docs/080_contributing.txt
|
||||
cp doc/090_filelists.md publish/$PKGDIR/misc/docs/090_filelists.md
|
||||
# copy runtime libraries (SDL, OpenAL, cURL)
|
||||
cd ../dhewm3-libs-master/i686-w64-mingw32/bin/
|
||||
cp OpenAL32.dll SDL2.dll ../../../yquake2remaster/publish/$PKGDIR/
|
||||
cp libcurl-4.dll ../../../yquake2remaster/publish/$PKGDIR/curl.dll
|
||||
cd -
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.pkgname }}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
||||
- name: Upload testbuild debug symbols
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.pkgname }}-debugsyms
|
||||
path: debug-syms/
|
||||
if-no-files-found: error
|
||||
build_win_x86_64_msvc:
|
||||
runs-on: windows-latest
|
||||
defaults:
|
||||
run:
|
||||
# use git bash for for all steps (unless specified otherwise per step)
|
||||
shell: bash
|
||||
strategy:
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
# Download and extract dhewm3-libs
|
||||
#echo $PWD # /d/a/dhewm3/dhewm3
|
||||
# as the repo will be cloned into the directory we're currently in (O_o)
|
||||
# go one directory up to D:\a\dhewm3\ and put the dhewm3libs there
|
||||
cd ..
|
||||
# https://github.com/dhewm/dhewm3-libs/archive/refs/heads/master.zip
|
||||
# for some reason the following downloads an empty file, so use the other URL I got from
|
||||
# "Copy Download Link" in Firefox (after downloading the file there) instead
|
||||
#curl -o dhewm3libs.zip https://github.com/dhewm/dhewm3-libs/archive/refs/heads/master.zip
|
||||
curl -o dhewm3libs.zip https://codeload.github.com/dhewm/dhewm3-libs/zip/refs/heads/master
|
||||
# only unpack the stuff needed (no i686 stuff, no docs from share/)
|
||||
unzip dhewm3libs.zip "dhewm3-libs-master/x86_64-w64-mingw32/**" -x "dhewm3-libs-master/x86_64-w64-mingw32/share/**"
|
||||
# vulkan
|
||||
curl -o vulkan_headers.zip https://codeload.github.com/KhronosGroup/Vulkan-Headers/zip/refs/heads/master
|
||||
unzip vulkan_headers.zip "Vulkan-Headers-master/include/**"
|
||||
cp -rv Vulkan-Headers-master/include/* dhewm3-libs-master/x86_64-w64-mingw32/include/
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: |
|
||||
# build with cmake and visual studio
|
||||
# NOTE: not setting -G "Visual Studio 17 2022" so it just uses the default VS version it can find
|
||||
cmake -A x64 -DYQUAKE2LIBS="../dhewm3-libs-master/x86_64-w64-mingw32/" -S . -B build
|
||||
time cmake --build build/ --config RelWithDebInfo
|
||||
- name: Create testbuild package
|
||||
run: |
|
||||
# Create release directory tree
|
||||
export PKGDIR="yquake2-win64-$(git rev-parse --short HEAD)"
|
||||
echo "pkgname=$PKGDIR" >> $GITHUB_ENV
|
||||
mkdir -p publish/$PKGDIR/misc/docs
|
||||
mkdir -p publish/$PKGDIR/baseq2
|
||||
# debug symbols (*.pdb) are put in a separate zip
|
||||
mkdir -p debug-syms/$PKGDIR
|
||||
# Copy release assets
|
||||
cd build/release/RelWithDebInfo/
|
||||
cp *.exe *.dll ../../../publish/$PKGDIR/
|
||||
cp baseq2/*.dll ../../../publish/$PKGDIR/baseq2/
|
||||
cp *.pdb ../../../debug-syms/$PKGDIR/
|
||||
cp baseq2/*.pdb ../../../debug-syms/$PKGDIR/
|
||||
cd ../../..
|
||||
# Copy misc assets
|
||||
cp -r stuff/yq2.cfg publish/$PKGDIR/misc/yq2.cfg
|
||||
cp -r stuff/mapfixes publish/$PKGDIR/misc
|
||||
cp LICENSE publish/$PKGDIR/misc/docs/LICENSE.txt
|
||||
cp README.md publish/$PKGDIR/misc/docs/README.txt
|
||||
cp doc/010_index.md publish/$PKGDIR/misc/docs/010_index.txt
|
||||
cp doc/020_installation.md publish/$PKGDIR/misc/docs/020_installation.txt
|
||||
cp doc/030_configuration.md publish/$PKGDIR/misc/docs/030_configuration.txt
|
||||
cp doc/040_cvarlist.md publish/$PKGDIR/misc/docs/040_cvarlist.txt
|
||||
cp doc/050_commands.md publish/$PKGDIR/misc/docs/050_commands.txt
|
||||
cp doc/060_multiplayer.md publish/$PKGDIR/misc/docs/060_multiplayer.txt
|
||||
cp doc/070_packaging.md publish/$PKGDIR/misc/docs/070_packaging.txt
|
||||
cp doc/080_contributing.md publish/$PKGDIR/misc/docs/080_contributing.txt
|
||||
cp doc/090_filelists.md publish/$PKGDIR/misc/docs/090_filelists.md
|
||||
# copy runtime libraries (SDL, OpenAL, cURL)
|
||||
cd ../dhewm3-libs-master/x86_64-w64-mingw32/bin/
|
||||
cp OpenAL32.dll SDL2.dll ../../../yquake2remaster/publish/$PKGDIR/
|
||||
cp libcurl-4.dll ../../../yquake2remaster/publish/$PKGDIR/curl.dll
|
||||
cd -
|
||||
- name: Upload testbuild package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.pkgname }}
|
||||
path: publish/
|
||||
if-no-files-found: error
|
||||
- name: Upload testbuild debug symbols
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.pkgname }}-debugsyms
|
||||
path: debug-syms/
|
||||
if-no-files-found: error
|
83
CHANGELOG
83
CHANGELOG
|
@ -1,3 +1,86 @@
|
|||
Quake II 8.41 to 8.50:
|
||||
- Consistent bindings between multiple gamepad types. (by protocultor)
|
||||
- Improved menu navigation with gamepads. (by protocultor)
|
||||
- The SDL 3 code now supports the stable SDL 3 API. Several bugs with
|
||||
SDL 3 were fixed. (by 0lvin, BjossiAlfreds, erysdren and protocultor)
|
||||
- Water warp effect for the OpenGL 1.4 renderer. (by protocultor)
|
||||
- Add a sound backend selector to the menu. (by protocultor)
|
||||
- Fix several problems with HTTP downloads. (by SiemensSchuckert)
|
||||
- Better navigation in input fields in the menu. Support left and right
|
||||
navigation, add support for the ctrl-l,c,x,v shortcuts. (by
|
||||
BjossiAlfreds)
|
||||
- Performance optimizations for the OpenGL 1.4 renderer, especially on
|
||||
embedded and mobile GPUs. Includes an alternative GL ES 1.0 renderer.
|
||||
(by protocultor)
|
||||
- Several fixes to `gl1_stereo`. (by protocultor)
|
||||
- Fix the SDL2 sound backend not working with modern backends.
|
||||
- Make the Windows key bindable. (by Andrew Malchuk)
|
||||
- Support true randomness when shuffling audio tracks. (by
|
||||
apartfromtime)
|
||||
- Fix leaking temporary spawnflags into entities spawned mid-level. (by
|
||||
BjossiAlfreds)
|
||||
- Support the unofficial GL4 renderer lib in the video menu (by atsb)
|
||||
- Clipboard support for the console and better navigation in the console
|
||||
line editor. (By BjossiAlfreds)
|
||||
- Support player models inside pak files in the menu. (by 0lvin)
|
||||
- Support 24 bit PCX files. (by 0lvin)
|
||||
- Check if an entity file matches the current map before loading it.
|
||||
This fixes problems with loading entity files from Quake II against
|
||||
Quake II Remaster maps and the other way round. (by 0lvin)
|
||||
|
||||
Quake 2 8.42RR12:
|
||||
- Fix intro .cin video crash
|
||||
- Update CMakefile with vulkan and gl4 targets
|
||||
- maps: remove spirit of player models on start points
|
||||
- maps: fix yellow wall in daikatana e2m2a
|
||||
- maps: make visibility entity optional
|
||||
- game: fix pickup chainfist
|
||||
- game: fix allocation code for translation and dynamic entities
|
||||
- game: sync target_sky, sync target_camera, target_autosave with ReRelease code
|
||||
- game: Add npc_timeminder from Anachronox
|
||||
- game: add ai_model_scale, misc_player_mannequin from ReRelease code
|
||||
- Add MacOS DMG and use windows x64 SDL3 build
|
||||
- Anachronox: support initial ATD sprites
|
||||
- Anachronox: update MDA load code
|
||||
- SiN: dynamic allocation of sub models list in .def
|
||||
|
||||
Quake 2 8.42RR11:
|
||||
- ReRelease: add support `flashlight` item
|
||||
- ReRelease: add support `trigger_flashlight`
|
||||
- ReRelease: add support `start_item` cvar/map property
|
||||
- ReRelease: add material support for custom footstep sound
|
||||
- ReRelease: add support `health_multiplier`
|
||||
- ReRelease: add support `g_itemsbobeffect` (bob effect for items)
|
||||
- ReRelease: add models scale support
|
||||
- ReRelease: ignore nodraw surfaces
|
||||
- ReRelease: add `g_language` localization cvar
|
||||
- ReRelease: update docs about localization
|
||||
- ReRelease: fix `key_yellow_key` item definition
|
||||
- ReRelease: sort spawn function before search
|
||||
- Other games maps: alternative text for unexisted iamges in menu
|
||||
- Other games maps: convert map suface flags to material type
|
||||
- Other games maps: update entities definition file
|
||||
- Other games maps: support mesh hide mask for player model preview
|
||||
- Other games maps: `choose_cdtrack` triger support
|
||||
- Anachronox: ignore tag name in model for now
|
||||
- DoD: add custom status bar
|
||||
- Daikatana: fix surface flags convert
|
||||
- yquake2: improve backends support @john-tornblom
|
||||
- yquake2: clipboard fix @BjossiAlfreds
|
||||
- yquake2: update cmd parser @devnexen
|
||||
- yquake2: update soft render with unaccelerated render support @john-tornblom
|
||||
- yquake2: fix compile without gl targets @john-tornblom
|
||||
- renders: sync gl4 with gl3 codes
|
||||
- game: use player model id based on max models limit
|
||||
- filesystem: fix pointers arithmetic
|
||||
|
||||
Quake 2 8.42RR10:
|
||||
- client: updated console logic,
|
||||
- game: Update default entities descriptor file,
|
||||
- game: Add hack for next level change in q64/outpost
|
||||
- game: Restore flame effect, currently used only as torch fire in
|
||||
Heretic 2 fire as example.
|
||||
|
||||
Quake 2 8.42RR9:
|
||||
- vk: fixed vulkan call groups,
|
||||
- game: Add ReRelease translated messages (English only)
|
||||
|
|
289
CMakeLists.txt
289
CMakeLists.txt
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
|
||||
|
||||
# Print a message that using the Makefiles is recommended.
|
||||
message(NOTICE: " The CMakeLists.txt is unmaintained. Use the Makefile if possible.")
|
||||
|
@ -65,6 +65,13 @@ option(CURL_SUPPORT "cURL support" ON)
|
|||
option(OPENAL_SUPPORT "OpenAL support" ON)
|
||||
option(SYSTEMWIDE_SUPPORT "Enable systemwide installation of game assets" OFF)
|
||||
option(SDL3_SUPPORT "Build against SDL 3 instead of SDL2" OFF)
|
||||
option(GL1_RENDERER "Build the GL1 renderer" ON)
|
||||
option(GL3_RENDERER "Build the GL3 renderer" ON)
|
||||
option(GL4_RENDERER "Build the GL4 renderer" ON)
|
||||
option(GLES1_RENDERER "Build the GLES1 renderer" OFF)
|
||||
option(GLES3_RENDERER "Build the GLES3 renderer" ON)
|
||||
option(SOFT_RENDERER "Build the software renderer" ON)
|
||||
option(VK_RENDERER "Build the Vulkan renderer" ON)
|
||||
|
||||
set(SYSTEMDIR "" CACHE STRING "Override the system default directory")
|
||||
|
||||
|
@ -164,10 +171,10 @@ unset(cpu)
|
|||
|
||||
# Systemwide installation of game assets.
|
||||
if(${SYSTEMWIDE_SUPPORT})
|
||||
add_definitions(-DSYSTEMWIDE)
|
||||
if(NOT ${SYSTEMDIR} STREQUAL "")
|
||||
add_definitions(-DSYSTEMDIR="${SYSTEMDIR}")
|
||||
endif()
|
||||
add_definitions(-DSYSTEMWIDE)
|
||||
if(NOT ${SYSTEMDIR} STREQUAL "")
|
||||
add_definitions(-DSYSTEMDIR="${SYSTEMDIR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# We need to pass some options to minizip / unzip.
|
||||
|
@ -189,11 +196,13 @@ else()
|
|||
list(APPEND yquake2SDLLinkerFlags ${SDL2_LIBRARY})
|
||||
endif()
|
||||
|
||||
# We need an OpenGL implementation.
|
||||
set(OpenGL_GL_PREFERENCE GLVND)
|
||||
find_package(OpenGL REQUIRED)
|
||||
list(APPEND yquake2IncludeDirectories ${OPENGL_INCLUDE_DIR})
|
||||
list(APPEND yquake2OpenGLLinkerFlags ${OPENGL_LIBRARIES})
|
||||
if(GL1_RENDERER)
|
||||
# We need an OpenGL implementation.
|
||||
set(OpenGL_GL_PREFERENCE GLVND)
|
||||
find_package(OpenGL REQUIRED)
|
||||
list(APPEND yquake2IncludeDirectories ${OPENGL_INCLUDE_DIR})
|
||||
list(APPEND yquake2OpenGLLinkerFlags ${OPENGL_LIBRARIES})
|
||||
endif()
|
||||
|
||||
# backtrace lookup
|
||||
# Some systems like Linux has it within the libc some like the BSD, Haiku ...
|
||||
|
@ -253,7 +262,7 @@ else()
|
|||
list(APPEND yquake2LinkerFlags "-rdynamic")
|
||||
else()
|
||||
list(APPEND yquake2LinkerFlags "-lnetwork")
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
|
||||
list(APPEND yquake2LinkerFlags "-lsocket -lnsl")
|
||||
|
@ -336,45 +345,102 @@ set(Game-Source
|
|||
${COMMON_SRC_DIR}/shared/flash.c
|
||||
${COMMON_SRC_DIR}/shared/rand.c
|
||||
${COMMON_SRC_DIR}/shared/shared.c
|
||||
${GAME_SRC_DIR}/bot/ai_class_dmbot.c
|
||||
${GAME_SRC_DIR}/bot/ai_class_monster_default.c
|
||||
${GAME_SRC_DIR}/bot/ai_dropnodes.c
|
||||
${GAME_SRC_DIR}/bot/ai_items.c
|
||||
${GAME_SRC_DIR}/bot/ai_links.c
|
||||
${GAME_SRC_DIR}/bot/ai_local.h
|
||||
${GAME_SRC_DIR}/bot/ai_main.c
|
||||
${GAME_SRC_DIR}/bot/ai_movement.c
|
||||
${GAME_SRC_DIR}/bot/ai_navigation.c
|
||||
${GAME_SRC_DIR}/bot/ai_nodes.c
|
||||
${GAME_SRC_DIR}/bot/ai_nodes_local.h
|
||||
${GAME_SRC_DIR}/bot/ai_nodes_shared.h
|
||||
${GAME_SRC_DIR}/bot/ai_tools.c
|
||||
${GAME_SRC_DIR}/bot/ai_weapons.c
|
||||
${GAME_SRC_DIR}/bot/ai_weapons.h
|
||||
${GAME_SRC_DIR}/bot/astar.c
|
||||
${GAME_SRC_DIR}/bot/bot_spawn.c
|
||||
${GAME_SRC_DIR}/dm/ball.c
|
||||
${GAME_SRC_DIR}/dm/tag.c
|
||||
${GAME_SRC_DIR}/g_ai.c
|
||||
${GAME_SRC_DIR}/g_chase.c
|
||||
${GAME_SRC_DIR}/g_cmds.c
|
||||
${GAME_SRC_DIR}/g_combat.c
|
||||
${GAME_SRC_DIR}/g_ctf.c
|
||||
${GAME_SRC_DIR}/g_func.c
|
||||
${GAME_SRC_DIR}/g_items.c
|
||||
${GAME_SRC_DIR}/g_light.c
|
||||
${GAME_SRC_DIR}/g_main.c
|
||||
${GAME_SRC_DIR}/g_misc.c
|
||||
${GAME_SRC_DIR}/g_monster.c
|
||||
${GAME_SRC_DIR}/g_newai.c
|
||||
${GAME_SRC_DIR}/g_newdm.c
|
||||
${GAME_SRC_DIR}/g_newfnc.c
|
||||
${GAME_SRC_DIR}/g_newtarg.c
|
||||
${GAME_SRC_DIR}/g_newtrig.c
|
||||
${GAME_SRC_DIR}/g_newweap.c
|
||||
${GAME_SRC_DIR}/g_obj.c
|
||||
${GAME_SRC_DIR}/g_phys.c
|
||||
${GAME_SRC_DIR}/g_spawn.c
|
||||
${GAME_SRC_DIR}/g_sphere.c
|
||||
${GAME_SRC_DIR}/g_svcmds.c
|
||||
${GAME_SRC_DIR}/g_target.c
|
||||
${GAME_SRC_DIR}/g_translate.c
|
||||
${GAME_SRC_DIR}/g_trigger.c
|
||||
${GAME_SRC_DIR}/g_turret.c
|
||||
${GAME_SRC_DIR}/g_utils.c
|
||||
${GAME_SRC_DIR}/g_weapon.c
|
||||
${GAME_SRC_DIR}/menu/menu.c
|
||||
${GAME_SRC_DIR}/monster/actor/actor.c
|
||||
${GAME_SRC_DIR}/monster/arachnid/arachnid.c
|
||||
${GAME_SRC_DIR}/monster/army/army.c
|
||||
${GAME_SRC_DIR}/monster/berserker/berserker.c
|
||||
${GAME_SRC_DIR}/monster/boss2/boss2.c
|
||||
${GAME_SRC_DIR}/monster/boss3/boss3.c
|
||||
${GAME_SRC_DIR}/monster/boss3/boss31.c
|
||||
${GAME_SRC_DIR}/monster/boss3/boss32.c
|
||||
${GAME_SRC_DIR}/monster/boss3/boss3.c
|
||||
${GAME_SRC_DIR}/monster/boss5/boss5.c
|
||||
${GAME_SRC_DIR}/monster/brain/brain.c
|
||||
${GAME_SRC_DIR}/monster/carrier/carrier.c
|
||||
${GAME_SRC_DIR}/monster/chick/chick.c
|
||||
${GAME_SRC_DIR}/monster/demon/demon.c
|
||||
${GAME_SRC_DIR}/monster/dog/dog.c
|
||||
${GAME_SRC_DIR}/monster/enforcer/enforcer.c
|
||||
${GAME_SRC_DIR}/monster/fixbot/fixbot.c
|
||||
${GAME_SRC_DIR}/monster/flipper/flipper.c
|
||||
${GAME_SRC_DIR}/monster/float/float.c
|
||||
${GAME_SRC_DIR}/monster/flyer/flyer.c
|
||||
${GAME_SRC_DIR}/monster/gekk/gekk.c
|
||||
${GAME_SRC_DIR}/monster/gladiator/gladb.c
|
||||
${GAME_SRC_DIR}/monster/gladiator/gladiator.c
|
||||
${GAME_SRC_DIR}/monster/guardian/guardian.c
|
||||
${GAME_SRC_DIR}/monster/gunner/gunner.c
|
||||
${GAME_SRC_DIR}/monster/hknight/hknight.c
|
||||
${GAME_SRC_DIR}/monster/hover/hover.c
|
||||
${GAME_SRC_DIR}/monster/infantry/infantry.c
|
||||
${GAME_SRC_DIR}/monster/insane/insane.c
|
||||
${GAME_SRC_DIR}/monster/knight/knight.c
|
||||
${GAME_SRC_DIR}/monster/medic/medic.c
|
||||
${GAME_SRC_DIR}/monster/misc/move.c
|
||||
${GAME_SRC_DIR}/monster/mutant/mutant.c
|
||||
${GAME_SRC_DIR}/monster/ogre/ogre.c
|
||||
${GAME_SRC_DIR}/monster/parasite/parasite.c
|
||||
${GAME_SRC_DIR}/monster/rotfish/fish.c
|
||||
${GAME_SRC_DIR}/monster/shalrath/shalrath.c
|
||||
${GAME_SRC_DIR}/monster/shambler/shambler.c
|
||||
${GAME_SRC_DIR}/monster/soldier/soldier.c
|
||||
${GAME_SRC_DIR}/monster/stalker/stalker.c
|
||||
${GAME_SRC_DIR}/monster/supertank/supertank.c
|
||||
${GAME_SRC_DIR}/monster/tank/tank.c
|
||||
${GAME_SRC_DIR}/monster/tarbaby/tarbaby.c
|
||||
${GAME_SRC_DIR}/monster/turret/turret.c
|
||||
${GAME_SRC_DIR}/monster/widow/widow2.c
|
||||
${GAME_SRC_DIR}/monster/widow/widow.c
|
||||
${GAME_SRC_DIR}/monster/wizard/wizard.c
|
||||
${GAME_SRC_DIR}/monster/zombie/zombie.c
|
||||
${GAME_SRC_DIR}/player/chase.c
|
||||
${GAME_SRC_DIR}/player/client.c
|
||||
${GAME_SRC_DIR}/player/hud.c
|
||||
${GAME_SRC_DIR}/player/trail.c
|
||||
|
@ -452,18 +518,26 @@ set(Client-Source
|
|||
${COMMON_SRC_DIR}/collision.c
|
||||
${COMMON_SRC_DIR}/crc.c
|
||||
${COMMON_SRC_DIR}/cmdparser.c
|
||||
${COMMON_SRC_DIR}/cmodels.c
|
||||
${COMMON_SRC_DIR}/cvar.c
|
||||
${COMMON_SRC_DIR}/filesystem.c
|
||||
${COMMON_SRC_DIR}/glob.c
|
||||
${COMMON_SRC_DIR}/maps.c
|
||||
${COMMON_SRC_DIR}/md4.c
|
||||
${COMMON_SRC_DIR}/movemsg.c
|
||||
${COMMON_SRC_DIR}/models/loadfile.c
|
||||
${COMMON_SRC_DIR}/models/models.c
|
||||
${COMMON_SRC_DIR}/models/models_md5.c
|
||||
${COMMON_SRC_DIR}/models/models_mdr.c
|
||||
${COMMON_SRC_DIR}/frame.c
|
||||
${COMMON_SRC_DIR}/netchan.c
|
||||
${COMMON_SRC_DIR}/pmove.c
|
||||
${COMMON_SRC_DIR}/protocol.c
|
||||
${COMMON_SRC_DIR}/szone.c
|
||||
${COMMON_SRC_DIR}/zone.c
|
||||
${COMMON_SRC_DIR}/shared/flash.c
|
||||
${COMMON_SRC_DIR}/shared/rand.c
|
||||
${COMMON_SRC_DIR}/shared/utils.c
|
||||
${COMMON_SRC_DIR}/shared/shared.c
|
||||
${COMMON_SRC_DIR}/unzip/ioapi.c
|
||||
${COMMON_SRC_DIR}/unzip/unzip.c
|
||||
|
@ -517,6 +591,8 @@ set(Client-Header
|
|||
${COMMON_SRC_DIR}/header/glob.h
|
||||
${COMMON_SRC_DIR}/header/shared.h
|
||||
${COMMON_SRC_DIR}/header/zone.h
|
||||
${COMMON_SRC_DIR}/models/anorms.h
|
||||
${COMMON_SRC_DIR}/models/models.h
|
||||
${COMMON_SRC_DIR}/unzip/ioapi.h
|
||||
${COMMON_SRC_DIR}/unzip/unzip.h
|
||||
${COMMON_SRC_DIR}/unzip/miniz/miniz.h
|
||||
|
@ -532,14 +608,21 @@ set(Server-Source
|
|||
${COMMON_SRC_DIR}/collision.c
|
||||
${COMMON_SRC_DIR}/crc.c
|
||||
${COMMON_SRC_DIR}/cmdparser.c
|
||||
${COMMON_SRC_DIR}/cmodels.c
|
||||
${COMMON_SRC_DIR}/cvar.c
|
||||
${COMMON_SRC_DIR}/filesystem.c
|
||||
${COMMON_SRC_DIR}/glob.c
|
||||
${COMMON_SRC_DIR}/maps.c
|
||||
${COMMON_SRC_DIR}/models/loadfile.c
|
||||
${COMMON_SRC_DIR}/models/models.c
|
||||
${COMMON_SRC_DIR}/models/models_md5.c
|
||||
${COMMON_SRC_DIR}/models/models_mdr.c
|
||||
${COMMON_SRC_DIR}/md4.c
|
||||
${COMMON_SRC_DIR}/frame.c
|
||||
${COMMON_SRC_DIR}/movemsg.c
|
||||
${COMMON_SRC_DIR}/netchan.c
|
||||
${COMMON_SRC_DIR}/pmove.c
|
||||
${COMMON_SRC_DIR}/protocol.c
|
||||
${COMMON_SRC_DIR}/szone.c
|
||||
${COMMON_SRC_DIR}/zone.c
|
||||
${COMMON_SRC_DIR}/shared/rand.c
|
||||
|
@ -570,6 +653,8 @@ set(Server-Header
|
|||
${COMMON_SRC_DIR}/header/zone.h
|
||||
${COMMON_SRC_DIR}/unzip/ioapi.h
|
||||
${COMMON_SRC_DIR}/unzip/unzip.h
|
||||
${COMMON_SRC_DIR}/models/anorms.h
|
||||
${COMMON_SRC_DIR}/models/models.h
|
||||
${COMMON_SRC_DIR}/unzip/miniz/miniz.h
|
||||
${COMMON_SRC_DIR}/unzip/miniz/miniz_tdef.h
|
||||
${COMMON_SRC_DIR}/unzip/miniz/miniz_tinfl.h
|
||||
|
@ -592,13 +677,17 @@ set(GL1-Source
|
|||
${REF_SRC_DIR}/gl1/gl1_warp.c
|
||||
${REF_SRC_DIR}/gl1/gl1_sdl.c
|
||||
${REF_SRC_DIR}/gl1/gl1_buffer.c
|
||||
${REF_SRC_DIR}/files/light.c
|
||||
${REF_SRC_DIR}/files/maps.c
|
||||
${REF_SRC_DIR}/files/mesh.c
|
||||
${REF_SRC_DIR}/files/models.c
|
||||
${REF_SRC_DIR}/files/pcx.c
|
||||
${REF_SRC_DIR}/files/stb.c
|
||||
${REF_SRC_DIR}/files/surf.c
|
||||
${REF_SRC_DIR}/files/wal.c
|
||||
${REF_SRC_DIR}/files/pvs.c
|
||||
${REF_SRC_DIR}/files/warp.c
|
||||
${COMMON_SRC_DIR}/shared/utils.c
|
||||
${COMMON_SRC_DIR}/shared/shared.c
|
||||
${COMMON_SRC_DIR}/cmodels.c
|
||||
${COMMON_SRC_DIR}/md4.c
|
||||
)
|
||||
|
||||
|
@ -606,7 +695,6 @@ set(Glad-GLES1-Source ${REF_SRC_DIR}/gl1/glad-gles1/src/glad.c)
|
|||
|
||||
set(GL1-Header
|
||||
${REF_SRC_DIR}/ref_shared.h
|
||||
${REF_SRC_DIR}/constants/anorms.h
|
||||
${REF_SRC_DIR}/constants/anormtab.h
|
||||
${REF_SRC_DIR}/constants/warpsin.h
|
||||
${REF_SRC_DIR}/files/stb_image.h
|
||||
|
@ -635,13 +723,18 @@ set(GL3-Source
|
|||
${REF_SRC_DIR}/gl3/gl3_surf.c
|
||||
${REF_SRC_DIR}/gl3/gl3_warp.c
|
||||
${REF_SRC_DIR}/gl3/gl3_shaders.c
|
||||
${REF_SRC_DIR}/files/glshaders.c
|
||||
${REF_SRC_DIR}/files/light.c
|
||||
${REF_SRC_DIR}/files/maps.c
|
||||
${REF_SRC_DIR}/files/mesh.c
|
||||
${REF_SRC_DIR}/files/models.c
|
||||
${REF_SRC_DIR}/files/pcx.c
|
||||
${REF_SRC_DIR}/files/stb.c
|
||||
${REF_SRC_DIR}/files/surf.c
|
||||
${REF_SRC_DIR}/files/wal.c
|
||||
${REF_SRC_DIR}/files/pvs.c
|
||||
${REF_SRC_DIR}/files/warp.c
|
||||
${COMMON_SRC_DIR}/shared/utils.c
|
||||
${COMMON_SRC_DIR}/shared/shared.c
|
||||
${COMMON_SRC_DIR}/cmodels.c
|
||||
${COMMON_SRC_DIR}/md4.c
|
||||
)
|
||||
|
||||
|
@ -650,12 +743,11 @@ set(Glad-GLES3-Source ${REF_SRC_DIR}/gl3/glad-gles3/src/glad.c)
|
|||
|
||||
set(GL3-Header
|
||||
${REF_SRC_DIR}/ref_shared.h
|
||||
${REF_SRC_DIR}/constants/anorms.h
|
||||
${REF_SRC_DIR}/constants/anormtab.h
|
||||
${REF_SRC_DIR}/constants/warpsin.h
|
||||
${REF_SRC_DIR}/files/stb_image.h
|
||||
${REF_SRC_DIR}/gl3/header/DG_dynarr.h
|
||||
${REF_SRC_DIR}/gl3/header/HandmadeMath.h
|
||||
${REF_SRC_DIR}/files/DG_dynarr.h
|
||||
${REF_SRC_DIR}/files/HandmadeMath.h
|
||||
${REF_SRC_DIR}/gl3/header/local.h
|
||||
${REF_SRC_DIR}/gl3/header/model.h
|
||||
${COMMON_SRC_DIR}/header/shared.h
|
||||
|
@ -671,6 +763,53 @@ set(Glad-GLES3-Header
|
|||
${REF_SRC_DIR}/gl3/glad-gles3/include/KHR/khrplatform.h
|
||||
)
|
||||
|
||||
set(GL4-Source
|
||||
${REF_SRC_DIR}/gl4/gl4_draw.c
|
||||
${REF_SRC_DIR}/gl4/gl4_image.c
|
||||
${REF_SRC_DIR}/gl4/gl4_light.c
|
||||
${REF_SRC_DIR}/gl4/gl4_lightmap.c
|
||||
${REF_SRC_DIR}/gl4/gl4_main.c
|
||||
${REF_SRC_DIR}/gl4/gl4_mesh.c
|
||||
${REF_SRC_DIR}/gl4/gl4_misc.c
|
||||
${REF_SRC_DIR}/gl4/gl4_model.c
|
||||
${REF_SRC_DIR}/gl4/gl4_sdl.c
|
||||
${REF_SRC_DIR}/gl4/gl4_surf.c
|
||||
${REF_SRC_DIR}/gl4/gl4_warp.c
|
||||
${REF_SRC_DIR}/gl4/gl4_shaders.c
|
||||
${REF_SRC_DIR}/files/glshaders.c
|
||||
${REF_SRC_DIR}/files/light.c
|
||||
${REF_SRC_DIR}/files/maps.c
|
||||
${REF_SRC_DIR}/files/mesh.c
|
||||
${REF_SRC_DIR}/files/models.c
|
||||
${REF_SRC_DIR}/files/stb.c
|
||||
${REF_SRC_DIR}/files/surf.c
|
||||
${REF_SRC_DIR}/files/wal.c
|
||||
${REF_SRC_DIR}/files/warp.c
|
||||
${COMMON_SRC_DIR}/shared/utils.c
|
||||
${COMMON_SRC_DIR}/shared/shared.c
|
||||
${COMMON_SRC_DIR}/cmodels.c
|
||||
${COMMON_SRC_DIR}/md4.c
|
||||
)
|
||||
|
||||
set(Glad-GL4-Source ${REF_SRC_DIR}/gl4/glad/src/glad.c)
|
||||
|
||||
set(GL4-Header
|
||||
${REF_SRC_DIR}/ref_shared.h
|
||||
${REF_SRC_DIR}/constants/anormtab.h
|
||||
${REF_SRC_DIR}/constants/warpsin.h
|
||||
${REF_SRC_DIR}/files/stb_image.h
|
||||
${REF_SRC_DIR}/files/DG_dynarr.h
|
||||
${REF_SRC_DIR}/files/HandmadeMath.h
|
||||
${REF_SRC_DIR}/gl4/header/local.h
|
||||
${REF_SRC_DIR}/gl4/header/model.h
|
||||
${COMMON_SRC_DIR}/header/shared.h
|
||||
)
|
||||
|
||||
set(Glad-GL4-Header
|
||||
${REF_SRC_DIR}/gl4/glad/include/glad/glad.h
|
||||
${REF_SRC_DIR}/gl4/glad/include/KHR/khrplatform.h
|
||||
)
|
||||
|
||||
set(SOFT-Source
|
||||
${REF_SRC_DIR}/soft/sw_aclip.c
|
||||
${REF_SRC_DIR}/soft/sw_alias.c
|
||||
|
@ -689,13 +828,18 @@ set(SOFT-Source
|
|||
${REF_SRC_DIR}/soft/sw_scan.c
|
||||
${REF_SRC_DIR}/soft/sw_sprite.c
|
||||
${REF_SRC_DIR}/soft/sw_surf.c
|
||||
${REF_SRC_DIR}/soft/sw_warp.c
|
||||
${REF_SRC_DIR}/files/light.c
|
||||
${REF_SRC_DIR}/files/maps.c
|
||||
${REF_SRC_DIR}/files/mesh.c
|
||||
${REF_SRC_DIR}/files/models.c
|
||||
${REF_SRC_DIR}/files/pcx.c
|
||||
${REF_SRC_DIR}/files/stb.c
|
||||
${REF_SRC_DIR}/files/surf.c
|
||||
${REF_SRC_DIR}/files/wal.c
|
||||
${REF_SRC_DIR}/files/pvs.c
|
||||
${REF_SRC_DIR}/files/warp.c
|
||||
${COMMON_SRC_DIR}/shared/utils.c
|
||||
${COMMON_SRC_DIR}/shared/shared.c
|
||||
${COMMON_SRC_DIR}/cmodels.c
|
||||
${COMMON_SRC_DIR}/md4.c
|
||||
)
|
||||
|
||||
|
@ -708,6 +852,54 @@ set(SOFT-Header
|
|||
${COMMON_SRC_DIR}/header/shared.h
|
||||
)
|
||||
|
||||
set(VK-Source
|
||||
${REF_SRC_DIR}/vk/vk_buffer.c
|
||||
${REF_SRC_DIR}/vk/vk_cmd.c
|
||||
${REF_SRC_DIR}/vk/vk_common.c
|
||||
${REF_SRC_DIR}/vk/vk_device.c
|
||||
${REF_SRC_DIR}/vk/vk_draw.c
|
||||
${REF_SRC_DIR}/vk/vk_image.c
|
||||
${REF_SRC_DIR}/vk/vk_light.c
|
||||
${REF_SRC_DIR}/vk/vk_lightmap.c
|
||||
${REF_SRC_DIR}/vk/vk_main.c
|
||||
${REF_SRC_DIR}/vk/vk_mesh.c
|
||||
${REF_SRC_DIR}/vk/vk_misc.c
|
||||
${REF_SRC_DIR}/vk/vk_model.c
|
||||
${REF_SRC_DIR}/vk/vk_pipeline.c
|
||||
${REF_SRC_DIR}/vk/vk_shaders.c
|
||||
${REF_SRC_DIR}/vk/vk_surf.c
|
||||
${REF_SRC_DIR}/vk/vk_swapchain.c
|
||||
${REF_SRC_DIR}/vk/vk_util.c
|
||||
${REF_SRC_DIR}/vk/vk_validation.c
|
||||
${REF_SRC_DIR}/vk/vk_warp.c
|
||||
${REF_SRC_DIR}/vk/volk/volk.c
|
||||
${REF_SRC_DIR}/files/light.c
|
||||
${REF_SRC_DIR}/files/maps.c
|
||||
${REF_SRC_DIR}/files/mesh.c
|
||||
${REF_SRC_DIR}/files/models.c
|
||||
${REF_SRC_DIR}/files/stb.c
|
||||
${REF_SRC_DIR}/files/surf.c
|
||||
${REF_SRC_DIR}/files/wal.c
|
||||
${REF_SRC_DIR}/files/warp.c
|
||||
${COMMON_SRC_DIR}/shared/utils.c
|
||||
${COMMON_SRC_DIR}/shared/shared.c
|
||||
${COMMON_SRC_DIR}/cmodels.c
|
||||
${COMMON_SRC_DIR}/md4.c
|
||||
)
|
||||
|
||||
set(VK-Header
|
||||
${REF_SRC_DIR}/ref_shared.h
|
||||
${REF_SRC_DIR}/files/stb_image.h
|
||||
${REF_SRC_DIR}/files/stb_image_resize.h
|
||||
${REF_SRC_DIR}/vk/header/local.h
|
||||
${REF_SRC_DIR}/vk/header/model.h
|
||||
${REF_SRC_DIR}/vk/header/qvk.h
|
||||
${REF_SRC_DIR}/vk/header/shaders.h
|
||||
${REF_SRC_DIR}/vk/header/util.h
|
||||
${REF_SRC_DIR}/vk/volk/volk.h
|
||||
${COMMON_SRC_DIR}/header/shared.h
|
||||
)
|
||||
|
||||
# Main Quake 2 executable
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
|
@ -781,6 +973,8 @@ else() # single-config, like normal Makefiles
|
|||
endif()
|
||||
target_link_libraries(game ${yquake2LinkerFlags})
|
||||
|
||||
if(${GL1_RENDERER})
|
||||
|
||||
# Build the GL1 dynamic library
|
||||
add_library(ref_gl1 MODULE ${GL1-Source} ${GL1-Header} ${REF-Platform-Specific-Source})
|
||||
set_target_properties(ref_gl1 PROPERTIES
|
||||
|
@ -795,6 +989,10 @@ if(SDL3_SUPPORT)
|
|||
target_link_libraries(ref_gl1 SDL3::SDL3)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(${GL3_RENDERER})
|
||||
|
||||
# Build the GL3 dynamic library
|
||||
add_library(ref_gl3 MODULE ${GL3-Source} ${Glad-GL3-Source} ${GL3-Header} ${Glad-GL3-Header} ${REF-Platform-Specific-Source})
|
||||
set_target_properties(ref_gl3 PROPERTIES
|
||||
|
@ -809,6 +1007,28 @@ if(SDL3_SUPPORT)
|
|||
target_link_libraries(ref_gl3 SDL3::SDL3)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(${GL4_RENDERER})
|
||||
|
||||
# Build the GL4 dynamic library
|
||||
add_library(ref_gl4 MODULE ${GL4-Source} ${Glad-GL4-Source} ${GL4-Header} ${Glad-GL4-Header} ${REF-Platform-Specific-Source})
|
||||
set_target_properties(ref_gl4 PROPERTIES
|
||||
PREFIX ""
|
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||
SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
)
|
||||
target_include_directories(ref_gl4 PRIVATE ${CMAKE_SOURCE_DIR}/src/client/refresh/gl4/glad/include)
|
||||
target_link_libraries(ref_gl4 ${yquake2LinkerFlags} ${yquake2SDLLinkerFlags})
|
||||
if(SDL3_SUPPORT)
|
||||
target_link_libraries(ref_gl4 SDL3::SDL3)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(${GLES3_RENDERER})
|
||||
|
||||
# Build the GLES3 dynamic library
|
||||
add_library(ref_gles3 MODULE ${GL3-Source} ${Glad-GLES3-Source} ${GL3-Header} ${Glad-GLES3-Header} ${REF-Platform-Specific-Source})
|
||||
set_target_properties(ref_gles3 PROPERTIES
|
||||
|
@ -825,6 +1045,10 @@ if(SDL3_SUPPORT)
|
|||
target_link_libraries(ref_gles3 SDL3::SDL3)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(${SOFT_RENDERER})
|
||||
|
||||
# Build the soft renderer dynamic library
|
||||
add_library(ref_soft MODULE ${SOFT-Source} ${SOFT-Header} ${REF-Platform-Specific-Source})
|
||||
set_target_properties(ref_soft PROPERTIES
|
||||
|
@ -838,7 +1062,26 @@ if(SDL3_SUPPORT)
|
|||
target_link_libraries(ref_soft SDL3::SDL3)
|
||||
endif()
|
||||
|
||||
if(FALSE)
|
||||
endif()
|
||||
|
||||
if(${VK_RENDERER})
|
||||
|
||||
# Build the vk renderer dynamic library
|
||||
add_library(ref_vk MODULE ${VK-Source} ${VK-Header} ${REF-Platform-Specific-Source})
|
||||
set_target_properties(ref_vk PROPERTIES
|
||||
PREFIX ""
|
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release
|
||||
SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
)
|
||||
target_link_libraries(ref_vk ${yquake2LinkerFlags} ${yquake2SDLLinkerFlags})
|
||||
if(SDL3_SUPPORT)
|
||||
target_link_libraries(ref_vk SDL3::SDL3)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(${GLES1_RENDERER})
|
||||
|
||||
# Build the GLES1 dynamic library
|
||||
add_library(ref_gles1 MODULE ${GL1-Source} ${Glad-GLES1-Source} ${GL1-Header} ${Glad-GLES1-Header} ${REF-Platform-Specific-Source})
|
||||
|
|
69
Makefile
69
Makefile
|
@ -150,7 +150,7 @@ endif
|
|||
# Highest supported optimizations are -O2, higher levels
|
||||
# will likely break this crappy code.
|
||||
ifdef DEBUG
|
||||
CFLAGS ?= -O0 -g -Wall -pipe -DDEBUG
|
||||
CFLAGS ?= -O0 -g -Wall -Wpointer-arith -pipe -DDEBUG
|
||||
ifdef ASAN
|
||||
override CFLAGS += -fsanitize=address -DUSE_SANITIZER
|
||||
endif
|
||||
|
@ -158,7 +158,7 @@ ifdef UBSAN
|
|||
override CFLAGS += -fsanitize=undefined -DUSE_SANITIZER
|
||||
endif
|
||||
else
|
||||
CFLAGS ?= -O2 -Wall -pipe -fomit-frame-pointer
|
||||
CFLAGS ?= -O2 -Wall -Wpointer-arith -pipe -fomit-frame-pointer
|
||||
endif
|
||||
|
||||
# Always needed are:
|
||||
|
@ -289,6 +289,10 @@ else
|
|||
SDLCFLAGS := $(shell sdl2-config --cflags)
|
||||
endif
|
||||
|
||||
ifdef NO_SDL_GYRO
|
||||
SDLCFLAGS += -DNO_SDL_GYRO
|
||||
endif
|
||||
|
||||
# ----------
|
||||
|
||||
# Base include path.
|
||||
|
@ -383,10 +387,17 @@ SDLLDFLAGS := $(shell sdl2-config --libs)
|
|||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_SDL3),yes)
|
||||
# The renderer libs don't need libSDL3main, libmingw32 or -mwindows.
|
||||
ifeq ($(YQ2_OSTYPE), Windows)
|
||||
DLL_SDLLDFLAGS = $(subst -mwindows,,$(subst -lmingw32,,$(subst -lSDL3main,,$(SDLLDFLAGS))))
|
||||
endif
|
||||
else
|
||||
# The renderer libs don't need libSDL2main, libmingw32 or -mwindows.
|
||||
ifeq ($(YQ2_OSTYPE), Windows)
|
||||
DLL_SDLLDFLAGS = $(subst -mwindows,,$(subst -lmingw32,,$(subst -lSDL2main,,$(SDLLDFLAGS))))
|
||||
endif
|
||||
endif
|
||||
|
||||
# ----------
|
||||
|
||||
|
@ -892,10 +903,12 @@ build/ref_vk/%.o: %.c
|
|||
|
||||
# The baseq2 game
|
||||
ifeq ($(YQ2_OSTYPE), Windows)
|
||||
game:
|
||||
game: stuff/models/entity.dat
|
||||
@echo "===> Building baseq2/game.dll"
|
||||
${Q}mkdir -p release/baseq2
|
||||
$(MAKE) release/baseq2/game.dll
|
||||
${Q}mkdir -p release/baseq2/models
|
||||
${Q}cp stuff/models/entity.dat release/baseq2/models
|
||||
|
||||
build/baseq2/%.o: %.c
|
||||
@echo "===> CC $<"
|
||||
|
@ -906,10 +919,12 @@ release/baseq2/game.dll : LDFLAGS += -shared
|
|||
|
||||
else ifeq ($(YQ2_OSTYPE), Darwin)
|
||||
|
||||
game:
|
||||
game: stuff/models/entity.dat
|
||||
@echo "===> Building baseq2/game.dylib"
|
||||
${Q}mkdir -p release/baseq2
|
||||
$(MAKE) release/baseq2/game.dylib
|
||||
${Q}mkdir -p release/baseq2/models
|
||||
${Q}cp stuff/models/entity.dat release/baseq2/models
|
||||
|
||||
build/baseq2/%.o: %.c
|
||||
@echo "===> CC $<"
|
||||
|
@ -921,10 +936,12 @@ release/baseq2/game.dylib : LDFLAGS += -shared
|
|||
|
||||
else # not Windows or Darwin
|
||||
|
||||
game:
|
||||
game: stuff/models/entity.dat
|
||||
@echo "===> Building baseq2/game.so"
|
||||
${Q}mkdir -p release/baseq2
|
||||
$(MAKE) release/baseq2/game.so
|
||||
${Q}mkdir -p release/baseq2/models
|
||||
${Q}cp stuff/models/entity.dat release/baseq2/models
|
||||
|
||||
build/baseq2/%.o: %.c
|
||||
@echo "===> CC $<"
|
||||
|
@ -942,6 +959,19 @@ GAME_OBJS_ = \
|
|||
src/common/shared/flash.o \
|
||||
src/common/shared/rand.o \
|
||||
src/common/shared/shared.o \
|
||||
src/game/bot/ai_class_dmbot.o \
|
||||
src/game/bot/ai_class_monster_default.o \
|
||||
src/game/bot/ai_dropnodes.o \
|
||||
src/game/bot/ai_items.o \
|
||||
src/game/bot/ai_links.o \
|
||||
src/game/bot/ai_main.o \
|
||||
src/game/bot/ai_movement.o \
|
||||
src/game/bot/ai_navigation.o \
|
||||
src/game/bot/ai_nodes.o \
|
||||
src/game/bot/ai_tools.o \
|
||||
src/game/bot/ai_weapons.o \
|
||||
src/game/bot/astar.o \
|
||||
src/game/bot/bot_spawn.o \
|
||||
src/game/g_ai.o \
|
||||
src/game/g_chase.o \
|
||||
src/game/g_cmds.o \
|
||||
|
@ -949,6 +979,7 @@ GAME_OBJS_ = \
|
|||
src/game/g_combat.o \
|
||||
src/game/g_func.o \
|
||||
src/game/g_items.o \
|
||||
src/game/g_light.o \
|
||||
src/game/g_main.o \
|
||||
src/game/g_misc.o \
|
||||
src/game/g_monster.o \
|
||||
|
@ -958,6 +989,7 @@ GAME_OBJS_ = \
|
|||
src/game/g_newtarg.o \
|
||||
src/game/g_newtrig.o \
|
||||
src/game/g_newweap.o \
|
||||
src/game/g_obj.o \
|
||||
src/game/g_phys.o \
|
||||
src/game/g_spawn.o \
|
||||
src/game/g_sphere.o \
|
||||
|
@ -986,7 +1018,6 @@ GAME_OBJS_ = \
|
|||
src/game/monster/demon/demon.o \
|
||||
src/game/monster/dog/dog.o \
|
||||
src/game/monster/enforcer/enforcer.o \
|
||||
src/game/monster/fish/fish.o \
|
||||
src/game/monster/fixbot/fixbot.o \
|
||||
src/game/monster/flipper/flipper.o \
|
||||
src/game/monster/float/float.o \
|
||||
|
@ -1006,6 +1037,7 @@ GAME_OBJS_ = \
|
|||
src/game/monster/mutant/mutant.o \
|
||||
src/game/monster/ogre/ogre.o \
|
||||
src/game/monster/parasite/parasite.o \
|
||||
src/game/monster/rotfish/fish.o \
|
||||
src/game/monster/shalrath/shalrath.o \
|
||||
src/game/monster/shambler/shambler.o \
|
||||
src/game/monster/soldier/soldier.o \
|
||||
|
@ -1072,7 +1104,10 @@ CLIENT_OBJS_ := \
|
|||
src/common/glob.o \
|
||||
src/common/md4.o \
|
||||
src/common/maps.o \
|
||||
src/common/models.o \
|
||||
src/common/models/loadfile.o \
|
||||
src/common/models/models.o \
|
||||
src/common/models/models_md5.o \
|
||||
src/common/models/models_mdr.o \
|
||||
src/common/movemsg.o \
|
||||
src/common/frame.o \
|
||||
src/common/netchan.o \
|
||||
|
@ -1147,12 +1182,9 @@ REFGL1_OBJS_ := \
|
|||
src/client/refresh/files/surf.o \
|
||||
src/client/refresh/files/maps.o \
|
||||
src/client/refresh/files/models.o \
|
||||
src/client/refresh/files/models_md5.o \
|
||||
src/client/refresh/files/models_mdr.o \
|
||||
src/client/refresh/files/stb.o \
|
||||
src/client/refresh/files/wal.o \
|
||||
src/client/refresh/files/warp.o \
|
||||
src/client/refresh/files/pvs.o \
|
||||
src/common/shared/shared.o \
|
||||
src/common/shared/utils.o \
|
||||
src/common/cmodels.o \
|
||||
|
@ -1190,12 +1222,9 @@ REFGL3_OBJS_ := \
|
|||
src/client/refresh/files/surf.o \
|
||||
src/client/refresh/files/maps.o \
|
||||
src/client/refresh/files/models.o \
|
||||
src/client/refresh/files/models_md5.o \
|
||||
src/client/refresh/files/models_mdr.o \
|
||||
src/client/refresh/files/stb.o \
|
||||
src/client/refresh/files/wal.o \
|
||||
src/client/refresh/files/warp.o \
|
||||
src/client/refresh/files/pvs.o \
|
||||
src/common/shared/shared.o \
|
||||
src/common/shared/utils.o \
|
||||
src/common/cmodels.o \
|
||||
|
@ -1236,12 +1265,9 @@ REFGL4_OBJS_ := \
|
|||
src/client/refresh/files/surf.o \
|
||||
src/client/refresh/files/maps.o \
|
||||
src/client/refresh/files/models.o \
|
||||
src/client/refresh/files/models_md5.o \
|
||||
src/client/refresh/files/models_mdr.o \
|
||||
src/client/refresh/files/stb.o \
|
||||
src/client/refresh/files/wal.o \
|
||||
src/client/refresh/files/warp.o \
|
||||
src/client/refresh/files/pvs.o \
|
||||
src/common/shared/shared.o \
|
||||
src/common/cmodels.o \
|
||||
src/common/md4.o
|
||||
|
@ -1283,12 +1309,9 @@ REFSOFT_OBJS_ := \
|
|||
src/client/refresh/files/surf.o \
|
||||
src/client/refresh/files/maps.o \
|
||||
src/client/refresh/files/models.o \
|
||||
src/client/refresh/files/models_md5.o \
|
||||
src/client/refresh/files/models_mdr.o \
|
||||
src/client/refresh/files/stb.o \
|
||||
src/client/refresh/files/wal.o \
|
||||
src/client/refresh/files/warp.o \
|
||||
src/client/refresh/files/pvs.o \
|
||||
src/common/shared/shared.o \
|
||||
src/common/shared/utils.o \
|
||||
src/common/cmodels.o \
|
||||
|
@ -1330,12 +1353,9 @@ REFVK_OBJS_ := \
|
|||
src/client/refresh/files/surf.o \
|
||||
src/client/refresh/files/maps.o \
|
||||
src/client/refresh/files/models.o \
|
||||
src/client/refresh/files/models_md5.o \
|
||||
src/client/refresh/files/models_mdr.o \
|
||||
src/client/refresh/files/stb.o \
|
||||
src/client/refresh/files/wal.o \
|
||||
src/client/refresh/files/warp.o \
|
||||
src/client/refresh/files/pvs.o \
|
||||
src/common/shared/shared.o \
|
||||
src/common/shared/utils.o \
|
||||
src/common/cmodels.o \
|
||||
|
@ -1366,7 +1386,10 @@ SERVER_OBJS_ := \
|
|||
src/common/md4.o \
|
||||
src/common/frame.o \
|
||||
src/common/maps.o \
|
||||
src/common/models.o \
|
||||
src/common/models/loadfile.o \
|
||||
src/common/models/models.o \
|
||||
src/common/models/models_md5.o \
|
||||
src/common/models/models_mdr.o \
|
||||
src/common/movemsg.o \
|
||||
src/common/netchan.o \
|
||||
src/common/pmove.o \
|
||||
|
|
322
README.md
322
README.md
|
@ -8,27 +8,9 @@ Feel free to try this code but you mileage may vary.
|
|||
Have a look at the yquake2 repository for the "normal" Yamagi Quake II:
|
||||
<https://github.com/yquake2/yquake2>
|
||||
|
||||
Alpha windows 64 bit [binaries](https://github.com/yquake2/yquake2remaster/releases).
|
||||
Saves format is unstabled and could change between alpha releases.
|
||||
|
||||
State:
|
||||
|
||||
* GL1/GLES3/GL3/GL4/VK:
|
||||
* base1: no known issues,
|
||||
* base2: no known issues,
|
||||
* q64/outpost: broken level change,
|
||||
* mguhub: sometimes broken logic for surface fall in next maps.
|
||||
* SOFT:
|
||||
* base1: broken wall light and wall glitch,
|
||||
* base2: broken wall light and wall glitch,
|
||||
* q64/outpost: broken level change, scale textures unsupported,
|
||||
* mguhub: broken wall light, sometimes broken logic for surface fall
|
||||
in next maps.
|
||||
|
||||
Monsters:
|
||||
|
||||
* incorrect dead animation for Arachnid,
|
||||
* broken fire effect for Guardian.
|
||||
* Alpha windows 64 bit [binaries](https://github.com/yquake2/yquake2remaster/releases).
|
||||
* Saves format is unstabled and could change between alpha releases.
|
||||
* MacOS build is only build tested and run is not checked.
|
||||
|
||||
Models support:
|
||||
|
||||
|
@ -36,10 +18,10 @@ Models support:
|
|||
| ------ | --------------- | ------------ | -------- | --------------------------------------- |
|
||||
| mdl | Quake 1 | 8 bit | Single | Unsupported grouped textures |
|
||||
| md2 | Quake 2 | 8 bit | Single | |
|
||||
| mda | Anachronox | Part of md2 | Single | No tagged surfaces |
|
||||
| md2 | Anachronox | 8/10/16 bit | Single | No tagged surfaces, unchecked with game |
|
||||
| mda | Anachronox | Part of md2 | Single | Unsupported skin pass combine |
|
||||
| md2 | Anachronox | 8/10/16 bit | Single | Unchecked with game |
|
||||
| mdx | Kingpin | 8 bit | Multiple | No sfx support, unchecked with game |
|
||||
| fm | Heretic 2 | 8 bit | Multiple | |
|
||||
| fm | Heretic 2 | 8 bit | Multiple | Without skeletal animation |
|
||||
| def | SiN | Part of sam | Multiple | Unchecked with game |
|
||||
| dkm | Daikatana DKM1 | 8 bit | Multiple | Unchecked with game |
|
||||
| dkm | Daikatana DKM2 | 10 bit | Multiple | Unchecked with game |
|
||||
|
@ -66,6 +48,13 @@ Texture support:
|
|||
| jpg | retexturing | 24 bit |
|
||||
| bmp | Daikatana | 24 bit |
|
||||
|
||||
Sprites support:
|
||||
|
||||
| Format | Original Game | Comments |
|
||||
| ------ | -------------- | ----------------------------- |
|
||||
| sp2 | Quake 2 | |
|
||||
| atd | Anachronox | Show first frame of animation |
|
||||
|
||||
Maps support:
|
||||
|
||||
| Format | Version | Game |
|
||||
|
@ -78,18 +67,20 @@ Maps support:
|
|||
|
||||
Note:
|
||||
|
||||
* Non Quake 2 maps are limmited mostly view only, and could have issues
|
||||
* Non Quake 2 maps are limited mostly view only, and could have issues
|
||||
with tranparency or some animations flags and properties.
|
||||
* If you like support some other maps type, create pull request for Mod_Load2QBSP
|
||||
function and provide a link to demo maps.
|
||||
* Use `maptype 1` before load any Heretic 2 maps. Look to
|
||||
[maptype_t](src/common/header/cmodel.h#L42) for more info.
|
||||
* Use `maptype 1` before load any Heretic 2 maps, or place game data to `heretic2` directory.
|
||||
Look to [maptype_t](src/common/header/cmodel.h#L42) for more info.
|
||||
|
||||
Games:
|
||||
|
||||
* Quake 2:
|
||||
* Quake 2 ReRelease:
|
||||
* SDK: <https://github.com/id-Software/quake2-rerelease-dll>
|
||||
* Tech info: <https://bethesda.net/en/article/6NIyBxapXOurTKtF4aPiF4/enhancing-quake-ii>
|
||||
* PSX source: <https://www.moddb.com/mods/quake-ii-psx/downloads/quake-ii-psx-10-sources>
|
||||
* PSX Mod: <https://www.moddb.com/mods/quake-ii-psx>
|
||||
* Anachronox:
|
||||
* SDK: <https://github.com/hogsy/chronon>
|
||||
* SDK: <https://code.idtech.space/ion-storm/anachronox-sdk>
|
||||
|
@ -108,46 +99,261 @@ Games:
|
|||
* Tools: [SiNview](https://web.archive.org/web/20001212060900/http://starbase.neosoft.com:80/~otaku/program.html)
|
||||
* Tools: <https://www.moddb.com/games/sin/downloads/sin-modding-tools-and-other-stuff>
|
||||
* SDK: <https://github.com/NightDive-Studio/sin-ex-game>
|
||||
* SDK: <https://github.com/jimdose/SiN_110_Source>
|
||||
* SDK: <https://code.idtech.space/ritual/sin-sdk>
|
||||
* Dawn of Darkness:
|
||||
* Docs: <https://www.moddb.com/mods/dawn-of-darkness1/downloads/dod-mood-scripts-gsm-tutorials-fgd-and-def-file>
|
||||
* Demo: [Episode 1](https://www.moddb.com/mods/dawn-of-darkness1/downloads/dawn-of-darkness-episode-1)
|
||||
* JaBot:
|
||||
* SDK: <https://www.moddb.com/mods/jabotq2/downloads/jabot-q2-v09x-win32-and-linux>
|
||||
* Additional maps used for check maps support:
|
||||
* PSX: <https://www.moddb.com/mods/quake-ii-psx/downloads/quake-ii-psx-10>
|
||||
* ReRelease N64 Jam: <https://www.moddb.com/games/quake-2/addons/quake-2-re-release-n64-sp-map-jam>
|
||||
* ReRelease Basic Jam: <https://www.moddb.com/games/quake-2/addons/quake-2-re-release-back-to-baseq2ics-jam-1>
|
||||
* ReRelease PSX Jam: <https://www.moddb.com/mods/psx-jam-1/downloads/quake-2-re-release-psx-jam-1>
|
||||
|
||||
Goals:
|
||||
Games check videos:
|
||||
|
||||
* [x] BSPX DECOUPLEDLM light map support (base1),
|
||||
* [x] QBSP map format support (mguhub),
|
||||
* [x] Use ffmpeg for load any video,
|
||||
* [x] RoQ and Theora cinematic videos support.
|
||||
* [x] Cinematic videos support in smk, mpeg, ogv format,
|
||||
* [x] Daikatana/Heretic 2 map partial format support,
|
||||
* [x] md5 improve load speed,
|
||||
* [x] support Anachronox .dat format,
|
||||
* [x] suport Daikatana/SiN .pak/.sin format from pakextract,
|
||||
* [x] Support flow/scale flags for Q64 maps,
|
||||
* [x] Add debug progress loading code for maps,
|
||||
* [x] MDR model format from Star Trek: Voyager – Elite Force,
|
||||
* [ ] MDA entity format from Anachronox,
|
||||
* [x] RGB particles support instead palette based one,
|
||||
* [x] Get rid of VID_PaletteColor client internal api use,
|
||||
* [x] Broken maps groups from base2 to next,
|
||||
* [ ] Single player ReRelease support,
|
||||
* [ ] Support effects and additional flags for ReRelease when possible.
|
||||
* [ ] Use shared model cache in client code insted reimplemnet in each render,
|
||||
* [x] Check load soft colormap as 24bit color from loaded image,
|
||||
* [ ] Fix transparent textures in Daikatana/SiN maps,
|
||||
* [ ] Use separete texture hi-color buffer for ui in soft render,
|
||||
* [ ] Cleanup function declarations in game save code,
|
||||
* [ ] Fix broken base3 with sorted fields names,
|
||||
* [x] Use 3 bytes vertex normal,
|
||||
* [ ] Support scalled textures for models and walls in soft render and fix
|
||||
* 8.42RR12+:
|
||||
|
||||
[](https://www.youtube.com/watch?v=uW3XDxrjQOU)
|
||||
[](https://www.youtube.com/watch?v=8Tlm8lSY5x8)
|
||||
[](https://www.youtube.com/watch?v=PR2_nK7DFJM)
|
||||
|
||||
* 8.42RR11:
|
||||
|
||||
[](https://www.youtube.com/watch?v=Ha1FuVXaQSE)
|
||||
[](https://www.youtube.com/watch?v=6P3wJojExyI)
|
||||
[](https://www.youtube.com/watch?v=ukqBrx80ESM)
|
||||
|
||||
* 8.42RR10:
|
||||
|
||||
[](https://www.youtube.com/watch?v=obIrzYsNxBY)
|
||||
|
||||
* 8.42RR9:
|
||||
|
||||
[](https://www.youtube.com/watch?v=N0iHhEDkZFg)
|
||||
|
||||
* 8.42RR8:
|
||||
|
||||
[](https://www.youtube.com/watch?v=NJ7T0cdyqk8)
|
||||
|
||||
* 8.31RR7:
|
||||
|
||||
[](https://www.youtube.com/watch?v=VAFs1HtQU_0)
|
||||
|
||||
|
||||
Goals, fully finished goals could be checked in [here](CHANGELOG):
|
||||
|
||||
* [ ] jabot: fix crash in SZ_GetSpace,
|
||||
* [ ] Anachronox: skins load broken with mingw win64 build,
|
||||
* [ ] Anachronox: rowdys map models disappear on dance space,
|
||||
* [ ] Anachronox: CTC entity format,
|
||||
* [ ] Anachronox: support material load textures/textureinfo.dat,
|
||||
* [ ] soft: fix crash with md5 models in player model select and ASAN=1
|
||||
* [ ] soft: q64/outpost scale textures unsupported,
|
||||
* [ ] soft: broken wall light and wall glitch,
|
||||
* [ ] soft: build with SDL3 has glitch in menu,
|
||||
* [ ] soft: support custom ttf fonts,
|
||||
* [ ] soft: support scalled textures for models and walls, and fix
|
||||
lighting with remastered maps,
|
||||
* [ ] Modified ReRelease game code support with removed KEX only related code.
|
||||
* [ ] soft: use separete texture hi-color buffer for ui in soft render,
|
||||
* [ ] DoD: fix statusbar `roarke`,
|
||||
* [ ] vulkan: group `it_pic` images,
|
||||
* [ ] vulkan: rearange surfaces before render,
|
||||
* [x] Use shared model cache in client code insted reimplement in each render,
|
||||
* [ ] reuse memory from models cache in renders model list,
|
||||
* [ ] reuse memory from models cache for bsp,
|
||||
* [ ] Fix transparent textures in Daikatana/SiN maps,
|
||||
* [ ] game: cleanup function declarations in game save code,
|
||||
* [ ] game: fix broken base3 with sorted fields names,
|
||||
* [x] game: remove grapple by default,
|
||||
* [x] ReRelease: crash on exit from psx/base2,
|
||||
* [ ] ReRelease: mguhub map has sometimes broken logic for surface fall in next maps,
|
||||
* [ ] ReRelease: incorrect light apply to models (wall looks fine),
|
||||
* [ ] ReRelease: incorrect dead animation for Arachnid,
|
||||
* [ ] ReRelease: broken fire effect for Guardian.
|
||||
* [ ] ReRelease: fix invisiable entities in basicsjam1_ziutek,
|
||||
* [ ] ReRelease: make lightmap textures dynamic n64jam_palmlix,
|
||||
* [x] ReRelease: support textures/*/*.mat load (footstep),
|
||||
* [ ] ReRelease: support textures/*/*.mat load texture effects,
|
||||
* [ ] ReRelease: support textures/*/*_glow.png load,
|
||||
* [ ] ReRelease: support tactile/*/*.bnvib/.wav feedback load,
|
||||
* [x] ReRelease: fix physics with incorrect floor height in psx/base0.bsp,
|
||||
* [ ] ReRelease: console `~` incorrectly show multibyte characters,
|
||||
* [ ] ReRelease: basicsjam1_detrohogga: Make pmove_state_t.origin 29.3 (PS_M_ORIGIN) > 4k coord values support,
|
||||
* [ ] ReRelease: fully implement `misc_flare`,
|
||||
* [ ] ReRelease: single player support,
|
||||
* [ ] ReRelease: support effects and additional flags when possible.
|
||||
* [ ] ReRelease: modified game code support with removed KEX only related code.
|
||||
|
||||
Not a goal:
|
||||
|
||||
* [ ] Multiplayer protocol support with KEX engine,
|
||||
* [ ] Support KEX engine features (inventary, compass and so on),
|
||||
* [ ] Support KEX engine features (inventory, compass and so on),
|
||||
* [ ] [KEX game library support](https://github.com/id-Software/quake2-rerelease-dll).
|
||||
|
||||
Code tested with such [maps](doc/100_tested_maps.md).
|
||||
|
||||
# Additional requirements:
|
||||
|
||||
Localization requires `Q2Game.kpf` file in root directory of game. If you
|
||||
like to support your language put it to localization/loc_<your language>.txt
|
||||
and extend MAX_FONTCODE to your [max symbol code](https://en.wikipedia.org/wiki/List_of_Unicode_characters).
|
||||
Used font and language file are defined by `g_language` and `r_ttffont`, as
|
||||
an example could be used fonts like [unifont](https://unifoundry.com/pub/unifont/unifont-15.0.06/font-builds/unifont-15.0.06.ttf).
|
||||
|
||||
Additional models:
|
||||
|
||||
| Spawn classname | Description |
|
||||
| ---------------- | ------------------------------ |
|
||||
| misc_actor | Quake 2 actor (Restored) |
|
||||
| misc_actorvx | ReRelease vault actor x |
|
||||
| misc_actorvy | ReRelease vault actor y |
|
||||
| misc_fighter | ReRelease vault fighter ship |
|
||||
| misc_transprt | ReRelease vault transport ship |
|
||||
| monster_arachnid | ReRelease arachnid |
|
||||
| monster_army | Quake 1 army soldier |
|
||||
| monster_boss5 | Xatrix boss 5 |
|
||||
| monster_carrier | Rogue carrier |
|
||||
| monster_demon | Quake 1 demon |
|
||||
| monster_dog | Quake 1 dog |
|
||||
| monster_enforcer | Quake 1 enforcer |
|
||||
| monster_floaterv | ReRelease vault technician |
|
||||
| monster_flyerv | ReRelease vault flyer |
|
||||
| monster_fixbot | Xatrix fixbot |
|
||||
| monster_gnorta | ReRelease vault gnorta |
|
||||
| monster_gekk | Xatrix gekk |
|
||||
| monster_hknight | Quake 1 hknight |
|
||||
| monster_guardian | ReRelease guardian |
|
||||
| monster_knight | Quake 1 knight |
|
||||
| monster_mutantv | ReRelease vault mutant |
|
||||
| monster_ogre | Quake 1 ogre |
|
||||
| monster_rotfish | Quake 1 rotfish |
|
||||
| monster_shalrath | Quake 1 shalrath |
|
||||
| monster_shambler | Quake 1 shambler |
|
||||
| monster_shockerv | ReRelease vault shocker |
|
||||
| monster_stalker | Rogue stalker |
|
||||
| monster_tankv | ReRelease vault tank |
|
||||
| monster_tarbaby | Quake 1 tarbaby |
|
||||
| monster_turret | Rogue turret |
|
||||
| monster_wizard | Quake 1 wizard |
|
||||
| monster_widow | Rogue widow |
|
||||
| monster_widow2 | Rogue widow 2 |
|
||||
| monster_zombie | Quake 1 zombie |
|
||||
| npc_timeminder | Anachronox save menu |
|
||||
|
||||
Full list of supported entities [classnames](stuff/models/entity.dat).
|
||||
|
||||
Quake 1 models usage requires such files:
|
||||
|
||||
| source Quake 1 Path | destination Quake 2 Path | md5 hash |
|
||||
| -------------------------- | --------------------------------- | -------------------------------- |
|
||||
| progs/soldier.mdl | models/monsters/army/tris.mdl | 5b6c30a984872b4273dd5861412d35c5 |
|
||||
| progs/demon.mdl | models/monsters/demon/tris.mdl | 4c73786e7cfb2083ca38cbc983cd6c4b |
|
||||
| progs/dog.mdl | models/monsters/dog/tris.mdl | e727fbc39acc652f812972612ce37565 |
|
||||
| progs/enforcer.mdl | models/monsters/enforcer/tris.mdl | 136c265f96d6077ee3312c52e134529f |
|
||||
| progs/fish.mdl | models/monsters/rotfish/tris.mdl | d770d6ef92ae8b372926e6c3d49e8716 |
|
||||
| progs/hknight.mdl | models/monsters/hknight/tris.mdl | ed20e30be6fdb83efbaa6d0b23671a49 |
|
||||
| progs/knight.mdl | models/monsters/knight/tris.mdl | 5328915db5c53e85cf75d46e7b747fb9 |
|
||||
| progs/ogre.mdl | models/monsters/ogre/tris.mdl | fbb592ca3788a576dd2f31fcf8c80fab |
|
||||
| progs/shalrath.mdl | models/monsters/shalrath/tris.mdl | dac8f6077b0d2bf970573d2d2c22529f |
|
||||
| progs/shambler.mdl | models/monsters/shambler/tris.mdl | 9b09375a0f614dc4081e363cc34f1185 |
|
||||
| progs/tarbaby.mdl | models/monsters/tarbaby/tris.mdl | 2bfc45593a43a0191982e3cfdc112dc5 |
|
||||
| progs/wizard.mdl | models/monsters/wizard/tris.mdl | bf60986594f045e60e8aa6339d553ee7 |
|
||||
| progs/zombie.mdl | models/monsters/zombie/tris.mdl | a923b1d03b9d237dd5ead9bd56acc900 |
|
||||
| progs/k_spike.mdl | models/proj/fireball/tris.mdl | da95b49a695b34c2c3516a8d789c6b20 |
|
||||
| progs/v_spike.mdl | models/proj/pod/tris.mdl | 2bdc0b264b9fd3443c8eee816305728f |
|
||||
| progs/w_spike.mdl | models/proj/spit/tris.mdl | 8cf9245df2164e8062b01a220b508d6b |
|
||||
| sound/army/death1.wav | sound/army/death1.wav | fe25952af40b536c3bb67bfca58062eb |
|
||||
| sound/army/idle.wav | sound/army/idle.wav | 4cdfbdda8fb5f40b125c7bcddb6e8914 |
|
||||
| sound/army/pain1.wav | sound/army/pain1.wav | 54d3b05fdcecf7480034858f2b22b06c |
|
||||
| sound/army/pain2.wav | sound/army/pain2.wav | e2bbc9d3405b9b9fdae76d2fc298fc2f |
|
||||
| sound/army/sattck1.wav | sound/army/sattck1.wav | b76ac35f900f280a7a7996da7e404362 |
|
||||
| sound/army/sight1.wav | sound/army/sight1.wav | e2a39533250ddd1b08053d5c4ebf7fd0 |
|
||||
| sound/demon/ddeath.wav | sound/demon/ddeath.wav | 62a48dcd405ca55c9ce18497e36faa0e |
|
||||
| sound/demon/dhit2.wav | sound/demon/dhit2.wav | 9e741696e4d0d66e30e718fc70ec186e |
|
||||
| sound/demon/djump.wav | sound/demon/djump.wav | 791ac9d6b6593808316145443cb7e7a0 |
|
||||
| sound/demon/dland2.wav | sound/demon/dland2.wav | db14c7b01838f826b7a712075f9026fd |
|
||||
| sound/demon/dpain1.wav | sound/demon/dpain1.wav | 5e6c485878393c9bebb0d0e6659bc479 |
|
||||
| sound/demon/idle1.wav | sound/demon/idle1.wav | 7a83f8caf3d5b1172a7dc5afdc942988 |
|
||||
| sound/demon/sight2.wav | sound/demon/sight2.wav | 65171c355c22a5069520b0881677ae3c |
|
||||
| sound/dog/dattack1.wav | sound/dog/dattack1.wav | 0c47c9d4aaae0bf3159a288b674f4a35 |
|
||||
| sound/dog/ddeath.wav | sound/dog/ddeath.wav | b0e7760b1d7286a028ff9773f6802958 |
|
||||
| sound/dog/dpain1.wav | sound/dog/dpain1.wav | 28e5ab93b41e13e2916433283a5d1a46 |
|
||||
| sound/dog/dsight.wav | sound/dog/dsight.wav | 0edc290765bac1fb4fe03ca55bc7c225 |
|
||||
| sound/dog/idle.wav | sound/dog/idle.wav | 42bd6026ff32bd94523ad9f8fe8362cc |
|
||||
| sound/enforcer/death1.wav | sound/enforcer/death1.wav | f38d7a235e13ef8918aac0c70437320d |
|
||||
| sound/enforcer/enfire.wav | sound/enforcer/enfire.wav | b080a6a53f138bef9fc4403fb9373a24 |
|
||||
| sound/enforcer/enfstop.wav | sound/enforcer/enfstop.wav | 0bc39c3c88187fb37d20ef21300e7b22 |
|
||||
| sound/enforcer/idle1.wav | sound/enforcer/idle1.wav | d0435763860fe54e938ad25bb1780f9e |
|
||||
| sound/enforcer/pain1.wav | sound/enforcer/pain1.wav | d52bc02afe624924684b25295edaa040 |
|
||||
| sound/enforcer/pain2.wav | sound/enforcer/pain2.wav | f6b0ad6485d93f5c6d7d61b847d06877 |
|
||||
| sound/enforcer/sight1.wav | sound/enforcer/sight1.wav | 9e9876444ba92ed18bfce4cec3a2ff12 |
|
||||
| sound/enforcer/sight2.wav | sound/enforcer/sight2.wav | 815dd4f6a890b0a35dc466005df74850 |
|
||||
| sound/enforcer/sight3.wav | sound/enforcer/sight3.wav | f8c8d19905b24d4adb6760a1b3762f3b |
|
||||
| sound/enforcer/sight4.wav | sound/enforcer/sight4.wav | 04e40eb925290bc56520de326df6b220 |
|
||||
| sound/fish/bite.wav | sound/fish/bite.wav | 7c56712615e2a2c3de4fe0e7e35cba05 |
|
||||
| sound/fish/death.wav | sound/fish/death.wav | 8d6152ee55507430a8c2eb276c4aa8ac |
|
||||
| sound/fish/idle.wav | sound/fish/idle.wav | 54a02731b85eb6f8b1a8ecce09771d20 |
|
||||
| sound/hknight/attack1.wav | sound/hknight/attack1.wav | 695e9d890a085addf1a607aa79137e8e |
|
||||
| sound/hknight/death1.wav | sound/hknight/death1.wav | 2d68c3c86632027676b823fcff3af08c |
|
||||
| sound/hknight/grunt.wav | sound/hknight/grunt.wav | 122f3d4623e0146732aa0e4deb0fe326 |
|
||||
| sound/hknight/hit.wav | sound/hknight/hit.wav | fece24e2548f1d769e8fce39a5c87d01 |
|
||||
| sound/hknight/idle.wav | sound/hknight/idle.wav | e9ca23c4853472750d1f56e52a3d227b |
|
||||
| sound/hknight/pain1.wav | sound/hknight/pain1.wav | 52c20eb6f5b5146ece6b0ac02f423341 |
|
||||
| sound/hknight/sight1.wav | sound/hknight/sight1.wav | 786d28ec653a0d512d078b32eb8cb58b |
|
||||
| sound/hknight/slash1.wav | sound/hknight/slash1.wav | 83e64bb90cff2a4f9764dd53489b9d7d |
|
||||
| sound/knight/idle.wav | sound/knight/idle.wav | 1b5c3981bee078318af346d8fe8090b9 |
|
||||
| sound/knight/kdeath.wav | sound/knight/kdeath.wav | 11a96f48a8f2433c23beae299c8fb96e |
|
||||
| sound/knight/khurt.wav | sound/knight/khurt.wav | 32c9f48dd4a6a87752aedf56fe8de668 |
|
||||
| sound/knight/ksight.wav | sound/knight/ksight.wav | eb75b4af348c88e84d8c87c19d5976fa |
|
||||
| sound/knight/sword1.wav | sound/knight/sword1.wav | 93045b5f3178413dc6b01ec2869d1f73 |
|
||||
| sound/knight/sword2.wav | sound/knight/sword2.wav | 82d1a7c263cd3df7b060dee2f7f8b1fd |
|
||||
| sound/ogre/ogdrag.wav | sound/ogre/ogdrag.wav | 658587dc89aaefae5ca3f058f7ff4227 |
|
||||
| sound/ogre/ogdth.wav | sound/ogre/ogdth.wav | de98e7bb9e70586edddd3308cfded3db |
|
||||
| sound/ogre/ogidle2.wav | sound/ogre/ogidle2.wav | 196ae9c33a4311160e1d5f3da878ab09 |
|
||||
| sound/ogre/ogidle.wav | sound/ogre/ogidle.wav | 177c829840a87c885bbc8951e7ce962e |
|
||||
| sound/ogre/ogpain1.wav | sound/ogre/ogpain1.wav | ac6d133d7720c12df49813fe10e683b5 |
|
||||
| sound/ogre/ogsawatk.wav | sound/ogre/ogsawatk.wav | 7257bdfd014bb61d778b8f88cb65d560 |
|
||||
| sound/ogre/ogwake.wav | sound/ogre/ogwake.wav | 3296459e495c4c12b31179d4eeffac19 |
|
||||
| sound/shalrath/attack2.wav | sound/shalrath/attack2.wav | 777fbda2f81350e45920ea1c36d318e1 |
|
||||
| sound/shalrath/attack.wav | sound/shalrath/attack.wav | 8814a72b399be619d14223235f78f294 |
|
||||
| sound/shalrath/death.wav | sound/shalrath/death.wav | 771844c5cfb5a42e82e221a63f101ac7 |
|
||||
| sound/shalrath/idle.wav | sound/shalrath/idle.wav | 1a45f12579f9cdd27152332d5f816048 |
|
||||
| sound/shalrath/pain.wav | sound/shalrath/pain.wav | 6ba007b79c50d7d5347f1a29fb315422 |
|
||||
| sound/shalrath/sight.wav | sound/shalrath/sight.wav | 3d3c2001cc976efc67af1552427eedd3 |
|
||||
| sound/shambler/melee1.wav | sound/shambler/melee1.wav | 77fe6240973a204b757a427ebf66bcfd |
|
||||
| sound/shambler/melee2.wav | sound/shambler/melee2.wav | 3be31638d769e3d690c92311dfafdeac |
|
||||
| sound/shambler/sattck1.wav | sound/shambler/sattck1.wav | ec8c3f79ea42d09154cb8975ada1b21c |
|
||||
| sound/shambler/sboom.wav | sound/shambler/sboom.wav | 9834601a645d7d1f62001b2a314ec18f |
|
||||
| sound/shambler/sdeath.wav | sound/shambler/sdeath.wav | e0e62d229a985a6e39218c6488599059 |
|
||||
| sound/shambler/shurt2.wav | sound/shambler/shurt2.wav | 1e87631ede95e061a75f9c31629ac0b8 |
|
||||
| sound/shambler/sidle.wav | sound/shambler/sidle.wav | 368a240e6c3e877793352a79c1828386 |
|
||||
| sound/shambler/smack.wav | sound/shambler/smack.wav | bd8c634c9894348360fec7b7419d1649 |
|
||||
| sound/shambler/ssight.wav | sound/shambler/ssight.wav | 657107577460d5acf3157dec97e07a89 |
|
||||
| sound/tarbaby/death1.wav | sound/tarbaby/death1.wav | 53f8c73de11c018086ba19ed036833d3 |
|
||||
| sound/tarbaby/hit1.wav | sound/tarbaby/hit1.wav | 42c5a1edd02421bf6df7ddc3e395c4f8 |
|
||||
| sound/tarbaby/land1.wav | sound/tarbaby/land1.wav | 5a1585ab22368a48827db9b7d3763b58 |
|
||||
| sound/tarbaby/sight1.wav | sound/tarbaby/sight1.wav | df4dd7ec91e094b5c2235be3f5353e4a |
|
||||
| sound/wizard/hit.wav | sound/wizard/hit.wav | 6598d669334df977f1f97b95288edf11 |
|
||||
| sound/wizard/wattack.wav | sound/wizard/wattack.wav | b3568a47439f81779d40335e76f5bc2d |
|
||||
| sound/wizard/wdeath.wav | sound/wizard/wdeath.wav | 99d9c71343bc23222abb92119d404400 |
|
||||
| sound/wizard/widle1.wav | sound/wizard/widle1.wav | b22b1dd9f66879b3447d36ab584316c7 |
|
||||
| sound/wizard/widle2.wav | sound/wizard/widle2.wav | 7178fd83df227360564adef01bed92c6 |
|
||||
| sound/wizard/wpain.wav | sound/wizard/wpain.wav | bd7e59ab7d7b835f9ed8ab51950914de |
|
||||
| sound/wizard/wsight.wav | sound/wizard/wsight.wav | df5949057c750528917c6cb32b7fd9fd |
|
||||
| sound/zombie/idle_w2.wav | sound/zombie/idle_w2.wav | d2bb59b9d7ac71097c07123a23525641 |
|
||||
| sound/zombie/z_fall.wav | sound/zombie/z_fall.wav | 6968318b2d196c6d54bc707d8a390547 |
|
||||
| sound/zombie/z_gib.wav | sound/zombie/z_gib.wav | 199dda66ade8d6f0ef4897e4d7608c0d |
|
||||
| sound/zombie/z_hit.wav | sound/zombie/z_hit.wav | 6c66ab3e6b149bf35956a4bbc0057acb |
|
||||
| sound/zombie/z_idle1.wav | sound/zombie/z_idle1.wav | 21088a7b38b1124d7ec72e58d5ab93a6 |
|
||||
| sound/zombie/z_idle.wav | sound/zombie/z_idle.wav | e5e570e38c4405111004190a79f0e925 |
|
||||
| sound/zombie/z_miss.wav | sound/zombie/z_miss.wav | 96fad96a8c3bc6f7bcc5da6c82678da2 |
|
||||
| sound/zombie/z_pain1.wav | sound/zombie/z_pain1.wav | fcd83b89a94b0cadbe1361a4df080ec0 |
|
||||
| sound/zombie/z_pain.wav | sound/zombie/z_pain.wav | 56637968b8309bd2f825153330bbdfc0 |
|
||||
| sound/zombie/z_shot1.wav | sound/zombie/z_shot1.wav | 561afb69b7851923a8fb3b54e3e13c96 |
|
||||
|
||||
Look to [infighter](https://github.com/decino/q2-infighter) for more info.
|
||||
|
||||
# Yamagi Quake II
|
||||
|
||||
|
|
|
@ -39,18 +39,17 @@ Yamagi Quake II ships with 4 renderers:
|
|||
|
||||
## Choosing a Sound System
|
||||
|
||||
Yamagi Quake II ships with 2 sound system:
|
||||
Yamagi Quake II ships with 2 sound systems:
|
||||
|
||||
* The **OpenAL** sound system: This is the default and highly
|
||||
recommended. It provides full surround sound support and even HRTF for
|
||||
recommended. It provides full surround sound support and HRTF for
|
||||
headphones. But also the plain stereo playback is much better than in
|
||||
the original sound system. The setup is done mostly through OpenAL,
|
||||
have a look at the documentation of your OpenAL library.
|
||||
* The **SDL** sound system: This is the classic sound system, providing
|
||||
an experience like the original client. Set `s_openal` to `0` and
|
||||
execute an `snd_restart` to activate it. The classic sound system may
|
||||
be somewhat problematic on modern systems like Windows 10 or Linux
|
||||
with Pulseaudio.
|
||||
an experience like the original client. It's less CPU demanding than
|
||||
OpenAL. Choose it in the options menu, or set `s_openal` to `0` and
|
||||
execute an `snd_restart`, to activate it.
|
||||
|
||||
|
||||
## Tuning for Precise Timings
|
||||
|
|
|
@ -106,6 +106,9 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable`
|
|||
* **cl_http_max_connections**: Maximum number of parallel downloads. Set
|
||||
to `4` by default. A higher number may help with slow servers.
|
||||
|
||||
* **cl_http_verifypeer**: SSL certificate validation. Set to `1`
|
||||
by default, set to `0` to disable.
|
||||
|
||||
* **cl_http_proxy**: Proxy to use, empty by default.
|
||||
|
||||
* **cl_http_show_dw_progress**: Show a HTTP download progress bar.
|
||||
|
@ -146,6 +149,10 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable`
|
|||
preview. `-1` - don't show animation. Defaults to `94` for show
|
||||
salute animation.
|
||||
|
||||
* **cl_model_mesh_hide**: Mesh mask to hide in multiplayer model preview.
|
||||
`0` - show whole model, `2` - hide second mesh from model. Defaults
|
||||
to `0` for show whole model.
|
||||
|
||||
* **cl_nodownload_list**: Whitespace separated list of substrings, files
|
||||
having one these strings in their name are never downloaded. Empty by
|
||||
default. Note that some substrings are always forbidden, for security
|
||||
|
@ -249,6 +256,14 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable`
|
|||
By default this cvar is set to `1`, and will only work if the
|
||||
game.dll implements this behaviour.
|
||||
|
||||
* **g_language**: Default language for ReRelease game, requires `Q2Game.kpf`
|
||||
or other source of `localization/loc_english.txt` like file.
|
||||
Defaults to `english`.
|
||||
|
||||
* **g_itemsbobeffect**: Bob effect of items like in ReRelease. Defaults to `0`.
|
||||
|
||||
* **g_start_items**: List of start items on level.
|
||||
|
||||
* **g_swap_speed**: Sets the speed of the "changing weapon" animation.
|
||||
Default is `1`. If set to `2`, it will be double the speed, `3` is
|
||||
the triple... up until the max of `8`, since there are at least 2
|
||||
|
@ -481,6 +496,8 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable`
|
|||
|
||||
* **r_flashblend**: Flash blend enable in gl1, gl3 and vulkan.
|
||||
|
||||
* **r_ttffont**: Use `ttf` font for game messages.
|
||||
|
||||
## Graphics (GL renderers only)
|
||||
|
||||
* **gl_zfix**: Sometimes two or even more surfaces overlap and flicker.
|
||||
|
@ -532,7 +549,12 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable`
|
|||
squares.
|
||||
|
||||
* **gl1_stencilshadow**: If `gl_shadows` is set to `1`, this makes them
|
||||
look a bit better (no flickering) by using the stencil buffer.
|
||||
look a bit better (no flickering) by using the stencil buffer. Does
|
||||
not work when `gl1_stereo` is `3`, `4` or `5`.
|
||||
|
||||
* **gl1_waterwarp**: Intensity of the "squeeze/stretch" effect on the
|
||||
FOV when diving underwater. Can be any floating point number, `0`
|
||||
disables it (Vanilla Quake II look). Default `1.0`.
|
||||
|
||||
* **gl1_lightmapcopies**: When enabled (`1`), keep 3 copies of the same
|
||||
lightmap rotating, shifting to another one when drawing a new frame.
|
||||
|
@ -540,9 +562,10 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable`
|
|||
(dynamic lighting) causes slowdown. By default in GL1 is disabled,
|
||||
while in GLES1 is enabled. Needs `gl1_multitexture 1` & `vid_restart`.
|
||||
|
||||
* **gl1_discardfb**: Only available in ES1. If set to `1` (default),
|
||||
send a hint to discard framebuffers after finishing a frame. Useful
|
||||
for GPUs that attempt to reuse them, something Quake 2 doesn't do.
|
||||
* **gl1_discardfb**: If `1`, clear color, depth and stencil buffers at
|
||||
the start of a frame, and discard them at the end if possible. If
|
||||
`2`, do only depth and stencil, no color. Increases performance in
|
||||
mobile / embedded. Default in GL1 is `0`, while in GLES1 is `1`.
|
||||
|
||||
|
||||
## Graphics (OpenGL 3.2 and OpenGL ES3 only)
|
||||
|
@ -596,18 +619,33 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable`
|
|||
* **sw_colorlight**: enable experimental color lighting.
|
||||
|
||||
|
||||
## Game Controller
|
||||
## Gamepad
|
||||
|
||||
* **in_initjoy**: Toggles initialization of game controller. Default is
|
||||
`1`, which enables gamepad usage; `0` disables its detection at
|
||||
startup. Can only be set from command line.
|
||||
|
||||
* **in_sdlbackbutton**: Defines which button is used in the gamepad as
|
||||
* **joy_escbutton**: Defines which button is used in the gamepad as
|
||||
the `Esc` key, to pull the main menu and 'cancel' / 'go back' on its
|
||||
options. Valid values are `0` = Back / Select / Minus, `1` = Start /
|
||||
Menu / Plus (default), or `2` = Guide / Home / PS. Requires a game
|
||||
options. Valid values are `0` = Start / Menu / Plus (default), `1` =
|
||||
Back / Select / Minus, or `2` = Guide / Home / PS. Requires a game
|
||||
restart, or gamepad replug, when changed.
|
||||
|
||||
* **joy_labels**: Defines style of button labels in binding menus. Note
|
||||
that binding through console only uses the SDL nomenclature (`0`).
|
||||
Default is `-1`, which requires at least SDL 2.0.12 to work.
|
||||
- `-1`: *Autodetect*, sets to `0` if gamepad type isn't detected
|
||||
- `0`: *SDL*, face buttons appear as cardinal points
|
||||
- `1`: *Xbox*, with One / Series X / S labels
|
||||
- `2`: *Playstation*, 4 & 5 format
|
||||
- `3`: *Switch*, traditional Nintendo button format
|
||||
|
||||
* **joy_confirm**: Style of *confirm* and *cancel* buttons in menus. As
|
||||
with the previous one, SDL 2.0.12 is required for `-1` to work.
|
||||
- `-1`: *Autodetect*, sets to `1` if Nintendo, `0` otherwise
|
||||
- `0`: SOUTH to confirm, EAST to cancel (standard style)
|
||||
- `1`: EAST to confirm, SOUTH to cancel (Japanese style)
|
||||
|
||||
* **joy_layout**: Allows to select the stick layout of the gamepad.
|
||||
- `0`: *Default*, left stick moves, right aims
|
||||
- `1`: *Southpaw*, same as previous one with inverted sticks
|
||||
|
|
|
@ -48,3 +48,16 @@ original clients (Vanilla Quake II) commands are still in place.
|
|||
* **listlights**: Show lights style and dlights list.
|
||||
|
||||
* **thirdperson**: Third person view.
|
||||
|
||||
## Jabot
|
||||
|
||||
* **sv makenodes**: Start creating a navigation file from scratch.
|
||||
|
||||
* **sv editnodes**: Modify the loaded navigation file.
|
||||
|
||||
* **sv savenodes**: Save nodes file
|
||||
|
||||
* **sv addbot <team> <name> <skin>**: Spawn a bot (consult ACEbot readme,
|
||||
it's just the same thing)
|
||||
|
||||
* **sv removebot <name>**: Remove a bot ("all" removes every bot in the map).
|
||||
|
|
|
@ -35,6 +35,8 @@ level.
|
|||
/ref_gl1.dll
|
||||
/ref_gl3.dll
|
||||
/ref_gles3.dll
|
||||
/ref_gl4.dll
|
||||
/ref_vk.dll
|
||||
/ref_soft.dll
|
||||
|
||||
# The Executables:
|
||||
|
@ -391,6 +393,238 @@ level.
|
|||
|
||||
```
|
||||
|
||||
# Remaster
|
||||
|
||||
Remaster does not requires files from original release. In game directory
|
||||
should be placed only files provided with rerelease.
|
||||
|
||||
```
|
||||
/baseq2/music/D_DDTBLU.ogg
|
||||
/baseq2/music/track02.ogg
|
||||
/baseq2/music/track03.ogg
|
||||
/baseq2/music/track04.ogg
|
||||
/baseq2/music/track05.ogg
|
||||
/baseq2/music/track06.ogg
|
||||
/baseq2/music/track07.ogg
|
||||
/baseq2/music/track08.ogg
|
||||
/baseq2/music/track09.ogg
|
||||
/baseq2/music/track10.ogg
|
||||
/baseq2/music/track11.ogg
|
||||
/baseq2/music/track12.ogg
|
||||
/baseq2/music/track13.ogg
|
||||
/baseq2/music/track14.ogg
|
||||
/baseq2/music/track15.ogg
|
||||
/baseq2/music/track16.ogg
|
||||
/baseq2/music/track17.ogg
|
||||
/baseq2/music/track18.ogg
|
||||
/baseq2/music/track19.ogg
|
||||
/baseq2/music/track20.ogg
|
||||
/baseq2/music/track21.ogg
|
||||
/baseq2/music/track64.ogg
|
||||
/baseq2/music/track65.ogg
|
||||
/baseq2/music/track66.ogg
|
||||
/baseq2/music/track67.ogg
|
||||
/baseq2/music/track68.ogg
|
||||
/baseq2/music/track69.ogg
|
||||
/baseq2/music/track70.ogg
|
||||
/baseq2/music/track71.ogg
|
||||
/baseq2/music/track72.ogg
|
||||
/baseq2/music/track73.ogg
|
||||
/baseq2/music/track74.ogg
|
||||
/baseq2/music/track75.ogg
|
||||
/baseq2/music/track76.ogg
|
||||
/baseq2/music/track77.ogg
|
||||
/baseq2/music/track78.ogg
|
||||
/baseq2/music/track79.ogg
|
||||
/baseq2/video/ects.ogv
|
||||
/baseq2/video/end_de.srt
|
||||
/baseq2/video/end_es.srt
|
||||
/baseq2/video/end_fr.srt
|
||||
/baseq2/video/end_it.srt
|
||||
/baseq2/video/end.ogv
|
||||
/baseq2/video/end_ru.srt
|
||||
/baseq2/video/end.srt
|
||||
/baseq2/video/eou1__de.srt
|
||||
/baseq2/video/eou1__es.srt
|
||||
/baseq2/video/eou1__fr.srt
|
||||
/baseq2/video/eou1__it.srt
|
||||
/baseq2/video/eou1_.ogv
|
||||
/baseq2/video/eou1__ru.srt
|
||||
/baseq2/video/eou1_.srt
|
||||
/baseq2/video/eou2__de.srt
|
||||
/baseq2/video/eou2__es.srt
|
||||
/baseq2/video/eou2__fr.srt
|
||||
/baseq2/video/eou2__it.srt
|
||||
/baseq2/video/eou2_.ogv
|
||||
/baseq2/video/eou2__ru.srt
|
||||
/baseq2/video/eou2_.srt
|
||||
/baseq2/video/eou3__de.srt
|
||||
/baseq2/video/eou3__es.srt
|
||||
/baseq2/video/eou3__fr.srt
|
||||
/baseq2/video/eou3__it.srt
|
||||
/baseq2/video/eou3_.ogv
|
||||
/baseq2/video/eou3__ru.srt
|
||||
/baseq2/video/eou3_.srt
|
||||
/baseq2/video/eou4__de.srt
|
||||
/baseq2/video/eou4__es.srt
|
||||
/baseq2/video/eou4__fr.srt
|
||||
/baseq2/video/eou4__it.srt
|
||||
/baseq2/video/eou4_.ogv
|
||||
/baseq2/video/eou4__ru.srt
|
||||
/baseq2/video/eou4_.srt
|
||||
/baseq2/video/eou5__de.srt
|
||||
/baseq2/video/eou5__es.srt
|
||||
/baseq2/video/eou5__fr.srt
|
||||
/baseq2/video/eou5__it.srt
|
||||
/baseq2/video/eou5_.ogv
|
||||
/baseq2/video/eou5__ru.srt
|
||||
/baseq2/video/eou5_.srt
|
||||
/baseq2/video/eou6__de.srt
|
||||
/baseq2/video/eou6__es.srt
|
||||
/baseq2/video/eou6__fr.srt
|
||||
/baseq2/video/eou6__it.srt
|
||||
/baseq2/video/eou6_.ogv
|
||||
/baseq2/video/eou6__ru.srt
|
||||
/baseq2/video/eou6_.srt
|
||||
/baseq2/video/eou7__de.srt
|
||||
/baseq2/video/eou7__es.srt
|
||||
/baseq2/video/eou7__fr.srt
|
||||
/baseq2/video/eou7__it.srt
|
||||
/baseq2/video/eou7_.ogv
|
||||
/baseq2/video/eou7__ru.srt
|
||||
/baseq2/video/eou7_.srt
|
||||
/baseq2/video/eou8__de.srt
|
||||
/baseq2/video/eou8__es.srt
|
||||
/baseq2/video/eou8__fr.srt
|
||||
/baseq2/video/eou8__it.srt
|
||||
/baseq2/video/eou8_.ogv
|
||||
/baseq2/video/eou8__ru.srt
|
||||
/baseq2/video/eou8_.srt
|
||||
/baseq2/video/n64/n64l0t.ogv
|
||||
/baseq2/video/n64/n64l10t.ogv
|
||||
/baseq2/video/n64/n64l11t.ogv
|
||||
/baseq2/video/n64/n64l12t.ogv
|
||||
/baseq2/video/n64/n64l13t.ogv
|
||||
/baseq2/video/n64/n64l14t.ogv
|
||||
/baseq2/video/n64/n64l15t.ogv
|
||||
/baseq2/video/n64/n64l16t.ogv
|
||||
/baseq2/video/n64/n64l17t.ogv
|
||||
/baseq2/video/n64/n64l18t.ogv
|
||||
/baseq2/video/n64/n64l1t.ogv
|
||||
/baseq2/video/n64/n64l2t.ogv
|
||||
/baseq2/video/n64/n64l3t.ogv
|
||||
/baseq2/video/n64/n64l4t.ogv
|
||||
/baseq2/video/n64/n64l5t.ogv
|
||||
/baseq2/video/n64/n64l6t.ogv
|
||||
/baseq2/video/n64/n64l7t.ogv
|
||||
/baseq2/video/n64/n64l8t.ogv
|
||||
/baseq2/video/n64/n64l9t.ogv
|
||||
/baseq2/video/ntro_de.srt
|
||||
/baseq2/video/ntro_es.srt
|
||||
/baseq2/video/ntro_fr.srt
|
||||
/baseq2/video/ntro_it.srt
|
||||
/baseq2/video/ntro.ogv
|
||||
/baseq2/video/ntro_ru.srt
|
||||
/baseq2/video/ntro.srt
|
||||
/baseq2/video/rend_de.srt
|
||||
/baseq2/video/rend_es.srt
|
||||
/baseq2/video/rend_fr.srt
|
||||
/baseq2/video/rend_it.srt
|
||||
/baseq2/video/rend.ogv
|
||||
/baseq2/video/rend_ru.srt
|
||||
/baseq2/video/rend.srt
|
||||
/baseq2/video/reu1__de.srt
|
||||
/baseq2/video/reu1__es.srt
|
||||
/baseq2/video/reu1__fr.srt
|
||||
/baseq2/video/reu1__it.srt
|
||||
/baseq2/video/reu1_.ogv
|
||||
/baseq2/video/reu1__ru.srt
|
||||
/baseq2/video/reu1_.srt
|
||||
/baseq2/video/reu2__de.srt
|
||||
/baseq2/video/reu2__es.srt
|
||||
/baseq2/video/reu2__fr.srt
|
||||
/baseq2/video/reu2__it.srt
|
||||
/baseq2/video/reu2_.ogv
|
||||
/baseq2/video/reu2__ru.srt
|
||||
/baseq2/video/reu2_.srt
|
||||
/baseq2/video/reu3__de.srt
|
||||
/baseq2/video/reu3__es.srt
|
||||
/baseq2/video/reu3__fr.srt
|
||||
/baseq2/video/reu3__it.srt
|
||||
/baseq2/video/reu3_.ogv
|
||||
/baseq2/video/reu3__ru.srt
|
||||
/baseq2/video/reu3_.srt
|
||||
/baseq2/video/reu4__de.srt
|
||||
/baseq2/video/reu4__es.srt
|
||||
/baseq2/video/reu4__fr.srt
|
||||
/baseq2/video/reu4__it.srt
|
||||
/baseq2/video/reu4_.ogv
|
||||
/baseq2/video/reu4__ru.srt
|
||||
/baseq2/video/reu4_.srt
|
||||
/baseq2/video/rintro_de.srt
|
||||
/baseq2/video/rintro_es.srt
|
||||
/baseq2/video/rintro_fr.srt
|
||||
/baseq2/video/rintro_it.srt
|
||||
/baseq2/video/rintro.ogv
|
||||
/baseq2/video/rintro_ru.srt
|
||||
/baseq2/video/rintro.srt
|
||||
/baseq2/video/xin_de.srt
|
||||
/baseq2/video/xin_es.srt
|
||||
/baseq2/video/xin_fr.srt
|
||||
/baseq2/video/xin_it.srt
|
||||
/baseq2/video/xin.ogv
|
||||
/baseq2/video/xin_ru.srt
|
||||
/baseq2/video/xin.srt
|
||||
/baseq2/video/xout_de.srt
|
||||
/baseq2/video/xout_es.srt
|
||||
/baseq2/video/xout_fr.srt
|
||||
/baseq2/video/xout_it.srt
|
||||
/baseq2/video/xout.ogv
|
||||
/baseq2/video/xout_ru.srt
|
||||
/baseq2/video/xout.srt
|
||||
/baseq2/video/xu1_de.srt
|
||||
/baseq2/video/xu1_es.srt
|
||||
/baseq2/video/xu1_fr.srt
|
||||
/baseq2/video/xu1_it.srt
|
||||
/baseq2/video/xu1.ogv
|
||||
/baseq2/video/xu1_ru.srt
|
||||
/baseq2/video/xu1.srt
|
||||
/baseq2/video/xu2_de.srt
|
||||
/baseq2/video/xu2_es.srt
|
||||
/baseq2/video/xu2_fr.srt
|
||||
/baseq2/video/xu2_it.srt
|
||||
/baseq2/video/xu2.ogv
|
||||
/baseq2/video/xu2_ru.srt
|
||||
/baseq2/video/xu2.srt
|
||||
/baseq2/video/xu3_de.srt
|
||||
/baseq2/video/xu3_es.srt
|
||||
/baseq2/video/xu3_fr.srt
|
||||
/baseq2/video/xu3_it.srt
|
||||
/baseq2/video/xu3.ogv
|
||||
/baseq2/video/xu3_ru.srt
|
||||
/baseq2/video/xu3.srt
|
||||
/baseq2/video/xu4_de.srt
|
||||
/baseq2/video/xu4_es.srt
|
||||
/baseq2/video/xu4_fr.srt
|
||||
/baseq2/video/xu4_it.srt
|
||||
/baseq2/video/xu4.ogv
|
||||
/baseq2/video/xu4_ru.srt
|
||||
/baseq2/video/xu4.srt
|
||||
/baseq2/pak0.pak
|
||||
/Q2Game.kpf
|
||||
```
|
||||
|
||||
Additionally could be added files from [PSX](https://www.moddb.com/mods/quake-ii-psx)
|
||||
|
||||
```
|
||||
/psx/pak0.pak
|
||||
/psx/video/psx/boss.ogv
|
||||
/psx/video/psx/command.ogv
|
||||
/psx/video/psx/intro.ogv
|
||||
/psx/video/psx/jail.ogv
|
||||
/psx/video/psx/power.ogv
|
||||
```
|
||||
|
||||
|
||||
## Checksums
|
||||
|
||||
|
|
|
@ -1,345 +0,0 @@
|
|||
# Map state:
|
||||
|
||||
* OK - no known issues,
|
||||
* ML - model light issues,
|
||||
* WL - wall light issues,
|
||||
* G - texture glitches,
|
||||
* B - can't load.
|
||||
|
||||
## Quake2 ReRelease
|
||||
|
||||
| map | gl1.4 | gl3/gles3 | gl4.6 | vk | soft |
|
||||
| ------------------------------ | ------ | --------- | ------ | ------ | ----------- |
|
||||
| badlands.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| base1.bsp | OK | OK | N/A | OK | WL/ML/G |
|
||||
| base2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| base3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| base64.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| biggun.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| boss1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| boss2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| bunk1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| city1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| city2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| city3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| city64.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| command.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| cool1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| e3/bunk_e3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| e3/fact_e3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| e3/jail4_e3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| e3/jail_e3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| e3/lab_e3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| e3/mine_e3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| e3/space_e3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| e3/ware1a_e3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| e3/ware2_e3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| e3/waste_e3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| ec/base3_ec.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| ec/base_ec.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| ec/command_ec.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| ec/factx_ec.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| ec/jail_ec.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| ec/kmdm3_ec.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| ec/mine1_ec.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| ec/power_ec.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| ec/space_ec.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| ec/waste_ec.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| fact1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| fact2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| fact3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| hangar1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| hangar2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| industry.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| jail1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| jail2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| jail3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| jail4.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| jail5.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| lab.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| mgdm1.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu1m1.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu1m2.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu1m3.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu1m4.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu1m5.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu1trial.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu2m1.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu2m2.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu2m3.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu3m1.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu3m2.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu3m3.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu3m4.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu3secret.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu4m1.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu4m2.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu4m3.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu4trial.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu5m1.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu5m2.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu5m3.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu5trial.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu6m1.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu6m2.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu6m3.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mgu6trial.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mguboss.bsp | OK | N/A | N/A | OK | N/A |
|
||||
| mguhub.bsp | OK | OK | ML | OK | ML |
|
||||
| mine1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| mine2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| mine3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| mine4.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| mintro.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| ndctf0.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| old/baseold.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| old/city2_4.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| old/fact1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| old/fact2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| old/fact3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| old/facthub.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| old/hangarold.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| old/kmdm3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| old/pjtrain1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| old/ware1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| old/xcommand5.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| outbase.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| power1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| power2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q2ctf1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q2ctf2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q2ctf3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q2ctf4.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q2ctf5.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q2dm1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q2dm2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q2dm3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q2dm4.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q2dm5.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q2dm6.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q2dm7.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q2dm8.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q2kctf1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q2kctf2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/bio.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/cargo.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/command.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/comm.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/complex.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/conduits.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/core.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/dm10.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/dm1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/dm2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/dm3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/dm4.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/dm5.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/dm6.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/dm7.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/dm8.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/dm9.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/geo-stat.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/intel.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/jail.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/lab.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/mines.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/orbit.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/organic.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/outpost.bsp | OK | N/A | N/A | N/A | B |
|
||||
| q64/process.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/rtest.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/ship.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/station.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| q64/storage.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rammo1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rammo2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rbase1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rbase2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rboss.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rdm10.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rdm11.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rdm12.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rdm13.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rdm14.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rdm1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rdm2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rdm3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rdm4.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rdm5.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rdm6.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rdm7.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rdm8.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rdm9.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| refinery.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rhangar1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rhangar2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rlava1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rlava2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rmine1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rmine2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rsewer1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rsewer2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rware1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| rware2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| security.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| sewer64.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| space.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| strike.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/base1_flashlight.bsp | OK | OK | OK | OK | OK |
|
||||
| test/gekk.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/mals_barrier_test.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/mals_box.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/mals_ladder_test.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/mals_locked_door_test.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/paril_health_relay.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/paril_ladder.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/paril_poi.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/paril_scaled_monsters.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/paril_soundstage.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/paril_steps.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/paril_waterlight.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/skysort.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/spbox2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/spbox.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/test_jerry.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/test_kaiser.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| test/tom_test_01.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| train.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| tutorial.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| ware1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| ware2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| waste1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| waste2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| waste3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| w_treat.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xcompnd1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xcompnd2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xdm1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xdm2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xdm3.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xdm4.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xdm5.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xdm6.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xdm7.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xhangar1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xhangar2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xintell.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xmoon1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xmoon2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xreactor.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xsewer1.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xsewer2.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xship.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xswamp.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
| xware.bsp | N/A | N/A | N/A | N/A | N/A |
|
||||
|
||||
Additionally supported models:
|
||||
|
||||
| source Quake 1 Path | destination Quake 2 Path | md5 hash |
|
||||
| -------------------------- | --------------------------------- | -------------------------------- |
|
||||
| progs/soldier.mdl | models/monsters/army/tris.mdl | 5b6c30a984872b4273dd5861412d35c5 |
|
||||
| progs/demon.mdl | models/monsters/demon/tris.mdl | 4c73786e7cfb2083ca38cbc983cd6c4b |
|
||||
| progs/dog.mdl | models/monsters/dog/tris.mdl | e727fbc39acc652f812972612ce37565 |
|
||||
| progs/enforcer.mdl | models/monsters/enforcer/tris.mdl | 136c265f96d6077ee3312c52e134529f |
|
||||
| progs/fish.mdl | models/monsters/fish/tris.mdl | d770d6ef92ae8b372926e6c3d49e8716 |
|
||||
| progs/hknight.mdl | models/monsters/hknight/tris.mdl | ed20e30be6fdb83efbaa6d0b23671a49 |
|
||||
| progs/knight.mdl | models/monsters/knight/tris.mdl | 5328915db5c53e85cf75d46e7b747fb9 |
|
||||
| progs/ogre.mdl | models/monsters/ogre/tris.mdl | fbb592ca3788a576dd2f31fcf8c80fab |
|
||||
| progs/shalrath.mdl | models/monsters/shalrath/tris.mdl | dac8f6077b0d2bf970573d2d2c22529f |
|
||||
| progs/shambler.mdl | models/monsters/shambler/tris.mdl | 9b09375a0f614dc4081e363cc34f1185 |
|
||||
| progs/tarbaby.mdl | models/monsters/tarbaby/tris.mdl | 2bfc45593a43a0191982e3cfdc112dc5 |
|
||||
| progs/wizard.mdl | models/monsters/wizard/tris.mdl | bf60986594f045e60e8aa6339d553ee7 |
|
||||
| progs/zombie.mdl | models/monsters/zombie/tris.mdl | a923b1d03b9d237dd5ead9bd56acc900 |
|
||||
| progs/k_spike.mdl | models/proj/fireball/tris.mdl | da95b49a695b34c2c3516a8d789c6b20 |
|
||||
| progs/v_spike.mdl | models/proj/pod/tris.mdl | 2bdc0b264b9fd3443c8eee816305728f |
|
||||
| progs/w_spike.mdl | models/proj/spit/tris.mdl | 8cf9245df2164e8062b01a220b508d6b |
|
||||
| sound/army/death1.wav | sound/army/death1.wav | fe25952af40b536c3bb67bfca58062eb |
|
||||
| sound/army/idle.wav | sound/army/idle.wav | 4cdfbdda8fb5f40b125c7bcddb6e8914 |
|
||||
| sound/army/pain1.wav | sound/army/pain1.wav | 54d3b05fdcecf7480034858f2b22b06c |
|
||||
| sound/army/pain2.wav | sound/army/pain2.wav | e2bbc9d3405b9b9fdae76d2fc298fc2f |
|
||||
| sound/army/sattck1.wav | sound/army/sattck1.wav | b76ac35f900f280a7a7996da7e404362 |
|
||||
| sound/army/sight1.wav | sound/army/sight1.wav | e2a39533250ddd1b08053d5c4ebf7fd0 |
|
||||
| sound/demon/ddeath.wav | sound/demon/ddeath.wav | 62a48dcd405ca55c9ce18497e36faa0e |
|
||||
| sound/demon/dhit2.wav | sound/demon/dhit2.wav | 9e741696e4d0d66e30e718fc70ec186e |
|
||||
| sound/demon/djump.wav | sound/demon/djump.wav | 791ac9d6b6593808316145443cb7e7a0 |
|
||||
| sound/demon/dland2.wav | sound/demon/dland2.wav | db14c7b01838f826b7a712075f9026fd |
|
||||
| sound/demon/dpain1.wav | sound/demon/dpain1.wav | 5e6c485878393c9bebb0d0e6659bc479 |
|
||||
| sound/demon/idle1.wav | sound/demon/idle1.wav | 7a83f8caf3d5b1172a7dc5afdc942988 |
|
||||
| sound/demon/sight2.wav | sound/demon/sight2.wav | 65171c355c22a5069520b0881677ae3c |
|
||||
| sound/dog/dattack1.wav | sound/dog/dattack1.wav | 0c47c9d4aaae0bf3159a288b674f4a35 |
|
||||
| sound/dog/ddeath.wav | sound/dog/ddeath.wav | b0e7760b1d7286a028ff9773f6802958 |
|
||||
| sound/dog/dpain1.wav | sound/dog/dpain1.wav | 28e5ab93b41e13e2916433283a5d1a46 |
|
||||
| sound/dog/dsight.wav | sound/dog/dsight.wav | 0edc290765bac1fb4fe03ca55bc7c225 |
|
||||
| sound/dog/idle.wav | sound/dog/idle.wav | 42bd6026ff32bd94523ad9f8fe8362cc |
|
||||
| sound/enforcer/death1.wav | sound/enforcer/death1.wav | f38d7a235e13ef8918aac0c70437320d |
|
||||
| sound/enforcer/enfire.wav | sound/enforcer/enfire.wav | b080a6a53f138bef9fc4403fb9373a24 |
|
||||
| sound/enforcer/enfstop.wav | sound/enforcer/enfstop.wav | 0bc39c3c88187fb37d20ef21300e7b22 |
|
||||
| sound/enforcer/idle1.wav | sound/enforcer/idle1.wav | d0435763860fe54e938ad25bb1780f9e |
|
||||
| sound/enforcer/pain1.wav | sound/enforcer/pain1.wav | d52bc02afe624924684b25295edaa040 |
|
||||
| sound/enforcer/pain2.wav | sound/enforcer/pain2.wav | f6b0ad6485d93f5c6d7d61b847d06877 |
|
||||
| sound/enforcer/sight1.wav | sound/enforcer/sight1.wav | 9e9876444ba92ed18bfce4cec3a2ff12 |
|
||||
| sound/enforcer/sight2.wav | sound/enforcer/sight2.wav | 815dd4f6a890b0a35dc466005df74850 |
|
||||
| sound/enforcer/sight3.wav | sound/enforcer/sight3.wav | f8c8d19905b24d4adb6760a1b3762f3b |
|
||||
| sound/enforcer/sight4.wav | sound/enforcer/sight4.wav | 04e40eb925290bc56520de326df6b220 |
|
||||
| sound/fish/bite.wav | sound/fish/bite.wav | 7c56712615e2a2c3de4fe0e7e35cba05 |
|
||||
| sound/fish/death.wav | sound/fish/death.wav | 8d6152ee55507430a8c2eb276c4aa8ac |
|
||||
| sound/fish/idle.wav | sound/fish/idle.wav | 54a02731b85eb6f8b1a8ecce09771d20 |
|
||||
| sound/hknight/attack1.wav | sound/hknight/attack1.wav | 695e9d890a085addf1a607aa79137e8e |
|
||||
| sound/hknight/death1.wav | sound/hknight/death1.wav | 2d68c3c86632027676b823fcff3af08c |
|
||||
| sound/hknight/grunt.wav | sound/hknight/grunt.wav | 122f3d4623e0146732aa0e4deb0fe326 |
|
||||
| sound/hknight/hit.wav | sound/hknight/hit.wav | fece24e2548f1d769e8fce39a5c87d01 |
|
||||
| sound/hknight/idle.wav | sound/hknight/idle.wav | e9ca23c4853472750d1f56e52a3d227b |
|
||||
| sound/hknight/pain1.wav | sound/hknight/pain1.wav | 52c20eb6f5b5146ece6b0ac02f423341 |
|
||||
| sound/hknight/sight1.wav | sound/hknight/sight1.wav | 786d28ec653a0d512d078b32eb8cb58b |
|
||||
| sound/hknight/slash1.wav | sound/hknight/slash1.wav | 83e64bb90cff2a4f9764dd53489b9d7d |
|
||||
| sound/knight/idle.wav | sound/knight/idle.wav | 1b5c3981bee078318af346d8fe8090b9 |
|
||||
| sound/knight/kdeath.wav | sound/knight/kdeath.wav | 11a96f48a8f2433c23beae299c8fb96e |
|
||||
| sound/knight/khurt.wav | sound/knight/khurt.wav | 32c9f48dd4a6a87752aedf56fe8de668 |
|
||||
| sound/knight/ksight.wav | sound/knight/ksight.wav | eb75b4af348c88e84d8c87c19d5976fa |
|
||||
| sound/knight/sword1.wav | sound/knight/sword1.wav | 93045b5f3178413dc6b01ec2869d1f73 |
|
||||
| sound/knight/sword2.wav | sound/knight/sword2.wav | 82d1a7c263cd3df7b060dee2f7f8b1fd |
|
||||
| sound/ogre/ogdrag.wav | sound/ogre/ogdrag.wav | 658587dc89aaefae5ca3f058f7ff4227 |
|
||||
| sound/ogre/ogdth.wav | sound/ogre/ogdth.wav | de98e7bb9e70586edddd3308cfded3db |
|
||||
| sound/ogre/ogidle2.wav | sound/ogre/ogidle2.wav | 196ae9c33a4311160e1d5f3da878ab09 |
|
||||
| sound/ogre/ogidle.wav | sound/ogre/ogidle.wav | 177c829840a87c885bbc8951e7ce962e |
|
||||
| sound/ogre/ogpain1.wav | sound/ogre/ogpain1.wav | ac6d133d7720c12df49813fe10e683b5 |
|
||||
| sound/ogre/ogsawatk.wav | sound/ogre/ogsawatk.wav | 7257bdfd014bb61d778b8f88cb65d560 |
|
||||
| sound/ogre/ogwake.wav | sound/ogre/ogwake.wav | 3296459e495c4c12b31179d4eeffac19 |
|
||||
| sound/shalrath/attack2.wav | sound/shalrath/attack2.wav | 777fbda2f81350e45920ea1c36d318e1 |
|
||||
| sound/shalrath/attack.wav | sound/shalrath/attack.wav | 8814a72b399be619d14223235f78f294 |
|
||||
| sound/shalrath/death.wav | sound/shalrath/death.wav | 771844c5cfb5a42e82e221a63f101ac7 |
|
||||
| sound/shalrath/idle.wav | sound/shalrath/idle.wav | 1a45f12579f9cdd27152332d5f816048 |
|
||||
| sound/shalrath/pain.wav | sound/shalrath/pain.wav | 6ba007b79c50d7d5347f1a29fb315422 |
|
||||
| sound/shalrath/sight.wav | sound/shalrath/sight.wav | 3d3c2001cc976efc67af1552427eedd3 |
|
||||
| sound/shambler/melee1.wav | sound/shambler/melee1.wav | 77fe6240973a204b757a427ebf66bcfd |
|
||||
| sound/shambler/melee2.wav | sound/shambler/melee2.wav | 3be31638d769e3d690c92311dfafdeac |
|
||||
| sound/shambler/sattck1.wav | sound/shambler/sattck1.wav | ec8c3f79ea42d09154cb8975ada1b21c |
|
||||
| sound/shambler/sboom.wav | sound/shambler/sboom.wav | 9834601a645d7d1f62001b2a314ec18f |
|
||||
| sound/shambler/sdeath.wav | sound/shambler/sdeath.wav | e0e62d229a985a6e39218c6488599059 |
|
||||
| sound/shambler/shurt2.wav | sound/shambler/shurt2.wav | 1e87631ede95e061a75f9c31629ac0b8 |
|
||||
| sound/shambler/sidle.wav | sound/shambler/sidle.wav | 368a240e6c3e877793352a79c1828386 |
|
||||
| sound/shambler/smack.wav | sound/shambler/smack.wav | bd8c634c9894348360fec7b7419d1649 |
|
||||
| sound/shambler/ssight.wav | sound/shambler/ssight.wav | 657107577460d5acf3157dec97e07a89 |
|
||||
| sound/tarbaby/death1.wav | sound/tarbaby/death1.wav | 53f8c73de11c018086ba19ed036833d3 |
|
||||
| sound/tarbaby/hit1.wav | sound/tarbaby/hit1.wav | 42c5a1edd02421bf6df7ddc3e395c4f8 |
|
||||
| sound/tarbaby/land1.wav | sound/tarbaby/land1.wav | 5a1585ab22368a48827db9b7d3763b58 |
|
||||
| sound/tarbaby/sight1.wav | sound/tarbaby/sight1.wav | df4dd7ec91e094b5c2235be3f5353e4a |
|
||||
| sound/wizard/hit.wav | sound/wizard/hit.wav | 6598d669334df977f1f97b95288edf11 |
|
||||
| sound/wizard/wattack.wav | sound/wizard/wattack.wav | b3568a47439f81779d40335e76f5bc2d |
|
||||
| sound/wizard/wdeath.wav | sound/wizard/wdeath.wav | 99d9c71343bc23222abb92119d404400 |
|
||||
| sound/wizard/widle1.wav | sound/wizard/widle1.wav | b22b1dd9f66879b3447d36ab584316c7 |
|
||||
| sound/wizard/widle2.wav | sound/wizard/widle2.wav | 7178fd83df227360564adef01bed92c6 |
|
||||
| sound/wizard/wpain.wav | sound/wizard/wpain.wav | bd7e59ab7d7b835f9ed8ab51950914de |
|
||||
| sound/wizard/wsight.wav | sound/wizard/wsight.wav | df5949057c750528917c6cb32b7fd9fd |
|
||||
| sound/zombie/idle_w2.wav | sound/zombie/idle_w2.wav | d2bb59b9d7ac71097c07123a23525641 |
|
||||
| sound/zombie/z_fall.wav | sound/zombie/z_fall.wav | 6968318b2d196c6d54bc707d8a390547 |
|
||||
| sound/zombie/z_gib.wav | sound/zombie/z_gib.wav | 199dda66ade8d6f0ef4897e4d7608c0d |
|
||||
| sound/zombie/z_hit.wav | sound/zombie/z_hit.wav | 6c66ab3e6b149bf35956a4bbc0057acb |
|
||||
| sound/zombie/z_idle1.wav | sound/zombie/z_idle1.wav | 21088a7b38b1124d7ec72e58d5ab93a6 |
|
||||
| sound/zombie/z_idle.wav | sound/zombie/z_idle.wav | e5e570e38c4405111004190a79f0e925 |
|
||||
| sound/zombie/z_miss.wav | sound/zombie/z_miss.wav | 96fad96a8c3bc6f7bcc5da6c82678da2 |
|
||||
| sound/zombie/z_pain1.wav | sound/zombie/z_pain1.wav | fcd83b89a94b0cadbe1361a4df080ec0 |
|
||||
| sound/zombie/z_pain.wav | sound/zombie/z_pain.wav | 56637968b8309bd2f825153330bbdfc0 |
|
||||
| sound/zombie/z_shot1.wav | sound/zombie/z_shot1.wav | 561afb69b7851923a8fb3b54e3e13c96 |
|
||||
|
||||
Look to [infighter](https://github.com/decino/q2-infighter) for more info.
|
|
@ -30,7 +30,7 @@
|
|||
#include "../../common/header/shared.h"
|
||||
#include "../../common/header/common.h"
|
||||
|
||||
#if defined(__linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__sun)
|
||||
#if defined(__linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__sun) || defined(__APPLE__)
|
||||
#include <unistd.h> // readlink(), amongst others
|
||||
#endif
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
|||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h> // GetModuleFileNameA()
|
||||
#include <wchar.h> // _wgetcwd()
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
@ -146,6 +147,32 @@ static void SetExecutablePath(char* exePath)
|
|||
#endif
|
||||
}
|
||||
|
||||
static qboolean
|
||||
Sys_GetCwd(char *buf, size_t size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
WCHAR wpath[PATH_MAX];
|
||||
DWORD len;
|
||||
|
||||
if (_wgetcwd(wpath, PATH_MAX) == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
len = WideCharToMultiByte(CP_UTF8, 0, wpath, -1, buf, size, NULL, NULL);
|
||||
if (len <= 0 || len == size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if (getcwd(buf, size) == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return Q_strlcat(buf, "/", size) == 1;
|
||||
}
|
||||
|
||||
|
||||
const char *Sys_GetBinaryDir(void)
|
||||
{
|
||||
static char exeDir[PATH_MAX] = {0};
|
||||
|
@ -157,8 +184,11 @@ const char *Sys_GetBinaryDir(void)
|
|||
SetExecutablePath(exeDir);
|
||||
|
||||
if (exeDir[0] == '\0') {
|
||||
Com_Printf("Couldn't determine executable path. Using ./ instead.\n");
|
||||
Q_strlcpy(exeDir, "./", sizeof(exeDir));
|
||||
if (Sys_GetCwd(exeDir, sizeof(exeDir)) == false)
|
||||
{
|
||||
Q_strlcpy(exeDir, "./", sizeof(exeDir));
|
||||
}
|
||||
Com_Printf("Couldn't determine executable path. Using %s instead.\n", exeDir);
|
||||
} else {
|
||||
// cut off executable name
|
||||
char *lastSlash = strrchr(exeDir, '/');
|
||||
|
|
|
@ -397,7 +397,7 @@ NET_StringToSockaddr(const char *s, struct sockaddr_storage *sadr)
|
|||
if (!*space)
|
||||
{
|
||||
Com_Printf("NET_StringToSockaddr: invalid IPv6 address %s\n", s);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
*space++ = '\0';
|
||||
|
@ -417,7 +417,7 @@ NET_StringToSockaddr(const char *s, struct sockaddr_storage *sadr)
|
|||
/* Error */
|
||||
Com_Printf("NET_StringToSockaddr: string %s:\n%s\n", s,
|
||||
gai_strerror(err));
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (resultp->ai_family)
|
||||
|
@ -432,7 +432,7 @@ NET_StringToSockaddr(const char *s, struct sockaddr_storage *sadr)
|
|||
default:
|
||||
Com_Printf("NET_StringToSockaddr: string %s:\nprotocol family %d not supported\n",
|
||||
s, resultp->ai_family);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
freeaddrinfo(resultp);
|
||||
|
|
|
@ -79,7 +79,7 @@ Hunk_Begin(int maxsize)
|
|||
prot |= PROT_MAX(prot);
|
||||
#endif
|
||||
|
||||
membase = mmap(0, maxhunksize, prot,
|
||||
membase = (byte *)mmap(0, maxhunksize, prot,
|
||||
flags, -1, 0);
|
||||
|
||||
if ((membase == NULL) || (membase == (byte *)-1))
|
||||
|
|
|
@ -406,8 +406,7 @@ Sys_GetGameAPI(void *parms)
|
|||
fnAPI GetGameAPI;
|
||||
|
||||
char name[MAX_OSPATH];
|
||||
char *path;
|
||||
char *str_p;
|
||||
const char *path, *str_p;
|
||||
#ifdef __APPLE__
|
||||
const char *gamename = "game.dylib";
|
||||
#else
|
||||
|
@ -618,21 +617,21 @@ Sys_Realpath(const char *in, char *out, size_t size)
|
|||
void *
|
||||
Sys_GetProcAddress(void *handle, const char *sym)
|
||||
{
|
||||
if (handle == NULL)
|
||||
{
|
||||
if (handle == NULL)
|
||||
{
|
||||
#ifdef RTLD_DEFAULT
|
||||
return dlsym(RTLD_DEFAULT, sym);
|
||||
return dlsym(RTLD_DEFAULT, sym);
|
||||
#else
|
||||
/* POSIX suggests that this is a portable equivalent */
|
||||
static void *global_namespace = NULL;
|
||||
/* POSIX suggests that this is a portable equivalent */
|
||||
static void *global_namespace = NULL;
|
||||
|
||||
if (global_namespace == NULL)
|
||||
global_namespace = dlopen(NULL, RTLD_GLOBAL|RTLD_LAZY);
|
||||
if (global_namespace == NULL)
|
||||
global_namespace = dlopen(NULL, RTLD_GLOBAL|RTLD_LAZY);
|
||||
|
||||
return dlsym(global_namespace, sym);
|
||||
return dlsym(global_namespace, sym);
|
||||
#endif
|
||||
}
|
||||
return dlsym(handle, sym);
|
||||
}
|
||||
return dlsym(handle, sym);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -193,7 +193,7 @@ NET_CompareAdr(netadr_t a, netadr_t b)
|
|||
|
||||
if (a.type == NA_LOOPBACK)
|
||||
{
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a.type == NA_IP)
|
||||
|
@ -240,7 +240,7 @@ NET_CompareBaseAdr(netadr_t a, netadr_t b)
|
|||
|
||||
if (a.type == NA_LOOPBACK)
|
||||
{
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a.type == NA_IP)
|
||||
|
@ -411,7 +411,7 @@ NET_StringToSockaddr(const char *s, struct sockaddr_storage *sadr)
|
|||
if (!*space)
|
||||
{
|
||||
Com_Printf("NET_StringToSockaddr: invalid IPv6 address %s\n", s);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
*space++ = '\0';
|
||||
|
@ -431,7 +431,7 @@ NET_StringToSockaddr(const char *s, struct sockaddr_storage *sadr)
|
|||
/* Error */
|
||||
Com_Printf("NET_StringToSockaddr: string %s:\n%s\n", s,
|
||||
gai_strerror(err));
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (resultp->ai_family)
|
||||
|
@ -800,7 +800,7 @@ NET_SendPacket(netsrc_t sock, int length, void *data, netadr_t to)
|
|||
|
||||
/* ============================================================================= */
|
||||
|
||||
int
|
||||
static int
|
||||
NET_IPSocket(char *net_interface, int port, netsrc_t type, int family)
|
||||
{
|
||||
char Buf[BUFSIZ], *Host, *Service;
|
||||
|
@ -1040,7 +1040,7 @@ NET_OpenIP(void)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
NET_IPXSocket(int port)
|
||||
{
|
||||
int newsocket;
|
||||
|
|
|
@ -275,7 +275,7 @@ Sys_Microseconds(void)
|
|||
static LARGE_INTEGER freq = { 0 };
|
||||
static LARGE_INTEGER base = { 0 };
|
||||
|
||||
if (!freq.QuadPart)
|
||||
if (!freq.QuadPart)
|
||||
{
|
||||
QueryPerformanceFrequency(&freq);
|
||||
}
|
||||
|
|
|
@ -458,8 +458,8 @@ SCR_ReadNextFrame(void)
|
|||
FS_Read(compressed, size, cl.cinematic_file);
|
||||
|
||||
/* read sound */
|
||||
start = cl.cinematicframe * cin.s_rate / cin.fps;
|
||||
end = (cl.cinematicframe + 1) * cin.s_rate / cin.fps;
|
||||
start = cl.cinematicframe * cin.s_rate / (int)cin.fps;
|
||||
end = (cl.cinematicframe + 1) * cin.s_rate / (int)cin.fps;
|
||||
count = end - start;
|
||||
|
||||
FS_Read(samples, count * cin.s_width * cin.s_channels,
|
||||
|
@ -528,7 +528,8 @@ SCR_ReadNextAVFrame(void)
|
|||
static qboolean
|
||||
SCR_LoadAVcodec(const char *arg, const char *dot)
|
||||
{
|
||||
char name[MAX_OSPATH], *path = NULL;
|
||||
const char *path = NULL;
|
||||
char name[MAX_OSPATH];
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
@ -599,6 +600,7 @@ SCR_RunCinematic(void)
|
|||
}
|
||||
|
||||
cin.pic = cin.pic_pending;
|
||||
cin.pic_pending = NULL;
|
||||
switch (cin.video_type)
|
||||
{
|
||||
case video_cin:
|
||||
|
@ -613,7 +615,8 @@ SCR_RunCinematic(void)
|
|||
break;
|
||||
#endif
|
||||
default:
|
||||
cin.pic_pending = NULL;
|
||||
/* should be never called */
|
||||
Com_Error(ERR_DROP, "Incorrect media data.");
|
||||
}
|
||||
|
||||
if (!cin.pic_pending)
|
||||
|
|
|
@ -35,28 +35,6 @@ extern char key_lines[NUM_KEY_LINES][MAXCMDLINE];
|
|||
extern int edit_line;
|
||||
extern int key_linepos;
|
||||
|
||||
void
|
||||
DrawStringScaled(int x, int y, const char *s, float factor)
|
||||
{
|
||||
while (*s)
|
||||
{
|
||||
Draw_CharScaled(x, y, *s, factor);
|
||||
x += 8*factor;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawAltStringScaled(int x, int y, const char *s, float factor)
|
||||
{
|
||||
while (*s)
|
||||
{
|
||||
Draw_CharScaled(x, y, *s ^ 0x80, factor);
|
||||
x += 8*factor;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Key_ClearTyping(void)
|
||||
{
|
||||
|
@ -472,7 +450,7 @@ Con_DrawInput(void)
|
|||
float scale;
|
||||
char *text;
|
||||
char ch;
|
||||
int txtlen;
|
||||
size_t txtlen;
|
||||
int linepos;
|
||||
int draw_icon;
|
||||
|
||||
|
@ -587,12 +565,12 @@ Con_DrawNotify(void)
|
|||
{
|
||||
if (chat_team)
|
||||
{
|
||||
DrawStringScaled(8 * scale, v * scale, "say_team:", scale);
|
||||
Draw_StringScaled(8 * scale, v * scale, scale, false, "say_team:");
|
||||
skip = 11;
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawStringScaled(8 * scale, v * scale, "say:", scale);
|
||||
Draw_StringScaled(8 * scale, v * scale, scale, false, "say:");
|
||||
skip = 5;
|
||||
}
|
||||
|
||||
|
@ -630,7 +608,7 @@ Con_DrawConsole(float frac)
|
|||
{
|
||||
int i, j, x, y, n;
|
||||
int rows;
|
||||
int verLen;
|
||||
size_t verLen;
|
||||
char *text;
|
||||
int row;
|
||||
int lines;
|
||||
|
@ -666,10 +644,7 @@ Con_DrawConsole(float frac)
|
|||
|
||||
verLen = strlen(version);
|
||||
|
||||
for (x = 0; x < verLen; x++)
|
||||
{
|
||||
Draw_CharScaled(viddef.width - ((verLen*8+5) * scale) + x * 8 * scale, lines - 35 * scale, 128 + version[x], scale);
|
||||
}
|
||||
Draw_StringScaled(viddef.width - ((verLen * 8 + 5) * scale), lines - 35 * scale, scale, true, version);
|
||||
|
||||
t = time(NULL);
|
||||
today = localtime(&t);
|
||||
|
@ -677,10 +652,7 @@ Con_DrawConsole(float frac)
|
|||
|
||||
Com_sprintf(tmpbuf, sizeof(tmpbuf), "%s", timebuf);
|
||||
|
||||
for (x = 0; x < 21; x++)
|
||||
{
|
||||
Draw_CharScaled(viddef.width - (173 * scale) + x * 8 * scale, lines - 25 * scale, 128 + tmpbuf[x], scale);
|
||||
}
|
||||
Draw_StringScaled(viddef.width - (173 * scale), lines - 25 * scale, scale, true, tmpbuf);
|
||||
|
||||
/* draw the text */
|
||||
con.vislines = lines;
|
||||
|
@ -790,7 +762,7 @@ Con_DrawConsole(float frac)
|
|||
sprintf(dlbar + strlen(dlbar), " %02d%%", cls.downloadpercent);
|
||||
|
||||
/* draw it */
|
||||
y = con.vislines - 12;
|
||||
y = (lines - 12 * scale) / scale;
|
||||
|
||||
for (i = 0; i < strlen(dlbar); i++)
|
||||
{
|
||||
|
|
|
@ -778,7 +778,7 @@ CL_AddMuzzleFlash2(void)
|
|||
}
|
||||
|
||||
void
|
||||
CL_TeleporterParticles(entity_state_t *ent)
|
||||
CL_TeleporterParticles(const entity_xstate_t *ent)
|
||||
{
|
||||
int i, j;
|
||||
cparticle_t *p;
|
||||
|
@ -2046,7 +2046,7 @@ CL_TeleportParticles(vec3_t org)
|
|||
extern struct sfx_s *cl_sfx_footsteps[4];
|
||||
|
||||
void
|
||||
CL_EntityEvent(entity_state_t *ent)
|
||||
CL_EntityEvent(entity_xstate_t *ent)
|
||||
{
|
||||
switch (ent->event)
|
||||
{
|
||||
|
@ -2064,8 +2064,52 @@ CL_EntityEvent(entity_state_t *ent)
|
|||
|
||||
if (cl_footsteps->value)
|
||||
{
|
||||
vec3_t mins = {0, 0, 0}, maxs = {0, 0, 0}, dir = { 0, 0, -1000000 };
|
||||
struct sfx_s *sfx = NULL;
|
||||
trace_t trace;
|
||||
trace = CM_BoxTrace(ent->origin, dir, mins, maxs, 0, MASK_DEADSOLID);
|
||||
|
||||
/* ladder does not have separate material */
|
||||
if ((trace.contents & CONTENTS_LADDER))
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
int step;
|
||||
|
||||
/* material has sometime 5 steps versions */
|
||||
step = randk() % 5;
|
||||
|
||||
Com_sprintf(name, sizeof(name), "player/ladder%i.wav",
|
||||
step + 1);
|
||||
|
||||
sfx = S_RegisterSound(name);
|
||||
}
|
||||
|
||||
/* step sound based onb material */
|
||||
if (!sfx && trace.surface->material[0])
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
int step;
|
||||
|
||||
/* material has sometime 5 steps versions */
|
||||
step = randk() % 5;
|
||||
|
||||
Com_sprintf(name, sizeof(name), "player/%s%i.wav",
|
||||
trace.surface->material, step + 1);
|
||||
|
||||
sfx = S_RegisterSound(name);
|
||||
}
|
||||
|
||||
/* no material steps sound found */
|
||||
if (!sfx)
|
||||
{
|
||||
int step;
|
||||
|
||||
step = randk() & 3;
|
||||
sfx = cl_sfx_footsteps[step];
|
||||
}
|
||||
|
||||
S_StartSound(NULL, ent->number, CHAN_BODY,
|
||||
cl_sfx_footsteps[randk() & 3], 1, ATTN_NORM, 0);
|
||||
sfx, 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -2092,6 +2136,80 @@ CL_ClearEffects(void)
|
|||
CL_ClearLightStyles();
|
||||
}
|
||||
|
||||
void
|
||||
CL_FlameEffects(vec3_t origin)
|
||||
{
|
||||
int n, count;
|
||||
|
||||
count = rand() & 0xF;
|
||||
|
||||
/* Particles going down */
|
||||
for(n = 0; n < count; n++)
|
||||
{
|
||||
cparticle_t *p;
|
||||
int j;
|
||||
|
||||
if (!free_particles)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
p = free_particles;
|
||||
free_particles = p->next;
|
||||
p->next = active_particles;
|
||||
active_particles = p;
|
||||
|
||||
VectorClear(p->accel);
|
||||
p->time = cl.time;
|
||||
|
||||
p->alpha = 1.0;
|
||||
p->alphavel = -1.0 / (1 + frandk() * 0.2);
|
||||
p->color = CL_CombineColors(0xff007fef, 0xff003bb7,
|
||||
(float)(randk() & 15) / 15.0);
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
p->org[j] = origin[j] + crandk() * 5;
|
||||
p->vel[j] = crandk() * 5;
|
||||
}
|
||||
|
||||
p->vel[2] = crandk() * -10;
|
||||
p->accel[2] = -PARTICLE_GRAVITY;
|
||||
}
|
||||
|
||||
count = rand() & 0x7;
|
||||
|
||||
/* Particles go up */
|
||||
for (n = 0; n < count; n++)
|
||||
{
|
||||
cparticle_t *p;
|
||||
int j;
|
||||
|
||||
if (!free_particles)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
p = free_particles;
|
||||
free_particles = p->next;
|
||||
p->next = active_particles;
|
||||
active_particles = p;
|
||||
VectorClear(p->accel);
|
||||
|
||||
p->time = cl.time;
|
||||
|
||||
p->alpha = 1.0;
|
||||
p->alphavel = -1.0 / (1 + frandk() * 0.5);
|
||||
p->color = CL_CombineColors(0xff0000ff, 0xff002f2f,
|
||||
(float)(randk() & 15) / 15.0);
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
p->org[j] = origin[j] + crandk() * 3;
|
||||
}
|
||||
p->vel[2] = 20 + crandk() * 5;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CL_Flashlight(int ent, vec3_t pos)
|
||||
{
|
||||
|
|
|
@ -32,15 +32,9 @@ extern struct model_s *cl_mod_powerscreen;
|
|||
void
|
||||
CL_AddPacketEntities(frame_t *frame)
|
||||
{
|
||||
entity_t ent = {0};
|
||||
entity_state_t *s1;
|
||||
float autorotate;
|
||||
int i;
|
||||
int pnum;
|
||||
centity_t *cent;
|
||||
float autorotate, autobob;
|
||||
int autoanim;
|
||||
clientinfo_t *ci;
|
||||
unsigned int effects, renderfx;
|
||||
int pnum;
|
||||
|
||||
/* To distinguish baseq2, xatrix and rogue. */
|
||||
cvar_t *gametype = Cvar_Get("gametype", "", CVAR_LATCH | CVAR_SERVERINFO);
|
||||
|
@ -50,16 +44,26 @@ CL_AddPacketEntities(frame_t *frame)
|
|||
|
||||
/* brush models can auto animate their frames */
|
||||
autoanim = 2 * cl.time / 1000;
|
||||
autobob = 5 * sinf(cl.time / 400.0f);
|
||||
|
||||
for (pnum = 0; pnum < frame->num_entities; pnum++)
|
||||
{
|
||||
unsigned int effects, renderfx, rr_effects;
|
||||
entity_xstate_t *s1;
|
||||
entity_t ent = {0};
|
||||
clientinfo_t *ci;
|
||||
centity_t *cent;
|
||||
int i;
|
||||
|
||||
s1 = &cl_parse_entities[(frame->parse_entities +
|
||||
pnum) & (MAX_PARSE_ENTITIES - 1)];
|
||||
|
||||
cent = &cl_entities[s1->number];
|
||||
|
||||
effects = s1->effects;
|
||||
rr_effects = s1->rr_effects;
|
||||
renderfx = s1->renderfx;
|
||||
ent.rr_mesh = s1->rr_mesh;
|
||||
|
||||
/* set frame */
|
||||
if (effects & EF_ANIM01)
|
||||
|
@ -132,10 +136,15 @@ CL_AddPacketEntities(frame_t *frame)
|
|||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
ent.origin[i] = ent.oldorigin[i] = cent->prev.origin[i] + cl.lerpfrac *
|
||||
(cent->current.origin[i] - cent->prev.origin[i]);
|
||||
(cent->current.origin[i] - cent->prev.origin[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (effects & EF_BOB) {
|
||||
ent.origin[2] += autobob;
|
||||
ent.oldorigin[2] += autobob;
|
||||
}
|
||||
|
||||
/* tweak the color of beams */
|
||||
if (renderfx & RF_BEAM)
|
||||
{
|
||||
|
@ -156,7 +165,7 @@ CL_AddPacketEntities(frame_t *frame)
|
|||
else
|
||||
{
|
||||
/* set skin */
|
||||
if (s1->modelindex == 255)
|
||||
if (s1->modelindex == CUSTOM_PLAYER_MODEL)
|
||||
{
|
||||
/* use custom player skin */
|
||||
ent.skinnum = 0;
|
||||
|
@ -198,6 +207,9 @@ CL_AddPacketEntities(frame_t *frame)
|
|||
ent.skin = NULL;
|
||||
ent.model = cl.model_draw[s1->modelindex];
|
||||
}
|
||||
|
||||
/* store scale */
|
||||
VectorCopy(s1->scale, ent.scale);
|
||||
}
|
||||
|
||||
/* only used for black hole model right now */
|
||||
|
@ -251,6 +263,44 @@ CL_AddPacketEntities(frame_t *frame)
|
|||
}
|
||||
}
|
||||
|
||||
if (rr_effects & EF_FLASHLIGHT) {
|
||||
vec3_t forward, start, end, diff, pos;
|
||||
vec3_t mins = {-1, -1, -1}, maxs = {1, 1, 1};
|
||||
trace_t trace;
|
||||
int len = 0, i;
|
||||
float step;
|
||||
|
||||
AngleVectors(ent.angles, forward, NULL, NULL);
|
||||
VectorMA(ent.origin, 256, forward, end);
|
||||
VectorCopy(ent.origin, start);
|
||||
/* search light end point */
|
||||
trace = CM_BoxTrace(start, end, mins, maxs, 0, MASK_SHOT);
|
||||
/* step back little bit, for cover nearest surfaces */
|
||||
VectorSubtract(trace.endpos, ent.origin, diff);
|
||||
len = VectorNormalize(diff);
|
||||
/* get light steps */
|
||||
step = (float)len / 16;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
diff[i] *= step;
|
||||
}
|
||||
|
||||
/* place only 16 lights in row max */
|
||||
if (len > 16)
|
||||
{
|
||||
len = 16;
|
||||
}
|
||||
|
||||
VectorCopy(trace.endpos, pos);
|
||||
/* Add light trace */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
/* create light */
|
||||
V_AddLight(pos, 128 * (len - i) / len + 64, 1, 1, 1);
|
||||
VectorSubtract(pos, diff, pos);
|
||||
}
|
||||
}
|
||||
|
||||
if (s1->number == cl.playernum + 1)
|
||||
{
|
||||
ent.flags |= RF_VIEWERMODEL;
|
||||
|
@ -381,7 +431,7 @@ CL_AddPacketEntities(frame_t *frame)
|
|||
/* duplicate for linked models */
|
||||
if (s1->modelindex2)
|
||||
{
|
||||
if (s1->modelindex2 == 255)
|
||||
if (s1->modelindex2 == CUSTOM_PLAYER_MODEL)
|
||||
{
|
||||
/* custom weapon */
|
||||
ci = &cl.clientinfo[s1->skinnum & 0xff];
|
||||
|
|
|
@ -41,6 +41,35 @@
|
|||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "refresh/files/stb_image.h"
|
||||
|
||||
/* ATD types */
|
||||
typedef struct
|
||||
{
|
||||
char *file;
|
||||
} atd_bitmap_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int bitmap;
|
||||
int next;
|
||||
float wait;
|
||||
int x;
|
||||
int y;
|
||||
} atd_frame_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int colortype;
|
||||
int width;
|
||||
int height;
|
||||
int bilinear;
|
||||
int clamp;
|
||||
char* type;
|
||||
atd_bitmap_t *bitmaps;
|
||||
size_t bitmap_count;
|
||||
atd_frame_t *frames;
|
||||
size_t frame_count;
|
||||
} atd_sprites_t;
|
||||
|
||||
// Fix Jennell Jaquays' name in the Quitscreen
|
||||
// this is 98x11 pixels, each value an index
|
||||
// into the standard baseq2/pak0/pics/quit.pcx colormap
|
||||
|
@ -820,8 +849,11 @@ Convert24to32(unsigned *d_8to24table, byte *pal)
|
|||
d_8to24table[255] &= LittleLong(0xffffff); // 255 is transparent
|
||||
}
|
||||
|
||||
/*
|
||||
* Load only static images without animation support
|
||||
*/
|
||||
static void
|
||||
LoadImageWithPalette(const char *filename, byte **pic, byte **palette,
|
||||
LoadImageWithPaletteStatic(const char *filename, byte **pic, byte **palette,
|
||||
int *width, int *height, int *bitsPerPixel)
|
||||
{
|
||||
const char* ext;
|
||||
|
@ -912,6 +944,268 @@ LoadImageWithPalette(const char *filename, byte **pic, byte **palette,
|
|||
FS_FreeFile(raw);
|
||||
}
|
||||
|
||||
static void
|
||||
LoadImageATDFree(atd_sprites_t* anim)
|
||||
{
|
||||
for (size_t i = 0; i < anim->bitmap_count; i++)
|
||||
{
|
||||
free(anim->bitmaps[i].file);
|
||||
}
|
||||
free(anim->bitmaps);
|
||||
free(anim->frames);
|
||||
free(anim->type);
|
||||
}
|
||||
|
||||
static void
|
||||
LoadImageATD(atd_sprites_t* anim, char *tmp_buf, int len)
|
||||
{
|
||||
char *curr_buff;
|
||||
|
||||
/* get lines count */
|
||||
curr_buff = tmp_buf;
|
||||
while(curr_buff && *curr_buff && (curr_buff < (tmp_buf + len)))
|
||||
{
|
||||
const char *token;
|
||||
|
||||
token = COM_Parse(&curr_buff);
|
||||
if (!token)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (token[0] == '#')
|
||||
{
|
||||
size_t linesize;
|
||||
|
||||
/* skip empty */
|
||||
linesize = strcspn(curr_buff, "\n\r");
|
||||
curr_buff += linesize;
|
||||
}
|
||||
else if (!strcmp(token, "type") ||
|
||||
!strcmp(token, "width") ||
|
||||
!strcmp(token, "height") ||
|
||||
!strcmp(token, "bilinear") ||
|
||||
!strcmp(token, "clamp") ||
|
||||
!strcmp(token, "colortype"))
|
||||
{
|
||||
char token_section[MAX_TOKEN_CHARS];
|
||||
|
||||
Q_strlcpy(token_section, token, sizeof(token_section));
|
||||
|
||||
token = COM_Parse(&curr_buff);
|
||||
if (strcmp(token, "="))
|
||||
{
|
||||
/* should = after token */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(token_section, "type") && !anim->type)
|
||||
{
|
||||
anim->type = strdup(COM_Parse(&curr_buff));
|
||||
}
|
||||
else
|
||||
{
|
||||
int value;
|
||||
|
||||
token = COM_Parse(&curr_buff);
|
||||
value = (int)strtol(token, (char **)NULL, 10);
|
||||
|
||||
if (!strcmp(token_section, "colortype"))
|
||||
{
|
||||
anim->colortype = value;
|
||||
}
|
||||
else if (!strcmp(token_section, "width"))
|
||||
{
|
||||
anim->width = value;
|
||||
}
|
||||
else if (!strcmp(token_section, "height"))
|
||||
{
|
||||
anim->height = value;
|
||||
}
|
||||
else if (!strcmp(token_section, "bilinear"))
|
||||
{
|
||||
anim->bilinear = value;
|
||||
}
|
||||
else if (!strcmp(token_section, "clamp"))
|
||||
{
|
||||
anim->clamp = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(token, "!bitmap"))
|
||||
{
|
||||
token = COM_Parse(&curr_buff);
|
||||
if (strcmp(token, "file"))
|
||||
{
|
||||
/* should file after token */
|
||||
return;
|
||||
}
|
||||
|
||||
token = COM_Parse(&curr_buff);
|
||||
if (strcmp(token, "="))
|
||||
{
|
||||
/* should = after token */
|
||||
return;
|
||||
}
|
||||
|
||||
/* save bitmap file */
|
||||
anim->bitmap_count++;
|
||||
anim->bitmaps = realloc(anim->bitmaps, anim->bitmap_count * sizeof(atd_bitmap_t));
|
||||
anim->bitmaps[anim->bitmap_count - 1].file = strdup(COM_Parse(&curr_buff));
|
||||
}
|
||||
else if (!strcmp(token, "!frame"))
|
||||
{
|
||||
atd_frame_t *frame;
|
||||
|
||||
anim->frame_count++;
|
||||
anim->frames = realloc(anim->frames, anim->frame_count * sizeof(frame_t));
|
||||
frame = &anim->frames[anim->frame_count - 1];
|
||||
frame->next = -1;
|
||||
frame->wait = 0.0f;
|
||||
frame->x = frame->y = 0;
|
||||
frame->bitmap = -1;
|
||||
|
||||
while(curr_buff && *curr_buff && (curr_buff < (tmp_buf + len)))
|
||||
{
|
||||
size_t linesize;
|
||||
|
||||
/* skip empty */
|
||||
linesize = strspn(curr_buff, "\n\r\t ");
|
||||
curr_buff += linesize;
|
||||
|
||||
/* new frame? */
|
||||
if (curr_buff[0] == '!')
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
token = COM_Parse(&curr_buff);
|
||||
if (token[0] == '#')
|
||||
{
|
||||
/* skip empty */
|
||||
linesize = strcspn(curr_buff, "\n\r");
|
||||
curr_buff += linesize;
|
||||
}
|
||||
else if (!strcmp(token, "bitmap") ||
|
||||
!strcmp(token, "next") ||
|
||||
!strcmp(token, "wait") ||
|
||||
!strcmp(token, "x") ||
|
||||
!strcmp(token, "y"))
|
||||
{
|
||||
char token_section[MAX_TOKEN_CHARS];
|
||||
|
||||
Q_strlcpy(token_section, token, sizeof(token_section));
|
||||
|
||||
token = COM_Parse(&curr_buff);
|
||||
if (strcmp(token, "="))
|
||||
{
|
||||
/* should = after token */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(token_section, "wait"))
|
||||
{
|
||||
token = COM_Parse(&curr_buff);
|
||||
frame->wait = (float)strtod(token, (char **)NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
int value;
|
||||
|
||||
token = COM_Parse(&curr_buff);
|
||||
value = (int)strtol(token, (char **)NULL, 10);
|
||||
|
||||
if (!strcmp(token_section, "bitmap"))
|
||||
{
|
||||
frame->bitmap = value;
|
||||
}
|
||||
else if (!strcmp(token_section, "next"))
|
||||
{
|
||||
frame->next = value;
|
||||
}
|
||||
else if (!strcmp(token_section, "x"))
|
||||
{
|
||||
frame->x = value;
|
||||
}
|
||||
else if (!strcmp(token_section, "y"))
|
||||
{
|
||||
frame->y = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Load images with sprites */
|
||||
static void
|
||||
LoadImageWithPalette(const char *filename, byte **pic, byte **palette,
|
||||
int *width, int *height, int *bitsPerPixel)
|
||||
{
|
||||
const char* ext;
|
||||
|
||||
ext = COM_FileExtension(filename);
|
||||
|
||||
if (!strcmp(ext, "atd"))
|
||||
{
|
||||
char *tmp_buf, *raw;
|
||||
int lindent, len;
|
||||
|
||||
*pic = NULL;
|
||||
|
||||
/* load the file */
|
||||
len = FS_LoadFile(filename, (void **)&raw);
|
||||
|
||||
if (!raw || len <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (len <= sizeof(int))
|
||||
{
|
||||
FS_FreeFile(raw);
|
||||
return;
|
||||
}
|
||||
|
||||
lindent = LittleLong(*((int*)raw));
|
||||
len -= 4;
|
||||
|
||||
if (lindent == IDATDSPRITEHEADER)
|
||||
{
|
||||
atd_sprites_t *anim = malloc(sizeof(atd_sprites_t));
|
||||
memset(anim, 0, sizeof(atd_sprites_t));
|
||||
|
||||
tmp_buf = malloc(len + 1);
|
||||
memcpy(tmp_buf, raw + 4, len);
|
||||
tmp_buf[len] = 0;
|
||||
LoadImageATD(anim, tmp_buf, len);
|
||||
free(tmp_buf);
|
||||
|
||||
if (anim->bitmap_count &&
|
||||
anim->frame_count &&
|
||||
(anim->frames[0].bitmap >= 0) &&
|
||||
(anim->frames[0].bitmap < anim->bitmap_count))
|
||||
{
|
||||
int bitmap;
|
||||
|
||||
bitmap = anim->frames[0].bitmap;
|
||||
LoadImageWithPaletteStatic(anim->bitmaps[bitmap].file,
|
||||
pic, palette, width, height, bitsPerPixel);
|
||||
}
|
||||
LoadImageATDFree(anim);
|
||||
free(anim);
|
||||
}
|
||||
|
||||
FS_FreeFile(raw);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadImageWithPaletteStatic(filename, pic, palette, width, height, bitsPerPixel);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SCR_LoadImageWithPalette(const char *filename, byte **pic, byte **palette,
|
||||
int *width, int *height, int *bitsPerPixel)
|
||||
|
|
|
@ -139,62 +139,6 @@ keyname_t keynames[] = {
|
|||
{"MWHEELUP", K_MWHEELUP},
|
||||
{"MWHEELDOWN", K_MWHEELDOWN},
|
||||
|
||||
{"BTN_A", K_BTN_A},
|
||||
{"BTN_B", K_BTN_B},
|
||||
{"BTN_X", K_BTN_X},
|
||||
{"BTN_Y", K_BTN_Y},
|
||||
{"STICK_LEFT", K_STICK_LEFT},
|
||||
{"STICK_RIGHT", K_STICK_RIGHT},
|
||||
{"SHOULDR_LEFT", K_SHOULDER_LEFT},
|
||||
{"SHOULDR_RIGHT", K_SHOULDER_RIGHT},
|
||||
{"TRIG_LEFT", K_TRIG_LEFT},
|
||||
{"TRIG_RIGHT", K_TRIG_RIGHT},
|
||||
|
||||
{"DP_UP", K_DPAD_UP},
|
||||
{"DP_DOWN", K_DPAD_DOWN},
|
||||
{"DP_LEFT", K_DPAD_LEFT},
|
||||
{"DP_RIGHT", K_DPAD_RIGHT},
|
||||
|
||||
{"PADDLE_1", K_PADDLE_1},
|
||||
{"PADDLE_2", K_PADDLE_2},
|
||||
{"PADDLE_3", K_PADDLE_3},
|
||||
{"PADDLE_4", K_PADDLE_4},
|
||||
{"BTN_MISC1", K_BTN_MISC1},
|
||||
{"TOUCHPAD", K_TOUCHPAD},
|
||||
{"BTN_BACK", K_BTN_BACK},
|
||||
{"BTN_GUIDE", K_BTN_GUIDE},
|
||||
{"BTN_START", K_BTN_START},
|
||||
|
||||
// virtual keys you get by pressing the corresponding normal joy key
|
||||
// and the altselector key
|
||||
{"BTN_A_ALT", K_BTN_A_ALT},
|
||||
{"BTN_B_ALT", K_BTN_B_ALT},
|
||||
{"BTN_X_ALT", K_BTN_X_ALT},
|
||||
{"BTN_Y_ALT", K_BTN_Y_ALT},
|
||||
{"STICK_LEFT_ALT", K_STICK_LEFT_ALT},
|
||||
{"STICK_RIGHT_ALT", K_STICK_RIGHT_ALT},
|
||||
{"SHOULDR_LEFT_ALT", K_SHOULDER_LEFT_ALT},
|
||||
{"SHOULDR_RIGHT_ALT", K_SHOULDER_RIGHT_ALT},
|
||||
{"TRIG_LEFT_ALT", K_TRIG_LEFT_ALT},
|
||||
{"TRIG_RIGHT_ALT", K_TRIG_RIGHT_ALT},
|
||||
|
||||
{"DP_UP_ALT", K_DPAD_UP_ALT},
|
||||
{"DP_DOWN_ALT", K_DPAD_DOWN_ALT},
|
||||
{"DP_LEFT_ALT", K_DPAD_LEFT_ALT},
|
||||
{"DP_RIGHT_ALT", K_DPAD_RIGHT_ALT},
|
||||
|
||||
{"PADDLE_1_ALT", K_PADDLE_1_ALT},
|
||||
{"PADDLE_2_ALT", K_PADDLE_2_ALT},
|
||||
{"PADDLE_3_ALT", K_PADDLE_3_ALT},
|
||||
{"PADDLE_4_ALT", K_PADDLE_4_ALT},
|
||||
{"BTN_MISC1_ALT", K_BTN_MISC1_ALT},
|
||||
{"TOUCHPAD_ALT", K_TOUCHPAD_ALT},
|
||||
{"BTN_BACK_ALT", K_BTN_BACK_ALT},
|
||||
{"BTN_GUIDE_ALT", K_BTN_GUIDE_ALT},
|
||||
{"BTN_START_ALT", K_BTN_START_ALT},
|
||||
|
||||
{"JOY_BACK", K_JOY_BACK},
|
||||
|
||||
{"SUPER", K_SUPER},
|
||||
{"COMPOSE", K_COMPOSE},
|
||||
{"MODE", K_MODE},
|
||||
|
@ -267,9 +211,150 @@ keyname_t keynames[] = {
|
|||
{NULL, 0}
|
||||
};
|
||||
|
||||
static char *gamepadbtns[] =
|
||||
{
|
||||
// It is imperative that this list of buttons follow EXACTLY the order they
|
||||
// appear in QKEYS enum in keyboard.h, which in turn is the same order as
|
||||
// they appear in SDL_GamepadButton / SDL_GameControllerButton enum.
|
||||
"BTN_SOUTH",
|
||||
"BTN_EAST",
|
||||
"BTN_WEST",
|
||||
"BTN_NORTH",
|
||||
"BTN_BACK",
|
||||
"BTN_GUIDE",
|
||||
"BTN_START",
|
||||
"STICK_LEFT",
|
||||
"STICK_RIGHT",
|
||||
"SHOULDR_LEFT",
|
||||
"SHOULDR_RIGHT",
|
||||
"DP_UP",
|
||||
"DP_DOWN",
|
||||
"DP_LEFT",
|
||||
"DP_RIGHT",
|
||||
"BTN_MISC1",
|
||||
"PADDL_RIGHT1",
|
||||
"PADDL_LEFT1",
|
||||
"PADDL_RIGHT2",
|
||||
"PADDL_LEFT2",
|
||||
"TOUCHPAD",
|
||||
"BTN_MISC2",
|
||||
"BTN_MISC3",
|
||||
"BTN_MISC4",
|
||||
"BTN_MISC5",
|
||||
"BTN_MISC6",
|
||||
"TRIG_LEFT",
|
||||
"TRIG_RIGHT",
|
||||
// Same with _ALT buttons ( button + 'alt modifier' pressed )
|
||||
"BTN_SOUTH_ALT",
|
||||
"BTN_EAST_ALT",
|
||||
"BTN_WEST_ALT",
|
||||
"BTN_NORTH_ALT",
|
||||
"BTN_BACK_ALT",
|
||||
"BTN_GUIDE_ALT",
|
||||
"BTN_START_ALT",
|
||||
"STICK_LEFT_ALT",
|
||||
"STICK_RIGHT_ALT",
|
||||
"SHOULDR_LEFT_ALT",
|
||||
"SHOULDR_RIGHT_ALT",
|
||||
"DP_UP_ALT",
|
||||
"DP_DOWN_ALT",
|
||||
"DP_LEFT_ALT",
|
||||
"DP_RIGHT_ALT",
|
||||
"BTN_MISC1_ALT",
|
||||
"PADDL_RIGHT1_ALT",
|
||||
"PADDL_LEFT1_ALT",
|
||||
"PADDL_RIGHT2_ALT",
|
||||
"PADDL_LEFT2_ALT",
|
||||
"TOUCHPAD_ALT",
|
||||
"BTN_MISC2_ALT",
|
||||
"BTN_MISC3_ALT",
|
||||
"BTN_MISC4_ALT",
|
||||
"BTN_MISC5_ALT",
|
||||
"BTN_MISC6_ALT",
|
||||
"TRIG_LEFT_ALT",
|
||||
"TRIG_RIGHT_ALT"
|
||||
};
|
||||
|
||||
#define NUM_GAMEPAD_BTNS (sizeof gamepadbtns / sizeof gamepadbtns[0])
|
||||
|
||||
static char *gpbtns_face[] =
|
||||
{
|
||||
// Xbox
|
||||
"A",
|
||||
"B",
|
||||
"X",
|
||||
"Y",
|
||||
"VIEW",
|
||||
"XBOX",
|
||||
"MENU",
|
||||
"LS",
|
||||
"RS",
|
||||
"LB",
|
||||
"RB",
|
||||
// Playstation
|
||||
"CROSS",
|
||||
"CIRCLE",
|
||||
"SQUARE",
|
||||
"TRIANGLE",
|
||||
"CREATE",
|
||||
"PS",
|
||||
"OPTIONS",
|
||||
"L3",
|
||||
"R3",
|
||||
"L1",
|
||||
"R1",
|
||||
// Nintendo Switch
|
||||
"B",
|
||||
"A",
|
||||
"Y",
|
||||
"X",
|
||||
"-",
|
||||
"HOME",
|
||||
"+",
|
||||
"L stick",
|
||||
"R stick",
|
||||
"L btn",
|
||||
"R btn",
|
||||
};
|
||||
|
||||
static char *gpbtns_paddles[] =
|
||||
{
|
||||
// Xbox
|
||||
"SHARE",
|
||||
"P1",
|
||||
"P3",
|
||||
"P2",
|
||||
"P4",
|
||||
// Playstation
|
||||
"MIC",
|
||||
"RB",
|
||||
"LB",
|
||||
"Right Fn",
|
||||
"Left Fn",
|
||||
// Switch
|
||||
"CAPTURE",
|
||||
"Right SR",
|
||||
"Left SL",
|
||||
"Right SL",
|
||||
"Left SR" // JoyCon btn positions suck
|
||||
};
|
||||
|
||||
static char *gpbtns_triggers[] =
|
||||
{
|
||||
// Xbox
|
||||
"LT",
|
||||
"RT",
|
||||
// Playstation
|
||||
"L2",
|
||||
"R2",
|
||||
// Switch
|
||||
"ZL",
|
||||
"ZR"
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
void
|
||||
static void
|
||||
CompleteCommand(void)
|
||||
{
|
||||
const char *cmd, *s;
|
||||
|
@ -300,7 +385,7 @@ CompleteCommand(void)
|
|||
key_lines[edit_line][key_linepos] = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
CompleteMapNameCommand(void)
|
||||
{
|
||||
const char *s, *cmdArg;
|
||||
|
@ -338,7 +423,7 @@ IsInConsole(void)
|
|||
(cls.state == ca_disconnected || cls.state == ca_connecting));
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
Key_Console(int key)
|
||||
{
|
||||
char txt[2];
|
||||
|
@ -606,7 +691,7 @@ char chat_buffer[MAXCMDLINE];
|
|||
int chat_bufferlen = 0;
|
||||
int chat_cursorpos = 0;
|
||||
|
||||
void
|
||||
static void
|
||||
Key_Message(int key)
|
||||
{
|
||||
char last;
|
||||
|
@ -734,10 +819,11 @@ Key_Message(int key)
|
|||
* Single ascii characters return themselves, while
|
||||
* the K_* names are matched up.
|
||||
*/
|
||||
int
|
||||
static int
|
||||
Key_StringToKeynum(char *str)
|
||||
{
|
||||
keyname_t *kn;
|
||||
int i;
|
||||
|
||||
if (!str || !str[0])
|
||||
{
|
||||
|
@ -757,6 +843,14 @@ Key_StringToKeynum(char *str)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_GAMEPAD_BTNS; i++)
|
||||
{
|
||||
if (!Q_stricmp(str, gamepadbtns[i]))
|
||||
{
|
||||
return K_JOY_FIRST_BTN + i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -784,6 +878,11 @@ Key_KeynumToString(int keynum)
|
|||
return tinystr;
|
||||
}
|
||||
|
||||
if (keynum >= K_JOY_FIRST_BTN) // gamepad button
|
||||
{
|
||||
return gamepadbtns[keynum - K_JOY_FIRST_BTN];
|
||||
}
|
||||
|
||||
for (kn = keynames; kn->name; kn++)
|
||||
{
|
||||
if (keynum == kn->keynum)
|
||||
|
@ -795,6 +894,49 @@ Key_KeynumToString(int keynum)
|
|||
return "<UNKNOWN KEYNUM>";
|
||||
}
|
||||
|
||||
/*
|
||||
* Same as Key_KeynumToString(), but for joystick/gamepad buttons.
|
||||
*/
|
||||
char *
|
||||
Key_KeynumToString_Joy(int key)
|
||||
{
|
||||
extern gamepad_labels_t joy_current_lbls;
|
||||
const int lbl_style = (int)joy_current_lbls - 1;
|
||||
|
||||
if (key < K_JOY_FIRST_BTN)
|
||||
{
|
||||
return Key_KeynumToString(key);
|
||||
}
|
||||
|
||||
// Don't print the _ALT buttons (buttons with the alt modifier pressed)
|
||||
if (key >= K_JOY_FIRST_BTN_ALT)
|
||||
{
|
||||
key -= K_JOY_FIRST_BTN_ALT - K_JOY_FIRST_BTN;
|
||||
}
|
||||
|
||||
if (lbl_style < 0) // was SDL
|
||||
{
|
||||
goto exit_sdl;
|
||||
}
|
||||
|
||||
// Alter this logic if new gamepad buttons are added in SDL
|
||||
if (key < K_DPAD_UP) // face & shoulder buttons
|
||||
{
|
||||
return gpbtns_face[lbl_style * (K_DPAD_UP - K_BTN_SOUTH) + key - K_BTN_SOUTH];
|
||||
}
|
||||
else if (key >= K_TRIG_LEFT) // triggers
|
||||
{
|
||||
return gpbtns_triggers[lbl_style * (K_JOY_FIRST_BTN_ALT - K_TRIG_LEFT) + key - K_TRIG_LEFT];
|
||||
}
|
||||
else if (key > K_DPAD_RIGHT && key < K_TOUCHPAD) // paddles & misc1
|
||||
{
|
||||
return gpbtns_paddles[lbl_style * (K_TOUCHPAD - K_BTN_MISC1) + key - K_BTN_MISC1];
|
||||
}
|
||||
|
||||
exit_sdl:
|
||||
return gamepadbtns[key - K_JOY_FIRST_BTN];
|
||||
}
|
||||
|
||||
void
|
||||
Key_SetBinding(int keynum, char *binding)
|
||||
{
|
||||
|
@ -821,7 +963,7 @@ Key_SetBinding(int keynum, char *binding)
|
|||
keybindings[keynum] = new;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
Key_Unbind_f(void)
|
||||
{
|
||||
int b;
|
||||
|
@ -843,7 +985,7 @@ Key_Unbind_f(void)
|
|||
Key_SetBinding(b, "");
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
Key_Unbindall_f(void)
|
||||
{
|
||||
int i;
|
||||
|
@ -861,7 +1003,7 @@ Key_Unbindall_f(void)
|
|||
* (=> default.cfg is done) */
|
||||
extern qboolean doneWithDefaultCfg;
|
||||
|
||||
void
|
||||
static void
|
||||
Key_Bind_f(void)
|
||||
{
|
||||
int i, c, b;
|
||||
|
@ -884,7 +1026,7 @@ Key_Bind_f(void)
|
|||
}
|
||||
|
||||
/* don't allow binding escape or the special console keys */
|
||||
if(b == K_ESCAPE || b == '^' || b == '`' || b == '~' || b == K_JOY_BACK)
|
||||
if(b == K_ESCAPE || b == '^' || b == '`' || b == '~')
|
||||
{
|
||||
if(doneWithDefaultCfg)
|
||||
{
|
||||
|
@ -1048,7 +1190,7 @@ Key_ReadConsoleHistory()
|
|||
fclose(f);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
Key_Bindlist_f(void)
|
||||
{
|
||||
int i;
|
||||
|
@ -1202,12 +1344,12 @@ Key_Event(int key, qboolean down, qboolean special)
|
|||
unsigned int time = Sys_Milliseconds();
|
||||
|
||||
// evil hack for the joystick key altselector, which turns K_BTN_x into K_BTN_x_ALT
|
||||
if(joy_altselector_pressed && key >= K_JOY_FIRST_REGULAR && key <= K_JOY_LAST_REGULAR)
|
||||
if(joy_altselector_pressed && key >= K_JOY_FIRST_BTN && key < K_JOY_FIRST_BTN_ALT)
|
||||
{
|
||||
// make sure key is not the altselector itself (which we won't turn into *_ALT)
|
||||
if(keybindings[key] == NULL || strcmp(keybindings[key], "+joyaltselector") != 0)
|
||||
{
|
||||
int altkey = key + (K_JOY_FIRST_REGULAR_ALT - K_JOY_FIRST_REGULAR);
|
||||
int altkey = key + (K_JOY_FIRST_BTN_ALT - K_JOY_FIRST_BTN);
|
||||
// allow fallback to binding with non-alt key
|
||||
if(keybindings[altkey] != NULL || keybindings[key] == NULL)
|
||||
key = altkey;
|
||||
|
@ -1274,7 +1416,7 @@ Key_Event(int key, qboolean down, qboolean special)
|
|||
}
|
||||
|
||||
/* Key is unbound */
|
||||
if ((key >= K_MOUSE1 && key != K_JOY_BACK) && !keybindings[key] && (cls.key_dest != key_console) &&
|
||||
if ((key >= K_MOUSE1) && !keybindings[key] && (cls.key_dest != key_console) &&
|
||||
(cls.state == ca_active))
|
||||
{
|
||||
Com_Printf("%s (%d) is unbound, hit F4 to set.\n", Key_KeynumToString(key), key);
|
||||
|
@ -1295,47 +1437,43 @@ Key_Event(int key, qboolean down, qboolean special)
|
|||
- moves one menu level up
|
||||
- closes the menu
|
||||
- closes the help computer
|
||||
- closes the chat window
|
||||
Fully same logic for K_JOY_BACK */
|
||||
if (!cls.disable_screen)
|
||||
- closes the chat window */
|
||||
if (key == K_ESCAPE && !cls.disable_screen)
|
||||
{
|
||||
if (key == K_ESCAPE || key == K_JOY_BACK)
|
||||
if (!down)
|
||||
{
|
||||
if (!down)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Close the help computer */
|
||||
if (cl.frame.playerstate.stats[STAT_LAYOUTS] &&
|
||||
(cls.key_dest == key_game))
|
||||
{
|
||||
Cbuf_AddText("cmd putaway\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (cls.key_dest)
|
||||
{
|
||||
/* Close chat window */
|
||||
case key_message:
|
||||
Key_Message(key);
|
||||
break;
|
||||
|
||||
/* Close menu or one layer up */
|
||||
case key_menu:
|
||||
M_Keydown(key);
|
||||
break;
|
||||
|
||||
/* Pause game and / or leave console,
|
||||
break into the menu. */
|
||||
case key_game:
|
||||
case key_console:
|
||||
M_Menu_Main_f();
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Close the help computer */
|
||||
if (cl.frame.playerstate.stats[STAT_LAYOUTS] &&
|
||||
(cls.key_dest == key_game))
|
||||
{
|
||||
Cbuf_AddText("cmd putaway\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (cls.key_dest)
|
||||
{
|
||||
/* Close chat window */
|
||||
case key_message:
|
||||
Key_Message(key);
|
||||
break;
|
||||
|
||||
/* Close menu or one layer up */
|
||||
case key_menu:
|
||||
M_Keydown(key);
|
||||
break;
|
||||
|
||||
/* Pause game and / or leave console,
|
||||
break into the menu. */
|
||||
case key_game:
|
||||
case key_console:
|
||||
M_Menu_Main_f();
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is one of the most ugly constructs I've
|
||||
|
@ -1419,7 +1557,8 @@ Key_Event(int key, qboolean down, qboolean special)
|
|||
/* FIXME: Better way to do CTRL+<key> actions in the console?
|
||||
special should be set to true in this case.
|
||||
*/
|
||||
if (keydown[K_CTRL] && IsInConsole() &&
|
||||
if (keydown[K_CTRL] &&
|
||||
(IsInConsole() || cls.key_dest == key_menu) &&
|
||||
key >= 'a' && key <= 'z')
|
||||
{
|
||||
special = true;
|
||||
|
|
|
@ -33,6 +33,7 @@ void CL_Changing_f(void);
|
|||
void CL_Reconnect_f(void);
|
||||
void CL_Connect_f(void);
|
||||
void CL_Rcon_f(void);
|
||||
void CL_Packet_f(void);
|
||||
void CL_CheckForResend(void);
|
||||
|
||||
cvar_t *rcon_client_password;
|
||||
|
@ -88,7 +89,7 @@ client_state_t cl;
|
|||
|
||||
centity_t cl_entities[MAX_EDICTS];
|
||||
|
||||
entity_state_t cl_parse_entities[MAX_PARSE_ENTITIES];
|
||||
entity_xstate_t cl_parse_entities[MAX_PARSE_ENTITIES];
|
||||
|
||||
/*Evil hack against too many power screen and power
|
||||
shield impact sounds. For example if the player
|
||||
|
@ -156,8 +157,8 @@ CL_Record_f(void)
|
|||
sizebuf_t buf;
|
||||
int i;
|
||||
int len;
|
||||
entity_state_t *ent;
|
||||
entity_state_t nullstate;
|
||||
entity_xstate_t *ent;
|
||||
entity_xstate_t nullstate;
|
||||
|
||||
if (Cmd_Argc() != 2)
|
||||
{
|
||||
|
@ -570,7 +571,8 @@ CL_InitLocal(void)
|
|||
cl_vwep = Cvar_Get("cl_vwep", "1", CVAR_ARCHIVE);
|
||||
|
||||
#ifdef USE_CURL
|
||||
cl_http_proxy = Cvar_Get("cl_http_proxy", "", 0);
|
||||
cl_http_verifypeer = Cvar_Get("cl_http_verifypeer", "1", CVAR_ARCHIVE);
|
||||
cl_http_proxy = Cvar_Get("cl_http_proxy", "", CVAR_ARCHIVE);
|
||||
cl_http_filelists = Cvar_Get("cl_http_filelists", "1", 0);
|
||||
cl_http_downloads = Cvar_Get("cl_http_downloads", "1", CVAR_ARCHIVE);
|
||||
cl_http_max_connections = Cvar_Get("cl_http_max_connections", "4", 0);
|
||||
|
@ -599,6 +601,7 @@ CL_InitLocal(void)
|
|||
Cmd_AddCommand("reconnect", CL_Reconnect_f);
|
||||
|
||||
Cmd_AddCommand("rcon", CL_Rcon_f);
|
||||
Cmd_AddCommand("packet", CL_Packet_f);
|
||||
|
||||
Cmd_AddCommand("setenv", CL_Setenv_f);
|
||||
|
||||
|
@ -967,8 +970,6 @@ CL_Shutdown(void)
|
|||
|
||||
isdown = true;
|
||||
|
||||
CM_ModFreeAll();
|
||||
|
||||
#ifdef USE_CURL
|
||||
CL_HTTP_Cleanup(true);
|
||||
#endif
|
||||
|
@ -982,4 +983,6 @@ CL_Shutdown(void)
|
|||
S_Shutdown();
|
||||
IN_Shutdown();
|
||||
VID_Shutdown();
|
||||
|
||||
Mods_NamesFinish();
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ CL_Drop(void)
|
|||
* We have gotten a challenge from the server, so try and
|
||||
* connect.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
CL_SendConnectPacket(void)
|
||||
{
|
||||
netadr_t adr;
|
||||
|
@ -374,7 +374,7 @@ void
|
|||
CL_Packet_f(void)
|
||||
{
|
||||
char send[2048];
|
||||
int i, l;
|
||||
size_t i, l;
|
||||
char *in, *out;
|
||||
netadr_t adr;
|
||||
|
||||
|
@ -563,7 +563,7 @@ CL_PingServers_f(void)
|
|||
/*
|
||||
* Responses to broadcasts, etc
|
||||
*/
|
||||
void
|
||||
static void
|
||||
CL_ConnectionlessPacket(void)
|
||||
{
|
||||
char *s;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
static int bitcounts[32]; /* just for protocol profiling */
|
||||
|
||||
static char *svc_strings[256] = {
|
||||
static const char *svc_strings[256] = {
|
||||
"svc_bad",
|
||||
|
||||
"svc_muzzleflash",
|
||||
|
@ -135,7 +135,7 @@ CL_ParseEntityBits(unsigned *bits)
|
|||
* Can go from either a baseline or a previous packet_entity
|
||||
*/
|
||||
static void
|
||||
CL_ParseDelta(entity_state_t *from, entity_state_t *to, int number, int bits)
|
||||
CL_ParseDelta(const entity_xstate_t *from, entity_xstate_t *to, int number, int bits)
|
||||
{
|
||||
/* set everything to the state we are delta'ing from */
|
||||
*to = *from;
|
||||
|
@ -143,16 +143,35 @@ CL_ParseDelta(entity_state_t *from, entity_state_t *to, int number, int bits)
|
|||
VectorCopy(from->origin, to->old_origin);
|
||||
to->number = number;
|
||||
|
||||
if (cls.serverProtocol != PROTOCOL_VERSION)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Always set scale to 1.0f for old clients */
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
to->scale[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_QII97_PROTOCOL(cls.serverProtocol))
|
||||
{
|
||||
if (bits & U_MODEL)
|
||||
{
|
||||
to->modelindex = MSG_ReadByte(&net_message);
|
||||
if (to->modelindex == QII97_PLAYER_MODEL)
|
||||
{
|
||||
to->modelindex = CUSTOM_PLAYER_MODEL;
|
||||
}
|
||||
}
|
||||
|
||||
if (bits & U_MODEL2)
|
||||
{
|
||||
to->modelindex2 = MSG_ReadByte(&net_message);
|
||||
if (to->modelindex2 == QII97_PLAYER_MODEL)
|
||||
{
|
||||
to->modelindex2 = CUSTOM_PLAYER_MODEL;
|
||||
}
|
||||
}
|
||||
|
||||
if (bits & U_MODEL3)
|
||||
|
@ -202,6 +221,17 @@ CL_ParseDelta(entity_state_t *from, entity_state_t *to, int number, int bits)
|
|||
if ((bits & U_SKIN8) && (bits & U_SKIN16))
|
||||
{
|
||||
to->skinnum = MSG_ReadLong(&net_message);
|
||||
|
||||
/* Additional scale with skinnum */
|
||||
if (cls.serverProtocol == PROTOCOL_VERSION)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
to->scale[i] = MSG_ReadFloat(&net_message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bits & U_SKIN8)
|
||||
{
|
||||
|
@ -225,6 +255,31 @@ CL_ParseDelta(entity_state_t *from, entity_state_t *to, int number, int bits)
|
|||
to->effects = MSG_ReadShort(&net_message);
|
||||
}
|
||||
|
||||
/* ReRelease effects */
|
||||
if (cls.serverProtocol != PROTOCOL_VERSION)
|
||||
{
|
||||
to->rr_effects = 0;
|
||||
to->rr_mesh = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((bits & (U_EFFECTS8 | U_EFFECTS16)) == (U_EFFECTS8 | U_EFFECTS16))
|
||||
{
|
||||
to->rr_effects = MSG_ReadLong(&net_message);
|
||||
to->rr_mesh = MSG_ReadLong(&net_message);
|
||||
}
|
||||
else if (bits & U_EFFECTS8)
|
||||
{
|
||||
to->rr_effects = MSG_ReadByte(&net_message);
|
||||
to->rr_mesh = MSG_ReadByte(&net_message);
|
||||
}
|
||||
else if (bits & U_EFFECTS16)
|
||||
{
|
||||
to->rr_effects = MSG_ReadShort(&net_message);
|
||||
to->rr_mesh = MSG_ReadShort(&net_message);
|
||||
}
|
||||
}
|
||||
|
||||
if ((bits & (U_RENDERFX8 | U_RENDERFX16)) == (U_RENDERFX8 | U_RENDERFX16))
|
||||
{
|
||||
to->renderfx = MSG_ReadLong(&net_message);
|
||||
|
@ -240,17 +295,17 @@ CL_ParseDelta(entity_state_t *from, entity_state_t *to, int number, int bits)
|
|||
|
||||
if (bits & U_ORIGIN1)
|
||||
{
|
||||
to->origin[0] = MSG_ReadCoord(&net_message);
|
||||
to->origin[0] = MSG_ReadCoord(&net_message, cls.serverProtocol);
|
||||
}
|
||||
|
||||
if (bits & U_ORIGIN2)
|
||||
{
|
||||
to->origin[1] = MSG_ReadCoord(&net_message);
|
||||
to->origin[1] = MSG_ReadCoord(&net_message, cls.serverProtocol);
|
||||
}
|
||||
|
||||
if (bits & U_ORIGIN3)
|
||||
{
|
||||
to->origin[2] = MSG_ReadCoord(&net_message);
|
||||
to->origin[2] = MSG_ReadCoord(&net_message, cls.serverProtocol);
|
||||
}
|
||||
|
||||
if (bits & U_ANGLE1)
|
||||
|
@ -270,7 +325,7 @@ CL_ParseDelta(entity_state_t *from, entity_state_t *to, int number, int bits)
|
|||
|
||||
if (bits & U_OLDORIGIN)
|
||||
{
|
||||
MSG_ReadPos(&net_message, to->old_origin);
|
||||
MSG_ReadPos(&net_message, to->old_origin, cls.serverProtocol);
|
||||
}
|
||||
|
||||
if (bits & U_SOUND)
|
||||
|
@ -298,10 +353,10 @@ CL_ParseDelta(entity_state_t *from, entity_state_t *to, int number, int bits)
|
|||
* the current frame
|
||||
*/
|
||||
static void
|
||||
CL_DeltaEntity(frame_t *frame, int newnum, entity_state_t *old, int bits)
|
||||
CL_DeltaEntity(frame_t *frame, int newnum, entity_xstate_t *old, int bits)
|
||||
{
|
||||
centity_t *ent;
|
||||
entity_state_t *state;
|
||||
entity_xstate_t *state;
|
||||
|
||||
ent = &cl_entities[newnum];
|
||||
|
||||
|
@ -364,11 +419,10 @@ CL_DeltaEntity(frame_t *frame, int newnum, entity_state_t *old, int bits)
|
|||
static void
|
||||
CL_ParsePacketEntities(frame_t *oldframe, frame_t *newframe)
|
||||
{
|
||||
entity_xstate_t *oldstate = NULL;
|
||||
int oldindex, oldnum;
|
||||
unsigned int newnum;
|
||||
unsigned bits;
|
||||
entity_state_t
|
||||
*oldstate = NULL;
|
||||
int oldindex, oldnum;
|
||||
|
||||
newframe->parse_entities = cl.parse_entities;
|
||||
newframe->num_entities = 0;
|
||||
|
@ -541,7 +595,7 @@ CL_ParsePacketEntities(frame_t *oldframe, frame_t *newframe)
|
|||
}
|
||||
|
||||
static void
|
||||
CL_ParsePlayerstate(frame_t *oldframe, frame_t *newframe)
|
||||
CL_ParsePlayerstate(frame_t *oldframe, frame_t *newframe, int protocol)
|
||||
{
|
||||
int flags, i, statbits;
|
||||
player_state_t *state;
|
||||
|
@ -569,9 +623,18 @@ CL_ParsePlayerstate(frame_t *oldframe, frame_t *newframe)
|
|||
|
||||
if (flags & PS_M_ORIGIN)
|
||||
{
|
||||
state->pmove.origin[0] = MSG_ReadShort(&net_message);
|
||||
state->pmove.origin[1] = MSG_ReadShort(&net_message);
|
||||
state->pmove.origin[2] = MSG_ReadShort(&net_message);
|
||||
if (IS_QII97_PROTOCOL(protocol))
|
||||
{
|
||||
state->pmove.origin[0] = MSG_ReadShort(&net_message);
|
||||
state->pmove.origin[1] = MSG_ReadShort(&net_message);
|
||||
state->pmove.origin[2] = MSG_ReadShort(&net_message);
|
||||
}
|
||||
else
|
||||
{
|
||||
state->pmove.origin[0] = MSG_ReadLong(&net_message);
|
||||
state->pmove.origin[1] = MSG_ReadLong(&net_message);
|
||||
state->pmove.origin[2] = MSG_ReadLong(&net_message);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & PS_M_VELOCITY)
|
||||
|
@ -632,7 +695,7 @@ CL_ParsePlayerstate(frame_t *oldframe, frame_t *newframe)
|
|||
|
||||
if (flags & PS_WEAPONINDEX)
|
||||
{
|
||||
if (IS_QII97_PROTOCOL(cls.serverProtocol))
|
||||
if (IS_QII97_PROTOCOL(protocol))
|
||||
{
|
||||
state->gunindex = MSG_ReadByte(&net_message);
|
||||
}
|
||||
|
@ -644,7 +707,7 @@ CL_ParsePlayerstate(frame_t *oldframe, frame_t *newframe)
|
|||
|
||||
if (flags & PS_WEAPONFRAME)
|
||||
{
|
||||
if (IS_QII97_PROTOCOL(cls.serverProtocol))
|
||||
if (IS_QII97_PROTOCOL(protocol))
|
||||
{
|
||||
state->gunframe = MSG_ReadByte(&net_message);
|
||||
}
|
||||
|
@ -691,7 +754,7 @@ CL_ParsePlayerstate(frame_t *oldframe, frame_t *newframe)
|
|||
if (i == STAT_PICKUP_STRING)
|
||||
{
|
||||
state->stats[i] = P_ConvertConfigStringFrom(state->stats[i],
|
||||
cls.serverProtocol);
|
||||
protocol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -700,11 +763,13 @@ CL_ParsePlayerstate(frame_t *oldframe, frame_t *newframe)
|
|||
static void
|
||||
CL_FireEntityEvents(frame_t *frame)
|
||||
{
|
||||
entity_state_t *s1;
|
||||
int pnum, num;
|
||||
int pnum;
|
||||
|
||||
for (pnum = 0; pnum < frame->num_entities; pnum++)
|
||||
{
|
||||
entity_xstate_t *s1;
|
||||
int num;
|
||||
|
||||
num = (frame->parse_entities + pnum) & (MAX_PARSE_ENTITIES - 1);
|
||||
s1 = &cl_parse_entities[num];
|
||||
|
||||
|
@ -720,8 +785,8 @@ CL_FireEntityEvents(frame_t *frame)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
SHOWNET(char *s)
|
||||
static void
|
||||
SHOWNET(const char *s)
|
||||
{
|
||||
if (cl_shownet->value >= 2)
|
||||
{
|
||||
|
@ -815,7 +880,7 @@ CL_ParseFrame(void)
|
|||
Com_Error(ERR_DROP, "CL_ParseFrame: 0x%X not playerinfo", cmd);
|
||||
}
|
||||
|
||||
CL_ParsePlayerstate(old, &cl.frame);
|
||||
CL_ParsePlayerstate(old, &cl.frame, cls.serverProtocol);
|
||||
|
||||
/* read packet entities */
|
||||
cmd = MSG_ReadByte(&net_message);
|
||||
|
@ -981,10 +1046,10 @@ CL_ParseServerData(void)
|
|||
static void
|
||||
CL_ParseBaseline(void)
|
||||
{
|
||||
entity_state_t *es;
|
||||
entity_xstate_t nullstate;
|
||||
entity_xstate_t *es;
|
||||
unsigned bits;
|
||||
int newnum;
|
||||
entity_state_t nullstate;
|
||||
|
||||
memset(&nullstate, 0, sizeof(nullstate));
|
||||
|
||||
|
@ -1151,7 +1216,8 @@ CL_ParseClientinfo(int player)
|
|||
static void
|
||||
CL_ParseConfigString(void)
|
||||
{
|
||||
int i, length;
|
||||
size_t length;
|
||||
int i;
|
||||
char *s;
|
||||
char olds[MAX_QPATH];
|
||||
|
||||
|
@ -1304,7 +1370,7 @@ CL_ParseStartSoundPacket(void)
|
|||
if (flags & SND_POS)
|
||||
{
|
||||
/* positioned in space */
|
||||
MSG_ReadPos(&net_message, pos_v);
|
||||
MSG_ReadPos(&net_message, pos_v, cls.serverProtocol);
|
||||
|
||||
pos = pos_v;
|
||||
}
|
||||
|
|
|
@ -81,17 +81,19 @@ void
|
|||
CL_ClipMoveToEntities(vec3_t start, vec3_t mins, vec3_t maxs,
|
||||
vec3_t end, trace_t *tr)
|
||||
{
|
||||
int i, x, zd, zu;
|
||||
trace_t trace;
|
||||
int headnode;
|
||||
float *angles;
|
||||
entity_state_t *ent;
|
||||
int num;
|
||||
cmodel_t *cmodel;
|
||||
vec3_t bmins, bmaxs;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < cl.frame.num_entities; i++)
|
||||
{
|
||||
int x, zd, zu;
|
||||
trace_t trace;
|
||||
int headnode;
|
||||
float *angles;
|
||||
int num;
|
||||
cmodel_t *cmodel;
|
||||
vec3_t bmins, bmaxs;
|
||||
entity_xstate_t *ent;
|
||||
|
||||
num = (cl.frame.parse_entities + i) & (MAX_PARSE_ENTITIES - 1);
|
||||
ent = &cl_parse_entities[num];
|
||||
|
||||
|
@ -184,15 +186,16 @@ int
|
|||
CL_PMpointcontents(vec3_t point)
|
||||
{
|
||||
int i;
|
||||
entity_state_t *ent;
|
||||
int num;
|
||||
cmodel_t *cmodel;
|
||||
int contents;
|
||||
|
||||
contents = CM_PointContents(point, 0);
|
||||
|
||||
for (i = 0; i < cl.frame.num_entities; i++)
|
||||
{
|
||||
entity_xstate_t *ent;
|
||||
int num;
|
||||
cmodel_t *cmodel;
|
||||
|
||||
num = (cl.frame.parse_entities + i) & (MAX_PARSE_ENTITIES - 1);
|
||||
ent = &cl_parse_entities[num];
|
||||
|
||||
|
|
|
@ -27,12 +27,12 @@
|
|||
|
||||
#include "header/client.h"
|
||||
|
||||
float scr_con_current; /* aproaches scr_conlines at scr_conspeed */
|
||||
float scr_conlines; /* 0.0 to 1.0 lines of console to display */
|
||||
static float scr_con_current; /* aproaches scr_conlines at scr_conspeed */
|
||||
static float scr_conlines; /* 0.0 to 1.0 lines of console to display */
|
||||
|
||||
qboolean scr_initialized; /* ready to draw */
|
||||
static qboolean scr_initialized; /* ready to draw */
|
||||
|
||||
int scr_draw_loading;
|
||||
static int scr_draw_loading;
|
||||
|
||||
vrect_t scr_vrect; /* position of render window on screen */
|
||||
|
||||
|
@ -59,18 +59,20 @@ typedef struct
|
|||
int x1, y1, x2, y2;
|
||||
} dirty_t;
|
||||
|
||||
dirty_t scr_dirty, scr_old_dirty[2];
|
||||
static dirty_t scr_dirty, scr_old_dirty[2];
|
||||
|
||||
char crosshair_pic[MAX_QPATH];
|
||||
int crosshair_width, crosshair_height;
|
||||
static char crosshair_pic[MAX_QPATH];
|
||||
static int crosshair_width, crosshair_height;
|
||||
|
||||
extern cvar_t *cl_showfps;
|
||||
extern cvar_t *crosshair_scale;
|
||||
extern cvar_t *cl_showspeed;
|
||||
extern float GetPlayerSpeed(float *, float *);
|
||||
|
||||
void SCR_TimeRefresh_f(void);
|
||||
void SCR_Loading_f(void);
|
||||
static void SCR_TimeRefresh_f(void);
|
||||
static void SCR_Loading_f(void);
|
||||
|
||||
#define CHAR_SIZE 8
|
||||
|
||||
/*
|
||||
* A new packet was just parsed
|
||||
|
@ -129,7 +131,7 @@ SCR_DebugGraph(float value, int color)
|
|||
current++;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SCR_DrawDebugGraph(void)
|
||||
{
|
||||
int a, x, y, w, i, h;
|
||||
|
@ -162,11 +164,58 @@ SCR_DrawDebugGraph(void)
|
|||
}
|
||||
}
|
||||
|
||||
char scr_centerstring[1024];
|
||||
float scr_centertime_start; /* for slow victory printing */
|
||||
float scr_centertime_off;
|
||||
int scr_center_lines;
|
||||
int scr_erase_center;
|
||||
static char scr_centerstring[1024];
|
||||
static float scr_centertime_start; /* for slow victory printing */
|
||||
static float scr_centertime_off;
|
||||
static int scr_center_lines;
|
||||
static int scr_erase_center;
|
||||
|
||||
static int
|
||||
SCR_CopyUtf8(const char *src, char *dst, int limit)
|
||||
{
|
||||
int symbols = 0;
|
||||
|
||||
while (*src && *src != '\n')
|
||||
{
|
||||
size_t size = 1;
|
||||
int i;
|
||||
|
||||
if (symbols >= limit)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(*src & 0x80))
|
||||
{
|
||||
size = 1;
|
||||
}
|
||||
else if ((*src & 0xE0) == 0xC0)
|
||||
{
|
||||
size = 2;
|
||||
}
|
||||
else if ((*src & 0xF0) == 0xE0)
|
||||
{
|
||||
size = 3;
|
||||
}
|
||||
else if ((*src & 0xF8) == 0xF0)
|
||||
{
|
||||
size = 4;
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
*dst = *src;
|
||||
dst ++;
|
||||
src ++;
|
||||
}
|
||||
|
||||
symbols ++;
|
||||
}
|
||||
|
||||
*dst = 0;
|
||||
|
||||
return symbols;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called for important messages that should stay
|
||||
|
@ -176,8 +225,6 @@ void
|
|||
SCR_CenterPrint(char *str)
|
||||
{
|
||||
char *s;
|
||||
char line[64];
|
||||
int i, j, l;
|
||||
|
||||
Q_strlcpy(scr_centerstring, str, sizeof(scr_centerstring));
|
||||
scr_centertime_off = scr_centertime->value;
|
||||
|
@ -204,29 +251,14 @@ SCR_CenterPrint(char *str)
|
|||
|
||||
do
|
||||
{
|
||||
/* scan the width of the line */
|
||||
for (l = 0; l < 40; l++)
|
||||
{
|
||||
if ((s[l] == '\n') || !s[l])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
char line[161];
|
||||
int l;
|
||||
|
||||
for (i = 0; i < (40 - l) / 2; i++)
|
||||
{
|
||||
line[i] = ' ';
|
||||
}
|
||||
l = SCR_CopyUtf8(s, line, 40);
|
||||
memmove(line + (40 - l) / 2, line, strlen(line) + 1);
|
||||
memset(line, ' ', (40 - l) / 2);
|
||||
|
||||
for (j = 0; j < l; j++)
|
||||
{
|
||||
line[i++] = s[j];
|
||||
}
|
||||
|
||||
line[i] = '\n';
|
||||
line[i + 1] = 0;
|
||||
|
||||
Com_Printf("%s", line);
|
||||
Com_Printf("%s\n", line);
|
||||
|
||||
while (*s && *s != '\n')
|
||||
{
|
||||
|
@ -246,20 +278,12 @@ SCR_CenterPrint(char *str)
|
|||
Con_ClearNotify();
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SCR_DrawCenterString(void)
|
||||
{
|
||||
char *start;
|
||||
int l;
|
||||
int j;
|
||||
int x, y;
|
||||
int remaining;
|
||||
float scale;
|
||||
const int char_unscaled_width = 8;
|
||||
const int char_unscaled_height = 8;
|
||||
|
||||
/* the finale prints the characters one at a time */
|
||||
remaining = 9999;
|
||||
int y;
|
||||
|
||||
scr_erase_center = 0;
|
||||
start = scr_centerstring;
|
||||
|
@ -277,31 +301,18 @@ SCR_DrawCenterString(void)
|
|||
|
||||
do
|
||||
{
|
||||
/* scan the width of the line */
|
||||
for (l = 0; l < 40; l++)
|
||||
{
|
||||
if ((start[l] == '\n') || !start[l])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
char message[241]; /* utf string could by 4 bytes per char */
|
||||
int l, x;
|
||||
|
||||
x = ((viddef.width / scale) - (l * char_unscaled_width)) / 2;
|
||||
SCR_AddDirtyPoint(x, y);
|
||||
l = SCR_CopyUtf8(start, message, 60);
|
||||
|
||||
for (j = 0; j < l; j++, x += char_unscaled_width)
|
||||
{
|
||||
Draw_CharScaled(x * scale, y * scale, start[j], scale);
|
||||
x = ((viddef.width / scale) - (l * CHAR_SIZE)) / 2;
|
||||
SCR_AddDirtyPoint(x * scale, y * scale);
|
||||
SCR_AddDirtyPoint((x + l * CHAR_SIZE) * scale, (y + CHAR_SIZE) * scale);
|
||||
|
||||
if (!remaining--)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
Draw_StringScaled(x * scale, y * scale, scale, false, message);
|
||||
|
||||
SCR_AddDirtyPoint(x, y + char_unscaled_height);
|
||||
|
||||
y += char_unscaled_height;
|
||||
y += CHAR_SIZE;
|
||||
|
||||
while (*start && *start != '\n')
|
||||
{
|
||||
|
@ -318,7 +329,7 @@ SCR_DrawCenterString(void)
|
|||
while (1);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SCR_CheckDrawCenterString(void)
|
||||
{
|
||||
scr_centertime_off -= cls.rframetime;
|
||||
|
@ -362,16 +373,16 @@ SCR_CalcVrect(void)
|
|||
/*
|
||||
* Keybinding command
|
||||
*/
|
||||
void
|
||||
static void
|
||||
SCR_SizeUp_f(void)
|
||||
{
|
||||
Cvar_SetValue("viewsize", (float)scr_viewsize->value + 10);
|
||||
}
|
||||
|
||||
/*
|
||||
*Keybinding command
|
||||
* Keybinding command
|
||||
*/
|
||||
void
|
||||
static void
|
||||
SCR_SizeDown_f(void)
|
||||
{
|
||||
Cvar_SetValue("viewsize", (float)scr_viewsize->value - 10);
|
||||
|
@ -380,7 +391,7 @@ SCR_SizeDown_f(void)
|
|||
/*
|
||||
* Set a specific sky and rotation speed
|
||||
*/
|
||||
void
|
||||
static void
|
||||
SCR_Sky_f(void)
|
||||
{
|
||||
int autorotate = 1;
|
||||
|
@ -448,7 +459,7 @@ SCR_Init(void)
|
|||
scr_initialized = true;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SCR_DrawNet(void)
|
||||
{
|
||||
float scale = SCR_GetMenuScale();
|
||||
|
@ -458,10 +469,10 @@ SCR_DrawNet(void)
|
|||
return;
|
||||
}
|
||||
|
||||
Draw_PicScaled(scr_vrect.x + 64 * scale, scr_vrect.y, "net", scale);
|
||||
Draw_PicScaledAltText(scr_vrect.x + 64 * scale, scr_vrect.y, "net", scale, "net");
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SCR_DrawPause(void)
|
||||
{
|
||||
int w, h;
|
||||
|
@ -478,10 +489,11 @@ SCR_DrawPause(void)
|
|||
}
|
||||
|
||||
Draw_GetPicSize(&w, &h, "pause");
|
||||
Draw_PicScaled((viddef.width - w * scale) / 2, viddef.height / 2 + 8 * scale, "pause", scale);
|
||||
Draw_PicScaledAltText((viddef.width - w * scale) / 2, viddef.height / 2 + CHAR_SIZE * scale,
|
||||
"pause", scale, "pause");
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SCR_DrawLoading(void)
|
||||
{
|
||||
int w, h;
|
||||
|
@ -493,7 +505,8 @@ SCR_DrawLoading(void)
|
|||
}
|
||||
|
||||
Draw_GetPicSize(&w, &h, "loading");
|
||||
Draw_PicScaled((viddef.width - w * scale) / 2, (viddef.height - h * scale) / 2, "loading", scale);
|
||||
Draw_PicScaledAltText((viddef.width - w * scale) / 2, (viddef.height - h * scale) / 2,
|
||||
"loading", scale, "loading");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -539,7 +552,7 @@ SCR_RunConsole(void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SCR_DrawConsole(void)
|
||||
{
|
||||
Con_CheckResize();
|
||||
|
@ -636,13 +649,13 @@ SCR_EndLoadingPlaque(void)
|
|||
Con_ClearNotify();
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SCR_Loading_f(void)
|
||||
{
|
||||
SCR_BeginLoadingPlaque();
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SCR_TimeRefresh_f(void)
|
||||
{
|
||||
int i;
|
||||
|
@ -725,7 +738,7 @@ SCR_DirtyScreen(void)
|
|||
/*
|
||||
* Clear any parts of the tiled background that were drawn on last frame
|
||||
*/
|
||||
void
|
||||
static void
|
||||
SCR_TileClear(void)
|
||||
{
|
||||
int i;
|
||||
|
@ -860,7 +873,7 @@ SCR_TileClear(void)
|
|||
}
|
||||
|
||||
#define STAT_MINUS 10
|
||||
char *sb_nums[2][11] = {
|
||||
static char *sb_nums[2][11] = {
|
||||
{
|
||||
"num_0", "num_1", "num_2", "num_3", "num_4", "num_5",
|
||||
"num_6", "num_7", "num_8", "num_9", "num_minus"
|
||||
|
@ -873,71 +886,27 @@ char *sb_nums[2][11] = {
|
|||
|
||||
#define ICON_WIDTH 24
|
||||
#define ICON_HEIGHT 24
|
||||
#define CHAR_WIDTH 16
|
||||
#define CHARACTER_WIDTH 16
|
||||
#define ICON_SPACE 8
|
||||
|
||||
/*
|
||||
* Allow embedded \n in the string
|
||||
*/
|
||||
void
|
||||
SizeHUDString(char *string, int *w, int *h)
|
||||
{
|
||||
int lines, width, current;
|
||||
|
||||
lines = 1;
|
||||
width = 0;
|
||||
|
||||
current = 0;
|
||||
|
||||
while (*string)
|
||||
{
|
||||
if (*string == '\n')
|
||||
{
|
||||
lines++;
|
||||
current = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
current++;
|
||||
|
||||
if (current > width)
|
||||
{
|
||||
width = current;
|
||||
}
|
||||
}
|
||||
|
||||
string++;
|
||||
}
|
||||
|
||||
*w = width * 8;
|
||||
*h = lines * 8;
|
||||
}
|
||||
|
||||
void
|
||||
DrawHUDStringScaled(const char *string, int x, int y, int centerwidth, int xor, float factor)
|
||||
static void
|
||||
DrawHUDStringScaled(const char *string, int x, int y, int centerwidth, qboolean alt, float factor)
|
||||
{
|
||||
int margin;
|
||||
char line[1024];
|
||||
int width;
|
||||
int i;
|
||||
|
||||
margin = x;
|
||||
|
||||
while (*string)
|
||||
{
|
||||
/* scan out one line of text from the string */
|
||||
width = 0;
|
||||
int width;
|
||||
char line[1024];
|
||||
|
||||
while (*string && *string != '\n')
|
||||
{
|
||||
line[width++] = *string++;
|
||||
}
|
||||
|
||||
line[width] = 0;
|
||||
width = SCR_CopyUtf8(string, line, 255);
|
||||
|
||||
if (centerwidth)
|
||||
{
|
||||
x = margin + (centerwidth - width * 8)*factor / 2;
|
||||
x = margin + (centerwidth - width * CHAR_SIZE) * factor / 2;
|
||||
}
|
||||
|
||||
else
|
||||
|
@ -945,27 +914,22 @@ DrawHUDStringScaled(const char *string, int x, int y, int centerwidth, int xor,
|
|||
x = margin;
|
||||
}
|
||||
|
||||
for (i = 0; i < width; i++)
|
||||
Draw_StringScaled(x, y, factor, alt, line);
|
||||
|
||||
while (*string && *string != '\n')
|
||||
{
|
||||
Draw_CharScaled(x, y, line[i] ^ xor, factor);
|
||||
x += 8*factor;
|
||||
string++;
|
||||
}
|
||||
|
||||
if (*string)
|
||||
{
|
||||
string++; /* skip the \n */
|
||||
y += 8*factor;
|
||||
y += CHAR_SIZE * factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawHUDString(char *string, int x, int y, int centerwidth, int xor)
|
||||
{
|
||||
DrawHUDStringScaled(string, x, y, centerwidth, xor, 1.0f);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SCR_DrawFieldScaled(int x, int y, int color, int width, int value, float factor)
|
||||
{
|
||||
char num[16], *ptr;
|
||||
|
@ -984,7 +948,7 @@ SCR_DrawFieldScaled(int x, int y, int color, int width, int value, float factor)
|
|||
}
|
||||
|
||||
SCR_AddDirtyPoint(x, y);
|
||||
SCR_AddDirtyPoint(x + (width * CHAR_WIDTH + 2)*factor, y + factor*24);
|
||||
SCR_AddDirtyPoint(x + (width * CHARACTER_WIDTH + 2) * factor, y + factor * 24);
|
||||
|
||||
Com_sprintf(num, sizeof(num), "%i", value);
|
||||
l = (int)strlen(num);
|
||||
|
@ -994,12 +958,15 @@ SCR_DrawFieldScaled(int x, int y, int color, int width, int value, float factor)
|
|||
l = width;
|
||||
}
|
||||
|
||||
x += (2 + CHAR_WIDTH * (width - l)) * factor;
|
||||
x += (2 + CHARACTER_WIDTH * (width - l)) * factor;
|
||||
|
||||
ptr = num;
|
||||
|
||||
while (*ptr && l)
|
||||
{
|
||||
char alttext[] = "?";
|
||||
|
||||
alttext[0] = *ptr;
|
||||
if (*ptr == '-')
|
||||
{
|
||||
frame = STAT_MINUS;
|
||||
|
@ -1010,19 +977,13 @@ SCR_DrawFieldScaled(int x, int y, int color, int width, int value, float factor)
|
|||
frame = *ptr - '0';
|
||||
}
|
||||
|
||||
Draw_PicScaled(x, y, sb_nums[color][frame], factor);
|
||||
x += CHAR_WIDTH*factor;
|
||||
Draw_PicScaledAltText(x, y, sb_nums[color][frame], factor, alttext);
|
||||
x += CHARACTER_WIDTH * factor;
|
||||
ptr++;
|
||||
l--;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SCR_DrawField(int x, int y, int color, int width, int value)
|
||||
{
|
||||
SCR_DrawFieldScaled(x, y, color, width, value, 1.0f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allows rendering code to cache all needed sbar graphics
|
||||
*/
|
||||
|
@ -1057,17 +1018,13 @@ SCR_TouchPics(void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SCR_ExecuteLayoutString(char *s)
|
||||
{
|
||||
int x, y;
|
||||
int value;
|
||||
const char *token;
|
||||
int width;
|
||||
int index;
|
||||
clientinfo_t *ci;
|
||||
float scale;
|
||||
|
||||
float scale = SCR_GetHUDScale();
|
||||
scale = SCR_GetHUDScale();
|
||||
|
||||
if ((cls.state != ca_active) || !cl.refresh_prepped)
|
||||
{
|
||||
|
@ -1084,6 +1041,8 @@ SCR_ExecuteLayoutString(char *s)
|
|||
|
||||
while (s)
|
||||
{
|
||||
const char *token;
|
||||
|
||||
token = COM_Parse(&s);
|
||||
|
||||
if (!strcmp(token, "xl"))
|
||||
|
@ -1130,27 +1089,38 @@ SCR_ExecuteLayoutString(char *s)
|
|||
|
||||
if (!strcmp(token, "pic"))
|
||||
{
|
||||
int index, value;
|
||||
|
||||
/* draw a pic from a stat number */
|
||||
token = COM_Parse(&s);
|
||||
index = (int)strtol(token, (char **)NULL, 10);
|
||||
|
||||
if ((index < 0) || (index >= MAX_STATS))
|
||||
{
|
||||
Com_Error(ERR_DROP, "bad stats index %d (0x%x)", index, index);
|
||||
Com_DPrintf("%s: bad stats index %d (0x%x) in pic\n",
|
||||
__func__, index, index);
|
||||
continue;
|
||||
}
|
||||
|
||||
value = cl.frame.playerstate.stats[index];
|
||||
|
||||
if (value >= MAX_IMAGES)
|
||||
{
|
||||
Com_Error(ERR_DROP, "Pic >= MAX_IMAGES");
|
||||
Com_DPrintf("%s: Pic %d >= MAX_IMAGES in pic\n",
|
||||
__func__, value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cl.configstrings[CS_IMAGES + value][0] != '\0')
|
||||
{
|
||||
const char *text;
|
||||
int w, h;
|
||||
|
||||
text = cl.configstrings[CS_IMAGES + value];
|
||||
Draw_GetPicSize(&w, &h, text);
|
||||
SCR_AddDirtyPoint(x, y);
|
||||
SCR_AddDirtyPoint(x + 23*scale, y + 23*scale);
|
||||
Draw_PicScaled(x, y, cl.configstrings[CS_IMAGES + value], scale);
|
||||
SCR_AddDirtyPoint(x + (w - 1) * scale, y + (h - 1) * scale);
|
||||
Draw_PicScaled(x, y, text, scale);
|
||||
}
|
||||
|
||||
continue;
|
||||
|
@ -1159,21 +1129,23 @@ SCR_ExecuteLayoutString(char *s)
|
|||
if (!strcmp(token, "client"))
|
||||
{
|
||||
/* draw a deathmatch client block */
|
||||
int score, ping, time;
|
||||
int score, ping, time, value;
|
||||
clientinfo_t *ci;
|
||||
|
||||
token = COM_Parse(&s);
|
||||
x = viddef.width / 2 - scale*160 + scale*(int)strtol(token, (char **)NULL, 10);
|
||||
x = viddef.width / 2 - scale * 160 + scale * (int)strtol(token, (char **)NULL, 10);
|
||||
token = COM_Parse(&s);
|
||||
y = viddef.height / 2 - scale*120 + scale*(int)strtol(token, (char **)NULL, 10);
|
||||
y = viddef.height / 2 - scale * 120 + scale * (int)strtol(token, (char **)NULL, 10);
|
||||
SCR_AddDirtyPoint(x, y);
|
||||
SCR_AddDirtyPoint(x + scale*159, y + scale*31);
|
||||
SCR_AddDirtyPoint(x + scale * 159, y + scale * 31);
|
||||
|
||||
token = COM_Parse(&s);
|
||||
value = (int)strtol(token, (char **)NULL, 10);
|
||||
|
||||
if ((value >= MAX_CLIENTS) || (value < 0))
|
||||
{
|
||||
Com_Error(ERR_DROP, "client >= MAX_CLIENTS");
|
||||
Com_DPrintf("%s: client >= MAX_CLIENTS in client\n", __func__);
|
||||
continue;
|
||||
}
|
||||
|
||||
ci = &cl.clientinfo[value];
|
||||
|
@ -1187,11 +1159,12 @@ SCR_ExecuteLayoutString(char *s)
|
|||
token = COM_Parse(&s);
|
||||
time = (int)strtol(token, (char **)NULL, 10);
|
||||
|
||||
DrawAltStringScaled(x + scale*32, y, ci->name, scale);
|
||||
DrawAltStringScaled(x + scale*32, y + scale*8, "Score: ", scale);
|
||||
DrawAltStringScaled(x + scale*(32 + 7 * 8), y + scale*8, va("%i", score), scale);
|
||||
DrawStringScaled(x + scale*32, y + scale*16, va("Ping: %i", ping), scale);
|
||||
DrawStringScaled(x + scale*32, y + scale*24, va("Time: %i", time), scale);
|
||||
Draw_StringScaled(x + scale * 32, y, scale, true, ci->name);
|
||||
Draw_StringScaled(x + scale * 32, y + scale * CHAR_SIZE, scale, true, "Score: ");
|
||||
Draw_StringScaled(x + scale * (32 + 7 * CHAR_SIZE),
|
||||
y + scale * CHAR_SIZE, scale, true, va("%i", score));
|
||||
Draw_StringScaled(x + scale * 32, y + scale * 16, scale, false, va("Ping: %i", ping));
|
||||
Draw_StringScaled(x + scale * 32, y + scale * 24, scale, false, va("Time: %i", time));
|
||||
|
||||
if (!ci->icon)
|
||||
{
|
||||
|
@ -1205,22 +1178,24 @@ SCR_ExecuteLayoutString(char *s)
|
|||
if (!strcmp(token, "ctf"))
|
||||
{
|
||||
/* draw a ctf client block */
|
||||
int score, ping;
|
||||
int score, ping, value;
|
||||
clientinfo_t *ci;
|
||||
char block[80];
|
||||
|
||||
token = COM_Parse(&s);
|
||||
x = viddef.width / 2 - scale*160 + scale*(int)strtol(token, (char **)NULL, 10);
|
||||
x = viddef.width / 2 - scale * 160 + scale*(int)strtol(token, (char **)NULL, 10);
|
||||
token = COM_Parse(&s);
|
||||
y = viddef.height / 2 - scale*120 + scale*(int)strtol(token, (char **)NULL, 10);
|
||||
y = viddef.height / 2 - scale * 120 + scale*(int)strtol(token, (char **)NULL, 10);
|
||||
SCR_AddDirtyPoint(x, y);
|
||||
SCR_AddDirtyPoint(x + scale*159, y + scale*31);
|
||||
SCR_AddDirtyPoint(x + scale * 159, y + scale * 31);
|
||||
|
||||
token = COM_Parse(&s);
|
||||
value = (int)strtol(token, (char **)NULL, 10);
|
||||
|
||||
if ((value >= MAX_CLIENTS) || (value < 0))
|
||||
{
|
||||
Com_Error(ERR_DROP, "client >= MAX_CLIENTS");
|
||||
Com_DPrintf("%s: client >= MAX_CLIENTS in client\n", __func__);
|
||||
continue;
|
||||
}
|
||||
|
||||
ci = &cl.clientinfo[value];
|
||||
|
@ -1238,31 +1213,28 @@ SCR_ExecuteLayoutString(char *s)
|
|||
|
||||
sprintf(block, "%3d %3d %-12.12s", score, ping, ci->name);
|
||||
|
||||
if (value == cl.playernum)
|
||||
{
|
||||
DrawAltStringScaled(x, y, block, scale);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
DrawStringScaled(x, y, block, scale);
|
||||
}
|
||||
Draw_StringScaled(x, y, scale, value == cl.playernum, token);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(token, "picn"))
|
||||
{
|
||||
int w, h;
|
||||
|
||||
/* draw a pic from a name */
|
||||
token = COM_Parse(&s);
|
||||
Draw_GetPicSize(&w, &h, token);
|
||||
SCR_AddDirtyPoint(x, y);
|
||||
SCR_AddDirtyPoint(x + scale * 23, y + scale * 23);
|
||||
Draw_PicScaled(x, y, (char *)token, scale);
|
||||
SCR_AddDirtyPoint(x + scale * (w - 1), y + scale * (h - 1));
|
||||
Draw_PicScaled(x, y, token, scale);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(token, "num"))
|
||||
{
|
||||
int value, width;
|
||||
|
||||
/* draw a number */
|
||||
token = COM_Parse(&s);
|
||||
width = (int)strtol(token, (char **)NULL, 10);
|
||||
|
@ -1275,7 +1247,7 @@ SCR_ExecuteLayoutString(char *s)
|
|||
if (!strcmp(token, "hnum"))
|
||||
{
|
||||
/* health number */
|
||||
int color;
|
||||
int color, value, width;
|
||||
|
||||
width = 3;
|
||||
value = cl.frame.playerstate.stats[STAT_HEALTH];
|
||||
|
@ -1305,7 +1277,7 @@ SCR_ExecuteLayoutString(char *s)
|
|||
if (!strcmp(token, "anum"))
|
||||
{
|
||||
/* ammo number */
|
||||
int color;
|
||||
int color, value, width;
|
||||
|
||||
width = 3;
|
||||
value = cl.frame.playerstate.stats[STAT_AMMO];
|
||||
|
@ -1335,7 +1307,7 @@ SCR_ExecuteLayoutString(char *s)
|
|||
if (!strcmp(token, "rnum"))
|
||||
{
|
||||
/* armor number */
|
||||
int color;
|
||||
int color, value, width;
|
||||
|
||||
width = 3;
|
||||
value = cl.frame.playerstate.stats[STAT_ARMOR];
|
||||
|
@ -1358,58 +1330,77 @@ SCR_ExecuteLayoutString(char *s)
|
|||
|
||||
if (!strcmp(token, "stat_string"))
|
||||
{
|
||||
int index;
|
||||
|
||||
token = COM_Parse(&s);
|
||||
index = (int)strtol(token, (char **)NULL, 10);
|
||||
|
||||
if ((index < 0) || (index >= MAX_STATS))
|
||||
{
|
||||
Com_Error(ERR_DROP, "Bad stat_string index");
|
||||
Com_DPrintf("%s: bad stats index %d (0x%x) in stat_string\n",
|
||||
__func__, index, index);
|
||||
continue;
|
||||
}
|
||||
|
||||
index = cl.frame.playerstate.stats[index];
|
||||
|
||||
if ((index < 0) || (index >= MAX_CONFIGSTRINGS))
|
||||
{
|
||||
Com_Error(ERR_DROP, "Bad stat_string index");
|
||||
Com_DPrintf("%s: bad stats index %d (0x%x) in stat_string\n",
|
||||
__func__, index, index);
|
||||
continue;
|
||||
}
|
||||
|
||||
DrawStringScaled(x, y, cl.configstrings[index], scale);
|
||||
Draw_StringScaled(x, y, scale, false, cl.configstrings[index]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(token, "cstring"))
|
||||
{
|
||||
token = COM_Parse(&s);
|
||||
DrawHUDStringScaled(token, x, y, 320, 0, scale); // FIXME: or scale 320 here?
|
||||
DrawHUDStringScaled(token, x, y, 320, false, scale); // FIXME: or scale 320 here?
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(token, "string"))
|
||||
{
|
||||
token = COM_Parse(&s);
|
||||
DrawStringScaled(x, y, token, scale);
|
||||
Draw_StringScaled(x, y, scale, false, token);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(token, "cstring2"))
|
||||
{
|
||||
token = COM_Parse(&s);
|
||||
DrawHUDStringScaled(token, x, y, 320, 0x80, scale); // FIXME: or scale 320 here?
|
||||
DrawHUDStringScaled(token, x, y, 320, true, scale); // FIXME: or scale 320 here?
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(token, "string2"))
|
||||
{
|
||||
token = COM_Parse(&s);
|
||||
DrawAltStringScaled(x, y, token, scale);
|
||||
Draw_StringScaled(x, y, scale, true, token);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(token, "if"))
|
||||
{
|
||||
int index, value;
|
||||
|
||||
/* draw a number */
|
||||
token = COM_Parse(&s);
|
||||
value = cl.frame.playerstate.stats[(int)strtol(token, (char **)NULL, 10)];
|
||||
index = (int)strtol(token, (char **)NULL, 10);
|
||||
|
||||
if ((index < 0) || (index >= MAX_STATS))
|
||||
{
|
||||
Com_DPrintf("%s: bad stats index %d (0x%x) in if\n",
|
||||
__func__, index, index);
|
||||
value = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = cl.frame.playerstate.stats[index];
|
||||
}
|
||||
|
||||
if (!value)
|
||||
{
|
||||
|
@ -1422,6 +1413,14 @@ SCR_ExecuteLayoutString(char *s)
|
|||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(token, "endif") || (token && !token[0]))
|
||||
{
|
||||
/* just skip endif and empty line */
|
||||
continue;
|
||||
}
|
||||
|
||||
Com_DPrintf("%s: Unknown token: %s\n", __func__, token);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1429,7 +1428,7 @@ SCR_ExecuteLayoutString(char *s)
|
|||
* The status bar is a small layout program that
|
||||
* is based on the stats array
|
||||
*/
|
||||
void
|
||||
static void
|
||||
SCR_DrawStats(void)
|
||||
{
|
||||
SCR_ExecuteLayoutString(cl.configstrings[CS_STATUSBAR]);
|
||||
|
@ -1437,7 +1436,7 @@ SCR_DrawStats(void)
|
|||
|
||||
#define STAT_LAYOUTS 13
|
||||
|
||||
void
|
||||
static void
|
||||
SCR_DrawLayout(void)
|
||||
{
|
||||
if (!cl.frame.playerstate.stats[STAT_LAYOUTS])
|
||||
|
@ -1450,7 +1449,7 @@ SCR_DrawLayout(void)
|
|||
|
||||
// ----
|
||||
|
||||
void
|
||||
static void
|
||||
SCR_DrawSpeed(void)
|
||||
{
|
||||
if (cl_showspeed->value < 1) //Disabled, do nothing
|
||||
|
@ -1463,7 +1462,7 @@ SCR_DrawSpeed(void)
|
|||
|
||||
GetPlayerSpeed(&speed, &speedxy);
|
||||
snprintf(spd_str, sizeof(spd_str), "%6.2f (%6.2f) QU/s", speed, speedxy);
|
||||
str_len = scale * (strlen(spd_str) * 8 + 2);
|
||||
str_len = scale * (strlen(spd_str) * CHAR_SIZE + 2);
|
||||
|
||||
if (cl_showspeed->value == 1) //Draw speed and xy speed at top right
|
||||
{
|
||||
|
@ -1478,7 +1477,7 @@ SCR_DrawSpeed(void)
|
|||
yPos = scale * 20;
|
||||
}
|
||||
|
||||
DrawStringScaled(xPos, yPos, spd_str, scale);
|
||||
Draw_StringScaled(xPos, yPos, scale, false, spd_str);
|
||||
SCR_AddDirtyPoint(xPos, yPos);
|
||||
SCR_AddDirtyPoint(viddef.width, yPos);
|
||||
}
|
||||
|
@ -1491,18 +1490,19 @@ SCR_DrawSpeed(void)
|
|||
}
|
||||
|
||||
snprintf(spd_str, sizeof(spd_str), "%6.2f", speedxy);
|
||||
str_len = scale * (strlen(spd_str) * 8 + 2);
|
||||
str_len = scale * (strlen(spd_str) * CHAR_SIZE + 2);
|
||||
yPos = scr_vrect.y + (scr_vrect.height / 2) + (scale * 10);
|
||||
xPos = scr_vrect.x + (scr_vrect.width / 2) - (str_len / 2);
|
||||
|
||||
DrawStringScaled(xPos, yPos, spd_str, scale);
|
||||
Draw_StringScaled(xPos, yPos, scale, false, spd_str);
|
||||
SCR_AddDirtyPoint(xPos, yPos);
|
||||
SCR_AddDirtyPoint(xPos + str_len, yPos);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SCR_Framecounter(void) {
|
||||
static void
|
||||
SCR_Framecounter(void)
|
||||
{
|
||||
long long newtime;
|
||||
static int frame;
|
||||
static int frametimes[60] = {0};
|
||||
|
@ -1510,39 +1510,26 @@ SCR_Framecounter(void) {
|
|||
|
||||
/* skip statistics without show fps */
|
||||
if (cl_showfps->value < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
newtime = Sys_Microseconds();
|
||||
frametimes[frame] = (int)(newtime - oldtime);
|
||||
|
||||
oldtime = newtime;
|
||||
frame++;
|
||||
if (frame > 59) {
|
||||
if (frame > 59)
|
||||
{
|
||||
frame = 0;
|
||||
}
|
||||
|
||||
float scale = SCR_GetConsoleScale();
|
||||
|
||||
if (cl_showfps->value == 1) {
|
||||
if (cl_showfps->value == 1)
|
||||
{
|
||||
// Calculate average of frames.
|
||||
int avg = 0;
|
||||
int num = 0;
|
||||
|
||||
for (int i = 0; i < 60; i++) {
|
||||
if (frametimes[i] != 0) {
|
||||
avg += frametimes[i];
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char str[10];
|
||||
snprintf(str, sizeof(str), "%3.2ffps", (1000.0 * 1000.0) / (avg / num));
|
||||
DrawStringScaled(viddef.width - scale*(strlen(str)*8 + 2), 0, str, scale);
|
||||
SCR_AddDirtyPoint(viddef.width - scale*(strlen(str)*8 + 2), 0);
|
||||
SCR_AddDirtyPoint(viddef.width, 0);
|
||||
} else if (cl_showfps->value >= 2) {
|
||||
// Calculate average of frames.
|
||||
int avg = 0;
|
||||
int num = 0;
|
||||
|
||||
|
@ -1553,35 +1540,55 @@ SCR_Framecounter(void) {
|
|||
}
|
||||
}
|
||||
|
||||
snprintf(str, sizeof(str), "%3.2ffps", (1000.0 * 1000.0) / (avg / num));
|
||||
Draw_StringScaled(viddef.width - scale * (strlen(str) * CHAR_SIZE + 2), 0, scale, false, str);
|
||||
SCR_AddDirtyPoint(viddef.width - scale * (strlen(str) * CHAR_SIZE + 2), 0);
|
||||
SCR_AddDirtyPoint(viddef.width, 0);
|
||||
}
|
||||
else if (cl_showfps->value >= 2)
|
||||
{
|
||||
// Calculate average of frames.
|
||||
int avg = 0;
|
||||
int num = 0;
|
||||
char str[64];
|
||||
|
||||
for (int i = 0; i < 60; i++) {
|
||||
if (frametimes[i] != 0) {
|
||||
avg += frametimes[i];
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
// Find lowest and highest
|
||||
int min = frametimes[0];
|
||||
int max = frametimes[1];
|
||||
|
||||
for (int i = 1; i < 60; i++) {
|
||||
if ((frametimes[i] > 0) && (min < frametimes[i])) {
|
||||
for (int i = 1; i < 60; i++)
|
||||
{
|
||||
if ((frametimes[i] > 0) && (min < frametimes[i]))
|
||||
{
|
||||
min = frametimes[i];
|
||||
}
|
||||
|
||||
if ((frametimes[i] > 0) && (max > frametimes[i])) {
|
||||
if ((frametimes[i] > 0) && (max > frametimes[i]))
|
||||
{
|
||||
max = frametimes[i];
|
||||
}
|
||||
}
|
||||
|
||||
char str[64];
|
||||
snprintf(str, sizeof(str), "Min: %7.2ffps, Max: %7.2ffps, Avg: %7.2ffps",
|
||||
(1000.0 * 1000.0) / min, (1000.0 * 1000.0) / max, (1000.0 * 1000.0) / (avg / num));
|
||||
DrawStringScaled(viddef.width - scale*(strlen(str)*8 + 2), 0, str, scale);
|
||||
SCR_AddDirtyPoint(viddef.width - scale*(strlen(str)*8 + 2), 0);
|
||||
Draw_StringScaled(viddef.width - scale * (strlen(str) * CHAR_SIZE + 2), 0, scale, false, str);
|
||||
SCR_AddDirtyPoint(viddef.width - scale * (strlen(str) * CHAR_SIZE + 2), 0);
|
||||
SCR_AddDirtyPoint(viddef.width, 0);
|
||||
|
||||
if (cl_showfps->value > 2)
|
||||
{
|
||||
snprintf(str, sizeof(str), "Max: %5.2fms, Min: %5.2fms, Avg: %5.2fms",
|
||||
0.001f*min, 0.001f*max, 0.001f*(avg / num));
|
||||
DrawStringScaled(viddef.width - scale*(strlen(str)*8 + 2), scale*10, str, scale);
|
||||
SCR_AddDirtyPoint(viddef.width - scale*(strlen(str)*8 + 2), scale*10);
|
||||
SCR_AddDirtyPoint(viddef.width, scale+10);
|
||||
Draw_StringScaled(viddef.width - scale * (strlen(str) * CHAR_SIZE + 2), scale * 10, scale, false, str);
|
||||
SCR_AddDirtyPoint(viddef.width - scale * (strlen(str) * CHAR_SIZE + 2), scale * 10);
|
||||
SCR_AddDirtyPoint(viddef.width, scale + 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1649,7 +1656,8 @@ SCR_UpdateScreen(void)
|
|||
}
|
||||
|
||||
Draw_GetPicSize(&w, &h, "loading");
|
||||
Draw_PicScaled((viddef.width - w * scale) / 2, (viddef.height - h * scale) / 2, "loading", scale);
|
||||
Draw_PicScaledAltText((viddef.width - w * scale) / 2, (viddef.height - h * scale) / 2,
|
||||
"loading", scale, "loading");
|
||||
}
|
||||
|
||||
/* if a cinematic is supposed to be running,
|
||||
|
|
|
@ -119,7 +119,6 @@ void
|
|||
CL_RegisterTEntSounds(void)
|
||||
{
|
||||
int i;
|
||||
char name[MAX_QPATH];
|
||||
|
||||
cl_sfx_ric1 = S_RegisterSound("world/ric1.wav");
|
||||
cl_sfx_ric2 = S_RegisterSound("world/ric2.wav");
|
||||
|
@ -139,6 +138,8 @@ CL_RegisterTEntSounds(void)
|
|||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
|
||||
Com_sprintf(name, sizeof(name), "player/step%i.wav", i + 1);
|
||||
cl_sfx_footsteps[i] = S_RegisterSound(name);
|
||||
}
|
||||
|
@ -252,7 +253,7 @@ CL_ParseParticles(void)
|
|||
int color, count;
|
||||
vec3_t pos, dir;
|
||||
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
|
||||
color = MSG_ReadByte(&net_message);
|
||||
|
@ -273,8 +274,8 @@ CL_ParseBeam(struct model_s *model)
|
|||
|
||||
ent = MSG_ReadShort(&net_message);
|
||||
|
||||
MSG_ReadPos(&net_message, start);
|
||||
MSG_ReadPos(&net_message, end);
|
||||
MSG_ReadPos(&net_message, start, cls.serverProtocol);
|
||||
MSG_ReadPos(&net_message, end, cls.serverProtocol);
|
||||
|
||||
/* override any beam with the same entity */
|
||||
for (i = 0, b = cl_beams; i < MAX_BEAMS; i++, b++)
|
||||
|
@ -320,9 +321,9 @@ CL_ParseBeam2(struct model_s *model)
|
|||
|
||||
ent = MSG_ReadShort(&net_message);
|
||||
|
||||
MSG_ReadPos(&net_message, start);
|
||||
MSG_ReadPos(&net_message, end);
|
||||
MSG_ReadPos(&net_message, offset);
|
||||
MSG_ReadPos(&net_message, start, cls.serverProtocol);
|
||||
MSG_ReadPos(&net_message, end, cls.serverProtocol);
|
||||
MSG_ReadPos(&net_message, offset, cls.serverProtocol);
|
||||
|
||||
/* override any beam with the same entity */
|
||||
for (i = 0, b = cl_beams; i < MAX_BEAMS; i++, b++)
|
||||
|
@ -371,8 +372,8 @@ CL_ParsePlayerBeam(struct model_s *model)
|
|||
|
||||
ent = MSG_ReadShort(&net_message);
|
||||
|
||||
MSG_ReadPos(&net_message, start);
|
||||
MSG_ReadPos(&net_message, end);
|
||||
MSG_ReadPos(&net_message, start, cls.serverProtocol);
|
||||
MSG_ReadPos(&net_message, end, cls.serverProtocol);
|
||||
|
||||
/* network optimization */
|
||||
if (model == cl_mod_heatbeam)
|
||||
|
@ -387,7 +388,7 @@ CL_ParsePlayerBeam(struct model_s *model)
|
|||
}
|
||||
else
|
||||
{
|
||||
MSG_ReadPos(&net_message, offset);
|
||||
MSG_ReadPos(&net_message, offset, cls.serverProtocol);
|
||||
}
|
||||
|
||||
/* Override any beam with the same entity
|
||||
|
@ -438,8 +439,8 @@ CL_ParseLightning(struct model_s *model)
|
|||
srcEnt = MSG_ReadShort(&net_message);
|
||||
destEnt = MSG_ReadShort(&net_message);
|
||||
|
||||
MSG_ReadPos(&net_message, start);
|
||||
MSG_ReadPos(&net_message, end);
|
||||
MSG_ReadPos(&net_message, start, cls.serverProtocol);
|
||||
MSG_ReadPos(&net_message, end, cls.serverProtocol);
|
||||
|
||||
/* override any beam with the same
|
||||
source AND destination entities */
|
||||
|
@ -486,8 +487,8 @@ CL_ParseLaser(int colors)
|
|||
laser_t *l;
|
||||
int i;
|
||||
|
||||
MSG_ReadPos(&net_message, start);
|
||||
MSG_ReadPos(&net_message, end);
|
||||
MSG_ReadPos(&net_message, start, cls.serverProtocol);
|
||||
MSG_ReadPos(&net_message, end, cls.serverProtocol);
|
||||
|
||||
for (i = 0, l = cl_lasers; i < MAX_LASERS; i++, l++)
|
||||
{
|
||||
|
@ -546,7 +547,7 @@ CL_ParseSteam(void)
|
|||
{
|
||||
s->id = id;
|
||||
s->count = MSG_ReadByte(&net_message);
|
||||
MSG_ReadPos(&net_message, s->org);
|
||||
MSG_ReadPos(&net_message, s->org, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, s->dir);
|
||||
r = MSG_ReadByte(&net_message);
|
||||
s->basecolor = VID_PaletteColor(r & 0xff);
|
||||
|
@ -560,7 +561,7 @@ CL_ParseSteam(void)
|
|||
else
|
||||
{
|
||||
MSG_ReadByte(&net_message);
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
MSG_ReadByte(&net_message);
|
||||
MSG_ReadShort(&net_message);
|
||||
|
@ -571,7 +572,7 @@ CL_ParseSteam(void)
|
|||
{
|
||||
/* instant */
|
||||
cnt = MSG_ReadByte(&net_message);
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
r = MSG_ReadByte(&net_message);
|
||||
magnitude = MSG_ReadShort(&net_message);
|
||||
|
@ -604,7 +605,7 @@ CL_ParseWidow(void)
|
|||
if (free_sustain)
|
||||
{
|
||||
s->id = id;
|
||||
MSG_ReadPos(&net_message, s->org);
|
||||
MSG_ReadPos(&net_message, s->org, cls.serverProtocol);
|
||||
s->endtime = cl.time + 2100;
|
||||
s->think = CL_Widowbeamout;
|
||||
s->thinkinterval = 1;
|
||||
|
@ -613,7 +614,7 @@ CL_ParseWidow(void)
|
|||
else
|
||||
{
|
||||
/* no free sustains */
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -638,7 +639,7 @@ CL_ParseNuke(void)
|
|||
if (free_sustain)
|
||||
{
|
||||
s->id = 21000;
|
||||
MSG_ReadPos(&net_message, s->org);
|
||||
MSG_ReadPos(&net_message, s->org, cls.serverProtocol);
|
||||
s->endtime = cl.time + 1000;
|
||||
s->think = CL_Nukeblast;
|
||||
s->thinkinterval = 1;
|
||||
|
@ -647,7 +648,7 @@ CL_ParseNuke(void)
|
|||
else
|
||||
{
|
||||
/* no free sustains */
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -664,7 +665,7 @@ static unsigned int splash_color[] = {
|
|||
void
|
||||
CL_ParseTEnt(void)
|
||||
{
|
||||
int type;
|
||||
temp_event_t type;
|
||||
vec3_t pos, pos2, dir;
|
||||
explosion_t *ex;
|
||||
int cnt;
|
||||
|
@ -678,7 +679,7 @@ CL_ParseTEnt(void)
|
|||
switch (type)
|
||||
{
|
||||
case TE_BLOOD: /* bullet hitting flesh */
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
CL_ParticleEffect(pos, dir, 0xff001f9b, 0xff00001b, 60);
|
||||
break;
|
||||
|
@ -686,7 +687,7 @@ CL_ParseTEnt(void)
|
|||
case TE_GUNSHOT: /* bullet hitting wall */
|
||||
case TE_SPARKS:
|
||||
case TE_BULLET_SPARKS:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
|
||||
if (type == TE_GUNSHOT)
|
||||
|
@ -722,7 +723,7 @@ CL_ParseTEnt(void)
|
|||
|
||||
case TE_SCREEN_SPARKS:
|
||||
case TE_SHIELD_SPARKS:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
|
||||
if (type == TE_SCREEN_SPARKS)
|
||||
|
@ -770,7 +771,7 @@ CL_ParseTEnt(void)
|
|||
break;
|
||||
|
||||
case TE_SHOTGUN: /* bullet hitting wall */
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
CL_ParticleEffect(pos, dir, 0xff000000, 0xff6b6b6b, 20);
|
||||
CL_SmokeAndFlash(pos);
|
||||
|
@ -778,7 +779,7 @@ CL_ParseTEnt(void)
|
|||
|
||||
case TE_SPLASH: /* bullet hitting water */
|
||||
cnt = MSG_ReadByte(&net_message);
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
r = MSG_ReadByte(&net_message);
|
||||
|
||||
|
@ -812,7 +813,7 @@ CL_ParseTEnt(void)
|
|||
|
||||
case TE_LASER_SPARKS:
|
||||
cnt = MSG_ReadByte(&net_message);
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
color = MSG_ReadByte(&net_message);
|
||||
CL_ParticleEffect2(pos, dir,
|
||||
|
@ -820,13 +821,13 @@ CL_ParseTEnt(void)
|
|||
break;
|
||||
|
||||
case TE_BLUEHYPERBLASTER:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, dir);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadPos(&net_message, dir, cls.serverProtocol);
|
||||
CL_BlasterParticles(pos, dir);
|
||||
break;
|
||||
|
||||
case TE_BLASTER: /* blaster hitting wall */
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
CL_BlasterParticles(pos, dir);
|
||||
|
||||
|
@ -864,8 +865,9 @@ CL_ParseTEnt(void)
|
|||
break;
|
||||
|
||||
case TE_RAILTRAIL: /* railgun effect */
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos2);
|
||||
case TE_RAILTRAIL2:
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadPos(&net_message, pos2, cls.serverProtocol);
|
||||
CL_RailTrail(pos, pos2);
|
||||
S_StartSound(pos2, 0, 0, cl_sfx_railg, 1, ATTN_NORM, 0);
|
||||
break;
|
||||
|
@ -873,7 +875,7 @@ CL_ParseTEnt(void)
|
|||
case TE_EXPLOSION2:
|
||||
case TE_GRENADE_EXPLOSION:
|
||||
case TE_GRENADE_EXPLOSION_WATER:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
ex = CL_AllocExplosion();
|
||||
VectorCopy(pos, ex->ent.origin);
|
||||
ex->type = ex_poly;
|
||||
|
@ -901,7 +903,7 @@ CL_ParseTEnt(void)
|
|||
break;
|
||||
|
||||
case TE_PLASMA_EXPLOSION:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
ex = CL_AllocExplosion();
|
||||
VectorCopy(pos, ex->ent.origin);
|
||||
ex->type = ex_poly;
|
||||
|
@ -929,7 +931,7 @@ CL_ParseTEnt(void)
|
|||
case TE_EXPLOSION1:
|
||||
case TE_ROCKET_EXPLOSION:
|
||||
case TE_ROCKET_EXPLOSION_WATER:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
ex = CL_AllocExplosion();
|
||||
VectorCopy(pos, ex->ent.origin);
|
||||
ex->type = ex_poly;
|
||||
|
@ -974,7 +976,7 @@ CL_ParseTEnt(void)
|
|||
break;
|
||||
|
||||
case TE_BFG_EXPLOSION:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
ex = CL_AllocExplosion();
|
||||
VectorCopy(pos, ex->ent.origin);
|
||||
ex->type = ex_poly;
|
||||
|
@ -991,7 +993,7 @@ CL_ParseTEnt(void)
|
|||
break;
|
||||
|
||||
case TE_BFG_BIGEXPLOSION:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
CL_BFGExplosionParticles(pos);
|
||||
break;
|
||||
|
||||
|
@ -1000,8 +1002,8 @@ CL_ParseTEnt(void)
|
|||
break;
|
||||
|
||||
case TE_BUBBLETRAIL:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos2);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadPos(&net_message, pos2, cls.serverProtocol);
|
||||
CL_BubbleTrail(pos, pos2);
|
||||
break;
|
||||
|
||||
|
@ -1011,7 +1013,7 @@ CL_ParseTEnt(void)
|
|||
break;
|
||||
|
||||
case TE_BOSSTPORT: /* boss teleporting to station */
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
CL_BigTeleportParticles(pos);
|
||||
S_StartSound(pos, 0, 0, S_RegisterSound(
|
||||
"misc/bigtele.wav"), 1, ATTN_NONE, 0);
|
||||
|
@ -1023,7 +1025,7 @@ CL_ParseTEnt(void)
|
|||
|
||||
case TE_WELDING_SPARKS:
|
||||
cnt = MSG_ReadByte(&net_message);
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
color = MSG_ReadByte(&net_message);
|
||||
CL_ParticleEffect2(pos, dir,
|
||||
|
@ -1043,14 +1045,14 @@ CL_ParseTEnt(void)
|
|||
break;
|
||||
|
||||
case TE_GREENBLOOD:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
CL_ParticleEffect2(pos, dir, 0xff0fbfff, 0xff003bb7, 30);
|
||||
break;
|
||||
|
||||
case TE_TUNNEL_SPARKS:
|
||||
cnt = MSG_ReadByte(&net_message);
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
color = MSG_ReadByte(&net_message);
|
||||
CL_ParticleEffect3(pos, dir, VID_PaletteColor(color), cnt);
|
||||
|
@ -1058,7 +1060,7 @@ CL_ParseTEnt(void)
|
|||
|
||||
case TE_BLASTER2:
|
||||
case TE_FLECHETTE:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
|
||||
if (type == TE_BLASTER2)
|
||||
|
@ -1124,6 +1126,11 @@ CL_ParseTEnt(void)
|
|||
S_StartSound(pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0);
|
||||
break;
|
||||
|
||||
case TE_FLAME:
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
CL_FlameEffects(pos);
|
||||
break;
|
||||
|
||||
case TE_LIGHTNING:
|
||||
ent = CL_ParseLightning(cl_mod_lightning);
|
||||
S_StartSound(NULL, ent, CHAN_WEAPON, cl_sfx_lightning,
|
||||
|
@ -1131,13 +1138,13 @@ CL_ParseTEnt(void)
|
|||
break;
|
||||
|
||||
case TE_DEBUGTRAIL:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos2);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadPos(&net_message, pos2, cls.serverProtocol);
|
||||
CL_DebugTrail(pos, pos2);
|
||||
break;
|
||||
|
||||
case TE_PLAIN_EXPLOSION:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
|
||||
ex = CL_AllocExplosion();
|
||||
VectorCopy(pos, ex->ent.origin);
|
||||
|
@ -1163,14 +1170,14 @@ CL_ParseTEnt(void)
|
|||
break;
|
||||
|
||||
case TE_FLASHLIGHT:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
ent = MSG_ReadShort(&net_message);
|
||||
CL_Flashlight(ent, pos);
|
||||
break;
|
||||
|
||||
case TE_FORCEWALL:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos2);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadPos(&net_message, pos2, cls.serverProtocol);
|
||||
color = MSG_ReadByte(&net_message);
|
||||
CL_ForceWall(pos, pos2, VID_PaletteColor(color));
|
||||
break;
|
||||
|
@ -1185,7 +1192,7 @@ CL_ParseTEnt(void)
|
|||
|
||||
case TE_HEATBEAM_SPARKS:
|
||||
cnt = 50;
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
r = 8;
|
||||
magnitude = 60;
|
||||
|
@ -1195,7 +1202,7 @@ CL_ParseTEnt(void)
|
|||
|
||||
case TE_HEATBEAM_STEAM:
|
||||
cnt = 20;
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
magnitude = 60;
|
||||
CL_ParticleSteamEffect(pos, dir, 0xff07abff, 0xff002bab, cnt, magnitude);
|
||||
|
@ -1207,14 +1214,14 @@ CL_ParseTEnt(void)
|
|||
break;
|
||||
|
||||
case TE_BUBBLETRAIL2:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos2);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadPos(&net_message, pos2, cls.serverProtocol);
|
||||
CL_BubbleTrail2(pos, pos2, 8);
|
||||
S_StartSound(pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0);
|
||||
break;
|
||||
|
||||
case TE_MOREBLOOD:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
CL_ParticleEffect(pos, dir, 0xff001f9b, 0xff00001b, 250);
|
||||
break;
|
||||
|
@ -1223,19 +1230,19 @@ CL_ParseTEnt(void)
|
|||
dir[0] = 0;
|
||||
dir[1] = 0;
|
||||
dir[2] = 1;
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
CL_ParticleSmokeEffect(pos, dir, 0xff000000, 0xff6b6b6b, 20, 20);
|
||||
break;
|
||||
|
||||
case TE_ELECTRIC_SPARKS:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
MSG_ReadDir(&net_message, dir);
|
||||
CL_ParticleEffect(pos, dir, 0xff5b430f, 0xff1f1700, 40);
|
||||
S_StartSound(pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0);
|
||||
break;
|
||||
|
||||
case TE_TRACKER_EXPLOSION:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
CL_ColorFlash(pos, 0, 150, -1, -1, -1);
|
||||
CL_ColorExplosionParticles(pos, 0xff000000, 0xff0f0f0f);
|
||||
S_StartSound(pos, 0, 0, cl_sfx_disrexp, 1, ATTN_NORM, 0);
|
||||
|
@ -1243,7 +1250,7 @@ CL_ParseTEnt(void)
|
|||
|
||||
case TE_TELEPORT_EFFECT:
|
||||
case TE_DBALL_GOAL:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
CL_TeleportParticles(pos);
|
||||
break;
|
||||
|
||||
|
@ -1256,12 +1263,12 @@ CL_ParseTEnt(void)
|
|||
break;
|
||||
|
||||
case TE_WIDOWSPLASH:
|
||||
MSG_ReadPos(&net_message, pos);
|
||||
MSG_ReadPos(&net_message, pos, cls.serverProtocol);
|
||||
CL_WidowSplash(pos);
|
||||
break;
|
||||
|
||||
default:
|
||||
Com_Error(ERR_DROP, "CL_ParseTEnt: bad type");
|
||||
Com_Error(ERR_DROP, "%s: bad type", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -358,14 +358,13 @@ CL_PrepRefresh(void)
|
|||
strcpy(name, cl.configstrings[CS_MODELS + i]);
|
||||
name[37] = 0; /* never go beyond one line */
|
||||
|
||||
if (name[0] != '*')
|
||||
if (developer->value && name[0] != '*')
|
||||
{
|
||||
CL_PrintInSameLine(name);
|
||||
SCR_UpdateScreen();
|
||||
IN_Update();
|
||||
}
|
||||
|
||||
SCR_UpdateScreen();
|
||||
IN_Update();
|
||||
|
||||
if (name[0] == '#')
|
||||
{
|
||||
/* special player weapon model */
|
||||
|
@ -395,11 +394,11 @@ CL_PrepRefresh(void)
|
|||
|
||||
CL_PrintInSameLine("Images");
|
||||
SCR_UpdateScreen();
|
||||
IN_Update();
|
||||
|
||||
for (i = 1; i < MAX_IMAGES && cl.configstrings[CS_IMAGES + i][0]; i++)
|
||||
{
|
||||
cl.image_precache[i] = Draw_FindPic(cl.configstrings[CS_IMAGES + i]);
|
||||
IN_Update();
|
||||
}
|
||||
|
||||
CL_PrintInSameLine("Clients");
|
||||
|
@ -411,11 +410,14 @@ CL_PrepRefresh(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
Com_Printf("client %i\r", i);
|
||||
SCR_UpdateScreen();
|
||||
IN_Update();
|
||||
if (developer->value)
|
||||
{
|
||||
Com_Printf("Client %i\r", i);
|
||||
SCR_UpdateScreen();
|
||||
IN_Update();
|
||||
}
|
||||
|
||||
CL_ParseClientinfo(i);
|
||||
CL_PrintInSameLine("");
|
||||
}
|
||||
|
||||
CL_LoadClientinfo(&cl.baseclientinfo, "unnamed\\male/grunt");
|
||||
|
@ -525,7 +527,7 @@ V_Render3dCrosshair(void)
|
|||
|
||||
|
||||
if(crosshair_3d->value || crosshair_3d_glow->value){
|
||||
VectorMA(cl.refdef.vieworg,8192,cl.v_forward,end);
|
||||
VectorMA(cl.refdef.vieworg, 8192, cl.v_forward,end);
|
||||
crosshair_trace = CL_PMTrace(cl.refdef.vieworg, vec3_origin, vec3_origin, end);
|
||||
|
||||
if(crosshair_3d_glow->value){
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
cvar_t *cl_http_downloads;
|
||||
cvar_t *cl_http_filelists;
|
||||
cvar_t *cl_http_verifypeer;
|
||||
cvar_t *cl_http_proxy;
|
||||
cvar_t *cl_http_max_connections;
|
||||
cvar_t *cl_http_show_dw_progress;
|
||||
|
@ -81,7 +82,7 @@ static size_t CL_HTTP_Recv(void *ptr, size_t size, size_t nmemb, void *stream)
|
|||
|
||||
if (!dl->fileSize)
|
||||
{
|
||||
double length = 0;
|
||||
curl_off_t length = 0;
|
||||
|
||||
qcurl_easy_getinfo(dl->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &length);
|
||||
|
||||
|
@ -264,6 +265,9 @@ static void CL_StartHTTPDownload (dlqueue_t *entry, dlhandle_t *dl)
|
|||
}
|
||||
|
||||
// Make sure that the download handle is in empty state.
|
||||
if (dl->tempBuffer) {
|
||||
free(dl->tempBuffer);
|
||||
}
|
||||
dl->tempBuffer = NULL;
|
||||
dl->fileSize = 0;
|
||||
dl->position = 0;
|
||||
|
@ -290,6 +294,8 @@ static void CL_StartHTTPDownload (dlqueue_t *entry, dlhandle_t *dl)
|
|||
qcurl_easy_setopt(dl->curl, CURLOPT_WRITEFUNCTION, CL_HTTP_Recv);
|
||||
}
|
||||
|
||||
qcurl_easy_setopt(dl->curl, CURLOPT_SSL_VERIFYPEER, (long)cl_http_verifypeer->value);
|
||||
qcurl_easy_setopt(dl->curl, CURLOPT_PROXY_SSL_VERIFYPEER, (long)cl_http_verifypeer->value);
|
||||
qcurl_easy_setopt(dl->curl, CURLOPT_PROXY, cl_http_proxy->string);
|
||||
qcurl_easy_setopt(dl->curl, CURLOPT_LOW_SPEED_TIME, (long)cl_http_bw_limit_tmout->value);
|
||||
qcurl_easy_setopt(dl->curl, CURLOPT_LOW_SPEED_LIMIT, (long)cl_http_bw_limit_rate->value);
|
||||
|
@ -477,6 +483,10 @@ static void CL_ParseFileList(dlhandle_t *dl)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!dl->tempBuffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
char *list = dl->tempBuffer;
|
||||
|
||||
for (;;)
|
||||
|
@ -1169,7 +1179,7 @@ qboolean CL_PendingHTTPDownloads(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
return pendingCount + handleCount;
|
||||
return ((pendingCount + handleCount) > 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -72,6 +72,7 @@ extern dlquirks_t dlquirks;
|
|||
|
||||
extern cvar_t *cl_http_downloads;
|
||||
extern cvar_t *cl_http_filelists;
|
||||
extern cvar_t *cl_http_verifypeer;
|
||||
extern cvar_t *cl_http_proxy;
|
||||
extern cvar_t *cl_http_max_connections;
|
||||
extern cvar_t *cl_http_show_dw_progress;
|
||||
|
|
|
@ -72,9 +72,9 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
entity_state_t baseline; /* delta from this if not from a previous frame */
|
||||
entity_state_t current;
|
||||
entity_state_t prev; /* will always be valid, but might just be a copy of current */
|
||||
entity_xstate_t baseline; /* delta from this if not from a previous frame */
|
||||
entity_xstate_t current;
|
||||
entity_xstate_t prev; /* will always be valid, but might just be a copy of current */
|
||||
|
||||
int serverframe; /* if not current, this ent isn't in the frame */
|
||||
|
||||
|
@ -331,17 +331,13 @@ typedef struct
|
|||
|
||||
extern centity_t cl_entities[MAX_EDICTS];
|
||||
|
||||
extern entity_state_t cl_parse_entities[MAX_PARSE_ENTITIES];
|
||||
extern entity_xstate_t cl_parse_entities[MAX_PARSE_ENTITIES];
|
||||
|
||||
extern netadr_t net_from;
|
||||
extern sizebuf_t net_message;
|
||||
|
||||
extern qboolean paused_at_load;
|
||||
|
||||
void DrawString (int x, int y, const char *s);
|
||||
void DrawStringScaled(int x, int y, const char *s, float factor);
|
||||
void DrawAltString (int x, int y, const char *s); /* toggle high bit */
|
||||
void DrawAltStringScaled(int x, int y, const char *s, float factor);
|
||||
qboolean CL_CheckOrDownloadFile (const char *filename);
|
||||
|
||||
void CL_AddNetgraph (void);
|
||||
|
@ -364,7 +360,7 @@ typedef struct cl_sustain
|
|||
|
||||
void CL_ParticleSteamEffect2(cl_sustain_t *self);
|
||||
|
||||
void CL_TeleporterParticles (entity_state_t *ent);
|
||||
void CL_TeleporterParticles (const entity_xstate_t *ent);
|
||||
void CL_ParticleEffect (vec3_t org, vec3_t dir, unsigned int basecolor, unsigned int finalcolor,
|
||||
int count);
|
||||
void CL_ParticleEffect2 (vec3_t org, vec3_t dir, unsigned int basecolor, unsigned int finalcolor,
|
||||
|
@ -405,7 +401,7 @@ void CL_SmokeTrail (vec3_t start, vec3_t end, unsigned int basecolor, unsigned i
|
|||
int spacing);
|
||||
void CL_Flashlight (int ent, vec3_t pos);
|
||||
void CL_ForceWall (vec3_t start, vec3_t end, int color);
|
||||
void CL_FlameEffects (centity_t *ent, vec3_t origin);
|
||||
void CL_FlameEffects (vec3_t origin);
|
||||
void CL_GenericParticleEffect (vec3_t org, vec3_t dir, unsigned int basecolor, unsigned int finalcolor,
|
||||
int count, int numcolors, int dirspread, float alphavel);
|
||||
void CL_BubbleTrail2 (vec3_t start, vec3_t end, int dist);
|
||||
|
@ -491,8 +487,18 @@ void CL_BaseMove (usercmd_t *cmd);
|
|||
|
||||
void IN_CenterView (void);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LBL_SDL = 0,
|
||||
LBL_XBOX,
|
||||
LBL_PLAYSTATION,
|
||||
LBL_SWITCH,
|
||||
LBL_MAX_COUNT
|
||||
} gamepad_labels_t;
|
||||
|
||||
float CL_KeyState (kbutton_t *key);
|
||||
char *Key_KeynumToString (int keynum);
|
||||
char *Key_KeynumToString_Joy (int key);
|
||||
|
||||
void CL_WriteDemoMessage (void);
|
||||
void CL_Stop_f (void);
|
||||
|
@ -535,7 +541,7 @@ void CL_DiminishingTrail (vec3_t start, vec3_t end, centity_t *old, int flags);
|
|||
void CL_FlyEffect (centity_t *ent, vec3_t origin);
|
||||
void CL_BfgParticles (entity_t *ent);
|
||||
void CL_AddParticles (void);
|
||||
void CL_EntityEvent (entity_state_t *ent);
|
||||
void CL_EntityEvent (entity_xstate_t *ent);
|
||||
void CL_TrapParticles (entity_t *ent);
|
||||
|
||||
void M_Init (void);
|
||||
|
|
|
@ -208,11 +208,11 @@ enum QKEYS {
|
|||
// From here on, only gamepad controls must be allowed.
|
||||
// Otherwise, separate bindings (keyboard / controller) menu options will not work.
|
||||
|
||||
K_BTN_A,
|
||||
K_JOY_FIRST_REGULAR = K_BTN_A,
|
||||
K_BTN_B,
|
||||
K_BTN_X,
|
||||
K_BTN_Y,
|
||||
K_BTN_SOUTH,
|
||||
K_JOY_FIRST_BTN = K_BTN_SOUTH,
|
||||
K_BTN_EAST,
|
||||
K_BTN_WEST,
|
||||
K_BTN_NORTH,
|
||||
K_BTN_BACK,
|
||||
K_BTN_GUIDE,
|
||||
K_BTN_START,
|
||||
|
@ -225,26 +225,28 @@ enum QKEYS {
|
|||
K_DPAD_LEFT,
|
||||
K_DPAD_RIGHT,
|
||||
K_BTN_MISC1,
|
||||
K_PADDLE_1,
|
||||
K_PADDLE_2,
|
||||
K_PADDLE_3,
|
||||
K_PADDLE_4,
|
||||
K_TOUCHPAD, // SDL_CONTROLLER_BUTTON_MAX - 1
|
||||
K_PADDLE_RIGHT_1,
|
||||
K_PADDLE_LEFT_1,
|
||||
K_PADDLE_RIGHT_2,
|
||||
K_PADDLE_LEFT_2,
|
||||
K_TOUCHPAD, // SDL_CONTROLLER_BUTTON_MAX - 1, SDL2 limit
|
||||
K_BTN_MISC2,
|
||||
K_BTN_MISC3,
|
||||
K_BTN_MISC4,
|
||||
K_BTN_MISC5,
|
||||
K_BTN_MISC6, // SDL_GAMEPAD_BUTTON_COUNT - 1, current SDL3 count
|
||||
K_TRIG_LEFT, // buttons for triggers (axes)
|
||||
K_TRIG_RIGHT,
|
||||
|
||||
// add other joystick/controller keys before this one
|
||||
// and adjust it accordingly, also remember to add corresponding _ALT key below!
|
||||
K_JOY_LAST_REGULAR = K_TRIG_RIGHT,
|
||||
// Add other gamepad keys before this one, adjust from SDL 2/3 definitions, and
|
||||
// add the corresponding _ALT key below! Respect the order, must be the same as above.
|
||||
// Also, verify if cl_keyboard.c needs a refactor on its arrays.
|
||||
|
||||
/* Can't be mapped to any action (=> not regular) */
|
||||
K_JOY_BACK,
|
||||
|
||||
K_BTN_A_ALT,
|
||||
K_JOY_FIRST_REGULAR_ALT = K_BTN_A_ALT,
|
||||
K_BTN_B_ALT,
|
||||
K_BTN_X_ALT,
|
||||
K_BTN_Y_ALT,
|
||||
K_BTN_SOUTH_ALT,
|
||||
K_JOY_FIRST_BTN_ALT = K_BTN_SOUTH_ALT,
|
||||
K_BTN_EAST_ALT,
|
||||
K_BTN_WEST_ALT,
|
||||
K_BTN_NORTH_ALT,
|
||||
K_BTN_BACK_ALT,
|
||||
K_BTN_GUIDE_ALT,
|
||||
K_BTN_START_ALT,
|
||||
|
@ -257,11 +259,16 @@ enum QKEYS {
|
|||
K_DPAD_LEFT_ALT,
|
||||
K_DPAD_RIGHT_ALT,
|
||||
K_BTN_MISC1_ALT,
|
||||
K_PADDLE_1_ALT,
|
||||
K_PADDLE_2_ALT,
|
||||
K_PADDLE_3_ALT,
|
||||
K_PADDLE_4_ALT,
|
||||
K_PADDLE_RIGHT_1_ALT,
|
||||
K_PADDLE_LEFT_1_ALT,
|
||||
K_PADDLE_RIGHT_2_ALT,
|
||||
K_PADDLE_LEFT_2_ALT,
|
||||
K_TOUCHPAD_ALT,
|
||||
K_BTN_MISC2_ALT,
|
||||
K_BTN_MISC3_ALT,
|
||||
K_BTN_MISC4_ALT,
|
||||
K_BTN_MISC5_ALT,
|
||||
K_BTN_MISC6_ALT,
|
||||
K_TRIG_LEFT_ALT,
|
||||
K_TRIG_RIGHT_ALT,
|
||||
|
||||
|
|
|
@ -43,9 +43,6 @@ void SCR_TouchPics(void);
|
|||
|
||||
void SCR_RunConsole(void);
|
||||
|
||||
extern float scr_con_current;
|
||||
extern float scr_conlines; /* lines of console to display */
|
||||
|
||||
extern int sb_lines;
|
||||
|
||||
extern cvar_t *scr_viewsize;
|
||||
|
@ -53,9 +50,6 @@ extern cvar_t *crosshair;
|
|||
|
||||
extern vrect_t scr_vrect; /* position of render window */
|
||||
|
||||
extern char crosshair_pic[MAX_QPATH];
|
||||
extern int crosshair_width, crosshair_height;
|
||||
|
||||
void SCR_AddDirtyPoint(int x, int y);
|
||||
void SCR_DirtyScreen(void);
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
*/
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "header/input.h"
|
||||
#include "../header/keyboard.h"
|
||||
|
@ -78,7 +79,7 @@ typedef enum
|
|||
// IN_Update() called at the beginning of a frame to the
|
||||
// actual movement functions called at a later time.
|
||||
static float mouse_x, mouse_y;
|
||||
static unsigned char sdl_back_button = SDL_CONTROLLER_BUTTON_START;
|
||||
static unsigned char joy_escbutton = SDL_CONTROLLER_BUTTON_START;
|
||||
static int joystick_left_x, joystick_left_y, joystick_right_x, joystick_right_y;
|
||||
static float gyro_yaw, gyro_pitch;
|
||||
static qboolean mlooking;
|
||||
|
@ -91,6 +92,12 @@ int sys_frame_time;
|
|||
// is pressed
|
||||
qboolean joy_altselector_pressed = false;
|
||||
|
||||
// Gamepad labels' style (Xbox, Playstation, etc.) in use, normally set after detection
|
||||
gamepad_labels_t joy_current_lbls = LBL_SDL;
|
||||
|
||||
// Using japanese style for confirm & cancel buttons on gamepad
|
||||
qboolean japanese_confirm = false;
|
||||
|
||||
// Console Variables
|
||||
cvar_t *freelook;
|
||||
cvar_t *lookstrafe;
|
||||
|
@ -134,6 +141,12 @@ static int last_haptic_effect_size = HAPTIC_EFFECT_LIST_SIZE;
|
|||
static int last_haptic_effect_pos = 0;
|
||||
static haptic_effects_cache_t last_haptic_effect[HAPTIC_EFFECT_LIST_SIZE];
|
||||
|
||||
// Gamepad labels' style (Xbox, Playstation, etc.) requested by user
|
||||
static cvar_t *joy_labels;
|
||||
|
||||
// Gamepad style for confirm and cancel buttons (traditional or japanese)
|
||||
static cvar_t *joy_confirm;
|
||||
|
||||
// Joystick sensitivity
|
||||
static cvar_t *joy_yawsensitivity;
|
||||
static cvar_t *joy_pitchsensitivity;
|
||||
|
@ -173,19 +186,20 @@ static cvar_t *gyro_calibration_x;
|
|||
static cvar_t *gyro_calibration_y;
|
||||
static cvar_t *gyro_calibration_z;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 14) // support for controller sensors (gyro, accelerometer)
|
||||
// If the used SDL version doesn't support gamepad sensors...
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
// ...disable support for reading them.
|
||||
#define NO_SDL_GYRO
|
||||
#endif
|
||||
|
||||
#ifndef NO_SDL_GYRO // use SDL_CONTROLLERSENSORUPDATE to read gyro
|
||||
static unsigned int num_samples;
|
||||
#define NATIVE_SDL_GYRO // uses SDL_CONTROLLERSENSORUPDATE to read gyro
|
||||
|
||||
#else // for SDL < 2.0.14, gyro can be read as a "secondary joystick" exposed by dkms-hid-nintendo
|
||||
|
||||
#else // gyro can be read as a "secondary joystick" exposed by dkms-hid-nintendo
|
||||
static unsigned int num_samples[3];
|
||||
static SDL_Joystick *imu_joystick = NULL; // gyro "joystick"
|
||||
#define IMU_JOY_AXIS_GYRO_ROLL 3
|
||||
#define IMU_JOY_AXIS_GYRO_PITCH 4
|
||||
#define IMU_JOY_AXIS_GYRO_YAW 5
|
||||
|
||||
#endif
|
||||
|
||||
// To ignore SDL_JOYDEVICEADDED at game init. Allows for hot plugging of game controller afterwards.
|
||||
|
@ -505,16 +519,120 @@ IN_TranslateScancodeToQ2Key(SDL_Scancode sc)
|
|||
static void IN_Controller_Init(qboolean notify_user);
|
||||
static void IN_Controller_Shutdown(qboolean notify_user);
|
||||
|
||||
/*
|
||||
* Sets the gamepad buttons' style of labels (SDL, Xbox, PS, Switch).
|
||||
* They are only visible in the gamepad binding options.
|
||||
* Traditional binding uses SDL style, no matter the gamepad.
|
||||
*/
|
||||
static void
|
||||
IN_GamepadLabels_Changed(void)
|
||||
{
|
||||
const int requested = (int)joy_labels->value;
|
||||
joy_labels->modified = false;
|
||||
joy_current_lbls = LBL_SDL;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 12)
|
||||
if (requested < 0 && controller) // try to autodetect...
|
||||
{
|
||||
switch (SDL_GameControllerGetType(controller))
|
||||
{
|
||||
case SDL_CONTROLLER_TYPE_XBOX360:
|
||||
case SDL_CONTROLLER_TYPE_XBOXONE:
|
||||
joy_current_lbls = LBL_XBOX;
|
||||
return;
|
||||
|
||||
case SDL_CONTROLLER_TYPE_PS3:
|
||||
case SDL_CONTROLLER_TYPE_PS4:
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
case SDL_CONTROLLER_TYPE_PS5:
|
||||
#endif // SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
joy_current_lbls = LBL_PLAYSTATION;
|
||||
return;
|
||||
|
||||
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO:
|
||||
#if SDL_VERSION_ATLEAST(2, 24, 0)
|
||||
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR:
|
||||
#endif // SDL_VERSION_ATLEAST(2, 24, 0)
|
||||
joy_current_lbls = LBL_SWITCH;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif // SDL_VERSION_ATLEAST(2, 0, 12)
|
||||
if (requested >= LBL_SDL && requested < LBL_MAX_COUNT)
|
||||
{
|
||||
joy_current_lbls = (gamepad_labels_t)requested;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets which gamepad button works as "confirm", and which
|
||||
* works as "cancel", in menus.
|
||||
*/
|
||||
static void
|
||||
IN_GamepadConfirm_Changed(void)
|
||||
{
|
||||
const int requested = (int)joy_confirm->value;
|
||||
japanese_confirm = false;
|
||||
joy_confirm->modified = false;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 12)
|
||||
if (requested < 0 && controller) // try to autodetect...
|
||||
{
|
||||
switch (SDL_GameControllerGetType(controller))
|
||||
{
|
||||
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO:
|
||||
#if SDL_VERSION_ATLEAST(2, 24, 0)
|
||||
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR:
|
||||
#endif // SDL_VERSION_ATLEAST(2, 24, 0)
|
||||
japanese_confirm = true;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif // SDL_VERSION_ATLEAST(2, 0, 12)
|
||||
if (requested == 1)
|
||||
{
|
||||
japanese_confirm = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
IN_GyroMode_Changed(void)
|
||||
{
|
||||
if (gyro_mode->value < 2)
|
||||
{
|
||||
gyro_active = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
gyro_active = true;
|
||||
}
|
||||
gyro_mode->modified = false;
|
||||
}
|
||||
|
||||
static void
|
||||
IN_VirtualKeyEvent(int keynum, qboolean *state_store, qboolean new_state)
|
||||
{
|
||||
if (new_state != *state_store)
|
||||
{
|
||||
*state_store = new_state;
|
||||
Key_Event(keynum, *state_store, true);
|
||||
}
|
||||
}
|
||||
|
||||
qboolean IN_NumpadIsOn()
|
||||
{
|
||||
SDL_Keymod mod = SDL_GetModState();
|
||||
SDL_Keymod mod = SDL_GetModState();
|
||||
|
||||
if ((mod & KMOD_NUM) == KMOD_NUM)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ((mod & KMOD_NUM) == KMOD_NUM)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
@ -533,6 +651,7 @@ IN_Update(void)
|
|||
|
||||
static qboolean left_trigger = false;
|
||||
static qboolean right_trigger = false;
|
||||
static qboolean left_stick[4] = {false, false, false, false}; // left, right, up, down virtual keys
|
||||
|
||||
static int consoleKeyCode = 0;
|
||||
|
||||
|
@ -733,8 +852,8 @@ IN_Update(void)
|
|||
qboolean down = (event.type == SDL_CONTROLLERBUTTONDOWN);
|
||||
unsigned char btn = event.cbutton.button;
|
||||
|
||||
// Handle Back Button, to override its original key
|
||||
Key_Event( (btn == sdl_back_button)? K_JOY_BACK : K_BTN_A + btn,
|
||||
// Handle Esc button first, to override its original key
|
||||
Key_Event( (btn == joy_escbutton)? K_ESCAPE : K_JOY_FIRST_BTN + btn,
|
||||
down, true );
|
||||
break;
|
||||
}
|
||||
|
@ -746,26 +865,12 @@ IN_Update(void)
|
|||
switch (event.caxis.axis)
|
||||
{
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
|
||||
{
|
||||
qboolean new_left_trigger = axis_value > 8192;
|
||||
if (new_left_trigger != left_trigger)
|
||||
{
|
||||
left_trigger = new_left_trigger;
|
||||
Key_Event(K_TRIG_LEFT, left_trigger, true);
|
||||
}
|
||||
IN_VirtualKeyEvent(K_TRIG_LEFT, &left_trigger, axis_value > 8192);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
|
||||
{
|
||||
qboolean new_right_trigger = axis_value > 8192;
|
||||
if (new_right_trigger != right_trigger)
|
||||
{
|
||||
right_trigger = new_right_trigger;
|
||||
Key_Event(K_TRIG_RIGHT, right_trigger, true);
|
||||
}
|
||||
IN_VirtualKeyEvent(K_TRIG_RIGHT, &right_trigger, axis_value > 8192);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cl_paused->value && cls.key_dest == key_game)
|
||||
|
@ -785,11 +890,29 @@ IN_Update(void)
|
|||
joystick_right_y = axis_value;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Virtual keys to navigate menus with left stick
|
||||
if (cls.key_dest == key_menu)
|
||||
{
|
||||
switch (event.caxis.axis)
|
||||
{
|
||||
case SDL_CONTROLLER_AXIS_LEFTX:
|
||||
IN_VirtualKeyEvent(K_LEFTARROW, &left_stick[0], axis_value < -16896);
|
||||
IN_VirtualKeyEvent(K_RIGHTARROW, &left_stick[1], axis_value > 16896);
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLER_AXIS_LEFTY:
|
||||
IN_VirtualKeyEvent(K_UPARROW, &left_stick[2], axis_value < -16896);
|
||||
IN_VirtualKeyEvent(K_DOWNARROW, &left_stick[3], axis_value > 16896);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef NATIVE_SDL_GYRO // controller sensors' reading supported (gyro, accelerometer)
|
||||
#ifndef NO_SDL_GYRO // gamepad sensors' reading is supported (gyro, accelerometer)
|
||||
case SDL_CONTROLLERSENSORUPDATE:
|
||||
if (event.csensor.sensor != SDL_SENSOR_GYRO)
|
||||
{
|
||||
|
@ -804,7 +927,7 @@ IN_Update(void)
|
|||
break;
|
||||
}
|
||||
|
||||
#else // gyro read as "secondary joystick"
|
||||
#else // gyro read from a "secondary joystick" (usually with name ending in "IMU")
|
||||
case SDL_JOYAXISMOTION:
|
||||
if ( !imu_joystick || event.cdevice.which != SDL_JoystickInstanceID(imu_joystick) )
|
||||
{
|
||||
|
@ -831,12 +954,11 @@ IN_Update(void)
|
|||
break;
|
||||
}
|
||||
|
||||
#endif // NATIVE_SDL_GYRO
|
||||
#endif // !NO_SDL_GYRO
|
||||
|
||||
if (gyro_active && gyro_mode->value &&
|
||||
!cl_paused->value && cls.key_dest == key_game)
|
||||
if (gyro_active && !cl_paused->value && cls.key_dest == key_game)
|
||||
{
|
||||
#ifdef NATIVE_SDL_GYRO
|
||||
#ifndef NO_SDL_GYRO
|
||||
if (!gyro_turning_axis->value)
|
||||
{
|
||||
gyro_yaw = event.csensor.data[1] - gyro_calibration_y->value; // yaw
|
||||
|
@ -864,7 +986,7 @@ IN_Update(void)
|
|||
gyro_yaw = axis_value - gyro_calibration_z->value;
|
||||
}
|
||||
}
|
||||
#endif // NATIVE_SDL_GYRO
|
||||
#endif // !NO_SDL_GYRO
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -956,7 +1078,7 @@ IN_Update(void)
|
|||
|
||||
case REASON_GYROCALIBRATION: // finish and save calibration
|
||||
{
|
||||
#ifdef NATIVE_SDL_GYRO
|
||||
#ifndef NO_SDL_GYRO
|
||||
const float inverseSamples = 1.f / num_samples;
|
||||
Cvar_SetValue("gyro_calibration_x", gyro_accum[0] * inverseSamples);
|
||||
Cvar_SetValue("gyro_calibration_y", gyro_accum[1] * inverseSamples);
|
||||
|
@ -985,6 +1107,19 @@ IN_Update(void)
|
|||
countdown_reason = REASON_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (joy_labels->modified)
|
||||
{
|
||||
IN_GamepadLabels_Changed();
|
||||
}
|
||||
if (joy_confirm->modified)
|
||||
{
|
||||
IN_GamepadConfirm_Changed();
|
||||
}
|
||||
if (gyro_mode->modified)
|
||||
{
|
||||
IN_GyroMode_Changed();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1081,7 +1216,7 @@ IN_TightenInput(float yaw, float pitch)
|
|||
{
|
||||
thumbstick_t input = { yaw, pitch };
|
||||
const float magnitude = IN_StickMagnitude(input);
|
||||
#ifdef NATIVE_SDL_GYRO
|
||||
#ifndef NO_SDL_GYRO
|
||||
const float threshold = (M_PI / 180.0f) * gyro_tightening->value;
|
||||
#else
|
||||
const float threshold = (2560.0f / 180.0f) * gyro_tightening->value;
|
||||
|
@ -1177,7 +1312,7 @@ IN_FlickStick(thumbstick_t stick, float axial_deadzone)
|
|||
// Flicking begins now, with a new target
|
||||
is_flicking = true;
|
||||
flick_progress = 0.0f;
|
||||
started_flick = cls.realtime;
|
||||
started_flick = sys_frame_time;
|
||||
target_angle = stick_angle;
|
||||
IN_ResetSmoothSamples();
|
||||
}
|
||||
|
@ -1369,7 +1504,7 @@ IN_Move(usercmd_t *cmd)
|
|||
//
|
||||
// For movement this is not needed, as those are absolute values independent of framerate
|
||||
float joyViewFactor = cls.rframetime/0.01666f;
|
||||
#ifdef NATIVE_SDL_GYRO
|
||||
#ifndef NO_SDL_GYRO
|
||||
float gyroViewFactor = (1.0f / M_PI) * joyViewFactor;
|
||||
#else
|
||||
float gyroViewFactor = (1.0f / 2560.0f) * joyViewFactor; // normalized for Switch gyro
|
||||
|
@ -1421,7 +1556,7 @@ IN_Move(usercmd_t *cmd)
|
|||
// Flick Stick: flick in progress, changing the yaw angle to the target progressively
|
||||
if (flick_progress < 1.0f)
|
||||
{
|
||||
float cur_progress = (float)(cls.realtime - started_flick) / FLICK_TIME;
|
||||
float cur_progress = (float)(sys_frame_time - started_flick) / FLICK_TIME;
|
||||
|
||||
if (cur_progress > 1.0f)
|
||||
{
|
||||
|
@ -1929,7 +2064,7 @@ Controller_Rumble(const char *name, vec3_t source, qboolean from_player,
|
|||
void
|
||||
StartCalibration(void)
|
||||
{
|
||||
#ifdef NATIVE_SDL_GYRO
|
||||
#ifndef NO_SDL_GYRO
|
||||
num_samples = 0;
|
||||
#else
|
||||
num_samples[0] = num_samples[1] = num_samples[2] = 0;
|
||||
|
@ -1959,19 +2094,19 @@ IN_Controller_Init(qboolean notify_user)
|
|||
SDL_Joystick *joystick = NULL;
|
||||
SDL_bool is_controller = SDL_FALSE;
|
||||
|
||||
cvar = Cvar_Get("in_sdlbackbutton", "1", CVAR_ARCHIVE);
|
||||
cvar = Cvar_Get("joy_escbutton", "0", CVAR_ARCHIVE);
|
||||
if (cvar)
|
||||
{
|
||||
switch ((int)cvar->value)
|
||||
{
|
||||
case 0:
|
||||
sdl_back_button = SDL_CONTROLLER_BUTTON_BACK;
|
||||
case 1:
|
||||
joy_escbutton = SDL_CONTROLLER_BUTTON_BACK;
|
||||
break;
|
||||
case 2:
|
||||
sdl_back_button = SDL_CONTROLLER_BUTTON_GUIDE;
|
||||
joy_escbutton = SDL_CONTROLLER_BUTTON_GUIDE;
|
||||
break;
|
||||
default:
|
||||
sdl_back_button = SDL_CONTROLLER_BUTTON_START;
|
||||
joy_escbutton = SDL_CONTROLLER_BUTTON_START;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1995,6 +2130,9 @@ IN_Controller_Init(qboolean notify_user)
|
|||
#ifdef SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE
|
||||
SDL_SetHint( SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1" );
|
||||
#endif
|
||||
#ifdef SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS // use button positions instead of labels, like SDL3
|
||||
SDL_SetHint( SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, "0" );
|
||||
#endif
|
||||
|
||||
if (SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) == -1)
|
||||
{
|
||||
|
@ -2036,6 +2174,9 @@ IN_Controller_Init(qboolean notify_user)
|
|||
|
||||
for (int i = 0; i < SDL_NumJoysticks(); i++)
|
||||
{
|
||||
const char* joystick_name;
|
||||
size_t name_len;
|
||||
|
||||
joystick = SDL_JoystickOpen(i);
|
||||
if (!joystick)
|
||||
{
|
||||
|
@ -2043,33 +2184,42 @@ IN_Controller_Init(qboolean notify_user)
|
|||
continue; // try next joystick
|
||||
}
|
||||
|
||||
const char* joystick_name = SDL_JoystickName(joystick);
|
||||
const int name_len = strlen(joystick_name);
|
||||
joystick_name = SDL_JoystickName(joystick);
|
||||
name_len = strlen(joystick_name);
|
||||
|
||||
Com_Printf ("Trying joystick %d, '%s'\n", i+1, joystick_name);
|
||||
|
||||
// Ugly hack to detect IMU-only devices - works for Switch controllers at least
|
||||
if (name_len > 4 && !strncmp(joystick_name + name_len - 4, " IMU", 4))
|
||||
if ( name_len > 6 && strstr(joystick_name + name_len - 6, "IMU") )
|
||||
{
|
||||
#ifndef NO_SDL_GYRO
|
||||
SDL_JoystickClose(joystick);
|
||||
joystick = NULL;
|
||||
#ifdef NATIVE_SDL_GYRO
|
||||
Com_Printf ("Skipping IMU device.\n");
|
||||
|
||||
#else // if it's not a Left JoyCon, use it as Gyro
|
||||
Com_Printf ("IMU device found.\n");
|
||||
if ( !imu_joystick && name_len > 16 && strncmp(joystick_name + name_len - 16, "Left Joy-Con IMU", 16) != 0 )
|
||||
qboolean using_imu = !imu_joystick && !( strstr(joystick_name, "Joy-Con") && strstr(joystick_name, "L") );
|
||||
Com_Printf ("IMU device found... ");
|
||||
SDL_JoystickClose(joystick);
|
||||
joystick = NULL;
|
||||
|
||||
if (using_imu)
|
||||
{
|
||||
imu_joystick = SDL_JoystickOpen(i);
|
||||
if (imu_joystick)
|
||||
{
|
||||
show_gyro = true;
|
||||
Com_Printf ("Using this device as Gyro sensor.\n");
|
||||
Com_Printf ("using it as Gyro sensor.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Printf ("Couldn't open IMU: %s.\n", SDL_GetError());
|
||||
Com_Printf ("\nCouldn't open IMU: %s.\n", SDL_GetError());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Printf ("skipping.\n");
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
@ -2106,7 +2256,7 @@ IN_Controller_Init(qboolean notify_user)
|
|||
show_gamepad = true;
|
||||
Com_Printf("Enabled as Game Controller, settings:\n%s\n", SDL_GameControllerMapping(controller));
|
||||
|
||||
#ifdef NATIVE_SDL_GYRO
|
||||
#ifndef NO_SDL_GYRO
|
||||
|
||||
if ( SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO)
|
||||
&& !SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE) )
|
||||
|
@ -2129,7 +2279,7 @@ IN_Controller_Init(qboolean notify_user)
|
|||
SDL_GameControllerSetLED(controller, 0, 80, 0); // green light
|
||||
}
|
||||
|
||||
#endif // NATIVE_SDL_GYRO
|
||||
#endif // !NO_SDL_GYRO
|
||||
|
||||
joystick_haptic = SDL_HapticOpenFromJoystick(SDL_GameControllerGetJoystick(controller));
|
||||
|
||||
|
@ -2163,11 +2313,15 @@ IN_Controller_Init(qboolean notify_user)
|
|||
Com_Printf("Controller doesn't support rumble.\n");
|
||||
}
|
||||
|
||||
#ifdef NATIVE_SDL_GYRO // "native" exits when finding a single working controller
|
||||
#ifndef NO_SDL_GYRO // "native SDL gyro" exits when finding a single working gamepad
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
IN_GamepadLabels_Changed();
|
||||
IN_GamepadConfirm_Changed();
|
||||
IN_GyroMode_Changed();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2198,11 +2352,13 @@ IN_Init(void)
|
|||
joy_haptic_distance = Cvar_Get("joy_haptic_distance", "100.0", CVAR_ARCHIVE);
|
||||
haptic_feedback_filter = Cvar_Get("joy_haptic_filter", default_haptic_filter, CVAR_ARCHIVE);
|
||||
|
||||
joy_yawsensitivity = Cvar_Get("joy_yawsensitivity", "1.0", CVAR_ARCHIVE);
|
||||
joy_pitchsensitivity = Cvar_Get("joy_pitchsensitivity", "1.0", CVAR_ARCHIVE);
|
||||
joy_yawsensitivity = Cvar_Get("joy_yawsensitivity", "2.5", CVAR_ARCHIVE);
|
||||
joy_pitchsensitivity = Cvar_Get("joy_pitchsensitivity", "2.5", CVAR_ARCHIVE);
|
||||
joy_forwardsensitivity = Cvar_Get("joy_forwardsensitivity", "1.0", CVAR_ARCHIVE);
|
||||
joy_sidesensitivity = Cvar_Get("joy_sidesensitivity", "1.0", CVAR_ARCHIVE);
|
||||
|
||||
joy_labels = Cvar_Get("joy_labels", "-1", CVAR_ARCHIVE);
|
||||
joy_confirm = Cvar_Get("joy_confirm", "-1", CVAR_ARCHIVE);
|
||||
joy_layout = Cvar_Get("joy_layout", "0", CVAR_ARCHIVE);
|
||||
joy_left_expo = Cvar_Get("joy_left_expo", "2.0", CVAR_ARCHIVE);
|
||||
joy_left_snapaxis = Cvar_Get("joy_left_snapaxis", "0.15", CVAR_ARCHIVE);
|
||||
|
@ -2217,16 +2373,11 @@ IN_Init(void)
|
|||
gyro_calibration_y = Cvar_Get("gyro_calibration_y", "0.0", CVAR_ARCHIVE);
|
||||
gyro_calibration_z = Cvar_Get("gyro_calibration_z", "0.0", CVAR_ARCHIVE);
|
||||
|
||||
gyro_yawsensitivity = Cvar_Get("gyro_yawsensitivity", "1.0", CVAR_ARCHIVE);
|
||||
gyro_pitchsensitivity = Cvar_Get("gyro_pitchsensitivity", "1.0", CVAR_ARCHIVE);
|
||||
gyro_yawsensitivity = Cvar_Get("gyro_yawsensitivity", "2.5", CVAR_ARCHIVE);
|
||||
gyro_pitchsensitivity = Cvar_Get("gyro_pitchsensitivity", "2.5", CVAR_ARCHIVE);
|
||||
gyro_tightening = Cvar_Get("gyro_tightening", "3.5", CVAR_ARCHIVE);
|
||||
gyro_turning_axis = Cvar_Get("gyro_turning_axis", "0", CVAR_ARCHIVE);
|
||||
|
||||
gyro_mode = Cvar_Get("gyro_mode", "2", CVAR_ARCHIVE);
|
||||
if ((int)gyro_mode->value == 2)
|
||||
{
|
||||
gyro_active = true;
|
||||
}
|
||||
|
||||
windowed_pauseonfocuslost = Cvar_Get("vid_pauseonfocuslost", "0", CVAR_USERINFO | CVAR_ARCHIVE);
|
||||
windowed_mouse = Cvar_Get("windowed_mouse", "1", CVAR_USERINFO | CVAR_ARCHIVE);
|
||||
|
@ -2280,7 +2431,7 @@ IN_Controller_Shutdown(qboolean notify_user)
|
|||
joystick_left_x = joystick_left_y = joystick_right_x = joystick_right_y = 0;
|
||||
gyro_yaw = gyro_pitch = 0;
|
||||
|
||||
#ifndef NATIVE_SDL_GYRO
|
||||
#ifdef NO_SDL_GYRO
|
||||
if (imu_joystick)
|
||||
{
|
||||
SDL_JoystickClose(imu_joystick);
|
||||
|
@ -2331,8 +2482,11 @@ IN_GetClipboardText(char *out, size_t n)
|
|||
SDL_free(s);
|
||||
}
|
||||
|
||||
/* Copy string s to the clipboard.
|
||||
Returns 0 on success, 1 otherwise.
|
||||
*/
|
||||
int
|
||||
IN_SetClipboardText(const char *s)
|
||||
{
|
||||
return SDL_SetClipboardText(s);
|
||||
return SDL_SetClipboardText(s) != 0;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
*/
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "SDL3/SDL_gamepad.h"
|
||||
#include "SDL3/SDL_properties.h"
|
||||
|
@ -81,7 +82,7 @@ typedef enum
|
|||
// IN_Update() called at the beginning of a frame to the
|
||||
// actual movement functions called at a later time.
|
||||
static float mouse_x, mouse_y;
|
||||
static unsigned char sdl_back_button = SDL_GAMEPAD_BUTTON_START;
|
||||
static unsigned char joy_escbutton = SDL_GAMEPAD_BUTTON_START;
|
||||
static int joystick_left_x, joystick_left_y, joystick_right_x, joystick_right_y;
|
||||
static float gyro_yaw, gyro_pitch;
|
||||
static qboolean mlooking;
|
||||
|
@ -94,6 +95,12 @@ int sys_frame_time;
|
|||
// is pressed
|
||||
qboolean joy_altselector_pressed = false;
|
||||
|
||||
// Gamepad labels' style (Xbox, Playstation, etc.) in use, normally set after detection
|
||||
gamepad_labels_t joy_current_lbls = LBL_SDL;
|
||||
|
||||
// Using japanese style for confirm & cancel buttons on gamepad
|
||||
qboolean japanese_confirm = false;
|
||||
|
||||
// Console Variables
|
||||
cvar_t *freelook;
|
||||
cvar_t *lookstrafe;
|
||||
|
@ -137,6 +144,12 @@ static int last_haptic_effect_size = HAPTIC_EFFECT_LIST_SIZE;
|
|||
static int last_haptic_effect_pos = 0;
|
||||
static haptic_effects_cache_t last_haptic_effect[HAPTIC_EFFECT_LIST_SIZE];
|
||||
|
||||
// Gamepad labels' style (Xbox, Playstation, etc.) requested by user
|
||||
static cvar_t *joy_labels;
|
||||
|
||||
// Gamepad style for confirm and cancel buttons (traditional or japanese)
|
||||
static cvar_t *joy_confirm;
|
||||
|
||||
// Joystick sensitivity
|
||||
static cvar_t *joy_yawsensitivity;
|
||||
static cvar_t *joy_pitchsensitivity;
|
||||
|
@ -175,8 +188,17 @@ static float gyro_accum[3];
|
|||
static cvar_t *gyro_calibration_x;
|
||||
static cvar_t *gyro_calibration_y;
|
||||
static cvar_t *gyro_calibration_z;
|
||||
|
||||
// If "SDL gyro" is not explicitly disabled, use SDL_EVENT_GAMEPAD_SENSOR_UPDATE to read gyro
|
||||
#ifndef NO_SDL_GYRO
|
||||
static unsigned int num_samples;
|
||||
#define NATIVE_SDL_GYRO // uses SDL_EVENT_GAMEPAD_SENSOR_UPDATE to read gyro
|
||||
#else // otherwise, gyro can be read as a "secondary joystick" exposed by dkms-hid-nintendo
|
||||
static unsigned int num_samples[3];
|
||||
static SDL_Joystick *imu_joystick = NULL; // gyro "joystick"
|
||||
#define IMU_JOY_AXIS_GYRO_ROLL 3
|
||||
#define IMU_JOY_AXIS_GYRO_PITCH 4
|
||||
#define IMU_JOY_AXIS_GYRO_YAW 5
|
||||
#endif
|
||||
|
||||
// To ignore SDL_EVENT_JOYSTICK_ADDED at game init. Allows for hot plugging of gamepad afterwards.
|
||||
static qboolean first_init = true;
|
||||
|
@ -495,16 +517,108 @@ IN_TranslateScancodeToQ2Key(SDL_Scancode sc)
|
|||
static void IN_Controller_Init(qboolean notify_user);
|
||||
static void IN_Controller_Shutdown(qboolean notify_user);
|
||||
|
||||
/*
|
||||
* Sets the gamepad buttons' style of labels (SDL, Xbox, PS, Switch).
|
||||
* They are only visible in the gamepad binding options.
|
||||
* Traditional binding uses SDL style, no matter the gamepad.
|
||||
*/
|
||||
static void
|
||||
IN_GamepadLabels_Changed(void)
|
||||
{
|
||||
const int requested = (int)joy_labels->value;
|
||||
joy_labels->modified = false;
|
||||
joy_current_lbls = LBL_SDL;
|
||||
|
||||
if (requested < 0 && controller) // try to autodetect...
|
||||
{
|
||||
switch (SDL_GetGamepadType(controller))
|
||||
{
|
||||
case SDL_GAMEPAD_TYPE_XBOX360:
|
||||
case SDL_GAMEPAD_TYPE_XBOXONE:
|
||||
joy_current_lbls = LBL_XBOX;
|
||||
return;
|
||||
|
||||
case SDL_GAMEPAD_TYPE_PS3:
|
||||
case SDL_GAMEPAD_TYPE_PS4:
|
||||
case SDL_GAMEPAD_TYPE_PS5:
|
||||
joy_current_lbls = LBL_PLAYSTATION;
|
||||
return;
|
||||
|
||||
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO:
|
||||
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR:
|
||||
joy_current_lbls = LBL_SWITCH;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (requested >= LBL_SDL && requested < LBL_MAX_COUNT)
|
||||
{
|
||||
joy_current_lbls = (gamepad_labels_t)requested;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets which gamepad button works as "confirm", and which
|
||||
* works as "cancel", in menus.
|
||||
*/
|
||||
static void
|
||||
IN_GamepadConfirm_Changed(void)
|
||||
{
|
||||
const int requested = (int)joy_confirm->value;
|
||||
japanese_confirm = false;
|
||||
joy_confirm->modified = false;
|
||||
|
||||
if (requested < 0 && controller) // try to autodetect...
|
||||
{
|
||||
switch (SDL_GetGamepadType(controller))
|
||||
{
|
||||
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO:
|
||||
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR:
|
||||
japanese_confirm = true;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (requested == 1)
|
||||
{
|
||||
japanese_confirm = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
IN_GyroMode_Changed(void)
|
||||
{
|
||||
if (gyro_mode->value < 2)
|
||||
{
|
||||
gyro_active = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
gyro_active = true;
|
||||
}
|
||||
gyro_mode->modified = false;
|
||||
}
|
||||
|
||||
static void
|
||||
IN_VirtualKeyEvent(int keynum, qboolean *state_store, qboolean new_state)
|
||||
{
|
||||
if (new_state != *state_store)
|
||||
{
|
||||
*state_store = new_state;
|
||||
Key_Event(keynum, *state_store, true);
|
||||
}
|
||||
}
|
||||
|
||||
qboolean IN_NumpadIsOn()
|
||||
{
|
||||
SDL_Keymod mod = SDL_GetModState();
|
||||
SDL_Keymod mod = SDL_GetModState();
|
||||
|
||||
if ((mod & SDL_KMOD_NUM) == SDL_KMOD_NUM)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ((mod & SDL_KMOD_NUM) == SDL_KMOD_NUM)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
@ -523,6 +637,7 @@ IN_Update(void)
|
|||
|
||||
static qboolean left_trigger = false;
|
||||
static qboolean right_trigger = false;
|
||||
static qboolean left_stick[4] = {false, false, false, false}; // left, right, up, down virtual keys
|
||||
|
||||
static int consoleKeyCode = 0;
|
||||
|
||||
|
@ -594,7 +709,7 @@ IN_Update(void)
|
|||
/* workaround for AZERTY-keyboards, which don't have 1, 2, ..., 9, 0 in first row:
|
||||
* always map those physical keys (scancodes) to those keycodes anyway
|
||||
* see also https://bugzilla.libsdl.org/show_bug.cgi?id=3188 */
|
||||
SDL_Scancode sc = event.key.keysym.scancode;
|
||||
SDL_Scancode sc = event.key.scancode;
|
||||
|
||||
if (sc >= SDL_SCANCODE_1 && sc <= SDL_SCANCODE_0)
|
||||
{
|
||||
|
@ -612,14 +727,14 @@ IN_Update(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
SDL_Keycode kc = event.key.keysym.sym;
|
||||
SDL_Keycode kc = event.key.key;
|
||||
if(sc == SDL_SCANCODE_GRAVE && kc != '\'' && kc != '"')
|
||||
{
|
||||
// special case/hack: open the console with the "console key"
|
||||
// (beneath Esc, left of 1, above Tab)
|
||||
// but not if the keycode for this is a quote (like on Brazilian
|
||||
// keyboards) - otherwise you couldn't type them in the console
|
||||
if((event.key.keysym.mod & (SDL_KMOD_CAPS|SDL_KMOD_SHIFT|SDL_KMOD_ALT|SDL_KMOD_CTRL|SDL_KMOD_GUI)) == 0)
|
||||
if((event.key.mod & (SDL_KMOD_CAPS|SDL_KMOD_SHIFT|SDL_KMOD_ALT|SDL_KMOD_CTRL|SDL_KMOD_GUI)) == 0)
|
||||
{
|
||||
// also, only do this if no modifiers like shift or AltGr or whatever are pressed
|
||||
// so kc will most likely be the ascii char generated by this and can be ignored
|
||||
|
@ -724,8 +839,8 @@ IN_Update(void)
|
|||
qboolean down = (event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN);
|
||||
unsigned char btn = event.gbutton.button;
|
||||
|
||||
// Handle Back Button, to override its original key
|
||||
Key_Event( (btn == sdl_back_button)? K_JOY_BACK : K_BTN_A + btn,
|
||||
// Handle Esc button first, to override its original key
|
||||
Key_Event( (btn == joy_escbutton)? K_ESCAPE : K_JOY_FIRST_BTN + btn,
|
||||
down, true );
|
||||
break;
|
||||
}
|
||||
|
@ -737,26 +852,12 @@ IN_Update(void)
|
|||
switch (event.gaxis.axis)
|
||||
{
|
||||
case SDL_GAMEPAD_AXIS_LEFT_TRIGGER :
|
||||
{
|
||||
qboolean new_left_trigger = axis_value > 8192;
|
||||
if (new_left_trigger != left_trigger)
|
||||
{
|
||||
left_trigger = new_left_trigger;
|
||||
Key_Event(K_TRIG_LEFT, left_trigger, true);
|
||||
}
|
||||
IN_VirtualKeyEvent(K_TRIG_LEFT, &left_trigger, axis_value > 8192);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER :
|
||||
{
|
||||
qboolean new_right_trigger = axis_value > 8192;
|
||||
if (new_right_trigger != right_trigger)
|
||||
{
|
||||
right_trigger = new_right_trigger;
|
||||
Key_Event(K_TRIG_RIGHT, right_trigger, true);
|
||||
}
|
||||
IN_VirtualKeyEvent(K_TRIG_RIGHT, &right_trigger, axis_value > 8192);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cl_paused->value && cls.key_dest == key_game)
|
||||
|
@ -776,11 +877,29 @@ IN_Update(void)
|
|||
joystick_right_y = axis_value;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Virtual keys to navigate menus with left stick
|
||||
if (cls.key_dest == key_menu)
|
||||
{
|
||||
switch (event.gaxis.axis)
|
||||
{
|
||||
case SDL_GAMEPAD_AXIS_LEFTX :
|
||||
IN_VirtualKeyEvent(K_LEFTARROW, &left_stick[0], axis_value < -16896);
|
||||
IN_VirtualKeyEvent(K_RIGHTARROW, &left_stick[1], axis_value > 16896);
|
||||
break;
|
||||
|
||||
case SDL_GAMEPAD_AXIS_LEFTY :
|
||||
IN_VirtualKeyEvent(K_UPARROW, &left_stick[2], axis_value < -16896);
|
||||
IN_VirtualKeyEvent(K_DOWNARROW, &left_stick[3], axis_value > 16896);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef NATIVE_SDL_GYRO // controller sensors' reading supported (gyro, accelerometer)
|
||||
#ifndef NO_SDL_GYRO // gamepad sensors' reading is supported (gyro, accelerometer)
|
||||
case SDL_EVENT_GAMEPAD_SENSOR_UPDATE :
|
||||
if (event.gsensor.sensor != SDL_SENSOR_GYRO)
|
||||
{
|
||||
|
@ -795,11 +914,11 @@ IN_Update(void)
|
|||
break;
|
||||
}
|
||||
|
||||
#else // gyro read as "secondary joystick"
|
||||
#else // gyro read from a "secondary joystick" (usually with name ending in "IMU")
|
||||
case SDL_EVENT_JOYSTICK_AXIS_MOTION :
|
||||
if ( !imu_joystick || event.gdevice.which != SDL_GetJoystickInstanceID(imu_joystick) )
|
||||
if ( !imu_joystick || event.gdevice.which != SDL_GetJoystickID(imu_joystick) )
|
||||
{
|
||||
break; // controller axes handled by SDL_CONTROLLERAXISMOTION
|
||||
break; // gamepad axes handled by SDL_EVENT_GAMEPAD_AXIS_MOTION
|
||||
}
|
||||
|
||||
int axis_value = event.gaxis.value;
|
||||
|
@ -822,12 +941,11 @@ IN_Update(void)
|
|||
break;
|
||||
}
|
||||
|
||||
#endif // NATIVE_SDL_GYRO
|
||||
#endif // !NO_SDL_GYRO
|
||||
|
||||
if (gyro_active && gyro_mode->value &&
|
||||
!cl_paused->value && cls.key_dest == key_game)
|
||||
if (gyro_active && !cl_paused->value && cls.key_dest == key_game)
|
||||
{
|
||||
#ifdef NATIVE_SDL_GYRO
|
||||
#ifndef NO_SDL_GYRO
|
||||
if (!gyro_turning_axis->value)
|
||||
{
|
||||
gyro_yaw = event.gsensor.data[1] - gyro_calibration_y->value; // yaw
|
||||
|
@ -838,7 +956,7 @@ IN_Update(void)
|
|||
}
|
||||
gyro_pitch = event.gsensor.data[0] - gyro_calibration_x->value;
|
||||
#else // old "joystick" gyro
|
||||
switch (event.gaxis.axis) // inside "case SDL_JOYAXISMOTION" here
|
||||
switch (event.gaxis.axis) // inside "case SDL_EVENT_JOYSTICK_AXIS_MOTION" here
|
||||
{
|
||||
case IMU_JOY_AXIS_GYRO_PITCH:
|
||||
gyro_pitch = -(axis_value - gyro_calibration_x->value);
|
||||
|
@ -855,7 +973,7 @@ IN_Update(void)
|
|||
gyro_yaw = axis_value - gyro_calibration_z->value;
|
||||
}
|
||||
}
|
||||
#endif // NATIVE_SDL_GYRO
|
||||
#endif // !NO_SDL_GYRO
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -864,7 +982,7 @@ IN_Update(void)
|
|||
break;
|
||||
|
||||
case SDL_EVENT_GAMEPAD_REMOVED :
|
||||
if (controller && event.gdevice.which == SDL_GetJoystickInstanceID(SDL_GetGamepadJoystick(controller))) {
|
||||
if (controller && event.gdevice.which == SDL_GetJoystickID(SDL_GetGamepadJoystick(controller))) {
|
||||
Cvar_SetValue("paused", 1);
|
||||
IN_Controller_Shutdown(true);
|
||||
IN_Controller_Init(false);
|
||||
|
@ -881,7 +999,7 @@ IN_Update(void)
|
|||
break;
|
||||
|
||||
case SDL_EVENT_JOYSTICK_BATTERY_UPDATED :
|
||||
if (!controller || event.jbattery.which != SDL_GetJoystickInstanceID(SDL_GetGamepadJoystick(controller)))
|
||||
if (!controller || event.jbattery.which != SDL_GetJoystickID(SDL_GetGamepadJoystick(controller)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -945,7 +1063,7 @@ IN_Update(void)
|
|||
|
||||
case REASON_GYROCALIBRATION: // finish and save calibration
|
||||
{
|
||||
#ifdef NATIVE_SDL_GYRO
|
||||
#ifndef NO_SDL_GYRO
|
||||
const float inverseSamples = 1.f / num_samples;
|
||||
Cvar_SetValue("gyro_calibration_x", gyro_accum[0] * inverseSamples);
|
||||
Cvar_SetValue("gyro_calibration_y", gyro_accum[1] * inverseSamples);
|
||||
|
@ -974,6 +1092,20 @@ IN_Update(void)
|
|||
countdown_reason = REASON_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
// Gamepad labels' type and "confirm & cancel style" change handling
|
||||
if (joy_labels->modified)
|
||||
{
|
||||
IN_GamepadLabels_Changed();
|
||||
}
|
||||
if (joy_confirm->modified)
|
||||
{
|
||||
IN_GamepadConfirm_Changed();
|
||||
}
|
||||
if (gyro_mode->modified)
|
||||
{
|
||||
IN_GyroMode_Changed();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1070,7 +1202,11 @@ IN_TightenInput(float yaw, float pitch)
|
|||
{
|
||||
thumbstick_t input = { yaw, pitch };
|
||||
const float magnitude = IN_StickMagnitude(input);
|
||||
#ifndef NO_SDL_GYRO
|
||||
const float threshold = (M_PI / 180.0f) * gyro_tightening->value;
|
||||
#else
|
||||
const float threshold = (2560.0f / 180.0f) * gyro_tightening->value;
|
||||
#endif
|
||||
|
||||
if (magnitude < threshold)
|
||||
{
|
||||
|
@ -1162,7 +1298,7 @@ IN_FlickStick(thumbstick_t stick, float axial_deadzone)
|
|||
// Flicking begins now, with a new target
|
||||
is_flicking = true;
|
||||
flick_progress = 0.0f;
|
||||
started_flick = cls.realtime;
|
||||
started_flick = sys_frame_time;
|
||||
target_angle = stick_angle;
|
||||
IN_ResetSmoothSamples();
|
||||
}
|
||||
|
@ -1354,7 +1490,7 @@ IN_Move(usercmd_t *cmd)
|
|||
//
|
||||
// For movement this is not needed, as those are absolute values independent of framerate
|
||||
float joyViewFactor = cls.rframetime/0.01666f;
|
||||
#ifdef NATIVE_SDL_GYRO
|
||||
#ifndef NO_SDL_GYRO
|
||||
float gyroViewFactor = (1.0f / M_PI) * joyViewFactor;
|
||||
#else
|
||||
float gyroViewFactor = (1.0f / 2560.0f) * joyViewFactor; // normalized for Switch gyro
|
||||
|
@ -1406,7 +1542,7 @@ IN_Move(usercmd_t *cmd)
|
|||
// Flick Stick: flick in progress, changing the yaw angle to the target progressively
|
||||
if (flick_progress < 1.0f)
|
||||
{
|
||||
float cur_progress = (float)(cls.realtime - started_flick) / FLICK_TIME;
|
||||
float cur_progress = (float)(sys_frame_time - started_flick) / FLICK_TIME;
|
||||
|
||||
if (cur_progress > 1.0f)
|
||||
{
|
||||
|
@ -2006,7 +2142,7 @@ Controller_Rumble(const char *name, vec3_t source, qboolean from_player,
|
|||
// Com_Printf("%-29s: vol %5u - %4u ms - dp %.3f l %5.0f h %5.0f\n",
|
||||
// name, effect_volume, duration, dist_prop, low_freq, hi_freq);
|
||||
|
||||
if (SDL_RumbleGamepad(controller, low_freq, hi_freq, duration) == -1)
|
||||
if (!SDL_RumbleGamepad(controller, low_freq, hi_freq, duration))
|
||||
{
|
||||
if (!joystick_haptic)
|
||||
{
|
||||
|
@ -2025,7 +2161,7 @@ Controller_Rumble(const char *name, vec3_t source, qboolean from_player,
|
|||
void
|
||||
StartCalibration(void)
|
||||
{
|
||||
#ifdef NATIVE_SDL_GYRO
|
||||
#ifndef NO_SDL_GYRO
|
||||
num_samples = 0;
|
||||
#else
|
||||
num_samples[0] = num_samples[1] = num_samples[2] = 0;
|
||||
|
@ -2053,21 +2189,21 @@ IN_Controller_Init(qboolean notify_user)
|
|||
int nummappings;
|
||||
char controllerdb[MAX_OSPATH] = {0};
|
||||
SDL_Joystick *joystick = NULL;
|
||||
SDL_bool is_controller = SDL_FALSE;
|
||||
bool is_controller = false;
|
||||
|
||||
cvar = Cvar_Get("in_sdlbackbutton", "1", CVAR_ARCHIVE);
|
||||
cvar = Cvar_Get("joy_escbutton", "0", CVAR_ARCHIVE);
|
||||
if (cvar)
|
||||
{
|
||||
switch ((int)cvar->value)
|
||||
{
|
||||
case 0:
|
||||
sdl_back_button = SDL_GAMEPAD_BUTTON_BACK;
|
||||
case 1:
|
||||
joy_escbutton = SDL_GAMEPAD_BUTTON_BACK;
|
||||
break;
|
||||
case 2:
|
||||
sdl_back_button = SDL_GAMEPAD_BUTTON_GUIDE;
|
||||
joy_escbutton = SDL_GAMEPAD_BUTTON_GUIDE;
|
||||
break;
|
||||
default:
|
||||
sdl_back_button = SDL_GAMEPAD_BUTTON_START;
|
||||
joy_escbutton = SDL_GAMEPAD_BUTTON_START;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2084,15 +2220,7 @@ IN_Controller_Init(qboolean notify_user)
|
|||
|
||||
if (!SDL_WasInit(SDL_INIT_GAMEPAD | SDL_INIT_HAPTIC))
|
||||
{
|
||||
|
||||
#ifdef SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE // extended input reports on PS controllers (enables gyro thru bluetooth)
|
||||
SDL_SetHint( SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1" );
|
||||
#endif
|
||||
#ifdef SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE
|
||||
SDL_SetHint( SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1" );
|
||||
#endif
|
||||
|
||||
if (SDL_Init(SDL_INIT_GAMEPAD | SDL_INIT_HAPTIC) == -1)
|
||||
if (!SDL_Init(SDL_INIT_GAMEPAD | SDL_INIT_HAPTIC))
|
||||
{
|
||||
Com_Printf ("Couldn't init SDL Gamepad: %s.\n", SDL_GetError());
|
||||
return;
|
||||
|
@ -2126,6 +2254,8 @@ IN_Controller_Init(qboolean notify_user)
|
|||
show_haptic = true;
|
||||
}
|
||||
|
||||
SDL_free((void *)joysticks);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2152,27 +2282,36 @@ IN_Controller_Init(qboolean notify_user)
|
|||
Com_Printf ("Trying joystick %d, '%s'\n", i+1, joystick_name);
|
||||
|
||||
// Ugly hack to detect IMU-only devices - works for Switch controllers at least
|
||||
if (name_len > 4 && !strncmp(joystick_name + name_len - 4, " IMU", 4))
|
||||
if ( name_len > 6 && strstr(joystick_name + name_len - 6, "IMU") )
|
||||
{
|
||||
#ifndef NO_SDL_GYRO
|
||||
SDL_CloseJoystick(joystick);
|
||||
joystick = NULL;
|
||||
#ifdef NATIVE_SDL_GYRO
|
||||
Com_Printf ("Skipping IMU device.\n");
|
||||
|
||||
#else // if it's not a Left JoyCon, use it as Gyro
|
||||
Com_Printf ("IMU device found.\n");
|
||||
if ( !imu_joystick && name_len > 16 && strncmp(joystick_name + name_len - 16, "Left Joy-Con IMU", 16) != 0 )
|
||||
qboolean using_imu = !imu_joystick && !( strstr(joystick_name, "Joy-Con") && strstr(joystick_name, "L") );
|
||||
Com_Printf ("IMU device found... ");
|
||||
SDL_CloseJoystick(joystick);
|
||||
joystick = NULL;
|
||||
|
||||
if (using_imu)
|
||||
{
|
||||
imu_joystick = SDL_OpenJoystick(joysticks[i]);
|
||||
if (imu_joystick)
|
||||
{
|
||||
show_gyro = true;
|
||||
Com_Printf ("Using this device as Gyro sensor.\n");
|
||||
Com_Printf ("using it as Gyro sensor.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Printf ("Couldn't open IMU: %s.\n", SDL_GetError());
|
||||
Com_Printf ("\nCouldn't open IMU: %s.\n", SDL_GetError());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Printf ("skipping.\n");
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
@ -2184,9 +2323,9 @@ IN_Controller_Init(qboolean notify_user)
|
|||
if (!is_controller)
|
||||
{
|
||||
char joystick_guid[65] = {0};
|
||||
SDL_JoystickGUID guid = SDL_GetJoystickInstanceGUID(joysticks[i]);
|
||||
SDL_GUID guid = SDL_GetJoystickGUIDForID(joysticks[i]);
|
||||
|
||||
SDL_GetJoystickGUIDString(guid, joystick_guid, 64);
|
||||
SDL_GUIDToString(guid, joystick_guid, 64);
|
||||
|
||||
Com_Printf ("To identify joystick as Gamepad, provide its config by either:\n"
|
||||
" * Putting 'gamecontrollerdb.txt' file in your game directory.\n"
|
||||
|
@ -2210,10 +2349,10 @@ IN_Controller_Init(qboolean notify_user)
|
|||
Com_Printf("Enabled as Gamepad, settings:\n%s\n",
|
||||
SDL_GetGamepadMapping(controller));
|
||||
|
||||
#ifdef NATIVE_SDL_GYRO
|
||||
#ifndef NO_SDL_GYRO
|
||||
|
||||
if (SDL_GamepadHasSensor(controller, SDL_SENSOR_GYRO)
|
||||
&& !SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE) )
|
||||
&& SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_GYRO, true) )
|
||||
{
|
||||
show_gyro = true;
|
||||
Com_Printf( "Gyro sensor enabled at %.2f Hz\n",
|
||||
|
@ -2224,13 +2363,13 @@ IN_Controller_Init(qboolean notify_user)
|
|||
Com_Printf("Gyro sensor not found.\n");
|
||||
}
|
||||
|
||||
SDL_bool hasLED = SDL_GetBooleanProperty(SDL_GetGamepadProperties(controller), SDL_PROP_JOYSTICK_CAP_RGB_LED_BOOLEAN, SDL_FALSE);
|
||||
bool hasLED = SDL_GetBooleanProperty(SDL_GetGamepadProperties(controller), SDL_PROP_JOYSTICK_CAP_RGB_LED_BOOLEAN, false);
|
||||
if (hasLED)
|
||||
{
|
||||
SDL_SetGamepadLED(controller, 0, 80, 0); // green light
|
||||
}
|
||||
|
||||
#endif // NATIVE_SDL_GYRO
|
||||
#endif // !NO_SDL_GYRO
|
||||
|
||||
joystick_haptic = SDL_OpenHapticFromJoystick(SDL_GetGamepadJoystick(controller));
|
||||
|
||||
|
@ -2248,7 +2387,7 @@ IN_Controller_Init(qboolean notify_user)
|
|||
show_haptic = true;
|
||||
}
|
||||
|
||||
SDL_bool hasRumble = SDL_GetBooleanProperty(SDL_GetGamepadProperties(controller), SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN, SDL_FALSE);
|
||||
bool hasRumble = SDL_GetBooleanProperty(SDL_GetGamepadProperties(controller), SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN, false);
|
||||
if (hasRumble)
|
||||
{
|
||||
show_haptic = true;
|
||||
|
@ -2259,13 +2398,16 @@ IN_Controller_Init(qboolean notify_user)
|
|||
Com_Printf("Gamepad doesn't support rumble.\n");
|
||||
}
|
||||
|
||||
#ifdef NATIVE_SDL_GYRO // "native" exits when finding a single working controller
|
||||
#ifndef NO_SDL_GYRO // "native SDL gyro" exits when finding a single working gamepad
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
SDL_free((void *)joysticks);
|
||||
IN_GamepadLabels_Changed();
|
||||
IN_GamepadConfirm_Changed();
|
||||
IN_GyroMode_Changed();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2296,11 +2438,13 @@ IN_Init(void)
|
|||
joy_haptic_distance = Cvar_Get("joy_haptic_distance", "100.0", CVAR_ARCHIVE);
|
||||
haptic_feedback_filter = Cvar_Get("joy_haptic_filter", default_haptic_filter, CVAR_ARCHIVE);
|
||||
|
||||
joy_yawsensitivity = Cvar_Get("joy_yawsensitivity", "1.0", CVAR_ARCHIVE);
|
||||
joy_pitchsensitivity = Cvar_Get("joy_pitchsensitivity", "1.0", CVAR_ARCHIVE);
|
||||
joy_yawsensitivity = Cvar_Get("joy_yawsensitivity", "2.5", CVAR_ARCHIVE);
|
||||
joy_pitchsensitivity = Cvar_Get("joy_pitchsensitivity", "2.5", CVAR_ARCHIVE);
|
||||
joy_forwardsensitivity = Cvar_Get("joy_forwardsensitivity", "1.0", CVAR_ARCHIVE);
|
||||
joy_sidesensitivity = Cvar_Get("joy_sidesensitivity", "1.0", CVAR_ARCHIVE);
|
||||
|
||||
joy_labels = Cvar_Get("joy_labels", "-1", CVAR_ARCHIVE);
|
||||
joy_confirm = Cvar_Get("joy_confirm", "-1", CVAR_ARCHIVE);
|
||||
joy_layout = Cvar_Get("joy_layout", "0", CVAR_ARCHIVE);
|
||||
joy_left_expo = Cvar_Get("joy_left_expo", "2.0", CVAR_ARCHIVE);
|
||||
joy_left_snapaxis = Cvar_Get("joy_left_snapaxis", "0.15", CVAR_ARCHIVE);
|
||||
|
@ -2315,16 +2459,11 @@ IN_Init(void)
|
|||
gyro_calibration_y = Cvar_Get("gyro_calibration_y", "0.0", CVAR_ARCHIVE);
|
||||
gyro_calibration_z = Cvar_Get("gyro_calibration_z", "0.0", CVAR_ARCHIVE);
|
||||
|
||||
gyro_yawsensitivity = Cvar_Get("gyro_yawsensitivity", "1.0", CVAR_ARCHIVE);
|
||||
gyro_pitchsensitivity = Cvar_Get("gyro_pitchsensitivity", "1.0", CVAR_ARCHIVE);
|
||||
gyro_yawsensitivity = Cvar_Get("gyro_yawsensitivity", "2.5", CVAR_ARCHIVE);
|
||||
gyro_pitchsensitivity = Cvar_Get("gyro_pitchsensitivity", "2.5", CVAR_ARCHIVE);
|
||||
gyro_tightening = Cvar_Get("gyro_tightening", "3.5", CVAR_ARCHIVE);
|
||||
gyro_turning_axis = Cvar_Get("gyro_turning_axis", "0", CVAR_ARCHIVE);
|
||||
|
||||
gyro_mode = Cvar_Get("gyro_mode", "2", CVAR_ARCHIVE);
|
||||
if ((int)gyro_mode->value == 2)
|
||||
{
|
||||
gyro_active = true;
|
||||
}
|
||||
|
||||
windowed_pauseonfocuslost = Cvar_Get("vid_pauseonfocuslost", "0", CVAR_USERINFO | CVAR_ARCHIVE);
|
||||
windowed_mouse = Cvar_Get("windowed_mouse", "1", CVAR_USERINFO | CVAR_ARCHIVE);
|
||||
|
@ -2345,8 +2484,6 @@ IN_Init(void)
|
|||
}
|
||||
}
|
||||
|
||||
SDL_StartTextInput();
|
||||
|
||||
IN_Controller_Init(false);
|
||||
|
||||
Com_Printf("------------------------------------\n\n");
|
||||
|
@ -2386,7 +2523,7 @@ IN_Controller_Shutdown(qboolean notify_user)
|
|||
joystick_left_x = joystick_left_y = joystick_right_x = joystick_right_y = 0;
|
||||
gyro_yaw = gyro_pitch = 0;
|
||||
|
||||
#ifndef NATIVE_SDL_GYRO
|
||||
#ifdef NO_SDL_GYRO
|
||||
if (imu_joystick)
|
||||
{
|
||||
SDL_CloseJoystick(imu_joystick);
|
||||
|
@ -2439,8 +2576,13 @@ IN_GetClipboardText(char *out, size_t n)
|
|||
SDL_free(s);
|
||||
}
|
||||
|
||||
/* Copy string s to the clipboard.
|
||||
Returns 0 on success, 1 otherwise.
|
||||
*/
|
||||
int
|
||||
IN_SetClipboardText(const char *s)
|
||||
{
|
||||
return SDL_SetClipboardText(s);
|
||||
bool res = SDL_SetClipboardText(s);
|
||||
|
||||
return !res;
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@ typedef struct
|
|||
menucommon_s generic;
|
||||
char * focuspic;
|
||||
char * errorpic;
|
||||
char * alttext;
|
||||
int width;
|
||||
int height;
|
||||
} menubitmap_s;
|
||||
|
@ -103,7 +104,6 @@ typedef struct
|
|||
int cursor;
|
||||
int length;
|
||||
int visible_length;
|
||||
int visible_offset;
|
||||
} menufield_s;
|
||||
|
||||
typedef struct
|
||||
|
@ -139,6 +139,7 @@ typedef struct
|
|||
|
||||
void M_PushMenu(menuframework_s* menu);
|
||||
|
||||
void Field_ResetCursor(menuframework_s *m);
|
||||
qboolean Field_Key(menufield_s *field, int key);
|
||||
|
||||
void Menu_AddItem(menuframework_s *menu, void *item);
|
||||
|
|
|
@ -257,6 +257,8 @@ M_PushMenu(menuframework_s* menu)
|
|||
cls.key_dest = key_menu;
|
||||
}
|
||||
|
||||
extern qboolean japanese_confirm;
|
||||
|
||||
int
|
||||
Key_GetMenuKey(int key)
|
||||
{
|
||||
|
@ -297,24 +299,27 @@ Key_GetMenuKey(int key)
|
|||
|
||||
case K_KP_ENTER:
|
||||
case K_ENTER:
|
||||
case K_BTN_A:
|
||||
return K_ENTER;
|
||||
|
||||
case K_ESCAPE:
|
||||
case K_JOY_BACK:
|
||||
case K_BTN_B:
|
||||
return K_ESCAPE;
|
||||
|
||||
case K_BACKSPACE:
|
||||
case K_DEL:
|
||||
case K_KP_DEL:
|
||||
if (IN_NumpadIsOn() == true) { break; }
|
||||
case K_BTN_Y:
|
||||
case K_BACKSPACE:
|
||||
case K_DEL:
|
||||
case K_BTN_NORTH:
|
||||
return K_BACKSPACE;
|
||||
|
||||
case K_KP_INS:
|
||||
if (IN_NumpadIsOn() == true) { break; }
|
||||
case K_INS:
|
||||
return K_INS;
|
||||
|
||||
case K_BTN_SOUTH:
|
||||
if (japanese_confirm) return K_ESCAPE;
|
||||
else return K_ENTER;
|
||||
|
||||
case K_BTN_EAST:
|
||||
if (japanese_confirm) return K_ENTER;
|
||||
else return K_ESCAPE;
|
||||
}
|
||||
|
||||
return key;
|
||||
|
@ -328,16 +333,13 @@ Default_MenuKey(menuframework_s *m, int key)
|
|||
|
||||
if (m)
|
||||
{
|
||||
menucommon_s *item;
|
||||
menucommon_s *item = Menu_ItemAtCursor(m);
|
||||
|
||||
if ((item = Menu_ItemAtCursor(m)) != 0)
|
||||
if (item && item->type == MTYPE_FIELD)
|
||||
{
|
||||
if (item->type == MTYPE_FIELD)
|
||||
if (Field_Key((menufield_s *)item, key))
|
||||
{
|
||||
if (Field_Key((menufield_s *)item, key))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -345,12 +347,19 @@ Default_MenuKey(menuframework_s *m, int key)
|
|||
switch (menu_key)
|
||||
{
|
||||
case K_ESCAPE:
|
||||
if (m)
|
||||
{
|
||||
Field_ResetCursor(m);
|
||||
}
|
||||
|
||||
M_PopMenu();
|
||||
return menu_out_sound;
|
||||
|
||||
case K_UPARROW:
|
||||
if (m)
|
||||
{
|
||||
Field_ResetCursor(m);
|
||||
|
||||
m->cursor--;
|
||||
Menu_AdjustCursor(m, -1);
|
||||
sound = menu_move_sound;
|
||||
|
@ -360,6 +369,8 @@ Default_MenuKey(menuframework_s *m, int key)
|
|||
case K_DOWNARROW:
|
||||
if (m)
|
||||
{
|
||||
Field_ResetCursor(m);
|
||||
|
||||
m->cursor++;
|
||||
Menu_AdjustCursor(m, 1);
|
||||
sound = menu_move_sound;
|
||||
|
@ -456,7 +467,7 @@ M_DrawCursor(int x, int y, int f)
|
|||
}
|
||||
|
||||
Com_sprintf(cursorname, sizeof(cursorname), "m_cursor%d", f);
|
||||
Draw_PicScaled(x * scale, y * scale, cursorname, scale);
|
||||
Draw_PicScaledAltText(x * scale, y * scale, cursorname, scale, "*");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -659,6 +670,7 @@ InitMainMenu(void)
|
|||
s_plaque.generic.name = "m_main_plaque";
|
||||
s_plaque.generic.callback = 0;
|
||||
s_plaque.focuspic = 0;
|
||||
s_plaque.alttext = NULL;
|
||||
|
||||
s_logo.generic.type = MTYPE_BITMAP;
|
||||
s_logo.generic.flags = QMF_LEFT_JUSTIFY | QMF_INACTIVE;
|
||||
|
@ -667,6 +679,7 @@ InitMainMenu(void)
|
|||
s_logo.generic.name = "m_main_logo";
|
||||
s_logo.generic.callback = 0;
|
||||
s_logo.focuspic = 0;
|
||||
s_logo.alttext = NULL;
|
||||
|
||||
y += 10;
|
||||
|
||||
|
@ -677,6 +690,7 @@ InitMainMenu(void)
|
|||
s_game.generic.name = "m_main_game";
|
||||
s_game.generic.callback = GameFunc;
|
||||
s_game.focuspic = "m_main_game_sel";
|
||||
s_game.alttext = "Game";
|
||||
|
||||
Draw_GetPicSize(&w, &h, ( char * )s_game.generic.name);
|
||||
y += h + 8;
|
||||
|
@ -688,6 +702,7 @@ InitMainMenu(void)
|
|||
s_multiplayer.generic.name = "m_main_multiplayer";
|
||||
s_multiplayer.generic.callback = MultiplayerFunc;
|
||||
s_multiplayer.focuspic = "m_main_multiplayer_sel";
|
||||
s_multiplayer.alttext = "Multiplayer";
|
||||
|
||||
Draw_GetPicSize(&w, &h, ( char * )s_multiplayer.generic.name);
|
||||
y += h + 8;
|
||||
|
@ -699,6 +714,7 @@ InitMainMenu(void)
|
|||
s_options.generic.name = "m_main_options";
|
||||
s_options.generic.callback = OptionsFunc;
|
||||
s_options.focuspic = "m_main_options_sel";
|
||||
s_options.alttext = "Options";
|
||||
|
||||
Draw_GetPicSize(&w, &h, ( char * )s_options.generic.name);
|
||||
y += h + 8;
|
||||
|
@ -710,6 +726,7 @@ InitMainMenu(void)
|
|||
s_video.generic.name = "m_main_video";
|
||||
s_video.generic.callback = VideoFunc;
|
||||
s_video.focuspic = "m_main_video_sel";
|
||||
s_video.alttext = "Video";
|
||||
|
||||
Draw_GetPicSize(&w, &h, ( char * )s_video.generic.name);
|
||||
y += h + 8;
|
||||
|
@ -721,6 +738,7 @@ InitMainMenu(void)
|
|||
s_quit.generic.name = "m_main_quit";
|
||||
s_quit.generic.callback = QuitFunc;
|
||||
s_quit.focuspic = "m_main_quit_sel";
|
||||
s_quit.alttext = "Quit";
|
||||
|
||||
Menu_AddItem(&s_main, (void *)&s_plaque);
|
||||
Menu_AddItem(&s_main, (void *)&s_logo);
|
||||
|
@ -754,7 +772,7 @@ M_Main_Draw(void)
|
|||
( int )(cls.realtime / 100) % NUM_CURSOR_FRAMES);
|
||||
}
|
||||
|
||||
const char *
|
||||
static const char *
|
||||
M_Main_Key(int key)
|
||||
{
|
||||
return Default_MenuKey(&s_main, key);
|
||||
|
@ -941,14 +959,14 @@ M_UnbindCommand(char *command, int scope)
|
|||
switch (scope)
|
||||
{
|
||||
case KEYS_KEYBOARD_MOUSE:
|
||||
end = K_JOY_FIRST_REGULAR;
|
||||
end = K_JOY_FIRST_BTN;
|
||||
break;
|
||||
case KEYS_CONTROLLER:
|
||||
begin = K_JOY_FIRST_REGULAR;
|
||||
end = K_JOY_LAST_REGULAR + 1;
|
||||
begin = K_JOY_FIRST_BTN;
|
||||
end = K_JOY_FIRST_BTN_ALT;
|
||||
break;
|
||||
case KEYS_CONTROLLER_ALT:
|
||||
begin = K_JOY_FIRST_REGULAR_ALT;
|
||||
begin = K_JOY_FIRST_BTN_ALT;
|
||||
}
|
||||
|
||||
for (j = begin; j < end; j++)
|
||||
|
@ -977,14 +995,14 @@ M_FindKeysForCommand(char *command, int *twokeys, int scope)
|
|||
switch (scope)
|
||||
{
|
||||
case KEYS_KEYBOARD_MOUSE:
|
||||
end = K_JOY_FIRST_REGULAR;
|
||||
end = K_JOY_FIRST_BTN;
|
||||
break;
|
||||
case KEYS_CONTROLLER:
|
||||
begin = K_JOY_FIRST_REGULAR;
|
||||
end = K_JOY_LAST_REGULAR + 1;
|
||||
begin = K_JOY_FIRST_BTN;
|
||||
end = K_JOY_FIRST_BTN_ALT;
|
||||
break;
|
||||
case KEYS_CONTROLLER_ALT:
|
||||
begin = K_JOY_FIRST_REGULAR_ALT;
|
||||
begin = K_JOY_FIRST_BTN_ALT;
|
||||
}
|
||||
|
||||
twokeys[0] = twokeys[1] = -1;
|
||||
|
@ -1125,7 +1143,7 @@ Keys_MenuKey(int key)
|
|||
if (menukeyitem_bind)
|
||||
{
|
||||
// Any key/button except from the game controller and escape keys
|
||||
if ((key != K_ESCAPE) && (key != '`') && (key < K_JOY_FIRST_REGULAR))
|
||||
if ((key != K_ESCAPE) && (key != '`') && (key < K_JOY_FIRST_BTN))
|
||||
{
|
||||
char cmd[1024];
|
||||
|
||||
|
@ -1278,7 +1296,7 @@ MultiplayerKeys_MenuKey(int key)
|
|||
if (menukeyitem_bind)
|
||||
{
|
||||
// Any key/button but the escape ones
|
||||
if ((key != K_ESCAPE) && (key != '`') && (key != K_JOY_BACK))
|
||||
if ((key != K_ESCAPE) && (key != '`'))
|
||||
{
|
||||
char cmd[1024];
|
||||
|
||||
|
@ -1320,6 +1338,30 @@ M_Menu_Multiplayer_Keys_f(void)
|
|||
* GAME CONTROLLER ( GAMEPAD / JOYSTICK ) BUTTONS MENU
|
||||
*/
|
||||
|
||||
static void
|
||||
GamepadMenu_StatusPrompt(menuframework_s *m)
|
||||
{
|
||||
static char m_gamepadbind_statusbar[64];
|
||||
int btn_confirm, btn_cancel;
|
||||
|
||||
if (japanese_confirm)
|
||||
{
|
||||
btn_confirm = K_BTN_EAST;
|
||||
btn_cancel = K_BTN_SOUTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
btn_confirm = K_BTN_SOUTH;
|
||||
btn_cancel = K_BTN_EAST;
|
||||
}
|
||||
|
||||
snprintf(m_gamepadbind_statusbar, 64, "%s assigns, %s clears, %s exits",
|
||||
Key_KeynumToString_Joy(btn_confirm), Key_KeynumToString_Joy(K_BTN_NORTH),
|
||||
Key_KeynumToString_Joy(btn_cancel));
|
||||
|
||||
Menu_SetStatusBar(m, m_gamepadbind_statusbar);
|
||||
}
|
||||
|
||||
char *controller_bindnames[][2] =
|
||||
{
|
||||
{"+attack", "attack"},
|
||||
|
@ -1327,12 +1369,20 @@ char *controller_bindnames[][2] =
|
|||
{"+movedown", "down / crouch"},
|
||||
{"weapnext", "next weapon"},
|
||||
{"weapprev", "previous weapon"},
|
||||
{"cycleweap weapon_chaingun weapon_machinegun weapon_blaster", "long range: quickswitch 1"},
|
||||
{"cycleweap weapon_supershotgun weapon_shotgun", "close range: quickswitch 2"},
|
||||
{"cycleweap weapon_rocketlauncher weapon_grenadelauncher ammo_grenades", "explosives: quickswitch 3"},
|
||||
{"cycleweap weapon_bfg weapon_railgun weapon_hyperblaster", "special: quickswitch 4"},
|
||||
{"prefweap weapon_railgun weapon_hyperblaster weapon_chaingun weapon_supershotgun weapon_machinegun weapon_shotgun weapon_blaster", "best safe weapon"},
|
||||
{"prefweap weapon_bfg weapon_railgun weapon_rocketlauncher weapon_hyperblaster weapon_grenadelauncher weapon_chaingun ammo_grenades weapon_supershotgun", "best unsafe weapon"},
|
||||
{"cycleweap weapon_plasmabeam weapon_boomer weapon_chaingun weapon_etf_rifle"
|
||||
" weapon_machinegun weapon_blaster", "long range: quickswitch 1"},
|
||||
{"cycleweap weapon_supershotgun weapon_shotgun weapon_chainfist",
|
||||
"close range: quickswitch 2"},
|
||||
{"cycleweap weapon_phalanx weapon_rocketlauncher weapon_proxlauncher"
|
||||
" weapon_grenadelauncher ammo_grenades", "explosives: quickswitch 3"},
|
||||
{"cycleweap weapon_bfg weapon_disintegrator weapon_railgun weapon_hyperblaster"
|
||||
" ammo_tesla ammo_trap", "special: quickswitch 4"},
|
||||
{"prefweap weapon_railgun weapon_plasmabeam weapon_boomer weapon_hyperblaster weapon_chaingun"
|
||||
" weapon_supershotgun weapon_etf_rifle weapon_machinegun weapon_shotgun weapon_blaster",
|
||||
"best safe weapon"},
|
||||
{"prefweap weapon_bfg weapon_disintegrator weapon_phalanx weapon_railgun weapon_rocketlauncher"
|
||||
" weapon_plasmabeam weapon_boomer weapon_hyperblaster weapon_grenadelauncher weapon_chaingun"
|
||||
" weapon_proxlauncher ammo_grenades weapon_supershotgun", "best unsafe weapon"},
|
||||
{"centerview", "center view"},
|
||||
{"inven", "inventory"},
|
||||
{"invuse", "use item"},
|
||||
|
@ -1367,7 +1417,7 @@ DrawControllerButtonBindingFunc(void *self)
|
|||
int x;
|
||||
const char *name;
|
||||
|
||||
name = Key_KeynumToString(keys[0]);
|
||||
name = Key_KeynumToString_Joy(keys[0]);
|
||||
|
||||
Menu_DrawString(a->generic.x + a->generic.parent->x + RCOLUMN_OFFSET * scale,
|
||||
a->generic.y + a->generic.parent->y, name);
|
||||
|
@ -1380,7 +1430,7 @@ DrawControllerButtonBindingFunc(void *self)
|
|||
a->generic.y + a->generic.parent->y, "or");
|
||||
Menu_DrawString(a->generic.x + a->generic.parent->x + 48 * scale + (x * scale),
|
||||
a->generic.y + a->generic.parent->y,
|
||||
Key_KeynumToString(keys[1]));
|
||||
Key_KeynumToString_Joy(keys[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1425,7 +1475,7 @@ ControllerButtons_MenuInit(void)
|
|||
Menu_AddItem(&s_controller_buttons_menu, (void *)&s_controller_buttons_actions[i]);
|
||||
}
|
||||
|
||||
Menu_SetStatusBar(&s_controller_buttons_menu, "BTN_A assigns, BTN_Y clears, BTN_B exits");
|
||||
GamepadMenu_StatusPrompt(&s_controller_buttons_menu);
|
||||
Menu_Center(&s_controller_buttons_menu);
|
||||
}
|
||||
|
||||
|
@ -1444,7 +1494,7 @@ ControllerButtons_MenuKey(int key)
|
|||
if (menukeyitem_bind)
|
||||
{
|
||||
// Only controller buttons allowed
|
||||
if (key >= K_JOY_FIRST_REGULAR && key != K_JOY_BACK)
|
||||
if (key >= K_JOY_FIRST_BTN)
|
||||
{
|
||||
char cmd[1024];
|
||||
|
||||
|
@ -1453,7 +1503,7 @@ ControllerButtons_MenuKey(int key)
|
|||
Cbuf_InsertText(cmd);
|
||||
}
|
||||
|
||||
Menu_SetStatusBar(&s_controller_buttons_menu, "BTN_A assigns, BTN_Y clears, BTN_B exits");
|
||||
GamepadMenu_StatusPrompt(&s_controller_buttons_menu);
|
||||
menukeyitem_bind = false;
|
||||
return menu_out_sound;
|
||||
}
|
||||
|
@ -1490,12 +1540,20 @@ char *controller_alt_bindnames[][2] =
|
|||
{
|
||||
{"weapnext", "next weapon"},
|
||||
{"weapprev", "previous weapon"},
|
||||
{"cycleweap weapon_chaingun weapon_machinegun weapon_blaster", "long range: quickswitch 1"},
|
||||
{"cycleweap weapon_supershotgun weapon_shotgun", "close range: quickswitch 2"},
|
||||
{"cycleweap weapon_rocketlauncher weapon_grenadelauncher ammo_grenades", "explosives: quickswitch 3"},
|
||||
{"cycleweap weapon_bfg weapon_railgun weapon_hyperblaster", "special: quickswitch 4"},
|
||||
{"prefweap weapon_railgun weapon_hyperblaster weapon_chaingun weapon_supershotgun weapon_machinegun weapon_shotgun weapon_blaster", "best safe weapon"},
|
||||
{"prefweap weapon_bfg weapon_railgun weapon_rocketlauncher weapon_hyperblaster weapon_grenadelauncher weapon_chaingun ammo_grenades weapon_supershotgun", "best unsafe weapon"},
|
||||
{"cycleweap weapon_plasmabeam weapon_boomer weapon_chaingun weapon_etf_rifle"
|
||||
" weapon_machinegun weapon_blaster", "long range: quickswitch 1"},
|
||||
{"cycleweap weapon_supershotgun weapon_shotgun weapon_chainfist",
|
||||
"close range: quickswitch 2"},
|
||||
{"cycleweap weapon_phalanx weapon_rocketlauncher weapon_proxlauncher"
|
||||
" weapon_grenadelauncher ammo_grenades", "explosives: quickswitch 3"},
|
||||
{"cycleweap weapon_bfg weapon_disintegrator weapon_railgun weapon_hyperblaster"
|
||||
" ammo_tesla ammo_trap", "special: quickswitch 4"},
|
||||
{"prefweap weapon_railgun weapon_plasmabeam weapon_boomer weapon_hyperblaster weapon_chaingun"
|
||||
" weapon_supershotgun weapon_etf_rifle weapon_machinegun weapon_shotgun weapon_blaster",
|
||||
"best safe weapon"},
|
||||
{"prefweap weapon_bfg weapon_disintegrator weapon_phalanx weapon_railgun weapon_rocketlauncher"
|
||||
" weapon_plasmabeam weapon_boomer weapon_hyperblaster weapon_grenadelauncher weapon_chaingun"
|
||||
" weapon_proxlauncher ammo_grenades weapon_supershotgun", "best unsafe weapon"},
|
||||
{"centerview", "center view"},
|
||||
{"inven", "inventory"},
|
||||
{"invuse", "use item"},
|
||||
|
@ -1530,10 +1588,10 @@ DrawControllerAltButtonBindingFunc(void *self)
|
|||
}
|
||||
else
|
||||
{
|
||||
int x;
|
||||
size_t x;
|
||||
const char *name;
|
||||
|
||||
name = Key_KeynumToString(keys[0]);
|
||||
name = Key_KeynumToString_Joy(keys[0]);
|
||||
|
||||
Menu_DrawString(a->generic.x + a->generic.parent->x + RCOLUMN_OFFSET * scale,
|
||||
a->generic.y + a->generic.parent->y, name);
|
||||
|
@ -1546,7 +1604,7 @@ DrawControllerAltButtonBindingFunc(void *self)
|
|||
a->generic.y + a->generic.parent->y, "or");
|
||||
Menu_DrawString(a->generic.x + a->generic.parent->x + 48 * scale + (x * scale),
|
||||
a->generic.y + a->generic.parent->y,
|
||||
Key_KeynumToString(keys[1]));
|
||||
Key_KeynumToString_Joy(keys[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1591,7 +1649,7 @@ ControllerAltButtons_MenuInit(void)
|
|||
Menu_AddItem(&s_controller_alt_buttons_menu, (void *)&s_controller_alt_buttons_actions[i]);
|
||||
}
|
||||
|
||||
Menu_SetStatusBar(&s_controller_alt_buttons_menu, "BTN_A assigns, BTN_Y clears, BTN_B exits");
|
||||
GamepadMenu_StatusPrompt(&s_controller_alt_buttons_menu);
|
||||
Menu_Center(&s_controller_alt_buttons_menu);
|
||||
}
|
||||
|
||||
|
@ -1610,17 +1668,17 @@ ControllerAltButtons_MenuKey(int key)
|
|||
if (menukeyitem_bind)
|
||||
{
|
||||
// Only controller buttons allowed, different from the alt buttons modifier
|
||||
if (key >= K_JOY_FIRST_REGULAR && key != K_JOY_BACK && (keybindings[key] == NULL || strcmp(keybindings[key], "+joyaltselector") != 0))
|
||||
if (key >= K_JOY_FIRST_BTN && (keybindings[key] == NULL || strcmp(keybindings[key], "+joyaltselector") != 0))
|
||||
{
|
||||
char cmd[1024];
|
||||
key = key + (K_JOY_FIRST_REGULAR_ALT - K_JOY_FIRST_REGULAR); // change input to its ALT mode
|
||||
key = key + (K_JOY_FIRST_BTN_ALT - K_JOY_FIRST_BTN); // change input to its ALT mode
|
||||
|
||||
Com_sprintf(cmd, sizeof(cmd), "bind \"%s\" \"%s\"\n",
|
||||
Key_KeynumToString(key), controller_alt_bindnames[item->generic.localdata[0]][0]);
|
||||
Cbuf_InsertText(cmd);
|
||||
}
|
||||
|
||||
Menu_SetStatusBar(&s_controller_alt_buttons_menu, "BTN_A assigns, BTN_Y clears, BTN_B exits");
|
||||
GamepadMenu_StatusPrompt(&s_controller_alt_buttons_menu);
|
||||
menukeyitem_bind = false;
|
||||
return menu_out_sound;
|
||||
}
|
||||
|
@ -2221,7 +2279,7 @@ CrosshairFunc(void *unused)
|
|||
}
|
||||
|
||||
static void
|
||||
PauseFocusFunc()
|
||||
PauseFocusFunc(void *unused)
|
||||
{
|
||||
Cvar_SetValue("vid_pauseonfocuslost", (float)s_options_pauseonfocus_box.curvalue);
|
||||
}
|
||||
|
@ -2255,7 +2313,7 @@ ControlsSetMenuItemValues(void)
|
|||
{
|
||||
s_options_oggshuffle_box.curvalue = Cvar_VariableValue("ogg_shuffle");
|
||||
s_options_oggenable_box.curvalue = (Cvar_VariableValue("ogg_enable") != 0);
|
||||
s_options_quality_list.curvalue = (Cvar_VariableValue("s_loadas8bit") == 0);
|
||||
s_options_quality_list.curvalue = (Cvar_VariableValue("s_openal") == 0);
|
||||
s_options_alwaysrun_box.curvalue = (cl_run->value != 0);
|
||||
s_options_invertmouse_box.curvalue = (m_pitch->value < 0);
|
||||
s_options_lookstrafe_box.curvalue = (lookstrafe->value != 0);
|
||||
|
@ -2340,18 +2398,9 @@ ConsoleFunc(void *unused)
|
|||
}
|
||||
|
||||
static void
|
||||
UpdateSoundQualityFunc(void *unused)
|
||||
UpdateSoundBackendFunc(void *unused)
|
||||
{
|
||||
if (s_options_quality_list.curvalue == 0)
|
||||
{
|
||||
Cvar_SetValue("s_khz", 22);
|
||||
Cvar_SetValue("s_loadas8bit", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Cvar_SetValue("s_khz", 44);
|
||||
Cvar_SetValue("s_loadas8bit", false);
|
||||
}
|
||||
Cvar_Set("s_openal", (s_options_quality_list.curvalue == 0)? "1":"0" );
|
||||
|
||||
m_popup_string = "Restarting the sound system. This\n"
|
||||
"could take up to a minute, so\n"
|
||||
|
@ -2387,9 +2436,9 @@ Options_MenuInit(void)
|
|||
0
|
||||
};
|
||||
|
||||
static const char *quality_items[] =
|
||||
static const char *sound_items[] =
|
||||
{
|
||||
"normal", "high", 0
|
||||
"openal", "sdl", 0
|
||||
};
|
||||
|
||||
static const char *yesno_names[] =
|
||||
|
@ -2457,9 +2506,9 @@ Options_MenuInit(void)
|
|||
s_options_quality_list.generic.type = MTYPE_SPINCONTROL;
|
||||
s_options_quality_list.generic.x = 0;
|
||||
s_options_quality_list.generic.y = (y += 10);
|
||||
s_options_quality_list.generic.name = "sound quality";
|
||||
s_options_quality_list.generic.callback = UpdateSoundQualityFunc;
|
||||
s_options_quality_list.itemnames = quality_items;
|
||||
s_options_quality_list.generic.name = "sound backend";
|
||||
s_options_quality_list.generic.callback = UpdateSoundBackendFunc;
|
||||
s_options_quality_list.itemnames = sound_items;
|
||||
|
||||
s_options_sensitivity_slider.generic.type = MTYPE_SLIDER;
|
||||
s_options_sensitivity_slider.generic.x = 0;
|
||||
|
@ -3114,6 +3163,23 @@ static char mods_statusbar[64];
|
|||
static char **modnames = NULL;
|
||||
static int nummods;
|
||||
|
||||
void
|
||||
Mods_NamesFinish(void)
|
||||
{
|
||||
if (modnames)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nummods; i ++)
|
||||
{
|
||||
free(modnames[i]);
|
||||
}
|
||||
|
||||
free(modnames);
|
||||
modnames = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Mods_NamesInit(void)
|
||||
{
|
||||
|
@ -3364,7 +3430,7 @@ ModsFunc(void *unused)
|
|||
M_Menu_Mods_f();
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
Game_MenuInit(void)
|
||||
{
|
||||
Mods_NamesInit();
|
||||
|
@ -4195,15 +4261,10 @@ RulesChangeFunc(void *self)
|
|||
s_maxclients_field.generic.statusbar = NULL;
|
||||
s_startserver_dmoptions_action.generic.statusbar = NULL;
|
||||
}
|
||||
|
||||
/* Ground Zero game modes */
|
||||
else if (M_IsGame("rogue"))
|
||||
else if (s_rules_box.curvalue == 2)
|
||||
{
|
||||
if (s_rules_box.curvalue == 2)
|
||||
{
|
||||
s_maxclients_field.generic.statusbar = NULL;
|
||||
s_startserver_dmoptions_action.generic.statusbar = NULL;
|
||||
}
|
||||
s_maxclients_field.generic.statusbar = NULL;
|
||||
s_startserver_dmoptions_action.generic.statusbar = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4238,16 +4299,12 @@ StartServerActionFunc(void *self)
|
|||
|
||||
Cvar_SetValue("singleplayer", 0);
|
||||
|
||||
if ((s_rules_box.curvalue < 2) || M_IsGame("rogue"))
|
||||
{
|
||||
Cvar_SetValue("deathmatch", (float)!s_rules_box.curvalue);
|
||||
Cvar_SetValue("coop", (float)s_rules_box.curvalue);
|
||||
}
|
||||
else
|
||||
{
|
||||
Cvar_SetValue("deathmatch", 1); /* deathmatch is always true for rogue games */
|
||||
Cvar_SetValue("coop", 0); /* This works for at least the main game and both addons */
|
||||
}
|
||||
/* deathmatch is always true for rogue games */
|
||||
Cvar_SetValue("deathmatch",
|
||||
(s_rules_box.curvalue == 3 || s_rules_box.curvalue == 0) ? 1 : 0);
|
||||
/* This works for at least the main game and both addons */
|
||||
Cvar_SetValue("coop", s_rules_box.curvalue == 1 ? 1 : 0);
|
||||
Cvar_SetValue("ctf", s_rules_box.curvalue == 3 ? 1 : 0);
|
||||
|
||||
spot = NULL;
|
||||
|
||||
|
@ -4315,16 +4372,11 @@ static void
|
|||
StartServer_MenuInit(void)
|
||||
{
|
||||
static const char *dm_coop_names[] =
|
||||
{
|
||||
"deathmatch",
|
||||
"cooperative",
|
||||
0
|
||||
};
|
||||
static const char *dm_coop_names_rogue[] =
|
||||
{
|
||||
"deathmatch",
|
||||
"cooperative",
|
||||
"tag",
|
||||
"ctf",
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -4379,7 +4431,7 @@ StartServer_MenuInit(void)
|
|||
char shortname[MAX_TOKEN_CHARS];
|
||||
char longname[MAX_TOKEN_CHARS];
|
||||
char scratch[200];
|
||||
int j, l;
|
||||
size_t j, l;
|
||||
|
||||
strcpy(shortname, COM_Parse(&s));
|
||||
l = strlen(shortname);
|
||||
|
@ -4434,24 +4486,24 @@ StartServer_MenuInit(void)
|
|||
s_rules_box.generic.y = 20;
|
||||
s_rules_box.generic.name = "rules";
|
||||
|
||||
/* Ground Zero games only available with rogue game */
|
||||
if (M_IsGame("rogue"))
|
||||
{
|
||||
s_rules_box.itemnames = dm_coop_names_rogue;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_rules_box.itemnames = dm_coop_names;
|
||||
}
|
||||
s_rules_box.itemnames = dm_coop_names;
|
||||
|
||||
if (Cvar_VariableValue("coop"))
|
||||
{
|
||||
s_rules_box.curvalue = 1;
|
||||
}
|
||||
else
|
||||
else if (Cvar_VariableValue("ctf"))
|
||||
{
|
||||
s_rules_box.curvalue = 3;
|
||||
}
|
||||
else if (Cvar_VariableValue("deathmatch"))
|
||||
{
|
||||
s_rules_box.curvalue = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_rules_box.curvalue = 2;
|
||||
}
|
||||
|
||||
s_rules_box.generic.callback = RulesChangeFunc;
|
||||
}
|
||||
|
@ -5042,7 +5094,7 @@ DMOptions_MenuDraw(void)
|
|||
Menu_Draw(&s_dmoptions_menu);
|
||||
}
|
||||
|
||||
const char *
|
||||
static const char *
|
||||
DMOptions_MenuKey(int key)
|
||||
{
|
||||
return Default_MenuKey(&s_dmoptions_menu, key);
|
||||
|
@ -5247,6 +5299,7 @@ AddressBook_MenuInit(void)
|
|||
|
||||
for (i = 0; i < NUM_ADDRESSBOOK_ENTRIES; i++)
|
||||
{
|
||||
menufield_s *f;
|
||||
const cvar_t *adr;
|
||||
char buffer[20];
|
||||
|
||||
|
@ -5254,23 +5307,26 @@ AddressBook_MenuInit(void)
|
|||
|
||||
adr = Cvar_Get(buffer, "", CVAR_ARCHIVE);
|
||||
|
||||
s_addressbook_fields[i].generic.type = MTYPE_FIELD;
|
||||
s_addressbook_fields[i].generic.name = 0;
|
||||
s_addressbook_fields[i].generic.callback = 0;
|
||||
s_addressbook_fields[i].generic.x = 0;
|
||||
s_addressbook_fields[i].generic.y = i * 18 + 0;
|
||||
s_addressbook_fields[i].generic.localdata[0] = i;
|
||||
s_addressbook_fields[i].cursor = 0;
|
||||
s_addressbook_fields[i].length = 60;
|
||||
s_addressbook_fields[i].visible_length = 30;
|
||||
f = &s_addressbook_fields[i];
|
||||
|
||||
strcpy(s_addressbook_fields[i].buffer, adr->string);
|
||||
f->generic.type = MTYPE_FIELD;
|
||||
f->generic.name = 0;
|
||||
f->generic.callback = 0;
|
||||
f->generic.x = 0;
|
||||
f->generic.y = i * 18 + 0;
|
||||
f->generic.localdata[0] = i;
|
||||
|
||||
Menu_AddItem(&s_addressbook_menu, &s_addressbook_fields[i]);
|
||||
f->length = 60;
|
||||
f->visible_length = 30;
|
||||
|
||||
Q_strlcpy(f->buffer, adr->string, f->length);
|
||||
f->cursor = strlen(f->buffer);
|
||||
|
||||
Menu_AddItem(&s_addressbook_menu, f);
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
static const char *
|
||||
AddressBook_MenuKey(int key)
|
||||
{
|
||||
if (key == K_ESCAPE)
|
||||
|
@ -5395,7 +5451,7 @@ IconOfSkinExists(const char* skin, char** pcxfiles, int npcxfiles,
|
|||
static void
|
||||
StripExtension(char* path)
|
||||
{
|
||||
int length;
|
||||
size_t length;
|
||||
|
||||
length = strlen(path) - 1;
|
||||
|
||||
|
@ -5678,7 +5734,8 @@ HasSkinsInDir(const char *dirname, int *num)
|
|||
{
|
||||
char **list_png, **list_pcx, **list_m8;
|
||||
char **curr = NULL, **list = NULL;
|
||||
int num_png, num_pcx, num_m8, dirname_size;
|
||||
int num_png, num_pcx, num_m8;
|
||||
size_t dirname_size;
|
||||
|
||||
*num = 0;
|
||||
/* dir name size plus one for skip slash */
|
||||
|
@ -5970,7 +6027,8 @@ PlayerConfig_ScanDirectories(void)
|
|||
return result;
|
||||
}
|
||||
|
||||
void ListModels_f(void)
|
||||
static void
|
||||
ListModels_f(void)
|
||||
{
|
||||
PlayerConfig_ScanDirectories();
|
||||
|
||||
|
@ -6163,11 +6221,12 @@ extern float CalcFov(float fov_x, float w, float h);
|
|||
static void
|
||||
PlayerConfig_AnimateModel(entity_t *entity, int count, int curTime)
|
||||
{
|
||||
const cvar_t *cl_start_frame, *cl_end_frame;
|
||||
const cvar_t *cl_start_frame, *cl_end_frame, *cl_mesh_mask;
|
||||
int startFrame, endFrame;
|
||||
|
||||
cl_start_frame = Cvar_Get("cl_model_preview_start", "84", CVAR_ARCHIVE);
|
||||
cl_end_frame = Cvar_Get("cl_model_preview_end", "94", CVAR_ARCHIVE);
|
||||
cl_mesh_mask = Cvar_Get("cl_model_mesh_hide", "0", CVAR_ARCHIVE);
|
||||
startFrame = cl_start_frame->value;
|
||||
endFrame = cl_end_frame->value;
|
||||
|
||||
|
@ -6179,6 +6238,8 @@ PlayerConfig_AnimateModel(entity_t *entity, int count, int curTime)
|
|||
{
|
||||
/* salute male 84..94 frame */
|
||||
entity[i].frame = (curTime / 100) % (endFrame - startFrame) + startFrame;
|
||||
/* hide part of meshes */
|
||||
entity[i].rr_mesh = cl_mesh_mask->value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6367,7 +6428,8 @@ M_Quit_Draw(void)
|
|||
float scale = SCR_GetMenuScale();
|
||||
|
||||
Draw_GetPicSize(&w, &h, "quit");
|
||||
Draw_PicScaled((viddef.width - w * scale) / 2, (viddef.height - h * scale) / 2, "quit", scale);
|
||||
Draw_PicScaledAltText((viddef.width - w * scale) / 2, (viddef.height - h * scale) / 2,
|
||||
"quit", scale, "Quit Y/N?");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -6409,6 +6471,7 @@ M_Init(void)
|
|||
Cmd_AddCommand("menu_gyro", M_Menu_Gyro_f);
|
||||
Cmd_AddCommand("menu_buttons", M_Menu_ControllerButtons_f);
|
||||
Cmd_AddCommand("menu_altbuttons", M_Menu_ControllerAltButtons_f);
|
||||
Cmd_AddCommand("menu_sticks", M_Menu_Stick_f);
|
||||
Cmd_AddCommand("menu_quit", M_Menu_Quit_f);
|
||||
|
||||
/* initialize the server address book cvars (adr0, adr1, ...)
|
||||
|
@ -6431,6 +6494,12 @@ M_Init(void)
|
|||
{
|
||||
m_cursor_width = w;
|
||||
}
|
||||
|
||||
/* No cursor image? */
|
||||
if (m_cursor_width == 0)
|
||||
{
|
||||
m_cursor_width = 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
#include "../header/client.h"
|
||||
#include "header/qmenu.h"
|
||||
|
||||
void IN_GetClipboardText(char *out, size_t n);
|
||||
int IN_SetClipboardText(const char *s);
|
||||
|
||||
static void Action_Draw(menuaction_s *a);
|
||||
static void Menu_DrawStatusBar(const char *string);
|
||||
static void MenuList_Draw(menulist_s *l);
|
||||
|
@ -64,7 +67,8 @@ ClampCvar(float min, float max, float value)
|
|||
Bitmap_Draw
|
||||
=================
|
||||
*/
|
||||
void Bitmap_Draw(menubitmap_s * item)
|
||||
static void
|
||||
Bitmap_Draw(menubitmap_s * item)
|
||||
{
|
||||
float scale = SCR_GetMenuScale();
|
||||
int x = 0;
|
||||
|
@ -76,11 +80,13 @@ void Bitmap_Draw(menubitmap_s * item)
|
|||
if (((item->generic.flags & QMF_HIGHLIGHT_IF_FOCUS) &&
|
||||
(Menu_ItemAtCursor(item->generic.parent) == item)))
|
||||
{
|
||||
Draw_PicScaled(x * scale, y * scale, item->focuspic, scale);
|
||||
Draw_PicScaledAltText(x * scale, y * scale, item->focuspic, scale,
|
||||
item->alttext);
|
||||
}
|
||||
else if (item->generic.name)
|
||||
{
|
||||
Draw_PicScaled(x * scale, y * scale, ( char * )item->generic.name, scale);
|
||||
Draw_PicScaledAltText(x * scale, y * scale, ( char * )item->generic.name, scale,
|
||||
item->alttext);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,19 +135,7 @@ Action_Draw(menuaction_s *a)
|
|||
}
|
||||
}
|
||||
|
||||
qboolean
|
||||
Field_DoEnter(menufield_s *f)
|
||||
{
|
||||
if (f->generic.callback)
|
||||
{
|
||||
f->generic.callback(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
Field_Draw(menufield_s *f)
|
||||
{
|
||||
int i, n;
|
||||
|
@ -166,7 +160,8 @@ Field_Draw(menufield_s *f)
|
|||
n = sizeof(tempbuffer);
|
||||
}
|
||||
|
||||
Q_strlcpy(tempbuffer, f->buffer + f->visible_offset, n);
|
||||
i = (f->cursor > f->visible_length) ? (f->cursor - f->visible_length) : 0;
|
||||
Q_strlcpy(tempbuffer, f->buffer + i, n);
|
||||
|
||||
Draw_CharScaled(x + (16 * scale),
|
||||
(y - 4) * scale, 18, scale);
|
||||
|
@ -191,30 +186,36 @@ Field_Draw(menufield_s *f)
|
|||
|
||||
if (Menu_ItemAtCursor(f->generic.parent) == f)
|
||||
{
|
||||
int offset;
|
||||
|
||||
if (f->visible_offset)
|
||||
{
|
||||
offset = f->visible_length;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
offset = f->cursor;
|
||||
}
|
||||
|
||||
if (((int)(Sys_Milliseconds() / 250)) & 1)
|
||||
{
|
||||
int offset;
|
||||
|
||||
if (f->cursor > f->visible_length)
|
||||
{
|
||||
offset = f->visible_length;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = f->cursor;
|
||||
}
|
||||
|
||||
Draw_CharScaled(
|
||||
x + (24 * scale) + (offset * (8 * scale)),
|
||||
y * scale, 11, scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
Draw_CharScaled(
|
||||
x + (24 * scale) + (offset * (8 * scale)),
|
||||
y * scale, ' ', scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Field_ResetCursor(menuframework_s *m)
|
||||
{
|
||||
menucommon_s *item = Menu_ItemAtCursor(m);
|
||||
|
||||
if (item && item->type == MTYPE_FIELD)
|
||||
{
|
||||
menufield_s *f = (menufield_s *)item;
|
||||
|
||||
f->cursor = strlen(f->buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,36 +224,97 @@ extern int keydown[];
|
|||
qboolean
|
||||
Field_Key(menufield_s *f, int key)
|
||||
{
|
||||
if (key > 127)
|
||||
char txt[256];
|
||||
|
||||
if (keydown[K_CTRL])
|
||||
{
|
||||
return false;
|
||||
if (key == 'l')
|
||||
{
|
||||
*f->buffer = '\0';
|
||||
f->cursor = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key == 'c' || key == 'x')
|
||||
{
|
||||
if (*f->buffer != '\0')
|
||||
{
|
||||
if (IN_SetClipboardText(f->buffer))
|
||||
{
|
||||
Com_Printf("Copying menu field to clipboard failed.\n");
|
||||
}
|
||||
else if (key == 'x')
|
||||
{
|
||||
*f->buffer = '\0';
|
||||
f->cursor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key == 'v')
|
||||
{
|
||||
IN_GetClipboardText(txt, sizeof(txt));
|
||||
|
||||
if (*txt != '\0')
|
||||
{
|
||||
if ((f->generic.flags & QMF_NUMBERSONLY) && !Q_strisnum(txt))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
f->cursor += Q_strins(f->buffer, txt, f->cursor, f->length);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case K_KP_LEFTARROW:
|
||||
case K_LEFTARROW:
|
||||
case K_BACKSPACE:
|
||||
|
||||
if (f->cursor > 0)
|
||||
{
|
||||
memmove(&f->buffer[f->cursor - 1],
|
||||
&f->buffer[f->cursor],
|
||||
strlen(&f->buffer[f->cursor]) + 1);
|
||||
f->cursor--;
|
||||
|
||||
if (f->visible_offset)
|
||||
{
|
||||
f->visible_offset--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case K_KP_RIGHTARROW:
|
||||
case K_RIGHTARROW:
|
||||
if (f->buffer[f->cursor] != '\0')
|
||||
{
|
||||
f->cursor++;
|
||||
}
|
||||
break;
|
||||
|
||||
case K_BACKSPACE:
|
||||
if (f->cursor > 0)
|
||||
{
|
||||
Q_strdel(f->buffer, f->cursor - 1, 1);
|
||||
f->cursor--;
|
||||
}
|
||||
break;
|
||||
|
||||
case K_END:
|
||||
if (f->buffer[f->cursor] == '\0')
|
||||
{
|
||||
f->cursor = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
f->cursor = strlen(f->buffer);
|
||||
}
|
||||
break;
|
||||
|
||||
case K_KP_DEL:
|
||||
case K_DEL:
|
||||
memmove(&f->buffer[f->cursor], &f->buffer[f->cursor + 1],
|
||||
strlen(&f->buffer[f->cursor + 1]) + 1);
|
||||
if (f->buffer[f->cursor] != '\0')
|
||||
{
|
||||
Q_strdel(f->buffer, f->cursor, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case K_KP_ENTER:
|
||||
|
@ -261,24 +323,21 @@ Field_Key(menufield_s *f, int key)
|
|||
case K_TAB:
|
||||
return false;
|
||||
|
||||
case K_SPACE:
|
||||
default:
|
||||
if (key > 127)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isdigit(key) && (f->generic.flags & QMF_NUMBERSONLY))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (f->cursor < f->length)
|
||||
{
|
||||
f->buffer[f->cursor++] = key;
|
||||
f->buffer[f->cursor] = 0;
|
||||
*txt = key;
|
||||
*(txt + 1) = '\0';
|
||||
|
||||
if (f->cursor > f->visible_length)
|
||||
{
|
||||
f->visible_offset++;
|
||||
}
|
||||
}
|
||||
f->cursor += Q_strins(f->buffer, txt, f->cursor, f->length);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -469,49 +528,33 @@ Menu_DrawStatusBar(const char *string)
|
|||
void
|
||||
Menu_DrawString(int x, int y, const char *string)
|
||||
{
|
||||
unsigned i;
|
||||
float scale = SCR_GetMenuScale();
|
||||
|
||||
for (i = 0; i < strlen(string); i++)
|
||||
{
|
||||
Draw_CharScaled(x + i * 8 * scale, y * scale, string[i], scale);
|
||||
}
|
||||
Draw_StringScaled(x, y * scale, scale, false, string);
|
||||
}
|
||||
|
||||
void
|
||||
Menu_DrawStringDark(int x, int y, const char *string)
|
||||
{
|
||||
unsigned i;
|
||||
float scale = SCR_GetMenuScale();
|
||||
|
||||
for (i = 0; i < strlen(string); i++)
|
||||
{
|
||||
Draw_CharScaled(x + i * 8 * scale, y * scale, string[i] + 128, scale);
|
||||
}
|
||||
Draw_StringScaled(x, y * scale, scale, true, string);
|
||||
}
|
||||
|
||||
void
|
||||
Menu_DrawStringR2L(int x, int y, const char *string)
|
||||
{
|
||||
unsigned i;
|
||||
float scale = SCR_GetMenuScale();
|
||||
|
||||
for (i = 0; i < strlen(string); i++)
|
||||
{
|
||||
Draw_CharScaled(x - i * 8 * scale, y * scale, string[strlen(string) - i - 1], scale);
|
||||
}
|
||||
Draw_StringScaled(x - 8 * scale * strlen(string), y * scale, scale, false, string);
|
||||
}
|
||||
|
||||
void
|
||||
Menu_DrawStringR2LDark(int x, int y, const char *string)
|
||||
{
|
||||
unsigned i;
|
||||
float scale = SCR_GetMenuScale();
|
||||
|
||||
for (i = 0; i < strlen(string); i++)
|
||||
{
|
||||
Draw_CharScaled(x - i * 8 * scale, y * scale, string[strlen(string) - i - 1] + 128, scale);
|
||||
}
|
||||
Draw_StringScaled(x - 8 * scale * strlen(string), y * scale, scale, true, string);
|
||||
}
|
||||
|
||||
void *
|
||||
|
|
|
@ -445,6 +445,7 @@ VID_MenuInit(void)
|
|||
"[3840 2160 ]",
|
||||
"[4096 2160 ]",
|
||||
"[5120 2880 ]",
|
||||
"[1600 900 ]",
|
||||
AUTO_MODE_NAME,
|
||||
CUSTOM_MODE_NAME,
|
||||
0
|
||||
|
|
|
@ -80,8 +80,8 @@ Mod_NumberLeafs(mleaf_t *leafs, mnode_t *node, int *r_leaftovis, int *r_vistolea
|
|||
|
||||
static void
|
||||
Mod_LoadQNodes(const char *name, cplane_t *planes, int numplanes, mleaf_t *leafs,
|
||||
int numleafs, mnode_t **nodes, int *numnodes, const byte *mod_base,
|
||||
const lump_t *l)
|
||||
int numleafs, mnode_t **nodes, int *numnodes, vec3_t mins, vec3_t maxs,
|
||||
const byte *mod_base, const lump_t *l)
|
||||
{
|
||||
dqnode_t *in;
|
||||
mnode_t *out;
|
||||
|
@ -101,6 +101,24 @@ Mod_LoadQNodes(const char *name, cplane_t *planes, int numplanes, mleaf_t *leafs
|
|||
*nodes = out;
|
||||
*numnodes = count;
|
||||
|
||||
/* Set initial min/max */
|
||||
if (count)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
mins[i] = in->mins[i];
|
||||
maxs[i] = in->maxs[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
mins[i] = 0;
|
||||
maxs[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++, in++, out++)
|
||||
{
|
||||
int j, planenum;
|
||||
|
@ -109,6 +127,17 @@ Mod_LoadQNodes(const char *name, cplane_t *planes, int numplanes, mleaf_t *leafs
|
|||
{
|
||||
out->minmaxs[j] = in->mins[j];
|
||||
out->minmaxs[3 + j] = in->maxs[j];
|
||||
|
||||
/* update min/max */
|
||||
if (mins[j] > in->mins[j])
|
||||
{
|
||||
mins[j] = in->mins[j];
|
||||
}
|
||||
|
||||
if (maxs[j] < in->maxs[j])
|
||||
{
|
||||
maxs[j] = in->maxs[j];
|
||||
}
|
||||
}
|
||||
|
||||
planenum = LittleLong(in->planenum) & 0xFFFFFFFF;
|
||||
|
@ -156,19 +185,31 @@ Mod_LoadQNodes(const char *name, cplane_t *planes, int numplanes, mleaf_t *leafs
|
|||
|
||||
void
|
||||
Mod_LoadQBSPNodes(const char *name, cplane_t *planes, int numplanes, mleaf_t *leafs,
|
||||
int numleafs, mnode_t **nodes, int *numnodes, const byte *mod_base,
|
||||
const lump_t *l, int ident)
|
||||
int numleafs, mnode_t **nodes, int *numnodes, vec3_t mins, vec3_t maxs,
|
||||
const byte *mod_base, const lump_t *l, int ident)
|
||||
{
|
||||
int r_leaftovis[MAX_MAP_LEAFS], r_vistoleaf[MAX_MAP_LEAFS];
|
||||
int *r_leaftovis, *r_vistoleaf;
|
||||
int numvisleafs;
|
||||
|
||||
r_leaftovis = malloc(numleafs * sizeof(int));
|
||||
r_vistoleaf = malloc(numleafs * sizeof(int));
|
||||
if (!r_leaftovis || !r_vistoleaf)
|
||||
{
|
||||
Com_Error(ERR_DROP, "%s: Can't allocate %d leaf temporary buf.",
|
||||
__func__, numleafs);
|
||||
return;
|
||||
}
|
||||
|
||||
Mod_LoadQNodes(name, planes, numplanes, leafs, numleafs, nodes, numnodes,
|
||||
mod_base, l);
|
||||
mins, maxs, mod_base, l);
|
||||
|
||||
Mod_SetParent(*nodes, NULL); /* sets nodes and leafs */
|
||||
|
||||
numvisleafs = 0;
|
||||
Mod_NumberLeafs(leafs, *nodes, r_leaftovis, r_vistoleaf, &numvisleafs);
|
||||
|
||||
free(r_leaftovis);
|
||||
free(r_vistoleaf);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -705,7 +746,7 @@ Mod_LoadQBSPMarksurfaces(const char *name, msurface_t ***marksurfaces, unsigned
|
|||
void
|
||||
Mod_LoadQBSPLeafs(const char *name, mleaf_t **leafs, int *numleafs,
|
||||
msurface_t **marksurfaces, unsigned int nummarksurfaces,
|
||||
const byte *mod_base, const lump_t *l)
|
||||
int *numclusters, const byte *mod_base, const lump_t *l)
|
||||
{
|
||||
dqleaf_t *in;
|
||||
mleaf_t *out;
|
||||
|
@ -724,6 +765,7 @@ Mod_LoadQBSPLeafs(const char *name, mleaf_t **leafs, int *numleafs,
|
|||
|
||||
*leafs = out;
|
||||
*numleafs = count;
|
||||
*numclusters = 0;
|
||||
|
||||
for (i = 0; i < count; i++, in++, out++)
|
||||
{
|
||||
|
@ -748,6 +790,11 @@ Mod_LoadQBSPLeafs(const char *name, mleaf_t **leafs, int *numleafs,
|
|||
Com_Error(ERR_DROP, "%s: wrong marksurfaces position in %s",
|
||||
__func__, name);
|
||||
}
|
||||
|
||||
if (out->cluster >= *numclusters)
|
||||
{
|
||||
*numclusters = out->cluster + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,10 +26,6 @@
|
|||
|
||||
#include "../ref_shared.h"
|
||||
|
||||
static const float r_avertexnormals[NUMVERTEXNORMALS][3] = {
|
||||
#include "../constants/anorms.h"
|
||||
};
|
||||
|
||||
static vec4_t *lerpbuff = NULL;
|
||||
static int lerpbuffnum = 0;
|
||||
|
||||
|
@ -76,31 +72,16 @@ R_VertBufferFree(void)
|
|||
lerpbuffnum = 0;
|
||||
}
|
||||
|
||||
/* compressed vertex normals used by mdl and md2 model formats */
|
||||
void
|
||||
R_ConvertNormalMDL(byte in_normal, signed char *normal)
|
||||
{
|
||||
const float *norm;
|
||||
int n;
|
||||
|
||||
norm = r_avertexnormals[in_normal % NUMVERTEXNORMALS];
|
||||
|
||||
for (n = 0; n < 3; n ++)
|
||||
{
|
||||
normal[n] = norm[n] * 127.f;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
R_LerpVerts(qboolean powerUpEffect, int nverts,
|
||||
const dxtrivertx_t *v, const dxtrivertx_t *ov,
|
||||
float *lerp, const float move[3],
|
||||
const float frontv[3], const float backv[3])
|
||||
const float frontv[3], const float backv[3], const float *scale)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (powerUpEffect)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nverts; i++, v++, ov++, lerp += 4)
|
||||
{
|
||||
int n;
|
||||
|
@ -111,18 +92,23 @@ R_LerpVerts(qboolean powerUpEffect, int nverts,
|
|||
|
||||
normal = v->normal[n] / 127.f;
|
||||
|
||||
lerp[n] = move[n] + ov->v[n] * backv[n] + v->v[n] * frontv[n] +
|
||||
lerp[n] = scale[n] * (move[n] + ov->v[n] * backv[n] + v->v[n] * frontv[n]) +
|
||||
normal * POWERSUIT_SCALE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nverts; i++, v++, ov++, lerp += 4)
|
||||
{
|
||||
lerp[0] = move[0] + ov->v[0] * backv[0] + v->v[0] * frontv[0];
|
||||
lerp[1] = move[1] + ov->v[1] * backv[1] + v->v[1] * frontv[1];
|
||||
lerp[2] = move[2] + ov->v[2] * backv[2] + v->v[2] * frontv[2];
|
||||
int n;
|
||||
|
||||
for (n = 0; n < 3; n++)
|
||||
{
|
||||
lerp[n] = scale[n] * (move[n] + ov->v[n] * backv[n] + v->v[n] * frontv[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -33,6 +33,8 @@
|
|||
// include resize implementation
|
||||
#define STB_IMAGE_RESIZE_IMPLEMENTATION
|
||||
#include "stb_image_resize.h"
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#include "../files/stb_truetype.h"
|
||||
|
||||
/*
|
||||
* Add extension to file name
|
||||
|
@ -641,6 +643,12 @@ R_LoadImage(const char *name, const char* namewe, const char *ext, imagetype_t t
|
|||
image = LoadImage_Ext(name, namewe, "png", type, r_retexturing, load_image);
|
||||
}
|
||||
|
||||
/* atd check */
|
||||
if (!image)
|
||||
{
|
||||
image = LoadImage_Ext(name, namewe, "atd", type, r_retexturing, load_image);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
@ -715,22 +723,25 @@ R_FindPic(const char *name, findimage_t find_image)
|
|||
const char* ext;
|
||||
|
||||
ext = COM_FileExtension(name);
|
||||
if(!ext[0])
|
||||
if (!ext[0])
|
||||
{
|
||||
/* file has no extension */
|
||||
strncpy(namewe, name, sizeof(namewe) - 1);
|
||||
namewe[sizeof(namewe) - 1] = 0;
|
||||
Q_strlcpy(namewe, name, sizeof(namewe));
|
||||
}
|
||||
else
|
||||
{
|
||||
int len;
|
||||
|
||||
len = strlen(name);
|
||||
size_t len;
|
||||
|
||||
/* Remove the extension */
|
||||
memset(namewe, 0, MAX_QPATH);
|
||||
memcpy(namewe, name, len - (strlen(ext) + 1));
|
||||
namewe[len - (strlen(ext))] = 0;
|
||||
len = (ext - name) - 1;
|
||||
if ((len < 1) || (len > sizeof(namewe) - 1))
|
||||
{
|
||||
Com_DPrintf("%s: Bad filename %s\n", __func__, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(namewe, name, len);
|
||||
namewe[len] = 0;
|
||||
}
|
||||
|
||||
/* Quake 2 */
|
||||
|
@ -758,3 +769,150 @@ R_FindPic(const char *name, findimage_t find_image)
|
|||
|
||||
return image;
|
||||
}
|
||||
|
||||
unsigned
|
||||
R_NextUTF8Code(const char **curr)
|
||||
{
|
||||
unsigned value = 0, size = 0, i;
|
||||
|
||||
value = **curr;
|
||||
if (!(value & 0x80))
|
||||
{
|
||||
size = 1;
|
||||
}
|
||||
else if ((value & 0xE0) == 0xC0)
|
||||
{
|
||||
size = 2;
|
||||
value = (value & 0x1F) << 6;
|
||||
}
|
||||
else if ((value & 0xF0) == 0xE0)
|
||||
{
|
||||
size = 3;
|
||||
value = (value & 0x0F) << 12;
|
||||
}
|
||||
else if ((value & 0xF8) == 0xF0)
|
||||
{
|
||||
size = 4;
|
||||
value = (value & 0x07) << 18;
|
||||
}
|
||||
|
||||
(*curr) ++;
|
||||
size --;
|
||||
|
||||
for (i = 0; (i < size); i++)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = **curr;
|
||||
if ((c & 0xC0) != 0x80)
|
||||
{
|
||||
break;
|
||||
}
|
||||
value |= (c & 0x3F) << ((size - i - 1) * 6);
|
||||
(*curr) ++;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
struct image_s *
|
||||
R_LoadConsoleChars(findimage_t find_image)
|
||||
{
|
||||
struct image_s *draw_chars;
|
||||
|
||||
/* load console characters */
|
||||
draw_chars = R_FindPic("conchars", find_image);
|
||||
|
||||
/* Anachronox */
|
||||
if (!draw_chars)
|
||||
{
|
||||
draw_chars = R_FindPic("fonts/conchars", find_image);
|
||||
}
|
||||
|
||||
/* Daikatana */
|
||||
if (!draw_chars)
|
||||
{
|
||||
draw_chars = R_FindPic("dkchars", find_image);
|
||||
}
|
||||
|
||||
if (!draw_chars)
|
||||
{
|
||||
Com_Error(ERR_FATAL, "%s: Couldn't load pics/conchars",
|
||||
__func__);
|
||||
}
|
||||
|
||||
return draw_chars;
|
||||
}
|
||||
|
||||
void
|
||||
R_LoadTTFFont(const char *ttffont, int vid_height, float *r_font_size,
|
||||
int *r_font_height, stbtt_bakedchar **draw_fontcodes,
|
||||
struct image_s **draw_font, struct image_s **draw_font_alt,
|
||||
loadimage_t R_LoadPic)
|
||||
{
|
||||
char font_name[MAX_QPATH] = {0};
|
||||
byte *data, *font_mask, *font_data;
|
||||
int size, i, power_two = 1, texture_size;
|
||||
|
||||
snprintf(font_name, sizeof(font_name), "fonts/%s.ttf", ttffont);
|
||||
|
||||
size = ri.FS_LoadFile(font_name, (void **)&data);
|
||||
if (size <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
*r_font_size = (vid_height / 240.0) * 4.0;
|
||||
if (*r_font_size < 8)
|
||||
{
|
||||
*r_font_size = 8.0;
|
||||
}
|
||||
|
||||
while (power_two < *r_font_size)
|
||||
{
|
||||
power_two <<= 1;
|
||||
}
|
||||
*r_font_height = 32 * power_two;
|
||||
|
||||
texture_size = (*r_font_height) * (*r_font_height);
|
||||
font_mask = malloc(texture_size);
|
||||
font_data = malloc(texture_size * 4);
|
||||
*draw_fontcodes = malloc(MAX_FONTCODE * sizeof(**draw_fontcodes));
|
||||
|
||||
stbtt_BakeFontBitmap(data,
|
||||
0 /* file offset */,
|
||||
*r_font_size * 1.5 /* symbol size ~ as console font */,
|
||||
font_mask,
|
||||
*r_font_height, *r_font_height,
|
||||
32 /* Start font code */, MAX_FONTCODE,
|
||||
*draw_fontcodes);
|
||||
|
||||
for (i = 0; i < texture_size; i++)
|
||||
{
|
||||
font_data[i * 4 + 0] = font_mask[i];
|
||||
font_data[i * 4 + 1] = font_mask[i];
|
||||
font_data[i * 4 + 2] = font_mask[i];
|
||||
font_data[i * 4 + 3] = font_mask[i] > 16 ? 255 : 0;
|
||||
}
|
||||
*draw_font = R_LoadPic("***ttf***", font_data,
|
||||
*r_font_height, *r_font_height, *r_font_height, *r_font_height,
|
||||
texture_size, it_pic, 32);
|
||||
|
||||
for (i = 0; i < texture_size; i++)
|
||||
{
|
||||
font_data[i * 4 + 0] = 0x0;
|
||||
font_data[i * 4 + 1] = font_mask[i];
|
||||
font_data[i * 4 + 2] = 0x0;
|
||||
font_data[i * 4 + 3] = font_mask[i] > 16 ? 255 : 0;
|
||||
}
|
||||
|
||||
*draw_font_alt = R_LoadPic("***ttf_alt***", font_data,
|
||||
*r_font_height, *r_font_height, *r_font_height, *r_font_height,
|
||||
texture_size, it_pic, 32);
|
||||
|
||||
free(font_data);
|
||||
free(font_mask);
|
||||
ri.FS_FreeFile((void *)data);
|
||||
|
||||
R_Printf(PRINT_ALL, "%s(): Loaded font %s %.0fp.\n", __func__, font_name, *r_font_size);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* stb_image - v2.28 - public domain image loader - http://nothings.org/stb
|
||||
/* stb_image - v2.30 - public domain image loader - http://nothings.org/stb
|
||||
no warranty implied; use at your own risk
|
||||
|
||||
Do this:
|
||||
|
@ -48,6 +48,8 @@ LICENSE
|
|||
|
||||
RECENT REVISION HISTORY:
|
||||
|
||||
2.30 (2024-05-31) avoid erroneous gcc warning
|
||||
2.29 (2023-05-xx) optimizations
|
||||
2.28 (2023-01-29) many error fixes, security errors, just tons of stuff
|
||||
2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes
|
||||
2.26 (2020-07-13) many minor fixes
|
||||
|
@ -98,7 +100,7 @@ RECENT REVISION HISTORY:
|
|||
Bug & warning fixes
|
||||
Marc LeBlanc David Woo Guillaume George Martins Mozeiko
|
||||
Christpher Lloyd Jerry Jansson Joseph Thomson Blazej Dariusz Roszkowski
|
||||
Phil Jordan Dave Moore Roy Eltham
|
||||
Phil Jordan Henner Zeller Dave Moore Roy Eltham
|
||||
Hayaki Saito Nathan Reed Won Chun
|
||||
Luke Graham Johan Duparc Nick Verigakis the Horde3D community
|
||||
Thomas Ruf Ronny Chevalier github:rlyeh
|
||||
|
@ -109,7 +111,7 @@ RECENT REVISION HISTORY:
|
|||
Cass Everitt Ryamond Barbiero github:grim210
|
||||
Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw
|
||||
Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus
|
||||
Josh Tobin Neil Bickford Matthew Gregan github:poppolopoppo
|
||||
Josh Tobin Nia Bickford Matthew Gregan github:poppolopoppo
|
||||
Julian Raschke Gregory Mullen Christian Floisand github:darealshinji
|
||||
Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007
|
||||
Brad Weinberger Matvey Cherevko github:mosra
|
||||
|
@ -371,6 +373,15 @@ RECENT REVISION HISTORY:
|
|||
|
||||
#define STBI_VERSION 1
|
||||
|
||||
#if defined(__has_attribute)
|
||||
# if __has_attribute(fallthrough)
|
||||
# define STBI_FALLTHROUGH __attribute__((fallthrough));
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(STBI_FALLTHROUGH)
|
||||
# define STBI_FALLTHROUGH
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
STBI_default = 0, // only used for desired_channels
|
||||
|
@ -1072,8 +1083,8 @@ static int stbi__addints_valid(int a, int b)
|
|||
return a <= INT_MAX - b;
|
||||
}
|
||||
|
||||
// returns 1 if the product of two signed shorts is valid, 0 on overflow.
|
||||
static int stbi__mul2shorts_valid(short a, short b)
|
||||
// returns 1 if the product of two ints fits in a signed short, 0 on overflow.
|
||||
static int stbi__mul2shorts_valid(int a, int b)
|
||||
{
|
||||
if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow
|
||||
if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX/b; // product is positive, so similar to mul2sizes_valid
|
||||
|
@ -1207,7 +1218,7 @@ static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int chan
|
|||
int img_len = w * h * channels;
|
||||
stbi__uint16 *enlarged;
|
||||
|
||||
enlarged = (stbi__uint16 *) stbi__malloc(img_len*2);
|
||||
enlarged = (stbi__uint16 *) stbi__malloc(((size_t)img_len)*2);
|
||||
if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory");
|
||||
|
||||
for (i = 0; i < img_len; ++i)
|
||||
|
@ -1267,7 +1278,12 @@ static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x,
|
|||
STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16);
|
||||
|
||||
if (ri.bits_per_channel != 8) {
|
||||
result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
|
||||
stbi_uc *converted = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
|
||||
if (converted == NULL) {
|
||||
STBI_FREE(result);
|
||||
return NULL;
|
||||
}
|
||||
result = converted;
|
||||
ri.bits_per_channel = 8;
|
||||
}
|
||||
|
||||
|
@ -1293,7 +1309,12 @@ static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x,
|
|||
STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16);
|
||||
|
||||
if (ri.bits_per_channel != 16) {
|
||||
result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
|
||||
stbi__uint16 * converted = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
|
||||
if (converted == NULL) {
|
||||
STBI_FREE(result);
|
||||
return NULL;
|
||||
}
|
||||
result = converted;
|
||||
ri.bits_per_channel = 16;
|
||||
}
|
||||
|
||||
|
@ -1379,7 +1400,12 @@ STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req
|
|||
result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
|
||||
if (result) {
|
||||
// need to 'unget' all the characters in the IO buffer
|
||||
fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
|
||||
if (fseek(f, -(int)(s.img_buffer_end - s.img_buffer), SEEK_CUR) != 0) {
|
||||
// fseek() failed; we can no longer maintain the file cursor position
|
||||
// guarantee of this function, so return null.
|
||||
STBI_FREE(result);
|
||||
return stbi__errpuc("bad file", "fseek() failed; seek position unreliable");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1392,7 +1418,12 @@ STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp,
|
|||
result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp);
|
||||
if (result) {
|
||||
// need to 'unget' all the characters in the IO buffer
|
||||
fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
|
||||
if (fseek(f, -(int)(s.img_buffer_end - s.img_buffer), SEEK_CUR) != 0) {
|
||||
// fseek() failed; we can no longer maintain the file cursor position
|
||||
// guarantee of this function, so return null.
|
||||
STBI_FREE(result);
|
||||
return (stbi__uint16 *) stbi__errpuc("bad file", "fseek() failed; seek position unreliable");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1446,8 +1477,9 @@ STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int *
|
|||
stbi__start_mem(&s,buffer,len);
|
||||
|
||||
result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp);
|
||||
if (stbi__vertically_flip_on_load) {
|
||||
stbi__vertical_flip_slices( result, *x, *y, *z, *comp );
|
||||
if (stbi__vertically_flip_on_load && result) {
|
||||
int channels = req_comp ? req_comp : *comp;
|
||||
stbi__vertical_flip_slices( result, *x, *y, *z, channels );
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1540,12 +1572,13 @@ STBIDEF int stbi_is_hdr (char const *filename)
|
|||
STBIDEF int stbi_is_hdr_from_file(FILE *f)
|
||||
{
|
||||
#ifndef STBI_NO_HDR
|
||||
long pos = ftell(f);
|
||||
int res;
|
||||
long pos = ftell(f);
|
||||
if (pos < 0) return stbi__err("bad file", "ftell() failed");
|
||||
stbi__context s;
|
||||
stbi__start_file(&s,f);
|
||||
res = stbi__hdr_test(&s);
|
||||
fseek(f, pos, SEEK_SET);
|
||||
if (fseek(f, pos, SEEK_SET) != 0) return stbi__err("bad file", "fseek() failed");
|
||||
return res;
|
||||
#else
|
||||
STBI_NOTUSED(f);
|
||||
|
@ -1755,6 +1788,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
|
|||
int i,j;
|
||||
unsigned char *good;
|
||||
|
||||
if (data == NULL) return data;
|
||||
if (req_comp == img_n) return data;
|
||||
STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
|
||||
|
||||
|
@ -1795,7 +1829,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD)
|
||||
#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PNM)
|
||||
// nothing
|
||||
#else
|
||||
static stbi__uint16 stbi__compute_y_16(int r, int g, int b)
|
||||
|
@ -1804,7 +1838,7 @@ static stbi__uint16 stbi__compute_y_16(int r, int g, int b)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD)
|
||||
#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PNM)
|
||||
// nothing
|
||||
#else
|
||||
static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y)
|
||||
|
@ -2221,8 +2255,8 @@ static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman
|
|||
if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta","Corrupt JPEG");
|
||||
dc = j->img_comp[b].dc_pred + diff;
|
||||
j->img_comp[b].dc_pred = dc;
|
||||
if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
|
||||
data[0] = (short) (dc * dequant[0]);
|
||||
if ((dc > SHRT_MAX) || (dequant[0] > SHRT_MAX) || !stbi__mul2shorts_valid((short) dc, (short) dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
|
||||
data[0] = (short) ((size_t)dc * dequant[0]);
|
||||
|
||||
// decode AC components, see JPEG spec
|
||||
k = 1;
|
||||
|
@ -2278,7 +2312,7 @@ static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__
|
|||
if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG");
|
||||
dc = j->img_comp[b].dc_pred + diff;
|
||||
j->img_comp[b].dc_pred = dc;
|
||||
if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
|
||||
if ((dc > SHRT_MAX) || !stbi__mul2shorts_valid((short) dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
|
||||
data[0] = (short) (dc * (1 << j->succ_low));
|
||||
} else {
|
||||
// refinement scan for DC coefficient
|
||||
|
@ -3384,13 +3418,13 @@ static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int stbi__skip_jpeg_junk_at_end(stbi__jpeg *j)
|
||||
static stbi_uc stbi__skip_jpeg_junk_at_end(stbi__jpeg *j)
|
||||
{
|
||||
// some JPEGs have junk at end, skip over it but if we find what looks
|
||||
// like a valid marker, resume there
|
||||
while (!stbi__at_eof(j->s)) {
|
||||
int x = stbi__get8(j->s);
|
||||
while (x == 255) { // might be a marker
|
||||
stbi_uc x = stbi__get8(j->s);
|
||||
while (x == 0xff) { // might be a marker
|
||||
if (stbi__at_eof(j->s)) return STBI__MARKER_none;
|
||||
x = stbi__get8(j->s);
|
||||
if (x != 0x00 && x != 0xff) {
|
||||
|
@ -4176,6 +4210,7 @@ typedef struct
|
|||
{
|
||||
stbi_uc *zbuffer, *zbuffer_end;
|
||||
int num_bits;
|
||||
int hit_zeof_once;
|
||||
stbi__uint32 code_buffer;
|
||||
|
||||
char *zout;
|
||||
|
@ -4242,9 +4277,20 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
|
|||
int b,s;
|
||||
if (a->num_bits < 16) {
|
||||
if (stbi__zeof(a)) {
|
||||
return -1; /* report error for unexpected end of data. */
|
||||
if (!a->hit_zeof_once) {
|
||||
// This is the first time we hit eof, insert 16 extra padding btis
|
||||
// to allow us to keep going; if we actually consume any of them
|
||||
// though, that is invalid data. This is caught later.
|
||||
a->hit_zeof_once = 1;
|
||||
a->num_bits += 16; // add 16 implicit zero bits
|
||||
} else {
|
||||
// We already inserted our extra 16 padding bits and are again
|
||||
// out, this stream is actually prematurely terminated.
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
stbi__fill_bits(a);
|
||||
}
|
||||
stbi__fill_bits(a);
|
||||
}
|
||||
b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
|
||||
if (b) {
|
||||
|
@ -4309,6 +4355,13 @@ static int stbi__parse_huffman_block(stbi__zbuf *a)
|
|||
int len,dist;
|
||||
if (z == 256) {
|
||||
a->zout = zout;
|
||||
if (a->hit_zeof_once && a->num_bits < 16) {
|
||||
// The first time we hit zeof, we inserted 16 extra zero bits into our bit
|
||||
// buffer so the decoder can just do its speculative decoding. But if we
|
||||
// actually consumed any of those bits (which is the case when num_bits < 16),
|
||||
// the stream actually read past the end so it is malformed.
|
||||
return stbi__err("unexpected end","Corrupt PNG");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (z >= 286) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data
|
||||
|
@ -4320,7 +4373,7 @@ static int stbi__parse_huffman_block(stbi__zbuf *a)
|
|||
dist = stbi__zdist_base[z];
|
||||
if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]);
|
||||
if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG");
|
||||
if (zout + len > a->zout_end) {
|
||||
if (len > a->zout_end - zout) {
|
||||
if (!stbi__zexpand(a, zout, len)) return 0;
|
||||
zout = a->zout;
|
||||
}
|
||||
|
@ -4464,6 +4517,7 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
|
|||
if (!stbi__parse_zlib_header(a)) return 0;
|
||||
a->num_bits = 0;
|
||||
a->code_buffer = 0;
|
||||
a->hit_zeof_once = 0;
|
||||
do {
|
||||
final = stbi__zreceive(a,1);
|
||||
type = stbi__zreceive(a,2);
|
||||
|
@ -4619,9 +4673,8 @@ enum {
|
|||
STBI__F_up=2,
|
||||
STBI__F_avg=3,
|
||||
STBI__F_paeth=4,
|
||||
// synthetic filters used for first scanline to avoid needing a dummy row of 0s
|
||||
STBI__F_avg_first,
|
||||
STBI__F_paeth_first
|
||||
// synthetic filter used for first scanline to avoid needing a dummy row of 0s
|
||||
STBI__F_avg_first
|
||||
};
|
||||
|
||||
static stbi_uc first_row_filter[5] =
|
||||
|
@ -4630,29 +4683,56 @@ static stbi_uc first_row_filter[5] =
|
|||
STBI__F_sub,
|
||||
STBI__F_none,
|
||||
STBI__F_avg_first,
|
||||
STBI__F_paeth_first
|
||||
STBI__F_sub // Paeth with b=c=0 turns out to be equivalent to sub
|
||||
};
|
||||
|
||||
static int stbi__paeth(int a, int b, int c)
|
||||
{
|
||||
int p = a + b - c;
|
||||
int pa = abs(p-a);
|
||||
int pb = abs(p-b);
|
||||
int pc = abs(p-c);
|
||||
if (pa <= pb && pa <= pc) return a;
|
||||
if (pb <= pc) return b;
|
||||
return c;
|
||||
// This formulation looks very different from the reference in the PNG spec, but is
|
||||
// actually equivalent and has favorable data dependencies and admits straightforward
|
||||
// generation of branch-free code, which helps performance significantly.
|
||||
int thresh = c*3 - (a + b);
|
||||
int lo = a < b ? a : b;
|
||||
int hi = a < b ? b : a;
|
||||
int t0 = (hi <= thresh) ? lo : c;
|
||||
int t1 = (thresh <= lo) ? hi : t0;
|
||||
return t1;
|
||||
}
|
||||
|
||||
static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 };
|
||||
|
||||
// adds an extra all-255 alpha channel
|
||||
// dest == src is legal
|
||||
// img_n must be 1 or 3
|
||||
static void stbi__create_png_alpha_expand8(stbi_uc *dest, stbi_uc *src, stbi__uint32 x, int img_n)
|
||||
{
|
||||
int i;
|
||||
// must process data backwards since we allow dest==src
|
||||
if (img_n == 1) {
|
||||
for (i=x-1; i >= 0; --i) {
|
||||
dest[i*2+1] = 255;
|
||||
dest[i*2+0] = src[i];
|
||||
}
|
||||
} else {
|
||||
STBI_ASSERT(img_n == 3);
|
||||
for (i=x-1; i >= 0; --i) {
|
||||
dest[i*4+3] = 255;
|
||||
dest[i*4+2] = src[i*3+2];
|
||||
dest[i*4+1] = src[i*3+1];
|
||||
dest[i*4+0] = src[i*3+0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create the png data from post-deflated data
|
||||
static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color)
|
||||
{
|
||||
int bytes = (depth == 16? 2 : 1);
|
||||
int bytes = (depth == 16 ? 2 : 1);
|
||||
stbi__context *s = a->s;
|
||||
stbi__uint32 i,j,stride = x*out_n*bytes;
|
||||
stbi__uint32 img_len, img_width_bytes;
|
||||
stbi_uc *filter_buf;
|
||||
int all_ok = 1;
|
||||
int k;
|
||||
int img_n = s->img_n; // copy it into a local for later
|
||||
|
||||
|
@ -4664,8 +4744,11 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|||
a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into
|
||||
if (!a->out) return stbi__err("outofmem", "Out of memory");
|
||||
|
||||
// note: error exits here don't need to clean up a->out individually,
|
||||
// stbi__do_png always does on error.
|
||||
if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG");
|
||||
img_width_bytes = (((img_n * x * depth) + 7) >> 3);
|
||||
if (!stbi__mad2sizes_valid(img_width_bytes, y, img_width_bytes)) return stbi__err("too large", "Corrupt PNG");
|
||||
img_len = (img_width_bytes + 1) * y;
|
||||
|
||||
// we used to check for exact match between raw_len and img_len on non-interlaced PNGs,
|
||||
|
@ -4673,189 +4756,137 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|||
// so just check for raw_len < img_len always.
|
||||
if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG");
|
||||
|
||||
// Allocate two scan lines worth of filter workspace buffer.
|
||||
filter_buf = (stbi_uc *) stbi__malloc_mad2(img_width_bytes, 2, 0);
|
||||
if (!filter_buf) return stbi__err("outofmem", "Out of memory");
|
||||
|
||||
// Filtering for low-bit-depth images
|
||||
if (depth < 8) {
|
||||
filter_bytes = 1;
|
||||
width = img_width_bytes;
|
||||
}
|
||||
|
||||
for (j=0; j < y; ++j) {
|
||||
stbi_uc *cur = a->out + stride*j;
|
||||
stbi_uc *prior;
|
||||
// cur/prior filter buffers alternate
|
||||
stbi_uc *cur = filter_buf + (j & 1)*img_width_bytes;
|
||||
stbi_uc *prior = filter_buf + (~j & 1)*img_width_bytes;
|
||||
stbi_uc *dest = a->out + stride*j;
|
||||
int nk = width * filter_bytes;
|
||||
int filter = *raw++;
|
||||
|
||||
if (filter > 4)
|
||||
return stbi__err("invalid filter","Corrupt PNG");
|
||||
|
||||
if (depth < 8) {
|
||||
if (img_width_bytes > x) return stbi__err("invalid width","Corrupt PNG");
|
||||
cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place
|
||||
filter_bytes = 1;
|
||||
width = img_width_bytes;
|
||||
// check filter type
|
||||
if (filter > 4) {
|
||||
all_ok = stbi__err("invalid filter","Corrupt PNG");
|
||||
break;
|
||||
}
|
||||
prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above
|
||||
|
||||
// if first row, use special filter that doesn't sample previous row
|
||||
if (j == 0) filter = first_row_filter[filter];
|
||||
|
||||
// handle first byte explicitly
|
||||
for (k=0; k < filter_bytes; ++k) {
|
||||
switch (filter) {
|
||||
case STBI__F_none : cur[k] = raw[k]; break;
|
||||
case STBI__F_sub : cur[k] = raw[k]; break;
|
||||
case STBI__F_up : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break;
|
||||
case STBI__F_avg : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break;
|
||||
case STBI__F_paeth : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break;
|
||||
case STBI__F_avg_first : cur[k] = raw[k]; break;
|
||||
case STBI__F_paeth_first: cur[k] = raw[k]; break;
|
||||
}
|
||||
// perform actual filtering
|
||||
switch (filter) {
|
||||
case STBI__F_none:
|
||||
memcpy(cur, raw, nk);
|
||||
break;
|
||||
case STBI__F_sub:
|
||||
memcpy(cur, raw, filter_bytes);
|
||||
for (k = filter_bytes; k < nk; ++k)
|
||||
cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]);
|
||||
break;
|
||||
case STBI__F_up:
|
||||
for (k = 0; k < nk; ++k)
|
||||
cur[k] = STBI__BYTECAST(raw[k] + prior[k]);
|
||||
break;
|
||||
case STBI__F_avg:
|
||||
for (k = 0; k < filter_bytes; ++k)
|
||||
cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1));
|
||||
for (k = filter_bytes; k < nk; ++k)
|
||||
cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1));
|
||||
break;
|
||||
case STBI__F_paeth:
|
||||
for (k = 0; k < filter_bytes; ++k)
|
||||
cur[k] = STBI__BYTECAST(raw[k] + prior[k]); // prior[k] == stbi__paeth(0,prior[k],0)
|
||||
for (k = filter_bytes; k < nk; ++k)
|
||||
cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes], prior[k], prior[k-filter_bytes]));
|
||||
break;
|
||||
case STBI__F_avg_first:
|
||||
memcpy(cur, raw, filter_bytes);
|
||||
for (k = filter_bytes; k < nk; ++k)
|
||||
cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1));
|
||||
break;
|
||||
}
|
||||
|
||||
if (depth == 8) {
|
||||
if (img_n != out_n)
|
||||
cur[img_n] = 255; // first pixel
|
||||
raw += img_n;
|
||||
cur += out_n;
|
||||
prior += out_n;
|
||||
} else if (depth == 16) {
|
||||
if (img_n != out_n) {
|
||||
cur[filter_bytes] = 255; // first pixel top byte
|
||||
cur[filter_bytes+1] = 255; // first pixel bottom byte
|
||||
}
|
||||
raw += filter_bytes;
|
||||
cur += output_bytes;
|
||||
prior += output_bytes;
|
||||
} else {
|
||||
raw += 1;
|
||||
cur += 1;
|
||||
prior += 1;
|
||||
}
|
||||
raw += nk;
|
||||
|
||||
// this is a little gross, so that we don't switch per-pixel or per-component
|
||||
if (depth < 8 || img_n == out_n) {
|
||||
int nk = (width - 1)*filter_bytes;
|
||||
#define STBI__CASE(f) \
|
||||
case f: \
|
||||
for (k=0; k < nk; ++k)
|
||||
switch (filter) {
|
||||
// "none" filter turns into a memcpy here; make that explicit.
|
||||
case STBI__F_none: memcpy(cur, raw, nk); break;
|
||||
STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break;
|
||||
STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
|
||||
STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break;
|
||||
STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break;
|
||||
STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break;
|
||||
STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break;
|
||||
}
|
||||
#undef STBI__CASE
|
||||
raw += nk;
|
||||
} else {
|
||||
STBI_ASSERT(img_n+1 == out_n);
|
||||
#define STBI__CASE(f) \
|
||||
case f: \
|
||||
for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \
|
||||
for (k=0; k < filter_bytes; ++k)
|
||||
switch (filter) {
|
||||
STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break;
|
||||
STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break;
|
||||
STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
|
||||
STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break;
|
||||
STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break;
|
||||
STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break;
|
||||
STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break;
|
||||
}
|
||||
#undef STBI__CASE
|
||||
|
||||
// the loop above sets the high byte of the pixels' alpha, but for
|
||||
// 16 bit png files we also need the low byte set. we'll do that here.
|
||||
if (depth == 16) {
|
||||
cur = a->out + stride*j; // start at the beginning of the row again
|
||||
for (i=0; i < x; ++i,cur+=output_bytes) {
|
||||
cur[filter_bytes+1] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we make a separate pass to expand bits to pixels; for performance,
|
||||
// this could run two scanlines behind the above code, so it won't
|
||||
// intefere with filtering but will still be in the cache.
|
||||
if (depth < 8) {
|
||||
for (j=0; j < y; ++j) {
|
||||
stbi_uc *cur = a->out + stride*j;
|
||||
stbi_uc *in = a->out + stride*j + x*out_n - img_width_bytes;
|
||||
// unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit
|
||||
// png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop
|
||||
// expand decoded bits in cur to dest, also adding an extra alpha channel if desired
|
||||
if (depth < 8) {
|
||||
stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range
|
||||
stbi_uc *in = cur;
|
||||
stbi_uc *out = dest;
|
||||
stbi_uc inb = 0;
|
||||
stbi__uint32 nsmp = x*img_n;
|
||||
|
||||
// note that the final byte might overshoot and write more data than desired.
|
||||
// we can allocate enough data that this never writes out of memory, but it
|
||||
// could also overwrite the next scanline. can it overwrite non-empty data
|
||||
// on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel.
|
||||
// so we need to explicitly clamp the final ones
|
||||
|
||||
// expand bits to bytes first
|
||||
if (depth == 4) {
|
||||
for (k=x*img_n; k >= 2; k-=2, ++in) {
|
||||
*cur++ = scale * ((*in >> 4) );
|
||||
*cur++ = scale * ((*in ) & 0x0f);
|
||||
for (i=0; i < nsmp; ++i) {
|
||||
if ((i & 1) == 0) inb = *in++;
|
||||
*out++ = scale * (inb >> 4);
|
||||
inb <<= 4;
|
||||
}
|
||||
if (k > 0) *cur++ = scale * ((*in >> 4) );
|
||||
} else if (depth == 2) {
|
||||
for (k=x*img_n; k >= 4; k-=4, ++in) {
|
||||
*cur++ = scale * ((*in >> 6) );
|
||||
*cur++ = scale * ((*in >> 4) & 0x03);
|
||||
*cur++ = scale * ((*in >> 2) & 0x03);
|
||||
*cur++ = scale * ((*in ) & 0x03);
|
||||
for (i=0; i < nsmp; ++i) {
|
||||
if ((i & 3) == 0) inb = *in++;
|
||||
*out++ = scale * (inb >> 6);
|
||||
inb <<= 2;
|
||||
}
|
||||
if (k > 0) *cur++ = scale * ((*in >> 6) );
|
||||
if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03);
|
||||
if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03);
|
||||
} else if (depth == 1) {
|
||||
for (k=x*img_n; k >= 8; k-=8, ++in) {
|
||||
*cur++ = scale * ((*in >> 7) );
|
||||
*cur++ = scale * ((*in >> 6) & 0x01);
|
||||
*cur++ = scale * ((*in >> 5) & 0x01);
|
||||
*cur++ = scale * ((*in >> 4) & 0x01);
|
||||
*cur++ = scale * ((*in >> 3) & 0x01);
|
||||
*cur++ = scale * ((*in >> 2) & 0x01);
|
||||
*cur++ = scale * ((*in >> 1) & 0x01);
|
||||
*cur++ = scale * ((*in ) & 0x01);
|
||||
} else {
|
||||
STBI_ASSERT(depth == 1);
|
||||
for (i=0; i < nsmp; ++i) {
|
||||
if ((i & 7) == 0) inb = *in++;
|
||||
*out++ = scale * (inb >> 7);
|
||||
inb <<= 1;
|
||||
}
|
||||
if (k > 0) *cur++ = scale * ((*in >> 7) );
|
||||
if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01);
|
||||
if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01);
|
||||
if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01);
|
||||
if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01);
|
||||
if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01);
|
||||
if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01);
|
||||
}
|
||||
if (img_n != out_n) {
|
||||
int q;
|
||||
// insert alpha = 255
|
||||
cur = a->out + stride*j;
|
||||
|
||||
// insert alpha=255 values if desired
|
||||
if (img_n != out_n)
|
||||
stbi__create_png_alpha_expand8(dest, dest, x, img_n);
|
||||
} else if (depth == 8) {
|
||||
if (img_n == out_n)
|
||||
memcpy(dest, cur, x*img_n);
|
||||
else
|
||||
stbi__create_png_alpha_expand8(dest, cur, x, img_n);
|
||||
} else if (depth == 16) {
|
||||
// convert the image data from big-endian to platform-native
|
||||
stbi__uint16 *dest16 = (stbi__uint16*)dest;
|
||||
stbi__uint32 nsmp = x*img_n;
|
||||
|
||||
if (img_n == out_n) {
|
||||
for (i = 0; i < nsmp; ++i, ++dest16, cur += 2)
|
||||
*dest16 = (cur[0] << 8) | cur[1];
|
||||
} else {
|
||||
STBI_ASSERT(img_n+1 == out_n);
|
||||
if (img_n == 1) {
|
||||
for (q=x-1; q >= 0; --q) {
|
||||
cur[q*2+1] = 255;
|
||||
cur[q*2+0] = cur[q];
|
||||
for (i = 0; i < x; ++i, dest16 += 2, cur += 2) {
|
||||
dest16[0] = (cur[0] << 8) | cur[1];
|
||||
dest16[1] = 0xffff;
|
||||
}
|
||||
} else {
|
||||
STBI_ASSERT(img_n == 3);
|
||||
for (q=x-1; q >= 0; --q) {
|
||||
cur[q*4+3] = 255;
|
||||
cur[q*4+2] = cur[q*3+2];
|
||||
cur[q*4+1] = cur[q*3+1];
|
||||
cur[q*4+0] = cur[q*3+0];
|
||||
for (i = 0; i < x; ++i, dest16 += 4, cur += 6) {
|
||||
dest16[0] = (cur[0] << 8) | cur[1];
|
||||
dest16[1] = (cur[2] << 8) | cur[3];
|
||||
dest16[2] = (cur[4] << 8) | cur[5];
|
||||
dest16[3] = 0xffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (depth == 16) {
|
||||
// force the image data from big-endian to platform-native.
|
||||
// this is done in a separate pass due to the decoding relying
|
||||
// on the data being untouched, but could probably be done
|
||||
// per-line during decode if care is taken.
|
||||
stbi_uc *cur = a->out;
|
||||
stbi__uint16 *cur16 = (stbi__uint16*)cur;
|
||||
|
||||
for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) {
|
||||
*cur16 = (cur[0] << 8) | cur[1];
|
||||
}
|
||||
}
|
||||
|
||||
STBI_FREE(filter_buf);
|
||||
if (!all_ok) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -5161,9 +5192,11 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|||
// non-paletted with tRNS = constant alpha. if header-scanning, we can stop now.
|
||||
if (scan == STBI__SCAN_header) { ++s->img_n; return 1; }
|
||||
if (z->depth == 16) {
|
||||
for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
|
||||
for (k = 0; k < s->img_n && k < 3; ++k) // extra loop test to suppress false GCC warning
|
||||
tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
|
||||
} else {
|
||||
for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger
|
||||
for (k = 0; k < s->img_n && k < 3; ++k)
|
||||
tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -5555,7 +5588,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||
|
||||
if (info.hsz == 12) {
|
||||
if (info.bpp < 24)
|
||||
psize = (info.offset - info.extra_read - 24) / 3;
|
||||
psize = (info.offset - info.extra_read - info.hsz) / 3;
|
||||
} else {
|
||||
if (info.bpp < 16)
|
||||
psize = (info.offset - info.extra_read - info.hsz) >> 2;
|
||||
|
@ -5742,7 +5775,7 @@ static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16)
|
|||
switch(bits_per_pixel) {
|
||||
case 8: return STBI_grey;
|
||||
case 16: if(is_grey) return STBI_grey_alpha;
|
||||
// fallthrough
|
||||
STBI_FALLTHROUGH;
|
||||
case 15: if(is_rgb16) *is_rgb16 = 1;
|
||||
return STBI_rgb;
|
||||
case 24: // fallthrough
|
||||
|
@ -5933,7 +5966,10 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
|
|||
for (i=0; i < tga_height; ++i) {
|
||||
int row = tga_inverted ? tga_height -i - 1 : i;
|
||||
stbi_uc *tga_row = tga_data + row*tga_width*tga_comp;
|
||||
stbi__getn(s, tga_row, tga_width * tga_comp);
|
||||
if(!stbi__getn(s, tga_row, tga_width * tga_comp)) {
|
||||
STBI_FREE(tga_data);
|
||||
return stbi__errpuc("bad palette", "Corrupt TGA");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// do I need to load a palette?
|
||||
|
@ -6527,7 +6563,7 @@ static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_c
|
|||
|
||||
if (!stbi__pic_load_core(s,x,y,comp, result)) {
|
||||
STBI_FREE(result);
|
||||
result=0;
|
||||
return 0;
|
||||
}
|
||||
*px = x;
|
||||
*py = y;
|
||||
|
@ -6990,9 +7026,20 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
|
|||
stride = g.w * g.h * 4;
|
||||
|
||||
if (out) {
|
||||
if (stride == 0) {
|
||||
void *ret = stbi__load_gif_main_outofmem(&g, out, delays);
|
||||
return ret;
|
||||
}
|
||||
if (!stbi__mul2sizes_valid(layers, stride)) {
|
||||
void *ret = stbi__load_gif_main_outofmem(&g, out, delays);
|
||||
return ret;
|
||||
}
|
||||
void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride );
|
||||
if (!tmp)
|
||||
return stbi__load_gif_main_outofmem(&g, out, delays);
|
||||
if (!tmp) {
|
||||
void *ret = stbi__load_gif_main_outofmem(&g, out, delays);
|
||||
if (delays && *delays) *delays = 0;
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
out = (stbi_uc*) tmp;
|
||||
out_size = layers * stride;
|
||||
|
@ -7006,9 +7053,16 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
|
|||
delays_size = layers * sizeof(int);
|
||||
}
|
||||
} else {
|
||||
if (!stbi__mul2sizes_valid(layers, stride)) {
|
||||
void *ret = stbi__load_gif_main_outofmem(&g, out, delays);
|
||||
return ret;
|
||||
}
|
||||
out = (stbi_uc*)stbi__malloc( layers * stride );
|
||||
if (!out)
|
||||
return stbi__load_gif_main_outofmem(&g, out, delays);
|
||||
if (!out) {
|
||||
void *ret = stbi__load_gif_main_outofmem(&g, out, delays);
|
||||
if (delays && *delays) *delays = 0;
|
||||
return ret;
|
||||
}
|
||||
out_size = layers * stride;
|
||||
if (delays) {
|
||||
*delays = (int*) stbi__malloc( layers * sizeof(int) );
|
||||
|
@ -7019,7 +7073,7 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
|
|||
}
|
||||
memcpy( out + ((layers - 1) * stride), u, stride );
|
||||
if (layers >= 2) {
|
||||
two_back = out - 2 * stride;
|
||||
two_back = out + (layers - 2) * stride;
|
||||
}
|
||||
|
||||
if (delays) {
|
||||
|
@ -7144,10 +7198,10 @@ static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp)
|
|||
if (req_comp == 4) output[3] = 1;
|
||||
} else {
|
||||
switch (req_comp) {
|
||||
case 4: output[3] = 1; /* fallthrough */
|
||||
case 4: output[3] = 1; STBI_FALLTHROUGH;
|
||||
case 3: output[0] = output[1] = output[2] = 0;
|
||||
break;
|
||||
case 2: output[1] = 1; /* fallthrough */
|
||||
case 2: output[1] = 1; STBI_FALLTHROUGH;
|
||||
case 1: output[0] = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -7218,7 +7272,10 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
|
|||
for (i=0; i < width; ++i) {
|
||||
stbi_uc rgbe[4];
|
||||
main_decode_loop:
|
||||
stbi__getn(s, rgbe, 4);
|
||||
if (!stbi__getn(s, rgbe, 4)) {
|
||||
STBI_FREE(hdr_data);
|
||||
return stbi__errpf("invalid decoded scanline length", "corrupt HDR");
|
||||
}
|
||||
stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp);
|
||||
}
|
||||
}
|
||||
|
@ -7702,9 +7759,10 @@ STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp)
|
|||
int r;
|
||||
stbi__context s;
|
||||
long pos = ftell(f);
|
||||
if (pos < 0) return stbi__err("bad file", "ftell() failed");
|
||||
stbi__start_file(&s, f);
|
||||
r = stbi__info_main(&s,x,y,comp);
|
||||
fseek(f,pos,SEEK_SET);
|
||||
if (fseek(f, pos, SEEK_SET) != 0) return stbi__err("bad file", "fseek() failed");
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -7723,9 +7781,10 @@ STBIDEF int stbi_is_16_bit_from_file(FILE *f)
|
|||
int r;
|
||||
stbi__context s;
|
||||
long pos = ftell(f);
|
||||
if (pos < 0) return stbi__err("bad file", "ftell() failed");
|
||||
stbi__start_file(&s, f);
|
||||
r = stbi__is_16_main(&s);
|
||||
fseek(f,pos,SEEK_SET);
|
||||
if (fseek(f, pos, SEEK_SET) != 0) return stbi__err("bad file", "fseek() failed");
|
||||
return r;
|
||||
}
|
||||
#endif // !STBI_NO_STDIO
|
||||
|
|
5080
src/client/refresh/files/stb_truetype.h
Normal file
5080
src/client/refresh/files/stb_truetype.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -36,7 +36,7 @@ int cur_lm_copy; // which lightmap copy to use (when lightmapcopies=on)
|
|||
|
||||
static GLushort vtx_ptr, idx_ptr; // pointers for array positions in gl_buf
|
||||
|
||||
extern void R_MYgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
|
||||
extern void R_SetPerspective(GLdouble fovy);
|
||||
|
||||
void
|
||||
R_ResetGLBuffer(void)
|
||||
|
@ -50,7 +50,6 @@ R_ApplyGLBuffer(void)
|
|||
// Properties of batched draws here
|
||||
GLint vtx_size;
|
||||
qboolean texture, mtex, alpha, color, alias, texenv_set;
|
||||
float fovy, dist;
|
||||
|
||||
if (vtx_ptr == 0 || idx_ptr == 0)
|
||||
{
|
||||
|
@ -107,9 +106,7 @@ R_ApplyGLBuffer(void)
|
|||
glScalef(-1, 1, 1);
|
||||
}
|
||||
|
||||
fovy = (r_gunfov->value < 0) ? r_newrefdef.fov_y : r_gunfov->value;
|
||||
dist = (r_farsee->value == 0) ? 4096.0f : 8192.0f;
|
||||
R_MYgluPerspective(fovy, (float)r_newrefdef.width / r_newrefdef.height, 4, dist);
|
||||
R_SetPerspective( (r_gunfov->value < 0) ? r_newrefdef.fov_y : r_gunfov->value );
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
|
|
|
@ -25,37 +25,38 @@
|
|||
*/
|
||||
|
||||
#include "header/local.h"
|
||||
#include "../files/stb_truetype.h"
|
||||
|
||||
image_t *draw_chars;
|
||||
static float gl_font_size = 8.0;
|
||||
static int gl_font_height = 128;
|
||||
image_t *draw_chars = NULL;
|
||||
static image_t *draw_font = NULL;
|
||||
static image_t *draw_font_alt = NULL;
|
||||
static stbtt_bakedchar *draw_fontcodes = NULL;
|
||||
|
||||
extern qboolean scrap_dirty;
|
||||
void Scrap_Upload(void);
|
||||
|
||||
extern unsigned r_rawpalette[256];
|
||||
|
||||
void R_LoadTTFFont(const char *ttffont, int vid_height, float *r_font_size,
|
||||
int *r_font_height, stbtt_bakedchar **draw_fontcodes,
|
||||
struct image_s **draw_font, struct image_s **draw_font_alt,
|
||||
loadimage_t R_LoadPic);
|
||||
|
||||
void
|
||||
Draw_InitLocal(void)
|
||||
{
|
||||
/* load console characters */
|
||||
draw_chars = R_FindPic("conchars", (findimage_t)R_FindImage);
|
||||
R_LoadTTFFont(r_ttffont->string, vid.height, &gl_font_size, &gl_font_height,
|
||||
&draw_fontcodes, &draw_font, &draw_font_alt, R_LoadPic);
|
||||
|
||||
/* Anachronox */
|
||||
if (!draw_chars)
|
||||
{
|
||||
draw_chars = R_FindPic ("fonts/conchars", (findimage_t)R_FindImage);
|
||||
}
|
||||
draw_chars = R_LoadConsoleChars((findimage_t)R_FindImage);
|
||||
}
|
||||
|
||||
/* Daikatana */
|
||||
if (!draw_chars)
|
||||
{
|
||||
draw_chars = R_FindPic ("dkchars", (findimage_t)R_FindImage);
|
||||
}
|
||||
|
||||
if (!draw_chars)
|
||||
{
|
||||
Com_Error(ERR_FATAL, "%s: Couldn't load pics/conchars",
|
||||
__func__);
|
||||
}
|
||||
void
|
||||
RDraw_FreeLocal(void)
|
||||
{
|
||||
free(draw_fontcodes);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -88,7 +89,7 @@ RDraw_CharScaled(int x, int y, int num, float scale)
|
|||
fcol = col * 0.0625;
|
||||
size = 0.0625;
|
||||
|
||||
scaledSize = 8*scale;
|
||||
scaledSize = 8 * scale;
|
||||
|
||||
R_UpdateGLBuffer(buf_2d, draw_chars->texnum, 0, 0, 1);
|
||||
|
||||
|
@ -96,6 +97,64 @@ RDraw_CharScaled(int x, int y, int num, float scale)
|
|||
fcol, frow, fcol + size, frow + size);
|
||||
}
|
||||
|
||||
void
|
||||
RDraw_StringScaled(int x, int y, float scale, qboolean alt, const char *message)
|
||||
{
|
||||
while (*message)
|
||||
{
|
||||
unsigned value = R_NextUTF8Code(&message);
|
||||
|
||||
if (draw_fontcodes && (draw_font || draw_font_alt))
|
||||
{
|
||||
float font_scale;
|
||||
|
||||
font_scale = gl_font_size / 8.0;
|
||||
|
||||
if (value >= 32 && value < MAX_FONTCODE)
|
||||
{
|
||||
float xf = 0, yf = 0, xdiff;
|
||||
stbtt_aligned_quad q;
|
||||
|
||||
stbtt_GetBakedQuad(draw_fontcodes, gl_font_height, gl_font_height,
|
||||
value - 32, &xf, &yf, &q, 1);
|
||||
|
||||
xdiff = (8 - xf / font_scale) / 2;
|
||||
if (xdiff < 0)
|
||||
{
|
||||
xdiff = 0;
|
||||
}
|
||||
|
||||
R_UpdateGLBuffer(buf_2d, alt ? draw_font_alt->texnum : draw_font->texnum, 0, 0, 1);
|
||||
|
||||
R_Buffer2DQuad(
|
||||
(float)(x + (xdiff + q.x0 / font_scale) * scale),
|
||||
(float)(y + q.y0 * scale / font_scale + 8 * scale),
|
||||
x + (xdiff + q.x1 / font_scale) * scale,
|
||||
y + q.y1 * scale / font_scale + 8 * scale,
|
||||
q.s0, q.t0, q.s1, q.t1);
|
||||
x += Q_max(8, xf / font_scale) * scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
x += 8 * scale;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int xor;
|
||||
|
||||
xor = alt ? 0x80 : 0;
|
||||
|
||||
if (value > ' ' && value < 128)
|
||||
{
|
||||
RDraw_CharScaled(x, y, value ^ xor, scale);
|
||||
}
|
||||
|
||||
x += 8 * scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
image_t *
|
||||
RDraw_FindPic(const char *name)
|
||||
{
|
||||
|
@ -165,7 +224,7 @@ RDraw_StretchPic(int x, int y, int w, int h, const char *pic)
|
|||
}
|
||||
|
||||
void
|
||||
RDraw_PicScaled(int x, int y, const char *pic, float factor)
|
||||
RDraw_PicScaled(int x, int y, const char *pic, float factor, const char *alttext)
|
||||
{
|
||||
image_t *gl;
|
||||
|
||||
|
@ -173,6 +232,13 @@ RDraw_PicScaled(int x, int y, const char *pic, float factor)
|
|||
|
||||
if (!gl)
|
||||
{
|
||||
if (alttext && alttext[0])
|
||||
{
|
||||
/* Show alttext if provided */
|
||||
RDraw_StringScaled(x, y, factor, false, alttext);
|
||||
return;
|
||||
}
|
||||
|
||||
R_Printf(PRINT_ALL, "Can't find pic: %s\n", pic);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -471,7 +471,7 @@ R_ImageList_f(void)
|
|||
/*
|
||||
* Fill background pixels so mipmapping doesn't have haloes
|
||||
*/
|
||||
void
|
||||
static void
|
||||
R_FloodFillSkin(byte *skin, int skinwidth, int skinheight)
|
||||
{
|
||||
byte fillcolor = *skin; /* assume this is the pixel to fill */
|
||||
|
@ -537,7 +537,7 @@ R_FloodFillSkin(byte *skin, int skinwidth, int skinheight)
|
|||
* texture to increase the
|
||||
* lighting range
|
||||
*/
|
||||
void
|
||||
static void
|
||||
R_LightScaleTexture(unsigned *in, int inwidth,
|
||||
int inheight, qboolean only_gamma)
|
||||
{
|
||||
|
@ -578,7 +578,7 @@ R_LightScaleTexture(unsigned *in, int inwidth,
|
|||
/*
|
||||
* Operates in place, quartering the size of the texture
|
||||
*/
|
||||
void
|
||||
static void
|
||||
R_MipMap(byte *in, int width, int height)
|
||||
{
|
||||
int i, j;
|
||||
|
@ -603,7 +603,7 @@ R_MipMap(byte *in, int width, int height)
|
|||
/*
|
||||
* Returns has_alpha
|
||||
*/
|
||||
void
|
||||
static void
|
||||
R_BuildPalettedTexture(unsigned char *paletted_texture, unsigned char *scaled,
|
||||
int scaled_width, int scaled_height)
|
||||
{
|
||||
|
@ -625,7 +625,7 @@ R_BuildPalettedTexture(unsigned char *paletted_texture, unsigned char *scaled,
|
|||
}
|
||||
}
|
||||
|
||||
qboolean
|
||||
static qboolean
|
||||
R_Upload32Native(unsigned *data, int width, int height, qboolean mipmap)
|
||||
{
|
||||
// This is for GL 2.x so no palettes, no scaling, no messing around with the data here. :)
|
||||
|
@ -661,7 +661,7 @@ R_Upload32Native(unsigned *data, int width, int height, qboolean mipmap)
|
|||
}
|
||||
|
||||
|
||||
qboolean
|
||||
static qboolean
|
||||
R_Upload32Soft(unsigned *data, int width, int height, qboolean mipmap)
|
||||
{
|
||||
int samples;
|
||||
|
@ -1139,42 +1139,41 @@ R_LoadPic(const char *name, byte *pic, int width, int realwidth,
|
|||
* Finds or loads the given image or null
|
||||
*/
|
||||
image_t *
|
||||
R_FindImage(const char *name, imagetype_t type)
|
||||
R_FindImage(const char *originname, imagetype_t type)
|
||||
{
|
||||
image_t *image;
|
||||
int i, len;
|
||||
char *ptr;
|
||||
char namewe[256];
|
||||
char namewe[256], name[256] = {0};
|
||||
const char* ext;
|
||||
image_t *image;
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
if (!name)
|
||||
if (!originname)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Q_strlcpy(name, originname, sizeof(name));
|
||||
|
||||
/* fix backslashes */
|
||||
Q_replacebackslash(name);
|
||||
|
||||
ext = COM_FileExtension(name);
|
||||
if(!ext[0])
|
||||
if (!ext[0])
|
||||
{
|
||||
/* file has no extension */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = strlen(name);
|
||||
|
||||
/* Remove the extension */
|
||||
memset(namewe, 0, 256);
|
||||
memcpy(namewe, name, len - (strlen(ext) + 1));
|
||||
|
||||
if (len < 5)
|
||||
len = (ext - name) - 1;
|
||||
if ((len < 1) || (len > sizeof(namewe) - 1))
|
||||
{
|
||||
Com_DPrintf("%s: Bad filename %s\n", __func__, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* fix backslashes */
|
||||
while ((ptr = strchr(name, '\\')))
|
||||
{
|
||||
*ptr = '/';
|
||||
}
|
||||
memcpy(namewe, name, len);
|
||||
namewe[len] = 0;
|
||||
|
||||
/* look for it */
|
||||
for (i = 0, image = gltextures; i < numgltextures; i++, image++)
|
||||
|
|
|
@ -101,6 +101,7 @@ cvar_t *gl_shadows;
|
|||
cvar_t *gl1_stencilshadow;
|
||||
cvar_t *r_mode;
|
||||
cvar_t *r_fixsurfsky;
|
||||
cvar_t *r_ttffont;
|
||||
|
||||
cvar_t *r_customwidth;
|
||||
cvar_t *r_customheight;
|
||||
|
@ -144,6 +145,7 @@ cvar_t *gl1_stereo_separation;
|
|||
cvar_t *gl1_stereo_anaglyph_colors;
|
||||
cvar_t *gl1_stereo_convergence;
|
||||
|
||||
static cvar_t *gl1_waterwarp;
|
||||
|
||||
refimport_t ri;
|
||||
|
||||
|
@ -151,6 +153,7 @@ void LM_FreeLightmapBuffers(void);
|
|||
void Scrap_Free(void);
|
||||
void Scrap_Init(void);
|
||||
|
||||
extern void R_SetDefaultState(void);
|
||||
extern void R_ResetGLBuffer(void);
|
||||
|
||||
void
|
||||
|
@ -635,6 +638,19 @@ R_PolyBlend(void)
|
|||
glColor4f(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
R_ResetClearColor(void)
|
||||
{
|
||||
if (gl1_discardfb->value == 1 && !r_clear->value)
|
||||
{
|
||||
glClearColor(0, 0, 0, 0.5);
|
||||
}
|
||||
else
|
||||
{
|
||||
glClearColor(1, 0, 0.5, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_SetupFrame(void)
|
||||
{
|
||||
|
@ -712,25 +728,41 @@ R_SetupFrame(void)
|
|||
vid.height - r_newrefdef.height - r_newrefdef.y,
|
||||
r_newrefdef.width, r_newrefdef.height);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClearColor(1, 0, 0.5, 0.5);
|
||||
R_ResetClearColor();
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
R_MYgluPerspective(GLdouble fovy, GLdouble aspect,
|
||||
GLdouble zNear, GLdouble zFar)
|
||||
R_SetPerspective(GLdouble fovy)
|
||||
{
|
||||
// gluPerspective style parameters
|
||||
static const GLdouble zNear = 4;
|
||||
const GLdouble zFar = (r_farsee->value) ? 8192.0f : 4096.0f;
|
||||
const GLdouble aspectratio = (GLdouble)r_newrefdef.width / r_newrefdef.height;
|
||||
|
||||
GLdouble xmin, xmax, ymin, ymax;
|
||||
|
||||
// traditional gluPerspective calculations - https://youtu.be/YqSNGcF5nvM?t=644
|
||||
ymax = zNear * tan(fovy * M_PI / 360.0);
|
||||
xmax = ymax * aspectratio;
|
||||
|
||||
if ((r_newrefdef.rdflags & RDF_UNDERWATER) && gl1_waterwarp->value)
|
||||
{
|
||||
const GLdouble warp = sin(r_newrefdef.time * 1.5) * 0.03 * gl1_waterwarp->value;
|
||||
ymax *= 1.0 - warp;
|
||||
xmax *= 1.0 + warp;
|
||||
}
|
||||
|
||||
ymin = -ymax;
|
||||
xmin = -xmax;
|
||||
|
||||
xmin = ymin * aspect;
|
||||
xmax = ymax * aspect;
|
||||
|
||||
xmin += - gl1_stereo_convergence->value * (2 * gl_state.camera_separation) / zNear;
|
||||
xmax += - gl1_stereo_convergence->value * (2 * gl_state.camera_separation) / zNear;
|
||||
if (gl_state.camera_separation)
|
||||
{
|
||||
const GLdouble separation = - gl1_stereo_convergence->value * (2 * gl_state.camera_separation) / zNear;
|
||||
xmin += separation;
|
||||
xmax += separation;
|
||||
}
|
||||
|
||||
glFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
|
||||
}
|
||||
|
@ -738,7 +770,6 @@ R_MYgluPerspective(GLdouble fovy, GLdouble aspect,
|
|||
void
|
||||
R_SetupGL(void)
|
||||
{
|
||||
float screenaspect;
|
||||
int x, x2, y2, y, w, h;
|
||||
|
||||
/* set up viewport */
|
||||
|
@ -768,18 +799,10 @@ R_SetupGL(void)
|
|||
glViewport(x, y2, w, h);
|
||||
|
||||
/* set up projection matrix */
|
||||
screenaspect = (float)r_newrefdef.width / r_newrefdef.height;
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
if (r_farsee->value == 0)
|
||||
{
|
||||
R_MYgluPerspective(r_newrefdef.fov_y, screenaspect, 4, 4096);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_MYgluPerspective(r_newrefdef.fov_y, screenaspect, 4, 8192);
|
||||
}
|
||||
R_SetPerspective(r_newrefdef.fov_y);
|
||||
|
||||
glCullFace(GL_FRONT);
|
||||
|
||||
|
@ -814,53 +837,72 @@ R_SetupGL(void)
|
|||
void
|
||||
R_Clear(void)
|
||||
{
|
||||
// Check whether the stencil buffer needs clearing, and do so if need be.
|
||||
GLbitfield stencilFlags = 0;
|
||||
if (gl_state.stereo_mode >= STEREO_MODE_ROW_INTERLEAVED && gl_state.stereo_mode <= STEREO_MODE_PIXEL_INTERLEAVED) {
|
||||
glClearStencil(GL_FALSE);
|
||||
stencilFlags |= GL_STENCIL_BUFFER_BIT;
|
||||
// Define which buffers need clearing
|
||||
GLbitfield clearFlags = 0;
|
||||
GLenum depthFunc = GL_LEQUAL;
|
||||
|
||||
// This breaks stereo modes, but we'll leave that responsibility to the user
|
||||
if (r_clear->value)
|
||||
{
|
||||
clearFlags |= GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
|
||||
// No stencil shadows allowed when using certain stereo modes, otherwise "wallhack" happens
|
||||
if (gl_state.stereo_mode >= STEREO_MODE_ROW_INTERLEAVED && gl_state.stereo_mode <= STEREO_MODE_PIXEL_INTERLEAVED)
|
||||
{
|
||||
glClearStencil(0);
|
||||
clearFlags |= GL_STENCIL_BUFFER_BIT;
|
||||
}
|
||||
else if (gl_shadows->value && gl_state.stencil && gl1_stencilshadow->value)
|
||||
{
|
||||
glClearStencil(1);
|
||||
clearFlags |= GL_STENCIL_BUFFER_BIT;
|
||||
}
|
||||
|
||||
if (gl1_ztrick->value)
|
||||
{
|
||||
static int trickframe;
|
||||
|
||||
if (r_clear->value)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | stencilFlags);
|
||||
}
|
||||
|
||||
trickframe++;
|
||||
|
||||
if (trickframe & 1)
|
||||
{
|
||||
gldepthmin = 0;
|
||||
gldepthmax = 0.49999;
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
gldepthmin = 1;
|
||||
gldepthmax = 0.5;
|
||||
glDepthFunc(GL_GEQUAL);
|
||||
depthFunc = GL_GEQUAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (r_clear->value)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | stencilFlags | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
glClear(GL_DEPTH_BUFFER_BIT | stencilFlags);
|
||||
}
|
||||
clearFlags |= GL_DEPTH_BUFFER_BIT;
|
||||
|
||||
gldepthmin = 0;
|
||||
gldepthmax = 1;
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
}
|
||||
|
||||
switch ((int)gl1_discardfb->value)
|
||||
{
|
||||
case 1:
|
||||
if (gl_state.stereo_mode == STEREO_MODE_NONE)
|
||||
{
|
||||
clearFlags |= GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
case 2:
|
||||
clearFlags |= GL_STENCIL_BUFFER_BIT;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (clearFlags)
|
||||
{
|
||||
glClear(clearFlags);
|
||||
}
|
||||
glDepthFunc(depthFunc);
|
||||
glDepthRange(gldepthmin, gldepthmax);
|
||||
|
||||
if (gl_zfix->value)
|
||||
|
@ -874,13 +916,6 @@ R_Clear(void)
|
|||
glPolygonOffset(-0.05, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/* stencilbuffer shadows */
|
||||
if (gl_shadows->value && gl_state.stencil && gl1_stencilshadow->value)
|
||||
{
|
||||
glClearStencil(GL_TRUE);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -932,7 +967,6 @@ R_SetGL2D(void)
|
|||
static void
|
||||
R_RenderView(const refdef_t *fd)
|
||||
{
|
||||
#ifndef YQ2_GL1_GLES
|
||||
if ((gl_state.stereo_mode != STEREO_MODE_NONE) && gl_state.camera_separation) {
|
||||
|
||||
qboolean drawing_left_eye = gl_state.camera_separation < 0;
|
||||
|
@ -982,6 +1016,13 @@ R_RenderView(const refdef_t *fd)
|
|||
qboolean flip_eyes = true;
|
||||
int client_x, client_y;
|
||||
|
||||
GLshort screen[] = {
|
||||
0, 0,
|
||||
(GLshort)vid.width, 0,
|
||||
(GLshort)vid.width, (GLshort)vid.height,
|
||||
0, (GLshort)vid.height
|
||||
};
|
||||
|
||||
//GLimp_GetClientAreaOffset(&client_x, &client_y);
|
||||
client_x = 0;
|
||||
client_y = 0;
|
||||
|
@ -989,47 +1030,53 @@ R_RenderView(const refdef_t *fd)
|
|||
R_SetGL2D();
|
||||
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilMask(GL_TRUE);
|
||||
glStencilMask(1);
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
|
||||
glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
|
||||
glStencilFunc(GL_NEVER, 0, 1);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
{
|
||||
glVertex2i(0, 0);
|
||||
glVertex2i(vid.width, 0);
|
||||
glVertex2i(vid.width, vid.height);
|
||||
glVertex2i(0, vid.height);
|
||||
}
|
||||
glEnd();
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(2, GL_SHORT, 0, screen);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
glStencilOp(GL_INVERT, GL_KEEP, GL_KEEP);
|
||||
glStencilFunc(GL_NEVER, 1, 1);
|
||||
|
||||
glBegin(GL_LINES);
|
||||
if (gl_state.stereo_mode == STEREO_MODE_ROW_INTERLEAVED || gl_state.stereo_mode == STEREO_MODE_PIXEL_INTERLEAVED)
|
||||
{
|
||||
if (gl_state.stereo_mode == STEREO_MODE_ROW_INTERLEAVED || gl_state.stereo_mode == STEREO_MODE_PIXEL_INTERLEAVED) {
|
||||
int y;
|
||||
for (y = 0; y <= vid.height; y += 2) {
|
||||
glVertex2f(0, y - 0.5f);
|
||||
glVertex2f(vid.width, y - 0.5f);
|
||||
}
|
||||
flip_eyes ^= (client_y & 1);
|
||||
}
|
||||
|
||||
if (gl_state.stereo_mode == STEREO_MODE_COLUMN_INTERLEAVED || gl_state.stereo_mode == STEREO_MODE_PIXEL_INTERLEAVED) {
|
||||
int x;
|
||||
for (x = 0; x <= vid.width; x += 2) {
|
||||
glVertex2f(x - 0.5f, 0);
|
||||
glVertex2f(x - 0.5f, vid.height);
|
||||
}
|
||||
flip_eyes ^= (client_x & 1);
|
||||
for (int y = 0; y <= vid.height; y += 2)
|
||||
{
|
||||
gl_buf.vtx[gl_buf.vt ] = 0;
|
||||
gl_buf.vtx[gl_buf.vt + 1] = y - 0.5f;
|
||||
gl_buf.vtx[gl_buf.vt + 2] = vid.width;
|
||||
gl_buf.vtx[gl_buf.vt + 3] = y - 0.5f;
|
||||
gl_buf.vt += 4;
|
||||
}
|
||||
flip_eyes ^= (client_y & 1);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glStencilMask(GL_FALSE);
|
||||
if (gl_state.stereo_mode == STEREO_MODE_COLUMN_INTERLEAVED || gl_state.stereo_mode == STEREO_MODE_PIXEL_INTERLEAVED)
|
||||
{
|
||||
for (int x = 0; x <= vid.width; x += 2)
|
||||
{
|
||||
gl_buf.vtx[gl_buf.vt ] = x - 0.5f;
|
||||
gl_buf.vtx[gl_buf.vt + 1] = 0;
|
||||
gl_buf.vtx[gl_buf.vt + 2] = x - 0.5f;
|
||||
gl_buf.vtx[gl_buf.vt + 3] = vid.height;
|
||||
gl_buf.vt += 4;
|
||||
}
|
||||
flip_eyes ^= (client_x & 1);
|
||||
}
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(2, GL_FLOAT, 0, gl_buf.vtx);
|
||||
glDrawArrays(GL_LINES, 0, gl_buf.vt / 2);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
gl_buf.vt = 0;
|
||||
|
||||
glStencilMask(0);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
||||
glStencilFunc(GL_EQUAL, drawing_left_eye ^ flip_eyes, 1);
|
||||
|
@ -1040,7 +1087,6 @@ R_RenderView(const refdef_t *fd)
|
|||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (r_norefresh->value)
|
||||
{
|
||||
|
@ -1182,9 +1228,9 @@ RI_RenderFrame(refdef_t *fd)
|
|||
}
|
||||
|
||||
#ifdef YQ2_GL1_GLES
|
||||
#define DEFAULT_LMCOPIES "1"
|
||||
#define GLES1_ENABLED_ONLY "1"
|
||||
#else
|
||||
#define DEFAULT_LMCOPIES "0"
|
||||
#define GLES1_ENABLED_ONLY "0"
|
||||
#endif
|
||||
|
||||
void
|
||||
|
@ -1235,6 +1281,8 @@ R_Register(void)
|
|||
gl_polyblend = ri.Cvar_Get("gl_polyblend", "1", 0);
|
||||
r_flashblend = ri.Cvar_Get("r_flashblend", "0", 0);
|
||||
r_fixsurfsky = ri.Cvar_Get("r_fixsurfsky", "0", CVAR_ARCHIVE);
|
||||
/* font should looks good with 8 pixels size */
|
||||
r_ttffont = ri.Cvar_Get("r_ttffont", "RussoOne-Regular", CVAR_ARCHIVE);
|
||||
|
||||
gl_texturemode = ri.Cvar_Get("gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE);
|
||||
gl1_texturealphamode = ri.Cvar_Get("gl1_texturealphamode", "default", CVAR_ARCHIVE);
|
||||
|
@ -1245,10 +1293,8 @@ R_Register(void)
|
|||
gl1_palettedtexture = ri.Cvar_Get("r_palettedtextures", "0", CVAR_ARCHIVE);
|
||||
gl1_pointparameters = ri.Cvar_Get("gl1_pointparameters", "1", CVAR_ARCHIVE);
|
||||
gl1_multitexture = ri.Cvar_Get("gl1_multitexture", "1", CVAR_ARCHIVE);
|
||||
gl1_lightmapcopies = ri.Cvar_Get("gl1_lightmapcopies", DEFAULT_LMCOPIES, CVAR_ARCHIVE);
|
||||
#ifdef YQ2_GL1_GLES
|
||||
gl1_discardfb = ri.Cvar_Get("gl1_discardfb", "1", CVAR_ARCHIVE);
|
||||
#endif
|
||||
gl1_lightmapcopies = ri.Cvar_Get("gl1_lightmapcopies", GLES1_ENABLED_ONLY, CVAR_ARCHIVE);
|
||||
gl1_discardfb = ri.Cvar_Get("gl1_discardfb", GLES1_ENABLED_ONLY, CVAR_ARCHIVE);
|
||||
|
||||
gl_drawbuffer = ri.Cvar_Get("gl_drawbuffer", "GL_BACK", 0);
|
||||
r_vsync = ri.Cvar_Get("r_vsync", "1", CVAR_ARCHIVE);
|
||||
|
@ -1280,13 +1326,15 @@ R_Register(void)
|
|||
gl1_stereo_anaglyph_colors = ri.Cvar_Get( "gl1_stereo_anaglyph_colors", "rc", CVAR_ARCHIVE );
|
||||
gl1_stereo_convergence = ri.Cvar_Get( "gl1_stereo_convergence", "1", CVAR_ARCHIVE );
|
||||
|
||||
gl1_waterwarp = ri.Cvar_Get( "gl1_waterwarp", "1.0", CVAR_ARCHIVE );
|
||||
|
||||
ri.Cmd_AddCommand("imagelist", R_ImageList_f);
|
||||
ri.Cmd_AddCommand("screenshot", R_ScreenShot);
|
||||
ri.Cmd_AddCommand("modellist", Mod_Modellist_f);
|
||||
ri.Cmd_AddCommand("gl_strings", R_Strings);
|
||||
}
|
||||
|
||||
#undef DEFAULT_LMCOPIES
|
||||
#undef GLES1_ENABLED_ONLY
|
||||
|
||||
/*
|
||||
* Changes the video mode
|
||||
|
@ -1689,28 +1737,28 @@ RI_Init(void)
|
|||
|
||||
// ----
|
||||
|
||||
/* Discard framebuffer: Available only on GLES1, enables the use of a "performance hint"
|
||||
* to the graphic driver, to get rid of the contents of the depth and stencil buffers.
|
||||
/* Discard framebuffer: Enables the use of a "performance hint" to the graphic
|
||||
* driver in GLES1, to get rid of the contents of the different framebuffers.
|
||||
* Useful for some GPUs that may attempt to keep them and/or write them back to
|
||||
* external/uniform memory, actions that are useless for Quake 2 rendering path.
|
||||
* https://registry.khronos.org/OpenGL/extensions/EXT/EXT_discard_framebuffer.txt
|
||||
* This extension is used by 'gl1_discardfb', and regardless of its existence,
|
||||
* that cvar will enable glClear at the start of each frame, helping mobile GPUs.
|
||||
*/
|
||||
gl_config.discardfb = false;
|
||||
|
||||
#ifdef YQ2_GL1_GLES
|
||||
R_Printf(PRINT_ALL, " - Discard framebuffer: ");
|
||||
|
||||
if (strstr(gl_config.extensions_string, "GL_EXT_discard_framebuffer"))
|
||||
{
|
||||
qglDiscardFramebufferEXT = (void (APIENTRY *)(GLenum, GLsizei, const GLenum *))
|
||||
RI_GetProcAddress ("glDiscardFramebufferEXT");
|
||||
qglDiscardFramebufferEXT = (void (APIENTRY *)(GLenum, GLsizei, const GLenum *))
|
||||
RI_GetProcAddress ("glDiscardFramebufferEXT");
|
||||
}
|
||||
|
||||
if (gl1_discardfb->value)
|
||||
{
|
||||
if (qglDiscardFramebufferEXT)
|
||||
if (qglDiscardFramebufferEXT) // enough to verify availability
|
||||
{
|
||||
gl_config.discardfb = true;
|
||||
R_Printf(PRINT_ALL, "Okay\n");
|
||||
}
|
||||
else
|
||||
|
@ -1740,6 +1788,7 @@ RI_Init(void)
|
|||
|
||||
// ----
|
||||
|
||||
R_ResetClearColor();
|
||||
R_SetDefaultState();
|
||||
|
||||
R_VertBufferInit();
|
||||
|
@ -1766,6 +1815,7 @@ RI_Shutdown(void)
|
|||
Mod_FreeAll();
|
||||
|
||||
R_ShutdownImages();
|
||||
RDraw_FreeLocal();
|
||||
|
||||
R_VertBufferFree();
|
||||
|
||||
|
@ -1789,17 +1839,17 @@ RI_BeginFrame(float camera_separation)
|
|||
gl_state.camera_separation = camera_separation;
|
||||
|
||||
// force a vid_restart if gl1_stereo has been modified.
|
||||
if ( gl_state.stereo_mode != gl1_stereo->value ) {
|
||||
if ( gl_state.stereo_mode != gl1_stereo->value )
|
||||
{
|
||||
// If we've gone from one mode to another with the same special buffer requirements there's no need to restart.
|
||||
if ( GL_GetSpecialBufferModeForStereoMode( gl_state.stereo_mode ) == GL_GetSpecialBufferModeForStereoMode( gl1_stereo->value ) ) {
|
||||
if ( GL_GetSpecialBufferModeForStereoMode( gl_state.stereo_mode ) == GL_GetSpecialBufferModeForStereoMode( gl1_stereo->value ) )
|
||||
{
|
||||
gl_state.stereo_mode = gl1_stereo->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
R_Printf(PRINT_ALL, "stereo supermode changed, restarting video!\n");
|
||||
cvar_t *ref;
|
||||
ref = ri.Cvar_Get("vid_fullscreen", "0", CVAR_ARCHIVE);
|
||||
ref->modified = true;
|
||||
ri.Cmd_ExecuteText(EXEC_APPEND, "vid_restart\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1894,12 +1944,12 @@ RI_BeginFrame(float camera_separation)
|
|||
gl1_particle_square->modified = false;
|
||||
}
|
||||
|
||||
#ifndef YQ2_GL1_GLES
|
||||
/* draw buffer stuff */
|
||||
if (gl_drawbuffer->modified)
|
||||
{
|
||||
gl_drawbuffer->modified = false;
|
||||
|
||||
#ifndef YQ2_GL1_GLES
|
||||
if ((gl_state.camera_separation == 0) || gl_state.stereo_mode != STEREO_MODE_OPENGL)
|
||||
{
|
||||
if (Q_stricmp(gl_drawbuffer->string, "GL_FRONT") == 0)
|
||||
|
@ -1911,8 +1961,8 @@ RI_BeginFrame(float camera_separation)
|
|||
glDrawBuffer(GL_BACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* texturemode stuff */
|
||||
if (gl_texturemode->modified || (gl_config.anisotropic && gl_anisotropic->modified)
|
||||
|
@ -1982,7 +2032,7 @@ RI_SetPalette(const unsigned char *palette)
|
|||
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(1, 0, 0.5, 0.5);
|
||||
R_ResetClearColor();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2119,6 +2169,7 @@ GetRefAPI(refimport_t imp)
|
|||
refexport.DrawPicScaled = RDraw_PicScaled;
|
||||
refexport.DrawStretchPic = RDraw_StretchPic;
|
||||
refexport.DrawCharScaled = RDraw_CharScaled;
|
||||
refexport.DrawStringScaled = RDraw_StringScaled;
|
||||
refexport.DrawTileClear = RDraw_TileClear;
|
||||
refexport.DrawFill = RDraw_Fill;
|
||||
refexport.DrawFadeScreen = RDraw_FadeScreen;
|
||||
|
@ -2171,6 +2222,15 @@ Com_Printf(const char *msg, ...)
|
|||
va_end(argptr);
|
||||
}
|
||||
|
||||
void
|
||||
Com_DPrintf(const char *msg, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
va_start(argptr, msg);
|
||||
ri.Com_VPrintf(PRINT_DEVELOPER, msg, argptr);
|
||||
va_end(argptr);
|
||||
}
|
||||
|
||||
void
|
||||
Com_Error(int code, const char *fmt, ...)
|
||||
{
|
||||
|
|
|
@ -174,13 +174,18 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdx_t *paliashdr, float backlerp,
|
|||
lerp = s_lerped[0];
|
||||
|
||||
R_LerpVerts(colorOnly, paliashdr->num_xyz, verts, ov, lerp,
|
||||
move, frontv, backv);
|
||||
move, frontv, backv, currententity->scale);
|
||||
|
||||
num_mesh_nodes = paliashdr->num_meshes;
|
||||
mesh_nodes = (dmdxmesh_t *)((char*)paliashdr + paliashdr->ofs_meshes);
|
||||
|
||||
for (i = 0; i < num_mesh_nodes; i++)
|
||||
{
|
||||
if (currententity->rr_mesh & (1 << i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
R_DrawAliasDrawCommands(currententity,
|
||||
order + mesh_nodes[i].ofs_glcmds,
|
||||
order + Q_min(paliashdr->num_glcmds,
|
||||
|
@ -237,6 +242,10 @@ static void
|
|||
R_DrawAliasShadow(entity_t *currententity, dmdx_t *paliashdr, int posenum,
|
||||
vec4_t *s_lerped, vec3_t shadevector)
|
||||
{
|
||||
// Don't do stencil test on unsupported stereo modes
|
||||
const qboolean stencilt = ( gl_state.stencil && gl1_stencilshadow->value &&
|
||||
( gl_state.stereo_mode < STEREO_MODE_ROW_INTERLEAVED
|
||||
|| gl_state.stereo_mode > STEREO_MODE_PIXEL_INTERLEAVED ) );
|
||||
int *order, i, num_mesh_nodes;
|
||||
float height = 0, lheight;
|
||||
dmdxmesh_t *mesh_nodes;
|
||||
|
@ -248,7 +257,7 @@ R_DrawAliasShadow(entity_t *currententity, dmdx_t *paliashdr, int posenum,
|
|||
R_UpdateGLBuffer(buf_shadow, 0, 0, 0, 1);
|
||||
|
||||
/* stencilbuffer shadows */
|
||||
if (gl_state.stencil && gl1_stencilshadow->value)
|
||||
if (stencilt)
|
||||
{
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilFunc(GL_EQUAL, 1, 2);
|
||||
|
@ -270,7 +279,7 @@ R_DrawAliasShadow(entity_t *currententity, dmdx_t *paliashdr, int posenum,
|
|||
R_ApplyGLBuffer();
|
||||
|
||||
/* stencilbuffer shadows */
|
||||
if (gl_state.stencil && gl1_stencilshadow->value)
|
||||
if (stencilt)
|
||||
{
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
|
@ -334,6 +343,15 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
/* fix scale */
|
||||
if (!currententity->scale[i])
|
||||
{
|
||||
currententity->scale[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
paliashdr = (dmdx_t *)currentmodel->extradata;
|
||||
|
||||
/* get lighting information */
|
||||
|
|
|
@ -169,7 +169,6 @@ R_Strings(void)
|
|||
void
|
||||
R_SetDefaultState(void)
|
||||
{
|
||||
glClearColor(1, 0, 0.5, 0.5);
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
glCullFace(GL_FRONT);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
|
||||
#include "header/local.h"
|
||||
|
||||
static YQ2_ALIGNAS_TYPE(int) byte mod_novis[MAX_MAP_LEAFS / 8];
|
||||
static byte *mod_novis = NULL;
|
||||
static size_t mod_novis_len = 0;
|
||||
|
||||
static model_t mod_known[MAX_MOD_KNOWN];
|
||||
static int mod_numknown = 0;
|
||||
|
@ -65,15 +66,34 @@ Mod_HasFreeSpace(void)
|
|||
const byte *
|
||||
Mod_ClusterPVS(int cluster, const model_t *model)
|
||||
{
|
||||
if ((cluster == -1) || !model->vis)
|
||||
if (!mod_novis)
|
||||
{
|
||||
Com_Error(ERR_DROP, "%s: incrorrect init of PVS/PHS", __func__);
|
||||
}
|
||||
|
||||
if (!model->vis)
|
||||
{
|
||||
Mod_DecompressVis(NULL, mod_novis, NULL,
|
||||
(model->numclusters + 7) >> 3);
|
||||
return mod_novis;
|
||||
}
|
||||
|
||||
return Mod_DecompressVis((byte *)model->vis +
|
||||
model->vis->bitofs[cluster][DVIS_PVS],
|
||||
if (cluster == -1)
|
||||
{
|
||||
memset(mod_novis, 0, (model->numclusters + 7) >> 3);
|
||||
return mod_novis;
|
||||
}
|
||||
|
||||
if (cluster < 0 || cluster >= model->numvisibility)
|
||||
{
|
||||
Com_Error(ERR_DROP, "%s: bad cluster", __func__);
|
||||
}
|
||||
|
||||
Mod_DecompressVis((byte *)model->vis +
|
||||
model->vis->bitofs[cluster][DVIS_PVS], mod_novis,
|
||||
(byte *)model->vis + model->numvisibility,
|
||||
(model->vis->numclusters + 7) >> 3);
|
||||
(model->numclusters + 7) >> 3);
|
||||
return mod_novis;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -117,7 +137,8 @@ void
|
|||
Mod_Init(void)
|
||||
{
|
||||
mod_max = 0;
|
||||
memset(mod_novis, 0xff, sizeof(mod_novis));
|
||||
mod_novis = NULL;
|
||||
mod_novis_len = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -362,33 +383,28 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen)
|
|||
Mod_LoadVisibility(mod->name, &mod->vis, &mod->numvisibility, mod_base,
|
||||
&header->lumps[LUMP_VISIBILITY]);
|
||||
Mod_LoadQBSPLeafs(mod->name, &mod->leafs, &mod->numleafs,
|
||||
mod->marksurfaces, mod->nummarksurfaces, mod_base,
|
||||
&header->lumps[LUMP_LEAFS]);
|
||||
mod->marksurfaces, mod->nummarksurfaces, &mod->numclusters,
|
||||
mod_base, &header->lumps[LUMP_LEAFS]);
|
||||
Mod_LoadQBSPNodes(mod->name, mod->planes, mod->numplanes, mod->leafs,
|
||||
mod->numleafs, &mod->nodes, &mod->numnodes, mod_base,
|
||||
&header->lumps[LUMP_NODES], header->ident);
|
||||
mod->numleafs, &mod->nodes, &mod->numnodes, mod->mins, mod->maxs,
|
||||
mod_base, &header->lumps[LUMP_NODES], header->ident);
|
||||
Mod_LoadSubmodels(mod, mod_base, &header->lumps[LUMP_MODELS]);
|
||||
mod->numframes = 2; /* regular and alternate animation */
|
||||
}
|
||||
|
||||
/* Temporary solution, need to use load file dirrectly */
|
||||
static int
|
||||
Mod_ReadFile(const char *path, void **buffer)
|
||||
{
|
||||
char *data;
|
||||
int size;
|
||||
|
||||
size = ri.FS_LoadFile(path, (void **)&data);
|
||||
if (size <= 0)
|
||||
if (mod->vis && mod->numclusters != mod->vis->numclusters)
|
||||
{
|
||||
return size;
|
||||
Com_Error(ERR_DROP, "%s: Map %s has incorrect number of clusters %d != %d",
|
||||
__func__, mod->name, mod->numclusters, mod->vis->numclusters);
|
||||
}
|
||||
|
||||
*buffer = malloc(size);
|
||||
memcpy(*buffer, data, size);
|
||||
ri.FS_FreeFile((void *)data);
|
||||
|
||||
return size;
|
||||
if ((mod->numleafs > mod_novis_len) || !mod_novis)
|
||||
{
|
||||
/* reallocate buffers for PVS/PHS buffers*/
|
||||
mod_novis_len = (mod->numleafs + 63) & ~63;
|
||||
mod_novis = realloc(mod_novis, mod_novis_len / 8);
|
||||
Com_Printf("Allocated " YQ2_COM_PRIdS " bit leafs of PVS/PHS buffer\n",
|
||||
mod_novis_len);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -397,9 +413,10 @@ Mod_ReadFile(const char *path, void **buffer)
|
|||
static model_t *
|
||||
Mod_ForName(const char *name, model_t *parent_model, qboolean crash)
|
||||
{
|
||||
char filename[256] = {0}, *tag;
|
||||
int i, modfilelen;
|
||||
model_t *mod;
|
||||
void *buf;
|
||||
int i, modfilelen;
|
||||
|
||||
if (!name[0])
|
||||
{
|
||||
|
@ -455,8 +472,18 @@ Mod_ForName(const char *name, model_t *parent_model, qboolean crash)
|
|||
|
||||
strcpy(mod->name, name);
|
||||
|
||||
/* Anachronox has tags in model path*/
|
||||
Q_strlcpy(filename, name, sizeof(filename));
|
||||
tag = strstr(filename, ".mda!");
|
||||
if (tag)
|
||||
{
|
||||
tag += 4; /* strlen(.mda) */
|
||||
*tag = 0;
|
||||
tag ++;
|
||||
}
|
||||
|
||||
/* load the file */
|
||||
modfilelen = ri.Mod_LoadFile(mod->name, &buf);
|
||||
modfilelen = ri.Mod_LoadFile(filename, &buf);
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
|
@ -478,32 +505,14 @@ Mod_ForName(const char *name, model_t *parent_model, qboolean crash)
|
|||
/* call the apropriate loader */
|
||||
switch (LittleLong(*(unsigned *)buf))
|
||||
{
|
||||
case MDAHEADER:
|
||||
/* fall through */
|
||||
case SDEFHEADER:
|
||||
/* fall through */
|
||||
case MDXHEADER:
|
||||
/* fall through */
|
||||
case DKMHEADER:
|
||||
/* fall through */
|
||||
case RAVENFMHEADER:
|
||||
/* fall through */
|
||||
case IDALIASHEADER:
|
||||
/* fall through */
|
||||
case IDMDLHEADER:
|
||||
/* fall through */
|
||||
case ID3HEADER:
|
||||
/* fall through */
|
||||
case MDR_IDENT:
|
||||
/* fall through */
|
||||
case IDMD5HEADER:
|
||||
/* fall through */
|
||||
case IDSPRITEHEADER:
|
||||
{
|
||||
mod->extradata = Mod_LoadModel(mod->name, buf, modfilelen,
|
||||
mod->mins, mod->maxs,
|
||||
(struct image_s ***)&mod->skins, &mod->numskins,
|
||||
(findimage_t)R_FindImage, (loadimage_t)R_LoadPic, Mod_ReadFile,
|
||||
(findimage_t)R_FindImage, (loadimage_t)R_LoadPic,
|
||||
&(mod->type));
|
||||
if (!mod->extradata)
|
||||
{
|
||||
|
@ -555,6 +564,13 @@ Mod_Free(model_t *mod)
|
|||
}
|
||||
|
||||
Hunk_Free(mod->extradata);
|
||||
|
||||
if (mod->type == mod_alias || mod->type == mod_sprite)
|
||||
{
|
||||
/* skins are allocated separately */
|
||||
free(mod->skins);
|
||||
}
|
||||
|
||||
memset(mod, 0, sizeof(*mod));
|
||||
}
|
||||
|
||||
|
@ -570,6 +586,14 @@ Mod_FreeAll(void)
|
|||
Mod_Free(&mod_known[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free PVS buffer */
|
||||
if (mod_novis)
|
||||
{
|
||||
free(mod_novis);
|
||||
mod_novis = NULL;
|
||||
}
|
||||
mod_novis_len = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -38,6 +38,8 @@ static SDL_GLContext context = NULL;
|
|||
qboolean IsHighDPIaware = false;
|
||||
static qboolean vsyncActive = false;
|
||||
|
||||
extern cvar_t *gl1_discardfb;
|
||||
|
||||
// ----
|
||||
|
||||
/*
|
||||
|
@ -47,13 +49,26 @@ void
|
|||
RI_EndFrame(void)
|
||||
{
|
||||
R_ApplyGLBuffer(); // to draw buffered 2D text
|
||||
|
||||
#ifdef YQ2_GL1_GLES
|
||||
if (gl_config.discardfb)
|
||||
static const GLenum attachments[3] = {GL_COLOR_EXT, GL_DEPTH_EXT, GL_STENCIL_EXT};
|
||||
|
||||
if (qglDiscardFramebufferEXT)
|
||||
{
|
||||
static const GLenum attachments[] = { GL_DEPTH_EXT, GL_STENCIL_EXT };
|
||||
qglDiscardFramebufferEXT(GL_FRAMEBUFFER_OES, 2, attachments);
|
||||
switch ((int)gl1_discardfb->value)
|
||||
{
|
||||
case 1:
|
||||
qglDiscardFramebufferEXT(GL_FRAMEBUFFER_OES, 3, &attachments[0]);
|
||||
break;
|
||||
case 2:
|
||||
qglDiscardFramebufferEXT(GL_FRAMEBUFFER_OES, 2, &attachments[1]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_GL_SwapWindow(window);
|
||||
}
|
||||
|
||||
|
@ -89,7 +104,11 @@ int RI_PrepareForWindow(void)
|
|||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
|
||||
|
||||
#ifdef USE_SDL3
|
||||
if (SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8))
|
||||
#else
|
||||
if (SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8) == 0)
|
||||
#endif
|
||||
{
|
||||
gl_state.stencil = true;
|
||||
}
|
||||
|
@ -111,7 +130,11 @@ int RI_PrepareForWindow(void)
|
|||
|
||||
msaa_samples = gl_msaa_samples->value;
|
||||
|
||||
#ifdef USE_SDL3
|
||||
if (!SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1))
|
||||
#else
|
||||
if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1) < 0)
|
||||
#endif
|
||||
{
|
||||
R_Printf(PRINT_ALL, "MSAA is unsupported: %s\n", SDL_GetError());
|
||||
|
||||
|
@ -120,7 +143,11 @@ int RI_PrepareForWindow(void)
|
|||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
|
||||
}
|
||||
#ifdef USE_SDL3
|
||||
else if (!SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaa_samples))
|
||||
#else
|
||||
else if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaa_samples) < 0)
|
||||
#endif
|
||||
{
|
||||
R_Printf(PRINT_ALL, "MSAA %ix is unsupported: %s\n", msaa_samples, SDL_GetError());
|
||||
|
||||
|
@ -157,7 +184,11 @@ void RI_SetVsync(void)
|
|||
vsync = -1;
|
||||
}
|
||||
|
||||
#ifdef USE_SDL3
|
||||
if (!SDL_GL_SetSwapInterval(vsync))
|
||||
#else
|
||||
if (SDL_GL_SetSwapInterval(vsync) == -1)
|
||||
#endif
|
||||
{
|
||||
if (vsync == -1)
|
||||
{
|
||||
|
@ -170,7 +201,7 @@ void RI_SetVsync(void)
|
|||
|
||||
#ifdef USE_SDL3
|
||||
int vsyncState;
|
||||
if (SDL_GL_GetSwapInterval(&vsyncState) != 0)
|
||||
if (!SDL_GL_GetSwapInterval(&vsyncState))
|
||||
{
|
||||
R_Printf(PRINT_ALL, "Failed to get vsync state, assuming vsync inactive.\n");
|
||||
vsyncActive = false;
|
||||
|
@ -239,7 +270,7 @@ int RI_InitContext(void* win)
|
|||
#ifdef YQ2_GL1_GLES
|
||||
|
||||
// Load GL pointers through GLAD and check context.
|
||||
if( !gladLoadGLES1Loader(SDL_GL_GetProcAddress))
|
||||
if( !gladLoadGLES1Loader( (void * (*)(const char *)) SDL_GL_GetProcAddress ) )
|
||||
{
|
||||
R_Printf(PRINT_ALL, "RI_InitContext(): ERROR: loading OpenGL ES function pointers failed!\n");
|
||||
return false;
|
||||
|
@ -282,7 +313,11 @@ int RI_InitContext(void* win)
|
|||
|
||||
if (gl_msaa_samples->value)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
if (SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &msaa_samples))
|
||||
#else
|
||||
if (SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &msaa_samples) == 0)
|
||||
#endif
|
||||
{
|
||||
ri.Cvar_SetValue("r_msaa_samples", msaa_samples);
|
||||
}
|
||||
|
@ -296,7 +331,11 @@ int RI_InitContext(void* win)
|
|||
|
||||
if (gl_state.stencil)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
if (!SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil_bits) || stencil_bits < 8)
|
||||
#else
|
||||
if (SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil_bits) < 0 || stencil_bits < 8)
|
||||
#endif
|
||||
{
|
||||
gl_state.stencil = false;
|
||||
}
|
||||
|
@ -350,7 +389,11 @@ RI_ShutdownContext(void)
|
|||
{
|
||||
if(context)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
SDL_GL_DestroyContext(context);
|
||||
#else
|
||||
SDL_GL_DeleteContext(context);
|
||||
#endif
|
||||
context = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -364,12 +407,11 @@ RI_ShutdownContext(void)
|
|||
int RI_GetSDLVersion()
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
SDL_Version ver;
|
||||
int version = SDL_GetVersion();
|
||||
return SDL_VERSIONNUM_MAJOR(version);
|
||||
#else
|
||||
SDL_version ver;
|
||||
#endif
|
||||
|
||||
SDL_VERSION(&ver);
|
||||
|
||||
return ver.major;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -376,7 +376,7 @@ R_BlendLightmaps(const model_t *currentmodel)
|
|||
}
|
||||
|
||||
static void
|
||||
R_RenderBrushPoly(const entity_t *currententity, msurface_t *fa)
|
||||
R_RenderBrushPoly(msurface_t *fa)
|
||||
{
|
||||
qboolean is_dynamic = false;
|
||||
int maps;
|
||||
|
@ -517,12 +517,12 @@ R_DrawAlphaSurfaces(void)
|
|||
}
|
||||
|
||||
static void
|
||||
R_RenderLightmappedPoly(const entity_t *currententity, msurface_t *surf)
|
||||
R_RenderLightmappedPoly(msurface_t *surf)
|
||||
{
|
||||
int i;
|
||||
int nv = surf->polys->numverts;
|
||||
mvtx_t* vert;
|
||||
const int nv = surf->polys->numverts;
|
||||
float sscroll, tscroll;
|
||||
mvtx_t* vert;
|
||||
int i;
|
||||
|
||||
c_brush_polys++;
|
||||
vert = surf->polys->verts;
|
||||
|
@ -728,7 +728,7 @@ dynamic_surf:
|
|||
}
|
||||
|
||||
static void
|
||||
R_DrawTextureChains(const entity_t *currententity)
|
||||
R_DrawTextureChains(void)
|
||||
{
|
||||
int i;
|
||||
msurface_t *s;
|
||||
|
@ -757,7 +757,7 @@ R_DrawTextureChains(const entity_t *currententity)
|
|||
for ( ; s; s = s->texturechain)
|
||||
{
|
||||
R_UpdateGLBuffer(buf_singletex, image->texnum, 0, s->flags, 1);
|
||||
R_RenderBrushPoly(currententity, s);
|
||||
R_RenderBrushPoly(s);
|
||||
}
|
||||
|
||||
image->texturechain = NULL;
|
||||
|
@ -780,7 +780,7 @@ R_DrawTextureChains(const entity_t *currententity)
|
|||
if (!(s->flags & SURF_DRAWTURB))
|
||||
{
|
||||
R_UpdateGLBuffer(buf_mtex, image->texnum, s->lightmaptexturenum, 0, 1);
|
||||
R_RenderLightmappedPoly(currententity, s);
|
||||
R_RenderLightmappedPoly(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -800,7 +800,7 @@ R_DrawTextureChains(const entity_t *currententity)
|
|||
if (s->flags & SURF_DRAWTURB)
|
||||
{
|
||||
R_UpdateGLBuffer(buf_singletex, image->texnum, 0, s->flags, 1);
|
||||
R_RenderBrushPoly(currententity, s);
|
||||
R_RenderBrushPoly(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -862,12 +862,12 @@ R_DrawInlineBModel(const entity_t *currententity, const model_t *currentmodel)
|
|||
{
|
||||
// Dynamic lighting already generated in R_GetBrushesLighting()
|
||||
R_UpdateGLBuffer(buf_mtex, image->texnum, psurf->lightmaptexturenum, 0, 1);
|
||||
R_RenderLightmappedPoly(currententity, psurf);
|
||||
R_RenderLightmappedPoly(psurf);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_UpdateGLBuffer(buf_singletex, image->texnum, 0, psurf->flags, 1);
|
||||
R_RenderBrushPoly(currententity, psurf);
|
||||
R_RenderBrushPoly(psurf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1090,6 +1090,11 @@ R_RecursiveWorldNode(entity_t *currententity, mnode_t *node)
|
|||
r_alpha_surfaces = surf;
|
||||
r_alpha_surfaces->texinfo->image = R_TextureAnimation(currententity, surf->texinfo);
|
||||
}
|
||||
else if (surf->texinfo->flags & SURF_NODRAW)
|
||||
{
|
||||
/* Surface should be skipped */
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* the polygon is visible, so add it to the texture sorted chain */
|
||||
|
@ -1223,7 +1228,7 @@ R_DrawWorld(void)
|
|||
R_RecursiveWorldNode(&ent, r_worldmodel->nodes);
|
||||
R_GetBrushesLighting();
|
||||
R_RegenAllLightmaps();
|
||||
R_DrawTextureChains(&ent);
|
||||
R_DrawTextureChains();
|
||||
R_BlendLightmaps(r_worldmodel);
|
||||
R_DrawSkyBox();
|
||||
R_DrawTriangleOutlines();
|
||||
|
@ -1237,7 +1242,7 @@ void
|
|||
R_MarkLeaves(void)
|
||||
{
|
||||
const byte *vis;
|
||||
YQ2_ALIGNAS_TYPE(int) byte fatvis[MAX_MAP_LEAFS / 8];
|
||||
byte *fatvis = NULL;
|
||||
mnode_t *node;
|
||||
int i;
|
||||
mleaf_t *leaf;
|
||||
|
@ -1284,6 +1289,7 @@ R_MarkLeaves(void)
|
|||
{
|
||||
int c;
|
||||
|
||||
fatvis = malloc(((r_worldmodel->numleafs + 31) / 32) * sizeof(int));
|
||||
memcpy(fatvis, vis, (r_worldmodel->numleafs + 7) / 8);
|
||||
vis = Mod_ClusterPVS(r_viewcluster2, r_worldmodel);
|
||||
c = (r_worldmodel->numleafs + 31) / 32;
|
||||
|
@ -1326,4 +1332,10 @@ R_MarkLeaves(void)
|
|||
while (node);
|
||||
}
|
||||
}
|
||||
|
||||
/* clean combined buffer */
|
||||
if (fatvis)
|
||||
{
|
||||
free(fatvis);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,8 +51,8 @@
|
|||
#define TEXNUM_LIGHTMAPS 1024
|
||||
#define TEXNUM_SCRAPS (TEXNUM_LIGHTMAPS + MAX_LIGHTMAPS * MAX_LIGHTMAP_COPIES)
|
||||
#define TEXNUM_IMAGES (TEXNUM_SCRAPS + MAX_SCRAPS)
|
||||
#define BLOCK_WIDTH 256 // default values; now defined in glstate_t
|
||||
#define BLOCK_HEIGHT 256
|
||||
#define BLOCK_WIDTH 1024 // default values; now defined in glstate_t
|
||||
#define BLOCK_HEIGHT 1024
|
||||
#define MAX_TEXTURE_UNITS 2
|
||||
#define GL_LIGHTMAP_FORMAT GL_RGBA
|
||||
|
||||
|
@ -127,8 +127,6 @@ typedef struct // 832k aprox.
|
|||
|
||||
#include "model.h"
|
||||
|
||||
void R_SetDefaultState(void);
|
||||
|
||||
extern glbuffer_t gl_buf;
|
||||
extern float gldepthmin, gldepthmax;
|
||||
|
||||
|
@ -168,6 +166,7 @@ extern cvar_t *r_fullbright;
|
|||
extern cvar_t *r_novis;
|
||||
extern cvar_t *r_lerpmodels;
|
||||
extern cvar_t *r_fixsurfsky;
|
||||
extern cvar_t *r_ttffont;
|
||||
|
||||
extern cvar_t *r_lightlevel;
|
||||
extern cvar_t *gl1_overbrightbits;
|
||||
|
@ -287,6 +286,7 @@ void R_SetTexturePalette(const unsigned palette[256]);
|
|||
|
||||
void R_InitImages(void);
|
||||
void R_ShutdownImages(void);
|
||||
void RDraw_FreeLocal(void);
|
||||
|
||||
void R_FreeUnusedImages(void);
|
||||
qboolean R_ImageHasFreeSpace(void);
|
||||
|
@ -397,7 +397,6 @@ typedef struct
|
|||
qboolean pointparameters;
|
||||
qboolean multitexture;
|
||||
qboolean lightmapcopies; // many copies of same lightmap, for embedded
|
||||
qboolean discardfb;
|
||||
|
||||
// ----
|
||||
|
||||
|
@ -487,9 +486,10 @@ int RI_GetSDLVersion();
|
|||
/* g11_draw */
|
||||
extern image_t * RDraw_FindPic(const char *name);
|
||||
extern void RDraw_GetPicSize(int *w, int *h, const char *pic);
|
||||
extern void RDraw_PicScaled(int x, int y, const char *pic, float factor);
|
||||
extern void RDraw_PicScaled(int x, int y, const char *pic, float factor, const char *alttext);
|
||||
extern void RDraw_StretchPic(int x, int y, int w, int h, const char *pic);
|
||||
extern void RDraw_CharScaled(int x, int y, int num, float scale);
|
||||
extern void RDraw_StringScaled(int x, int y, float scale, qboolean alt, const char *message);
|
||||
extern void RDraw_TileClear(int x, int y, int w, int h, const char *pic);
|
||||
extern void RDraw_Fill(int x, int y, int w, int h, int c);
|
||||
extern void RDraw_FadeScreen(void);
|
||||
|
|
|
@ -84,6 +84,7 @@ typedef struct model_s
|
|||
msurface_t **marksurfaces;
|
||||
|
||||
int numvisibility;
|
||||
int numclusters;
|
||||
dvis_t *vis;
|
||||
|
||||
byte *lightdata;
|
||||
|
|
|
@ -26,36 +26,31 @@
|
|||
*/
|
||||
|
||||
#include "header/local.h"
|
||||
#include "../files/stb_truetype.h"
|
||||
|
||||
unsigned d_8to24table[256];
|
||||
|
||||
gl3image_t *draw_chars;
|
||||
static float gl3_font_size = 8.0;
|
||||
static int gl3_font_height = 128;
|
||||
gl3image_t *draw_chars = NULL;
|
||||
static gl3image_t *draw_font = NULL;
|
||||
static gl3image_t *draw_font_alt = NULL;
|
||||
static stbtt_bakedchar *draw_fontcodes = NULL;
|
||||
|
||||
static GLuint vbo2D = 0, vao2D = 0, vao2Dcolor = 0; // vao2D is for textured rendering, vao2Dcolor for color-only
|
||||
|
||||
void R_LoadTTFFont(const char *ttffont, int vid_height, float *r_font_size,
|
||||
int *r_font_height, stbtt_bakedchar **draw_fontcodes,
|
||||
struct image_s **draw_font, struct image_s **draw_font_alt,
|
||||
loadimage_t R_LoadPic);
|
||||
|
||||
void
|
||||
GL3_Draw_InitLocal(void)
|
||||
{
|
||||
/* load console characters */
|
||||
draw_chars = R_FindPic("conchars", (findimage_t)GL3_FindImage);
|
||||
R_LoadTTFFont(r_ttffont->string, vid.height, &gl3_font_size, &gl3_font_height,
|
||||
&draw_fontcodes, &draw_font, &draw_font_alt, (loadimage_t)GL3_LoadPic);
|
||||
|
||||
/* Anachronox */
|
||||
if (!draw_chars)
|
||||
{
|
||||
draw_chars = R_FindPic ("fonts/conchars", (findimage_t)GL3_FindImage);
|
||||
}
|
||||
|
||||
/* Daikatana */
|
||||
if (!draw_chars)
|
||||
{
|
||||
draw_chars = R_FindPic ("dkchars", (findimage_t)GL3_FindImage);
|
||||
}
|
||||
|
||||
if (!draw_chars)
|
||||
{
|
||||
Com_Error(ERR_FATAL, "%s: Couldn't load pics/conchars",
|
||||
__func__);
|
||||
}
|
||||
draw_chars = R_LoadConsoleChars((findimage_t)GL3_FindImage);
|
||||
|
||||
// set up attribute layout for 2D textured rendering
|
||||
glGenVertexArrays(1, &vao2D);
|
||||
|
@ -98,6 +93,7 @@ GL3_Draw_ShutdownLocal(void)
|
|||
vao2D = 0;
|
||||
glDeleteVertexArrays(1, &vao2Dcolor);
|
||||
vao2Dcolor = 0;
|
||||
free(draw_fontcodes);
|
||||
}
|
||||
|
||||
// bind the texture before calling this
|
||||
|
@ -173,6 +169,64 @@ GL3_Draw_CharScaled(int x, int y, int num, float scale)
|
|||
drawTexturedRectangle(x, y, scaledSize, scaledSize, fcol, frow, fcol+size, frow+size);
|
||||
}
|
||||
|
||||
void
|
||||
GL3_Draw_StringScaled(int x, int y, float scale, qboolean alt, const char *message)
|
||||
{
|
||||
while (*message)
|
||||
{
|
||||
unsigned value = R_NextUTF8Code(&message);
|
||||
|
||||
if (draw_fontcodes && (draw_font || draw_font_alt))
|
||||
{
|
||||
float font_scale;
|
||||
|
||||
font_scale = gl3_font_size / 8.0;
|
||||
|
||||
if (value >= 32 && value < MAX_FONTCODE)
|
||||
{
|
||||
float xf = 0, yf = 0, xdiff;
|
||||
stbtt_aligned_quad q;
|
||||
|
||||
stbtt_GetBakedQuad(draw_fontcodes, gl3_font_height, gl3_font_height,
|
||||
value - 32, &xf, &yf, &q, 1);
|
||||
|
||||
xdiff = (8 - xf / font_scale) / 2;
|
||||
if (xdiff < 0)
|
||||
{
|
||||
xdiff = 0;
|
||||
}
|
||||
|
||||
GL3_UseProgram(gl3state.si2D.shaderProgram);
|
||||
GL3_Bind(alt ? draw_font_alt->texnum : draw_font->texnum);
|
||||
drawTexturedRectangle(
|
||||
(float)(x + (xdiff + q.x0 / font_scale) * scale),
|
||||
(float)(y + q.y0 * scale / font_scale + 8 * scale),
|
||||
(q.x1 - q.x0) * scale / font_scale,
|
||||
(q.y1 - q.y0) * scale / font_scale,
|
||||
q.s0, q.t0, q.s1, q.t1);
|
||||
x += Q_max(8, xf / font_scale) * scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
x += 8 * scale;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int xor;
|
||||
|
||||
xor = alt ? 0x80 : 0;
|
||||
|
||||
if (value > ' ' && value < 128)
|
||||
{
|
||||
GL3_Draw_CharScaled(x, y, value ^ xor, scale);
|
||||
}
|
||||
|
||||
x += 8 * scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gl3image_t *
|
||||
GL3_Draw_FindPic(const char *name)
|
||||
{
|
||||
|
@ -214,11 +268,20 @@ GL3_Draw_StretchPic(int x, int y, int w, int h, const char *pic)
|
|||
}
|
||||
|
||||
void
|
||||
GL3_Draw_PicScaled(int x, int y, const char *pic, float factor)
|
||||
GL3_Draw_PicScaled(int x, int y, const char *pic, float factor, const char *alttext)
|
||||
{
|
||||
gl3image_t *gl = R_FindPic(pic, (findimage_t)GL3_FindImage);
|
||||
gl3image_t *gl;
|
||||
|
||||
gl = R_FindPic(pic, (findimage_t)GL3_FindImage);
|
||||
if (!gl)
|
||||
{
|
||||
if (alttext && alttext[0])
|
||||
{
|
||||
/* Show alttext if provided */
|
||||
GL3_Draw_StringScaled(x, y, factor, false, alttext);
|
||||
return;
|
||||
}
|
||||
|
||||
R_Printf(PRINT_ALL, "Can't find pic: %s\n", pic);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -186,7 +186,7 @@ GL3_BindLightmap(int lightmapnum)
|
|||
/*
|
||||
* Returns has_alpha
|
||||
*/
|
||||
qboolean
|
||||
static qboolean
|
||||
GL3_Upload32(unsigned *data, int width, int height, qboolean mipmap)
|
||||
{
|
||||
qboolean res;
|
||||
|
@ -237,7 +237,7 @@ GL3_Upload32(unsigned *data, int width, int height, qboolean mipmap)
|
|||
/*
|
||||
* Returns has_alpha
|
||||
*/
|
||||
qboolean
|
||||
static qboolean
|
||||
GL3_Upload8(byte *data, int width, int height, qboolean mipmap, qboolean is_sky)
|
||||
{
|
||||
int s = width * height;
|
||||
|
@ -609,42 +609,41 @@ GL3_LoadPic(char *name, byte *pic, int width, int realwidth,
|
|||
* Finds or loads the given image or NULL
|
||||
*/
|
||||
gl3image_t *
|
||||
GL3_FindImage(const char *name, imagetype_t type)
|
||||
GL3_FindImage(const char *originname, imagetype_t type)
|
||||
{
|
||||
char namewe[256], name[256] = {0};
|
||||
gl3image_t *image;
|
||||
int i, len;
|
||||
char *ptr;
|
||||
char namewe[256];
|
||||
const char* ext;
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
if (!name)
|
||||
if (!originname)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Q_strlcpy(name, originname, sizeof(name));
|
||||
|
||||
/* fix backslashes */
|
||||
Q_replacebackslash(name);
|
||||
|
||||
ext = COM_FileExtension(name);
|
||||
if(!ext[0])
|
||||
if (!ext[0])
|
||||
{
|
||||
/* file has no extension */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = strlen(name);
|
||||
|
||||
/* Remove the extension */
|
||||
memset(namewe, 0, 256);
|
||||
memcpy(namewe, name, len - (strlen(ext) + 1));
|
||||
|
||||
if (len < 5)
|
||||
len = (ext - name) - 1;
|
||||
if ((len < 1) || (len > sizeof(namewe) - 1))
|
||||
{
|
||||
Com_DPrintf("%s: Bad filename %s\n", __func__, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* fix backslashes */
|
||||
while ((ptr = strchr(name, '\\')))
|
||||
{
|
||||
*ptr = '/';
|
||||
}
|
||||
memcpy(namewe, name, len);
|
||||
namewe[len] = 0;
|
||||
|
||||
/* look for it */
|
||||
for (i = 0, image = gl3textures; i < numgl3textures; i++, image++)
|
||||
|
|
|
@ -130,6 +130,7 @@ cvar_t *gl_shadows;
|
|||
cvar_t *gl3_debugcontext;
|
||||
cvar_t *gl3_usebigvbo;
|
||||
cvar_t *r_fixsurfsky;
|
||||
cvar_t *r_ttffont;
|
||||
cvar_t *r_palettedtexture;
|
||||
cvar_t *r_validation;
|
||||
cvar_t *gl3_usefbo;
|
||||
|
@ -232,6 +233,8 @@ GL3_Register(void)
|
|||
r_drawentities = ri.Cvar_Get("r_drawentities", "1", 0);
|
||||
r_drawworld = ri.Cvar_Get("r_drawworld", "1", 0);
|
||||
r_fullbright = ri.Cvar_Get("r_fullbright", "0", 0);
|
||||
/* font should looks good with 8 pixels size */
|
||||
r_ttffont = ri.Cvar_Get("r_ttffont", "RussoOne-Regular", CVAR_ARCHIVE);
|
||||
r_fixsurfsky = ri.Cvar_Get("r_fixsurfsky", "0", CVAR_ARCHIVE);
|
||||
r_palettedtexture = ri.Cvar_Get("r_palettedtexture", "0", 0);
|
||||
r_validation = ri.Cvar_Get("r_validation", "0", CVAR_ARCHIVE);
|
||||
|
@ -366,12 +369,16 @@ SetMode_impl(int *pwidth, int *pheight, int mode, int fullscreen)
|
|||
|
||||
R_Printf(PRINT_ALL, " %dx%d (vid_fullscreen %i)\n", *pwidth, *pheight, fullscreen);
|
||||
|
||||
|
||||
if (!ri.GLimp_InitGraphics(fullscreen, pwidth, pheight))
|
||||
{
|
||||
return rserr_invalid_mode;
|
||||
}
|
||||
|
||||
if (mode == -2 || fullscreen)
|
||||
{
|
||||
GL3_BindVBO(0);
|
||||
}
|
||||
|
||||
/* This is totaly obscure: For some strange reasons the renderer
|
||||
maintains two(!) repesentations of the resolution. One comes
|
||||
from the client and is saved in gl3_newrefdef. The other one
|
||||
|
@ -526,19 +533,6 @@ GL3_Init(void)
|
|||
R_Printf(PRINT_ALL, "\nOpenGL setting:\n");
|
||||
GL3_Strings();
|
||||
|
||||
/*
|
||||
if (gl_config.major_version < 3)
|
||||
{
|
||||
// if (gl_config.major_version == 3 && gl_config.minor_version < 2)
|
||||
{
|
||||
QGL_Shutdown();
|
||||
R_Printf(PRINT_ALL, "Support for OpenGL 3.2 is not available\n");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
R_Printf(PRINT_ALL, "\n\nProbing for OpenGL extensions:\n");
|
||||
|
||||
|
||||
|
@ -2018,6 +2012,7 @@ GetRefAPI(refimport_t imp)
|
|||
re.DrawStretchPic = GL3_Draw_StretchPic;
|
||||
|
||||
re.DrawCharScaled = GL3_Draw_CharScaled;
|
||||
re.DrawStringScaled = GL3_Draw_StringScaled;
|
||||
re.DrawTileClear = GL3_Draw_TileClear;
|
||||
re.DrawFill = GL3_Draw_Fill;
|
||||
re.DrawFadeScreen = GL3_Draw_FadeScreen;
|
||||
|
@ -2070,6 +2065,15 @@ Com_Printf(const char *msg, ...)
|
|||
va_end(argptr);
|
||||
}
|
||||
|
||||
void
|
||||
Com_DPrintf(const char *msg, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
va_start(argptr, msg);
|
||||
ri.Com_VPrintf(PRINT_DEVELOPER, msg, argptr);
|
||||
va_end(argptr);
|
||||
}
|
||||
|
||||
void
|
||||
Com_Error(int code, const char *fmt, ...)
|
||||
{
|
||||
|
|
|
@ -289,7 +289,8 @@ DrawAliasFrameLerp(dmdx_t *paliashdr, entity_t* entity, vec3_t shadelight,
|
|||
|
||||
lerp = s_lerped[0];
|
||||
|
||||
R_LerpVerts(colorOnly, paliashdr->num_xyz, verts, ov, lerp, move, frontv, backv);
|
||||
R_LerpVerts(colorOnly, paliashdr->num_xyz, verts, ov, lerp,
|
||||
move, frontv, backv, entity->scale);
|
||||
|
||||
YQ2_STATIC_ASSERT(sizeof(gl3_alias_vtx_t) == 9 * sizeof(GLfloat), "invalid gl3_alias_vtx_t size");
|
||||
|
||||
|
@ -298,6 +299,11 @@ DrawAliasFrameLerp(dmdx_t *paliashdr, entity_t* entity, vec3_t shadelight,
|
|||
|
||||
for (i = 0; i < num_mesh_nodes; i++)
|
||||
{
|
||||
if (entity->rr_mesh & (1 << i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
DrawAliasFrameLerpCommands(paliashdr, entity, shadelight,
|
||||
order + mesh_nodes[i].ofs_glcmds,
|
||||
order + Q_min(paliashdr->num_glcmds,
|
||||
|
@ -469,7 +475,8 @@ DrawAliasShadow(gl3_shadowinfo_t* shadowInfo)
|
|||
|
||||
// false: don't extrude vertices for powerup - this means the powerup shell
|
||||
// is not seen in the shadow, only the underlying model..
|
||||
R_LerpVerts(false, paliashdr->num_xyz, verts, ov, s_lerped[0], move, frontv, backv);
|
||||
R_LerpVerts(false, paliashdr->num_xyz, verts, ov, s_lerped[0],
|
||||
move, frontv, backv, entity->scale);
|
||||
}
|
||||
|
||||
lheight = entity->origin[2] - shadowInfo->lightspot[2];
|
||||
|
@ -546,6 +553,15 @@ GL3_DrawAliasModel(entity_t *entity)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
/* fix scale */
|
||||
if (!entity->scale[i])
|
||||
{
|
||||
entity->scale[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
gl3model_t* model = entity->model;
|
||||
paliashdr = (dmdx_t *)model->extradata;
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
|
||||
#include "header/local.h"
|
||||
|
||||
static YQ2_ALIGNAS_TYPE(int) byte mod_novis[MAX_MAP_LEAFS / 8];
|
||||
static byte *mod_novis = NULL;
|
||||
static size_t mod_novis_len = 0;
|
||||
|
||||
static gl3model_t mod_known[MAX_MOD_KNOWN];
|
||||
static int mod_numknown = 0;
|
||||
|
@ -66,15 +67,34 @@ Mod_HasFreeSpace(void)
|
|||
const byte *
|
||||
GL3_Mod_ClusterPVS(int cluster, const gl3model_t *model)
|
||||
{
|
||||
if ((cluster == -1) || !model->vis)
|
||||
if (!mod_novis)
|
||||
{
|
||||
Com_Error(ERR_DROP, "%s: incrorrect init of PVS/PHS", __func__);
|
||||
}
|
||||
|
||||
if (!model->vis)
|
||||
{
|
||||
Mod_DecompressVis(NULL, mod_novis, NULL,
|
||||
(model->numclusters + 7) >> 3);
|
||||
return mod_novis;
|
||||
}
|
||||
|
||||
return Mod_DecompressVis((byte *)model->vis +
|
||||
model->vis->bitofs[cluster][DVIS_PVS],
|
||||
if (cluster == -1)
|
||||
{
|
||||
memset(mod_novis, 0, (model->numclusters + 7) >> 3);
|
||||
return mod_novis;
|
||||
}
|
||||
|
||||
if (cluster < 0 || cluster >= model->numvisibility)
|
||||
{
|
||||
Com_Error(ERR_DROP, "%s: bad cluster", __func__);
|
||||
}
|
||||
|
||||
Mod_DecompressVis((byte *)model->vis +
|
||||
model->vis->bitofs[cluster][DVIS_PVS], mod_novis,
|
||||
(byte *)model->vis + model->numvisibility,
|
||||
(model->vis->numclusters + 7) >> 3);
|
||||
(model->numclusters + 7) >> 3);
|
||||
return mod_novis;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -118,7 +138,8 @@ void
|
|||
GL3_Mod_Init(void)
|
||||
{
|
||||
mod_max = 0;
|
||||
memset(mod_novis, 0xff, sizeof(mod_novis));
|
||||
mod_novis = NULL;
|
||||
mod_novis_len = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -363,33 +384,28 @@ Mod_LoadBrushModel(gl3model_t *mod, const void *buffer, int modfilelen)
|
|||
Mod_LoadVisibility(mod->name, &mod->vis, &mod->numvisibility, mod_base,
|
||||
&header->lumps[LUMP_VISIBILITY]);
|
||||
Mod_LoadQBSPLeafs(mod->name, &mod->leafs, &mod->numleafs,
|
||||
mod->marksurfaces, mod->nummarksurfaces, mod_base,
|
||||
&header->lumps[LUMP_LEAFS]);
|
||||
mod->marksurfaces, mod->nummarksurfaces, &mod->numclusters,
|
||||
mod_base, &header->lumps[LUMP_LEAFS]);
|
||||
Mod_LoadQBSPNodes(mod->name, mod->planes, mod->numplanes, mod->leafs,
|
||||
mod->numleafs, &mod->nodes, &mod->numnodes, mod_base,
|
||||
&header->lumps[LUMP_NODES], header->ident);
|
||||
mod->numleafs, &mod->nodes, &mod->numnodes, mod->mins, mod->maxs,
|
||||
mod_base, &header->lumps[LUMP_NODES], header->ident);
|
||||
Mod_LoadSubmodels(mod, mod_base, &header->lumps[LUMP_MODELS]);
|
||||
mod->numframes = 2; /* regular and alternate animation */
|
||||
}
|
||||
|
||||
/* Temporary solution, need to use load file dirrectly */
|
||||
static int
|
||||
Mod_ReadFile(const char *path, void **buffer)
|
||||
{
|
||||
char *data;
|
||||
int size;
|
||||
|
||||
size = ri.FS_LoadFile(path, (void **)&data);
|
||||
if (size <= 0)
|
||||
if (mod->vis && mod->numclusters != mod->vis->numclusters)
|
||||
{
|
||||
return size;
|
||||
Com_Error(ERR_DROP, "%s: Map %s has incorrect number of clusters %d != %d",
|
||||
__func__, mod->name, mod->numclusters, mod->vis->numclusters);
|
||||
}
|
||||
|
||||
*buffer = malloc(size);
|
||||
memcpy(*buffer, data, size);
|
||||
ri.FS_FreeFile((void *)data);
|
||||
|
||||
return size;
|
||||
if ((mod->numleafs > mod_novis_len) || !mod_novis)
|
||||
{
|
||||
/* reallocate buffers for PVS/PHS buffers*/
|
||||
mod_novis_len = (mod->numleafs + 63) & ~63;
|
||||
mod_novis = realloc(mod_novis, mod_novis_len / 8);
|
||||
Com_Printf("Allocated " YQ2_COM_PRIdS " bit leafs of PVS/PHS buffer\n",
|
||||
mod_novis_len);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -398,9 +414,10 @@ Mod_ReadFile(const char *path, void **buffer)
|
|||
static gl3model_t *
|
||||
Mod_ForName(const char *name, gl3model_t *parent_model, qboolean crash)
|
||||
{
|
||||
char filename[256] = {0}, *tag;
|
||||
int i, modfilelen;
|
||||
gl3model_t *mod;
|
||||
void *buf;
|
||||
int i, modfilelen;
|
||||
|
||||
if (!name[0])
|
||||
{
|
||||
|
@ -456,8 +473,18 @@ Mod_ForName(const char *name, gl3model_t *parent_model, qboolean crash)
|
|||
|
||||
strcpy(mod->name, name);
|
||||
|
||||
/* Anachronox has tags in model path*/
|
||||
Q_strlcpy(filename, name, sizeof(filename));
|
||||
tag = strstr(filename, ".mda!");
|
||||
if (tag)
|
||||
{
|
||||
tag += 4; /* strlen(.mda) */
|
||||
*tag = 0;
|
||||
tag ++;
|
||||
}
|
||||
|
||||
/* load the file */
|
||||
modfilelen = ri.Mod_LoadFile(mod->name, &buf);
|
||||
modfilelen = ri.Mod_LoadFile(filename, &buf);
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
|
@ -479,32 +506,14 @@ Mod_ForName(const char *name, gl3model_t *parent_model, qboolean crash)
|
|||
/* call the apropriate loader */
|
||||
switch (LittleLong(*(unsigned *)buf))
|
||||
{
|
||||
case MDAHEADER:
|
||||
/* fall through */
|
||||
case SDEFHEADER:
|
||||
/* fall through */
|
||||
case MDXHEADER:
|
||||
/* fall through */
|
||||
case DKMHEADER:
|
||||
/* fall through */
|
||||
case RAVENFMHEADER:
|
||||
/* fall through */
|
||||
case IDALIASHEADER:
|
||||
/* fall through */
|
||||
case IDMDLHEADER:
|
||||
/* fall through */
|
||||
case ID3HEADER:
|
||||
/* fall through */
|
||||
case MDR_IDENT:
|
||||
/* fall through */
|
||||
case IDMD5HEADER:
|
||||
/* fall through */
|
||||
case IDSPRITEHEADER:
|
||||
{
|
||||
mod->extradata = Mod_LoadModel(mod->name, buf, modfilelen,
|
||||
mod->mins, mod->maxs,
|
||||
(struct image_s ***)&mod->skins, &mod->numskins,
|
||||
(findimage_t)GL3_FindImage, (loadimage_t)GL3_LoadPic, Mod_ReadFile,
|
||||
(findimage_t)GL3_FindImage, (loadimage_t)GL3_LoadPic,
|
||||
&(mod->type));
|
||||
if (!mod->extradata)
|
||||
{
|
||||
|
@ -556,6 +565,13 @@ Mod_Free(gl3model_t *mod)
|
|||
}
|
||||
|
||||
Hunk_Free(mod->extradata);
|
||||
|
||||
if (mod->type == mod_alias || mod->type == mod_sprite)
|
||||
{
|
||||
/* skins are allocated separately */
|
||||
free(mod->skins);
|
||||
}
|
||||
|
||||
memset(mod, 0, sizeof(*mod));
|
||||
}
|
||||
|
||||
|
@ -571,6 +587,14 @@ GL3_Mod_FreeAll(void)
|
|||
Mod_Free(&mod_known[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free PVS buffer */
|
||||
if (mod_novis)
|
||||
{
|
||||
free(mod_novis);
|
||||
mod_novis = NULL;
|
||||
}
|
||||
mod_novis_len = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -53,7 +53,7 @@ enum {
|
|||
*/
|
||||
static void APIENTRY
|
||||
DebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
|
||||
const GLchar *message, const void *userParam)
|
||||
const GLchar *message, const void *userParam)
|
||||
{
|
||||
const char* sourceStr = "Source: Unknown";
|
||||
const char* typeStr = "Type: Unknown";
|
||||
|
@ -155,7 +155,11 @@ void GL3_SetVsync(void)
|
|||
vsync = -1;
|
||||
}
|
||||
|
||||
#ifdef USE_SDL3
|
||||
if (!SDL_GL_SetSwapInterval(vsync))
|
||||
#else
|
||||
if (SDL_GL_SetSwapInterval(vsync) == -1)
|
||||
#endif
|
||||
{
|
||||
if (vsync == -1)
|
||||
{
|
||||
|
@ -168,15 +172,15 @@ void GL3_SetVsync(void)
|
|||
|
||||
#ifdef USE_SDL3
|
||||
int vsyncState;
|
||||
if (SDL_GL_GetSwapInterval(&vsyncState) != 0)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "Failed to get vsync state, assuming vsync inactive.\n");
|
||||
vsyncActive = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
vsyncActive = vsyncState ? true : false;
|
||||
}
|
||||
if (!SDL_GL_GetSwapInterval(&vsyncState))
|
||||
{
|
||||
R_Printf(PRINT_ALL, "Failed to get vsync state, assuming vsync inactive.\n");
|
||||
vsyncActive = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
vsyncActive = vsyncState ? true : false;
|
||||
}
|
||||
#else
|
||||
vsyncActive = SDL_GL_GetSwapInterval() != 0;
|
||||
#endif
|
||||
|
@ -204,7 +208,11 @@ int GL3_PrepareForWindow(void)
|
|||
|
||||
while (1)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
if (!SDL_GL_LoadLibrary(libgl))
|
||||
#else
|
||||
if (SDL_GL_LoadLibrary(libgl) < 0)
|
||||
#endif
|
||||
{
|
||||
if (libgl == NULL)
|
||||
{
|
||||
|
@ -236,7 +244,11 @@ int GL3_PrepareForWindow(void)
|
|||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
|
||||
#ifdef USE_SDL3
|
||||
if (SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8))
|
||||
#else
|
||||
if (SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8) == 0)
|
||||
#endif
|
||||
{
|
||||
gl3config.stencil = true;
|
||||
}
|
||||
|
@ -287,7 +299,11 @@ int GL3_PrepareForWindow(void)
|
|||
{
|
||||
msaa_samples = gl_msaa_samples->value;
|
||||
|
||||
#ifdef USE_SDL3
|
||||
if (!SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1))
|
||||
#else
|
||||
if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1) < 0)
|
||||
#endif
|
||||
{
|
||||
R_Printf(PRINT_ALL, "MSAA is unsupported: %s\n", SDL_GetError());
|
||||
|
||||
|
@ -296,7 +312,11 @@ int GL3_PrepareForWindow(void)
|
|||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
|
||||
}
|
||||
#ifdef USE_SDL3
|
||||
else if (!SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaa_samples))
|
||||
#else
|
||||
else if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaa_samples) < 0)
|
||||
#endif
|
||||
{
|
||||
R_Printf(PRINT_ALL, "MSAA %ix is unsupported: %s\n", msaa_samples, SDL_GetError());
|
||||
|
||||
|
@ -350,7 +370,11 @@ int GL3_InitContext(void* win)
|
|||
|
||||
if (gl_msaa_samples->value)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
if (SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &msaa_samples))
|
||||
#else
|
||||
if (SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &msaa_samples) == 0)
|
||||
#endif
|
||||
{
|
||||
ri.Cvar_SetValue("r_msaa_samples", msaa_samples);
|
||||
}
|
||||
|
@ -361,7 +385,11 @@ int GL3_InitContext(void* win)
|
|||
|
||||
if (gl3config.stencil)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
if (!SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil_bits) || stencil_bits < 8)
|
||||
#else
|
||||
if (SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil_bits) < 0 || stencil_bits < 8)
|
||||
#endif
|
||||
{
|
||||
gl3config.stencil = false;
|
||||
}
|
||||
|
@ -435,7 +463,7 @@ int GL3_InitContext(void* win)
|
|||
}
|
||||
|
||||
// Window title - set here so we can display renderer name in it.
|
||||
char title[40] = {0};
|
||||
char title[64] = {0};
|
||||
#ifdef YQ2_GL3_GLES3
|
||||
snprintf(title, sizeof(title), "Yamagi Quake II %s - OpenGL ES 3.0", YQ2VERSION);
|
||||
#else
|
||||
|
@ -477,7 +505,11 @@ void GL3_ShutdownContext()
|
|||
{
|
||||
if(context)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
SDL_GL_DestroyContext(context);
|
||||
#else
|
||||
SDL_GL_DeleteContext(context);
|
||||
#endif
|
||||
context = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -491,12 +523,11 @@ void GL3_ShutdownContext()
|
|||
int GL3_GetSDLVersion()
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
SDL_Version ver;
|
||||
int version = SDL_GetVersion();
|
||||
return SDL_VERSIONNUM_MAJOR(version);
|
||||
#else
|
||||
SDL_version ver;
|
||||
#endif
|
||||
|
||||
SDL_VERSION(&ver);
|
||||
|
||||
return ver.major;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -729,6 +729,11 @@ RecursiveWorldNode(entity_t *currententity, mnode_t *node)
|
|||
gl3_alpha_surfaces = surf;
|
||||
gl3_alpha_surfaces->texinfo->image = R_TextureAnimation(currententity, surf->texinfo);
|
||||
}
|
||||
else if (surf->texinfo->flags & SURF_NODRAW)
|
||||
{
|
||||
/* Surface should be skipped */
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// calling RenderLightmappedPoly() here probably isn't optimal, rendering everything
|
||||
|
@ -792,11 +797,10 @@ void
|
|||
GL3_MarkLeaves(void)
|
||||
{
|
||||
const byte *vis;
|
||||
YQ2_ALIGNAS_TYPE(int) byte fatvis[MAX_MAP_LEAFS / 8];
|
||||
byte *fatvis = NULL;
|
||||
mnode_t *node;
|
||||
int i, c;
|
||||
int i;
|
||||
mleaf_t *leaf;
|
||||
int cluster;
|
||||
|
||||
if ((gl3_oldviewcluster == gl3_viewcluster) &&
|
||||
(gl3_oldviewcluster2 == gl3_viewcluster2) &&
|
||||
|
@ -838,6 +842,9 @@ GL3_MarkLeaves(void)
|
|||
/* may have to combine two clusters because of solid water boundaries */
|
||||
if (gl3_viewcluster2 != gl3_viewcluster)
|
||||
{
|
||||
int c;
|
||||
|
||||
fatvis = malloc(((gl3_worldmodel->numleafs + 31) / 32) * sizeof(int));
|
||||
memcpy(fatvis, vis, (gl3_worldmodel->numleafs + 7) / 8);
|
||||
vis = GL3_Mod_ClusterPVS(gl3_viewcluster2, gl3_worldmodel);
|
||||
c = (gl3_worldmodel->numleafs + 31) / 32;
|
||||
|
@ -854,6 +861,8 @@ GL3_MarkLeaves(void)
|
|||
i < gl3_worldmodel->numleafs;
|
||||
i++, leaf++)
|
||||
{
|
||||
int cluster;
|
||||
|
||||
cluster = leaf->cluster;
|
||||
|
||||
if (cluster == -1)
|
||||
|
@ -878,5 +887,10 @@ GL3_MarkLeaves(void)
|
|||
while (node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* clean combined buffer */
|
||||
if (fatvis)
|
||||
{
|
||||
free(fatvis);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -190,8 +190,8 @@ enum {
|
|||
// width and height used to be 128, so now we should be able to get the same lightmap data
|
||||
// that used 32 lightmaps before into one, so 4 lightmaps should be enough
|
||||
BLOCK_WIDTH = 1024,
|
||||
BLOCK_HEIGHT = 512,
|
||||
MAX_LIGHTMAPS = 8,
|
||||
BLOCK_HEIGHT = 1024,
|
||||
MAX_LIGHTMAPS = 16,
|
||||
MAX_LIGHTMAPS_PER_SURFACE = MAXLIGHTMAPS // 4
|
||||
};
|
||||
|
||||
|
@ -417,15 +417,17 @@ extern void GL3_Draw_ShutdownLocal(void);
|
|||
extern gl3image_t * GL3_Draw_FindPic(const char *name);
|
||||
extern void GL3_Draw_GetPicSize(int *w, int *h, const char *pic);
|
||||
|
||||
extern void GL3_Draw_PicScaled(int x, int y, const char *pic, float factor);
|
||||
extern void GL3_Draw_PicScaled(int x, int y, const char *pic, float factor, const char *alttext);
|
||||
extern void GL3_Draw_StretchPic(int x, int y, int w, int h, const char *pic);
|
||||
extern void GL3_Draw_CharScaled(int x, int y, int num, float scale);
|
||||
extern void GL3_Draw_StringScaled(int x, int y, float scale, qboolean alt, const char *message);
|
||||
extern void GL3_Draw_TileClear(int x, int y, int w, int h, const char *pic);
|
||||
extern void GL3_DrawFrameBufferObject(int x, int y, int w, int h, GLuint fboTexture, const float v_blend[4]);
|
||||
extern void GL3_Draw_Fill(int x, int y, int w, int h, int c);
|
||||
extern void GL3_Draw_FadeScreen(void);
|
||||
extern void GL3_Draw_Flash(const float color[4], float x, float y, float w, float h);
|
||||
extern void GL3_Draw_StretchRaw(int x, int y, int w, int h, int cols, int rows, const byte *data, int bits);
|
||||
extern void GL3_Draw_FreeLocal(void);
|
||||
|
||||
// gl3_image.c
|
||||
|
||||
|
@ -550,6 +552,7 @@ extern cvar_t *r_modulate;
|
|||
extern cvar_t *gl_lightmap;
|
||||
extern cvar_t *gl_shadows;
|
||||
extern cvar_t *r_fixsurfsky;
|
||||
extern cvar_t *r_ttffont;
|
||||
extern cvar_t *r_palettedtexture;
|
||||
extern cvar_t *r_validation;
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ typedef struct model_s
|
|||
msurface_t **marksurfaces;
|
||||
|
||||
int numvisibility;
|
||||
int numclusters;
|
||||
dvis_t *vis;
|
||||
|
||||
byte *lightdata;
|
||||
|
|
|
@ -26,36 +26,31 @@
|
|||
*/
|
||||
|
||||
#include "header/local.h"
|
||||
#include "../files/stb_truetype.h"
|
||||
|
||||
unsigned d_8to24table[256];
|
||||
|
||||
gl4image_t *draw_chars;
|
||||
static float gl4_font_size = 8.0;
|
||||
static int gl4_font_height = 128;
|
||||
gl4image_t *draw_chars = NULL;
|
||||
static gl4image_t *draw_font = NULL;
|
||||
static gl4image_t *draw_font_alt = NULL;
|
||||
static stbtt_bakedchar *draw_fontcodes = NULL;
|
||||
|
||||
static GLuint vbo2D = 0, vao2D = 0, vao2Dcolor = 0; // vao2D is for textured rendering, vao2Dcolor for color-only
|
||||
|
||||
void R_LoadTTFFont(const char *ttffont, int vid_height, float *r_font_size,
|
||||
int *r_font_height, stbtt_bakedchar **draw_fontcodes,
|
||||
struct image_s **draw_font, struct image_s **draw_font_alt,
|
||||
loadimage_t R_LoadPic);
|
||||
|
||||
void
|
||||
GL4_Draw_InitLocal(void)
|
||||
{
|
||||
/* load console characters */
|
||||
draw_chars = R_FindPic("conchars", (findimage_t)GL4_FindImage);
|
||||
R_LoadTTFFont(r_ttffont->string, vid.height, &gl4_font_size, &gl4_font_height,
|
||||
&draw_fontcodes, &draw_font, &draw_font_alt, (loadimage_t)GL4_LoadPic);
|
||||
|
||||
/* Anachronox */
|
||||
if (!draw_chars)
|
||||
{
|
||||
draw_chars = R_FindPic ("fonts/conchars", (findimage_t)GL4_FindImage);
|
||||
}
|
||||
|
||||
/* Daikatana */
|
||||
if (!draw_chars)
|
||||
{
|
||||
draw_chars = R_FindPic ("dkchars", (findimage_t)GL4_FindImage);
|
||||
}
|
||||
|
||||
if (!draw_chars)
|
||||
{
|
||||
Com_Error(ERR_FATAL, "%s: Couldn't load pics/conchars.pcx",
|
||||
__func__);
|
||||
}
|
||||
draw_chars = R_LoadConsoleChars((findimage_t)GL4_FindImage);
|
||||
|
||||
// set up attribute layout for 2D textured rendering
|
||||
glGenVertexArrays(1, &vao2D);
|
||||
|
@ -98,6 +93,7 @@ GL4_Draw_ShutdownLocal(void)
|
|||
vao2D = 0;
|
||||
glDeleteVertexArrays(1, &vao2Dcolor);
|
||||
vao2Dcolor = 0;
|
||||
free(draw_fontcodes);
|
||||
}
|
||||
|
||||
// bind the texture before calling this
|
||||
|
@ -173,6 +169,64 @@ GL4_Draw_CharScaled(int x, int y, int num, float scale)
|
|||
drawTexturedRectangle(x, y, scaledSize, scaledSize, fcol, frow, fcol+size, frow+size);
|
||||
}
|
||||
|
||||
void
|
||||
GL4_Draw_StringScaled(int x, int y, float scale, qboolean alt, const char *message)
|
||||
{
|
||||
while (*message)
|
||||
{
|
||||
unsigned value = R_NextUTF8Code(&message);
|
||||
|
||||
if (draw_fontcodes && (draw_font || draw_font_alt))
|
||||
{
|
||||
float font_scale;
|
||||
|
||||
font_scale = gl4_font_size / 8.0;
|
||||
|
||||
if (value >= 32 && value < MAX_FONTCODE)
|
||||
{
|
||||
float xf = 0, yf = 0, xdiff;
|
||||
stbtt_aligned_quad q;
|
||||
|
||||
stbtt_GetBakedQuad(draw_fontcodes, gl4_font_height, gl4_font_height,
|
||||
value - 32, &xf, &yf, &q, 1);
|
||||
|
||||
xdiff = (8 - xf / font_scale) / 2;
|
||||
if (xdiff < 0)
|
||||
{
|
||||
xdiff = 0;
|
||||
}
|
||||
|
||||
GL4_UseProgram(gl4state.si2D.shaderProgram);
|
||||
GL4_Bind(alt ? draw_font_alt->texnum : draw_font->texnum);
|
||||
drawTexturedRectangle(
|
||||
(float)(x + (xdiff + q.x0 / font_scale) * scale),
|
||||
(float)(y + q.y0 * scale / font_scale + 8 * scale),
|
||||
(q.x1 - q.x0) * scale / font_scale,
|
||||
(q.y1 - q.y0) * scale / font_scale,
|
||||
q.s0, q.t0, q.s1, q.t1);
|
||||
x += Q_max(8, xf / font_scale) * scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
x += 8 * scale;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int xor;
|
||||
|
||||
xor = alt ? 0x80 : 0;
|
||||
|
||||
if (value > ' ' && value < 128)
|
||||
{
|
||||
GL4_Draw_CharScaled(x, y, value ^ xor, scale);
|
||||
}
|
||||
|
||||
x += 8 * scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gl4image_t *
|
||||
GL4_Draw_FindPic(const char *name)
|
||||
{
|
||||
|
@ -214,11 +268,18 @@ GL4_Draw_StretchPic(int x, int y, int w, int h, const char *pic)
|
|||
}
|
||||
|
||||
void
|
||||
GL4_Draw_PicScaled(int x, int y, const char *pic, float factor)
|
||||
GL4_Draw_PicScaled(int x, int y, const char *pic, float factor, const char *alttext)
|
||||
{
|
||||
gl4image_t *gl = R_FindPic(pic, (findimage_t)GL4_FindImage);
|
||||
if (!gl)
|
||||
{
|
||||
if (alttext && alttext[0])
|
||||
{
|
||||
/* Show alttext if provided */
|
||||
GL4_Draw_StringScaled(x, y, factor, false, alttext);
|
||||
return;
|
||||
}
|
||||
|
||||
R_Printf(PRINT_ALL, "Can't find pic: %s\n", pic);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -610,42 +610,40 @@ GL4_LoadPic(char *name, byte *pic, int width, int realwidth,
|
|||
* Finds or loads the given image or NULL
|
||||
*/
|
||||
gl4image_t *
|
||||
GL4_FindImage(const char *name, imagetype_t type)
|
||||
GL4_FindImage(const char *originname, imagetype_t type)
|
||||
{
|
||||
char namewe[256], name[256] = {0};
|
||||
gl4image_t *image;
|
||||
int i, len;
|
||||
char *ptr;
|
||||
char namewe[256];
|
||||
const char* ext;
|
||||
int i, len;
|
||||
|
||||
if (!name)
|
||||
if (!originname)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Q_strlcpy(name, originname, sizeof(name));
|
||||
|
||||
/* fix backslashes */
|
||||
Q_replacebackslash(name);
|
||||
|
||||
ext = COM_FileExtension(name);
|
||||
if(!ext[0])
|
||||
if (!ext[0])
|
||||
{
|
||||
/* file has no extension */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = strlen(name);
|
||||
|
||||
/* Remove the extension */
|
||||
memset(namewe, 0, 256);
|
||||
memcpy(namewe, name, len - (strlen(ext) + 1));
|
||||
|
||||
if (len < 5)
|
||||
len = (ext - name) - 1;
|
||||
if ((len < 1) || (len > sizeof(namewe) - 1))
|
||||
{
|
||||
Com_DPrintf("%s: Bad filename %s\n", __func__, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* fix backslashes */
|
||||
while ((ptr = strchr(name, '\\')))
|
||||
{
|
||||
*ptr = '/';
|
||||
}
|
||||
memcpy(namewe, name, len);
|
||||
namewe[len] = 0;
|
||||
|
||||
/* look for it */
|
||||
for (i = 0, image = gl4textures; i < numgl4textures; i++, image++)
|
||||
|
|
|
@ -126,6 +126,7 @@ cvar_t *gl_shadows;
|
|||
cvar_t *gl4_debugcontext;
|
||||
cvar_t *gl4_usebigvbo;
|
||||
cvar_t *r_fixsurfsky;
|
||||
cvar_t *r_ttffont;
|
||||
cvar_t *r_palettedtexture;
|
||||
cvar_t *r_validation;
|
||||
cvar_t *gl4_usefbo;
|
||||
|
@ -228,6 +229,8 @@ GL4_Register(void)
|
|||
r_drawentities = ri.Cvar_Get("r_drawentities", "1", 0);
|
||||
r_drawworld = ri.Cvar_Get("r_drawworld", "1", 0);
|
||||
r_fullbright = ri.Cvar_Get("r_fullbright", "0", 0);
|
||||
/* font should looks good with 8 pixels size */
|
||||
r_ttffont = ri.Cvar_Get("r_ttffont", "RussoOne-Regular", CVAR_ARCHIVE);
|
||||
r_fixsurfsky = ri.Cvar_Get("r_fixsurfsky", "0", CVAR_ARCHIVE);
|
||||
r_palettedtexture = ri.Cvar_Get("r_palettedtexture", "0", 0);
|
||||
r_validation = ri.Cvar_Get("r_validation", "0", CVAR_ARCHIVE);
|
||||
|
@ -362,12 +365,16 @@ SetMode_impl(int *pwidth, int *pheight, int mode, int fullscreen)
|
|||
|
||||
R_Printf(PRINT_ALL, " %dx%d (vid_fullscreen %i)\n", *pwidth, *pheight, fullscreen);
|
||||
|
||||
|
||||
if (!ri.GLimp_InitGraphics(fullscreen, pwidth, pheight))
|
||||
{
|
||||
return rserr_invalid_mode;
|
||||
}
|
||||
|
||||
if (mode == -2 || fullscreen)
|
||||
{
|
||||
GL4_BindVBO(0);
|
||||
}
|
||||
|
||||
/* This is totaly obscure: For some strange reasons the renderer
|
||||
maintains two(!) repesentations of the resolution. One comes
|
||||
from the client and is saved in gl4_newrefdef. The other one
|
||||
|
@ -1590,9 +1597,6 @@ GL4_RenderView(refdef_t *fd)
|
|||
|
||||
GL4_DrawAlphaSurfaces();
|
||||
|
||||
// simple gamma correction
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
|
||||
// Note: R_Flash() is now GL4_Draw_Flash() and called from GL4_RenderFrame()
|
||||
|
||||
if (r_speeds->value)
|
||||
|
@ -1938,6 +1942,7 @@ GetRefAPI(refimport_t imp)
|
|||
re.DrawStretchPic = GL4_Draw_StretchPic;
|
||||
|
||||
re.DrawCharScaled = GL4_Draw_CharScaled;
|
||||
re.DrawStringScaled = GL4_Draw_StringScaled;
|
||||
re.DrawTileClear = GL4_Draw_TileClear;
|
||||
re.DrawFill = GL4_Draw_Fill;
|
||||
re.DrawFadeScreen = GL4_Draw_FadeScreen;
|
||||
|
@ -1990,6 +1995,15 @@ Com_Printf(const char *msg, ...)
|
|||
va_end(argptr);
|
||||
}
|
||||
|
||||
void
|
||||
Com_DPrintf(const char *msg, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
va_start(argptr, msg);
|
||||
ri.Com_VPrintf(PRINT_DEVELOPER, msg, argptr);
|
||||
va_end(argptr);
|
||||
}
|
||||
|
||||
void
|
||||
Com_Error(int code, const char *fmt, ...)
|
||||
{
|
||||
|
|
|
@ -289,7 +289,8 @@ DrawAliasFrameLerp(dmdx_t *paliashdr, entity_t* entity, vec3_t shadelight,
|
|||
|
||||
lerp = s_lerped[0];
|
||||
|
||||
R_LerpVerts(colorOnly, paliashdr->num_xyz, verts, ov, lerp, move, frontv, backv);
|
||||
R_LerpVerts(colorOnly, paliashdr->num_xyz, verts, ov, lerp,
|
||||
move, frontv, backv, entity->scale);
|
||||
|
||||
YQ2_STATIC_ASSERT(sizeof(gl4_alias_vtx_t) == 9 * sizeof(GLfloat), "invalid gl4_alias_vtx_t size");
|
||||
|
||||
|
@ -298,6 +299,11 @@ DrawAliasFrameLerp(dmdx_t *paliashdr, entity_t* entity, vec3_t shadelight,
|
|||
|
||||
for (i = 0; i < num_mesh_nodes; i++)
|
||||
{
|
||||
if (entity->rr_mesh & (1 << i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
DrawAliasFrameLerpCommands(paliashdr, entity, shadelight,
|
||||
order + mesh_nodes[i].ofs_glcmds,
|
||||
order + Q_min(paliashdr->num_glcmds,
|
||||
|
@ -469,7 +475,8 @@ DrawAliasShadow(gl4_shadowinfo_t* shadowInfo)
|
|||
|
||||
// false: don't extrude vertices for powerup - this means the powerup shell
|
||||
// is not seen in the shadow, only the underlying model..
|
||||
R_LerpVerts(false, paliashdr->num_xyz, verts, ov, s_lerped[0], move, frontv, backv);
|
||||
R_LerpVerts(false, paliashdr->num_xyz, verts, ov, s_lerped[0],
|
||||
move, frontv, backv, entity->scale);
|
||||
}
|
||||
|
||||
lheight = entity->origin[2] - shadowInfo->lightspot[2];
|
||||
|
@ -546,6 +553,15 @@ GL4_DrawAliasModel(entity_t *entity)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
/* fix scale */
|
||||
if (!entity->scale[i])
|
||||
{
|
||||
entity->scale[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
gl4model_t* model = entity->model;
|
||||
paliashdr = (dmdx_t *)model->extradata;
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
|
||||
#include "header/local.h"
|
||||
|
||||
YQ2_ALIGNAS_TYPE(int) static byte mod_novis[MAX_MAP_LEAFS / 8];
|
||||
static byte *mod_novis = NULL;
|
||||
static size_t mod_novis_len = 0;
|
||||
|
||||
static gl4model_t mod_known[MAX_MOD_KNOWN];
|
||||
static int mod_numknown = 0;
|
||||
|
@ -66,15 +67,34 @@ Mod_HasFreeSpace(void)
|
|||
const byte *
|
||||
GL4_Mod_ClusterPVS(int cluster, const gl4model_t *model)
|
||||
{
|
||||
if ((cluster == -1) || !model->vis)
|
||||
if (!mod_novis)
|
||||
{
|
||||
Com_Error(ERR_DROP, "%s: incrorrect init of PVS/PHS", __func__);
|
||||
}
|
||||
|
||||
if (!model->vis)
|
||||
{
|
||||
Mod_DecompressVis(NULL, mod_novis, NULL,
|
||||
(model->numclusters + 7) >> 3);
|
||||
return mod_novis;
|
||||
}
|
||||
|
||||
return Mod_DecompressVis((byte *)model->vis +
|
||||
model->vis->bitofs[cluster][DVIS_PVS],
|
||||
if (cluster == -1)
|
||||
{
|
||||
memset(mod_novis, 0, (model->numclusters + 7) >> 3);
|
||||
return mod_novis;
|
||||
}
|
||||
|
||||
if (cluster < 0 || cluster >= model->numvisibility)
|
||||
{
|
||||
Com_Error(ERR_DROP, "%s: bad cluster", __func__);
|
||||
}
|
||||
|
||||
Mod_DecompressVis((byte *)model->vis +
|
||||
model->vis->bitofs[cluster][DVIS_PVS], mod_novis,
|
||||
(byte *)model->vis + model->numvisibility,
|
||||
(model->vis->numclusters + 7) >> 3);
|
||||
(model->numclusters + 7) >> 3);
|
||||
return mod_novis;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -118,7 +138,8 @@ void
|
|||
GL4_Mod_Init(void)
|
||||
{
|
||||
mod_max = 0;
|
||||
memset(mod_novis, 0xff, sizeof(mod_novis));
|
||||
mod_novis = NULL;
|
||||
mod_novis_len = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -363,33 +384,28 @@ Mod_LoadBrushModel(gl4model_t *mod, const void *buffer, int modfilelen)
|
|||
Mod_LoadVisibility(mod->name, &mod->vis, &mod->numvisibility, mod_base,
|
||||
&header->lumps[LUMP_VISIBILITY]);
|
||||
Mod_LoadQBSPLeafs(mod->name, &mod->leafs, &mod->numleafs,
|
||||
mod->marksurfaces, mod->nummarksurfaces, mod_base,
|
||||
&header->lumps[LUMP_LEAFS]);
|
||||
mod->marksurfaces, mod->nummarksurfaces, &mod->numclusters,
|
||||
mod_base, &header->lumps[LUMP_LEAFS]);
|
||||
Mod_LoadQBSPNodes(mod->name, mod->planes, mod->numplanes, mod->leafs,
|
||||
mod->numleafs, &mod->nodes, &mod->numnodes, mod_base,
|
||||
&header->lumps[LUMP_NODES], header->ident);
|
||||
mod->numleafs, &mod->nodes, &mod->numnodes, mod->mins, mod->maxs,
|
||||
mod_base, &header->lumps[LUMP_NODES], header->ident);
|
||||
Mod_LoadSubmodels(mod, mod_base, &header->lumps[LUMP_MODELS]);
|
||||
mod->numframes = 2; /* regular and alternate animation */
|
||||
}
|
||||
|
||||
/* Temporary solution, need to use load file dirrectly */
|
||||
static int
|
||||
Mod_ReadFile(const char *path, void **buffer)
|
||||
{
|
||||
char *data;
|
||||
int size;
|
||||
|
||||
size = ri.FS_LoadFile(path, (void **)&data);
|
||||
if (size <= 0)
|
||||
if (mod->vis && mod->numclusters != mod->vis->numclusters)
|
||||
{
|
||||
return size;
|
||||
Com_Error(ERR_DROP, "%s: Map %s has incorrect number of clusters %d != %d",
|
||||
__func__, mod->name, mod->numclusters, mod->vis->numclusters);
|
||||
}
|
||||
|
||||
*buffer = malloc(size);
|
||||
memcpy(*buffer, data, size);
|
||||
ri.FS_FreeFile((void *)data);
|
||||
|
||||
return size;
|
||||
if ((mod->numleafs > mod_novis_len) || !mod_novis)
|
||||
{
|
||||
/* reallocate buffers for PVS/PHS buffers*/
|
||||
mod_novis_len = (mod->numleafs + 63) & ~63;
|
||||
mod_novis = realloc(mod_novis, mod_novis_len / 8);
|
||||
Com_Printf("Allocated " YQ2_COM_PRIdS " bit leafs of PVS/PHS buffer\n",
|
||||
mod_novis_len);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -398,9 +414,10 @@ Mod_ReadFile(const char *path, void **buffer)
|
|||
static gl4model_t *
|
||||
Mod_ForName(const char *name, gl4model_t *parent_model, qboolean crash)
|
||||
{
|
||||
char filename[256] = {0}, *tag;
|
||||
int i, modfilelen;
|
||||
gl4model_t *mod;
|
||||
void *buf;
|
||||
int i, modfilelen;
|
||||
|
||||
if (!name[0])
|
||||
{
|
||||
|
@ -456,8 +473,18 @@ Mod_ForName(const char *name, gl4model_t *parent_model, qboolean crash)
|
|||
|
||||
strcpy(mod->name, name);
|
||||
|
||||
/* Anachronox has tags in model path*/
|
||||
Q_strlcpy(filename, name, sizeof(filename));
|
||||
tag = strstr(filename, ".mda!");
|
||||
if (tag)
|
||||
{
|
||||
tag += 4; /* strlen(.mda) */
|
||||
*tag = 0;
|
||||
tag ++;
|
||||
}
|
||||
|
||||
/* load the file */
|
||||
modfilelen = ri.Mod_LoadFile(mod->name, &buf);
|
||||
modfilelen = ri.Mod_LoadFile(filename, &buf);
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
|
@ -479,32 +506,14 @@ Mod_ForName(const char *name, gl4model_t *parent_model, qboolean crash)
|
|||
/* call the apropriate loader */
|
||||
switch (LittleLong(*(unsigned *)buf))
|
||||
{
|
||||
case MDAHEADER:
|
||||
/* fall through */
|
||||
case SDEFHEADER:
|
||||
/* fall through */
|
||||
case MDXHEADER:
|
||||
/* fall through */
|
||||
case DKMHEADER:
|
||||
/* fall through */
|
||||
case RAVENFMHEADER:
|
||||
/* fall through */
|
||||
case IDALIASHEADER:
|
||||
/* fall through */
|
||||
case IDMDLHEADER:
|
||||
/* fall through */
|
||||
case ID3HEADER:
|
||||
/* fall through */
|
||||
case MDR_IDENT:
|
||||
/* fall through */
|
||||
case IDMD5HEADER:
|
||||
/* fall through */
|
||||
case IDSPRITEHEADER:
|
||||
{
|
||||
mod->extradata = Mod_LoadModel(mod->name, buf, modfilelen,
|
||||
mod->mins, mod->maxs,
|
||||
(struct image_s ***)&mod->skins, &mod->numskins,
|
||||
(findimage_t)GL4_FindImage, (loadimage_t)GL4_LoadPic, Mod_ReadFile,
|
||||
(findimage_t)GL4_FindImage, (loadimage_t)GL4_LoadPic,
|
||||
&(mod->type));
|
||||
if (!mod->extradata)
|
||||
{
|
||||
|
@ -556,6 +565,13 @@ Mod_Free(gl4model_t *mod)
|
|||
}
|
||||
|
||||
Hunk_Free(mod->extradata);
|
||||
|
||||
if (mod->type == mod_alias || mod->type == mod_sprite)
|
||||
{
|
||||
/* skins are allocated separately */
|
||||
free(mod->skins);
|
||||
}
|
||||
|
||||
memset(mod, 0, sizeof(*mod));
|
||||
}
|
||||
|
||||
|
@ -571,6 +587,14 @@ GL4_Mod_FreeAll(void)
|
|||
Mod_Free(&mod_known[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free PVS buffer */
|
||||
if (mod_novis)
|
||||
{
|
||||
free(mod_novis);
|
||||
mod_novis = NULL;
|
||||
}
|
||||
mod_novis_len = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -53,7 +53,7 @@ enum {
|
|||
*/
|
||||
static void APIENTRY
|
||||
DebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
|
||||
const GLchar *message, const void *userParam)
|
||||
const GLchar *message, const void *userParam)
|
||||
{
|
||||
const char* sourceStr = "Source: Unknown";
|
||||
const char* typeStr = "Type: Unknown";
|
||||
|
@ -155,15 +155,15 @@ void GL4_SetVsync(void)
|
|||
|
||||
#ifdef USE_SDL3
|
||||
int vsyncState;
|
||||
if (SDL_GL_GetSwapInterval(&vsyncState) != 0)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "Failed to get vsync state, assuming vsync inactive.\n");
|
||||
vsyncActive = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
vsyncActive = vsyncState ? true : false;
|
||||
}
|
||||
if (SDL_GL_GetSwapInterval(&vsyncState) != 0)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "Failed to get vsync state, assuming vsync inactive.\n");
|
||||
vsyncActive = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
vsyncActive = vsyncState ? true : false;
|
||||
}
|
||||
#else
|
||||
vsyncActive = SDL_GL_GetSwapInterval() != 0;
|
||||
#endif
|
||||
|
@ -439,9 +439,9 @@ void GL4_ShutdownContext()
|
|||
if(context)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
SDL_GL_DestroyContext(context);
|
||||
SDL_GL_DestroyContext(context);
|
||||
#else
|
||||
SDL_GL_DeleteContext(context);
|
||||
SDL_GL_DeleteContext(context);
|
||||
#endif
|
||||
context = NULL;
|
||||
}
|
||||
|
|
|
@ -726,6 +726,11 @@ RecursiveWorldNode(entity_t *currententity, mnode_t *node)
|
|||
gl4_alpha_surfaces = surf;
|
||||
gl4_alpha_surfaces->texinfo->image = R_TextureAnimation(currententity, surf->texinfo);
|
||||
}
|
||||
else if (surf->texinfo->flags & SURF_NODRAW)
|
||||
{
|
||||
/* Surface should be skipped */
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// calling RenderLightmappedPoly() here probably isn't optimal, rendering everything
|
||||
|
@ -789,11 +794,10 @@ void
|
|||
GL4_MarkLeaves(void)
|
||||
{
|
||||
const byte *vis;
|
||||
YQ2_ALIGNAS_TYPE(int) byte fatvis[MAX_MAP_LEAFS / 8];
|
||||
byte *fatvis = NULL;
|
||||
mnode_t *node;
|
||||
int i, c;
|
||||
int i;
|
||||
mleaf_t *leaf;
|
||||
int cluster;
|
||||
|
||||
if ((gl4_oldviewcluster == gl4_viewcluster) &&
|
||||
(gl4_oldviewcluster2 == gl4_viewcluster2) &&
|
||||
|
@ -835,6 +839,9 @@ GL4_MarkLeaves(void)
|
|||
/* may have to combine two clusters because of solid water boundaries */
|
||||
if (gl4_viewcluster2 != gl4_viewcluster)
|
||||
{
|
||||
int c;
|
||||
|
||||
fatvis = malloc(((gl4_worldmodel->numleafs + 31) / 32) * sizeof(int));
|
||||
memcpy(fatvis, vis, (gl4_worldmodel->numleafs + 7) / 8);
|
||||
vis = GL4_Mod_ClusterPVS(gl4_viewcluster2, gl4_worldmodel);
|
||||
c = (gl4_worldmodel->numleafs + 31) / 32;
|
||||
|
@ -851,6 +858,8 @@ GL4_MarkLeaves(void)
|
|||
i < gl4_worldmodel->numleafs;
|
||||
i++, leaf++)
|
||||
{
|
||||
int cluster;
|
||||
|
||||
cluster = leaf->cluster;
|
||||
|
||||
if (cluster == -1)
|
||||
|
@ -875,5 +884,10 @@ GL4_MarkLeaves(void)
|
|||
while (node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* clean combined buffer */
|
||||
if (fatvis)
|
||||
{
|
||||
free(fatvis);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -180,8 +180,8 @@ enum {
|
|||
// width and height used to be 128, so now we should be able to get the same lightmap data
|
||||
// that used 32 lightmaps before into one, so 4 lightmaps should be enough
|
||||
BLOCK_WIDTH = 1024,
|
||||
BLOCK_HEIGHT = 512,
|
||||
MAX_LIGHTMAPS = 8,
|
||||
BLOCK_HEIGHT = 1024,
|
||||
MAX_LIGHTMAPS = 16,
|
||||
MAX_LIGHTMAPS_PER_SURFACE = MAXLIGHTMAPS // 4
|
||||
};
|
||||
|
||||
|
@ -407,9 +407,10 @@ extern void GL4_Draw_ShutdownLocal(void);
|
|||
extern gl4image_t * GL4_Draw_FindPic(const char *name);
|
||||
extern void GL4_Draw_GetPicSize(int *w, int *h, const char *pic);
|
||||
|
||||
extern void GL4_Draw_PicScaled(int x, int y, const char *pic, float factor);
|
||||
extern void GL4_Draw_PicScaled(int x, int y, const char *pic, float factor, const char *alttext);
|
||||
extern void GL4_Draw_StretchPic(int x, int y, int w, int h, const char *pic);
|
||||
extern void GL4_Draw_CharScaled(int x, int y, int num, float scale);
|
||||
extern void GL4_Draw_StringScaled(int x, int y, float scale, qboolean alt, const char *message);
|
||||
extern void GL4_Draw_TileClear(int x, int y, int w, int h, const char *pic);
|
||||
extern void GL4_DrawFrameBufferObject(int x, int y, int w, int h, GLuint fboTexture, const float v_blend[4]);
|
||||
extern void GL4_Draw_Fill(int x, int y, int w, int h, int c);
|
||||
|
@ -540,6 +541,7 @@ extern cvar_t *r_modulate;
|
|||
extern cvar_t *gl_lightmap;
|
||||
extern cvar_t *gl_shadows;
|
||||
extern cvar_t *r_fixsurfsky;
|
||||
extern cvar_t *r_ttffont;
|
||||
extern cvar_t *r_palettedtexture;
|
||||
extern cvar_t *r_validation;
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ typedef struct model_s
|
|||
msurface_t **marksurfaces;
|
||||
|
||||
int numvisibility;
|
||||
int numclusters;
|
||||
dvis_t *vis;
|
||||
|
||||
byte *lightdata;
|
||||
|
|
|
@ -90,6 +90,7 @@ typedef enum
|
|||
|
||||
#define MAX_MOD_KNOWN (MAX_MODELS * 2)
|
||||
#define MAX_TEXTURES (MAX_IMAGES * 4)
|
||||
#define MAX_FONTCODE 0x500
|
||||
|
||||
extern void R_Printf(int level, const char* msg, ...) PRINTF_ATTR(2, 3);
|
||||
|
||||
|
@ -110,10 +111,6 @@ extern void SmoothColorImage(unsigned *dst, size_t size, size_t rstep);
|
|||
extern void scale2x(const byte *src, byte *dst, int width, int height);
|
||||
extern void scale3x(const byte *src, byte *dst, int width, int height);
|
||||
|
||||
extern float Mod_RadiusFromBounds(const vec3_t mins, const vec3_t maxs);
|
||||
extern const byte* Mod_DecompressVis(const byte *in, const byte* numvisibility,
|
||||
int row);
|
||||
|
||||
/* Shared models struct */
|
||||
|
||||
enum {
|
||||
|
@ -318,29 +315,29 @@ typedef struct
|
|||
} bspxlightgrid_t;
|
||||
|
||||
/* Shared models func */
|
||||
typedef int (*readfile_t)(const char *path, void **buffer);
|
||||
typedef struct image_s* (*findimage_t)(const char *name, imagetype_t type);
|
||||
extern void *Mod_LoadModel(const char *mod_name, const void *buffer, int modfilelen,
|
||||
vec3_t mins, vec3_t maxs, struct image_s ***skins, int *numskins,
|
||||
findimage_t find_image, loadimage_t load_image, readfile_t read_file,
|
||||
modtype_t *type);
|
||||
findimage_t find_image, loadimage_t load_image, modtype_t *type);
|
||||
extern int Mod_ReLoadSkins(const char *name, struct image_s **skins, findimage_t find_image,
|
||||
loadimage_t load_image, void *extradata, modtype_t type);
|
||||
extern struct image_s *GetSkyImage(const char *skyname, const char* surfname,
|
||||
qboolean palettedtexture, findimage_t find_image);
|
||||
extern struct image_s *GetTexImage(const char *name, findimage_t find_image);
|
||||
extern struct image_s *R_FindPic(const char *name, findimage_t find_image);
|
||||
extern struct image_s *R_LoadConsoleChars(findimage_t find_image);
|
||||
extern unsigned R_NextUTF8Code(const char **curr);
|
||||
extern struct image_s *R_LoadImage(const char *name, const char* namewe, const char *ext,
|
||||
imagetype_t type, int r_retexturing, loadimage_t load_image);
|
||||
extern void Mod_LoadQBSPMarksurfaces(const char *name, msurface_t ***marksurfaces,
|
||||
unsigned int *nummarksurfaces, msurface_t *surfaces, int numsurfaces,
|
||||
const byte *mod_base, const lump_t *lMod_LoadQBSPMarksurfaces);
|
||||
extern void Mod_LoadQBSPNodes(const char *name, cplane_t *planes, int numplanes,
|
||||
mleaf_t *leafs, int numleafs, mnode_t **nodes, int *numnodes,
|
||||
mleaf_t *leafs, int numleafs, mnode_t **nodes, int *numnodes, vec3_t mins, vec3_t maxs,
|
||||
const byte *mod_base, const lump_t *l, int ident);
|
||||
extern void Mod_LoadQBSPLeafs(const char *name, mleaf_t **leafs, int *numleafs,
|
||||
msurface_t **marksurfaces, unsigned int nummarksurfaces,
|
||||
const byte *mod_base, const lump_t *l);
|
||||
int *numclusters, const byte *mod_base, const lump_t *l);
|
||||
extern void Mod_LoadQBSPEdges(const char *name, medge_t **edges, int *numedges,
|
||||
const byte *mod_base, const lump_t *l);
|
||||
extern void Mod_LoadVertexes(const char *name, mvertex_t **vertexes, int *numvertexes,
|
||||
|
@ -382,7 +379,7 @@ extern qboolean R_CullAliasMeshModel(dmdx_t *paliashdr, cplane_t *frustum,
|
|||
extern void R_LerpVerts(qboolean powerUpEffect, int nverts,
|
||||
const dxtrivertx_t *v, const dxtrivertx_t *ov,
|
||||
float *lerp, const float move[3],
|
||||
const float frontv[3], const float backv[3]);
|
||||
const float frontv[3], const float backv[3], const float *scale);
|
||||
extern void R_ConvertNormalMDL(byte in_normal, signed char *normal);
|
||||
extern vec4_t *R_VertBufferRealloc(int num);
|
||||
extern void R_VertBufferInit(void);
|
||||
|
|
|
@ -553,7 +553,8 @@ void RE_EndRegistration (void);
|
|||
struct image_s *RE_Draw_FindPic (const char *name);
|
||||
|
||||
void RE_Draw_GetPicSize (int *w, int *h, const char *name);
|
||||
void RE_Draw_PicScaled (int x, int y, const char *name, float scale);
|
||||
void RE_Draw_PicScaled (int x, int y, const char *name, float scale, const char *alttext);
|
||||
void RE_Draw_StringScaled(int x, int y, float scale, qboolean alt, const char *message);
|
||||
void RE_Draw_StretchPic (int x, int y, int w, int h, const char *name);
|
||||
void RE_Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *data, int bits);
|
||||
void RE_Draw_CharScaled (int x, int y, int c, float scale);
|
||||
|
|
|
@ -108,6 +108,7 @@ typedef struct model_s
|
|||
msurface_t **marksurfaces;
|
||||
|
||||
int numvisibility;
|
||||
int numclusters;
|
||||
dvis_t *vis;
|
||||
|
||||
byte *lightdata;
|
||||
|
|
|
@ -457,7 +457,7 @@ R_AliasPreparePoints(const entity_t *currententity, finalvert_t *verts, const fi
|
|||
RF_SHELL_HALF_DAM));
|
||||
|
||||
R_LerpVerts(colorOnly, s_pmdl->num_xyz, r_thisframe->verts, r_lastframe->verts,
|
||||
s_lerped[0], r_lerp_move, r_lerp_frontv, r_lerp_backv);
|
||||
s_lerped[0], r_lerp_move, r_lerp_frontv, r_lerp_backv, currententity->scale);
|
||||
|
||||
R_AliasTransformFinalVerts(s_pmdl->num_xyz,
|
||||
verts, /* destination for transformed verts */
|
||||
|
@ -476,6 +476,11 @@ R_AliasPreparePoints(const entity_t *currententity, finalvert_t *verts, const fi
|
|||
const dtriangle_t *ptri;
|
||||
int num_tris;
|
||||
|
||||
if (currententity->rr_mesh & (1 << i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
num_tris = Q_min(s_pmdl->num_tris - mesh_nodes[i].ofs_tris, mesh_nodes[i].num_tris);
|
||||
ptri = (dtriangle_t *)((byte *)s_pmdl + s_pmdl->ofs_tris) + mesh_nodes[i].ofs_tris;
|
||||
|
||||
|
@ -795,17 +800,21 @@ R_AliasDrawModel
|
|||
void
|
||||
R_AliasDrawModel(entity_t *currententity, const model_t *currentmodel)
|
||||
{
|
||||
int i;
|
||||
|
||||
s_pmdl = (dmdx_t *)currentmodel->extradata;
|
||||
|
||||
if ( r_lerpmodels->value == 0 )
|
||||
{
|
||||
currententity->backlerp = 0;
|
||||
}
|
||||
|
||||
float oldAliasxscale = aliasxscale;
|
||||
float oldAliasyscale = aliasyscale;
|
||||
|
||||
if ( currententity->flags & RF_WEAPONMODEL )
|
||||
if (currententity->flags & RF_WEAPONMODEL)
|
||||
{
|
||||
if ( r_lefthand->value == 2.0F )
|
||||
if (r_lefthand->value == 2.0F)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -821,6 +830,15 @@ R_AliasDrawModel(entity_t *currententity, const model_t *currentmodel)
|
|||
aliasxscale = -aliasxscale;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
/* fix scale */
|
||||
if (!currententity->scale[i])
|
||||
{
|
||||
currententity->scale[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** we have to set our frame pointers and transformations before
|
||||
** doing any real work
|
||||
|
|
|
@ -322,7 +322,7 @@ R_DrawSolidClippedSubmodelPolygons(entity_t *currententity, const model_t *curre
|
|||
numsurfaces = currentmodel->nummodelsurfaces;
|
||||
pedges = currentmodel->edges;
|
||||
|
||||
for (i=0 ; i<numsurfaces ; i++, psurf++)
|
||||
for (i = 0; i < numsurfaces; i++, psurf++)
|
||||
{
|
||||
cplane_t *pplane;
|
||||
bedge_t *pbedge;
|
||||
|
@ -337,7 +337,9 @@ R_DrawSolidClippedSubmodelPolygons(entity_t *currententity, const model_t *curre
|
|||
// draw the polygon
|
||||
if (( !(psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
|
||||
((psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME: use bounding-box-based frustum clipping info?
|
||||
|
||||
|
@ -349,7 +351,7 @@ R_DrawSolidClippedSubmodelPolygons(entity_t *currententity, const model_t *curre
|
|||
pbedge = &bedges[numbedges];
|
||||
numbedges += psurf->numedges;
|
||||
|
||||
for (j=0 ; j<psurf->numedges ; j++)
|
||||
for (j = 0; j < psurf->numedges; j++)
|
||||
{
|
||||
int lindex;
|
||||
|
||||
|
|
|
@ -47,24 +47,7 @@ Draw_InitLocal
|
|||
void
|
||||
Draw_InitLocal (void)
|
||||
{
|
||||
draw_chars = R_FindPic ("conchars", (findimage_t)R_FindImage);
|
||||
|
||||
/* Anachronox */
|
||||
if (!draw_chars)
|
||||
{
|
||||
draw_chars = R_FindPic ("fonts/conchars", (findimage_t)R_FindImage);
|
||||
}
|
||||
|
||||
/* Daikatana */
|
||||
if (!draw_chars)
|
||||
{
|
||||
draw_chars = R_FindPic ("dkchars", (findimage_t)R_FindImage);
|
||||
}
|
||||
|
||||
if (!draw_chars)
|
||||
{
|
||||
Com_Error(ERR_FATAL, "%s: Couldn't load pics/conchars", __func__);
|
||||
}
|
||||
draw_chars = R_LoadConsoleChars((findimage_t)R_FindImage);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -385,25 +368,47 @@ RE_Draw_StretchRaw(int x, int y, int w, int h, int cols, int rows, const byte *d
|
|||
|
||||
RE_Draw_StretchPicImplementation (x, y, w, h, &pic);
|
||||
|
||||
if (r_retexturing->value)
|
||||
if (image_scaled != (byte *)data)
|
||||
{
|
||||
free(image_scaled);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RE_Draw_StringScaled(int x, int y, float scale, qboolean alt, const char *message)
|
||||
{
|
||||
int xor;
|
||||
|
||||
xor = alt ? 0x80 : 0;
|
||||
|
||||
while (*message)
|
||||
{
|
||||
RE_Draw_CharScaled(x * scale, y * scale, *message ^ xor, scale);
|
||||
x += 8 * scale;
|
||||
message ++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Draw_Pic
|
||||
=============
|
||||
*/
|
||||
void
|
||||
RE_Draw_PicScaled(int x, int y, const char *name, float scale)
|
||||
RE_Draw_PicScaled(int x, int y, const char *name, float scale, const char *alttext)
|
||||
{
|
||||
const image_t *pic;
|
||||
|
||||
pic = R_FindPic (name, (findimage_t)R_FindImage);
|
||||
if (!pic)
|
||||
{
|
||||
if (alttext && alttext[0])
|
||||
{
|
||||
/* Show alttext if provided */
|
||||
RE_Draw_StringScaled(x, y, scale, false, alttext);
|
||||
return;
|
||||
}
|
||||
|
||||
R_Printf(PRINT_ALL, "Can't find pic: %s\n", name);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -548,48 +548,47 @@ Finds or loads the given image or NULL
|
|||
===============
|
||||
*/
|
||||
image_t *
|
||||
R_FindImage(const char *name, imagetype_t type)
|
||||
R_FindImage(const char *originname, imagetype_t type)
|
||||
{
|
||||
image_t *image;
|
||||
int i, len;
|
||||
char *ptr;
|
||||
char namewe[256];
|
||||
char namewe[256], name[256] = {0};
|
||||
const char* ext;
|
||||
image_t *image;
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
if (!name)
|
||||
if (!originname)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Q_strlcpy(name, originname, sizeof(name));
|
||||
|
||||
/* just return white image if show lightmap only */
|
||||
if ((type == it_wall || type == it_skin) && r_lightmap->value)
|
||||
{
|
||||
return r_whitetexture_mip;
|
||||
}
|
||||
|
||||
/* fix backslashes */
|
||||
Q_replacebackslash(name);
|
||||
|
||||
ext = COM_FileExtension(name);
|
||||
if(!ext[0])
|
||||
if (!ext[0])
|
||||
{
|
||||
/* file has no extension */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = strlen(name);
|
||||
|
||||
/* Remove the extension */
|
||||
memset(namewe, 0, 256);
|
||||
memcpy(namewe, name, len - (strlen(ext) + 1));
|
||||
|
||||
if (len < 5)
|
||||
len = (ext - name) - 1;
|
||||
if ((len < 1) || (len > sizeof(namewe) - 1))
|
||||
{
|
||||
Com_DPrintf("%s: Bad filename %s\n", __func__, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* fix backslashes */
|
||||
while ((ptr = strchr(name, '\\')))
|
||||
{
|
||||
*ptr = '/';
|
||||
}
|
||||
memcpy(namewe, name, len);
|
||||
namewe[len] = 0;
|
||||
|
||||
// look for it
|
||||
for (i=0, image=r_images ; i<numr_images ; i++,image++)
|
||||
|
|
|
@ -1780,8 +1780,7 @@ RE_IsVsyncActive(void)
|
|||
|
||||
static int RE_PrepareForWindow(void)
|
||||
{
|
||||
int flags = SDL_SWSURFACE;
|
||||
return flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1809,17 +1808,18 @@ GetRefAPI(refimport_t imp)
|
|||
|
||||
// Need to communicate the SDL major version to the client.
|
||||
#ifdef USE_SDL3
|
||||
SDL_Version ver;
|
||||
int version = SDL_VERSIONNUM_MAJOR(SDL_GetVersion());
|
||||
#else
|
||||
SDL_version ver;
|
||||
#endif
|
||||
SDL_VERSION(&ver);
|
||||
int version = ver.major;
|
||||
#endif
|
||||
|
||||
memset(&refexport, 0, sizeof(refexport_t));
|
||||
ri = imp;
|
||||
|
||||
refexport.api_version = API_VERSION;
|
||||
refexport.framework_version = ver.major;
|
||||
refexport.framework_version = version;
|
||||
|
||||
refexport.BeginRegistration = RE_BeginRegistration;
|
||||
refexport.RegisterModel = RE_RegisterModel;
|
||||
|
@ -1835,6 +1835,7 @@ GetRefAPI(refimport_t imp)
|
|||
refexport.DrawPicScaled = RE_Draw_PicScaled;
|
||||
refexport.DrawStretchPic = RE_Draw_StretchPic;
|
||||
refexport.DrawCharScaled = RE_Draw_CharScaled;
|
||||
refexport.DrawStringScaled = RE_Draw_StringScaled;
|
||||
refexport.DrawTileClear = RE_Draw_TileClear;
|
||||
refexport.DrawFill = RE_Draw_Fill;
|
||||
refexport.DrawFadeScreen = RE_Draw_FadeScreen;
|
||||
|
@ -1854,9 +1855,9 @@ GetRefAPI(refimport_t imp)
|
|||
refexport.EndWorldRenderpass = RE_EndWorldRenderpass;
|
||||
refexport.EndFrame = RE_EndFrame;
|
||||
|
||||
// Tell the client that we're unsing the
|
||||
// Tell the client that we're unsing the
|
||||
// new renderer restart API.
|
||||
ri.Vid_RequestRestart(RESTART_NO);
|
||||
ri.Vid_RequestRestart(RESTART_NO);
|
||||
|
||||
Swap_Init ();
|
||||
|
||||
|
@ -1905,19 +1906,32 @@ RE_InitContext(void *win)
|
|||
if (r_vsync->value)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
renderer = SDL_CreateRenderer(window, NULL, SDL_RENDERER_PRESENTVSYNC);
|
||||
renderer = SDL_CreateRenderer(window, NULL);
|
||||
SDL_SetRenderVSync(renderer, 1);
|
||||
#else
|
||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||
if(!renderer)
|
||||
{
|
||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE | SDL_RENDERER_PRESENTVSYNC);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
renderer = SDL_CreateRenderer(window, NULL, 0);
|
||||
renderer = SDL_CreateRenderer(window, NULL);
|
||||
#else
|
||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
||||
if(!renderer)
|
||||
{
|
||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if(!renderer) {
|
||||
Com_Printf("Can't create renderer: %s\n", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Select the color for drawing. It is set to black here. */
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||
|
@ -1963,7 +1977,10 @@ RE_InitContext(void *win)
|
|||
#endif
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
vid_buffer_width, vid_buffer_height);
|
||||
|
||||
if(!texture) {
|
||||
Com_Printf("Can't create texture: %s\n", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
R_InitGraphics(vid_buffer_width, vid_buffer_height);
|
||||
SWimp_CreateRender(vid_buffer_width, vid_buffer_height);
|
||||
|
||||
|
@ -2178,7 +2195,7 @@ RE_BufferDifferenceStart(int vmin, int vmax)
|
|||
return (pixel_t*)back_buffer - swap_frames[0];
|
||||
}
|
||||
|
||||
static int
|
||||
static size_t
|
||||
RE_BufferDifferenceEnd(int vmin, int vmax)
|
||||
{
|
||||
int *front_buffer, *back_buffer;
|
||||
|
@ -2205,7 +2222,11 @@ RE_CleanFrame(void)
|
|||
memset(swap_buffers, 0,
|
||||
vid_buffer_height * vid_buffer_width * sizeof(pixel_t) * 2);
|
||||
|
||||
#ifdef USE_SDL3
|
||||
if (!SDL_LockTexture(texture, NULL, (void**)&pixels, &pitch))
|
||||
#else
|
||||
if (SDL_LockTexture(texture, NULL, (void**)&pixels, &pitch))
|
||||
#endif
|
||||
{
|
||||
Com_Printf("Can't lock texture: %s\n", SDL_GetError());
|
||||
return;
|
||||
|
@ -2237,7 +2258,11 @@ RE_FlushFrame(int vmin, int vmax)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef USE_SDL3
|
||||
if (!SDL_LockTexture(texture, NULL, (void**)&pixels, &pitch))
|
||||
#else
|
||||
if (SDL_LockTexture(texture, NULL, (void**)&pixels, &pitch))
|
||||
#endif
|
||||
{
|
||||
Com_Printf("Can't lock texture: %s\n", SDL_GetError());
|
||||
return;
|
||||
|
@ -2317,7 +2342,11 @@ RE_Draw_StretchDirectRaw(int x, int y, int w, int h, int cols, int rows, const b
|
|||
}
|
||||
|
||||
/* Full screen update should be faster */
|
||||
#ifdef USE_SDL3
|
||||
if (!SDL_LockTexture(texture_rgba, NULL, (void**)&pixels, &pitch))
|
||||
#else
|
||||
if (SDL_LockTexture(texture_rgba, NULL, (void**)&pixels, &pitch))
|
||||
#endif
|
||||
{
|
||||
Com_Printf("Can't lock texture: %s\n", SDL_GetError());
|
||||
return;
|
||||
|
@ -2353,16 +2382,28 @@ RE_Draw_StretchDirectRaw(int x, int y, int w, int h, int cols, int rows, const b
|
|||
|
||||
if (cols == vid_buffer_width && rows == vid_buffer_height)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
SDL_RenderTexture(renderer, texture_rgba, NULL, NULL);
|
||||
#else
|
||||
SDL_RenderCopy(renderer, texture_rgba, NULL, NULL);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
SDL_FRect srcrect;
|
||||
#else
|
||||
SDL_Rect srcrect;
|
||||
#endif
|
||||
srcrect.x = 0;
|
||||
srcrect.y = 0;
|
||||
srcrect.w = cols;
|
||||
srcrect.h = rows;
|
||||
#ifdef USE_SDL3
|
||||
SDL_RenderTexture(renderer, texture_rgba, &srcrect, NULL);
|
||||
#else
|
||||
SDL_RenderCopy(renderer, texture_rgba, &srcrect, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
|
@ -2630,6 +2671,15 @@ Com_Printf(const char *msg, ...)
|
|||
va_end(argptr);
|
||||
}
|
||||
|
||||
void
|
||||
Com_DPrintf(const char *msg, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
va_start(argptr, msg);
|
||||
ri.Com_VPrintf(PRINT_DEVELOPER, msg, argptr);
|
||||
va_end(argptr);
|
||||
}
|
||||
|
||||
void
|
||||
Com_Error(int code, const char *fmt, ...)
|
||||
{
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
#include <limits.h>
|
||||
#include "header/local.h"
|
||||
|
||||
static YQ2_ALIGNAS_TYPE(int) byte mod_novis[MAX_MAP_LEAFS / 8];
|
||||
static byte *mod_novis = NULL;
|
||||
static size_t mod_novis_len = 0;
|
||||
|
||||
static model_t mod_known[MAX_MOD_KNOWN];
|
||||
static int mod_numknown = 0;
|
||||
|
@ -69,15 +70,34 @@ Mod_HasFreeSpace(void)
|
|||
const byte *
|
||||
Mod_ClusterPVS(int cluster, const model_t *model)
|
||||
{
|
||||
if ((cluster == -1) || !model->vis)
|
||||
if (!mod_novis)
|
||||
{
|
||||
Com_Error(ERR_DROP, "%s: incrorrect init of PVS/PHS", __func__);
|
||||
}
|
||||
|
||||
if (!model->vis)
|
||||
{
|
||||
Mod_DecompressVis(NULL, mod_novis, NULL,
|
||||
(model->numclusters + 7) >> 3);
|
||||
return mod_novis;
|
||||
}
|
||||
|
||||
return Mod_DecompressVis((byte *)model->vis +
|
||||
model->vis->bitofs[cluster][DVIS_PVS],
|
||||
if (cluster == -1)
|
||||
{
|
||||
memset(mod_novis, 0, (model->numclusters + 7) >> 3);
|
||||
return mod_novis;
|
||||
}
|
||||
|
||||
if (cluster < 0 || cluster >= model->numvisibility)
|
||||
{
|
||||
Com_Error(ERR_DROP, "%s: bad cluster", __func__);
|
||||
}
|
||||
|
||||
Mod_DecompressVis((byte *)model->vis +
|
||||
model->vis->bitofs[cluster][DVIS_PVS], mod_novis,
|
||||
(byte *)model->vis + model->numvisibility,
|
||||
(model->vis->numclusters + 7) >> 3);
|
||||
(model->numclusters + 7) >> 3);
|
||||
return mod_novis;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -121,7 +141,8 @@ void
|
|||
Mod_Init(void)
|
||||
{
|
||||
mod_max = 0;
|
||||
memset(mod_novis, 0xff, sizeof(mod_novis));
|
||||
mod_novis = NULL;
|
||||
mod_novis_len = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -320,7 +341,7 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen)
|
|||
header = (dheader_t *)mod_base;
|
||||
|
||||
/* check for BSPX extensions */
|
||||
bspx_header = Mod_LoadBSPX(modfilelen, (byte*)mod_base);
|
||||
bspx_header = Mod_LoadBSPX(modfilelen, mod_base);
|
||||
|
||||
// calculate the needed hunksize from the lumps
|
||||
hunkSize = Mod_CalcNonModelLumpHunkSize(mod_base, header);
|
||||
|
@ -368,35 +389,30 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen)
|
|||
Mod_LoadVisibility(mod->name, &mod->vis, &mod->numvisibility, mod_base,
|
||||
&header->lumps[LUMP_VISIBILITY]);
|
||||
Mod_LoadQBSPLeafs(mod->name, &mod->leafs, &mod->numleafs,
|
||||
mod->marksurfaces, mod->nummarksurfaces, mod_base,
|
||||
&header->lumps[LUMP_LEAFS]);
|
||||
mod->marksurfaces, mod->nummarksurfaces, &mod->numclusters,
|
||||
mod_base, &header->lumps[LUMP_LEAFS]);
|
||||
Mod_LoadQBSPNodes(mod->name, mod->planes, mod->numplanes, mod->leafs,
|
||||
mod->numleafs, &mod->nodes, &mod->numnodes, mod_base,
|
||||
&header->lumps[LUMP_NODES], header->ident);
|
||||
mod->numleafs, &mod->nodes, &mod->numnodes, mod->mins, mod->maxs,
|
||||
mod_base, &header->lumps[LUMP_NODES], header->ident);
|
||||
Mod_LoadSubmodels(mod, mod_base, &header->lumps[LUMP_MODELS]);
|
||||
mod->numframes = 2; /* regular and alternate animation */
|
||||
|
||||
R_InitSkyBox(mod);
|
||||
}
|
||||
|
||||
/* Temporary solution, need to use load file dirrectly */
|
||||
static int
|
||||
Mod_ReadFile(const char *path, void **buffer)
|
||||
{
|
||||
char *data;
|
||||
int size;
|
||||
|
||||
size = ri.FS_LoadFile(path, (void **)&data);
|
||||
if (size <= 0)
|
||||
if (mod->vis && mod->numclusters != mod->vis->numclusters)
|
||||
{
|
||||
return size;
|
||||
Com_Error(ERR_DROP, "%s: Map %s has incorrect number of clusters %d != %d",
|
||||
__func__, mod->name, mod->numclusters, mod->vis->numclusters);
|
||||
}
|
||||
|
||||
*buffer = malloc(size);
|
||||
memcpy(*buffer, data, size);
|
||||
ri.FS_FreeFile((void *)data);
|
||||
if ((mod->numleafs > mod_novis_len) || !mod_novis)
|
||||
{
|
||||
/* reallocate buffers for PVS/PHS buffers*/
|
||||
mod_novis_len = (mod->numleafs + 63) & ~63;
|
||||
mod_novis = realloc(mod_novis, mod_novis_len / 8);
|
||||
Com_Printf("Allocated " YQ2_COM_PRIdS " bit leafs of PVS/PHS buffer\n",
|
||||
mod_novis_len);
|
||||
}
|
||||
|
||||
return size;
|
||||
R_InitSkyBox(mod);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -405,9 +421,10 @@ Mod_ReadFile(const char *path, void **buffer)
|
|||
static model_t *
|
||||
Mod_ForName(const char *name, model_t *parent_model, qboolean crash)
|
||||
{
|
||||
char filename[256] = {0}, *tag;
|
||||
int i, modfilelen;
|
||||
model_t *mod;
|
||||
void *buf;
|
||||
int i, modfilelen;
|
||||
|
||||
if (!name[0])
|
||||
{
|
||||
|
@ -463,8 +480,18 @@ Mod_ForName(const char *name, model_t *parent_model, qboolean crash)
|
|||
|
||||
strcpy(mod->name, name);
|
||||
|
||||
/* Anachronox has tags in model path*/
|
||||
Q_strlcpy(filename, name, sizeof(filename));
|
||||
tag = strstr(filename, ".mda!");
|
||||
if (tag)
|
||||
{
|
||||
tag += 4; /* strlen(.mda) */
|
||||
*tag = 0;
|
||||
tag ++;
|
||||
}
|
||||
|
||||
/* load the file */
|
||||
modfilelen = ri.Mod_LoadFile(mod->name, &buf);
|
||||
modfilelen = ri.Mod_LoadFile(filename, &buf);
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
|
@ -486,32 +513,14 @@ Mod_ForName(const char *name, model_t *parent_model, qboolean crash)
|
|||
/* call the apropriate loader */
|
||||
switch (LittleLong(*(unsigned *)buf))
|
||||
{
|
||||
case MDAHEADER:
|
||||
/* fall through */
|
||||
case SDEFHEADER:
|
||||
/* fall through */
|
||||
case MDXHEADER:
|
||||
/* fall through */
|
||||
case DKMHEADER:
|
||||
/* fall through */
|
||||
case RAVENFMHEADER:
|
||||
/* fall through */
|
||||
case IDALIASHEADER:
|
||||
/* fall through */
|
||||
case IDMDLHEADER:
|
||||
/* fall through */
|
||||
case ID3HEADER:
|
||||
/* fall through */
|
||||
case MDR_IDENT:
|
||||
/* fall through */
|
||||
case IDMD5HEADER:
|
||||
/* fall through */
|
||||
case IDSPRITEHEADER:
|
||||
{
|
||||
mod->extradata = Mod_LoadModel(mod->name, buf, modfilelen,
|
||||
mod->mins, mod->maxs,
|
||||
(struct image_s ***)&mod->skins, &mod->numskins,
|
||||
(findimage_t)R_FindImage, (loadimage_t)R_LoadPic, Mod_ReadFile,
|
||||
(findimage_t)R_FindImage, (loadimage_t)R_LoadPic,
|
||||
&(mod->type));
|
||||
if (!mod->extradata)
|
||||
{
|
||||
|
@ -563,6 +572,13 @@ Mod_Free(model_t *mod)
|
|||
}
|
||||
|
||||
Hunk_Free(mod->extradata);
|
||||
|
||||
if (mod->type == mod_alias || mod->type == mod_sprite)
|
||||
{
|
||||
/* skins are allocated separately */
|
||||
free(mod->skins);
|
||||
}
|
||||
|
||||
memset(mod, 0, sizeof(*mod));
|
||||
}
|
||||
|
||||
|
@ -578,6 +594,14 @@ Mod_FreeAll(void)
|
|||
Mod_Free(&mod_known[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free PVS buffer */
|
||||
if (mod_novis)
|
||||
{
|
||||
free(mod_novis);
|
||||
mod_novis = NULL;
|
||||
}
|
||||
mod_novis_len = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -536,6 +536,12 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
|
|||
return;
|
||||
}
|
||||
|
||||
if (fa->texinfo->flags & SURF_NODRAW)
|
||||
{
|
||||
/* Surface should be skipped */
|
||||
return;
|
||||
}
|
||||
|
||||
// sky surfaces encountered in the world will cause the
|
||||
// environment box surfaces to be emited
|
||||
if ( fa->texinfo->flags & SURF_SKY )
|
||||
|
|
|
@ -42,7 +42,7 @@ surfcache_t *sc_base;
|
|||
/*
|
||||
* Color light apply is not required
|
||||
*/
|
||||
static qboolean
|
||||
static int
|
||||
R_GreyscaledLight(const light3_t light)
|
||||
{
|
||||
light3_t light_masked;
|
||||
|
@ -108,6 +108,8 @@ R_DrawSurfaceBlock_Light (pixel_t *prowdest, pixel_t *psource, size_t size,
|
|||
for (b=(size-1); b>=0; b--)
|
||||
{
|
||||
pixel_t pix;
|
||||
int j;
|
||||
|
||||
pix = psource[b];
|
||||
prowdest[b] = R_ApplyLight(pix, light);
|
||||
|
||||
|
|
|
@ -149,6 +149,7 @@ extern cvar_t *r_2D_unfiltered;
|
|||
extern cvar_t *r_videos_unfiltered;
|
||||
extern cvar_t *vk_pixel_size;
|
||||
extern cvar_t *r_fixsurfsky;
|
||||
extern cvar_t *r_ttffont;
|
||||
|
||||
extern cvar_t *vid_fullscreen;
|
||||
extern cvar_t *vid_gamma;
|
||||
|
@ -193,6 +194,7 @@ void R_RenderDlights(void);
|
|||
void R_DrawAlphaSurfaces(void);
|
||||
void RE_InitParticleTexture(void);
|
||||
void Draw_InitLocal(void);
|
||||
void Draw_FreeLocal(void);
|
||||
void R_RotateForEntity(entity_t *e, float *mvMatrix);
|
||||
void R_MarkLeaves(void);
|
||||
|
||||
|
@ -206,9 +208,10 @@ void R_DrawSkyBox(void);
|
|||
struct image_s *RE_Draw_FindPic (const char *name);
|
||||
|
||||
void RE_Draw_GetPicSize (int *w, int *h, const char *name);
|
||||
void RE_Draw_PicScaled (int x, int y, const char *name, float scale);
|
||||
void RE_Draw_PicScaled (int x, int y, const char *name, float scale, const char *alttext);
|
||||
void RE_Draw_StretchPic (int x, int y, int w, int h, const char *name);
|
||||
void RE_Draw_CharScaled (int x, int y, int num, float scale);
|
||||
void RE_Draw_StringScaled(int x, int y, float scale, qboolean alt, const char *message);
|
||||
void RE_Draw_TileClear (int x, int y, int w, int h, const char *name);
|
||||
void RE_Draw_Fill (int x, int y, int w, int h, int c);
|
||||
void RE_Draw_FadeScreen (void);
|
||||
|
@ -275,8 +278,8 @@ typedef struct
|
|||
#define MAX_LIGHTMAPS 256
|
||||
#define DYNLIGHTMAP_OFFSET MAX_LIGHTMAPS
|
||||
|
||||
#define BLOCK_WIDTH 256
|
||||
#define BLOCK_HEIGHT 256
|
||||
#define BLOCK_WIDTH 1024
|
||||
#define BLOCK_HEIGHT 1024
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
|
|
@ -104,6 +104,7 @@ typedef struct model_s
|
|||
msurface_t **marksurfaces;
|
||||
|
||||
int numvisibility;
|
||||
int numclusters;
|
||||
dvis_t *vis;
|
||||
|
||||
byte *lightdata;
|
||||
|
|
|
@ -340,7 +340,7 @@ void QVk_Draw2DCallsRender(void);
|
|||
void QVk_DrawColorRect(float x, float y, float w, float h,
|
||||
float r, float g, float b, float a, qvkrenderpasstype_t rpType);
|
||||
void QVk_DrawTexRect(float x, float y, float w, float h,
|
||||
float u, float v, float us, float vs, qvktexture_t *texture);
|
||||
float u, float v, float us, float vs, const qvktexture_t *texture);
|
||||
void QVk_BindPipeline(qvkpipeline_t *pipeline);
|
||||
void QVk_SubmitStagingBuffers(void);
|
||||
void Qvk_MemoryBarrier(VkCommandBuffer cmdBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
|
||||
|
|
|
@ -279,7 +279,7 @@ static float draw2dcolor_calls[16 * MAXDRAWCALLS] = {0};
|
|||
static float draw2dcolor_r, draw2dcolor_g, draw2dcolor_b, draw2dcolor_a;
|
||||
static qvkrenderpasstype_t draw2dcolor_rpType;
|
||||
static calltype_t draw2dcolor_calltype;
|
||||
static qvktexture_t *draw2dcolor_texture = NULL;
|
||||
static const qvktexture_t *draw2dcolor_texture = NULL;
|
||||
|
||||
VkFormat QVk_FindDepthFormat()
|
||||
{
|
||||
|
@ -1696,7 +1696,8 @@ void QVk_GetDrawableSize(int *width, int *height)
|
|||
#endif
|
||||
}
|
||||
|
||||
void QVk_WaitAndShutdownAll (void)
|
||||
void
|
||||
QVk_WaitAndShutdownAll(void)
|
||||
{
|
||||
if (!vk_initialized)
|
||||
{
|
||||
|
@ -1711,6 +1712,7 @@ void QVk_WaitAndShutdownAll (void)
|
|||
Mod_FreeAll();
|
||||
Mod_FreeModelsKnown();
|
||||
Vk_ShutdownImages();
|
||||
Draw_FreeLocal();
|
||||
Mesh_Free();
|
||||
R_VertBufferFree();
|
||||
QVk_Shutdown();
|
||||
|
@ -2253,7 +2255,9 @@ VkResult QVk_EndFrame(qboolean force)
|
|||
{
|
||||
// continue only if QVk_BeginFrame() had been previously issued
|
||||
if (!vk_frameStarted)
|
||||
{
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
QVk_Draw2DCallsRender();
|
||||
|
||||
|
@ -2592,7 +2596,7 @@ uint8_t *QVk_GetStagingBuffer(VkDeviceSize size, int alignment, VkCommandBuffer
|
|||
stagingBuffer = &vk_stagingBuffers[vk_activeStagingBuffer];
|
||||
if (size > stagingBuffer->resource.size)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s: %d: Resize stanging buffer %" YQ2_COM_PRIu64 "-> %" YQ2_COM_PRIu64 "\n",
|
||||
R_Printf(PRINT_ALL, "%s: %d: Resize stanging buffer " YQ2_COM_PRIdS "-> " YQ2_COM_PRIdS "\n",
|
||||
__func__, vk_activeStagingBuffer, stagingBuffer->resource.size, size);
|
||||
|
||||
DestroyStagingBuffer(stagingBuffer);
|
||||
|
@ -2814,7 +2818,7 @@ QVk_DrawColorRect(float x, float y, float w, float h, float r, float g, float b,
|
|||
|
||||
|
||||
void QVk_DrawTexRect(float x, float y, float w, float h,
|
||||
float u, float v, float us, float vs, qvktexture_t *texture)
|
||||
float u, float v, float us, float vs, const qvktexture_t *texture)
|
||||
{
|
||||
float *last;
|
||||
|
||||
|
|
|
@ -21,63 +21,64 @@
|
|||
*/
|
||||
|
||||
#include "header/local.h"
|
||||
#include "../files/stb_truetype.h"
|
||||
|
||||
static image_t *draw_chars;
|
||||
static int vk_rawTexture_height = 0;
|
||||
static int vk_rawTexture_width = 0;
|
||||
static float vk_font_size = 8.0;
|
||||
static int vk_font_height = 128;
|
||||
static image_t *draw_chars = NULL;
|
||||
static image_t *draw_font = NULL;
|
||||
static image_t *draw_font_alt = NULL;
|
||||
static stbtt_bakedchar *draw_fontcodes = NULL;
|
||||
|
||||
/*
|
||||
===============
|
||||
Draw_InitLocal
|
||||
===============
|
||||
*/
|
||||
void Draw_InitLocal (void)
|
||||
void R_LoadTTFFont(const char *ttffont, int vid_height, float *r_font_size,
|
||||
int *r_font_height, stbtt_bakedchar **draw_fontcodes,
|
||||
struct image_s **draw_font, struct image_s **draw_font_alt,
|
||||
loadimage_t R_LoadPic);
|
||||
|
||||
void
|
||||
Draw_InitLocal(void)
|
||||
{
|
||||
draw_chars = R_FindPic ("conchars", (findimage_t)Vk_FindImage);
|
||||
R_LoadTTFFont(r_ttffont->string, vid.height, &vk_font_size, &vk_font_height,
|
||||
&draw_fontcodes, &draw_font, &draw_font_alt, Vk_LoadPic);
|
||||
|
||||
/* Anachronox */
|
||||
if (!draw_chars)
|
||||
{
|
||||
draw_chars = R_FindPic ("fonts/conchars", (findimage_t)Vk_FindImage);
|
||||
}
|
||||
|
||||
/* Daikatana */
|
||||
if (!draw_chars)
|
||||
{
|
||||
draw_chars = R_FindPic ("dkchars", (findimage_t)Vk_FindImage);
|
||||
}
|
||||
|
||||
if (!draw_chars)
|
||||
{
|
||||
Com_Error(ERR_FATAL, "%s: Couldn't load pics/conchars",
|
||||
__func__);
|
||||
}
|
||||
draw_chars = R_LoadConsoleChars((findimage_t)Vk_FindImage);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_FreeLocal(void)
|
||||
{
|
||||
free(draw_fontcodes);
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
RE_Draw_CharScaled
|
||||
|
||||
Draws one 8*8 graphics character with 0 being transparent.
|
||||
It can be clipped to the top of the screen to allow the console to be
|
||||
smoothly scrolled off.
|
||||
================
|
||||
*/
|
||||
void RE_Draw_CharScaled (int x, int y, int num, float scale)
|
||||
* Draws one 8*8 graphics character with 0 being transparent.
|
||||
* It can be clipped to the top of the screen to allow the console to be
|
||||
* smoothly scrolled off.
|
||||
*/
|
||||
void
|
||||
RE_Draw_CharScaled(int x, int y, int num, float scale)
|
||||
{
|
||||
int row, col;
|
||||
float frow, fcol, size;
|
||||
int row, col;
|
||||
float frow, fcol, size, scaledSize;
|
||||
|
||||
if (!vk_frameStarted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
num &= 255;
|
||||
|
||||
if ((num & 127) == 32)
|
||||
return; // space
|
||||
{
|
||||
return; /* space */
|
||||
}
|
||||
|
||||
if (y <= -8)
|
||||
return; // totally off screen
|
||||
{
|
||||
return; /* totally off screen */
|
||||
}
|
||||
|
||||
row = num >> 4;
|
||||
col = num & 15;
|
||||
|
@ -86,17 +87,76 @@ void RE_Draw_CharScaled (int x, int y, int num, float scale)
|
|||
fcol = col * 0.0625;
|
||||
size = 0.0625;
|
||||
|
||||
scaledSize = 8 * scale;
|
||||
|
||||
QVk_DrawTexRect((float)x / vid.width, (float)y / vid.height,
|
||||
8.f * scale / vid.width, 8.f * scale / vid.height,
|
||||
scaledSize / vid.width, scaledSize / vid.height,
|
||||
fcol, frow, size, size, &draw_chars->vk_texture);
|
||||
}
|
||||
|
||||
void
|
||||
RE_Draw_StringScaled(int x, int y, float scale, qboolean alt, const char *message)
|
||||
{
|
||||
while (*message)
|
||||
{
|
||||
unsigned value = R_NextUTF8Code(&message);
|
||||
|
||||
if (draw_fontcodes && (draw_font || draw_font_alt))
|
||||
{
|
||||
float font_scale;
|
||||
|
||||
font_scale = vk_font_size / 8.0;
|
||||
|
||||
if (value >= 32 && value < MAX_FONTCODE)
|
||||
{
|
||||
float xf = 0, yf = 0, xdiff;
|
||||
stbtt_aligned_quad q;
|
||||
|
||||
stbtt_GetBakedQuad(draw_fontcodes, vk_font_height, vk_font_height,
|
||||
value - 32, &xf, &yf, &q, 1);
|
||||
|
||||
xdiff = (8 - xf / font_scale) / 2;
|
||||
if (xdiff < 0)
|
||||
{
|
||||
xdiff = 0;
|
||||
}
|
||||
|
||||
QVk_DrawTexRect((float)(x + (xdiff + q.x0 / font_scale) * scale) / vid.width,
|
||||
(float)(y + q.y0 * scale / font_scale + 8 * scale) / vid.height,
|
||||
(q.x1 - q.x0) * scale / font_scale / vid.width,
|
||||
(q.y1 - q.y0) * scale / font_scale / vid.height,
|
||||
q.s0, q.t0, q.s1 - q.s0, q.t1 - q.t0,
|
||||
alt ? &draw_font_alt->vk_texture : &draw_font->vk_texture);
|
||||
x += Q_max(8, xf / font_scale) * scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
x += 8 * scale;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int xor;
|
||||
|
||||
xor = alt ? 0x80 : 0;
|
||||
|
||||
if (value > ' ' && value < 128)
|
||||
{
|
||||
RE_Draw_CharScaled(x, y, value ^ xor, scale);
|
||||
}
|
||||
|
||||
x += 8 * scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
RE_Draw_FindPic
|
||||
=============
|
||||
*/
|
||||
image_t *RE_Draw_FindPic (const char *name)
|
||||
image_t *
|
||||
RE_Draw_FindPic(const char *name)
|
||||
{
|
||||
return R_FindPic(name, (findimage_t)Vk_FindImage);
|
||||
}
|
||||
|
@ -106,9 +166,10 @@ image_t *RE_Draw_FindPic (const char *name)
|
|||
RE_Draw_GetPicSize
|
||||
=============
|
||||
*/
|
||||
void RE_Draw_GetPicSize (int *w, int *h, const char *name)
|
||||
void
|
||||
RE_Draw_GetPicSize(int *w, int *h, const char *name)
|
||||
{
|
||||
image_t *image;
|
||||
const image_t *image;
|
||||
|
||||
image = R_FindPic(name, (findimage_t)Vk_FindImage);
|
||||
if (!image)
|
||||
|
@ -126,12 +187,15 @@ void RE_Draw_GetPicSize (int *w, int *h, const char *name)
|
|||
RE_Draw_StretchPic
|
||||
=============
|
||||
*/
|
||||
void RE_Draw_StretchPic (int x, int y, int w, int h, const char *name)
|
||||
void
|
||||
RE_Draw_StretchPic(int x, int y, int w, int h, const char *name)
|
||||
{
|
||||
image_t *vk;
|
||||
|
||||
if (!vk_frameStarted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vk = R_FindPic(name, (findimage_t)Vk_FindImage);
|
||||
if (!vk)
|
||||
|
@ -151,37 +215,46 @@ void RE_Draw_StretchPic (int x, int y, int w, int h, const char *name)
|
|||
RE_Draw_PicScaled
|
||||
=============
|
||||
*/
|
||||
void RE_Draw_PicScaled (int x, int y, const char *name, float scale)
|
||||
void
|
||||
RE_Draw_PicScaled(int x, int y, const char *name, float scale, const char *alttext)
|
||||
{
|
||||
image_t *vk;
|
||||
|
||||
vk = R_FindPic(name, (findimage_t)Vk_FindImage);
|
||||
if (!vk)
|
||||
{
|
||||
if (alttext && alttext[0])
|
||||
{
|
||||
/* Show alttext if provided */
|
||||
RE_Draw_StringScaled(x, y, scale, false, alttext);
|
||||
return;
|
||||
}
|
||||
|
||||
R_Printf(PRINT_ALL, "%s(): Can't find pic: %s\n", __func__, name);
|
||||
return;
|
||||
}
|
||||
|
||||
RE_Draw_StretchPic(x, y, vk->width*scale, vk->height*scale, name);
|
||||
RE_Draw_StretchPic(x, y, vk->width * scale, vk->height * scale, name);
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
RE_Draw_TileClear
|
||||
|
||||
This repeats a 64*64 tile graphic to fill the screen around a sized down
|
||||
refresh window.
|
||||
=============
|
||||
*/
|
||||
void RE_Draw_TileClear (int x, int y, int w, int h, const char *name)
|
||||
* This repeats a 64*64 tile graphic to fill
|
||||
* the screen around a sized down
|
||||
* refresh window.
|
||||
*/
|
||||
void
|
||||
RE_Draw_TileClear(int x, int y, int w, int h, const char *name)
|
||||
{
|
||||
image_t *image;
|
||||
const image_t *image;
|
||||
float divisor;
|
||||
|
||||
if (!vk_frameStarted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
image = R_FindPic(name, (findimage_t)Vk_FindImage);
|
||||
|
||||
if (!image)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s(): Can't find pic: %s\n", __func__, name);
|
||||
|
@ -219,27 +292,27 @@ void RE_Draw_TileClear (int x, int y, int w, int h, const char *name)
|
|||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
RE_Draw_Fill
|
||||
|
||||
Fills a box of pixels with a single color
|
||||
=============
|
||||
*/
|
||||
void RE_Draw_Fill (int x, int y, int w, int h, int c)
|
||||
* Fills a box of pixels with a single color
|
||||
*/
|
||||
void
|
||||
RE_Draw_Fill(int x, int y, int w, int h, int c)
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned c;
|
||||
byte v[4];
|
||||
unsigned c;
|
||||
byte v[4];
|
||||
} color;
|
||||
|
||||
if (!vk_frameStarted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((unsigned)c > 255)
|
||||
{
|
||||
Com_Error(ERR_FATAL, "%s: bad color", __func__);
|
||||
}
|
||||
|
||||
color.c = d_8to24table[c];
|
||||
|
||||
|
@ -261,10 +334,13 @@ RE_Draw_FadeScreen
|
|||
|
||||
================
|
||||
*/
|
||||
void RE_Draw_FadeScreen (void)
|
||||
void
|
||||
RE_Draw_FadeScreen(void)
|
||||
{
|
||||
if (!vk_frameStarted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QVk_DrawColorRect(
|
||||
0.0f, 0.0f, 1.0f, 1.0f,
|
||||
|
@ -281,20 +357,20 @@ void RE_Draw_FadeScreen (void)
|
|||
RE_Draw_StretchRaw
|
||||
=============
|
||||
*/
|
||||
static int vk_rawTexture_height;
|
||||
static int vk_rawTexture_width;
|
||||
|
||||
void RE_Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *data, int bits)
|
||||
void
|
||||
RE_Draw_StretchRaw(int x, int y, int w, int h, int cols, int rows, const byte *data, int bits)
|
||||
{
|
||||
|
||||
int i, j;
|
||||
int i, j;
|
||||
unsigned *dest;
|
||||
byte *source;
|
||||
byte *image_scaled = NULL;
|
||||
unsigned *raw_image32;
|
||||
|
||||
if (!vk_frameStarted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (bits == 32)
|
||||
{
|
||||
|
|
|
@ -1187,41 +1187,40 @@ Finds or loads the given image or NULL
|
|||
===============
|
||||
*/
|
||||
image_t *
|
||||
Vk_FindImage(const char *name, imagetype_t type)
|
||||
Vk_FindImage(const char *originname, imagetype_t type)
|
||||
{
|
||||
image_t *image;
|
||||
int i, len;
|
||||
char *ptr;
|
||||
char namewe[256];
|
||||
char namewe[256], name[256] = {0};
|
||||
const char* ext;
|
||||
image_t *image;
|
||||
int i, len;
|
||||
|
||||
if (!name)
|
||||
if (!originname)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Q_strlcpy(name, originname, sizeof(name));
|
||||
|
||||
/* fix backslashes */
|
||||
Q_replacebackslash(name);
|
||||
|
||||
ext = COM_FileExtension(name);
|
||||
if(!ext[0])
|
||||
if (!ext[0])
|
||||
{
|
||||
/* file has no extension */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = strlen(name);
|
||||
if (len < 5)
|
||||
/* Remove the extension */
|
||||
len = (ext - name) - 1;
|
||||
if ((len < 1) || (len > sizeof(namewe) - 1))
|
||||
{
|
||||
Com_DPrintf("%s: Bad filename %s\n", __func__, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Remove the extension */
|
||||
memset(namewe, 0, sizeof(namewe));
|
||||
memcpy(namewe, name, len - (strlen(ext) + 1));
|
||||
|
||||
/* fix backslashes */
|
||||
while ((ptr = strchr(name, '\\')))
|
||||
{
|
||||
*ptr = '/';
|
||||
}
|
||||
memcpy(namewe, name, len);
|
||||
namewe[len] = 0;
|
||||
|
||||
/* look for it */
|
||||
for (i=0, image=vktextures ; i<numvktextures ; i++,image++)
|
||||
|
|
|
@ -139,6 +139,7 @@ cvar_t *r_lerp_list;
|
|||
cvar_t *r_2D_unfiltered;
|
||||
cvar_t *r_videos_unfiltered;
|
||||
cvar_t *r_fixsurfsky;
|
||||
cvar_t *r_ttffont;
|
||||
|
||||
cvar_t *vid_fullscreen;
|
||||
cvar_t *vid_gamma;
|
||||
|
@ -1207,6 +1208,8 @@ R_Register(void)
|
|||
/* don't bilerp videos */
|
||||
r_videos_unfiltered = ri.Cvar_Get("r_videos_unfiltered", "0", CVAR_ARCHIVE);
|
||||
r_fixsurfsky = ri.Cvar_Get("r_fixsurfsky", "0", CVAR_ARCHIVE);
|
||||
/* font should looks good with 8 pixels size */
|
||||
r_ttffont = ri.Cvar_Get("r_ttffont", "RussoOne-Regular", CVAR_ARCHIVE);
|
||||
|
||||
// clamp vk_msaa to accepted range so that video menu doesn't crash on us
|
||||
if (vk_msaa->value < 0)
|
||||
|
@ -1716,6 +1719,20 @@ static int RE_PrepareForWindow(void)
|
|||
return SDL_WINDOW_VULKAN;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
RE_GetSDLVersion(void)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
int version = SDL_GetVersion();
|
||||
return SDL_VERSIONNUM_MAJOR(version);
|
||||
#else
|
||||
SDL_version ver;
|
||||
SDL_VERSION(&ver);
|
||||
return ver.major;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
GetRefAPI
|
||||
|
@ -1726,18 +1743,10 @@ GetRefAPI(refimport_t imp)
|
|||
{
|
||||
refexport_t refexport = {0};
|
||||
|
||||
// Need to communicate the SDL major version to the client.
|
||||
#ifdef USE_SDL3
|
||||
SDL_Version ver;
|
||||
#else
|
||||
SDL_version ver;
|
||||
#endif
|
||||
SDL_VERSION(&ver);
|
||||
|
||||
ri = imp;
|
||||
|
||||
refexport.api_version = API_VERSION;
|
||||
refexport.framework_version = ver.major;
|
||||
refexport.framework_version = RE_GetSDLVersion();
|
||||
|
||||
refexport.BeginRegistration = RE_BeginRegistration;
|
||||
refexport.RegisterModel = RE_RegisterModel;
|
||||
|
@ -1752,6 +1761,7 @@ GetRefAPI(refimport_t imp)
|
|||
refexport.DrawPicScaled = RE_Draw_PicScaled;
|
||||
refexport.DrawStretchPic = RE_Draw_StretchPic;
|
||||
refexport.DrawCharScaled = RE_Draw_CharScaled;
|
||||
refexport.DrawStringScaled = RE_Draw_StringScaled;
|
||||
refexport.DrawTileClear = RE_Draw_TileClear;
|
||||
refexport.DrawFill = RE_Draw_Fill;
|
||||
refexport.DrawFadeScreen= RE_Draw_FadeScreen;
|
||||
|
@ -1814,6 +1824,15 @@ Com_Printf(const char *msg, ...)
|
|||
va_end(argptr);
|
||||
}
|
||||
|
||||
void
|
||||
Com_DPrintf(const char *msg, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
va_start(argptr, msg);
|
||||
ri.Com_VPrintf(PRINT_DEVELOPER, msg, argptr);
|
||||
va_end(argptr);
|
||||
}
|
||||
|
||||
void
|
||||
Com_Error(int code, const char *fmt, ...)
|
||||
{
|
||||
|
|
|
@ -359,7 +359,7 @@ Vk_DrawAliasFrameLerp(entity_t *currententity, dmdx_t *paliashdr, float backlerp
|
|||
}
|
||||
|
||||
R_LerpVerts(colorOnly, paliashdr->num_xyz, verts, ov, (float*)s_lerped,
|
||||
move, frontv, backv);
|
||||
move, frontv, backv, currententity->scale);
|
||||
|
||||
VkDescriptorSet descriptorSets[] = {
|
||||
skin->vk_texture.descriptorSet,
|
||||
|
@ -383,6 +383,11 @@ Vk_DrawAliasFrameLerp(entity_t *currententity, dmdx_t *paliashdr, float backlerp
|
|||
|
||||
for (i = 0; i < num_mesh_nodes; i++)
|
||||
{
|
||||
if (currententity->rr_mesh & (1 << i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Vk_DrawAliasFrameLerpCommands(
|
||||
order + mesh_nodes[i].ofs_glcmds,
|
||||
order + Q_min(paliashdr->num_glcmds,
|
||||
|
@ -527,6 +532,15 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
/* fix scale */
|
||||
if (!currententity->scale[i])
|
||||
{
|
||||
currententity->scale[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
paliashdr = (dmdx_t *)currentmodel->extradata;
|
||||
|
||||
/* get lighting information */
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue