mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 01:01:33 +00:00
Merge branch 'next' into instant-setscale
This commit is contained in:
commit
52f53f03b7
68 changed files with 3095 additions and 4522 deletions
|
@ -94,7 +94,7 @@ default:
|
|||
- - |
|
||||
# apt_common
|
||||
echo -e "\e[0Ksection_start:`date +%s`:apt_common[collapsed=true]\r\e[0KInstalling common packages"
|
||||
- apt-get install make git ccache nasm
|
||||
- apt-get install make git ccache nasm cmake ca-certificates
|
||||
- |
|
||||
# apt_common
|
||||
echo -e "\e[0Ksection_end:`date +%s`:apt_common\r\e[0K"
|
||||
|
@ -526,21 +526,22 @@ Windows x64:
|
|||
Debian stable Clang:
|
||||
stage: build
|
||||
|
||||
when: manual
|
||||
when: on_success
|
||||
|
||||
allow_failure: true
|
||||
allow_failure: false
|
||||
|
||||
artifacts:
|
||||
paths:
|
||||
- "bin/"
|
||||
- "src/comptime.h"
|
||||
- "build.clang/bin/"
|
||||
- "build.clang/src/comptime.h"
|
||||
expose_as: "clang"
|
||||
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-clang"
|
||||
|
||||
variables:
|
||||
CC: clang
|
||||
WFLAGS: -Wno-cast-align
|
||||
CFLAGS: -Wno-cast-align
|
||||
CXX: clang
|
||||
WFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror
|
||||
CFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror
|
||||
LDFLAGS: -Wl,-fuse-ld=gold
|
||||
|
||||
script:
|
||||
|
@ -560,10 +561,18 @@ Debian stable Clang:
|
|||
# apt_development
|
||||
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
|
||||
|
||||
- - |
|
||||
# cmake
|
||||
echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
|
||||
- cmake -B build.clang -D CPM_USE_LOCAL_PACKAGES:BOOL=ON -D SRB2_CONFIG_ENABLE_TESTS:BOOL=OFF -D SRB2_CONFIG_SYSTEM_LIBRARIES:BOOL=ON -G "Unix Makefiles"
|
||||
- |
|
||||
# cmake
|
||||
echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
|
||||
|
||||
- - |
|
||||
# make
|
||||
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
|
||||
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1
|
||||
- make --directory=build.clang --keep-going || make --directory=src --keep-going
|
||||
- |
|
||||
# make
|
||||
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
|
||||
|
@ -573,19 +582,22 @@ Debian testing Clang:
|
|||
|
||||
when: manual
|
||||
|
||||
allow_failure: true
|
||||
|
||||
image: debian:testing-slim
|
||||
|
||||
artifacts:
|
||||
paths:
|
||||
- "bin/"
|
||||
- "src/comptime.h"
|
||||
- "build.clang/bin/"
|
||||
- "build.clang/src/comptime.h"
|
||||
expose_as: "testing-clang"
|
||||
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-clang"
|
||||
|
||||
variables:
|
||||
CC: clang
|
||||
WFLAGS: -Wno-cast-align -Wno-deprecated-non-prototype -Wno-single-bit-bitfield-constant-conversion
|
||||
CFLAGS: -Wno-cast-align -Wno-deprecated-non-prototype -Wno-single-bit-bitfield-constant-conversion
|
||||
CXX: clang
|
||||
WFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror -Wno-deprecated-non-prototype -Wno-single-bit-bitfield-constant-conversion
|
||||
CFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror -Wno-deprecated-non-prototype -Wno-single-bit-bitfield-constant-conversion
|
||||
LDFLAGS: -Wl,-fuse-ld=gold
|
||||
|
||||
Alpine 3 GCC:
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
================================================================
|
||||
How to add Low-res modes to your XF86Config under Linux MANUALLY
|
||||
================================================================
|
||||
|
||||
I TAKE NO RESPONSIBILITY FOR ANY DAMAGE DONE TO YOUR EQUIPMENT!!!
|
||||
|
||||
This document explains how to add low-res modes like 320x200 to your
|
||||
X-Server configuration, because some new setup tools for the X-Server
|
||||
do not support this. ONLY RECOMMENDED FOR USERS WHO KNOW WHAT THEY DO!
|
||||
|
||||
I do not take any responsibility for damage done to your monitor, your
|
||||
videocard, your harddisk, your cat, your dog or anything else!!!
|
||||
IMPORTANT IS, THAT YOUR "HorizSync" AND "VertRefresh" VALUES REALLY
|
||||
MATCH YOUR MONITOR! OTHERWISE YOUR MONITOR CAN BLOW UP!!!
|
||||
|
||||
OK, if you have read up to here, you either know what you do or really
|
||||
die-hard want those low-res modes. Here is what to do:
|
||||
Look up your XF86Config. Is is either in /etc or in /etc/X11. Here is
|
||||
what you have to add to the definition of your modeslines:
|
||||
|
||||
# Low-res Doublescan modes
|
||||
# If your chipset does not support doublescan, you get a 'squashed'
|
||||
# resolution like 320x400.
|
||||
|
||||
# 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio
|
||||
Modeline "320x200" 12.588 320 336 384 400 200 204 205 225 Doublescan
|
||||
# 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio
|
||||
Modeline "320x240" 12.588 320 336 384 400 240 245 246 262 Doublescan
|
||||
# 320x240 @ 72 Hz, 36.5 kHz hsync
|
||||
Modeline "320x240" 15.750 320 336 384 400 240 244 246 262 Doublescan
|
||||
# 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio
|
||||
ModeLine "400x300" 18 400 416 448 512 300 301 302 312 Doublescan
|
||||
# 400x300 @ 60 Hz, 37.8 kHz hsync
|
||||
Modeline "400x300" 20 400 416 480 528 300 301 303 314 Doublescan
|
||||
# 400x300 @ 72 Hz, 48.0 kHz hsync
|
||||
Modeline "400x300" 25 400 424 488 520 300 319 322 333 Doublescan
|
||||
|
||||
If your video card only supports a specific set of discrete dotclocks
|
||||
(RAMDAC) you may have to replace the dotclocks given here by one of the
|
||||
specified (e.g in the first modeline the dotclock is 12.588 MHz). I believe
|
||||
that nowadays all cards and monitors should work with these settings, but
|
||||
if you have outdated hardware you better check the frequencies yourself. If
|
||||
there is any uncertainty, please check the "XFree86 Video Timings HOWTO".
|
||||
|
||||
|
||||
Then have a look at the section "Screen" with the appropriate driver
|
||||
(usually either "svga" or "accel"). Under Subsection "Display" there
|
||||
are modes for the given color depth. Add the desired modes. As an
|
||||
example I give you my screens definition here with low-res modes in
|
||||
16 bit color depth:
|
||||
|
||||
Section "Screen"
|
||||
Driver "accel"
|
||||
Device "3D Charger"
|
||||
Monitor "Iiyama Pro 450"
|
||||
DefaultColorDepth 16
|
||||
|
||||
Subsection "Display"
|
||||
Depth 8
|
||||
Modes "1280x1024" "1024x768" "800x600" "640x480"
|
||||
ViewPort 0 0
|
||||
Virtual 1280 1024
|
||||
EndSubsection
|
||||
Subsection "Display"
|
||||
Depth 16
|
||||
Modes "1152x864" "1024x768" "800x600" "640x480" "400x300" "320x200" <- THIS IS ACTUALLY WHAT YOU WANT!!!
|
||||
ViewPort 0 0 ^^^^^^^^^^^^^^^^^^^
|
||||
Virtual 1152 864
|
||||
EndSubsection
|
||||
Subsection "Display"
|
||||
Depth 24
|
||||
Modes "800x600" "640x480"
|
||||
ViewPort 0 0
|
||||
Virtual 800 600
|
||||
EndSubsection
|
||||
Subsection "Display"
|
||||
Depth 32
|
||||
Modes "800x600" "640x480"
|
||||
ViewPort 0 0
|
||||
Virtual 800 600
|
||||
EndSubsection
|
||||
EndSection
|
||||
|
||||
Once again: important is, that you edit the correct Screen section.
|
||||
If you use the SVGA Server and edit the ACCEL Server, you might
|
||||
wonder where your new modes have gone.
|
||||
|
||||
If everything went fine and you want to say thank you, just write
|
||||
to "metzgermeister@users.sourceforge.net". If your monitor blew
|
||||
up and you want to kill me, find me playing Legacy or Q3A on the net
|
||||
and frag me (with your second monitor, hehe).
|
||||
|
||||
- metzgermeister
|
|
@ -1,212 +0,0 @@
|
|||
1-99 : Player Starts
|
||||
1 - Player 1 Start 1
|
||||
2 - Player 2 Start 2
|
||||
3 - Player 3 Start 3
|
||||
4 - Player 4 Start 4
|
||||
5 - Player 5 Start 4001
|
||||
6 - Player 6 Start 4002
|
||||
7 - Player 7 Start 4003
|
||||
8 - Player 8 Start 4004
|
||||
9 - Player 9 Start 4005
|
||||
10 - Player 10 Start 4006
|
||||
11 - Player 11 Start 4007
|
||||
12 - Player 12 Start 4008
|
||||
13 - Player 13 Start 4009
|
||||
14 - Player 14 Start 4010
|
||||
15 - Player 15 Start 4011
|
||||
16 - Player 16 Start 4012
|
||||
17 - Player 17 Start 4013
|
||||
18 - Player 18 Start 4014
|
||||
19 - Player 19 Start 4015
|
||||
20 - Player 20 Start 4016
|
||||
21 - Player 21 Start 4017
|
||||
22 - Player 22 Start 4018
|
||||
23 - Player 23 Start 4019
|
||||
24 - Player 24 Start 4020
|
||||
25 - Player 25 Start 4021
|
||||
26 - Player 26 Start 4022
|
||||
27 - Player 27 Start 4023
|
||||
28 - Player 28 Start 4024
|
||||
29 - Player 29 Start 4025
|
||||
30 - Player 30 Start 4026
|
||||
31 - Player 31 Start 4027
|
||||
32 - Player 32 Start 4028
|
||||
33 - Player Match Start 11
|
||||
34 - Red Team Start 87
|
||||
35 - Blue Team Start 89
|
||||
36 - Tag start New
|
||||
|
||||
100 - 199 : Enemies
|
||||
100 - Blue Crawla 3004
|
||||
101 - Red Crawla 9
|
||||
102 - GFZ Fish 58
|
||||
103 - Gold Buzz 5005
|
||||
104 - Red Buzz 5006
|
||||
105 - Jetty-Syn Bomber 3005
|
||||
106 - Jetty-Syn Gunner 22
|
||||
107 - Crawla Commander 21
|
||||
108 - Deton 71
|
||||
109 - Skim 56
|
||||
110 - THZ Turret 2004
|
||||
111 - Pop-up Turret 42
|
||||
|
||||
200 - 299 : Bosses and their associated items (if any)
|
||||
200 - Boss 1 16
|
||||
201 - Boss 2 2008
|
||||
290 - Boss Fly Point 17
|
||||
291 - EggTrap Center 2049
|
||||
|
||||
300 - 399 : Collectibles
|
||||
300 - Ring 2014
|
||||
301 - Homing Ring 69
|
||||
302 - Rail Ring 3003
|
||||
303 - Infinity Ring 80
|
||||
304 - Automatic Ring 26
|
||||
305 - Explosion Ring 54
|
||||
306 - Red CTF Flag 31
|
||||
307 - Blue CTF Flag 34
|
||||
308 - Special Stage Token 2013
|
||||
309 - Emerald 1 420
|
||||
310 - Emerald 2 421
|
||||
311 - Emerald 3 422
|
||||
312 - Emerald 4 423
|
||||
313 - Emerald 5 424
|
||||
314 - Emerald 6 425
|
||||
315 - Emerald 7 426
|
||||
316 - Hunting Emerald 1 64
|
||||
317 - Hunting Emerald 2 3002
|
||||
318 - Hunting Emerald 3 3001
|
||||
|
||||
400 - 499 : Boxes
|
||||
400 - Super Ring Box 2011
|
||||
401 - Grey Ring Box 2012
|
||||
402 - Ring Shield Box 48
|
||||
403 - Fire Shield Box 2002
|
||||
404 - Bomb Shield Box 2018
|
||||
405 - Jump Shield Box 35
|
||||
406 - Water Shield Box 2028
|
||||
407 - Sneaker Box 25
|
||||
408 - Invincibility Box 2022
|
||||
409 - 1-Up Box 41
|
||||
410 - Eggman Box 2005
|
||||
411 - Mixup Box 78
|
||||
412 - Question Box 3000
|
||||
|
||||
500 - 599 : Interactive Objects (friendly or otherwise - includes springs)
|
||||
500 - Bubble Patch 33
|
||||
501 - Level End Sign 86
|
||||
502 - Starpost 3006
|
||||
520 - Spike Ball -1
|
||||
521 - Special Stage Spike Ball 23
|
||||
522 - Ceiling Spike 67
|
||||
523 - Floor Spike 68
|
||||
540 - Fan 32
|
||||
541 - Steam Riser 30
|
||||
550 - Yellow Spring 28
|
||||
551 - Red Spring 79
|
||||
552 - Blue Spring 5004
|
||||
553 - Yellow Spring Down 65
|
||||
554 - Red Spring Down 66
|
||||
555 - Yellow Diagonal Spring 2015
|
||||
556 - Red Diagonal Spring 38
|
||||
557 - Yellow Diag Spring Down 20
|
||||
558 - Red Diag Spring Down 39
|
||||
|
||||
600 - 699 : Special placement patterns
|
||||
600 - Vertical Rigns - Stack of 5 (suitable for Yellow Spring) 84
|
||||
601 - Vertical Rings - Stack of 5 (suitable for Red Spring) 44
|
||||
602 - Diagonal rings (5) 76
|
||||
603 - Diagonal rings (10) 77
|
||||
604 - A ring of rings 47
|
||||
605 - A BIGGER ring of rings 2007
|
||||
606 - A ring of wing items 2048
|
||||
607 - A BIGGER ring of wing items 2010
|
||||
608 - A ring of rings and wings (alternating) 2046
|
||||
609 - A BIGGER ring of rings and wings (alternating) 2047
|
||||
|
||||
700 - 799 : Powerup indicators/environmental effects/miscellany
|
||||
700 - Ambient Water 1a (S) 2026
|
||||
701 - Ambient Water 1b (S) 2024
|
||||
702 - Ambient Water 2a (M) 2023
|
||||
703 - Ambient Water 2b (M) 2045
|
||||
704 - Ambient Water 3a (L) 83
|
||||
705 - Ambient Water 3b (L) 2019
|
||||
706 - Ambient Water 4a (XL) 2025
|
||||
707 - Ambient Water 4b (XL) 27
|
||||
708 - Random Ambient 1 14
|
||||
709 - Random Ambient 2 43
|
||||
750 - Chaos Spawner 8
|
||||
751 - Teleport Point 5003
|
||||
752 - Alternate View Point 5007
|
||||
753 - Zoom Tube Waypoint 18
|
||||
754 - Pusher 5001
|
||||
755 - Puller 5002
|
||||
756 - Street Light 2003
|
||||
|
||||
800 - 899 : Greenflower Scenery
|
||||
800 - Flower 1 36
|
||||
801 - Flower 2 70
|
||||
802 - Flower 3 73
|
||||
804 - Berry Bush 74
|
||||
805 - Bush 75
|
||||
|
||||
900 - 999 : Techno Hill Scenery
|
||||
900 - THZ Plant 2035
|
||||
901 - Alarm 2006
|
||||
|
||||
1000 - 1099 : Deep Sea Scenery
|
||||
1000 - Gargoyle 81
|
||||
|
||||
1100 - 1199 : Castle Eggman Scenery
|
||||
1100 - Ceiling Chain 49
|
||||
1101 - Torch Flame 24
|
||||
1102 - Eggman Statue 52
|
||||
1103 - CEZ Flower 2001
|
||||
|
||||
1200 - 1299 : Arid Canyon Scenery
|
||||
1300 - 1399 : Red Volcano Scenery
|
||||
1400 - 1499 : Dark City Scenery
|
||||
1500 - 1599 : Doom Ship Scenery
|
||||
1600 - 1699 : Egg Rock/Final Fight Scenery
|
||||
1700 - 1799 : NiGHTS Items
|
||||
1700 - Axis 72
|
||||
1701 - Axis Transfer (Normal) 61
|
||||
1702 - Axis Transfer (Line) 46
|
||||
1703 - Nights Drone 60
|
||||
1704 - Nights Bumper 82
|
||||
1705 - Hoop 57
|
||||
1706 - Nights Wing 37
|
||||
1707 - Super Loop Powerup 3007
|
||||
1708 - Drill Refill Powerup 3008
|
||||
1709 - Helper Powerup 3009
|
||||
1710 - Egg Capsule 40
|
||||
|
||||
1800 - 1849 : Mario Items
|
||||
1800 - Coin 10005
|
||||
1801 - Goomba 10000
|
||||
1802 - Blue Goomba 10001
|
||||
1803 - FireFlower 50
|
||||
1804 - Shell 10
|
||||
1805 - Puma 29
|
||||
1806 - Koopa 19
|
||||
1807 - Axe 12
|
||||
1808 - Mario Bush 1 10002
|
||||
1809 - Mario Bush 2 10003
|
||||
1810 - Toad 10004
|
||||
|
||||
1850 - 1899 : Christmas Items
|
||||
1850 - Xmas Pole 5
|
||||
1851 - Candy Cane 13
|
||||
1852 - Snowman 6
|
||||
|
||||
1900 - 1999 : Misc Scenery
|
||||
1900 - Stalagmite 0
|
||||
1901 - Stalagmite 1
|
||||
1902 - Stalagmite 2
|
||||
1903 - Stalagmite 3
|
||||
1904 - Stalagmite 4
|
||||
1905 - Stalagmite 5
|
||||
1906 - Stalagmite 6
|
||||
1907 - Stalagmite 7
|
||||
1908 - Stalagmite 8
|
||||
1909 - Stalagmite 9
|
|
@ -1,223 +0,0 @@
|
|||
Description OldNum NewNum Description
|
||||
Old Water 14 Removed
|
||||
|
||||
Level Parameters/Misc:
|
||||
Per-Sector Gravity 64 1
|
||||
Custom Exit 71 2
|
||||
Zoom Tube Parameters 18 3
|
||||
Speed Pad 65 4
|
||||
Camera Scanner 63 5
|
||||
Disable Linedef 73 6
|
||||
Flat Alignment 66 7
|
||||
Sector Special Parameters New 8
|
||||
Mace Parameters New 9
|
||||
Sprite Cull Height New 10
|
||||
Rope Hang Parameters New 11
|
||||
Rock Spawner Parameters New 12
|
||||
|
||||
PolyObjects
|
||||
Marks first line in PolyObject New 20
|
||||
Explicitly includes a PolyObject line New 21
|
||||
PolyObject: Parameters New 22
|
||||
PolyObject: Waving Flag New 31
|
||||
|
||||
Level-Load Effects:
|
||||
Instant Floor Lower 26 50
|
||||
Instant Ceiling Raise 24 51
|
||||
Continuously Falling Sector 88 52
|
||||
Continuous Floor/Ceiling Mover 2 53
|
||||
Continuous Floor Mover 3 54
|
||||
Continuous Ceiling Mover 4 55
|
||||
Continuous Two-Speed Floor/Ceiling Mover 6 56
|
||||
Continuous Two-Speed Floor Mover 7 57
|
||||
Continuous Two-Speed Ceiling Mover 8 58
|
||||
Activate Floating Platform 232 59
|
||||
Activate Floating Platform (Adjustable Speed) 233 60
|
||||
Crusher 1 (Ceiling to Floor) 43 61
|
||||
Crusher 2 (Floor to Ceiling) 50 62
|
||||
Fake Floor/Ceiling 242 63
|
||||
Appearing/Disappearing FOF New 64
|
||||
Bridge Thinker New 65
|
||||
|
||||
Floor Over Floors:
|
||||
"Floor Over Floor: Solid, Opaque, Shadowcasting " 25 100
|
||||
"Floor Over Floor: Solid, Opaque, Non-Shadowcasting " 33 101
|
||||
"Floor Over Floor: Solid, Translucent " 44 102
|
||||
"Floor Over Floor: Solid, Sides Only " 69 103
|
||||
"Floor Over Floor: Solid, No Sides " 51 104
|
||||
"Floor Over Floor: Solid, Invisible " 57 105
|
||||
|
||||
"Floor Over Floor: Water, Opaque " 48 120
|
||||
"Floor Over Floor: Water, Translucent " 45 121
|
||||
"Floor Over Floor: Water, Opaque, No Sides " 75 122
|
||||
"Floor Over Floor: Water, Translucent, No Sides " 74 123
|
||||
|
||||
"Floor Over Floor: Platform, Opaque " 59 140
|
||||
"Floor Over Floor: Platform, Translucent " 81 141
|
||||
"Floor Over Floor: Platform, Translucent, No Sides " 77 142
|
||||
|
||||
Floor Over Floor: Bobbing (Air) 38 150
|
||||
Floor Over Floor: Adjustable Bobbing (Air) 68 151
|
||||
Floor Over Floor: Reverse Adjustable Bobbing (Air) 72 152
|
||||
|
||||
"Floor Over Floor: Floating, Bobbing " 34 160
|
||||
|
||||
Floor Over Floor: Crumbling (Respawn) 36 170
|
||||
Floor Over Floor: Crumbling (No Respawn) 35 171
|
||||
"Floor Over Floor: Crumbling (Respawn), Platform " 79 172
|
||||
"Floor Over Floor: Crumbling (No Respawn), Platform " 80 173
|
||||
"Floor Over Floor: Crumbling (Respawn), Platform, Translucent " 82 174
|
||||
"Floor Over Floor: Crumbling (No Respawn), Platform, Translucent " 83 175
|
||||
"Floor Over Floor: Crumbling (Respawn), Floating, Bobbing " 39 176
|
||||
"Floor Over Floor: Crumbling (No Respawn), Floating, Bobbing " 1 177
|
||||
"Floor Over Floor: Crumbling (Respawn), Floating " 37 178
|
||||
"Floor Over Floor: Crumbling (No Respawn), Floating " 42 179
|
||||
"Floor Over Floor: Crumbling (Respawn), Bobbing (Air) " 40 180
|
||||
|
||||
"Floor Over Floor: Rising Platform, Solid, Opaque, Shadowcasting " 89 190
|
||||
"Floor Over Floor: Rising Platform, Solid, Opaque, Non-Shadowcasting " 90 191
|
||||
"Floor Over Floor: Rising Platform, Solid, Translucent " 91 192
|
||||
"Floor Over Floor: Rising Platform, Solid, Invisible " 94 193
|
||||
"Floor Over Floor: Rising Platform, Platform, Opaque " 92 194
|
||||
"Floor Over Floor: Rising Platform, Platform, Translucent " 93 195
|
||||
|
||||
Floor Over Floor: Light Block 49 200
|
||||
Floor Over Floor: Half Light Block 47 201
|
||||
Floor Over Floor: Fog Block 46 202
|
||||
|
||||
"Floor Over Floor: Intangible, Opaque " 62 220
|
||||
"Floor Over Floor: Intangible, Translucent " 52 221
|
||||
"Floor Over Floor: Intangible, Sides Only " 67 222
|
||||
"Floor Over Floor: Intangible, Invisible " 58 223
|
||||
|
||||
Floor Over Floor: Mario Block 41 250
|
||||
Floor Over Floor: Thwomp Block 54 251
|
||||
Floor Over Floor: Shatter Block 76 252
|
||||
"Floor Over Floor: Shatter Block, Translucent " 86 253
|
||||
Floor Over Floor: Bustable Block 55 254
|
||||
Floor Over Floor: Spin Bust Block 78 255
|
||||
"Floor Over Floor: Spin Bust Block, Translucent " 84 256
|
||||
Floor Over Floor: Quicksand Block 56 257
|
||||
Floor Over Floor: Laser Block 53 258
|
||||
Floor Over Floor: Custom 87 259
|
||||
|
||||
Linedef Executor Triggers:
|
||||
Trigger Linedef Executor (Continuous) 96 300
|
||||
Trigger Linedef Executor (Each Time) 97 301
|
||||
Trigger Linedef Executor (Once) 98 302
|
||||
Trigger Linedef Executor (Ring Count - Continuous) 95 303
|
||||
Trigger Linedef Executor (Ring Count - Once) 99 304
|
||||
Trigger Linedef Executor (Character Ability - Continuous) 19 305
|
||||
Trigger Linedef Executor (Character Ability - Each Time) 20 306
|
||||
Trigger Linedef Executor (Character Ability - Once) 21 307
|
||||
"Trigger Linedef Executor (Race Only, Once) " 9 308
|
||||
Trigger Linedef Executor (CTF Red Team - Continuous) 10 309
|
||||
Trigger Linedef Executor (CTF Red Team - Each Time) 11 310
|
||||
Trigger Linedef Executor (CTF Blue Team - Continuous) 12 311
|
||||
Trigger Linedef Executor (CTF Blue Team - Each Time) 13 312
|
||||
Trigger Linedef Executor (No More Enemies - Once) 15 313
|
||||
Trigger Linedef Executor (# of Pushables - Continuous) New 314
|
||||
Trigger Linedef Executor (# of Pushables - Once) New 315
|
||||
Trigger Linedef Executors (PolyObject - Land On) New 316
|
||||
Trigger Linedef Executor (Level Load) New 399
|
||||
|
||||
Linedef Executor Options:
|
||||
Linedef Executor: Set Tagged Sector's Floor Height/Pic 101 400
|
||||
Linedef Executor: Set Tagged Sector's Ceiling Height/Pic 102 401
|
||||
Linedef Executor: Set Tagged Sector's Light Level 103 402
|
||||
Linedef Executor: Move Tagged Sector's Floor 106 403
|
||||
Linedef Executor: Move Tagged Sector's Ceiling 107 404
|
||||
Linedef Executor: Lower Floor by Line 108 405
|
||||
Linedef Executor: Raise Floor by Line 109 406
|
||||
Linedef Executor: Lower Ceiling by Line 110 407
|
||||
Linedef Executor: Raise Ceiling by Line 111 408
|
||||
Linedef Executor: Change Calling Sector's Tag 112 409
|
||||
Linedef Executor: Change Front Sector's Tag 114 410
|
||||
Linedef Executor: Stop Plane Movement 116 411
|
||||
Linedef Executor: Teleport Player to Tagged Sector 104 412
|
||||
Linedef Executor: Change Music 105 413
|
||||
Linedef Executor: Play SFX 115 414
|
||||
Linedef Executor: Run Script 113 415
|
||||
Linedef Executor: Start Adjustable Fire Flicker 119 416
|
||||
Linedef Executor: Start Adjustable Glowing Light 120 417
|
||||
Linedef Executor: Start Adjustable Strobe Flash (unsynchronized) New 418
|
||||
Linedef Executor: Start Adjustable Strobe Flash (synchronized) New 419
|
||||
Linedef Executor: Fade Light Level 117 420
|
||||
Linedef Executor: Stop Lighting Effect 118 421
|
||||
Linedef Executor: Cut-Away View 121 422
|
||||
Linedef Executor: Change Sky 123 423
|
||||
Linedef Executor: Change Weather 124 424
|
||||
Linedef Executor: Change Object State 125 425
|
||||
Linedef Executor: Stop Object 122 426
|
||||
Linedef Executor: Award Score 126 427
|
||||
Linedef Executor: Start Platform Movement 127 428
|
||||
Linedef Executor: Crush Ceiling Once New 429
|
||||
Linedef Executor: Crush Floor Once New 430
|
||||
Linedef Executor: Crush Floor & Ceiling Once New 431
|
||||
Linedef Executor: Enable 2D Mode New 432
|
||||
Linedef Executor: Disable 2D Mode New 433
|
||||
Linedef Executor: Award Custom Power New 434
|
||||
Linedef Executor: Stop Conveyor New 435
|
||||
Linedef Executor: Start Conveyor New 436
|
||||
Linedef Executor: Disable Player Movement New 437
|
||||
|
||||
Linedef Executor: Execute Linedef Executor New 450
|
||||
|
||||
Linedef Executor: PolyObject: Door Slide New 480
|
||||
Linedef Executor: PolyObject: Door Swing New 481
|
||||
Linedef Executor: PolyObject: Move XY New 482
|
||||
Linedef Executor: PolyObject: Move XY w/ override New 483
|
||||
Linedef Executor: PolyObject: Rotate Right New 484
|
||||
Linedef Executor: PolyObject: Rotate Right w/ override New 485
|
||||
Linedef Executor: PolyObject: Rotate Left New 486
|
||||
Linedef Executor: PolyObject: Rotate Left w/ override New 487
|
||||
Linedef Executor: PolyObject: Start waypoint movement New 488
|
||||
Linedef Executor: PolyObject: Make Invisible New 489
|
||||
Linedef Executor: PolyObject: Make Visible New 490
|
||||
|
||||
Scrollers/Pushers:
|
||||
Scroll Wall First Side Left 100 500
|
||||
Scroll Wall First Side Opposite Direction 85 501
|
||||
Scroll Wall According to Linedef 254 502
|
||||
Acc Scroll Wall According to Linedef 218 503
|
||||
Disp Scroll Wall According to Linedef 249 504
|
||||
Scroll Texture by Offsets 255 505
|
||||
|
||||
Scroll Floor Texture 251 510
|
||||
Acc Scroll Floor Texture 215 511
|
||||
Disp Scroll Floor Texture 246 512
|
||||
Scroll Ceiling Texture 250 513
|
||||
Acc Scroll Ceiling Texture 214 514
|
||||
Disp Scroll Ceiling Texture 245 515
|
||||
|
||||
Carry Objects on Floor (no scroll) 252 520
|
||||
Acc Carry Objects on Floor 216 521
|
||||
Disp Carry Objects on Floor 247 522
|
||||
Carry Objects on Ceiling 203 523
|
||||
Acc Carry Objects on Ceiling 205 524
|
||||
Disp Carry Objects on Ceiling 201 525
|
||||
|
||||
Scroll Floor Texture and Carry Objects 253 530
|
||||
Acc Scroll Floor Texture and Carry Objects 217 531
|
||||
Disp Scroll Floor Texture and Carry Objects 248 532
|
||||
Scroll Ceiling Texture and Carry Objects 202 533
|
||||
Acc Scroll Ceiling Texture and Carry Objects 204 534
|
||||
Disp Scroll Ceiling Texture and Carry Objects 200 535
|
||||
|
||||
Friction 223 540
|
||||
Horizontal Wind 224 541
|
||||
Upwards Wind 229 542
|
||||
Downwards Wind 230 543
|
||||
Horizontal Current 225 544
|
||||
Upwards Current 227 545
|
||||
Downwards Current 228 546
|
||||
Boom Push/Pull Thing 226 547
|
||||
|
||||
Lighting:
|
||||
Floor Lighting 213 600
|
||||
Ceiling Lighting 5 601
|
||||
Adjustable Pulsating Light 60 602
|
||||
Adjustable Flickering Light 61 603
|
||||
Adjustable Blinking Light (unsynchronized) New 604
|
||||
Adjustable Blinking Light (synchronized) New 605
|
||||
Colormap 16 606
|
BIN
doc/SSN-Todo.xls
BIN
doc/SSN-Todo.xls
Binary file not shown.
|
@ -1,78 +0,0 @@
|
|||
Removed:
|
||||
- Buttons 1-20 690-709
|
||||
- Button 21 (THZ2 A/740 B/741 D/742 E/745 710
|
||||
- Close Door Blazing (Tag 743) 711
|
||||
- Raise Ceiling to Highest (Tag 744) 981
|
||||
- THZ2 Slime Raise (B/712 W713 P714 D715 S716) 986
|
||||
|
||||
Stuff to Remove/Change:
|
||||
- Light Blinks On Every 0.5 Seconds 2 Add Linedef Combine
|
||||
- Light Blinks On Every 1 Second 3 Add Linedef Combine
|
||||
- Light Pulses Smoothly 8 Remove
|
||||
- Light Blinks On Every 0.5 Seconds (Sync) 12 Add Linedef Combine
|
||||
- Lights Blinks On Every 1 Second (Sync) 13 Add Linedef Combine
|
||||
- Light Flickers Like Fire 17 Remove
|
||||
? - Damage (Fire) and Current 519 Remove (convert to combination)
|
||||
? - Damage (Water) and Current 984 Remove (convert to combination)
|
||||
|
||||
Section 1:
|
||||
1 - Damage (Generic) 11
|
||||
2 - Damage (Water) 983
|
||||
3 - Damage (Fire) 7
|
||||
4 - Damage (Electrical) 18
|
||||
5 - Spikes 4
|
||||
6 - Death Pit (Camera Mod) 16
|
||||
7 - Death Pit (No Camera Mod) 5
|
||||
8 - Instant Kill 10
|
||||
9 - Ring Drainer (Floor Touch) 978
|
||||
10 - Ring Drainer (No Floor Touch) 980
|
||||
11 - Special Stage Damage 9
|
||||
12 - Space Countdown 6
|
||||
13 - Ramp Sector (Increase step-up) 992
|
||||
14 - Non-Ramp Sector (Don't step-down) 996
|
||||
15 - Bouncy Sector (FOF Control Only) 14
|
||||
|
||||
Section 2: << 4
|
||||
1 - Trigger Linedef Exec (Pushable Objects) 971
|
||||
2 - Trigger LD Exec (Anywhere in Sec/All Pls) 972
|
||||
3 - Trigger Linedef Exec (Floor Touch/All Pls) 973
|
||||
4 - Trigger Linedef Exec (Anywhere in Sec) 974
|
||||
5 - Trigger Linedef Exec (Floor Touch) 975
|
||||
6 - Trigger Linedef Exec (Emerald Check) 967
|
||||
7 - Trigger Linedef Exec (NiGHTS Mare) 968
|
||||
8 - Check for linedef executor on FOFs (ANY) 970
|
||||
9 - Egg Trap Capsule 666
|
||||
10 - Special Stage Time/Rings, Par 990
|
||||
11 - Custom Global Gravity 991
|
||||
|
||||
Section 3: << 8
|
||||
1 - Ice/Sludge (required?!) 256
|
||||
2 - Wind/Current (required?!) 512
|
||||
3 - Ice/Sludge and Wind/Current 768
|
||||
4 - Conveyor Belt 985
|
||||
5 - Speed Pad (No Spin) 976
|
||||
6 - Speed Pad (Spin) 977
|
||||
7 - Bustable Block Sprite Parameter 1500-1515
|
||||
8 - "
|
||||
9 - "
|
||||
10 - "
|
||||
11 - "
|
||||
12 - "
|
||||
13 - "
|
||||
14 - "
|
||||
15 - "
|
||||
|
||||
Section 4: << 12
|
||||
1 - Starpost Activator 993
|
||||
2 - Special Stage Goal Combine 33
|
||||
2 - Exit Sector Combine 982
|
||||
2 - No Tag Zone Combine 987
|
||||
2 - CTF: Flag Return Combine 995
|
||||
3 - CTF: Red Team Base 988
|
||||
4 - CTF: Blue Team Base 989
|
||||
5 - Fan Sector 997
|
||||
6 - Super Sonic Transform 969
|
||||
7 - Spinner 979
|
||||
8 - Zoom Tube Start 998
|
||||
9 - Zoom Tube End 999
|
||||
10 - Finish Line 994
|
307
doc/faq.txt
307
doc/faq.txt
|
@ -1,307 +0,0 @@
|
|||
SRB2
|
||||
Release v1.09, ? 2005.
|
||||
|
||||
Last Updated: June 2005
|
||||
|
||||
Original game & sources by: Id Software.
|
||||
Additions: (c)1998 by: Fabrice Denis & Boris Pereira
|
||||
(c)1999 by: Fabrice Denis, Boris Pereira & Thierry Van Elsuwe
|
||||
(c)2000 by: Boris Pereira & Thierry Van Elsuwe
|
||||
(c)2004 By: AJ, Graue, Alam Arias, Logan Arias & Andrew Clunis
|
||||
|
||||
Special thanks to Steven McGranahan, Lee Killough, Robert Bäuml and Bell Kin for
|
||||
their large contribution and to other DooM LEGACY & SRB2 Team members.
|
||||
|
||||
Web site: http://www.SRB2.org/
|
||||
e-mail: none@none.com
|
||||
|
||||
OpenGL specific:
|
||||
Web site: http://legacy.newdoom.com/gl
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
F.A.Q.
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
|
||||
If you have any trouble with SRB2, you might find a solution
|
||||
here.
|
||||
|
||||
If you find a solution to a problem that was not listed here,
|
||||
please tell us so that we can update the FAQ and help other people!
|
||||
|
||||
Mail your hardware/software problems to:
|
||||
|
||||
None@none.com subject: FAQ
|
||||
|
||||
|
||||
--------
|
||||
CONTENTS
|
||||
--------
|
||||
|
||||
[0] Miscellaneous
|
||||
[1] Mouse/Joystick/Keyboard
|
||||
[2] Video
|
||||
[3] Sound
|
||||
[4] Network
|
||||
[5] Troubleshooting
|
||||
|
||||
|
||||
-----------------
|
||||
[0] MISCELLANEOUS
|
||||
-----------------
|
||||
|
||||
* under win95 or OS/2, I don't have enough memory. How can i handle with ?
|
||||
|
||||
Tell win95 to put more dpmi memory for your dos box.
|
||||
Or use the -mb option.
|
||||
|
||||
|
||||
|
||||
---------------------------
|
||||
[1] MOUSE/JOYSTICK/KEYBOARD
|
||||
---------------------------
|
||||
|
||||
* My mouse/joystick does not work in SRB2.
|
||||
|
||||
First, check that the mouse/joystick is activated : go at the
|
||||
console and type either 'use_mouse' (or use the respective
|
||||
menuitem) or 'use_joystick'.
|
||||
|
||||
If it tells '0' or off than the mouse/joystick is not used,
|
||||
set the variable to 1. eg: 'use_mouse 1'.
|
||||
|
||||
For the joystick, different values will support different
|
||||
types of joystick, check the console documentation for the
|
||||
command 'use_joystick' for more.
|
||||
|
||||
Even if the mouse or joystick is activated, you have to
|
||||
set up the contols into the Setup Controls menu. That is:
|
||||
tell what use you will make of the mouse/joystick buttons.
|
||||
|
||||
|
||||
---------
|
||||
[2] VIDEO
|
||||
---------
|
||||
|
||||
|
||||
* Where are the other video modes ? I have only '320x200' in the
|
||||
Video Modes menu.
|
||||
|
||||
DOS
|
||||
---
|
||||
|
||||
SRB2 adds new video modes only if a VESA2 (or better) driver
|
||||
is present. The VESA2 driver is a standard of 'talking' between a
|
||||
program and the huge amount of different graphics cards
|
||||
available today.
|
||||
|
||||
If you don't have a VESA2 driver, you can download UNIVBE, or
|
||||
SMART DISPLAY DOCTOR from
|
||||
|
||||
http://www.scitechsoft.com/products/ent/free_titles.html
|
||||
|
||||
or if you have an S3 based card, you can download the free
|
||||
software called 'S3VBE'.
|
||||
|
||||
ftp://ftp.externet.hu/pub/mirror/sac/graph/s3vbe318.zip
|
||||
ftp://ftp.digsys.bg/pub/simtelnet/msdos/graphics/s3vbe318.zip
|
||||
http://www.filesearching.com/cgi-bin/s?q=s3vbe318.zip
|
||||
http://www.google.com/search?q=s3vbe318.zip
|
||||
|
||||
* The game doesn't restore the video mode I have chosen the last time
|
||||
I played SRB2.
|
||||
|
||||
The current video mode has to be made the 'default' so that it is
|
||||
saved to the config : press the key 'D' on the Video Options menu
|
||||
to set the current video mode the default.
|
||||
|
||||
* I have some problems with OpenGL mode
|
||||
|
||||
Have a look at the FAQ for OpenGL on the glLegacy web site:
|
||||
|
||||
http://www.doomnation.com/gllegacy/faqe.htm
|
||||
|
||||
# Linux: I only have a 1024x768 (or 800x600, 1280x1024, ...) resolution
|
||||
in fullscreen mode under X and SRB2 is really really slow. Can I
|
||||
have lower resolutions like 320x200 in fullscreen mode as well?
|
||||
|
||||
Probably yes. SRB2 can only use the resolutions offered by the
|
||||
X-Server. So if all fullscreen modes have a very high resolution you
|
||||
have to modify /etc/XF86Config (or /etc/X11/XF86Config). Use XF86Setup
|
||||
(or the appropriate tool coming with your distribution - sax,
|
||||
xf86config, ...) to do this.
|
||||
If you do not succeed there, you can enter them manually into your
|
||||
XF86Config file. ONLY RECOMMENDED FOR USERS WHO KNOW WHAT THEY DO!
|
||||
For a short guide on how to do this, have a look at the file
|
||||
"Doublescan.txt".
|
||||
In case of doubt consult the XFree86-HOWTO (or ask your system
|
||||
administrator :).
|
||||
|
||||
# Linux: I cannot have any fullscreen modes at all!
|
||||
|
||||
You have only modes above 1024x768 in your XF86Config. Proceed as
|
||||
described above.
|
||||
|
||||
# Linux: After a certain idle time my screensaver jams the display of
|
||||
SRB2. I can still operate SRB2, but I do not see what's happening
|
||||
and the screensaver won't go away.
|
||||
|
||||
You probably have KDE. The KDE screensaver does not obey the screensaver
|
||||
rules (at least mine, version 1.1). The solution is to deactivate the
|
||||
KDE screensaver and use another screensaver (like the xscreensaver,
|
||||
e.g.). But the hell, when you started SRB2 you should have played it
|
||||
as well and not left it alone!!!
|
||||
|
||||
---------
|
||||
[3] SOUND
|
||||
---------
|
||||
|
||||
+ DOS:I can't have CD audio music, why ?
|
||||
|
||||
Make sure that the MSCDEX driver version 2.0 or later is loaded.
|
||||
If it says 'MSCDEX version xxx' at game startup, and you still
|
||||
don't hear the cd music, then probably your card doesn't respond
|
||||
when SRB2 tries to set the cd volume. If so, make sure your sound
|
||||
card's mixer have the cd volume set up so that you can hear something.
|
||||
|
||||
+ When the CD plays, the game is very 'jerky'. It doesn't do that when
|
||||
I type 'cd off' in the console.
|
||||
|
||||
You have an old/bad cd driver, that can take up to a second to
|
||||
respond to cd driver commands. Either get the latest version of
|
||||
your driver, or turn cd update off. Check 'cd_udpate' in the
|
||||
console documentation for more.
|
||||
|
||||
* DOS:How can I *ALWAYS* disable the sounds or music of the game ?
|
||||
|
||||
Edit the allegro.cfg file and set digicard/midicard to 0 (none)
|
||||
|
||||
* DOS:My sterero sound is reversed, how can I set it the right way ?
|
||||
|
||||
Change the console variable 'stereoreverse' to either 1 or 0.
|
||||
Or, you can edit the allegro.cfg file, and set the 'flip_pan' variable.
|
||||
|
||||
|
||||
* DOS:The sounds are too 'slow', or 'low-pitched'
|
||||
|
||||
It seems to be a problem of the auto-detection of some 8bit sound
|
||||
cards. You will have to set manually the 'sb_freq' value in the
|
||||
allegro.cfg file to a lower value : 11906, 16129.
|
||||
|
||||
* DOS:SRB2 doesn't play any sound/music, but I have a sound
|
||||
blaster genuine/compatible card.
|
||||
|
||||
If you have a genuine or compatible SoundBlaster card, it is very
|
||||
important that you set the BLASTER environment variable.
|
||||
|
||||
If you are playing under DOS, and never installed your sound card
|
||||
under DOS, run the setup of your sound card for DOS.
|
||||
|
||||
Check if the BLASTER variable was set: type 'SET' under dos
|
||||
(or DOSbox)
|
||||
|
||||
Do you see something like 'BLASTER=A220 I5 D1 ...' ?
|
||||
|
||||
Yes? If you don't hear sounds/music, then tweak the settings in the
|
||||
allegro.cfg file until you get something, first try changing the
|
||||
type of the sound card, it is not always properly detected.
|
||||
|
||||
No? You have to set this variable in order that your sound card is
|
||||
detected. Run the setup that was shipped with your sound card, and
|
||||
make sure you run the setup for DOS too, it will usually add a
|
||||
line of the type 'SET BLASTER=... ...' in the autoexec.bat file.
|
||||
|
||||
|
||||
* DOS:How can I have better midi music on my 8bit sound card ?
|
||||
|
||||
Use the DIGMID driver, it is supported in SRB2.
|
||||
|
||||
What the hell is this? Well, the Gravis Ultrasound uses digital
|
||||
samples to play midi music. On a simple 8bit card, you can use digital
|
||||
samples too, which will sound usually better than what is output
|
||||
by the poor fm synthesis chip of 8bit cards.
|
||||
|
||||
You will need to get a Gravis Ultrasound patch set, you can find
|
||||
several ones for free on internet, it consists of a bunch of '.pat'
|
||||
files which are the digital samples to play the midi instruments
|
||||
(eg: piano, conga, guitar, ect.).
|
||||
|
||||
Check the Allegro homepage for some links to GUS patches:
|
||||
http://alleg.sourceforge.net/digmid.html
|
||||
http://alleg.sourceforge.net/
|
||||
http://www.talula.demon.co.uk/allegro/digmid.html
|
||||
http://www.talula.demon.co.uk/allegro/
|
||||
|
||||
Now to activate the DIGMID driver:
|
||||
|
||||
Set the 'midi_card' value to 8 (DIGMID) in the allegro.cfg file.
|
||||
Make sure you leave the 'digi_voices' blank, or set it to a low
|
||||
value, because the midi music will use digital voices.
|
||||
At the end of the allegro.cfg file, set the 'patches' value
|
||||
to the path, where you have installed a Gravis Ultrasound midi
|
||||
patch set. eg: patches = d:\music\midipat\
|
||||
|
||||
# Linux: CD music does not work or only works when run as root.
|
||||
|
||||
We do not encourage you to run SRB2 as root (you never know
|
||||
what SRB2 can do to your system - it's a mighty piece of code :).
|
||||
There is a common problem with ATAPI CD-rom drives, which are
|
||||
treated as harddisks. Usually there is a link /dev/cdrom pointing to
|
||||
device hd[b,c,d]. As harddisks are not supposed to be read directly
|
||||
via this device (especially not by a common user), there are no read
|
||||
permissions for "all". For CD-roms you can savely set read permissions
|
||||
unless you are very paranoid. Assuming your CD-rom drive is /dev/hdc,
|
||||
set permissions with "chmod +r /dev/hdc" (as root). SCSI CD-rom drives
|
||||
should not have this problem. But if they do, proceed as described
|
||||
with ATAPI drives.
|
||||
|
||||
# Linux: The CD music volume is not set properly.
|
||||
|
||||
Go to the console and type "jigglecdvolume 1".
|
||||
|
||||
-----------
|
||||
[4] NETWORK
|
||||
-----------
|
||||
|
||||
* Where can I find Internet servers ?
|
||||
|
||||
For the moment there is one public server.
|
||||
http://srb2.servegame.org/ Master server web page
|
||||
srb2.servegame.org:28910 current Master Server
|
||||
|
||||
* When I start SRB2 with -server or -connect it say :
|
||||
"BinToPort: Address already in use (EADDRINUSE)"
|
||||
|
||||
It appears only when SRB2 crashes or when you leave with ctrl-break.
|
||||
use -udpport 12345 (or any other free slot) on both sides (client and
|
||||
server).
|
||||
|
||||
This can also happens when there is already a SRB2 running on your
|
||||
computer if you whant to try two SRB2 running on the same computer
|
||||
use -clientport 12345 (or any other free slot). Then the second will
|
||||
connect to the first one.
|
||||
|
||||
* Do you use the tcp protocol ?
|
||||
|
||||
No, we use the udp protocol which is faster, but don't worry udp is a
|
||||
part of the internet protocol.
|
||||
|
||||
|
||||
-------------------
|
||||
[5] Troubleshooting
|
||||
-------------------
|
||||
|
||||
# Linux: SRB2 is hung in fullscreen mode and won´t let me leave.
|
||||
What shall I do?
|
||||
|
||||
Some people press the reset button, but hey, we are not in the
|
||||
stoneage of operating systems! There are two "proper" ways to
|
||||
get out: kill your X-Server. You can usually do this by pressing
|
||||
"CTRL-ALT-BACKSPACE". But if you have other open applications with
|
||||
important data (probably hacked away on your diploma thesis for 3
|
||||
weeks without saving once) you can also kill SRB2 directly. Press
|
||||
"CTRL-ALT-F2" and you will get to a console. Log in, type
|
||||
"killall llxSRB2" and switch back to the X-Server with "CTRL-ALT-F7".
|
||||
Some X-Server crash on this procedure - blame the X-Server for the
|
||||
loss of 3 weeks work on your diploma thesis :)
|
|
@ -1,68 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
Sonic Robo Blast 2 Manual
|
||||
</title>
|
||||
<link rel="stylesheet" type="text/css" href="srb2manstyle.css">
|
||||
<!-- Borrowed some javascript code so the height of the iframe is equal to the size of the document - Sonict -->
|
||||
<script type="text/javascript">
|
||||
/* free code from dyn-web.com */
|
||||
|
||||
function getDocHeight(doc) {
|
||||
doc = doc || document;
|
||||
// from http://stackoverflow.com/questions/1145850/get-height-of-entire-document-with-javascript
|
||||
var body = doc.body, html = doc.documentElement;
|
||||
var height = Math.max( body.scrollHeight, body.offsetHeight,
|
||||
html.clientHeight, html.scrollHeight, html.offsetHeight );
|
||||
return height;
|
||||
}
|
||||
|
||||
function setIframeHeight(id) {
|
||||
var ifrm = document.getElementById(id);
|
||||
var doc = ifrm.contentDocument? ifrm.contentDocument: ifrm.contentWindow.document;
|
||||
ifrm.style.visibility = 'hidden';
|
||||
ifrm.style.height = "10px"; // reset to minimal height in case going from longer to shorter doc
|
||||
ifrm.style.height = getDocHeight( doc ) + "px";
|
||||
ifrm.style.visibility = 'visible';
|
||||
}
|
||||
</script>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<p class="c1">
|
||||
<img src="manual_img/sonicname2.png" alt="SONIC" width="136" height="36">
|
||||
<br>
|
||||
<img src="manual_img/srb2banner.png" alt="ROBO BLAST 2" width="224" height="43">
|
||||
</p>
|
||||
<p class="c1">
|
||||
<big><big><strong>Manual</strong></big></big>
|
||||
</p>
|
||||
<table class="cf" align="center">
|
||||
<tr><td class="c">
|
||||
<ul class="hmenu">
|
||||
<li class="hmenu"><a class="hmenu" href="intro.htm" target="ifrm">Main</a></li>
|
||||
<li class="hmenu"><a class="hmenu" href="items.htm" target="ifrm">Items</a></li>
|
||||
<li class="hmenu"><a class="hmenu" href="playerabilities.htm" target="ifrm">Player Abilities</a></li>
|
||||
<li class="hmenu"><a class="hmenu" href="basicplay.htm" target="ifrm">Gameplay</a></li>
|
||||
<li class="hmenu"><a class="hmenu" href="surroundings.htm" target="ifrm">Surroundings</a></li>
|
||||
</ul>
|
||||
</td></tr>
|
||||
<tr><td class="c">
|
||||
<ul class="hmenu">
|
||||
<li class="hmenu"><a class="hmenu" href="multiplayer.htm" target="ifrm">Multiplayer</a></li>
|
||||
<li class="hmenu"><a class="hmenu" href="zones.htm" target="ifrm">Zones</a></li>
|
||||
<li class="hmenu"><a class="hmenu" href="controls.htm" target="ifrm">Controls</a></li>
|
||||
<li class="hmenu"><a class="hmenu" href="consolecommands.htm" target="ifrm">Console Commands</a></li>
|
||||
<li class="hmenu"><a class="hmenu" href="misc.htm" target="ifrm">Misc</a></li>
|
||||
</ul>
|
||||
</td></tr>
|
||||
</table>
|
||||
<hr>
|
||||
<p class="c1">
|
||||
<!-- The "onload" property of the iframe makes an error when validated through the W3C validation checker. -->
|
||||
<!-- This will not be fixed as it isn't worth the time to fix it up properly. - Sonict -->
|
||||
<iframe id="ifrm" name="ifrm" src="intro.htm" onload="setIframeHeight(this.id)"> </iframe>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
|
@ -1,39 +0,0 @@
|
|||
SVN-RULES
|
||||
|
||||
- As you can see, there is sub-directory in the repository, one for eatch
|
||||
platform (djgpp (dos),win32,SDL) the root directory is for all platform,
|
||||
so take care of the order we have put in.
|
||||
- do not commit/upload tests of bugged code, try to fix a maximum of know
|
||||
bugs and update know bugs list in source.txt. If you must commit your source
|
||||
make your code in #ifdef so we can disable it
|
||||
- SRB2 is a modification of doom/Doom Legacy source. We allow additionnal feature
|
||||
and visual addition.
|
||||
- Maximize communications between members, do not impose your changes, if your
|
||||
are not sure about a feature/change, talk about it in irc://irc.esper.net/srb2 chat room.
|
||||
|
||||
CODE-RULES
|
||||
|
||||
- We use no tab, 4 space indent, and tab size 8 (in case some tab have filtred
|
||||
and for makefile)
|
||||
- Self documented code, variable and function must have a name that help
|
||||
understand the code, so do not call variable and function a,b, a2, ...
|
||||
- the usage of extern in a c file is prohibited, except for declaration of a
|
||||
function with body (so it is like public keyword in c++)
|
||||
Also function protos haren't allowed for external function, put it un the
|
||||
corresponding h file.
|
||||
- Try to minimize #ifdef usage for :
|
||||
- code readability
|
||||
- the main code is for all port so if something is good for a platform all
|
||||
platform can benefit by this feature
|
||||
- Take care of platform dependent code, we would like to have code that work
|
||||
on Dos, Win32, SDL, ... little and big endian, software/Glide/OpenGl.
|
||||
|
||||
GOOD PRACTICE
|
||||
|
||||
- Try to put as mush static variable and function on module so it help to
|
||||
understand the role of the varaible/function in the module also this
|
||||
help the compiler to optimize
|
||||
- minimise global variable
|
||||
- make a log of your work, so you don't need to put a lot of comment in
|
||||
the code, this will also help us to update the what's new section of doc
|
||||
when doing final release
|
240
doc/source.txt
240
doc/source.txt
|
@ -1,240 +0,0 @@
|
|||
|
||||
1. Compile SRB2
|
||||
2. Explanation of the code
|
||||
2.1 The memory model
|
||||
2.2 Hardware Texture model
|
||||
|
||||
1. Compile SRB2
|
||||
=================
|
||||
|
||||
DOS
|
||||
---
|
||||
|
||||
need:
|
||||
- djgpp 2.03 (http://www.delorie.com/djgpp/)
|
||||
- allegro 3.12 (http://alleg.sourceforge.net/index.html)
|
||||
(
|
||||
- libsocket 0.7.4 (beta 4) or better
|
||||
for use with Winsock 1.1 (example Windows 3.1)
|
||||
(http://www.phekda.freeserve.co.uk/richdawe/lsck/lsck.htm)
|
||||
OR
|
||||
- Wattcp-32 v2.2 dev.rel 6 or better
|
||||
For use with a packet driver
|
||||
(http://www.bgnett.no/~giva/)
|
||||
(http://groups.yahoo.com/group/watt-32/)
|
||||
(http://groups.yahoo.com/group/watt-32/files/v2.2/)
|
||||
)
|
||||
- bcd 1.03 (inlcude in this package)
|
||||
- gcc 2.95.2 is recommended
|
||||
- nasm 0.98 (or better) (http://nasm.sourceforge.net/)
|
||||
|
||||
compile:
|
||||
make
|
||||
make WATTCP=1 (to make a Wattcp-32 version)
|
||||
|
||||
debug:
|
||||
when craching SRB2 will return eip
|
||||
type make asm, then you will have a 8 megs srb2.s (a assembler file)
|
||||
the you can find the faulting instruction and function
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Linux/SDL
|
||||
-----
|
||||
|
||||
need:
|
||||
- tested with gcc 2.95 and 3.X.
|
||||
- SDL 1.2
|
||||
- SDL_mixer 1.2
|
||||
- ibogg and libvorbis (http://Xiph.org/)
|
||||
- nasm 0.98 (or better)(http://nasm.sourceforge.net/) only with 2.95, else add CC30=1
|
||||
|
||||
compile
|
||||
make LINUX=1
|
||||
|
||||
debug:
|
||||
gdb ?
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Win32
|
||||
-----
|
||||
|
||||
need :
|
||||
- glide 3.x sdk (optional) (http://www.3dfx.com)
|
||||
- directx6 sdk (or higher) (http://www.micosoft.com/directx)
|
||||
- nasm 0.98 (or better) (http://nasm.sourceforge.net/)
|
||||
- use src\win32\wLegacy.dsp
|
||||
- VC6 should also work with VC5, and VS.NET 200X
|
||||
|
||||
debug:
|
||||
press on "step over" with the release version (there is some debug info
|
||||
on it). Then change the eip in the regster window when you will type
|
||||
enter the edi will go to the faulting instruction. don't forget that
|
||||
you can follow the stack for calls.
|
||||
You can also use trace with the debug version but add -win and -nomouse.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Win32/minGW/SDL
|
||||
-----
|
||||
|
||||
need:
|
||||
- tested with gcc 2.95 and 3.X.
|
||||
- can also use Dev-C++ 5.0 beta 9 (4.9.9.0) from http://www.bloodshed.net/dev/devcpp.html
|
||||
- SDL 1.2
|
||||
- SDL_mixer 1.2
|
||||
|
||||
compile
|
||||
make minGW=1 SDL=1
|
||||
or use src\SDL\Win32SDL.dev with Dev-C++ 4.9.9.0 or later
|
||||
|
||||
debug:
|
||||
gdb ?
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
WinCE/SDL WIP
|
||||
-----
|
||||
|
||||
need:
|
||||
- ActiveSync 3.8
|
||||
http://www.microsoft.com/windowsmobile/downloads/activesync38.mspx
|
||||
|
||||
- ActiveSync 3.7.1, if 3.8 isn't available for your language
|
||||
http://www.microsoft.com/windowsmobile/downloads/activesync37.mspx
|
||||
|
||||
- eMbedded Visual Tools 3.0 - 2002 Edition
|
||||
http://www.microsoft.com/downloads/details.aspx?FamilyID=f663bf48-31ee-4cbe-aac5-0affd5fb27dd
|
||||
|
||||
- Pocket PC 2000 SDK
|
||||
http://www.microsoft.com/downloads/details.aspx?FamilyID=bb3f4d7b-de2a-4e1a-a175-26a68c301ac4
|
||||
|
||||
- Pocket PC 2002 SDK (eMVT 3.0 2002 Ed. comes with this)
|
||||
http://www.microsoft.com/downloads/details.aspx?FamilyID=2dbee84a-bd94-4167-b817-2b2e548b2e92
|
||||
|
||||
- Pocket PC 2002 SDK Emulator Images (eMVT 3.0 2002 Ed. comes with this)
|
||||
http://www.microsoft.com/downloads/details.aspx?FamilyID=25f4de97-ae80-477a-9df1-496b85b3d3e3
|
||||
|
||||
- eMbedded Visual C++ 4.0
|
||||
http://www.microsoft.com/downloads/details.aspx?familyid=1DACDB3D-50D1-41B2-A107-FA75AE960856
|
||||
|
||||
- eMbedded Visual C++ 4.0 SP3 (Win CE 4.0-4.2)
|
||||
http://www.microsoft.com/downloads/details.aspx?FamilyID=5bb36f3e-5b3d-419a-9610-2fe53815ae3b
|
||||
|
||||
OR
|
||||
|
||||
- eMbedded Visual C++ 4.0 SP4 (No SH3 support,Win CE 4.0-5.0 support)
|
||||
http://www.microsoft.com/downloads/details.aspx?FamilyID=4a4ed1f4-91d3-4dbe-986e-a812984318e5
|
||||
|
||||
- eMbedded Visual C++ 4.0 Update 5625 (SP4 only)
|
||||
http://www.microsoft.com/downloads/details.aspx?FamilyID=aa282a6d-6f57-436d-8c10-0ec02d94f5b1
|
||||
|
||||
- Windows CE: Standard Software Development Kit
|
||||
http://www.microsoft.com/downloads/details.aspx?familyid=a08f6991-16b0-4019-a174-0c40e6d25fe7
|
||||
|
||||
- SDK for Windows Mobile 2003-based Pocket PCs
|
||||
http://www.microsoft.com/downloads/details.aspx?FamilyId=9996B314-0364-4623-9EDE-0B5FBB133652
|
||||
|
||||
- Emulator Images for Windows Mobile 2003 Second Edition software for Pocket PC
|
||||
http://www.microsoft.com/downloads/details.aspx?familyid=5C53E3B5-F2A2-47D7-A41D-825FD68EBB6C
|
||||
|
||||
- Microsoft Device Emulator 1.0 Community Preview
|
||||
http://beta.microsoft.com Use Guest ID "MSDEVICE" to access the Community Preview website
|
||||
|
||||
- Windows CE Utilities for Visual Studio .NET 2003 Add-on Pack 1.1
|
||||
(if you also have VS 2003 installed, you need this to install Win CE 5.0 SDK, else no need)
|
||||
http://www.microsoft.com/downloads/details.aspx?FamilyId=7EC99CA6-2095-4086-B0CC-7C6C39B28762
|
||||
|
||||
- Windows CE 5.0: Standard Software Development Kit (eMC++ 4 SP4 only)
|
||||
http://www.microsoft.com/downloads/details.aspx?FamilyID=fa1a3d66-3f61-4ddc-9510-ae450e2318c3
|
||||
|
||||
- SDL 1.27 (use patch and zip in tools\SDL1.2.7_CE)
|
||||
|
||||
compile
|
||||
use src\SDL\WinCE\SRB2CE.vcw
|
||||
|
||||
debug:
|
||||
?
|
||||
|
||||
|
||||
2. Explanation of the code
|
||||
==========================
|
||||
|
||||
2.1 The memory model (original) (z_zone.c) (by BP)
|
||||
--------------------
|
||||
|
||||
SRB2 allocate a heap of 6/32/48 megs at begining and provide a Z_Malloc function
|
||||
to allocate in this heap.
|
||||
|
||||
Z_Malloc( int size,int tag,void* user )
|
||||
|
||||
size is the size in byte
|
||||
tag can be : PU_STATIC allocated static (like malloc do)
|
||||
call Z_Free to free it
|
||||
PU_LEVEL same as static but the zone is "tagged" with the
|
||||
tag PU_LEVEL, when calling
|
||||
Z_FreeTag (PU_LEVEL, PU_LEVEL) all zone tagged
|
||||
with PU_LEVEL are freed (at the end of the level)
|
||||
PU_CACHE this one _can_ be freed automatiquely by one other
|
||||
call to Z_Malloc. the *user point to a pointer
|
||||
to this zone so when freed automatiquely the
|
||||
pointer is set to NULL so eatch time you use it
|
||||
you must check if the pointer is not NULL and
|
||||
reload it.
|
||||
|
||||
(...)
|
||||
|
||||
2.2 Hardware Texture model (by BP)
|
||||
--------------------------
|
||||
|
||||
Eatch texture/patch/flats/pic in SRB2 are converted to hardware texture at
|
||||
runtime (the GlideMipmap_s structure (hw_data.h)). I will call hardware
|
||||
texture a gr_texture so there is no confusion.
|
||||
|
||||
To remind you :
|
||||
- Texture are set of patch and are associate to linedefs (walls) can be
|
||||
upper, lower or middle texture. It can have hole on it.
|
||||
- patch are sprites (the doom patch are run of vertical lines)
|
||||
- flats are used for floors and ceiling of sectors and have size of 64x64
|
||||
it can't have hole on it
|
||||
- pic are new legacy format for picture, it can only handle plain texture
|
||||
like flats it is now used for hud in full screen for the main picture
|
||||
of legacy and for coronas (the format was extended to handle 32 bit color
|
||||
or intensity + alpha, not all are implemented at this time)
|
||||
|
||||
Since patch, flat and pic are basic structure represented by only one lump in
|
||||
the wad, the wad loader allocate for eatch lump a GlideMipmap_s (cache3Dfx)
|
||||
and init data field to NULL. Since the data structure is allocated in
|
||||
PU_3DFXCACHE (like PU_CACHE) the data will be initilised when needed
|
||||
(hw_cache.c).
|
||||
|
||||
The GlideMipmap_s structures for textures are initialized on
|
||||
HWR_PrepLevelCache (hw_cache.c) it is called in P_SetupLevel (load level)
|
||||
the number of textures is computed with TEXTURE1, TEXTURE2 lumps since this
|
||||
can be changed in runtime in SRB2 (load a wad while runing) it must be
|
||||
reallocated. Well, at this time it is realloceted at eatch level start. We
|
||||
can do better, since numtextures change only when a wad is loaded.
|
||||
|
||||
The 3dfx driver use glide3, it load gr_texture in gr_texture memory of the
|
||||
card in fifo order when there is no more place it remove the first gr_texture,
|
||||
the downloaded field of GlideMipmap_s go to false and when needed it is
|
||||
reloaded in gr_texture memory. In OpenGl, since OpenGl keep texture in there
|
||||
own memory and handle gr_texture memory of the card we no more need to
|
||||
redownload it but if we not free time to time gr_texture memory in opengl,
|
||||
it will get alot of memory, so the gr_texture memory is cleared at eatch
|
||||
new level (same time of texture reallocation). Opengl and 3dfx link the
|
||||
loaded gr_texture with the nextmipmap field of GlideMipmap_s so before clear
|
||||
textures of the heap we MUST free gr_texture memory of OpenGl or 3dfx !
|
||||
|
||||
SRB2 can also draw patch with a differant colormap (thanks to Hurdler).
|
||||
When needed it create the same gr_texture but just with a differant colormap.
|
||||
This one is linked with the original in the GlideMipmap_s with the
|
||||
nextcolormap field.
|
||||
|
||||
So when a polygone with a gr_texture must be drawn, first we check if the
|
||||
gr_textures is not allready loaded in hadware memory (downloaded field) if
|
||||
not then we check if gr_texture data is there (not grabbed by z_malloc
|
||||
function) if not we must recompute it eatch type of gr_texture (texture,
|
||||
patch, flat, pic have there own methode) the we can send the gr_texture
|
||||
to 3dfx or OpenGl.
|
1992
doc/specials.html
1992
doc/specials.html
File diff suppressed because it is too large
Load diff
311
doc/specs/udmf_srb2.txt
Normal file
311
doc/specs/udmf_srb2.txt
Normal file
|
@ -0,0 +1,311 @@
|
|||
===============================================================================
|
||||
Universal Doom Map Format Sonic Robo Blast 2 extensions v1.0 19.02.2024
|
||||
|
||||
Copyright (c) 2024 Sonic Team Junior
|
||||
uses Universal Doom Map Format Specification v1.1 as a template,
|
||||
original document Copyright (c) 2009 James Haley.
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.2
|
||||
or any later version published by the Free Software Foundation;
|
||||
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
|
||||
|
||||
===============================================================================
|
||||
|
||||
This document discusses the UDMF implementation found in Sonic Robo Blast 2's engine.
|
||||
|
||||
=======================================
|
||||
I. Grammar / Syntax
|
||||
=======================================
|
||||
|
||||
No changes.
|
||||
|
||||
=======================================
|
||||
II. Implementation Semantics
|
||||
=======================================
|
||||
|
||||
------------------------------------
|
||||
II.A : Storage and Retrieval of Data
|
||||
------------------------------------
|
||||
|
||||
No changes.
|
||||
|
||||
-----------------------------------
|
||||
II.B : Storage Within Archive Files
|
||||
-----------------------------------
|
||||
|
||||
No changes.
|
||||
|
||||
--------------------------------
|
||||
II.C : Implementation Dependence
|
||||
--------------------------------
|
||||
|
||||
The SRB2 engine only supports the following namespace:
|
||||
"srb2"
|
||||
|
||||
The engine is allowed to refuse maps with an unsupported namespace,
|
||||
or emit a warning.
|
||||
|
||||
=======================================
|
||||
III. Standardized Fields
|
||||
=======================================
|
||||
|
||||
The SRB2 engine ignores any user-defined fields.
|
||||
All boolean fields default to false unless mentioned otherwise.
|
||||
|
||||
Sonic Robo Blast 2 defines the following standardized fields:
|
||||
|
||||
vertex
|
||||
{
|
||||
x = <float>; // X coordinate. No valid default.
|
||||
y = <float>; // Y coordinate. No valid default.
|
||||
zfloor = <float>; // Floor height at this vertex. Only applies to triangular sectors
|
||||
zceiling = <float>; // Ceiling height at this vertex. Only applies to triangular sectors
|
||||
}
|
||||
|
||||
linedef
|
||||
{
|
||||
id = <integer>; // ID of line. Interpreted as tag.
|
||||
moreids = <string>; // Additional line IDs, specified as a space separated list of numbers (e.g. "2 666 1003 4505")
|
||||
|
||||
v1 = <integer>; // Index of first vertex. No valid default.
|
||||
v2 = <integer>; // Index of second vertex. No valid default.
|
||||
|
||||
blocking = <bool>; // Line blocks things.
|
||||
blockmonsters = <bool>; // Line blocks enemies.
|
||||
twosided = <bool>; // Line is 2S.
|
||||
dontpegtop = <bool>; // Upper texture unpegged.
|
||||
dontpegbottom = <bool>; // Lower texture unpegged.
|
||||
skewtd = <bool>; // Upper and lower textures are skewed.
|
||||
noclimb = <bool>; // Line is not climbable.
|
||||
noskew = <bool>; // Middle texture is not skewed.
|
||||
midpeg = <bool>; // Middle texture is pegged.
|
||||
midsolid = <bool>; // Middle texture is solid.
|
||||
wrapmidtex = <bool>; // Line's mid textures are wrapped.
|
||||
nonet = <bool>; // Special only takes effect in singleplayer games.
|
||||
netonly = <bool>; // Special only takes effect in multiplayer games.
|
||||
bouncy = <bool>; // Line is bouncy.
|
||||
transfer = <bool>; // In 3D floor sides, uses the sidedef properties of the control sector.
|
||||
|
||||
alpha = <float>; // Translucency of this line. Default is 1.0
|
||||
renderstyle = <string>; // Render style. Can be:
|
||||
// - "translucent"
|
||||
// - "add"
|
||||
// - "subtract"
|
||||
// - "reversesubtract"
|
||||
// - "modulate"
|
||||
// - "fog"
|
||||
// Default is "translucent".
|
||||
|
||||
special = <integer>; // Linedef action. Default = 0.
|
||||
arg0 = <integer>; // Argument 0. Default = 0.
|
||||
arg1 = <integer>; // Argument 1. Default = 0.
|
||||
arg2 = <integer>; // Argument 2. Default = 0.
|
||||
arg3 = <integer>; // Argument 3. Default = 0.
|
||||
arg4 = <integer>; // Argument 4. Default = 0.
|
||||
arg5 = <integer>; // Argument 5. Default = 0.
|
||||
arg6 = <integer>; // Argument 6. Default = 0.
|
||||
arg7 = <integer>; // Argument 7. Default = 0.
|
||||
arg8 = <integer>; // Argument 8. Default = 0.
|
||||
arg9 = <integer>; // Argument 9. Default = 0.
|
||||
stringarg0 = <string>; // String argument 0.
|
||||
stringarg1 = <string>; // String argument 1.
|
||||
|
||||
sidefront = <integer>; // Sidedef 1 index. No valid default.
|
||||
sideback = <integer>; // Sidedef 2 index. Default = -1.
|
||||
|
||||
comment = <string>; // A comment. Implementors should attach no special
|
||||
// semantic meaning to this field.
|
||||
}
|
||||
|
||||
sidedef
|
||||
{
|
||||
offsetx = <integer>; // X offset. Default = 0.
|
||||
offsety = <integer>; // Y offset. Default = 0.
|
||||
|
||||
texturetop = <string>; // Upper texture. Default = "-".
|
||||
texturebottom = <string>; // Lower texture. Default = "-".
|
||||
texturemiddle = <string>; // Middle texture. Default = "-".
|
||||
|
||||
repeatcnt = <string>; // Number of middle texture repetitions. Default = 0
|
||||
|
||||
sector = <integer>; // Sector index. No valid default.
|
||||
|
||||
scalex_top = <float>; // X scale for upper texture. Default = 1.0.
|
||||
scaley_top = <float>; // Y scale for upper texture. Default = 1.0.
|
||||
scalex_mid = <float>; // X scale for mid texture. Default = 1.0.
|
||||
scaley_mid = <float>; // Y scale for mid texture. Default = 1.0.
|
||||
scalex_bottom = <float>; // X scale for lower texture. Default = 1.0.
|
||||
scaley_bottom = <float>; // Y scale for lower texture. Default = 1.0.
|
||||
offsetx_top = <float>; // X offset for upper texture. Default = 0.0.
|
||||
offsety_top = <float>; // Y offset for upper texture. Default = 0.0.
|
||||
offsetx_mid = <float>; // X offset for mid texture. Default = 0.0.
|
||||
offsety_mid = <float>; // Y offset for mid texture. Default = 0.0.
|
||||
offsetx_bottom = <float>; // X offset for lower texture. Default = 0.0.
|
||||
offsety_bottom = <float>; // Y offset for lower texture. Default = 0.0.
|
||||
|
||||
comment = <string>; // A comment. Implementors should attach no special
|
||||
// semantic meaning to this field.
|
||||
}
|
||||
|
||||
sector
|
||||
{
|
||||
heightfloor = <integer>; // Floor height. Default = 0.
|
||||
heightceiling = <integer>; // Ceiling height. Default = 0.
|
||||
|
||||
texturefloor = <string>; // Floor flat. No valid default.
|
||||
textureceiling = <string>; // Ceiling flat. No valid default.
|
||||
|
||||
lightlevel = <integer>; // Light level. Default = 255.
|
||||
lightfloor = <integer>; // The floor's light level. Default is 0.
|
||||
lightceiling = <integer>; // The ceiling's light level. Default is 0.
|
||||
lightfloorabsolute = <bool>; // true = 'lightfloor' is an absolute value. Default is
|
||||
// relative to the owning sector's light level.
|
||||
lightceilingabsolute = <bool>; // true = 'lightceiling' is an absolute value. Default is
|
||||
// relative to the owning sector's light level.
|
||||
|
||||
special = <integer>; // Sector special. Default = 0.
|
||||
id = <integer>; // Sector tag/id. Default = 0.
|
||||
moreids = <string>; // Additional sector IDs/tags, specified as a space separated list of numbers (e.g. "2 666 1003 4505")
|
||||
|
||||
xpanningfloor = <float>; // X texture offset of floor texture. Default = 0.0.
|
||||
ypanningfloor = <float>; // Y texture offset of floor texture. Default = 0.0.
|
||||
xpanningceiling = <float>; // X texture offset of ceiling texture. Default = 0.0.
|
||||
ypanningceiling = <float>; // Y texture offset of ceiling texture. Default = 0.0.
|
||||
xscalefloor = <float>; // X texture scale of floor texture. Default = 1.0.
|
||||
yscalefloor = <float>; // Y texture scale of floor texture. Default = 1.0.
|
||||
xscaleceiling = <float>; // X texture scale of ceiling texture. Default = 1.0.
|
||||
yscaleceiling = <float>; // Y texture scale of ceiling texture. Default = 1.0.
|
||||
rotationfloor = <float>; // Rotation of floor texture in degrees. Default = 0.0.
|
||||
rotationceiling = <float>; // Rotation of ceiling texture in degrees. Default = 0.0.
|
||||
ceilingplane_a = <float>; // Define the plane equation for the sector's ceiling. Default is a horizontal plane at 'heightceiling'.
|
||||
ceilingplane_b = <float>; // 'heightceiling' will still be used to calculate texture alignment.
|
||||
ceilingplane_c = <float>; // The plane equation will only be used if all 4 values are given.
|
||||
ceilingplane_d = <float>; // The plane is defined as a*x + b*y + c*z + d = 0 with the normal vector pointing downward.
|
||||
floorplane_a = <float>; // Define the plane equation for the sector's floor. Default is a horizontal plane at 'heightfloor'.
|
||||
floorplane_b = <float>; // 'heightfloor' will still be used to calculate texture alignment.
|
||||
floorplane_c = <float>; // The plane equation will only be used if all 4 values are given.
|
||||
floorplane_d = <float>; // The plane is defined as a*x + b*y + c*z + d = 0 with the normal vector pointing upward.
|
||||
|
||||
lightcolor = <integer>; // Sector's light color as RRGGBB value. Default = 0x000000.
|
||||
lightalpha = <integer>; // Sector's light opacity. Default = 25.
|
||||
fadecolor = <integer>; // Sector's fog color as RRGGBB value. Default = 0x000000.
|
||||
fadealpha = <integer>; // Sector's fog opacity. Default = 25.
|
||||
fadestart = <integer>; // Sector's fading range start. Default = 0.
|
||||
fadeend = <integer>; // Sector's fading range end. Default = 31.
|
||||
colormapfog = <bool>; // Sector's colormap uses fog lighting.
|
||||
colormapfadesprites = <bool>; // Sector's colormap affects full-bright sprites.
|
||||
colormapprotected = <bool>; // Sector's colormap is not affected by colormap change specials.
|
||||
|
||||
flipspecial_nofloor = <bool>; // Trigger effects that require a plane touch are not executed when the floor is touched.
|
||||
flipspecial_ceiling = <bool>; // Trigger effects that require a plane touch are executed when the ceiling is touched.
|
||||
triggerspecial_touch = <bool>; // Trigger effects are executed anywhere in the sector.
|
||||
triggerspecial_headbump = <bool>; // Trigger effects are executed if the top of the triggerer object touches a plane.
|
||||
triggerline_plane = <bool>; // Trigger effects require a plane touch to be executed.
|
||||
triggerline_mobj = <bool>; // Trigger effects can be executed by non-pushable objects.
|
||||
|
||||
invertprecip = <bool>; // Inverts the precipitation effect; if the sector is considered to be indoors,
|
||||
// precipitation is generated, and if the sector is considered to be outdoors,
|
||||
// precipitation is not generated.
|
||||
gravityflip = <bool>; // Sector flips any objects in it, if the sector has negative gravity.
|
||||
heatwave = <bool>; // Sector has the heat wave effect.
|
||||
noclipcamera = <bool>; // Sector is not tangible to the camera.
|
||||
outerspace = <bool>; // Sector has the space countdown effect.
|
||||
doublestepup = <bool>; // Sector has half the vertical height needed for objects to walk into it.
|
||||
nostepdown = <bool>; // Sector has the staircase effect disabled.
|
||||
speedpad = <bool>; // Sector is a speed pad.
|
||||
starpostactivator = <bool>; // Sector activates any Star Posts in it when walked into by a plyer.
|
||||
exit = <bool>; // Sector is an exit sector.
|
||||
specialstagepit = <bool>; // Sector is a Special Stage pit.
|
||||
returnflag = <bool>; // Sector returns any Capture the Flag flags that come in contact with it to their respective bases.
|
||||
redteambase = <bool>; // Sector is a Red Team base.
|
||||
blueteambase = <bool>; // Sector is Blue Team base.
|
||||
fan = <bool>; // Sector is a fan sector.
|
||||
supertransform = <bool>; // Sector transforms any players that come in contact with it into their 'super' mode.
|
||||
forcespin = <bool>; // Sector forces any players that come in contact with it to roll.
|
||||
zoomtubestart = <bool>; // Sector is the starting point of a zoom tube path.
|
||||
zoomtubeend = <bool>; // Sector is the ending point of a zoom tube path.
|
||||
finishline = <bool>; // Sector is a Circuit finish line.
|
||||
ropehang = <bool>; // Sector is a rope hang. Must be applied to a 3D floor.
|
||||
jumpflip = <bool>; // Sector flips the gravity of players who jump from it.
|
||||
gravityoverride = <bool>; // Reverse gravity effect is only applied when an object is in the sector.
|
||||
|
||||
friction = <float>; // Sector's friction factor.
|
||||
gravity = <float>; // Sector's gravity. Default is 1.0.
|
||||
damagetype = <integer>; // Damage type for sector damage. Can be:
|
||||
// - "None"
|
||||
// - "Generic"
|
||||
// - "Water"
|
||||
// - "Fire"
|
||||
// - "Lava"
|
||||
// - "Electric"
|
||||
// - "Spike"
|
||||
// - "DeathPitTilt"
|
||||
// - "DeathPitNoTilt"
|
||||
// - "Instakill"
|
||||
// - "SpecialStage"
|
||||
// Default = "None".
|
||||
triggertag = <integer>; // Tag to trigger when this sector is entered. Default = 0.
|
||||
triggerer = <string>; // Who can execute the trigger tag when this sector is entered. Can be:
|
||||
// - "Player"
|
||||
// - "AllPlayers"
|
||||
// - "Mobj"
|
||||
// Default = "Player".
|
||||
|
||||
comment = <string>; // A comment. Implementors should attach no special
|
||||
// semantic meaning to this field.
|
||||
}
|
||||
|
||||
thing
|
||||
{
|
||||
id = <integer>; // Thing ID. Default = 0.
|
||||
moreids = <string>; // Additional thing IDs, specified as a space separated list of numbers (e.g. "2 666 1003 4505")
|
||||
|
||||
x = <float>; // X coordinate. No valid default.
|
||||
y = <float>; // Y coordinate. No valid default.
|
||||
|
||||
height = <float>; // Z height relative to floor.
|
||||
// Relative to ceiling if flip = true.
|
||||
// Absolute if absolutez = true.
|
||||
// Default = 0.
|
||||
|
||||
angle = <integer>; // Map angle of thing in degrees. Default = 0 (East).
|
||||
pitch = <integer>; // Pitch of thing in degrees. Default = 0 (horizontal).
|
||||
roll = <integer>; // Roll of thing in degrees. Default = 0.
|
||||
scalex = <float>; // Horizontal visual scaling on thing. Default = 1.0.
|
||||
scaley = <float>; // Vertical visual scaling on thing. Default = 1.0.
|
||||
scale = <float>; // Vertical and horizontal visual scaling on thing. Default = 1.0.
|
||||
mobjscale = <float>; // Physical scale of the thing. Default = 1.0.
|
||||
|
||||
type = <integer>; // Thing type. No valid default.
|
||||
|
||||
flip = <bool>; // Thing spawns flipped, on the ceiling.
|
||||
absolutez = <bool>; // If true, the thing height is absolute, instead of being relative to the floor or ceiling.
|
||||
|
||||
arg0 = <integer>; // Argument 0. Default = 0.
|
||||
arg1 = <integer>; // Argument 1. Default = 0.
|
||||
arg2 = <integer>; // Argument 2. Default = 0.
|
||||
arg3 = <integer>; // Argument 3. Default = 0.
|
||||
arg4 = <integer>; // Argument 4. Default = 0.
|
||||
arg5 = <integer>; // Argument 5. Default = 0.
|
||||
arg6 = <integer>; // Argument 6. Default = 0.
|
||||
arg7 = <integer>; // Argument 7. Default = 0.
|
||||
arg8 = <integer>; // Argument 8. Default = 0.
|
||||
arg9 = <integer>; // Argument 9. Default = 0.
|
||||
stringarg0 = <string>; // String argument 0.
|
||||
stringarg1 = <string>; // String argument 1.
|
||||
|
||||
comment = <string>; // A comment. Implementors should attach no special
|
||||
// semantic meaning to this field.
|
||||
}
|
||||
|
||||
|
||||
=======================================
|
||||
Changelog
|
||||
=======================================
|
||||
|
||||
1.0: 19.02.2024
|
||||
Initial version.
|
||||
|
||||
===============================================================================
|
||||
EOF
|
||||
===============================================================================
|
|
@ -154,6 +154,10 @@ if (UNIX)
|
|||
target_compile_definitions(SRB2SDL2 PRIVATE -DUNIXCOMMON)
|
||||
endif()
|
||||
|
||||
if (BSD MATCHES "FreeBSD")
|
||||
target_compile_definitions(SRB2SDL2 PRIVATE -DFREEBSD)
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
find_program(OBJCOPY objcopy)
|
||||
endif()
|
||||
|
|
|
@ -120,7 +120,7 @@ static void CONS_backcolor_Change(void);
|
|||
#ifdef macintosh
|
||||
#define CON_BUFFERSIZE 4096 // my compiler can't handle local vars >32k
|
||||
#else
|
||||
#define CON_BUFFERSIZE 16384
|
||||
#define CON_BUFFERSIZE 32768
|
||||
#endif
|
||||
|
||||
static char con_buffer[CON_BUFFERSIZE];
|
||||
|
|
|
@ -96,6 +96,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
|
|||
#endif
|
||||
|
||||
#if defined (__unix__) || (defined (UNIXCOMMON) && !defined (__APPLE__))
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#define NEWSIGNALHANDLER
|
||||
|
@ -855,11 +856,21 @@ static void I_GetConsoleEvents(void)
|
|||
// we use this when sending back commands
|
||||
event_t ev = {0};
|
||||
char key = 0;
|
||||
ssize_t d;
|
||||
struct pollfd pfd =
|
||||
{
|
||||
.fd = STDIN_FILENO,
|
||||
.events = POLLIN,
|
||||
.revents = 0,
|
||||
};
|
||||
|
||||
if (!consolevent)
|
||||
return;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (poll(&pfd, 1, 0) < 1 || !(pfd.revents & POLLIN))
|
||||
return;
|
||||
|
||||
ev.type = ev_console;
|
||||
ev.key = 0;
|
||||
if (read(STDIN_FILENO, &key, 1) == -1 || !key)
|
||||
|
@ -886,7 +897,7 @@ static void I_GetConsoleEvents(void)
|
|||
tty_con.cursor = 0;
|
||||
ev.key = KEY_ENTER;
|
||||
}
|
||||
else return;
|
||||
else continue;
|
||||
}
|
||||
else if (tty_con.cursor < sizeof(tty_con.buffer))
|
||||
{
|
||||
|
@ -894,11 +905,11 @@ static void I_GetConsoleEvents(void)
|
|||
ev.key = tty_con.buffer[tty_con.cursor] = key;
|
||||
tty_con.cursor++;
|
||||
// print the current line (this is differential)
|
||||
d = write(STDOUT_FILENO, &key, 1);
|
||||
write(STDOUT_FILENO, &key, 1);
|
||||
}
|
||||
if (ev.key) D_PostEvent(&ev);
|
||||
//tty_FlushIn();
|
||||
(void)d;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined (_WIN32)
|
||||
|
|
|
@ -244,12 +244,12 @@ extern char logfilename[1024];
|
|||
#define MAXPLAYERNAME 21
|
||||
#define PLAYERSMASK (MAXPLAYERS-1)
|
||||
|
||||
// Don't make MAXSKINS higher than 256, since skin numbers are used with an
|
||||
// UINT8 in various parts of the codebase. If you do anyway, the data type
|
||||
// of those variables will have to be changed into at least an UINT16.
|
||||
// Don't make MAXSKINS higher than 255, since skin numbers are used with an UINT8 in
|
||||
// various parts of the codebase, and one number is reserved. If you do anyway,
|
||||
// the data type of those variables will have to be changed into at least an UINT16.
|
||||
// This change must affect code such as demo recording and playback,
|
||||
// and the structure of some networking packets and commands.
|
||||
#define MAXSKINS 256
|
||||
#define MAXSKINS 255
|
||||
#define MAXCHARACTERSLOTS (MAXSKINS * 3) // Should be higher than MAXSKINS.
|
||||
|
||||
#define COLORRAMPSIZE 16
|
||||
|
@ -552,7 +552,7 @@ void *M_Memcpy(void* dest, const void* src, size_t n);
|
|||
char *va(const char *format, ...) FUNCPRINTF;
|
||||
char *M_GetToken(const char *inputString);
|
||||
void M_UnGetToken(void);
|
||||
void M_TokenizerOpen(const char *inputString);
|
||||
void M_TokenizerOpen(const char *inputString, size_t len);
|
||||
void M_TokenizerClose(void);
|
||||
const char *M_TokenizerRead(UINT32 i);
|
||||
const char *M_TokenizerReadZDoom(UINT32 i);
|
||||
|
|
|
@ -297,7 +297,7 @@ static void F_NewCutscene(const char *basetext)
|
|||
cutscene_basetext = basetext;
|
||||
memset(cutscene_disptext,0,sizeof(cutscene_disptext));
|
||||
cutscene_writeptr = cutscene_baseptr = 0;
|
||||
cutscene_textspeed = 9;
|
||||
cutscene_textspeed = 8;
|
||||
cutscene_textcount = TICRATE/2;
|
||||
}
|
||||
|
||||
|
@ -313,22 +313,22 @@ const char *introtext[NUMINTROSCENES];
|
|||
static tic_t introscenetime[NUMINTROSCENES] =
|
||||
{
|
||||
5*TICRATE, // STJr Presents
|
||||
11*TICRATE + (TICRATE/2), // Two months had passed since...
|
||||
15*TICRATE + (TICRATE/2), // As it was about to drain the rings...
|
||||
14*TICRATE, // What Sonic, Tails, and Knuckles...
|
||||
18*TICRATE, // About once every year, a strange...
|
||||
19*TICRATE + (TICRATE/2), // Curses! Eggman yelled. That ridiculous...
|
||||
19*TICRATE + (TICRATE/4), // It was only later that he had an idea...
|
||||
10*TICRATE + (TICRATE/2), // Before beginning his scheme, Eggman decided to give Sonic...
|
||||
16*TICRATE, // We're ready to fire in 15 seconds, the robot said...
|
||||
16*TICRATE, // Meanwhile, Sonic was tearing across the zones...
|
||||
10*TICRATE + (TICRATE/2), // Two months had passed since...
|
||||
12*TICRATE + ((TICRATE/4) * 3), // As it was about to drain the rings...
|
||||
12*TICRATE + (TICRATE/4), // What Sonic, Tails, and Knuckles...
|
||||
16*TICRATE, // About once every year, a strange...
|
||||
20*TICRATE + (TICRATE/2), // Curses! Eggman yelled. That ridiculous...
|
||||
18*TICRATE + (TICRATE/4), // It was only later that he had an idea...
|
||||
9*TICRATE + (TICRATE/2), // Before beginning his scheme, Eggman decided to give Sonic...
|
||||
14*TICRATE, // We're ready to fire in 15 seconds, the robot said...
|
||||
14*TICRATE + (TICRATE/2), // Meanwhile, Sonic was tearing across the zones...
|
||||
16*TICRATE + (TICRATE/2), // Sonic knew he was getting closer to the city...
|
||||
17*TICRATE, // Greenflower City was gone...
|
||||
7*TICRATE, // You're not quite as dead as we thought, huh?...
|
||||
11*TICRATE + (TICRATE/2), // Greenflower City was gone...
|
||||
8*TICRATE, // You're not quite as dead as we thought, huh?...
|
||||
8*TICRATE, // We'll see... let's give you a quick warm up...
|
||||
18*TICRATE + (TICRATE/2), // Eggman took this as his cue and blasted off...
|
||||
16*TICRATE, // Easy! We go find Eggman and stop his...
|
||||
25*TICRATE, // I'm just finding what mission obje...
|
||||
15*TICRATE, // Easy! We go find Eggman and stop his...
|
||||
23*TICRATE, // I'm just finding what mission obje...
|
||||
};
|
||||
|
||||
// custom intros
|
||||
|
@ -1281,6 +1281,9 @@ void F_CreditDrawer(void)
|
|||
UINT8 colornum;
|
||||
const UINT8 *colormap;
|
||||
|
||||
// compensation for y on non-green resolutions, used to prevent text from disappearing before reaching the top
|
||||
UINT16 compy = (vid.height - (BASEVIDHEIGHT * vid.dup)) / 2;
|
||||
|
||||
if (players[consoleplayer].skincolor)
|
||||
colornum = players[consoleplayer].skincolor;
|
||||
else
|
||||
|
@ -1312,17 +1315,17 @@ void F_CreditDrawer(void)
|
|||
y += 80<<FRACBITS;
|
||||
break;
|
||||
case 1:
|
||||
if (y>>FRACBITS > -20)
|
||||
if (y>>FRACBITS > -20-compy)
|
||||
V_DrawCreditString((160 - (V_CreditStringWidth(&credits[i][1])>>1))<<FRACBITS, y, 0, &credits[i][1]);
|
||||
y += 30<<FRACBITS;
|
||||
break;
|
||||
case 2:
|
||||
if (y>>FRACBITS > -10)
|
||||
if (y>>FRACBITS > -10-compy)
|
||||
V_DrawStringAtFixed((BASEVIDWIDTH-V_StringWidth(&credits[i][1], V_ALLOWLOWERCASE|V_YELLOWMAP))<<FRACBITS>>1, y, V_ALLOWLOWERCASE|V_YELLOWMAP, &credits[i][1]);
|
||||
y += 12<<FRACBITS;
|
||||
break;
|
||||
default:
|
||||
if (y>>FRACBITS > -10)
|
||||
if (y>>FRACBITS > -10-compy)
|
||||
V_DrawStringAtFixed(32<<FRACBITS, y, V_ALLOWLOWERCASE, credits[i]);
|
||||
y += 12<<FRACBITS;
|
||||
break;
|
||||
|
|
|
@ -569,7 +569,7 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
|
|||
if (rendermode == render_opengl)
|
||||
{
|
||||
// send in the wipe type and wipe frame because we need to cache the graphic
|
||||
HWR_DoTintedWipe(wipetype, wipeframe-1);
|
||||
HWR_DoWipe(wipetype, wipeframe-1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
|
|
@ -10,5 +10,6 @@ target_sources(SRB2SDL2 PRIVATE
|
|||
hw_md3load.c
|
||||
hw_model.c
|
||||
hw_batching.c
|
||||
hw_shaders.c
|
||||
r_opengl/r_opengl.c
|
||||
)
|
||||
|
|
|
@ -9,4 +9,5 @@ hw_md2load.c
|
|||
hw_md3load.c
|
||||
hw_model.c
|
||||
hw_batching.c
|
||||
hw_shaders.c
|
||||
r_opengl/r_opengl.c
|
||||
|
|
|
@ -76,7 +76,7 @@ void HWR_SetCurrentTexture(GLMipmap_t *texture)
|
|||
// If batching is enabled, this function collects the polygon data and the chosen texture
|
||||
// for later use in HWR_RenderBatches. Otherwise the rendering backend is used to
|
||||
// render the polygon immediately.
|
||||
void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader, boolean horizonSpecial)
|
||||
void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader_target, boolean horizonSpecial)
|
||||
{
|
||||
if (currently_batching)
|
||||
{
|
||||
|
@ -114,7 +114,7 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
|
|||
polygonArray[polygonArraySize].numVerts = iNumPts;
|
||||
polygonArray[polygonArraySize].polyFlags = PolyFlags;
|
||||
polygonArray[polygonArraySize].texture = current_texture;
|
||||
polygonArray[polygonArraySize].shader = shader;
|
||||
polygonArray[polygonArraySize].shader = (shader_target != -1) ? HWR_GetShaderFromTarget(shader_target) : shader_target;
|
||||
polygonArray[polygonArraySize].horizonSpecial = horizonSpecial;
|
||||
// default to polygonArraySize so we don't lose order on horizon lines
|
||||
// (yes, it's supposed to be negative, since we're sorting in that direction)
|
||||
|
@ -134,7 +134,7 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
|
|||
DIGEST(hash, pSurf->PolyColor.rgba);
|
||||
if (cv_glshaders.value && gl_shadersavailable)
|
||||
{
|
||||
DIGEST(hash, shader);
|
||||
DIGEST(hash, shader_target);
|
||||
DIGEST(hash, pSurf->TintColor.rgba);
|
||||
DIGEST(hash, pSurf->FadeColor.rgba);
|
||||
DIGEST(hash, pSurf->LightInfo.light_level);
|
||||
|
@ -151,8 +151,7 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
|
|||
}
|
||||
else
|
||||
{
|
||||
if (shader)
|
||||
HWD.pfnSetShader(shader);
|
||||
HWD.pfnSetShader((shader_target != SHADER_NONE) ? HWR_GetShaderFromTarget(shader_target) : shader_target);
|
||||
HWD.pfnDrawPolygon(pSurf, pOutVerts, iNumPts, PolyFlags);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,14 @@
|
|||
INT32 patchformat = GL_TEXFMT_AP_88; // use alpha for holes
|
||||
INT32 textureformat = GL_TEXFMT_P_8; // use chromakey for hole
|
||||
|
||||
RGBA_t mapPalette[256] = {0}; // the palette for the currently loaded level or menu etc.
|
||||
|
||||
// Returns a pointer to the palette which should be used for caching textures.
|
||||
RGBA_t *HWR_GetTexturePalette(void)
|
||||
{
|
||||
return HWR_ShouldUsePaletteRendering() ? mapPalette : pLocalPalette;
|
||||
}
|
||||
|
||||
static INT32 format2bpp(GLTextureFormat_t format)
|
||||
{
|
||||
if (format == GL_TEXFMT_RGBA)
|
||||
|
@ -49,7 +57,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
|||
INT32 pblockheight, INT32 blockmodulo,
|
||||
fixed_t yfracstep, fixed_t scale_y,
|
||||
texpatch_t *originPatch, INT32 patchheight,
|
||||
INT32 bpp)
|
||||
INT32 bpp, RGBA_t *palette)
|
||||
{
|
||||
fixed_t yfrac, position, count;
|
||||
UINT8 *dest;
|
||||
|
@ -113,7 +121,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
|||
memcpy(dest, &texelu16, sizeof(UINT16));
|
||||
break;
|
||||
case 3:
|
||||
colortemp = V_GetColor(texel);
|
||||
colortemp = palette[texel];
|
||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||
{
|
||||
RGBA_t rgbatexel;
|
||||
|
@ -123,7 +131,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
|||
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
|
||||
break;
|
||||
case 4:
|
||||
colortemp = V_GetColor(texel);
|
||||
colortemp = palette[texel];
|
||||
colortemp.s.alpha = alpha;
|
||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||
{
|
||||
|
@ -152,7 +160,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
|||
INT32 pblockheight, INT32 blockmodulo,
|
||||
fixed_t yfracstep, fixed_t scale_y,
|
||||
texpatch_t *originPatch, INT32 patchheight,
|
||||
INT32 bpp)
|
||||
INT32 bpp, RGBA_t *palette)
|
||||
{
|
||||
fixed_t yfrac, position, count;
|
||||
UINT8 *dest;
|
||||
|
@ -217,7 +225,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
|||
memcpy(dest, &texelu16, sizeof(UINT16));
|
||||
break;
|
||||
case 3:
|
||||
colortemp = V_GetColor(texel);
|
||||
colortemp = palette[texel];
|
||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||
{
|
||||
RGBA_t rgbatexel;
|
||||
|
@ -227,7 +235,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
|||
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
|
||||
break;
|
||||
case 4:
|
||||
colortemp = V_GetColor(texel);
|
||||
colortemp = palette[texel];
|
||||
colortemp.s.alpha = alpha;
|
||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||
{
|
||||
|
@ -269,10 +277,13 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
|
|||
UINT8 *block = mipmap->data;
|
||||
INT32 bpp;
|
||||
INT32 blockmodulo;
|
||||
RGBA_t *palette;
|
||||
|
||||
if (pwidth <= 0 || pheight <= 0)
|
||||
return;
|
||||
|
||||
palette = HWR_GetTexturePalette();
|
||||
|
||||
ncols = pwidth;
|
||||
|
||||
// source advance
|
||||
|
@ -298,7 +309,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
|
|||
pblockheight, blockmodulo,
|
||||
yfracstep, scale_y,
|
||||
NULL, pheight, // not that pheight is going to get used anyway...
|
||||
bpp);
|
||||
bpp, palette);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,16 +328,19 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
|
|||
INT32 bpp;
|
||||
INT32 blockmodulo;
|
||||
INT32 width, height;
|
||||
RGBA_t *palette;
|
||||
// Column drawing function pointer.
|
||||
static void (*ColumnDrawerPointer)(const column_t *patchcol, UINT8 *block, GLMipmap_t *mipmap,
|
||||
INT32 pblockheight, INT32 blockmodulo,
|
||||
fixed_t yfracstep, fixed_t scale_y,
|
||||
texpatch_t *originPatch, INT32 patchheight,
|
||||
INT32 bpp);
|
||||
INT32 bpp, RGBA_t *palette);
|
||||
|
||||
if (texture->width <= 0 || texture->height <= 0)
|
||||
return;
|
||||
|
||||
palette = HWR_GetTexturePalette();
|
||||
|
||||
ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawFlippedColumnInCache : HWR_DrawColumnInCache;
|
||||
|
||||
x1 = patch->originx;
|
||||
|
@ -386,7 +400,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
|
|||
pblockheight, blockmodulo,
|
||||
yfracstep, scale_y,
|
||||
patch, height,
|
||||
bpp);
|
||||
bpp, palette);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -429,6 +443,9 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
|
|||
INT32 i;
|
||||
boolean skyspecial = false; //poor hack for Legacy large skies..
|
||||
|
||||
RGBA_t *palette;
|
||||
palette = HWR_GetTexturePalette();
|
||||
|
||||
texture = textures[texnum];
|
||||
|
||||
// hack the Legacy skies..
|
||||
|
@ -447,6 +464,9 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
|
|||
|
||||
grtex->mipmap.width = (UINT16)texture->width;
|
||||
grtex->mipmap.height = (UINT16)texture->height;
|
||||
if (skyspecial)
|
||||
grtex->mipmap.format = GL_TEXFMT_RGBA; // that skyspecial code below assumes this format ...
|
||||
else
|
||||
grtex->mipmap.format = textureformat;
|
||||
|
||||
blockwidth = texture->width;
|
||||
|
@ -459,7 +479,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
|
|||
INT32 j;
|
||||
RGBA_t col;
|
||||
|
||||
col = V_GetColor(HWR_PATCHES_CHROMAKEY_COLORINDEX);
|
||||
col = palette[HWR_PATCHES_CHROMAKEY_COLORINDEX];
|
||||
for (j = 0; j < blockheight; j++)
|
||||
{
|
||||
for (i = 0; i < blockwidth; i++)
|
||||
|
@ -739,19 +759,6 @@ void HWR_LoadMapTextures(size_t pnumtextures)
|
|||
gl_maptexturesloaded = true;
|
||||
}
|
||||
|
||||
void HWR_SetPalette(RGBA_t *palette)
|
||||
{
|
||||
HWD.pfnSetPalette(palette);
|
||||
|
||||
// hardware driver will flush there own cache if cache is non paletized
|
||||
// now flush data texture cache so 32 bit texture are recomputed
|
||||
if (patchformat == GL_TEXFMT_RGBA || textureformat == GL_TEXFMT_RGBA)
|
||||
{
|
||||
Z_FreeTag(PU_HWRCACHE);
|
||||
Z_FreeTag(PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Make sure texture is downloaded and set it as the source
|
||||
// --------------------------------------------------------------------------
|
||||
|
@ -823,18 +830,13 @@ void HWR_GetRawFlat(lumpnum_t flatlumpnum)
|
|||
|
||||
void HWR_GetLevelFlat(levelflat_t *levelflat)
|
||||
{
|
||||
if (levelflat->type == LEVELFLAT_NONE)
|
||||
if (levelflat->type == LEVELFLAT_NONE || levelflat->texture_id < 0)
|
||||
{
|
||||
HWR_SetCurrentTexture(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
INT32 texturenum = texturetranslation[levelflat->texture_id];
|
||||
if (texturenum <= 0)
|
||||
{
|
||||
HWR_SetCurrentTexture(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
GLMapTexture_t *grtex = &gl_flats[texturenum];
|
||||
GLMipmap_t *grMipmap = &grtex->mipmap;
|
||||
|
@ -970,6 +972,139 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch)
|
|||
Z_ChangeTag(gpatch->mipmap->data, PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
|
||||
static const INT32 picmode2GR[] =
|
||||
{
|
||||
GL_TEXFMT_P_8, // PALETTE
|
||||
0, // INTENSITY (unsupported yet)
|
||||
GL_TEXFMT_ALPHA_INTENSITY_88, // INTENSITY_ALPHA (corona use this)
|
||||
0, // RGB24 (unsupported yet)
|
||||
GL_TEXFMT_RGBA, // RGBA32 (opengl only)
|
||||
};
|
||||
|
||||
static void HWR_DrawPicInCache(UINT8 *block, INT32 pblockwidth, INT32 pblockheight,
|
||||
INT32 blockmodulo, pic_t *pic, INT32 bpp)
|
||||
{
|
||||
INT32 i,j;
|
||||
fixed_t posx, posy, stepx, stepy;
|
||||
UINT8 *dest, *src, texel;
|
||||
UINT16 texelu16;
|
||||
INT32 picbpp;
|
||||
RGBA_t col;
|
||||
RGBA_t *palette = HWR_GetTexturePalette();
|
||||
|
||||
stepy = ((INT32)SHORT(pic->height)<<FRACBITS)/pblockheight;
|
||||
stepx = ((INT32)SHORT(pic->width)<<FRACBITS)/pblockwidth;
|
||||
picbpp = format2bpp(picmode2GR[pic->mode]);
|
||||
posy = 0;
|
||||
for (j = 0; j < pblockheight; j++)
|
||||
{
|
||||
posx = 0;
|
||||
dest = &block[j*blockmodulo];
|
||||
src = &pic->data[(posy>>FRACBITS)*SHORT(pic->width)*picbpp];
|
||||
for (i = 0; i < pblockwidth;i++)
|
||||
{
|
||||
switch (pic->mode)
|
||||
{ // source bpp
|
||||
case PALETTE :
|
||||
texel = src[(posx+FRACUNIT/2)>>FRACBITS];
|
||||
switch (bpp)
|
||||
{ // destination bpp
|
||||
case 1 :
|
||||
*dest++ = texel; break;
|
||||
case 2 :
|
||||
texelu16 = (UINT16)(texel | 0xff00);
|
||||
memcpy(dest, &texelu16, sizeof(UINT16));
|
||||
dest += sizeof(UINT16);
|
||||
break;
|
||||
case 3 :
|
||||
col = palette[texel];
|
||||
memcpy(dest, &col, sizeof(RGBA_t)-sizeof(UINT8));
|
||||
dest += sizeof(RGBA_t)-sizeof(UINT8);
|
||||
break;
|
||||
case 4 :
|
||||
memcpy(dest, &palette[texel], sizeof(RGBA_t));
|
||||
dest += sizeof(RGBA_t);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case INTENSITY :
|
||||
*dest++ = src[(posx+FRACUNIT/2)>>FRACBITS];
|
||||
break;
|
||||
case INTENSITY_ALPHA : // assume dest bpp = 2
|
||||
memcpy(dest, src + ((posx+FRACUNIT/2)>>FRACBITS)*sizeof(UINT16), sizeof(UINT16));
|
||||
dest += sizeof(UINT16);
|
||||
break;
|
||||
case RGB24 :
|
||||
break; // not supported yet
|
||||
case RGBA32 : // assume dest bpp = 4
|
||||
dest += sizeof(UINT32);
|
||||
memcpy(dest, src + ((posx+FRACUNIT/2)>>FRACBITS)*sizeof(UINT32), sizeof(UINT32));
|
||||
break;
|
||||
}
|
||||
posx += stepx;
|
||||
}
|
||||
posy += stepy;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
// HWR_GetPic : Download a Doom pic (raw row encoded with no 'holes')
|
||||
// Returns :
|
||||
// -----------------+
|
||||
patch_t *HWR_GetPic(lumpnum_t lumpnum)
|
||||
{
|
||||
patch_t *patch = HWR_GetCachedGLPatch(lumpnum);
|
||||
GLPatch_t *grPatch = (GLPatch_t *)(patch->hardware);
|
||||
|
||||
if (!grPatch->mipmap->downloaded && !grPatch->mipmap->data)
|
||||
{
|
||||
pic_t *pic;
|
||||
UINT8 *block;
|
||||
size_t len;
|
||||
|
||||
pic = W_CacheLumpNum(lumpnum, PU_CACHE);
|
||||
patch->width = SHORT(pic->width);
|
||||
patch->height = SHORT(pic->height);
|
||||
len = W_LumpLength(lumpnum) - sizeof (pic_t);
|
||||
|
||||
grPatch->mipmap->width = (UINT16)patch->width;
|
||||
grPatch->mipmap->height = (UINT16)patch->height;
|
||||
|
||||
if (pic->mode == PALETTE)
|
||||
grPatch->mipmap->format = textureformat; // can be set by driver
|
||||
else
|
||||
grPatch->mipmap->format = picmode2GR[pic->mode];
|
||||
|
||||
Z_Free(grPatch->mipmap->data);
|
||||
|
||||
// allocate block
|
||||
block = MakeBlock(grPatch->mipmap);
|
||||
|
||||
if (patch->width == SHORT(pic->width) &&
|
||||
patch->height == SHORT(pic->height) &&
|
||||
format2bpp(grPatch->mipmap->format) == format2bpp(picmode2GR[pic->mode]))
|
||||
{
|
||||
// no conversion needed
|
||||
M_Memcpy(grPatch->mipmap->data, pic->data,len);
|
||||
}
|
||||
else
|
||||
HWR_DrawPicInCache(block, SHORT(pic->width), SHORT(pic->height),
|
||||
SHORT(pic->width)*format2bpp(grPatch->mipmap->format),
|
||||
pic,
|
||||
format2bpp(grPatch->mipmap->format));
|
||||
|
||||
Z_Unlock(pic);
|
||||
Z_ChangeTag(block, PU_HWRCACHE_UNLOCKED);
|
||||
|
||||
grPatch->mipmap->flags = 0;
|
||||
grPatch->max_s = grPatch->max_t = 1.0f;
|
||||
}
|
||||
HWD.pfnSetTexture(grPatch->mipmap);
|
||||
//CONS_Debug(DBG_RENDER, "picloaded at %x as texture %d\n",grPatch->mipmap->data, grPatch->mipmap->downloaded);
|
||||
|
||||
return patch;
|
||||
}
|
||||
|
||||
patch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum)
|
||||
{
|
||||
lumpcache_t *lumpcache = wadfiles[wadnum]->patchcache;
|
||||
|
@ -997,6 +1132,7 @@ static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32
|
|||
UINT8 *flat;
|
||||
UINT8 *dest, *src, texel;
|
||||
RGBA_t col;
|
||||
RGBA_t *palette = HWR_GetTexturePalette();
|
||||
|
||||
// Place the flats data into flat
|
||||
W_ReadLump(fademasklumpnum, Z_Malloc(W_LumpLength(fademasklumpnum),
|
||||
|
@ -1014,7 +1150,7 @@ static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32
|
|||
{
|
||||
// fademask bpp is always 1, and is used just for alpha
|
||||
texel = src[(posx)>>FRACBITS];
|
||||
col = V_GetColor(texel);
|
||||
col = palette[texel];
|
||||
*dest = col.s.red; // take the red level of the colour and use it for alpha, as fademasks do
|
||||
|
||||
dest++;
|
||||
|
@ -1086,4 +1222,185 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum)
|
|||
Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
|
||||
// =================================================
|
||||
// PALETTE HANDLING
|
||||
// =================================================
|
||||
|
||||
void HWR_SetPalette(RGBA_t *palette)
|
||||
{
|
||||
if (HWR_ShouldUsePaletteRendering())
|
||||
{
|
||||
// set the palette for palette postprocessing
|
||||
|
||||
if (cv_glpalettedepth.value == 16)
|
||||
{
|
||||
// crush to 16-bit rgb565, like software currently does in the standard configuration
|
||||
// Note: Software's screenshots have the 24-bit palette, but the screen gets
|
||||
// the 16-bit version! For making comparison screenshots either use an external screenshot
|
||||
// tool or set the palette depth to 24 bits.
|
||||
RGBA_t crushed_palette[256];
|
||||
int i;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
float fred = (float)(palette[i].s.red >> 3);
|
||||
float fgreen = (float)(palette[i].s.green >> 2);
|
||||
float fblue = (float)(palette[i].s.blue >> 3);
|
||||
crushed_palette[i].s.red = (UINT8)(fred / 31.0f * 255.0f);
|
||||
crushed_palette[i].s.green = (UINT8)(fgreen / 63.0f * 255.0f);
|
||||
crushed_palette[i].s.blue = (UINT8)(fblue / 31.0f * 255.0f);
|
||||
crushed_palette[i].s.alpha = 255;
|
||||
}
|
||||
HWD.pfnSetScreenPalette(crushed_palette);
|
||||
}
|
||||
else
|
||||
{
|
||||
HWD.pfnSetScreenPalette(palette);
|
||||
}
|
||||
|
||||
// this part is responsible for keeping track of the palette OUTSIDE of a level.
|
||||
if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)))
|
||||
HWR_SetMapPalette();
|
||||
}
|
||||
else
|
||||
{
|
||||
// set the palette for the textures
|
||||
HWD.pfnSetTexturePalette(palette);
|
||||
// reset mapPalette so next call to HWR_SetMapPalette will update everything correctly
|
||||
memset(mapPalette, 0, sizeof(mapPalette));
|
||||
// hardware driver will flush there own cache if cache is non paletized
|
||||
// now flush data texture cache so 32 bit texture are recomputed
|
||||
if (patchformat == GL_TEXFMT_RGBA || textureformat == GL_TEXFMT_RGBA)
|
||||
{
|
||||
Z_FreeTag(PU_HWRCACHE);
|
||||
Z_FreeTag(PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void HWR_SetPaletteLookup(RGBA_t *palette)
|
||||
{
|
||||
int r, g, b;
|
||||
UINT8 *lut = Z_Malloc(
|
||||
HWR_PALETTE_LUT_SIZE*HWR_PALETTE_LUT_SIZE*HWR_PALETTE_LUT_SIZE*sizeof(UINT8),
|
||||
PU_STATIC, NULL);
|
||||
#define STEP_SIZE (256/HWR_PALETTE_LUT_SIZE)
|
||||
for (b = 0; b < HWR_PALETTE_LUT_SIZE; b++)
|
||||
{
|
||||
for (g = 0; g < HWR_PALETTE_LUT_SIZE; g++)
|
||||
{
|
||||
for (r = 0; r < HWR_PALETTE_LUT_SIZE; r++)
|
||||
{
|
||||
lut[b*HWR_PALETTE_LUT_SIZE*HWR_PALETTE_LUT_SIZE+g*HWR_PALETTE_LUT_SIZE+r] =
|
||||
NearestPaletteColor(r*STEP_SIZE, g*STEP_SIZE, b*STEP_SIZE, palette);
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef STEP_SIZE
|
||||
HWD.pfnSetPaletteLookup(lut);
|
||||
Z_Free(lut);
|
||||
}
|
||||
|
||||
// Updates mapPalette to reflect the loaded level or other game state.
|
||||
// Textures are flushed if needed.
|
||||
// Call this function only in palette rendering mode.
|
||||
void HWR_SetMapPalette(void)
|
||||
{
|
||||
RGBA_t RGBA_converted[256];
|
||||
RGBA_t *palette;
|
||||
int i;
|
||||
|
||||
if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)))
|
||||
{
|
||||
// outside of a level, pMasterPalette should have PLAYPAL ready for us
|
||||
palette = pMasterPalette;
|
||||
}
|
||||
else
|
||||
{
|
||||
// in a level pMasterPalette might have a flash palette, but we
|
||||
// want the map's original palette.
|
||||
lumpnum_t lumpnum = W_GetNumForName(GetPalette());
|
||||
size_t palsize = W_LumpLength(lumpnum);
|
||||
UINT8 *RGB_data;
|
||||
if (palsize < 768) // 256 * 3
|
||||
I_Error("HWR_SetMapPalette: A programmer assumed palette lumps are at least 768 bytes long, but apparently this was a wrong assumption!\n");
|
||||
RGB_data = W_CacheLumpNum(lumpnum, PU_CACHE);
|
||||
// we got the RGB palette now, but we need it in RGBA format.
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
RGBA_converted[i].s.red = *(RGB_data++);
|
||||
RGBA_converted[i].s.green = *(RGB_data++);
|
||||
RGBA_converted[i].s.blue = *(RGB_data++);
|
||||
RGBA_converted[i].s.alpha = 255;
|
||||
}
|
||||
palette = RGBA_converted;
|
||||
}
|
||||
|
||||
// check if the palette has changed from the previous one
|
||||
if (memcmp(mapPalette, palette, sizeof(mapPalette)))
|
||||
{
|
||||
memcpy(mapPalette, palette, sizeof(mapPalette));
|
||||
// in palette rendering mode, this means that all rgba textures now have wrong colors
|
||||
// and the lookup table is outdated
|
||||
HWR_SetPaletteLookup(mapPalette);
|
||||
HWD.pfnSetTexturePalette(mapPalette);
|
||||
if (patchformat == GL_TEXFMT_RGBA || textureformat == GL_TEXFMT_RGBA)
|
||||
{
|
||||
Z_FreeTag(PU_HWRCACHE);
|
||||
Z_FreeTag(PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a hardware lighttable from the supplied lighttable.
|
||||
// Returns the id of the hw lighttable, usable in FSurfaceInfo.
|
||||
UINT32 HWR_CreateLightTable(UINT8 *lighttable)
|
||||
{
|
||||
UINT32 i, id;
|
||||
RGBA_t *palette = HWR_GetTexturePalette();
|
||||
RGBA_t *hw_lighttable = Z_Malloc(256 * 32 * sizeof(RGBA_t), PU_STATIC, NULL);
|
||||
|
||||
// To make the palette index -> RGBA mapping easier for the shader,
|
||||
// the hardware lighttable is composed of RGBA colors instead of palette indices.
|
||||
for (i = 0; i < 256 * 32; i++)
|
||||
hw_lighttable[i] = palette[lighttable[i]];
|
||||
|
||||
id = HWD.pfnCreateLightTable(hw_lighttable);
|
||||
Z_Free(hw_lighttable);
|
||||
return id;
|
||||
}
|
||||
|
||||
// get hwr lighttable id for colormap, create it if it doesn't already exist
|
||||
UINT32 HWR_GetLightTableID(extracolormap_t *colormap)
|
||||
{
|
||||
boolean default_colormap = false;
|
||||
if (!colormap)
|
||||
{
|
||||
colormap = R_GetDefaultColormap(); // a place to store the hw lighttable id
|
||||
// alternatively could just store the id in a global variable if there are issues
|
||||
default_colormap = true;
|
||||
}
|
||||
|
||||
// create hw lighttable if there isn't one
|
||||
if (!colormap->gl_lighttable_id)
|
||||
{
|
||||
UINT8 *colormap_pointer;
|
||||
|
||||
if (default_colormap)
|
||||
colormap_pointer = colormaps; // don't actually use the data from the "default colormap"
|
||||
else
|
||||
colormap_pointer = colormap->colormap;
|
||||
colormap->gl_lighttable_id = HWR_CreateLightTable(colormap_pointer);
|
||||
}
|
||||
|
||||
return colormap->gl_lighttable_id;
|
||||
}
|
||||
|
||||
// Note: all hardware lighttable ids assigned before this
|
||||
// call become invalid and must not be used.
|
||||
void HWR_ClearLightTables(void)
|
||||
{
|
||||
if (vid.glstate == VID_GL_LIBRARY_LOADED)
|
||||
HWD.pfnClearLightTables();
|
||||
}
|
||||
|
||||
#endif //HWRENDER
|
||||
|
|
|
@ -18,6 +18,12 @@
|
|||
#define ZCLIP_PLANE 4.0f // Used for the actual game drawing
|
||||
#define NZCLIP_PLANE 0.9f // Seems to be only used for the HUD and screen textures
|
||||
|
||||
// The width/height/depth of the palette lookup table used by palette rendering.
|
||||
// Changing this also requires changing the shader code!
|
||||
// Also assumed to be a power of two in some parts of the code.
|
||||
// 64 seems to work perfectly for the vanilla palette.
|
||||
#define HWR_PALETTE_LUT_SIZE 64
|
||||
|
||||
// ==========================================================================
|
||||
// SIMPLE TYPES
|
||||
// ==========================================================================
|
||||
|
@ -122,33 +128,31 @@ typedef struct
|
|||
} FOutVector;
|
||||
|
||||
#ifdef GL_SHADERS
|
||||
// Predefined shader types
|
||||
|
||||
// Shader targets used to render specific types of geometry.
|
||||
// A shader target is resolved to an actual shader with HWR_GetShaderFromTarget.
|
||||
// The shader returned may be a base shader or a custom shader.
|
||||
enum
|
||||
{
|
||||
SHADER_NONE = -1,
|
||||
SHADER_DEFAULT = 0,
|
||||
|
||||
SHADER_FLOOR,
|
||||
SHADER_FLOOR = 0,
|
||||
SHADER_WALL,
|
||||
SHADER_SPRITE,
|
||||
SHADER_MODEL, SHADER_MODEL_LIGHTING,
|
||||
SHADER_MODEL,
|
||||
SHADER_WATER,
|
||||
SHADER_FOG,
|
||||
SHADER_SKY,
|
||||
SHADER_PALETTE_POSTPROCESS,
|
||||
SHADER_UI_COLORMAP_FADE,
|
||||
SHADER_UI_TINTED_WIPE,
|
||||
|
||||
NUMBASESHADERS,
|
||||
NUMSHADERTARGETS
|
||||
};
|
||||
|
||||
// Maximum amount of shader programs
|
||||
// Must be higher than NUMBASESHADERS
|
||||
#define HWR_MAXSHADERS 16
|
||||
|
||||
// Shader sources (vertex and fragment)
|
||||
typedef struct
|
||||
{
|
||||
char *vertex;
|
||||
char *fragment;
|
||||
} shadersource_t;
|
||||
// Must be at least NUMSHADERTARGETS*2 to fit base and custom shaders for each shader target.
|
||||
#define HWR_MAXSHADERS NUMSHADERTARGETS*2
|
||||
|
||||
// Custom shader reference table
|
||||
typedef struct
|
||||
|
@ -272,11 +276,15 @@ struct FSurfaceInfo
|
|||
RGBA_t PolyColor;
|
||||
RGBA_t TintColor;
|
||||
RGBA_t FadeColor;
|
||||
UINT32 LightTableId;
|
||||
FLightInfo LightInfo;
|
||||
};
|
||||
typedef struct FSurfaceInfo FSurfaceInfo;
|
||||
|
||||
//Hurdler: added for backward compatibility
|
||||
#define GL_DEFAULTMIX 0x00000000
|
||||
#define GL_DEFAULTFOG 0xFF000000
|
||||
|
||||
// Various settings and states for the rendering backend.
|
||||
enum hwdsetspecialstate
|
||||
{
|
||||
HWD_SET_MODEL_LIGHTING = 1,
|
||||
|
@ -289,15 +297,13 @@ enum hwdsetspecialstate
|
|||
|
||||
typedef enum hwdsetspecialstate hwdspecialstate_t;
|
||||
|
||||
// Lactozilla: Shader options
|
||||
enum hwdshaderoption
|
||||
enum hwdshaderstage
|
||||
{
|
||||
HWD_SHADEROPTION_OFF,
|
||||
HWD_SHADEROPTION_ON,
|
||||
HWD_SHADEROPTION_NOCUSTOM,
|
||||
HWD_SHADERSTAGE_VERTEX,
|
||||
HWD_SHADERSTAGE_FRAGMENT,
|
||||
};
|
||||
|
||||
typedef enum hwdshaderoption hwdshaderoption_t;
|
||||
typedef enum hwdshaderstage hwdshaderstage_t;
|
||||
|
||||
// Lactozilla: Shader info
|
||||
// Generally set at the start of the frame.
|
||||
|
@ -318,5 +324,18 @@ enum hwdfiltermode
|
|||
HWD_SET_TEXTUREFILTER_MIXED3,
|
||||
};
|
||||
|
||||
// Screen texture slots
|
||||
enum hwdscreentexture
|
||||
{
|
||||
HWD_SCREENTEXTURE_WIPE_START, // source image for the wipe/fade effect
|
||||
HWD_SCREENTEXTURE_WIPE_END, // destination image for the wipe/fade effect
|
||||
HWD_SCREENTEXTURE_GENERIC1, // underwater/heat effect, intermission background
|
||||
HWD_SCREENTEXTURE_GENERIC2, // palette-based colormap fade, screen before palette rendering's postprocessing
|
||||
HWD_SCREENTEXTURE_GENERIC3, // screen after palette rendering's postprocessing
|
||||
NUMSCREENTEXTURES, // (generic3 is unused if palette rendering is disabled)
|
||||
};
|
||||
|
||||
typedef enum hwdscreentexture hwdscreentexture_t;
|
||||
|
||||
|
||||
#endif //_HWR_DEFS_
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "../st_stuff.h"
|
||||
#include "../p_local.h" // stplyr
|
||||
#include "../g_game.h" // players
|
||||
#include "../f_finale.h" // fade color factors
|
||||
|
||||
#include <fcntl.h>
|
||||
#include "../i_video.h" // for rendermode != render_glide
|
||||
|
@ -707,6 +708,7 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength)
|
|||
{
|
||||
FOutVector v[4];
|
||||
FSurfaceInfo Surf;
|
||||
FBITFIELD poly_flags = PF_NoTexture|PF_Modulated|PF_NoDepthTest;
|
||||
|
||||
v[0].x = v[3].x = -1.0f;
|
||||
v[2].x = v[1].x = 1.0f;
|
||||
|
@ -719,17 +721,59 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength)
|
|||
v[0].t = v[1].t = 1.0f;
|
||||
v[2].t = v[3].t = 0.0f;
|
||||
|
||||
if (color & 0xFF00) // Do COLORMAP fade.
|
||||
if (color & 0xFF00) // Special fade options
|
||||
{
|
||||
UINT16 option = color & 0x0F00;
|
||||
if (option == 0x0A00 || option == 0x0B00) // Tinted fades
|
||||
{
|
||||
INT32 r, g, b;
|
||||
int fade = strength * 8;
|
||||
|
||||
r = FADEREDFACTOR*fade/10;
|
||||
g = FADEGREENFACTOR*fade/10;
|
||||
b = FADEBLUEFACTOR*fade/10;
|
||||
|
||||
Surf.PolyColor.s.red = min(r, 255);
|
||||
Surf.PolyColor.s.green = min(g, 255);
|
||||
Surf.PolyColor.s.blue = min(b, 255);
|
||||
Surf.PolyColor.s.alpha = 255;
|
||||
|
||||
if (option == 0x0A00) // Tinted subtractive fade
|
||||
poly_flags |= PF_ReverseSubtract;
|
||||
else if (option == 0x0B00) // Tinted additive fade
|
||||
poly_flags |= PF_Additive;
|
||||
}
|
||||
else // COLORMAP fade
|
||||
{
|
||||
if (HWR_ShouldUsePaletteRendering())
|
||||
{
|
||||
const hwdscreentexture_t scr_tex = HWD_SCREENTEXTURE_GENERIC2;
|
||||
|
||||
Surf.LightTableId = HWR_GetLightTableID(NULL);
|
||||
Surf.LightInfo.light_level = strength;
|
||||
HWD.pfnMakeScreenTexture(scr_tex);
|
||||
HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_UI_COLORMAP_FADE));
|
||||
HWD.pfnDrawScreenTexture(scr_tex, &Surf, PF_ColorMapped|PF_NoDepthTest);
|
||||
HWD.pfnUnSetShader();
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Surf.PolyColor.rgba = UINT2RGBA(0x01010160);
|
||||
Surf.PolyColor.s.alpha = (strength*8);
|
||||
poly_flags |= PF_Translucent;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Do TRANSMAP** fade.
|
||||
{
|
||||
Surf.PolyColor.rgba = V_GetColor(color).rgba;
|
||||
RGBA_t *palette = HWR_GetTexturePalette();
|
||||
Surf.PolyColor.rgba = palette[color&0xFF].rgba;
|
||||
Surf.PolyColor.s.alpha = softwaretranstogl[strength];
|
||||
poly_flags |= PF_Translucent;
|
||||
}
|
||||
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
|
||||
HWD.pfnDrawPolygon(&Surf, v, 4, poly_flags);
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
|
@ -897,7 +941,8 @@ void HWR_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT16 ac
|
|||
}
|
||||
else // Do TRANSMAP** fade.
|
||||
{
|
||||
Surf.PolyColor.rgba = V_GetColor(actualcolor).rgba;
|
||||
RGBA_t *palette = HWR_GetTexturePalette();
|
||||
Surf.PolyColor.rgba = palette[actualcolor&0xFF].rgba;
|
||||
Surf.PolyColor.s.alpha = softwaretranstogl[strength];
|
||||
}
|
||||
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
|
||||
|
@ -1102,8 +1147,9 @@ void HWR_drawAMline(const fline_t *fl, INT32 color)
|
|||
{
|
||||
F2DCoord v1, v2;
|
||||
RGBA_t color_rgba;
|
||||
RGBA_t *palette = HWR_GetTexturePalette();
|
||||
|
||||
color_rgba = V_GetColor(color);
|
||||
color_rgba = palette[color&0xFF];
|
||||
|
||||
v1.x = ((float)fl->a.x-(vid.width/2.0f))*(2.0f/vid.width);
|
||||
v1.y = ((float)fl->a.y-(vid.height/2.0f))*(2.0f/vid.height);
|
||||
|
@ -1288,6 +1334,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
|
|||
FOutVector v[4];
|
||||
FSurfaceInfo Surf;
|
||||
float fx, fy, fw, fh;
|
||||
RGBA_t *palette = HWR_GetTexturePalette();
|
||||
UINT8 alphalevel = ((color & V_ALPHAMASK) >> V_ALPHASHIFT);
|
||||
|
||||
UINT8 perplayershuffle = 0;
|
||||
|
@ -1374,7 +1421,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
|
|||
{
|
||||
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
|
||||
{
|
||||
RGBA_t rgbaColour = V_GetColor(color);
|
||||
RGBA_t rgbaColour = palette[color&0xFF];
|
||||
FRGBAFloat clearColour;
|
||||
clearColour.red = (float)rgbaColour.s.red / 255;
|
||||
clearColour.green = (float)rgbaColour.s.green / 255;
|
||||
|
@ -1451,7 +1498,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
|
|||
v[0].t = v[1].t = 0.0f;
|
||||
v[2].t = v[3].t = 1.0f;
|
||||
|
||||
Surf.PolyColor = V_GetColor(color);
|
||||
Surf.PolyColor = palette[color&0xFF];
|
||||
|
||||
if (alphalevel)
|
||||
{
|
||||
|
@ -1539,11 +1586,12 @@ static inline boolean saveTGA(const char *file_name, void *buffer,
|
|||
UINT8 *HWR_GetScreenshot(void)
|
||||
{
|
||||
UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf));
|
||||
int tex = HWR_ShouldUsePaletteRendering() ? HWD_SCREENTEXTURE_GENERIC3 : HWD_SCREENTEXTURE_GENERIC2;
|
||||
|
||||
if (!buf)
|
||||
return NULL;
|
||||
// returns 24bit 888 RGB
|
||||
HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf);
|
||||
HWD.pfnReadScreenTexture(tex, (void *)buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -1551,6 +1599,7 @@ boolean HWR_Screenshot(const char *pathname)
|
|||
{
|
||||
boolean ret;
|
||||
UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf));
|
||||
int tex = HWR_ShouldUsePaletteRendering() ? HWD_SCREENTEXTURE_GENERIC3 : HWD_SCREENTEXTURE_GENERIC2;
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
|
@ -1559,7 +1608,7 @@ boolean HWR_Screenshot(const char *pathname)
|
|||
}
|
||||
|
||||
// returns 24bit 888 RGB
|
||||
HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf);
|
||||
HWD.pfnReadScreenTexture(tex, (void *)buf);
|
||||
|
||||
#ifdef USE_PNG
|
||||
ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL);
|
||||
|
|
|
@ -32,7 +32,7 @@ EXPORT void HWRAPI(Shutdown) (void);
|
|||
#ifdef _WINDOWS
|
||||
EXPORT void HWRAPI(GetModeList) (vmode_t **pvidmodes, INT32 *numvidmodes);
|
||||
#endif
|
||||
EXPORT void HWRAPI(SetPalette) (RGBA_t *ppal);
|
||||
EXPORT void HWRAPI(SetTexturePalette) (RGBA_t *ppal);
|
||||
EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl);
|
||||
EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color);
|
||||
EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags);
|
||||
|
@ -43,11 +43,10 @@ EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFl
|
|||
EXPORT void HWRAPI(SetTexture) (GLMipmap_t *TexInfo);
|
||||
EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *TexInfo);
|
||||
EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *TexInfo);
|
||||
EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data);
|
||||
EXPORT void HWRAPI(ReadScreenTexture) (int tex, UINT8 *dst_data);
|
||||
EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip);
|
||||
EXPORT void HWRAPI(ClearMipMapCache) (void);
|
||||
|
||||
//Hurdler: added for backward compatibility
|
||||
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value);
|
||||
|
||||
//Hurdler: added for new development
|
||||
|
@ -57,24 +56,26 @@ EXPORT void HWRAPI(SetTransform) (FTransform *ptransform);
|
|||
EXPORT INT32 HWRAPI(GetTextureUsed) (void);
|
||||
|
||||
EXPORT void HWRAPI(FlushScreenTextures) (void);
|
||||
EXPORT void HWRAPI(StartScreenWipe) (void);
|
||||
EXPORT void HWRAPI(EndScreenWipe) (void);
|
||||
EXPORT void HWRAPI(DoScreenWipe) (void);
|
||||
EXPORT void HWRAPI(DrawIntermissionBG) (void);
|
||||
EXPORT void HWRAPI(MakeScreenTexture) (void);
|
||||
EXPORT void HWRAPI(MakeScreenFinalTexture) (void);
|
||||
EXPORT void HWRAPI(DrawScreenFinalTexture) (int width, int height);
|
||||
EXPORT void HWRAPI(DoScreenWipe) (int wipeStart, int wipeEnd, FSurfaceInfo *surf, FBITFIELD polyFlags);
|
||||
EXPORT void HWRAPI(DrawScreenTexture) (int tex, FSurfaceInfo *surf, FBITFIELD polyflags);
|
||||
EXPORT void HWRAPI(MakeScreenTexture) (int tex);
|
||||
EXPORT void HWRAPI(DrawScreenFinalTexture) (int tex, int width, int height);
|
||||
|
||||
#define SCREENVERTS 10
|
||||
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
|
||||
|
||||
EXPORT boolean HWRAPI(CompileShaders) (void);
|
||||
EXPORT void HWRAPI(CleanShaders) (void);
|
||||
EXPORT void HWRAPI(SetShader) (int type);
|
||||
EXPORT boolean HWRAPI(InitShaders) (void);
|
||||
EXPORT void HWRAPI(LoadShader) (int slot, char *code, hwdshaderstage_t stage);
|
||||
EXPORT boolean HWRAPI(CompileShader) (int slot);
|
||||
EXPORT void HWRAPI(SetShader) (int slot);
|
||||
EXPORT void HWRAPI(UnSetShader) (void);
|
||||
|
||||
EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value);
|
||||
EXPORT void HWRAPI(LoadCustomShader) (int number, char *code, size_t size, boolean isfragment);
|
||||
|
||||
EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut);
|
||||
EXPORT UINT32 HWRAPI(CreateLightTable)(RGBA_t *hw_lighttable);
|
||||
EXPORT void HWRAPI(ClearLightTables)(void);
|
||||
EXPORT void HWRAPI(SetScreenPalette)(RGBA_t *palette);
|
||||
|
||||
// ==========================================================================
|
||||
// HWR DRIVER OBJECT, FOR CLIENT PROGRAM
|
||||
|
@ -85,7 +86,7 @@ EXPORT void HWRAPI(LoadCustomShader) (int number, char *code, size_t size, boole
|
|||
struct hwdriver_s
|
||||
{
|
||||
Init pfnInit;
|
||||
SetPalette pfnSetPalette;
|
||||
SetTexturePalette pfnSetTexturePalette;
|
||||
FinishUpdate pfnFinishUpdate;
|
||||
Draw2DLine pfnDraw2DLine;
|
||||
DrawPolygon pfnDrawPolygon;
|
||||
|
@ -96,10 +97,10 @@ struct hwdriver_s
|
|||
SetTexture pfnSetTexture;
|
||||
UpdateTexture pfnUpdateTexture;
|
||||
DeleteTexture pfnDeleteTexture;
|
||||
ReadRect pfnReadRect;
|
||||
ReadScreenTexture pfnReadScreenTexture;
|
||||
GClipRect pfnGClipRect;
|
||||
ClearMipMapCache pfnClearMipMapCache;
|
||||
SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility
|
||||
SetSpecialState pfnSetSpecialState;
|
||||
DrawModel pfnDrawModel;
|
||||
CreateModelVBOs pfnCreateModelVBOs;
|
||||
SetTransform pfnSetTransform;
|
||||
|
@ -112,21 +113,23 @@ struct hwdriver_s
|
|||
#endif
|
||||
PostImgRedraw pfnPostImgRedraw;
|
||||
FlushScreenTextures pfnFlushScreenTextures;
|
||||
StartScreenWipe pfnStartScreenWipe;
|
||||
EndScreenWipe pfnEndScreenWipe;
|
||||
DoScreenWipe pfnDoScreenWipe;
|
||||
DrawIntermissionBG pfnDrawIntermissionBG;
|
||||
DrawScreenTexture pfnDrawScreenTexture;
|
||||
MakeScreenTexture pfnMakeScreenTexture;
|
||||
MakeScreenFinalTexture pfnMakeScreenFinalTexture;
|
||||
DrawScreenFinalTexture pfnDrawScreenFinalTexture;
|
||||
|
||||
CompileShaders pfnCompileShaders;
|
||||
CleanShaders pfnCleanShaders;
|
||||
InitShaders pfnInitShaders;
|
||||
LoadShader pfnLoadShader;
|
||||
CompileShader pfnCompileShader;
|
||||
SetShader pfnSetShader;
|
||||
UnSetShader pfnUnSetShader;
|
||||
|
||||
SetShaderInfo pfnSetShaderInfo;
|
||||
LoadCustomShader pfnLoadCustomShader;
|
||||
|
||||
SetPaletteLookup pfnSetPaletteLookup;
|
||||
CreateLightTable pfnCreateLightTable;
|
||||
ClearLightTables pfnClearLightTables;
|
||||
SetScreenPalette pfnSetScreenPalette;
|
||||
};
|
||||
|
||||
extern struct hwdriver_s hwdriver;
|
||||
|
|
|
@ -107,6 +107,8 @@ void HWR_FreeExtraSubsectors(void);
|
|||
// --------
|
||||
// hw_cache.c
|
||||
// --------
|
||||
RGBA_t *HWR_GetTexturePalette(void);
|
||||
|
||||
void HWR_InitMapTextures(void);
|
||||
void HWR_LoadMapTextures(size_t pnumtextures);
|
||||
void HWR_FreeMapTextures(void);
|
||||
|
@ -131,6 +133,10 @@ void HWR_FreeColormapCache(void);
|
|||
void HWR_UnlockCachedPatch(GLPatch_t *gpatch);
|
||||
|
||||
void HWR_SetPalette(RGBA_t *palette);
|
||||
void HWR_SetMapPalette(void);
|
||||
UINT32 HWR_CreateLightTable(UINT8 *lighttable);
|
||||
UINT32 HWR_GetLightTableID(extracolormap_t *colormap);
|
||||
void HWR_ClearLightTables(void);
|
||||
|
||||
|
||||
// --------
|
||||
|
@ -139,4 +145,18 @@ void HWR_SetPalette(RGBA_t *palette);
|
|||
extern INT32 patchformat;
|
||||
extern INT32 textureformat;
|
||||
|
||||
// --------
|
||||
// hw_shaders.c
|
||||
// --------
|
||||
boolean HWR_InitShaders(void);
|
||||
void HWR_CompileShaders(void);
|
||||
|
||||
int HWR_GetShaderFromTarget(int shader_target);
|
||||
|
||||
void HWR_LoadAllCustomShaders(void);
|
||||
void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3);
|
||||
const char *HWR_GetShaderName(INT32 shader);
|
||||
|
||||
extern customshaderxlat_t shaderxlat[];
|
||||
|
||||
#endif //_HW_GLOB_
|
||||
|
|
|
@ -130,26 +130,6 @@ static line_t *gl_linedef;
|
|||
static sector_t *gl_frontsector;
|
||||
static sector_t *gl_backsector;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// STUFF FOR THE PROJECTION CODE
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
FTransform atransform;
|
||||
// duplicates of the main code, set after R_SetupFrame() passed them into sharedstruct,
|
||||
// copied here for local use
|
||||
static fixed_t dup_viewx, dup_viewy, dup_viewz;
|
||||
static angle_t dup_viewangle;
|
||||
|
||||
static float gl_viewx, gl_viewy, gl_viewz;
|
||||
float gl_viewsin, gl_viewcos;
|
||||
|
||||
// Maybe not necessary with the new T&L code (needs to be checked!)
|
||||
static float gl_viewludsin, gl_viewludcos; // look up down kik test
|
||||
static float gl_fovlud;
|
||||
|
||||
static angle_t gl_aimingangle;
|
||||
static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox);
|
||||
|
||||
// Render stats
|
||||
ps_metric_t ps_hw_skyboxtime = {0};
|
||||
ps_metric_t ps_hw_nodesorttime = {0};
|
||||
|
@ -170,13 +150,39 @@ ps_metric_t ps_hw_batchdrawtime = {0};
|
|||
|
||||
boolean gl_init = false;
|
||||
boolean gl_maploaded = false;
|
||||
boolean gl_shadersavailable = true;
|
||||
boolean gl_sessioncommandsadded = false;
|
||||
// false if shaders have not been initialized yet, or if shaders are not available
|
||||
boolean gl_shadersavailable = false;
|
||||
|
||||
// Whether the internal state is set to palette rendering or not.
|
||||
static boolean gl_palette_rendering_state = false;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// STUFF FOR THE PROJECTION CODE
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
FTransform atransform;
|
||||
// duplicates of the main code, set after R_SetupFrame() passed them into sharedstruct,
|
||||
// copied here for local use
|
||||
static fixed_t dup_viewx, dup_viewy, dup_viewz;
|
||||
static angle_t dup_viewangle;
|
||||
|
||||
static float gl_viewx, gl_viewy, gl_viewz;
|
||||
float gl_viewsin, gl_viewcos;
|
||||
|
||||
// Maybe not necessary with the new T&L code (needs to be checked!)
|
||||
static float gl_viewludsin, gl_viewludcos; // look up down kik test
|
||||
static float gl_fovlud;
|
||||
|
||||
static angle_t gl_aimingangle;
|
||||
static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox);
|
||||
|
||||
// ==========================================================================
|
||||
// Lighting
|
||||
// ==========================================================================
|
||||
|
||||
static boolean HWR_UseShader(void)
|
||||
// Returns true if shaders can be used.
|
||||
boolean HWR_UseShader(void)
|
||||
{
|
||||
return (cv_glshaders.value && gl_shadersavailable);
|
||||
}
|
||||
|
@ -242,6 +248,11 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
|
|||
Surface->LightInfo.light_level = light_level;
|
||||
Surface->LightInfo.fade_start = (colormap != NULL) ? colormap->fadestart : 0;
|
||||
Surface->LightInfo.fade_end = (colormap != NULL) ? colormap->fadeend : 31;
|
||||
|
||||
if (HWR_ShouldUsePaletteRendering())
|
||||
Surface->LightTableId = HWR_GetLightTableID(colormap);
|
||||
else
|
||||
Surface->LightTableId = 0;
|
||||
}
|
||||
|
||||
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if this can work
|
||||
|
@ -372,7 +383,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
|
|||
FOutVector *v3d;
|
||||
polyvertex_t *pv;
|
||||
pslope_t *slope = NULL;
|
||||
INT32 shader = SHADER_DEFAULT;
|
||||
INT32 shader = SHADER_NONE;
|
||||
|
||||
size_t nrPlaneVerts;
|
||||
INT32 i;
|
||||
|
@ -533,6 +544,9 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
|
|||
PolyFlags |= PF_ColorMapped;
|
||||
}
|
||||
|
||||
if (!cv_renderfloors.value)
|
||||
return;
|
||||
|
||||
HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags, shader, false);
|
||||
|
||||
if (subsector)
|
||||
|
@ -759,7 +773,10 @@ static void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, I
|
|||
//
|
||||
static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap)
|
||||
{
|
||||
INT32 shader = SHADER_DEFAULT;
|
||||
INT32 shader = SHADER_NONE;
|
||||
|
||||
if (!cv_renderwalls.value)
|
||||
return;
|
||||
|
||||
HWR_Lighting(pSurf, lightlevel, wallcolormap);
|
||||
|
||||
|
@ -834,6 +851,9 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
|||
FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, v1x, v1y, v2x, v2y);
|
||||
extracolormap_t *colormap = NULL;
|
||||
|
||||
if (!cv_renderwalls.value)
|
||||
return;
|
||||
|
||||
realtop = top = wallVerts[3].y;
|
||||
realbot = bot = wallVerts[0].y;
|
||||
diff = top - bot;
|
||||
|
@ -872,13 +892,15 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
|||
{
|
||||
if (pfloor && (pfloor->fofflags & FOF_FOG))
|
||||
{
|
||||
lightnum = HWR_CalcWallLight(pfloor->master->frontsector->lightlevel, v1x, v1y, v2x, v2y);
|
||||
lightnum = pfloor->master->frontsector->lightlevel;
|
||||
colormap = pfloor->master->frontsector->extra_colormap;
|
||||
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y);
|
||||
}
|
||||
else
|
||||
{
|
||||
lightnum = HWR_CalcWallLight(*list[i].lightlevel, v1x, v1y, v2x, v2y);
|
||||
lightnum = *list[i].lightlevel;
|
||||
colormap = *list[i].extra_colormap;
|
||||
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1109,8 +1131,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
float cliplow = (float)texturehpeg;
|
||||
float cliphigh = (float)(texturehpeg + (gl_curline->flength*FRACUNIT));
|
||||
|
||||
FUINT lightnum = HWR_CalcWallLight(gl_frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
|
||||
FUINT lightnum = gl_frontsector->lightlevel;
|
||||
extracolormap_t *colormap = gl_frontsector->extra_colormap;
|
||||
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y);
|
||||
|
||||
FSurfaceInfo Surf;
|
||||
Surf.PolyColor.s.alpha = 255;
|
||||
|
@ -1705,8 +1728,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
|
||||
blendmode = PF_Fog|PF_NoTexture;
|
||||
|
||||
lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
|
||||
lightnum = rover->master->frontsector->lightlevel;
|
||||
colormap = rover->master->frontsector->extra_colormap;
|
||||
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y);
|
||||
|
||||
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap);
|
||||
|
||||
|
@ -1827,8 +1851,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
|
||||
blendmode = PF_Fog|PF_NoTexture;
|
||||
|
||||
lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
|
||||
lightnum = rover->master->frontsector->lightlevel;
|
||||
colormap = rover->master->frontsector->extra_colormap;
|
||||
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y);
|
||||
|
||||
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap);
|
||||
|
||||
|
@ -2694,7 +2719,7 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
|
|||
{
|
||||
FSurfaceInfo Surf;
|
||||
FOutVector *v3d;
|
||||
INT32 shader = SHADER_DEFAULT;
|
||||
INT32 shader = SHADER_NONE;
|
||||
|
||||
size_t nrPlaneVerts = polysector->numVertices;
|
||||
INT32 i;
|
||||
|
@ -3527,7 +3552,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
float fscale; float fx; float fy; float offset;
|
||||
extracolormap_t *colormap = NULL;
|
||||
FBITFIELD blendmode = PF_Translucent|PF_Modulated;
|
||||
INT32 shader = SHADER_DEFAULT;
|
||||
INT32 shader = SHADER_NONE;
|
||||
UINT8 i;
|
||||
INT32 heightsec, phs;
|
||||
SINT8 flip = P_MobjFlip(thing);
|
||||
|
@ -3735,7 +3760,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
boolean lightset = true;
|
||||
FBITFIELD blend = 0;
|
||||
FBITFIELD occlusion;
|
||||
INT32 shader = SHADER_DEFAULT;
|
||||
INT32 shader = SHADER_NONE;
|
||||
boolean use_linkdraw_hack = false;
|
||||
UINT8 alpha;
|
||||
|
||||
|
@ -4306,7 +4331,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
|||
}
|
||||
|
||||
{
|
||||
INT32 shader = SHADER_DEFAULT;
|
||||
INT32 shader = SHADER_NONE;
|
||||
FBITFIELD blend = 0;
|
||||
FBITFIELD occlusion;
|
||||
boolean use_linkdraw_hack = false;
|
||||
|
@ -4380,7 +4405,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
|||
// Sprite drawer for precipitation
|
||||
static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
|
||||
{
|
||||
INT32 shader = SHADER_DEFAULT;
|
||||
INT32 shader = SHADER_NONE;
|
||||
FBITFIELD blend = 0;
|
||||
FOutVector wallVerts[4];
|
||||
patch_t *gpatch;
|
||||
|
@ -4825,7 +4850,6 @@ static void HWR_CreateDrawNodes(void)
|
|||
|
||||
// Okay! Let's draw it all! Woo!
|
||||
HWD.pfnSetTransform(&atransform);
|
||||
HWD.pfnSetShader(SHADER_DEFAULT);
|
||||
|
||||
for (i = 0; i < p; i++)
|
||||
{
|
||||
|
@ -5058,6 +5082,9 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
if (!cv_renderthings.value)
|
||||
return;
|
||||
|
||||
if (!thing)
|
||||
return;
|
||||
|
||||
|
@ -5884,7 +5911,8 @@ static void HWR_DrawSkyBackground(player_t *player)
|
|||
HWR_BuildSkyDome();
|
||||
}
|
||||
|
||||
HWD.pfnSetShader(SHADER_SKY); // sky shader
|
||||
if (HWR_UseShader())
|
||||
HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_SKY));
|
||||
HWD.pfnSetTransform(&dometransform);
|
||||
HWD.pfnRenderSkyDome(&gl_sky);
|
||||
}
|
||||
|
@ -5970,8 +5998,6 @@ static void HWR_DrawSkyBackground(player_t *player)
|
|||
HWD.pfnUnSetShader();
|
||||
HWD.pfnDrawPolygon(NULL, v, 4, 0);
|
||||
}
|
||||
|
||||
HWD.pfnSetShader(SHADER_DEFAULT);
|
||||
}
|
||||
|
||||
|
||||
|
@ -6061,13 +6087,7 @@ static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean
|
|||
//
|
||||
static void HWR_SetShaderState(void)
|
||||
{
|
||||
hwdshaderoption_t state = cv_glshaders.value;
|
||||
|
||||
if (!cv_glallowshaders.value)
|
||||
state = (cv_glshaders.value == HWD_SHADEROPTION_ON ? HWD_SHADEROPTION_NOCUSTOM : cv_glshaders.value);
|
||||
|
||||
HWD.pfnSetSpecialState(HWD_SET_SHADERS, (INT32)state);
|
||||
HWD.pfnSetShader(SHADER_DEFAULT);
|
||||
HWD.pfnSetSpecialState(HWD_SET_SHADERS, (INT32)HWR_UseShader());
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
|
@ -6083,6 +6103,7 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
|
|||
else
|
||||
type = &postimgtype;
|
||||
|
||||
if (!HWR_ShouldUsePaletteRendering())
|
||||
{
|
||||
// do we really need to save player (is it not the same)?
|
||||
player_t *saved_player = stplyr;
|
||||
|
@ -6275,6 +6296,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
|
|||
HWR_RenderSkyboxView(viewnumber, player); // This is drawn before everything else so it is placed behind
|
||||
PS_STOP_TIMING(ps_hw_skyboxtime);
|
||||
|
||||
if (!HWR_ShouldUsePaletteRendering())
|
||||
{
|
||||
// do we really need to save player (is it not the same)?
|
||||
player_t *saved_player = stplyr;
|
||||
|
@ -6451,6 +6473,56 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
|
|||
HWD.pfnGClipRect(0, 0, vid.width, vid.height, NZCLIP_PLANE);
|
||||
}
|
||||
|
||||
// Returns whether palette rendering is "actually enabled."
|
||||
// Can't have palette rendering if shaders are disabled.
|
||||
boolean HWR_ShouldUsePaletteRendering(void)
|
||||
{
|
||||
return (cv_glpaletterendering.value && HWR_UseShader());
|
||||
}
|
||||
|
||||
// enable or disable palette rendering state depending on settings and availability
|
||||
// called when relevant settings change
|
||||
// shader recompilation is done in the cvar callback
|
||||
static void HWR_TogglePaletteRendering(void)
|
||||
{
|
||||
// which state should we go to?
|
||||
if (HWR_ShouldUsePaletteRendering())
|
||||
{
|
||||
// are we not in that state already?
|
||||
if (!gl_palette_rendering_state)
|
||||
{
|
||||
gl_palette_rendering_state = true;
|
||||
|
||||
// The textures will still be converted to RGBA by r_opengl.
|
||||
// This however makes hw_cache use paletted blending for composite textures!
|
||||
// (patchformat is not touched)
|
||||
textureformat = GL_TEXFMT_P_8;
|
||||
|
||||
HWR_SetMapPalette();
|
||||
HWR_SetPalette(pLocalPalette);
|
||||
|
||||
// If the r_opengl "texture palette" stays the same during this switch, these textures
|
||||
// will not be cleared out. However they are still out of date since the
|
||||
// composite texture blending method has changed. Therefore they need to be cleared.
|
||||
HWR_LoadMapTextures(numtextures);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// are we not in that state already?
|
||||
if (gl_palette_rendering_state)
|
||||
{
|
||||
gl_palette_rendering_state = false;
|
||||
textureformat = GL_TEXFMT_RGBA;
|
||||
HWR_SetPalette(pLocalPalette);
|
||||
// If the r_opengl "texture palette" stays the same during this switch, these textures
|
||||
// will not be cleared out. However they are still out of date since the
|
||||
// composite texture blending method has changed. Therefore they need to be cleared.
|
||||
HWR_LoadMapTextures(numtextures);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HWR_LoadLevel(void)
|
||||
{
|
||||
#ifdef ALAM_LIGHTING
|
||||
|
@ -6464,6 +6536,9 @@ void HWR_LoadLevel(void)
|
|||
HWR_ClearSkyDome();
|
||||
HWR_BuildSkyDome();
|
||||
|
||||
if (HWR_ShouldUsePaletteRendering())
|
||||
HWR_SetMapPalette();
|
||||
|
||||
gl_maploaded = true;
|
||||
}
|
||||
|
||||
|
@ -6471,13 +6546,17 @@ void HWR_LoadLevel(void)
|
|||
// 3D ENGINE COMMANDS
|
||||
// ==========================================================================
|
||||
|
||||
static CV_PossibleValue_t glshaders_cons_t[] = {{HWD_SHADEROPTION_OFF, "Off"}, {HWD_SHADEROPTION_ON, "On"}, {HWD_SHADEROPTION_NOCUSTOM, "Ignore custom shaders"}, {0, NULL}};
|
||||
static CV_PossibleValue_t glshaders_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Ignore custom shaders"}, {0, NULL}};
|
||||
static CV_PossibleValue_t glmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}};
|
||||
static CV_PossibleValue_t glfakecontrast_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Smooth"}, {0, NULL}};
|
||||
static CV_PossibleValue_t glshearing_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Third-person"}, {0, NULL}};
|
||||
|
||||
static void CV_glfiltermode_OnChange(void);
|
||||
static void CV_glanisotropic_OnChange(void);
|
||||
static void CV_glmodellighting_OnChange(void);
|
||||
static void CV_glpaletterendering_OnChange(void);
|
||||
static void CV_glpalettedepth_OnChange(void);
|
||||
static void CV_glshaders_OnChange(void);
|
||||
|
||||
static CV_PossibleValue_t glfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"},
|
||||
{HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"},
|
||||
|
@ -6487,7 +6566,7 @@ static CV_PossibleValue_t glfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSA
|
|||
{0, NULL}};
|
||||
CV_PossibleValue_t glanisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}};
|
||||
|
||||
consvar_t cv_glshaders = CVAR_INIT ("gr_shaders", "On", CV_SAVE, glshaders_cons_t, NULL);
|
||||
consvar_t cv_glshaders = CVAR_INIT ("gr_shaders", "On", CV_SAVE|CV_CALL, glshaders_cons_t, CV_glshaders_OnChange);
|
||||
|
||||
#ifdef ALAM_LIGHTING
|
||||
consvar_t cv_gldynamiclighting = CVAR_INIT ("gr_dynamiclighting", "On", CV_SAVE, CV_OnOff, NULL);
|
||||
|
@ -6498,7 +6577,7 @@ consvar_t cv_glcoronasize = CVAR_INIT ("gr_coronasize", "1", CV_SAVE|CV_FLOAT, 0
|
|||
|
||||
consvar_t cv_glmodels = CVAR_INIT ("gr_models", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||
consvar_t cv_glmodelinterpolation = CVAR_INIT ("gr_modelinterpolation", "Sometimes", CV_SAVE, glmodelinterpolation_cons_t, NULL);
|
||||
consvar_t cv_glmodellighting = CVAR_INIT ("gr_modellighting", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||
consvar_t cv_glmodellighting = CVAR_INIT ("gr_modellighting", "Off", CV_SAVE|CV_CALL, CV_OnOff, CV_glmodellighting_OnChange);
|
||||
|
||||
consvar_t cv_glshearing = CVAR_INIT ("gr_shearing", "Off", CV_SAVE, glshearing_cons_t, NULL);
|
||||
consvar_t cv_glspritebillboarding = CVAR_INIT ("gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||
|
@ -6513,20 +6592,63 @@ consvar_t cv_glsolvetjoin = CVAR_INIT ("gr_solvetjoin", "On", 0, CV_OnOff, NULL)
|
|||
|
||||
consvar_t cv_glbatching = CVAR_INIT ("gr_batching", "On", 0, CV_OnOff, NULL);
|
||||
|
||||
static CV_PossibleValue_t glpalettedepth_cons_t[] = {{16, "16 bits"}, {24, "24 bits"}, {0, NULL}};
|
||||
|
||||
consvar_t cv_glpaletterendering = CVAR_INIT ("gr_paletterendering", "Off", CV_SAVE|CV_CALL, CV_OnOff, CV_glpaletterendering_OnChange);
|
||||
consvar_t cv_glpalettedepth = CVAR_INIT ("gr_palettedepth", "16 bits", CV_SAVE|CV_CALL, glpalettedepth_cons_t, CV_glpalettedepth_OnChange);
|
||||
|
||||
#define ONLY_IF_GL_LOADED if (vid.glstate != VID_GL_LIBRARY_LOADED) return;
|
||||
consvar_t cv_glwireframe = CVAR_INIT ("gr_wireframe", "Off", 0, CV_OnOff, NULL);
|
||||
|
||||
static void CV_glfiltermode_OnChange(void)
|
||||
{
|
||||
if (rendermode == render_opengl)
|
||||
ONLY_IF_GL_LOADED
|
||||
HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_glfiltermode.value);
|
||||
}
|
||||
|
||||
static void CV_glanisotropic_OnChange(void)
|
||||
{
|
||||
if (rendermode == render_opengl)
|
||||
ONLY_IF_GL_LOADED
|
||||
HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_glanisotropicmode.value);
|
||||
}
|
||||
|
||||
static void CV_glmodellighting_OnChange(void)
|
||||
{
|
||||
ONLY_IF_GL_LOADED
|
||||
// if shaders have been compiled, then they now need to be recompiled.
|
||||
if (gl_shadersavailable)
|
||||
HWR_CompileShaders();
|
||||
}
|
||||
|
||||
static void CV_glpaletterendering_OnChange(void)
|
||||
{
|
||||
ONLY_IF_GL_LOADED
|
||||
if (gl_shadersavailable)
|
||||
{
|
||||
HWR_CompileShaders();
|
||||
HWR_TogglePaletteRendering();
|
||||
}
|
||||
}
|
||||
|
||||
static void CV_glpalettedepth_OnChange(void)
|
||||
{
|
||||
ONLY_IF_GL_LOADED
|
||||
// refresh the screen palette
|
||||
if (HWR_ShouldUsePaletteRendering())
|
||||
HWR_SetPalette(pLocalPalette);
|
||||
}
|
||||
|
||||
static void CV_glshaders_OnChange(void)
|
||||
{
|
||||
ONLY_IF_GL_LOADED
|
||||
HWR_SetShaderState();
|
||||
if (cv_glpaletterendering.value)
|
||||
{
|
||||
// can't do palette rendering without shaders, so update the state if needed
|
||||
HWR_TogglePaletteRendering();
|
||||
}
|
||||
}
|
||||
|
||||
//added by Hurdler: console varibale that are saved
|
||||
void HWR_AddCommands(void)
|
||||
{
|
||||
|
@ -6553,6 +6675,8 @@ void HWR_AddCommands(void)
|
|||
|
||||
CV_RegisterVar(&cv_glbatching);
|
||||
|
||||
CV_RegisterVar(&cv_glpaletterendering);
|
||||
CV_RegisterVar(&cv_glpalettedepth);
|
||||
CV_RegisterVar(&cv_glwireframe);
|
||||
|
||||
#ifndef NEWCLIP
|
||||
|
@ -6569,6 +6693,8 @@ void HWR_Startup(void)
|
|||
{
|
||||
CONS_Printf("HWR_Startup()...\n");
|
||||
|
||||
textureformat = patchformat = GL_TEXFMT_RGBA;
|
||||
|
||||
HWR_InitPolyPool();
|
||||
HWR_InitMapTextures();
|
||||
HWR_InitModels();
|
||||
|
@ -6576,14 +6702,12 @@ void HWR_Startup(void)
|
|||
HWR_InitLight();
|
||||
#endif
|
||||
|
||||
gl_shadersavailable = HWR_InitShaders();
|
||||
HWR_SetShaderState();
|
||||
HWR_LoadAllCustomShaders();
|
||||
if (!HWR_CompileShaders())
|
||||
gl_shadersavailable = false;
|
||||
HWR_TogglePaletteRendering();
|
||||
}
|
||||
|
||||
if (rendermode == render_opengl)
|
||||
textureformat = patchformat = GL_TEXFMT_RGBA;
|
||||
|
||||
gl_init = true;
|
||||
}
|
||||
|
||||
|
@ -6647,6 +6771,9 @@ void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 te
|
|||
{
|
||||
static size_t allocedwalls = 0;
|
||||
|
||||
if (!cv_renderwalls.value)
|
||||
return;
|
||||
|
||||
// Force realloc if buffer has been freed
|
||||
if (!wallinfo)
|
||||
allocedwalls = 0;
|
||||
|
@ -6673,7 +6800,10 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend,
|
|||
FBITFIELD blendmode = blend;
|
||||
UINT8 alpha = pSurf->PolyColor.s.alpha; // retain the alpha
|
||||
|
||||
INT32 shader = SHADER_DEFAULT;
|
||||
INT32 shader = SHADER_NONE;
|
||||
|
||||
if (!cv_renderwalls.value)
|
||||
return;
|
||||
|
||||
// Lighting is done here instead so that fog isn't drawn incorrectly on transparent walls after sorting
|
||||
HWR_Lighting(pSurf, lightlevel, wallcolormap);
|
||||
|
@ -6718,7 +6848,7 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
|
||||
// Armageddon Blast Flash!
|
||||
// Could this even be considered postprocessor?
|
||||
if (player->flashcount)
|
||||
if (player->flashcount && !HWR_ShouldUsePaletteRendering())
|
||||
{
|
||||
FOutVector v[4];
|
||||
FSurfaceInfo Surf;
|
||||
|
@ -6743,7 +6873,7 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
|
||||
// Capture the screen for intermission and screen waving
|
||||
if(gamestate != GS_INTERMISSION)
|
||||
HWD.pfnMakeScreenTexture();
|
||||
HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_GENERIC1);
|
||||
|
||||
if (splitscreen) // Not supported in splitscreen - someone want to add support?
|
||||
return;
|
||||
|
@ -6787,7 +6917,7 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
|
||||
// Capture the screen again for screen waving on the intermission
|
||||
if(gamestate != GS_INTERMISSION)
|
||||
HWD.pfnMakeScreenTexture();
|
||||
HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_GENERIC1);
|
||||
}
|
||||
// Flipping of the screen isn't done here anymore
|
||||
}
|
||||
|
@ -6795,18 +6925,18 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
void HWR_StartScreenWipe(void)
|
||||
{
|
||||
//CONS_Debug(DBG_RENDER, "In HWR_StartScreenWipe()\n");
|
||||
HWD.pfnStartScreenWipe();
|
||||
HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_WIPE_START);
|
||||
}
|
||||
|
||||
void HWR_EndScreenWipe(void)
|
||||
{
|
||||
//CONS_Debug(DBG_RENDER, "In HWR_EndScreenWipe()\n");
|
||||
HWD.pfnEndScreenWipe();
|
||||
HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_WIPE_END);
|
||||
}
|
||||
|
||||
void HWR_DrawIntermissionBG(void)
|
||||
{
|
||||
HWD.pfnDrawIntermissionBG();
|
||||
HWD.pfnDrawScreenTexture(HWD_SCREENTEXTURE_GENERIC1, NULL, 0);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -6851,201 +6981,40 @@ void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum)
|
|||
return;
|
||||
|
||||
HWR_GetFadeMask(wipelumpnum);
|
||||
HWD.pfnDoScreenWipe();
|
||||
}
|
||||
|
||||
void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum)
|
||||
if (wipestyle == WIPESTYLE_COLORMAP && HWR_UseShader())
|
||||
{
|
||||
// It does the same thing
|
||||
HWR_DoWipe(wipenum, scrnnum);
|
||||
FSurfaceInfo surf = {0};
|
||||
FBITFIELD polyflags = PF_Modulated|PF_NoDepthTest;
|
||||
|
||||
polyflags |= (wipestyleflags & WSF_TOWHITE) ? PF_Additive : PF_ReverseSubtract;
|
||||
surf.PolyColor.s.red = FADEREDFACTOR;
|
||||
surf.PolyColor.s.green = FADEGREENFACTOR;
|
||||
surf.PolyColor.s.blue = FADEBLUEFACTOR;
|
||||
// polycolor alpha communicates fadein / fadeout to the shader and the backend
|
||||
surf.PolyColor.s.alpha = (wipestyleflags & WSF_FADEIN) ? 255 : 0;
|
||||
|
||||
HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_UI_TINTED_WIPE));
|
||||
HWD.pfnDoScreenWipe(HWD_SCREENTEXTURE_WIPE_START, HWD_SCREENTEXTURE_WIPE_END,
|
||||
&surf, polyflags);
|
||||
HWD.pfnUnSetShader();
|
||||
}
|
||||
else
|
||||
{
|
||||
HWD.pfnDoScreenWipe(HWD_SCREENTEXTURE_WIPE_START, HWD_SCREENTEXTURE_WIPE_END,
|
||||
NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void HWR_MakeScreenFinalTexture(void)
|
||||
{
|
||||
HWD.pfnMakeScreenFinalTexture();
|
||||
int tex = HWR_ShouldUsePaletteRendering() ? HWD_SCREENTEXTURE_GENERIC3 : HWD_SCREENTEXTURE_GENERIC2;
|
||||
HWD.pfnMakeScreenTexture(tex);
|
||||
}
|
||||
|
||||
void HWR_DrawScreenFinalTexture(int width, int height)
|
||||
{
|
||||
HWD.pfnDrawScreenFinalTexture(width, height);
|
||||
}
|
||||
|
||||
static inline UINT16 HWR_FindShaderDefs(UINT16 wadnum)
|
||||
{
|
||||
UINT16 i;
|
||||
lumpinfo_t *lump_p;
|
||||
|
||||
lump_p = wadfiles[wadnum]->lumpinfo;
|
||||
for (i = 0; i < wadfiles[wadnum]->numlumps; i++, lump_p++)
|
||||
if (memcmp(lump_p->name, "SHADERS", 7) == 0)
|
||||
return i;
|
||||
|
||||
return INT16_MAX;
|
||||
}
|
||||
|
||||
boolean HWR_CompileShaders(void)
|
||||
{
|
||||
return HWD.pfnCompileShaders();
|
||||
}
|
||||
|
||||
customshaderxlat_t shaderxlat[] =
|
||||
{
|
||||
{"Flat", SHADER_FLOOR},
|
||||
{"WallTexture", SHADER_WALL},
|
||||
{"Sprite", SHADER_SPRITE},
|
||||
{"Model", SHADER_MODEL},
|
||||
{"ModelLighting", SHADER_MODEL_LIGHTING},
|
||||
{"WaterRipple", SHADER_WATER},
|
||||
{"Fog", SHADER_FOG},
|
||||
{"Sky", SHADER_SKY},
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
void HWR_LoadAllCustomShaders(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
// read every custom shader
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
HWR_LoadCustomShadersFromFile(i, W_FileHasFolders(wadfiles[i]));
|
||||
}
|
||||
|
||||
void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3)
|
||||
{
|
||||
UINT16 lump;
|
||||
char *shaderdef, *line;
|
||||
char *stoken;
|
||||
char *value;
|
||||
size_t size;
|
||||
int linenum = 1;
|
||||
int shadertype = 0;
|
||||
int i;
|
||||
|
||||
lump = HWR_FindShaderDefs(wadnum);
|
||||
if (lump == INT16_MAX)
|
||||
return;
|
||||
|
||||
shaderdef = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE);
|
||||
size = W_LumpLengthPwad(wadnum, lump);
|
||||
|
||||
line = Z_Malloc(size+1, PU_STATIC, NULL);
|
||||
M_Memcpy(line, shaderdef, size);
|
||||
line[size] = '\0';
|
||||
|
||||
stoken = strtok(line, "\r\n ");
|
||||
while (stoken)
|
||||
{
|
||||
if ((stoken[0] == '/' && stoken[1] == '/')
|
||||
|| (stoken[0] == '#'))// skip comments
|
||||
{
|
||||
stoken = strtok(NULL, "\r\n");
|
||||
goto skip_field;
|
||||
}
|
||||
|
||||
if (!stricmp(stoken, "GLSL"))
|
||||
{
|
||||
value = strtok(NULL, "\r\n ");
|
||||
if (!value)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: Missing shader type (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
|
||||
stoken = strtok(NULL, "\r\n"); // skip end of line
|
||||
goto skip_lump;
|
||||
}
|
||||
|
||||
if (!stricmp(value, "VERTEX"))
|
||||
shadertype = 1;
|
||||
else if (!stricmp(value, "FRAGMENT"))
|
||||
shadertype = 2;
|
||||
|
||||
skip_lump:
|
||||
stoken = strtok(NULL, "\r\n ");
|
||||
linenum++;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = strtok(NULL, "\r\n= ");
|
||||
if (!value)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: Missing shader target (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
|
||||
stoken = strtok(NULL, "\r\n"); // skip end of line
|
||||
goto skip_field;
|
||||
}
|
||||
|
||||
if (!shadertype)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "HWR_LoadCustomShadersFromFile: Missing shader type (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
|
||||
Z_Free(line);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; shaderxlat[i].type; i++)
|
||||
{
|
||||
if (!stricmp(shaderxlat[i].type, stoken))
|
||||
{
|
||||
size_t shader_size;
|
||||
char *shader_source;
|
||||
char *shader_lumpname;
|
||||
UINT16 shader_lumpnum;
|
||||
|
||||
if (PK3)
|
||||
{
|
||||
shader_lumpname = Z_Malloc(strlen(value) + 12, PU_STATIC, NULL);
|
||||
strcpy(shader_lumpname, "Shaders/sh_");
|
||||
strcat(shader_lumpname, value);
|
||||
shader_lumpnum = W_CheckNumForFullNamePK3(shader_lumpname, wadnum, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
shader_lumpname = Z_Malloc(strlen(value) + 4, PU_STATIC, NULL);
|
||||
strcpy(shader_lumpname, "SH_");
|
||||
strcat(shader_lumpname, value);
|
||||
shader_lumpnum = W_CheckNumForNamePwad(shader_lumpname, wadnum, 0);
|
||||
}
|
||||
|
||||
if (shader_lumpnum == INT16_MAX)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "HWR_LoadCustomShadersFromFile: Missing shader source %s (file %s, line %d)\n", shader_lumpname, wadfiles[wadnum]->filename, linenum);
|
||||
Z_Free(shader_lumpname);
|
||||
continue;
|
||||
}
|
||||
|
||||
shader_size = W_LumpLengthPwad(wadnum, shader_lumpnum);
|
||||
shader_source = Z_Malloc(shader_size, PU_STATIC, NULL);
|
||||
W_ReadLumpPwad(wadnum, shader_lumpnum, shader_source);
|
||||
|
||||
HWD.pfnLoadCustomShader(shaderxlat[i].id, shader_source, shader_size, (shadertype == 2));
|
||||
|
||||
Z_Free(shader_source);
|
||||
Z_Free(shader_lumpname);
|
||||
}
|
||||
}
|
||||
|
||||
skip_field:
|
||||
stoken = strtok(NULL, "\r\n= ");
|
||||
linenum++;
|
||||
}
|
||||
}
|
||||
|
||||
Z_Free(line);
|
||||
return;
|
||||
}
|
||||
|
||||
const char *HWR_GetShaderName(INT32 shader)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
if (shader)
|
||||
{
|
||||
for (i = 0; shaderxlat[i].type; i++)
|
||||
{
|
||||
if (shaderxlat[i].id == shader)
|
||||
return shaderxlat[i].type;
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
return "Default";
|
||||
int tex = HWR_ShouldUsePaletteRendering() ? HWD_SCREENTEXTURE_GENERIC3 : HWD_SCREENTEXTURE_GENERIC2;
|
||||
HWD.pfnDrawScreenFinalTexture(tex, width, height);
|
||||
}
|
||||
|
||||
#endif // HWRENDER
|
||||
|
|
|
@ -61,11 +61,11 @@ void HWR_StartScreenWipe(void);
|
|||
void HWR_EndScreenWipe(void);
|
||||
void HWR_DrawIntermissionBG(void);
|
||||
void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum);
|
||||
void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum);
|
||||
void HWR_MakeScreenFinalTexture(void);
|
||||
void HWR_DrawScreenFinalTexture(int width, int height);
|
||||
|
||||
// This stuff is put here so models can use them
|
||||
boolean HWR_UseShader(void);
|
||||
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap);
|
||||
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work
|
||||
|
||||
|
@ -74,13 +74,7 @@ FBITFIELD HWR_GetBlendModeFlag(INT32 style);
|
|||
FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 transtablenum, FSurfaceInfo *pSurf);
|
||||
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf);
|
||||
|
||||
boolean HWR_CompileShaders(void);
|
||||
|
||||
void HWR_LoadAllCustomShaders(void);
|
||||
void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3);
|
||||
const char *HWR_GetShaderName(INT32 shader);
|
||||
|
||||
extern customshaderxlat_t shaderxlat[];
|
||||
boolean HWR_ShouldUsePaletteRendering(void);
|
||||
|
||||
extern CV_PossibleValue_t glanisotropicmode_cons_t[];
|
||||
|
||||
|
@ -103,8 +97,9 @@ extern consvar_t cv_glspritebillboarding;
|
|||
extern consvar_t cv_glskydome;
|
||||
extern consvar_t cv_glfakecontrast;
|
||||
extern consvar_t cv_glslopecontrast;
|
||||
|
||||
extern consvar_t cv_glbatching;
|
||||
extern consvar_t cv_glpaletterendering;
|
||||
extern consvar_t cv_glpalettedepth;
|
||||
|
||||
extern consvar_t cv_glwireframe;
|
||||
|
||||
|
|
|
@ -390,8 +390,6 @@ static void md2_loadTexture(md2_t *model)
|
|||
if (!grPatch->mipmap->downloaded && !grPatch->mipmap->data)
|
||||
{
|
||||
int w = 0, h = 0;
|
||||
UINT32 size;
|
||||
RGBA_t *image;
|
||||
|
||||
#ifdef HAVE_PNG
|
||||
grPatch->mipmap->format = PNG_Load(filename, &w, &h, grPatch);
|
||||
|
@ -412,6 +410,11 @@ static void md2_loadTexture(md2_t *model)
|
|||
grPatch->mipmap->width = (UINT16)w;
|
||||
grPatch->mipmap->height = (UINT16)h;
|
||||
|
||||
// for palette rendering, color cube is applied in post-processing instead of here
|
||||
if (!HWR_ShouldUsePaletteRendering())
|
||||
{
|
||||
UINT32 size;
|
||||
RGBA_t *image;
|
||||
// Lactozilla: Apply colour cube
|
||||
image = grPatch->mipmap->data;
|
||||
size = w*h;
|
||||
|
@ -421,6 +424,7 @@ static void md2_loadTexture(md2_t *model)
|
|||
image++;
|
||||
}
|
||||
}
|
||||
}
|
||||
HWD.pfnSetTexture(grPatch->mipmap);
|
||||
}
|
||||
|
||||
|
@ -1550,7 +1554,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
p.flip = atransform.flip;
|
||||
p.mirror = atransform.mirror;
|
||||
|
||||
HWD.pfnSetShader(SHADER_MODEL); // model shader
|
||||
if (HWR_UseShader())
|
||||
HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_MODEL));
|
||||
{
|
||||
float this_scale = FIXED_TO_FLOAT(interp.scale);
|
||||
|
||||
|
|
636
src/hardware/hw_shaders.c
Normal file
636
src/hardware/hw_shaders.c
Normal file
|
@ -0,0 +1,636 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2021 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file hw_shaders.c
|
||||
/// \brief Handles the shaders used by the game.
|
||||
|
||||
#ifdef HWRENDER
|
||||
|
||||
#include "hw_glob.h"
|
||||
#include "hw_drv.h"
|
||||
#include "hw_shaders.h"
|
||||
#include "../z_zone.h"
|
||||
|
||||
// ================
|
||||
// Shader sources
|
||||
// ================
|
||||
|
||||
static struct {
|
||||
const char *vertex;
|
||||
const char *fragment;
|
||||
} const gl_shadersources[] = {
|
||||
// Floor shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_FLOOR_FRAGMENT_SHADER},
|
||||
|
||||
// Wall shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
|
||||
|
||||
// Sprite shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
|
||||
|
||||
// Model shader
|
||||
{GLSL_MODEL_VERTEX_SHADER, GLSL_MODEL_FRAGMENT_SHADER},
|
||||
|
||||
// Water shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WATER_FRAGMENT_SHADER},
|
||||
|
||||
// Fog shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_FOG_FRAGMENT_SHADER},
|
||||
|
||||
// Sky shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_SKY_FRAGMENT_SHADER},
|
||||
|
||||
// Palette postprocess shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_PALETTE_POSTPROCESS_FRAGMENT_SHADER},
|
||||
|
||||
// UI colormap fade shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_UI_COLORMAP_FADE_FRAGMENT_SHADER},
|
||||
|
||||
// UI tinted wipe shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_UI_TINTED_WIPE_FRAGMENT_SHADER},
|
||||
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int base_shader; // index of base shader_t
|
||||
int custom_shader; // index of custom shader_t
|
||||
} shadertarget_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *vertex;
|
||||
char *fragment;
|
||||
boolean compiled;
|
||||
} shader_t; // these are in an array and accessed by indices
|
||||
|
||||
// the array has NUMSHADERTARGETS entries for base shaders and for custom shaders
|
||||
// the array could be expanded in the future to fit "dynamic" custom shaders that
|
||||
// aren't fixed to shader targets
|
||||
static shader_t gl_shaders[NUMSHADERTARGETS*2];
|
||||
|
||||
static shadertarget_t gl_shadertargets[NUMSHADERTARGETS];
|
||||
|
||||
#define WHITESPACE_CHARS " \t"
|
||||
|
||||
#define MODEL_LIGHTING_DEFINE "#define SRB2_MODEL_LIGHTING"
|
||||
#define PALETTE_RENDERING_DEFINE "#define SRB2_PALETTE_RENDERING"
|
||||
|
||||
// Initialize shader variables and the backend's shader system. Load the base shaders.
|
||||
// Returns false if shaders cannot be used.
|
||||
boolean HWR_InitShaders(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!HWD.pfnInitShaders())
|
||||
return false;
|
||||
|
||||
for (i = 0; i < NUMSHADERTARGETS; i++)
|
||||
{
|
||||
// set up string pointers for base shaders
|
||||
gl_shaders[i].vertex = Z_StrDup(gl_shadersources[i].vertex);
|
||||
gl_shaders[i].fragment = Z_StrDup(gl_shadersources[i].fragment);
|
||||
// set shader target indices to correct values
|
||||
gl_shadertargets[i].base_shader = i;
|
||||
gl_shadertargets[i].custom_shader = -1;
|
||||
}
|
||||
|
||||
HWR_CompileShaders();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// helper function: strstr but returns an int with the substring position
|
||||
// returns INT32_MAX if not found
|
||||
static INT32 strstr_int(const char *str1, const char *str2)
|
||||
{
|
||||
char *location = strstr(str1, str2);
|
||||
if (location)
|
||||
return location - str1;
|
||||
else
|
||||
return INT32_MAX;
|
||||
}
|
||||
|
||||
// Creates a preprocessed copy of the shader according to the current graphics settings
|
||||
// Returns a pointer to the results on success and NULL on failure.
|
||||
// Remember memory management of the returned string.
|
||||
static char *HWR_PreprocessShader(char *original)
|
||||
{
|
||||
const char *line_ending = "\n";
|
||||
int line_ending_len;
|
||||
char *read_pos = original;
|
||||
int original_len = strlen(original);
|
||||
int distance_to_end = original_len;
|
||||
int new_len;
|
||||
char *new_shader;
|
||||
char *write_pos;
|
||||
char shader_glsl_version[3];
|
||||
int version_pos = -1;
|
||||
int version_len = 0;
|
||||
|
||||
if (strstr(original, "\r\n"))
|
||||
{
|
||||
line_ending = "\r\n";
|
||||
// check if all line endings are same
|
||||
while ((read_pos = strchr(read_pos, '\n')))
|
||||
{
|
||||
read_pos--;
|
||||
if (*read_pos != '\r')
|
||||
{
|
||||
// this file contains mixed CRLF and LF line endings.
|
||||
// treating it as a LF file during parsing should keep
|
||||
// the results sane enough as long as the gpu driver is fine
|
||||
// with these kinds of weirdly formatted shader sources.
|
||||
line_ending = "\n";
|
||||
break;
|
||||
}
|
||||
read_pos += 2;
|
||||
}
|
||||
read_pos = original;
|
||||
}
|
||||
|
||||
line_ending_len = strlen(line_ending);
|
||||
|
||||
// Find the #version directive, if it exists. Also don't get fooled if it's
|
||||
// inside a comment. Copy the version digits so they can be used in the preamble.
|
||||
// Time for some string parsing :D
|
||||
|
||||
#define STARTSWITH(str, with_what) !strncmp(str, with_what, sizeof(with_what)-1)
|
||||
#define ADVANCE(amount) read_pos += (amount); distance_to_end -= (amount);
|
||||
while (true)
|
||||
{
|
||||
// we're at the start of a line or at the end of a block comment.
|
||||
// first get any possible whitespace out of the way
|
||||
int whitespace_len = strspn(read_pos, WHITESPACE_CHARS);
|
||||
if (whitespace_len == distance_to_end)
|
||||
break; // we got to the end
|
||||
ADVANCE(whitespace_len)
|
||||
|
||||
if (STARTSWITH(read_pos, "#version"))
|
||||
{
|
||||
// found a version directive (and it's not inside a comment)
|
||||
// now locate, verify and read the version number
|
||||
int version_number_len;
|
||||
version_pos = read_pos - original;
|
||||
ADVANCE(sizeof("#version") - 1)
|
||||
whitespace_len = strspn(read_pos, WHITESPACE_CHARS);
|
||||
if (!whitespace_len)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "HWR_PreprocessShader: Syntax error in #version. Expected space after #version, but got other text.\n");
|
||||
return NULL;
|
||||
}
|
||||
else if (whitespace_len == distance_to_end)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "HWR_PreprocessShader: Syntax error in #version. Expected version number, but got end of file.\n");
|
||||
return NULL;
|
||||
}
|
||||
ADVANCE(whitespace_len)
|
||||
version_number_len = strspn(read_pos, "0123456789");
|
||||
if (!version_number_len)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "HWR_PreprocessShader: Syntax error in #version. Expected version number, but got other text.\n");
|
||||
return NULL;
|
||||
}
|
||||
else if (version_number_len != 3)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "HWR_PreprocessShader: Syntax error in #version. Expected version with 3 digits, but got %d digits.\n", version_number_len);
|
||||
return NULL;
|
||||
}
|
||||
M_Memcpy(shader_glsl_version, read_pos, 3);
|
||||
ADVANCE(version_number_len)
|
||||
version_len = (read_pos - original) - version_pos;
|
||||
whitespace_len = strspn(read_pos, WHITESPACE_CHARS);
|
||||
ADVANCE(whitespace_len)
|
||||
if (STARTSWITH(read_pos, "es"))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "HWR_PreprocessShader: Support for ES shaders is not implemented.\n");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// go to next newline or end of next block comment if it starts before the newline
|
||||
// and is not inside a line comment
|
||||
INT32 newline_pos = strstr_int(read_pos, line_ending);
|
||||
INT32 line_comment_pos;
|
||||
INT32 block_comment_pos;
|
||||
// optimization: temporarily put a null at the line ending, so strstr does not needlessly
|
||||
// look past it since we're only interested in the current line
|
||||
if (newline_pos != INT32_MAX)
|
||||
read_pos[newline_pos] = '\0';
|
||||
line_comment_pos = strstr_int(read_pos, "//");
|
||||
block_comment_pos = strstr_int(read_pos, "/*");
|
||||
// restore the line ending, remove the null we just put there
|
||||
if (newline_pos != INT32_MAX)
|
||||
read_pos[newline_pos] = line_ending[0];
|
||||
if (line_comment_pos < block_comment_pos)
|
||||
{
|
||||
// line comment found, skip rest of the line
|
||||
if (newline_pos != INT32_MAX)
|
||||
{
|
||||
ADVANCE(newline_pos + line_ending_len)
|
||||
}
|
||||
else
|
||||
{
|
||||
// we got to the end
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (block_comment_pos < line_comment_pos)
|
||||
{
|
||||
// block comment found, skip past it
|
||||
INT32 block_comment_end;
|
||||
ADVANCE(block_comment_pos + 2)
|
||||
block_comment_end = strstr_int(read_pos, "*/");
|
||||
if (block_comment_end == INT32_MAX)
|
||||
{
|
||||
// could also leave insertion_pos at 0 and let the GLSL compiler
|
||||
// output an error message for this broken comment
|
||||
CONS_Alert(CONS_ERROR, "HWR_PreprocessShader: Encountered unclosed block comment in shader.\n");
|
||||
return NULL;
|
||||
}
|
||||
ADVANCE(block_comment_end + 2)
|
||||
}
|
||||
else if (newline_pos == INT32_MAX)
|
||||
{
|
||||
// we got to the end
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// nothing special on this line, move to the next one
|
||||
ADVANCE(newline_pos + line_ending_len)
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef STARTSWITH
|
||||
#undef ADVANCE
|
||||
|
||||
#define ADD_TO_LEN(def) new_len += sizeof(def) - 1 + line_ending_len;
|
||||
|
||||
// Calculate length of modified shader.
|
||||
new_len = original_len;
|
||||
if (cv_glmodellighting.value)
|
||||
ADD_TO_LEN(MODEL_LIGHTING_DEFINE)
|
||||
if (cv_glpaletterendering.value)
|
||||
ADD_TO_LEN(PALETTE_RENDERING_DEFINE)
|
||||
|
||||
#undef ADD_TO_LEN
|
||||
|
||||
#define VERSION_PART "#version "
|
||||
|
||||
if (new_len != original_len)
|
||||
{
|
||||
if (version_pos != -1)
|
||||
new_len += sizeof(VERSION_PART) - 1 + 3 + line_ending_len;
|
||||
new_len += sizeof("#line 0") - 1 + line_ending_len;
|
||||
}
|
||||
|
||||
// Allocate memory for modified shader.
|
||||
new_shader = Z_Malloc(new_len + 1, PU_STATIC, NULL);
|
||||
|
||||
read_pos = original;
|
||||
write_pos = new_shader;
|
||||
|
||||
if (new_len != original_len && version_pos != -1)
|
||||
{
|
||||
strcpy(write_pos, VERSION_PART);
|
||||
write_pos += sizeof(VERSION_PART) - 1;
|
||||
M_Memcpy(write_pos, shader_glsl_version, 3);
|
||||
write_pos += 3;
|
||||
strcpy(write_pos, line_ending);
|
||||
write_pos += line_ending_len;
|
||||
}
|
||||
|
||||
#undef VERSION_PART
|
||||
|
||||
#define WRITE_DEFINE(define) \
|
||||
{ \
|
||||
strcpy(write_pos, define); \
|
||||
write_pos += sizeof(define) - 1; \
|
||||
strcpy(write_pos, line_ending); \
|
||||
write_pos += line_ending_len; \
|
||||
}
|
||||
|
||||
// Write the defines.
|
||||
if (cv_glmodellighting.value)
|
||||
WRITE_DEFINE(MODEL_LIGHTING_DEFINE)
|
||||
if (cv_glpaletterendering.value)
|
||||
WRITE_DEFINE(PALETTE_RENDERING_DEFINE)
|
||||
|
||||
#undef WRITE_DEFINE
|
||||
|
||||
// Write a #line directive, so compiler errors will report line numbers from the
|
||||
// original shader without our preamble lines.
|
||||
if (new_len != original_len)
|
||||
{
|
||||
// line numbering in the #line directive is different for versions 110-150
|
||||
if (version_pos == -1 || shader_glsl_version[0] == '1')
|
||||
strcpy(write_pos, "#line 0");
|
||||
else
|
||||
strcpy(write_pos, "#line 1");
|
||||
write_pos += sizeof("#line 0") - 1;
|
||||
strcpy(write_pos, line_ending);
|
||||
write_pos += line_ending_len;
|
||||
}
|
||||
|
||||
// Copy the original shader.
|
||||
M_Memcpy(write_pos, read_pos, original_len);
|
||||
|
||||
// Erase the original #version directive, if it exists and was copied.
|
||||
if (new_len != original_len && version_pos != -1)
|
||||
memset(write_pos + version_pos, ' ', version_len);
|
||||
|
||||
// Terminate the new string.
|
||||
new_shader[new_len] = '\0';
|
||||
|
||||
return new_shader;
|
||||
}
|
||||
|
||||
// preprocess and compile shader at gl_shaders[index]
|
||||
static void HWR_CompileShader(int index)
|
||||
{
|
||||
char *vertex_source = gl_shaders[index].vertex;
|
||||
char *fragment_source = gl_shaders[index].fragment;
|
||||
|
||||
if (vertex_source)
|
||||
{
|
||||
char *preprocessed = HWR_PreprocessShader(vertex_source);
|
||||
if (!preprocessed) return;
|
||||
HWD.pfnLoadShader(index, preprocessed, HWD_SHADERSTAGE_VERTEX);
|
||||
}
|
||||
if (fragment_source)
|
||||
{
|
||||
char *preprocessed = HWR_PreprocessShader(fragment_source);
|
||||
if (!preprocessed) return;
|
||||
HWD.pfnLoadShader(index, preprocessed, HWD_SHADERSTAGE_FRAGMENT);
|
||||
}
|
||||
|
||||
gl_shaders[index].compiled = HWD.pfnCompileShader(index);
|
||||
}
|
||||
|
||||
// compile or recompile shaders
|
||||
void HWR_CompileShaders(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUMSHADERTARGETS; i++)
|
||||
{
|
||||
int custom_index = gl_shadertargets[i].custom_shader;
|
||||
HWR_CompileShader(i);
|
||||
if (!gl_shaders[i].compiled)
|
||||
CONS_Alert(CONS_ERROR, "HWR_CompileShaders: Compilation failed for base %s shader!\n", shaderxlat[i].type);
|
||||
if (custom_index != -1)
|
||||
{
|
||||
HWR_CompileShader(custom_index);
|
||||
if (!gl_shaders[custom_index].compiled)
|
||||
CONS_Alert(CONS_ERROR, "HWR_CompileShaders: Recompilation failed for the custom %s shader! See the console messages above for more information.\n", shaderxlat[i].type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int HWR_GetShaderFromTarget(int shader_target)
|
||||
{
|
||||
int custom_shader = gl_shadertargets[shader_target].custom_shader;
|
||||
// use custom shader if following are true
|
||||
// - custom shader exists
|
||||
// - custom shader has been compiled successfully
|
||||
// - custom shaders are enabled
|
||||
// - custom shaders are allowed by the server
|
||||
if (custom_shader != -1 && gl_shaders[custom_shader].compiled &&
|
||||
cv_glshaders.value == 1 && cv_glallowshaders.value)
|
||||
return custom_shader;
|
||||
else
|
||||
return gl_shadertargets[shader_target].base_shader;
|
||||
}
|
||||
|
||||
static inline UINT16 HWR_FindShaderDefs(UINT16 wadnum)
|
||||
{
|
||||
UINT16 i;
|
||||
lumpinfo_t *lump_p;
|
||||
|
||||
lump_p = wadfiles[wadnum]->lumpinfo;
|
||||
for (i = 0; i < wadfiles[wadnum]->numlumps; i++, lump_p++)
|
||||
if (memcmp(lump_p->name, "SHADERS", 7) == 0)
|
||||
return i;
|
||||
|
||||
return INT16_MAX;
|
||||
}
|
||||
|
||||
customshaderxlat_t shaderxlat[] =
|
||||
{
|
||||
{"Flat", SHADER_FLOOR},
|
||||
{"WallTexture", SHADER_WALL},
|
||||
{"Sprite", SHADER_SPRITE},
|
||||
{"Model", SHADER_MODEL},
|
||||
{"WaterRipple", SHADER_WATER},
|
||||
{"Fog", SHADER_FOG},
|
||||
{"Sky", SHADER_SKY},
|
||||
{"PalettePostprocess", SHADER_PALETTE_POSTPROCESS},
|
||||
{"UIColormapFade", SHADER_UI_COLORMAP_FADE},
|
||||
{"UITintedWipe", SHADER_UI_TINTED_WIPE},
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
void HWR_LoadAllCustomShaders(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
// read every custom shader
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
HWR_LoadCustomShadersFromFile(i, W_FileHasFolders(wadfiles[i]));
|
||||
}
|
||||
|
||||
void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3)
|
||||
{
|
||||
UINT16 lump;
|
||||
char *shaderdef, *line;
|
||||
char *stoken;
|
||||
char *value;
|
||||
size_t size;
|
||||
int linenum = 1;
|
||||
int shadertype = 0;
|
||||
int i;
|
||||
boolean modified_shaders[NUMSHADERTARGETS] = {0};
|
||||
|
||||
if (!gl_shadersavailable)
|
||||
return;
|
||||
|
||||
lump = HWR_FindShaderDefs(wadnum);
|
||||
if (lump == INT16_MAX)
|
||||
return;
|
||||
|
||||
shaderdef = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE);
|
||||
size = W_LumpLengthPwad(wadnum, lump);
|
||||
|
||||
line = Z_Malloc(size+1, PU_STATIC, NULL);
|
||||
M_Memcpy(line, shaderdef, size);
|
||||
line[size] = '\0';
|
||||
|
||||
stoken = strtok(line, "\r\n ");
|
||||
while (stoken)
|
||||
{
|
||||
if ((stoken[0] == '/' && stoken[1] == '/')
|
||||
|| (stoken[0] == '#'))// skip comments
|
||||
{
|
||||
stoken = strtok(NULL, "\r\n");
|
||||
goto skip_field;
|
||||
}
|
||||
|
||||
if (!stricmp(stoken, "GLSL"))
|
||||
{
|
||||
value = strtok(NULL, "\r\n ");
|
||||
if (!value)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: Missing shader type (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
|
||||
stoken = strtok(NULL, "\r\n"); // skip end of line
|
||||
goto skip_lump;
|
||||
}
|
||||
|
||||
if (!stricmp(value, "VERTEX"))
|
||||
shadertype = 1;
|
||||
else if (!stricmp(value, "FRAGMENT"))
|
||||
shadertype = 2;
|
||||
|
||||
skip_lump:
|
||||
stoken = strtok(NULL, "\r\n ");
|
||||
linenum++;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = strtok(NULL, "\r\n= ");
|
||||
if (!value)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: Missing shader target (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
|
||||
stoken = strtok(NULL, "\r\n"); // skip end of line
|
||||
goto skip_field;
|
||||
}
|
||||
|
||||
if (!shadertype)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "HWR_LoadCustomShadersFromFile: Missing shader type (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
|
||||
Z_Free(line);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; shaderxlat[i].type; i++)
|
||||
{
|
||||
if (!stricmp(shaderxlat[i].type, stoken))
|
||||
{
|
||||
size_t shader_string_length;
|
||||
char *shader_source;
|
||||
char *shader_lumpname;
|
||||
UINT16 shader_lumpnum;
|
||||
int shader_index; // index in gl_shaders
|
||||
|
||||
if (PK3)
|
||||
{
|
||||
shader_lumpname = Z_Malloc(strlen(value) + 12, PU_STATIC, NULL);
|
||||
strcpy(shader_lumpname, "Shaders/sh_");
|
||||
strcat(shader_lumpname, value);
|
||||
shader_lumpnum = W_CheckNumForFullNamePK3(shader_lumpname, wadnum, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
shader_lumpname = Z_Malloc(strlen(value) + 4, PU_STATIC, NULL);
|
||||
strcpy(shader_lumpname, "SH_");
|
||||
strcat(shader_lumpname, value);
|
||||
shader_lumpnum = W_CheckNumForNamePwad(shader_lumpname, wadnum, 0);
|
||||
}
|
||||
|
||||
if (shader_lumpnum == INT16_MAX)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "HWR_LoadCustomShadersFromFile: Missing shader source %s (file %s, line %d)\n", shader_lumpname, wadfiles[wadnum]->filename, linenum);
|
||||
Z_Free(shader_lumpname);
|
||||
continue;
|
||||
}
|
||||
|
||||
shader_string_length = W_LumpLengthPwad(wadnum, shader_lumpnum) + 1;
|
||||
shader_source = Z_Malloc(shader_string_length, PU_STATIC, NULL);
|
||||
W_ReadLumpPwad(wadnum, shader_lumpnum, shader_source);
|
||||
shader_source[shader_string_length-1] = '\0';
|
||||
|
||||
shader_index = shaderxlat[i].id + NUMSHADERTARGETS;
|
||||
if (!modified_shaders[shaderxlat[i].id])
|
||||
{
|
||||
// this will clear any old custom shaders from previously loaded files
|
||||
// Z_Free checks if the pointer is NULL!
|
||||
Z_Free(gl_shaders[shader_index].vertex);
|
||||
gl_shaders[shader_index].vertex = NULL;
|
||||
Z_Free(gl_shaders[shader_index].fragment);
|
||||
gl_shaders[shader_index].fragment = NULL;
|
||||
}
|
||||
modified_shaders[shaderxlat[i].id] = true;
|
||||
|
||||
if (shadertype == 1)
|
||||
{
|
||||
if (gl_shaders[shader_index].vertex)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: %s is overwriting another %s vertex shader from the same addon! (file %s, line %d)\n", shader_lumpname, shaderxlat[i].type, wadfiles[wadnum]->filename, linenum);
|
||||
Z_Free(gl_shaders[shader_index].vertex);
|
||||
}
|
||||
gl_shaders[shader_index].vertex = shader_source;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gl_shaders[shader_index].fragment)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: %s is overwriting another %s fragment shader from the same addon! (file %s, line %d)\n", shader_lumpname, shaderxlat[i].type, wadfiles[wadnum]->filename, linenum);
|
||||
Z_Free(gl_shaders[shader_index].fragment);
|
||||
}
|
||||
gl_shaders[shader_index].fragment = shader_source;
|
||||
}
|
||||
|
||||
Z_Free(shader_lumpname);
|
||||
}
|
||||
}
|
||||
|
||||
skip_field:
|
||||
stoken = strtok(NULL, "\r\n= ");
|
||||
linenum++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < NUMSHADERTARGETS; i++)
|
||||
{
|
||||
if (modified_shaders[i])
|
||||
{
|
||||
int shader_index = i + NUMSHADERTARGETS; // index to gl_shaders
|
||||
gl_shadertargets[i].custom_shader = shader_index;
|
||||
// if only one stage (vertex/fragment) is defined, the other one
|
||||
// is copied from the base shaders.
|
||||
if (!gl_shaders[shader_index].fragment)
|
||||
gl_shaders[shader_index].fragment = Z_StrDup(gl_shadersources[i].fragment);
|
||||
if (!gl_shaders[shader_index].vertex)
|
||||
gl_shaders[shader_index].vertex = Z_StrDup(gl_shadersources[i].vertex);
|
||||
HWR_CompileShader(shader_index);
|
||||
if (!gl_shaders[shader_index].compiled)
|
||||
CONS_Alert(CONS_ERROR, "HWR_LoadCustomShadersFromFile: A compilation error occured for the %s shader in file %s. See the console messages above for more information.\n", shaderxlat[i].type, wadfiles[wadnum]->filename);
|
||||
}
|
||||
}
|
||||
|
||||
Z_Free(line);
|
||||
return;
|
||||
}
|
||||
|
||||
const char *HWR_GetShaderName(INT32 shader)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; shaderxlat[i].type; i++)
|
||||
{
|
||||
if (shaderxlat[i].id == shader)
|
||||
return shaderxlat[i].type;
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
#endif // HWRENDER
|
424
src/hardware/hw_shaders.h
Normal file
424
src/hardware/hw_shaders.h
Normal file
|
@ -0,0 +1,424 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2021 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file hw_shaders.h
|
||||
/// \brief Handles the shaders used by the game.
|
||||
|
||||
#ifndef _HW_SHADERS_H_
|
||||
#define _HW_SHADERS_H_
|
||||
|
||||
#include "../doomtype.h"
|
||||
|
||||
// ================
|
||||
// Vertex shaders
|
||||
// ================
|
||||
|
||||
//
|
||||
// Generic vertex shader
|
||||
//
|
||||
|
||||
#define GLSL_DEFAULT_VERTEX_SHADER \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
"gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"gl_FrontColor = gl_Color;\n" \
|
||||
"gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \
|
||||
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"}\0"
|
||||
|
||||
// replicates the way fixed function lighting is used by the model lighting option,
|
||||
// stores the lighting result to gl_Color
|
||||
// (ambient lighting of 0.75 and diffuse lighting from above)
|
||||
#define GLSL_MODEL_VERTEX_SHADER \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
"#ifdef SRB2_MODEL_LIGHTING\n" \
|
||||
"float nDotVP = dot(gl_Normal, vec3(0, 1, 0));\n" \
|
||||
"float light = min(0.75 + max(nDotVP, 0.0), 1.0);\n" \
|
||||
"gl_FrontColor = vec4(light, light, light, 1.0);\n" \
|
||||
"#else\n" \
|
||||
"gl_FrontColor = gl_Color;\n" \
|
||||
"#endif\n" \
|
||||
"gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \
|
||||
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"}\0"
|
||||
|
||||
// ==================
|
||||
// Fragment shaders
|
||||
// ==================
|
||||
|
||||
//
|
||||
// Generic fragment shader
|
||||
//
|
||||
|
||||
#define GLSL_DEFAULT_FRAGMENT_SHADER \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"void main(void) {\n" \
|
||||
"gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * poly_color;\n" \
|
||||
"}\0"
|
||||
|
||||
//
|
||||
// Software fragment shader
|
||||
//
|
||||
|
||||
// Include GLSL_FLOOR_FUDGES or GLSL_WALL_FUDGES or define the fudges in shaders that use this macro.
|
||||
#define GLSL_DOOM_COLORMAP \
|
||||
"float R_DoomColormap(float light, float z)\n" \
|
||||
"{\n" \
|
||||
"float lightnum = clamp(light / 17.0, 0.0, 15.0);\n" \
|
||||
"float lightz = clamp(z / 16.0, 0.0, 127.0);\n" \
|
||||
"float startmap = (15.0 - lightnum) * 4.0;\n" \
|
||||
"float scale = 160.0 / (lightz + 1.0);\n" \
|
||||
"float cap = (155.0 - light) * 0.26;\n" \
|
||||
"return max(startmap * STARTMAP_FUDGE - scale * 0.5 * SCALE_FUDGE, cap);\n" \
|
||||
"}\n"
|
||||
// lighting cap adjustment:
|
||||
// first num (155.0), increase to make it start to go dark sooner
|
||||
// second num (0.26), increase to make it go dark faster
|
||||
|
||||
#define GLSL_DOOM_LIGHT_EQUATION \
|
||||
"float R_DoomLightingEquation(float light)\n" \
|
||||
"{\n" \
|
||||
"float z = gl_FragCoord.z / gl_FragCoord.w;\n" \
|
||||
"float colormap = floor(R_DoomColormap(light, z)) + 0.5;\n" \
|
||||
"return clamp(colormap, 0.0, 31.0) / 32.0;\n" \
|
||||
"}\n"
|
||||
|
||||
#define GLSL_SOFTWARE_TINT_EQUATION \
|
||||
"if (tint_color.a > 0.0) {\n" \
|
||||
"float color_bright = sqrt((base_color.r * base_color.r) + (base_color.g * base_color.g) + (base_color.b * base_color.b));\n" \
|
||||
"float strength = sqrt(tint_color.a);\n" \
|
||||
"final_color.r = clamp((color_bright * (tint_color.r * strength)) + (base_color.r * (1.0 - strength)), 0.0, 1.0);\n" \
|
||||
"final_color.g = clamp((color_bright * (tint_color.g * strength)) + (base_color.g * (1.0 - strength)), 0.0, 1.0);\n" \
|
||||
"final_color.b = clamp((color_bright * (tint_color.b * strength)) + (base_color.b * (1.0 - strength)), 0.0, 1.0);\n" \
|
||||
"}\n"
|
||||
|
||||
#define GLSL_SOFTWARE_FADE_EQUATION \
|
||||
"float darkness = R_DoomLightingEquation(lighting);\n" \
|
||||
"if (fade_start != 0.0 || fade_end != 31.0) {\n" \
|
||||
"float fs = fade_start / 31.0;\n" \
|
||||
"float fe = fade_end / 31.0;\n" \
|
||||
"float fd = fe - fs;\n" \
|
||||
"darkness = clamp((darkness - fs) * (1.0 / fd), 0.0, 1.0);\n" \
|
||||
"}\n" \
|
||||
"final_color = mix(final_color, fade_color, darkness);\n"
|
||||
|
||||
#define GLSL_PALETTE_RENDERING \
|
||||
"float tex_pal_idx = texture3D(palette_lookup_tex, vec3((texel * 63.0 + 0.5) / 64.0))[0] * 255.0;\n" \
|
||||
"float z = gl_FragCoord.z / gl_FragCoord.w;\n" \
|
||||
"float light_y = clamp(floor(R_DoomColormap(lighting, z)), 0.0, 31.0);\n" \
|
||||
"vec2 lighttable_coord = vec2((tex_pal_idx + 0.5) / 256.0, (light_y + 0.5) / 32.0);\n" \
|
||||
"vec4 final_color = texture2D(lighttable_tex, lighttable_coord);\n" \
|
||||
"final_color.a = texel.a * poly_color.a;\n" \
|
||||
"gl_FragColor = final_color;\n" \
|
||||
|
||||
#define GLSL_SOFTWARE_FRAGMENT_SHADER \
|
||||
"#ifdef SRB2_PALETTE_RENDERING\n" \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform sampler3D palette_lookup_tex;\n" \
|
||||
"uniform sampler2D lighttable_tex;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"uniform float lighting;\n" \
|
||||
GLSL_DOOM_COLORMAP \
|
||||
"void main(void) {\n" \
|
||||
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
|
||||
GLSL_PALETTE_RENDERING \
|
||||
"}\n" \
|
||||
"#else\n" \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"uniform vec4 tint_color;\n" \
|
||||
"uniform vec4 fade_color;\n" \
|
||||
"uniform float lighting;\n" \
|
||||
"uniform float fade_start;\n" \
|
||||
"uniform float fade_end;\n" \
|
||||
GLSL_DOOM_COLORMAP \
|
||||
GLSL_DOOM_LIGHT_EQUATION \
|
||||
"void main(void) {\n" \
|
||||
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
|
||||
"vec4 base_color = texel * poly_color;\n" \
|
||||
"vec4 final_color = base_color;\n" \
|
||||
GLSL_SOFTWARE_TINT_EQUATION \
|
||||
GLSL_SOFTWARE_FADE_EQUATION \
|
||||
"final_color.a = texel.a * poly_color.a;\n" \
|
||||
"gl_FragColor = final_color;\n" \
|
||||
"}\n" \
|
||||
"#endif\0"
|
||||
|
||||
// hand tuned adjustments for light level calculation
|
||||
#define GLSL_FLOOR_FUDGES \
|
||||
"#define STARTMAP_FUDGE 1.06\n" \
|
||||
"#define SCALE_FUDGE 1.15\n"
|
||||
|
||||
#define GLSL_WALL_FUDGES \
|
||||
"#define STARTMAP_FUDGE 1.05\n" \
|
||||
"#define SCALE_FUDGE 2.2\n"
|
||||
|
||||
#define GLSL_FLOOR_FRAGMENT_SHADER \
|
||||
GLSL_FLOOR_FUDGES \
|
||||
GLSL_SOFTWARE_FRAGMENT_SHADER
|
||||
|
||||
#define GLSL_WALL_FRAGMENT_SHADER \
|
||||
GLSL_WALL_FUDGES \
|
||||
GLSL_SOFTWARE_FRAGMENT_SHADER
|
||||
|
||||
// same as above but multiplies results with the lighting value from the
|
||||
// accompanying vertex shader (stored in gl_Color) if model lighting is enabled
|
||||
#define GLSL_MODEL_FRAGMENT_SHADER \
|
||||
GLSL_WALL_FUDGES \
|
||||
"#ifdef SRB2_PALETTE_RENDERING\n" \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform sampler3D palette_lookup_tex;\n" \
|
||||
"uniform sampler2D lighttable_tex;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"uniform float lighting;\n" \
|
||||
GLSL_DOOM_COLORMAP \
|
||||
"void main(void) {\n" \
|
||||
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
|
||||
"#ifdef SRB2_MODEL_LIGHTING\n" \
|
||||
"texel *= gl_Color;\n" \
|
||||
"#endif\n" \
|
||||
GLSL_PALETTE_RENDERING \
|
||||
"}\n" \
|
||||
"#else\n" \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"uniform vec4 tint_color;\n" \
|
||||
"uniform vec4 fade_color;\n" \
|
||||
"uniform float lighting;\n" \
|
||||
"uniform float fade_start;\n" \
|
||||
"uniform float fade_end;\n" \
|
||||
GLSL_DOOM_COLORMAP \
|
||||
GLSL_DOOM_LIGHT_EQUATION \
|
||||
"void main(void) {\n" \
|
||||
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
|
||||
"vec4 base_color = texel * poly_color;\n" \
|
||||
"vec4 final_color = base_color;\n" \
|
||||
GLSL_SOFTWARE_TINT_EQUATION \
|
||||
GLSL_SOFTWARE_FADE_EQUATION \
|
||||
"#ifdef SRB2_MODEL_LIGHTING\n" \
|
||||
"final_color *= gl_Color;\n" \
|
||||
"#endif\n" \
|
||||
"final_color.a = texel.a * poly_color.a;\n" \
|
||||
"gl_FragColor = final_color;\n" \
|
||||
"}\n" \
|
||||
"#endif\0"
|
||||
|
||||
//
|
||||
// Water surface shader
|
||||
//
|
||||
// Mostly guesstimated, rather than the rest being built off Software science.
|
||||
// Still needs to distort things underneath/around the water...
|
||||
//
|
||||
|
||||
#define GLSL_WATER_TEXEL \
|
||||
"float water_z = (gl_FragCoord.z / gl_FragCoord.w) / 2.0;\n" \
|
||||
"float a = -pi * (water_z * freq) + (leveltime * speed);\n" \
|
||||
"float sdistort = sin(a) * amp;\n" \
|
||||
"float cdistort = cos(a) * amp;\n" \
|
||||
"vec4 texel = texture2D(tex, vec2(gl_TexCoord[0].s - sdistort, gl_TexCoord[0].t - cdistort));\n"
|
||||
|
||||
#define GLSL_WATER_FRAGMENT_SHADER \
|
||||
GLSL_FLOOR_FUDGES \
|
||||
"const float freq = 0.025;\n" \
|
||||
"const float amp = 0.025;\n" \
|
||||
"const float speed = 2.0;\n" \
|
||||
"const float pi = 3.14159;\n" \
|
||||
"#ifdef SRB2_PALETTE_RENDERING\n" \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform sampler3D palette_lookup_tex;\n" \
|
||||
"uniform sampler2D lighttable_tex;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"uniform float lighting;\n" \
|
||||
"uniform float leveltime;\n" \
|
||||
GLSL_DOOM_COLORMAP \
|
||||
"void main(void) {\n" \
|
||||
GLSL_WATER_TEXEL \
|
||||
GLSL_PALETTE_RENDERING \
|
||||
"}\n" \
|
||||
"#else\n" \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"uniform vec4 tint_color;\n" \
|
||||
"uniform vec4 fade_color;\n" \
|
||||
"uniform float lighting;\n" \
|
||||
"uniform float fade_start;\n" \
|
||||
"uniform float fade_end;\n" \
|
||||
"uniform float leveltime;\n" \
|
||||
GLSL_DOOM_COLORMAP \
|
||||
GLSL_DOOM_LIGHT_EQUATION \
|
||||
"void main(void) {\n" \
|
||||
GLSL_WATER_TEXEL \
|
||||
"vec4 base_color = texel * poly_color;\n" \
|
||||
"vec4 final_color = base_color;\n" \
|
||||
GLSL_SOFTWARE_TINT_EQUATION \
|
||||
GLSL_SOFTWARE_FADE_EQUATION \
|
||||
"final_color.a = texel.a * poly_color.a;\n" \
|
||||
"gl_FragColor = final_color;\n" \
|
||||
"}\n" \
|
||||
"#endif\0"
|
||||
|
||||
//
|
||||
// Fog block shader
|
||||
//
|
||||
// Alpha of the planes themselves are still slightly off -- see HWR_FogBlockAlpha
|
||||
//
|
||||
|
||||
// The floor fudges are used, but should the wall fudges be used instead? or something inbetween?
|
||||
// or separate values for floors and walls? (need to change more than this shader for that)
|
||||
#define GLSL_FOG_FRAGMENT_SHADER \
|
||||
GLSL_FLOOR_FUDGES \
|
||||
"uniform vec4 tint_color;\n" \
|
||||
"uniform vec4 fade_color;\n" \
|
||||
"uniform float lighting;\n" \
|
||||
"uniform float fade_start;\n" \
|
||||
"uniform float fade_end;\n" \
|
||||
GLSL_DOOM_COLORMAP \
|
||||
GLSL_DOOM_LIGHT_EQUATION \
|
||||
"void main(void) {\n" \
|
||||
"vec4 base_color = gl_Color;\n" \
|
||||
"vec4 final_color = base_color;\n" \
|
||||
GLSL_SOFTWARE_TINT_EQUATION \
|
||||
GLSL_SOFTWARE_FADE_EQUATION \
|
||||
"gl_FragColor = final_color;\n" \
|
||||
"}\0"
|
||||
|
||||
//
|
||||
// Sky fragment shader
|
||||
// Modulates poly_color with gl_Color
|
||||
//
|
||||
#define GLSL_SKY_FRAGMENT_SHADER \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"void main(void) {\n" \
|
||||
"gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * gl_Color * poly_color;\n" \
|
||||
"}\0"
|
||||
|
||||
// Shader for the palette rendering postprocess step
|
||||
#define GLSL_PALETTE_POSTPROCESS_FRAGMENT_SHADER \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform sampler3D palette_lookup_tex;\n" \
|
||||
"uniform sampler1D palette_tex;\n" \
|
||||
"void main(void) {\n" \
|
||||
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
|
||||
"float tex_pal_idx = texture3D(palette_lookup_tex, vec3((texel * 63.0 + 0.5) / 64.0))[0] * 255.0;\n" \
|
||||
"float palette_coord = (tex_pal_idx + 0.5) / 256.0;\n" \
|
||||
"vec4 final_color = texture1D(palette_tex, palette_coord);\n" \
|
||||
"gl_FragColor = final_color;\n" \
|
||||
"}\0"
|
||||
|
||||
// Applies a palettized colormap fade to tex
|
||||
#define GLSL_UI_COLORMAP_FADE_FRAGMENT_SHADER \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform float lighting;\n" \
|
||||
"uniform sampler3D palette_lookup_tex;\n" \
|
||||
"uniform sampler2D lighttable_tex;\n" \
|
||||
"void main(void) {\n" \
|
||||
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
|
||||
"float tex_pal_idx = texture3D(palette_lookup_tex, vec3((texel * 63.0 + 0.5) / 64.0))[0] * 255.0;\n" \
|
||||
"vec2 lighttable_coord = vec2((tex_pal_idx + 0.5) / 256.0, (lighting + 0.5) / 32.0);\n" \
|
||||
"gl_FragColor = texture2D(lighttable_tex, lighttable_coord);\n" \
|
||||
"}\0"
|
||||
|
||||
// For wipes that use additive and subtractive blending.
|
||||
// alpha_factor = 31 * 8 / 10 = 24.8
|
||||
// Calculated based on the use of the "fade" variable from the GETCOLOR macro
|
||||
// in r_data.c:R_CreateFadeColormaps.
|
||||
// However this value created some ugliness in fades to white (special stage entry)
|
||||
// while palette rendering is enabled, so I raised the value just a bit.
|
||||
#define GLSL_UI_TINTED_WIPE_FRAGMENT_SHADER \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"const float alpha_factor = 24.875;\n" \
|
||||
"void main(void) {\n" \
|
||||
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
|
||||
"vec4 final_color = poly_color;\n" \
|
||||
"float alpha = texel.a;\n" \
|
||||
"if (final_color.a >= 0.5)\n" \
|
||||
"alpha = 1.0 - alpha;\n" \
|
||||
"alpha *= alpha_factor;\n" \
|
||||
"final_color *= alpha;\n" \
|
||||
"final_color.a = 1.0;\n" \
|
||||
"gl_FragColor = final_color;\n" \
|
||||
"}\0"
|
||||
|
||||
//
|
||||
// Generic vertex shader
|
||||
//
|
||||
|
||||
#define GLSL_FALLBACK_VERTEX_SHADER \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
"gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"gl_FrontColor = gl_Color;\n" \
|
||||
"gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \
|
||||
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"}\0"
|
||||
|
||||
//
|
||||
// Generic fragment shader
|
||||
//
|
||||
|
||||
#define GLSL_FALLBACK_FRAGMENT_SHADER \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"void main(void) {\n" \
|
||||
"gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * poly_color;\n" \
|
||||
"}\0"
|
||||
|
||||
//
|
||||
// Software fragment shader
|
||||
//
|
||||
|
||||
#define GLSL_SOFTWARE_FADE_EQUATION \
|
||||
"float darkness = R_DoomLightingEquation(lighting);\n" \
|
||||
"if (fade_start != 0.0 || fade_end != 31.0) {\n" \
|
||||
"float fs = fade_start / 31.0;\n" \
|
||||
"float fe = fade_end / 31.0;\n" \
|
||||
"float fd = fe - fs;\n" \
|
||||
"darkness = clamp((darkness - fs) * (1.0 / fd), 0.0, 1.0);\n" \
|
||||
"}\n" \
|
||||
"final_color = mix(final_color, fade_color, darkness);\n"
|
||||
|
||||
// same as above but multiplies results with the lighting value from the
|
||||
// accompanying vertex shader (stored in gl_Color)
|
||||
#define GLSL_SOFTWARE_MODEL_LIGHTING_FRAGMENT_SHADER \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"uniform vec4 tint_color;\n" \
|
||||
"uniform vec4 fade_color;\n" \
|
||||
"uniform float lighting;\n" \
|
||||
"uniform float fade_start;\n" \
|
||||
"uniform float fade_end;\n" \
|
||||
GLSL_DOOM_COLORMAP \
|
||||
GLSL_DOOM_LIGHT_EQUATION \
|
||||
"void main(void) {\n" \
|
||||
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
|
||||
"vec4 base_color = texel * poly_color;\n" \
|
||||
"vec4 final_color = base_color;\n" \
|
||||
GLSL_SOFTWARE_TINT_EQUATION \
|
||||
GLSL_SOFTWARE_FADE_EQUATION \
|
||||
"final_color *= gl_Color;\n" \
|
||||
"final_color.a = texel.a * poly_color.a;\n" \
|
||||
"gl_FragColor = final_color;\n" \
|
||||
"}\0"
|
||||
|
||||
//
|
||||
// Sky fragment shader
|
||||
// Modulates poly_color with gl_Color
|
||||
//
|
||||
#define GLSL_SKY_FRAGMENT_SHADER \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"void main(void) {\n" \
|
||||
"gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * gl_Color * poly_color;\n" \
|
||||
"}\0"
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -46,6 +46,7 @@
|
|||
#define _CREATE_DLL_ // necessary for Unix AND Windows
|
||||
#include "../../doomdef.h"
|
||||
#include "../hw_drv.h"
|
||||
#include "../../z_zone.h"
|
||||
|
||||
// ==========================================================================
|
||||
// DEFINITIONS
|
||||
|
|
|
@ -620,7 +620,7 @@ static void Command_CSay_f(void)
|
|||
DoSayCommand(0, 1, HU_CSAY);
|
||||
}
|
||||
|
||||
static tic_t spam_tokens[MAXPLAYERS];
|
||||
static tic_t spam_tokens[MAXPLAYERS] = { 1 }; // fill the buffer with 1 so the motd can be sent.
|
||||
static tic_t spam_tics[MAXPLAYERS];
|
||||
|
||||
/** Receives a message, processing an ::XD_SAY command.
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "i_system.h" // I_GetPreciseTime
|
||||
#include "m_misc.h"
|
||||
#include "st_stuff.h" // st_palette
|
||||
#include "doomstat.h" // singletics
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
|
@ -604,7 +605,7 @@ static void GIF_framewrite(void)
|
|||
UINT16 delay = 0;
|
||||
INT32 startline;
|
||||
|
||||
if (gif_dynamicdelay ==(UINT8) 2)
|
||||
if (gif_dynamicdelay ==(UINT8) 2 && !singletics)
|
||||
{
|
||||
// golden's attempt at creating a "dynamic delay"
|
||||
UINT16 mingifdelay = 10; // minimum gif delay in milliseconds (keep at 10 because gifs can't get more precise).
|
||||
|
@ -617,7 +618,7 @@ static void GIF_framewrite(void)
|
|||
gif_delayus -= frames*(mingifdelay*1000); // remove frames by the amount of milliseconds they take. don't reset to 0, the microseconds help consistency.
|
||||
}
|
||||
}
|
||||
else if (gif_dynamicdelay ==(UINT8) 1)
|
||||
else if (gif_dynamicdelay ==(UINT8) 1 && !singletics)
|
||||
{
|
||||
float delayf = ceil(100.0f/NEWTICRATE);
|
||||
|
||||
|
|
|
@ -1098,15 +1098,23 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c
|
|||
fixed_t fheight = P_GetSectorFloorZAt(sec, mt->x << FRACBITS, mt->y << FRACBITS);
|
||||
mt->z = (UINT16)((player->mo->z - fheight)>>FRACBITS);
|
||||
}
|
||||
|
||||
mt->angle = (INT16)(FixedInt(AngleFixed(player->mo->angle)));
|
||||
|
||||
mt->options = (mt->z << ZSHIFT) | (UINT16)cv_opflags.value;
|
||||
mt->options = (UINT16)cv_opflags.value;
|
||||
mt->scale = player->mo->scale;
|
||||
mt->spritexscale = player->mo->spritexscale;
|
||||
mt->spriteyscale = player->mo->spriteyscale;
|
||||
memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args));
|
||||
memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs));
|
||||
mt->pitch = mt->roll = 0;
|
||||
|
||||
// Ignore offsets
|
||||
if (mt->type == MT_EMBLEM)
|
||||
mt->args[1] = 1;
|
||||
else
|
||||
mt->args[0] = 1;
|
||||
|
||||
return mt;
|
||||
}
|
||||
|
||||
|
|
17
src/m_menu.c
17
src/m_menu.c
|
@ -1406,18 +1406,19 @@ static menuitem_t OP_OpenGLOptionsMenu[] =
|
|||
|
||||
{IT_HEADER, NULL, "General", NULL, 51},
|
||||
{IT_STRING|IT_CVAR, NULL, "Shaders", &cv_glshaders, 63},
|
||||
{IT_STRING|IT_CVAR, NULL, "Lack of perspective", &cv_glshearing, 73},
|
||||
{IT_STRING|IT_CVAR, NULL, "Field of view", &cv_fov, 83},
|
||||
{IT_STRING|IT_CVAR, NULL, "Palette rendering", &cv_glpaletterendering, 73},
|
||||
{IT_STRING|IT_CVAR, NULL, "Lack of perspective", &cv_glshearing, 83},
|
||||
{IT_STRING|IT_CVAR, NULL, "Field of view", &cv_fov, 93},
|
||||
|
||||
{IT_HEADER, NULL, "Miscellaneous", NULL, 102},
|
||||
{IT_STRING|IT_CVAR, NULL, "Bit depth", &cv_scr_depth, 114},
|
||||
{IT_STRING|IT_CVAR, NULL, "Texture filter", &cv_glfiltermode, 124},
|
||||
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_glanisotropicmode, 134},
|
||||
{IT_HEADER, NULL, "Miscellaneous", NULL, 112},
|
||||
{IT_STRING|IT_CVAR, NULL, "Bit depth", &cv_scr_depth, 124},
|
||||
{IT_STRING|IT_CVAR, NULL, "Texture filter", &cv_glfiltermode, 134},
|
||||
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_glanisotropicmode, 144},
|
||||
#ifdef ALAM_LIGHTING
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 144},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 154},
|
||||
#endif
|
||||
#if defined (_WINDOWS) && (!(defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL)))
|
||||
{IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 154},
|
||||
{IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 164},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -1254,7 +1254,7 @@ void M_SaveFrame(void)
|
|||
// paranoia: should be unnecessary without singletics
|
||||
static tic_t oldtic = 0;
|
||||
|
||||
if (oldtic == I_GetTime())
|
||||
if (oldtic == I_GetTime() && !singletics)
|
||||
return;
|
||||
else
|
||||
oldtic = I_GetTime();
|
||||
|
@ -1978,9 +1978,9 @@ void M_UnGetToken(void)
|
|||
|
||||
static tokenizer_t *globalTokenizer = NULL;
|
||||
|
||||
void M_TokenizerOpen(const char *inputString)
|
||||
void M_TokenizerOpen(const char *inputString, size_t len)
|
||||
{
|
||||
globalTokenizer = Tokenizer_Open(inputString, 2);
|
||||
globalTokenizer = Tokenizer_Open(inputString, len, 2);
|
||||
}
|
||||
|
||||
void M_TokenizerClose(void)
|
||||
|
|
|
@ -12,11 +12,18 @@
|
|||
#include "m_tokenizer.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
tokenizer_t *Tokenizer_Open(const char *inputString, unsigned numTokens)
|
||||
tokenizer_t *Tokenizer_Open(const char *inputString, size_t len, unsigned numTokens)
|
||||
{
|
||||
tokenizer_t *tokenizer = Z_Malloc(sizeof(tokenizer_t), PU_STATIC, NULL);
|
||||
const size_t lenpan = 2;
|
||||
|
||||
tokenizer->input = inputString;
|
||||
tokenizer->zdup = malloc(len+lenpan);
|
||||
for (size_t i = 0; i < lenpan; i++)
|
||||
{
|
||||
tokenizer->zdup[len+i] = 0x00;
|
||||
}
|
||||
|
||||
tokenizer->input = M_Memcpy(tokenizer->zdup, inputString, len);
|
||||
tokenizer->startPos = 0;
|
||||
tokenizer->endPos = 0;
|
||||
tokenizer->inputLength = 0;
|
||||
|
@ -51,6 +58,7 @@ void Tokenizer_Close(tokenizer_t *tokenizer)
|
|||
Z_Free(tokenizer->token[i]);
|
||||
Z_Free(tokenizer->capacity);
|
||||
Z_Free(tokenizer->token);
|
||||
free(tokenizer->zdup);
|
||||
Z_Free(tokenizer);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
typedef struct Tokenizer
|
||||
{
|
||||
char *zdup;
|
||||
const char *input;
|
||||
unsigned numTokens;
|
||||
UINT32 *capacity;
|
||||
|
@ -29,7 +30,7 @@ typedef struct Tokenizer
|
|||
const char *(*get)(struct Tokenizer*, UINT32);
|
||||
} tokenizer_t;
|
||||
|
||||
tokenizer_t *Tokenizer_Open(const char *inputString, unsigned numTokens);
|
||||
tokenizer_t *Tokenizer_Open(const char *inputString, size_t len, unsigned numTokens);
|
||||
void Tokenizer_Close(tokenizer_t *tokenizer);
|
||||
|
||||
const char *Tokenizer_Read(tokenizer_t *tokenizer, UINT32 i);
|
||||
|
|
|
@ -394,7 +394,7 @@ consvar_t cv_ps_descriptor = CVAR_INIT ("ps_descriptor", "Average", 0, ps_descri
|
|||
consvar_t cv_freedemocamera = CVAR_INIT("freedemocamera", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||
|
||||
// NOTE: this should be in hw_main.c, but we can't put it there as it breaks dedicated build
|
||||
consvar_t cv_glallowshaders = CVAR_INIT ("gr_allowclientshaders", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||
consvar_t cv_glallowshaders = CVAR_INIT ("gr_allowcustomshaders", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||
|
||||
char timedemo_name[256];
|
||||
boolean timedemo_csv;
|
||||
|
@ -893,6 +893,9 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_renderhitboxinterpolation);
|
||||
CV_RegisterVar(&cv_renderhitboxgldepth);
|
||||
CV_RegisterVar(&cv_renderhitbox);
|
||||
CV_RegisterVar(&cv_renderwalls);
|
||||
CV_RegisterVar(&cv_renderfloors);
|
||||
CV_RegisterVar(&cv_renderthings);
|
||||
CV_RegisterVar(&cv_renderer);
|
||||
CV_RegisterVar(&cv_scr_depth);
|
||||
CV_RegisterVar(&cv_scr_width);
|
||||
|
@ -4663,15 +4666,28 @@ static void Command_Cheats_f(void)
|
|||
CV_ResetCheatNetVars();
|
||||
return;
|
||||
}
|
||||
else if (COM_CheckParm("on"))
|
||||
{
|
||||
if (!(server || (IsPlayerAdmin(consoleplayer))))
|
||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||
else
|
||||
G_SetUsedCheats(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (usedCheats)
|
||||
CONS_Printf(M_GetText("Cheats are enabled, the game cannot be saved.\n"));
|
||||
else
|
||||
CONS_Printf(M_GetText("Cheats are disabled, the game can be saved.\n"));
|
||||
|
||||
if (CV_CheatsEnabled())
|
||||
{
|
||||
CONS_Printf(M_GetText("At least one CHEAT-marked variable has been changed -- Cheats are enabled.\n"));
|
||||
CONS_Printf(M_GetText("At least one CHEAT-marked variable has been changed.\n"));
|
||||
if (server || (IsPlayerAdmin(consoleplayer)))
|
||||
CONS_Printf(M_GetText("Type CHEATS OFF to reset all cheat variables to default.\n"));
|
||||
}
|
||||
else
|
||||
CONS_Printf(M_GetText("No CHEAT-marked variables are changed -- Cheats are disabled.\n"));
|
||||
CONS_Printf(M_GetText("No CHEAT-marked variables are changed.\n"));
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
|
|
@ -1640,7 +1640,7 @@ boolean CURLPrepareFile(const char* url, int dfilenum)
|
|||
#endif
|
||||
|
||||
// Set user agent, as some servers won't accept invalid user agents.
|
||||
curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("Sonic Robo Blast 2/v%d.%d", VERSION, SUBVERSION));
|
||||
curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("Sonic Robo Blast 2/%s", VERSIONSTRING));
|
||||
|
||||
// Authenticate if the user so wishes
|
||||
login = CURLGetLogin(url, NULL);
|
||||
|
|
|
@ -265,7 +265,7 @@ static const char* inet_ntopA(short af, const void *cp, char *buf, socklen_t len
|
|||
#ifdef HAVE_MINIUPNPC // based on old XChat patch
|
||||
static void I_ShutdownUPnP(void);
|
||||
static void I_InitUPnP(void);
|
||||
I_mutex upnp_mutex;
|
||||
static I_mutex upnp_mutex;
|
||||
static struct UPNPUrls urls;
|
||||
static struct IGDdatas data;
|
||||
static char lanaddr[64];
|
||||
|
@ -300,7 +300,11 @@ init_upnpc_once(struct upnpdata *upnpuserdata)
|
|||
int upnp_error = -2;
|
||||
int scope_id = 0;
|
||||
int status_code = 0;
|
||||
CONS_Printf(M_GetText("Looking for UPnP Internet Gateway Device\n"));
|
||||
|
||||
memset(&urls, 0, sizeof(struct UPNPUrls));
|
||||
memset(&data, 0, sizeof(struct IGDdatas));
|
||||
|
||||
I_OutputMsg(M_GetText("Looking for UPnP Internet Gateway Device\n"));
|
||||
devlist = upnpDiscoverDevices(deviceTypes, 500, NULL, NULL, 0, false, 2, &upnp_error, 0);
|
||||
if (devlist)
|
||||
{
|
||||
|
@ -316,39 +320,37 @@ init_upnpc_once(struct upnpdata *upnpuserdata)
|
|||
if (!dev)
|
||||
dev = devlist; /* defaulting to first device */
|
||||
|
||||
CONS_Printf(M_GetText("Found UPnP device:\n desc: %s\n st: %s\n"),
|
||||
I_OutputMsg(M_GetText("Found UPnP device:\n desc: %s\n st: %s\n"),
|
||||
dev->descURL, dev->st);
|
||||
|
||||
UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
|
||||
CONS_Printf(M_GetText("Local LAN IP address: %s\n"), lanaddr);
|
||||
I_OutputMsg(M_GetText("Local LAN IP address: %s\n"), lanaddr);
|
||||
descXML = miniwget(dev->descURL, &descXMLsize, scope_id, &status_code);
|
||||
if (descXML)
|
||||
{
|
||||
parserootdesc(descXML, descXMLsize, &data);
|
||||
free(descXML);
|
||||
descXML = NULL;
|
||||
memset(&urls, 0, sizeof(struct UPNPUrls));
|
||||
memset(&data, 0, sizeof(struct IGDdatas));
|
||||
GetUPNPUrls(&urls, &data, dev->descURL, status_code);
|
||||
I_AddExitFunc(I_ShutdownUPnP);
|
||||
}
|
||||
freeUPNPDevlist(devlist);
|
||||
I_unlock_mutex(upnp_mutex);
|
||||
}
|
||||
else if (upnp_error == UPNPDISCOVER_SOCKET_ERROR)
|
||||
{
|
||||
CONS_Printf(M_GetText("No UPnP devices discovered\n"));
|
||||
I_OutputMsg(M_GetText("No UPnP devices discovered\n"));
|
||||
}
|
||||
I_unlock_mutex(upnp_mutex);
|
||||
upnpuserdata->upnpc_started =1;
|
||||
}
|
||||
|
||||
static inline void I_UPnP_add(const char * addr, const char *port, const char * servicetype)
|
||||
{
|
||||
if (!urls.controlURL || urls.controlURL[0] == '\0')
|
||||
return;
|
||||
I_lock_mutex(&upnp_mutex);
|
||||
if (addr == NULL)
|
||||
addr = lanaddr;
|
||||
if (!urls.controlURL || urls.controlURL[0] == '\0')
|
||||
return;
|
||||
UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
|
||||
port, port, addr, "SRB2", servicetype, NULL, NULL);
|
||||
I_unlock_mutex(upnp_mutex);
|
||||
|
@ -356,9 +358,9 @@ static inline void I_UPnP_add(const char * addr, const char *port, const char *
|
|||
|
||||
static inline void I_UPnP_rem(const char *port, const char * servicetype)
|
||||
{
|
||||
I_lock_mutex(&upnp_mutex);
|
||||
if (!urls.controlURL || urls.controlURL[0] == '\0')
|
||||
return;
|
||||
I_lock_mutex(&upnp_mutex);
|
||||
UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype,
|
||||
port, servicetype, NULL);
|
||||
I_unlock_mutex(upnp_mutex);
|
||||
|
@ -1132,10 +1134,10 @@ boolean I_InitTcpDriver(void)
|
|||
{
|
||||
I_AddExitFunc(I_ShutdownTcpDriver);
|
||||
#ifdef HAVE_MINIUPNPC
|
||||
if (M_CheckParm("-noUPnP"))
|
||||
UPNP_support = false;
|
||||
else
|
||||
if (M_CheckParm("-useUPnP"))
|
||||
I_InitUPnP();
|
||||
else
|
||||
UPNP_support = false;
|
||||
#endif
|
||||
}
|
||||
return init_tcp_driver;
|
||||
|
|
102
src/p_enemy.c
102
src/p_enemy.c
|
@ -541,7 +541,7 @@ boolean P_Move(mobj_t *actor, fixed_t speed)
|
|||
|
||||
if (!P_TryMove(actor, tryx, tryy, false))
|
||||
{
|
||||
if (actor->flags & MF_FLOAT && floatok)
|
||||
if (!P_MobjWasRemoved(actor) && actor->flags & MF_FLOAT && floatok)
|
||||
{
|
||||
// must adjust height
|
||||
if (actor->z < tmfloorz)
|
||||
|
@ -585,6 +585,7 @@ void P_NewChaseDir(mobj_t *actor)
|
|||
dirtype_t d[3];
|
||||
dirtype_t tdir = DI_NODIR, olddir, turnaround;
|
||||
|
||||
I_Assert(!P_MobjWasRemoved(actor));
|
||||
I_Assert(actor->target != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(actor->target));
|
||||
|
||||
|
@ -623,7 +624,7 @@ void P_NewChaseDir(mobj_t *actor)
|
|||
dirtype_t newdir = diags[((deltay < 0)<<1) + (deltax > 0)];
|
||||
|
||||
actor->movedir = newdir;
|
||||
if ((newdir != turnaround) && P_TryWalk(actor))
|
||||
if ((newdir != turnaround) && (P_TryWalk(actor) || P_MobjWasRemoved(actor)))
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -644,7 +645,7 @@ void P_NewChaseDir(mobj_t *actor)
|
|||
{
|
||||
actor->movedir = d[1];
|
||||
|
||||
if (P_TryWalk(actor))
|
||||
if (P_TryWalk(actor) || P_MobjWasRemoved(actor))
|
||||
return; // either moved forward or attacked
|
||||
}
|
||||
|
||||
|
@ -652,7 +653,7 @@ void P_NewChaseDir(mobj_t *actor)
|
|||
{
|
||||
actor->movedir = d[2];
|
||||
|
||||
if (P_TryWalk(actor))
|
||||
if (P_TryWalk(actor) || P_MobjWasRemoved(actor))
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -661,7 +662,7 @@ void P_NewChaseDir(mobj_t *actor)
|
|||
{
|
||||
actor->movedir =olddir;
|
||||
|
||||
if (P_TryWalk(actor))
|
||||
if (P_TryWalk(actor) || P_MobjWasRemoved(actor))
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -674,7 +675,7 @@ void P_NewChaseDir(mobj_t *actor)
|
|||
{
|
||||
actor->movedir = tdir;
|
||||
|
||||
if (P_TryWalk(actor))
|
||||
if (P_TryWalk(actor) || P_MobjWasRemoved(actor))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -687,7 +688,7 @@ void P_NewChaseDir(mobj_t *actor)
|
|||
{
|
||||
actor->movedir = tdir;
|
||||
|
||||
if (P_TryWalk(actor))
|
||||
if (P_TryWalk(actor) || P_MobjWasRemoved(actor))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -697,7 +698,7 @@ void P_NewChaseDir(mobj_t *actor)
|
|||
{
|
||||
actor->movedir = turnaround;
|
||||
|
||||
if (P_TryWalk(actor))
|
||||
if (P_TryWalk(actor) || P_MobjWasRemoved(actor))
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1100,7 +1101,7 @@ nomissile:
|
|||
return; // got a new target
|
||||
|
||||
// chase towards player
|
||||
if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed))
|
||||
if (--actor->movecount < 0 || (!P_Move(actor, actor->info->speed) && !P_MobjWasRemoved(actor)))
|
||||
P_NewChaseDir(actor);
|
||||
}
|
||||
|
||||
|
@ -1188,7 +1189,7 @@ nomissile:
|
|||
return; // got a new target
|
||||
|
||||
// chase towards player
|
||||
if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed))
|
||||
if (--actor->movecount < 0 || (!P_Move(actor, actor->info->speed) && !P_MobjWasRemoved(actor)))
|
||||
P_NewChaseDir(actor);
|
||||
}
|
||||
|
||||
|
@ -1266,6 +1267,7 @@ void A_FaceStabRev(mobj_t *actor)
|
|||
else
|
||||
{
|
||||
P_TryMove(actor, actor->x - P_ReturnThrustX(actor, actor->angle, 2<<FRACBITS), actor->y - P_ReturnThrustY(actor, actor->angle, 2<<FRACBITS), false);
|
||||
if (!P_MobjWasRemoved(actor))
|
||||
P_FaceStabFlume(actor);
|
||||
}
|
||||
}
|
||||
|
@ -1332,8 +1334,9 @@ void A_FaceStabHurl(mobj_t *actor)
|
|||
|
||||
while (step > 0)
|
||||
{
|
||||
if (!hwork->hnext)
|
||||
if (P_MobjWasRemoved(hwork->hnext))
|
||||
P_SetTarget(&hwork->hnext, P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_FACESTABBERSPEAR));
|
||||
|
||||
if (!P_MobjWasRemoved(hwork->hnext))
|
||||
{
|
||||
hwork = hwork->hnext;
|
||||
|
@ -1341,6 +1344,20 @@ void A_FaceStabHurl(mobj_t *actor)
|
|||
P_SetScale(hwork, FixedSqrt(step*basesize), true);
|
||||
hwork->fuse = 2;
|
||||
P_MoveOrigin(hwork, actor->x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<<FRACBITS)));
|
||||
if (P_MobjWasRemoved(hwork))
|
||||
{
|
||||
// if one of the sections are removed, erase the entire damn thing.
|
||||
mobj_t *hnext = actor->hnext;
|
||||
hwork = actor;
|
||||
do
|
||||
{
|
||||
hnext = hwork->hnext;
|
||||
P_RemoveMobj(hwork);
|
||||
hwork = hnext;
|
||||
}
|
||||
while (!P_MobjWasRemoved(hwork));
|
||||
return;
|
||||
}
|
||||
}
|
||||
step -= NUMGRADS;
|
||||
}
|
||||
|
@ -1357,10 +1374,13 @@ void A_FaceStabHurl(mobj_t *actor)
|
|||
#undef NUMGRADS
|
||||
#undef NUMSTEPS
|
||||
}
|
||||
if (P_MobjWasRemoved(actor))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
P_SetMobjState(actor, locvar2);
|
||||
if (!P_MobjWasRemoved(actor))
|
||||
actor->reactiontime = actor->info->reactiontime;
|
||||
}
|
||||
|
||||
|
@ -1391,6 +1411,8 @@ void A_FaceStabMiss(mobj_t *actor)
|
|||
actor->y + P_ReturnThrustY(actor, actor->angle, actor->extravalue2<<FRACBITS),
|
||||
false))
|
||||
{
|
||||
if (P_MobjWasRemoved(actor))
|
||||
return;
|
||||
actor->extravalue2 = 0;
|
||||
P_SetMobjState(actor, locvar2);
|
||||
}
|
||||
|
@ -1423,6 +1445,8 @@ void A_StatueBurst(mobj_t *actor)
|
|||
P_SetTarget(&new->target, actor->target);
|
||||
if (locvar2)
|
||||
P_SetMobjState(new, (statenum_t)locvar2);
|
||||
if (P_MobjWasRemoved(new))
|
||||
return;
|
||||
S_StartSound(new, new->info->attacksound);
|
||||
S_StopSound(actor);
|
||||
S_StartSound(actor, sfx_s3k96);
|
||||
|
@ -1518,7 +1542,7 @@ void A_JetJawChomp(mobj_t *actor)
|
|||
}
|
||||
|
||||
// chase towards player
|
||||
if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed))
|
||||
if (--actor->movecount < 0 || (!P_Move(actor, actor->info->speed) && !P_MobjWasRemoved(actor)))
|
||||
P_NewChaseDir(actor);
|
||||
}
|
||||
|
||||
|
@ -1939,13 +1963,14 @@ void A_SharpChase(mobj_t *actor)
|
|||
}
|
||||
|
||||
// chase towards player
|
||||
if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed))
|
||||
if (--actor->movecount < 0 || (!P_Move(actor, actor->info->speed) && !P_MobjWasRemoved(actor)))
|
||||
P_NewChaseDir(actor);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor->threshold = actor->info->painchance;
|
||||
P_SetMobjState(actor, actor->info->missilestate);
|
||||
if (!P_MobjWasRemoved(actor))
|
||||
S_StartSound(actor, actor->info->attacksound);
|
||||
}
|
||||
}
|
||||
|
@ -2032,6 +2057,8 @@ void A_CrushstaceanWalk(mobj_t *actor)
|
|||
false)
|
||||
|| (actor->reactiontime-- <= 0))
|
||||
{
|
||||
if (P_MobjWasRemoved(actor))
|
||||
return;
|
||||
actor->flags2 ^= MF2_AMBUSH;
|
||||
P_SetTarget(&actor->target, NULL);
|
||||
P_SetMobjState(actor, locvar2);
|
||||
|
@ -2213,6 +2240,8 @@ void A_CrushclawLaunch(mobj_t *actor)
|
|||
true)
|
||||
&& !locvar1)
|
||||
{
|
||||
if (P_MobjWasRemoved(actor))
|
||||
return;
|
||||
actor->extravalue1 = 0;
|
||||
actor->extravalue2 = FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y)>>FRACBITS;
|
||||
P_SetMobjState(actor, locvar2);
|
||||
|
@ -2221,6 +2250,8 @@ void A_CrushclawLaunch(mobj_t *actor)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (P_MobjWasRemoved(actor))
|
||||
return;
|
||||
actor->z = actor->target->z;
|
||||
if ((!locvar1 && (actor->extravalue2 > 256)) || (locvar1 && (actor->extravalue2 < 16)))
|
||||
{
|
||||
|
@ -2646,7 +2677,7 @@ nomissile:
|
|||
return; // got a new target
|
||||
|
||||
// chase towards player
|
||||
if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed))
|
||||
if (--actor->movecount < 0 || (!P_Move(actor, actor->info->speed) && !P_MobjWasRemoved(actor)))
|
||||
P_NewChaseDir(actor);
|
||||
}
|
||||
|
||||
|
@ -5771,7 +5802,11 @@ void A_MinusDigging(mobj_t *actor)
|
|||
if (P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) < actor->radius*2)
|
||||
{
|
||||
P_SetMobjState(actor, actor->info->meleestate);
|
||||
if (P_MobjWasRemoved(actor))
|
||||
return;
|
||||
P_TryMove(actor, actor->target->x, actor->target->y, false);
|
||||
if (P_MobjWasRemoved(actor))
|
||||
return;
|
||||
S_StartSound(actor, actor->info->attacksound);
|
||||
|
||||
// Spawn growing dirt pile.
|
||||
|
@ -5779,7 +5814,9 @@ void A_MinusDigging(mobj_t *actor)
|
|||
if (P_MobjWasRemoved(par))
|
||||
return;
|
||||
P_SetMobjState(par, actor->info->raisestate);
|
||||
P_SetScale(par, 2*actor->scale, false);
|
||||
if (P_MobjWasRemoved(par))
|
||||
return;
|
||||
P_SetScale(par, actor->scale*2);
|
||||
par->old_scale = par->scale;
|
||||
if (actor->eflags & MFE_VERTICALFLIP)
|
||||
par->eflags |= MFE_VERTICALFLIP;
|
||||
|
@ -5793,6 +5830,8 @@ void A_MinusDigging(mobj_t *actor)
|
|||
// Move
|
||||
var1 = 3;
|
||||
A_Chase(actor);
|
||||
if (P_MobjWasRemoved(actor))
|
||||
return;
|
||||
|
||||
// Carry over shit, maybe
|
||||
if (P_MobjWasRemoved(actor->tracer) || !actor->tracer->health)
|
||||
|
@ -5816,7 +5855,7 @@ void A_MinusDigging(mobj_t *actor)
|
|||
{
|
||||
if (P_TryMove(actor->tracer, actor->x, actor->y, false))
|
||||
actor->tracer->z = mz;
|
||||
else
|
||||
else if (!P_MobjWasRemoved(actor))
|
||||
P_SetTarget(&actor->tracer, NULL);
|
||||
}
|
||||
}
|
||||
|
@ -7290,7 +7329,7 @@ nomissile:
|
|||
// chase towards player
|
||||
if (P_AproxDistance(actor->target->x-actor->x, actor->target->y-actor->y) > actor->radius+actor->target->radius)
|
||||
{
|
||||
if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed))
|
||||
if (--actor->movecount < 0 || (!P_Move(actor, actor->info->speed) && !P_MobjWasRemoved(actor)))
|
||||
P_NewChaseDir(actor);
|
||||
}
|
||||
// too close, don't want to chase.
|
||||
|
@ -7647,7 +7686,7 @@ void A_Boss7Chase(mobj_t *actor)
|
|||
if (leveltime & 1)
|
||||
{
|
||||
// chase towards player
|
||||
if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed))
|
||||
if (--actor->movecount < 0 || (!P_Move(actor, actor->info->speed) && !P_MobjWasRemoved(actor)))
|
||||
P_NewChaseDir(actor);
|
||||
}
|
||||
}
|
||||
|
@ -8105,6 +8144,8 @@ void A_GuardChase(mobj_t *actor)
|
|||
false)
|
||||
&& speed > 0) // can't be the same check as previous so that P_TryMove gets to happen.
|
||||
{
|
||||
if (P_MobjWasRemoved(actor))
|
||||
return;
|
||||
INT32 direction = actor->spawnpoint ? actor->spawnpoint->args[0] : TMGD_BACK;
|
||||
|
||||
switch (direction)
|
||||
|
@ -8121,6 +8162,8 @@ void A_GuardChase(mobj_t *actor)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (P_MobjWasRemoved(actor))
|
||||
return;
|
||||
|
||||
if (actor->extravalue1 < actor->info->speed)
|
||||
actor->extravalue1++;
|
||||
|
@ -8157,7 +8200,11 @@ void A_GuardChase(mobj_t *actor)
|
|||
// chase towards player
|
||||
if (--actor->movecount < 0 || !P_Move(actor, (actor->flags2 & MF2_AMBUSH) ? actor->info->speed * 2 : actor->info->speed))
|
||||
{
|
||||
if (P_MobjWasRemoved(actor))
|
||||
return;
|
||||
P_NewChaseDir(actor);
|
||||
if (P_MobjWasRemoved(actor))
|
||||
return;
|
||||
actor->movecount += 5; // Increase tics before change in direction allowed.
|
||||
}
|
||||
}
|
||||
|
@ -8628,6 +8675,9 @@ void A_PlaySeeSound(mobj_t *actor)
|
|||
if (LUA_CallAction(A_PLAYSEESOUND, actor))
|
||||
return;
|
||||
|
||||
if (P_MobjWasRemoved(actor))
|
||||
return;
|
||||
|
||||
if (actor->info->seesound)
|
||||
S_StartScreamSound(actor, actor->info->seesound);
|
||||
}
|
||||
|
@ -11718,7 +11768,13 @@ void A_BrakChase(mobj_t *actor)
|
|||
|
||||
// chase towards player
|
||||
if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed))
|
||||
{
|
||||
if (P_MobjWasRemoved(actor))
|
||||
return;
|
||||
P_NewChaseDir(actor);
|
||||
if (P_MobjWasRemoved(actor))
|
||||
return;
|
||||
}
|
||||
|
||||
// Optionally play a sound effect
|
||||
if (locvar2 > 0 && locvar2 < NUMSFX)
|
||||
|
@ -13296,6 +13352,8 @@ void A_DoNPCSkid(mobj_t *actor)
|
|||
if ((FixedHypot(actor->momx, actor->momy) < locvar2)
|
||||
|| !P_TryMove(actor, actor->x + actor->momx, actor->y + actor->momy, false))
|
||||
{
|
||||
if (P_MobjWasRemoved(actor))
|
||||
return;
|
||||
actor->momx = actor->momy = 0;
|
||||
P_SetMobjState(actor, locvar1);
|
||||
return;
|
||||
|
@ -13838,6 +13896,8 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing)
|
|||
y = dustdevil->y;
|
||||
}
|
||||
P_TryMove(thing, x - thing->momx, y - thing->momy, true);
|
||||
if (P_MobjWasRemoved(thing))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{ //Player on the top of the tornado.
|
||||
|
@ -14243,6 +14303,8 @@ static void P_SnapperLegPlace(mobj_t *mo)
|
|||
|
||||
seg->z = mo->z + ((mo->eflags & MFE_VERTICALFLIP) ? (((mo->height<<1)/3) - seg->height) : mo->height/3);
|
||||
P_TryMove(seg, mo->x + FixedMul(c, rad) + necklen*c, mo->y + FixedMul(s, rad) + necklen*s, true);
|
||||
if (P_MobjWasRemoved(seg))
|
||||
return;
|
||||
seg->angle = a;
|
||||
|
||||
// Move as many legs as available.
|
||||
|
@ -14264,6 +14326,8 @@ static void P_SnapperLegPlace(mobj_t *mo)
|
|||
y = s*o2 - c*o1;
|
||||
seg->z = mo->z + (((mo->eflags & MFE_VERTICALFLIP) ? (mo->height - seg->height) : 0));
|
||||
P_TryMove(seg, mo->x + x, mo->y + y, true);
|
||||
if (P_MobjWasRemoved(seg))
|
||||
return;
|
||||
P_SetMobjState(seg, seg->info->raisestate);
|
||||
}
|
||||
else
|
||||
|
@ -14407,6 +14471,8 @@ void A_SnapperThinker(mobj_t *actor)
|
|||
s = FINESINE(fa);
|
||||
|
||||
P_TryMove(actor, actor->x + c*speed, actor->y + s*speed, false);
|
||||
if (P_MobjWasRemoved(actor))
|
||||
return;
|
||||
|
||||
// The snapper spawns dust if going fast!
|
||||
if (actor->reactiontime < 4)
|
||||
|
|
|
@ -1396,12 +1396,15 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
for (; special->hprev != NULL; special = special->hprev); // Move to the first sprite in the hoop
|
||||
i = 0;
|
||||
for (; special->type == MT_HOOP; special = special->hnext)
|
||||
{
|
||||
if (!P_MobjWasRemoved(special->target))
|
||||
{
|
||||
special->fuse = 11;
|
||||
special->movedir = i;
|
||||
special->extravalue1 = special->target->extravalue1;
|
||||
special->extravalue2 = special->target->extravalue2;
|
||||
special->target->threshold = 4242;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// Make the collision detectors disappear.
|
||||
|
|
34
src/p_map.c
34
src/p_map.c
|
@ -2734,7 +2734,7 @@ increment_move
|
|||
tryy = y;
|
||||
}
|
||||
|
||||
if (!P_CheckPosition(thing, tryx, tryy))
|
||||
if (!P_CheckPosition(thing, tryx, tryy) || P_MobjWasRemoved(thing))
|
||||
return false; // solid wall or thing
|
||||
|
||||
if (!(thing->flags & MF_NOCLIP))
|
||||
|
@ -2958,6 +2958,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
|
||||
{
|
||||
fixed_t tryx, tryy;
|
||||
I_Assert(!P_MobjWasRemoved(thing));
|
||||
|
||||
tryx = thing->x;
|
||||
tryy = thing->y;
|
||||
|
@ -2975,7 +2976,7 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
else
|
||||
tryy = y;
|
||||
|
||||
if (!P_CheckPosition(thing, tryx, tryy))
|
||||
if (!P_CheckPosition(thing, tryx, tryy) || P_MobjWasRemoved(thing))
|
||||
return false; // solid wall or thing
|
||||
|
||||
if (!(thing->flags & MF_NOCLIP))
|
||||
|
@ -3714,6 +3715,12 @@ static void P_CheckLavaWall(mobj_t *mo, sector_t *sec)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void P_StairStepSlideMove(mobj_t *mo)
|
||||
{
|
||||
if (!P_TryMove(mo, mo->x, mo->y + mo->momy, true) && !P_MobjWasRemoved(mo)) //Allow things to drop off.
|
||||
P_TryMove(mo, mo->x + mo->momx, mo->y, true);
|
||||
}
|
||||
|
||||
//
|
||||
// P_SlideMove
|
||||
// The momx / momy move is bad, so try to slide
|
||||
|
@ -3735,6 +3742,8 @@ void P_SlideMove(mobj_t *mo)
|
|||
|
||||
memset(&junk, 0x00, sizeof(junk));
|
||||
|
||||
I_Assert(!P_MobjWasRemoved(mo));
|
||||
|
||||
if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height)
|
||||
{
|
||||
// Don't mess with your momentum if it's a pushable object. Pushables do their own crazy things already.
|
||||
|
@ -3869,7 +3878,10 @@ void P_SlideMove(mobj_t *mo)
|
|||
|
||||
retry:
|
||||
if ((++hitcount == 3) || papercol)
|
||||
goto stairstep; // don't loop forever
|
||||
{
|
||||
P_StairStepSlideMove(mo);
|
||||
return;
|
||||
}
|
||||
|
||||
// trace along the three leading corners
|
||||
if (mo->momx > 0)
|
||||
|
@ -3921,9 +3933,7 @@ papercollision:
|
|||
if (bestslidefrac == FRACUNIT+1)
|
||||
{
|
||||
// the move must have hit the middle, so stairstep
|
||||
stairstep:
|
||||
if (!P_TryMove(mo, mo->x, mo->y + mo->momy, true)) //Allow things to drop off.
|
||||
P_TryMove(mo, mo->x + mo->momx, mo->y, true);
|
||||
P_StairStepSlideMove(mo);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3935,7 +3945,13 @@ stairstep:
|
|||
newy = FixedMul(mo->momy, bestslidefrac);
|
||||
|
||||
if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true))
|
||||
goto stairstep;
|
||||
{
|
||||
if (!P_MobjWasRemoved(mo))
|
||||
P_StairStepSlideMove(mo);
|
||||
return;
|
||||
}
|
||||
if (P_MobjWasRemoved(mo))
|
||||
return;
|
||||
}
|
||||
|
||||
// Now continue along the wall.
|
||||
|
@ -3986,11 +4002,13 @@ stairstep:
|
|||
tmymove = 0;
|
||||
}
|
||||
if (!P_TryMove(mo, newx, newy, true)) {
|
||||
if (success)
|
||||
if (success || P_MobjWasRemoved(mo))
|
||||
return; // Good enough!!
|
||||
else
|
||||
goto retry;
|
||||
}
|
||||
if (P_MobjWasRemoved(mo))
|
||||
return;
|
||||
success = true;
|
||||
} while(tmxmove || tmymove);
|
||||
}
|
||||
|
|
41
src/p_mobj.c
41
src/p_mobj.c
|
@ -2118,7 +2118,7 @@ void P_RingXYMovement(mobj_t *mo)
|
|||
I_Assert(mo != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(mo));
|
||||
|
||||
if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy))
|
||||
if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy) && !P_MobjWasRemoved(mo))
|
||||
P_SlideMove(mo);
|
||||
}
|
||||
|
||||
|
@ -2132,8 +2132,10 @@ void P_SceneryXYMovement(mobj_t *mo)
|
|||
oldx = mo->x;
|
||||
oldy = mo->y;
|
||||
|
||||
if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy))
|
||||
if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy) && !P_MobjWasRemoved(mo))
|
||||
P_SlideMove(mo);
|
||||
if (P_MobjWasRemoved(mo))
|
||||
return;
|
||||
|
||||
if ((!(mo->eflags & MFE_VERTICALFLIP) && mo->z > mo->floorz) || (mo->eflags & MFE_VERTICALFLIP && mo->z+mo->height < mo->ceilingz))
|
||||
return; // no friction when airborne
|
||||
|
@ -2329,9 +2331,12 @@ boolean P_CheckDeathPitCollide(mobj_t *mo)
|
|||
if (mo->player && mo->player->pflags & PF_GODMODE)
|
||||
return false;
|
||||
|
||||
if (((mo->z <= mo->subsector->sector->floorheight
|
||||
fixed_t sectorFloor = P_GetSectorFloorZAt(mo->subsector->sector, mo->x, mo->y);
|
||||
fixed_t sectorCeiling = P_GetSectorCeilingZAt(mo->subsector->sector, mo->x, mo->y);
|
||||
|
||||
if (((mo->z <= sectorFloor
|
||||
&& ((mo->subsector->sector->flags & MSF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->subsector->sector->flags & MSF_FLIPSPECIAL_FLOOR))
|
||||
|| (mo->z + mo->height >= mo->subsector->sector->ceilingheight
|
||||
|| (mo->z + mo->height >= sectorCeiling
|
||||
&& ((mo->subsector->sector->flags & MSF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->subsector->sector->flags & MSF_FLIPSPECIAL_CEILING)))
|
||||
&& (mo->subsector->sector->damagetype == SD_DEATHPITTILT
|
||||
|| mo->subsector->sector->damagetype == SD_DEATHPITNOTILT))
|
||||
|
@ -3906,6 +3911,8 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
|
|||
}
|
||||
else
|
||||
P_TryMove(mobj, mobj->x, mobj->y, true);
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
|
||||
P_CheckCrumblingPlatforms(mobj);
|
||||
|
||||
|
@ -4700,6 +4707,8 @@ static void P_Boss4PinchSpikeballs(mobj_t *mobj, angle_t angle, fixed_t dz)
|
|||
{
|
||||
seg->z = bz + (dz*(9-s));
|
||||
P_TryMove(seg, workx + (dx*s), worky + (dy*s), true);
|
||||
if (P_MobjWasRemoved(seg))
|
||||
return;
|
||||
}
|
||||
angle += ANGLE_MAX/3;
|
||||
}
|
||||
|
@ -4937,6 +4946,8 @@ static void P_Boss4Thinker(mobj_t *mobj)
|
|||
(mobj->spawnpoint->x<<FRACBITS) - P_ReturnThrustX(mobj, mobj->angle, mobj->movefactor),
|
||||
(mobj->spawnpoint->y<<FRACBITS) - P_ReturnThrustY(mobj, mobj->angle, mobj->movefactor),
|
||||
true);
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
|
||||
P_Boss4PinchSpikeballs(mobj, FixedAngle(mobj->movecount), mobj->z - mobj->watertop - mobjinfo[MT_EGGMOBILE4_MACE].height - mobj->height/2);
|
||||
|
||||
|
@ -5505,6 +5516,8 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
|||
{
|
||||
P_InstaThrust(mobj, mobj->angle, -4*FRACUNIT);
|
||||
P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true);
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
mobj->momz -= gravity;
|
||||
if (mobj->z < mobj->watertop || mobj->z < (mobj->floorz + 16*FRACUNIT))
|
||||
{
|
||||
|
@ -5848,6 +5861,8 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
|||
P_InstaThrust(mobj, mobj->angle, 30*FRACUNIT);
|
||||
if (!P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true))
|
||||
{ // Hit a wall? Find a direction to bounce
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
mobj->threshold--;
|
||||
if (!mobj->threshold) { // failed bounce!
|
||||
S_StartSound(mobj, sfx_mspogo);
|
||||
|
@ -5888,6 +5903,8 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
|||
P_InstaThrust(mobj, mobj->angle, -speed);
|
||||
while (!P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true) && tries++ < 16)
|
||||
{
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
S_StartSound(mobj, sfx_mspogo);
|
||||
P_BounceMove(mobj);
|
||||
mobj->angle = R_PointToAngle2(mobj->momx, mobj->momy,0,0);
|
||||
|
@ -7487,6 +7504,8 @@ static void P_RosySceneryThink(mobj_t *mobj)
|
|||
fixed_t x = mobj->x, y = mobj->y, z = mobj->z;
|
||||
angle_t angletoplayer = R_PointToAngle2(x, y, mobj->target->x, mobj->target->y);
|
||||
boolean allowed = P_TryMove(mobj, mobj->target->x, mobj->target->y, false);
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->x = x;
|
||||
|
@ -8052,6 +8071,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
break;
|
||||
}
|
||||
|
||||
if (!P_MobjWasRemoved(mobj))
|
||||
P_SceneryThinker(mobj);
|
||||
}
|
||||
|
||||
|
@ -10282,6 +10302,8 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_SetTarget(&mobj->hnext, NULL);
|
||||
if (mobj->hprev && P_MobjWasRemoved(mobj->hprev))
|
||||
P_SetTarget(&mobj->hprev, NULL);
|
||||
if (mobj->dontdrawforviewmobj && P_MobjWasRemoved(mobj->dontdrawforviewmobj))
|
||||
P_SetTarget(&mobj->dontdrawforviewmobj, NULL);
|
||||
|
||||
mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG);
|
||||
|
||||
|
@ -10412,6 +10434,8 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
|| mobj->type == MT_CANNONBALLDECOR
|
||||
|| mobj->type == MT_FALLINGROCK) {
|
||||
P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
//if (mobj->standingslope) CONS_Printf("slope physics on mobj\n");
|
||||
P_ButteredSlope(mobj);
|
||||
}
|
||||
|
@ -10513,6 +10537,8 @@ void P_PushableThinker(mobj_t *mobj)
|
|||
// it has to be pushable RIGHT NOW for this part to happen
|
||||
if (mobj->flags & MF_PUSHABLE && !(mobj->momx || mobj->momy))
|
||||
P_TryMove(mobj, mobj->x, mobj->y, true);
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
|
||||
if (mobj->type == MT_MINECART && mobj->health)
|
||||
{
|
||||
|
@ -10855,9 +10881,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...)
|
|||
)))
|
||||
mobj->flags2 |= MF2_DONTRESPAWN;
|
||||
|
||||
if (!(mobj->flags & MF_NOTHINK))
|
||||
P_AddThinker(THINK_MOBJ, &mobj->thinker);
|
||||
|
||||
if (type == MT_PLAYER)
|
||||
{
|
||||
// when spawning MT_PLAYER, set mobj->player before calling MobjSpawn hook to prevent P_RemoveMobj from succeeding on player mobj.
|
||||
|
@ -10867,6 +10890,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...)
|
|||
va_end(args);
|
||||
}
|
||||
|
||||
if (!(mobj->flags & MF_NOTHINK) || (titlemapinaction && mobj->type == MT_ALTVIEWMAN))
|
||||
P_AddThinker(THINK_MOBJ, &mobj->thinker);
|
||||
|
||||
// increment mobj reference, so we don't get a dangling reference in case MobjSpawn calls P_RemoveMobj
|
||||
mobj->thinker.references++;
|
||||
|
||||
|
@ -14006,6 +14032,7 @@ boolean P_CheckMissileSpawn(mobj_t *th)
|
|||
|
||||
if (!P_TryMove(th, th->x, th->y, true))
|
||||
{
|
||||
if (!P_MobjWasRemoved(th))
|
||||
P_ExplodeMissile(th);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -585,17 +585,17 @@ Ploadflat (levelflat_t *levelflat, const char *flatname, boolean resize)
|
|||
|
||||
// Look for a flat
|
||||
int texturenum = R_CheckFlatNumForName(levelflat->name);
|
||||
if (texturenum <= 0)
|
||||
if (texturenum < 0)
|
||||
{
|
||||
// If we can't find a flat, try looking for a texture!
|
||||
texturenum = R_CheckTextureNumForName(levelflat->name);
|
||||
if (texturenum <= 0)
|
||||
if (texturenum < 0)
|
||||
{
|
||||
// Use "not found" texture
|
||||
texturenum = R_CheckTextureNumForName("REDWALL");
|
||||
|
||||
// Give up?
|
||||
if (texturenum <= 0)
|
||||
if (texturenum < 0)
|
||||
{
|
||||
levelflat->type = LEVELFLAT_NONE;
|
||||
texturenum = -1;
|
||||
|
@ -1525,6 +1525,12 @@ static boolean TextmapCount(size_t size)
|
|||
numvertexes = 0;
|
||||
numsectors = 0;
|
||||
|
||||
if(!tkn)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "No text in lump!\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Look for namespace at the beginning.
|
||||
if (!fastcmp(tkn, "namespace"))
|
||||
{
|
||||
|
@ -3109,7 +3115,12 @@ static boolean P_LoadMapData(const virtres_t *virt)
|
|||
if (udmf) // Count how many entries for each type we got in textmap.
|
||||
{
|
||||
virtlump_t *textmap = vres_Find(virt, "TEXTMAP");
|
||||
M_TokenizerOpen((char *)textmap->data);
|
||||
if (textmap->size == 0)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Emtpy TEXTMAP Lump!\n");
|
||||
return false;
|
||||
}
|
||||
M_TokenizerOpen((char *)textmap->data, textmap->size);
|
||||
if (!TextmapCount(textmap->size))
|
||||
{
|
||||
M_TokenizerClose();
|
||||
|
|
|
@ -844,7 +844,7 @@ void P_Ticker(boolean run)
|
|||
if (quake.time)
|
||||
--quake.time;
|
||||
|
||||
if (metalplayback)
|
||||
if (!P_MobjWasRemoved(metalplayback))
|
||||
G_ReadMetalTic(metalplayback);
|
||||
if (metalrecording)
|
||||
G_WriteMetalTic(players[consoleplayer].mo);
|
||||
|
|
|
@ -11084,6 +11084,7 @@ static void P_MinecartThink(player_t *player)
|
|||
fa = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
if (!P_TryMove(minecart, minecart->x + FINECOSINE(fa), minecart->y + FINESINE(fa), true))
|
||||
{
|
||||
if (!P_MobjWasRemoved(minecart))
|
||||
P_KillMobj(minecart, NULL, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
@ -12441,7 +12442,7 @@ void P_PlayerThink(player_t *player)
|
|||
player->texttimer = 4*TICRATE;
|
||||
player->textvar = 2; // GET n RINGS!
|
||||
|
||||
if (player->capsule && player->capsule->health != player->capsule->spawnpoint->angle)
|
||||
if (!P_MobjWasRemoved(player->capsule) && player->capsule->health != player->capsule->spawnpoint->angle)
|
||||
player->textvar++; // GET n MORE RINGS!
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
#include "byteptr.h"
|
||||
#include "dehacked.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_glob.h" // HWR_ClearLightTables
|
||||
#endif
|
||||
|
||||
//
|
||||
// Graphics.
|
||||
// SRB2 graphics for walls and sprites
|
||||
|
@ -426,6 +430,9 @@ void R_ClearColormaps(void)
|
|||
{
|
||||
// Purged by PU_LEVEL, just overwrite the pointer
|
||||
extra_colormaps = R_CreateDefaultColormap(true);
|
||||
#ifdef HWRENDER
|
||||
HWR_ClearLightTables();
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
|
|
29
src/r_defs.h
29
src/r_defs.h
|
@ -25,6 +25,10 @@
|
|||
|
||||
#include "screen.h" // MAXVIDWIDTH, MAXVIDHEIGHT
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "m_aatree.h"
|
||||
#endif
|
||||
|
||||
#include "taglist.h"
|
||||
|
||||
//
|
||||
|
@ -69,6 +73,11 @@ typedef struct extracolormap_s
|
|||
|
||||
lighttable_t *colormap;
|
||||
|
||||
#ifdef HWRENDER
|
||||
// The id of the hardware lighttable. Zero means it does not exist yet.
|
||||
UINT32 gl_lighttable_id;
|
||||
#endif
|
||||
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
lumpnum_t lump; // for colormap lump matching, init to LUMPERROR
|
||||
char lumpname[9]; // for netsyncing
|
||||
|
@ -897,6 +906,26 @@ typedef struct
|
|||
// the [0] is &columnofs[width]
|
||||
} ATTRPACK softwarepatch_t;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4200)
|
||||
#endif
|
||||
|
||||
// a pic is an unmasked block of pixels, stored in horizontal way
|
||||
typedef struct
|
||||
{
|
||||
INT16 width;
|
||||
UINT8 zero; // set to 0 allow autodetection of pic_t
|
||||
// mode instead of patch or raw
|
||||
UINT8 mode; // see pic_mode_t above
|
||||
INT16 height;
|
||||
INT16 reserved1; // set to 0
|
||||
UINT8 data[0];
|
||||
} ATTRPACK pic_t;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(default : 4200)
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
|
|
@ -1363,7 +1363,7 @@ void R_SkyboxFrame(player_t *player)
|
|||
newview->z += campos.z * -mh->skybox_scalez;
|
||||
}
|
||||
|
||||
if (r_viewmobj->subsector)
|
||||
if (!P_MobjWasRemoved(r_viewmobj) && r_viewmobj->subsector)
|
||||
newview->sector = r_viewmobj->subsector->sector;
|
||||
else
|
||||
newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
|
||||
|
|
|
@ -881,6 +881,9 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
if (!(pl->minx <= pl->maxx))
|
||||
return;
|
||||
|
||||
if (!cv_renderfloors.value)
|
||||
return;
|
||||
|
||||
// sky flat
|
||||
if (pl->picnum == skyflatnum)
|
||||
{
|
||||
|
|
17
src/r_segs.c
17
src/r_segs.c
|
@ -117,6 +117,9 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
INT32 range;
|
||||
unsigned lengthcol;
|
||||
|
||||
if (!cv_renderwalls.value)
|
||||
return;
|
||||
|
||||
// Calculate light table.
|
||||
// Use different light tables
|
||||
// for horizontal / vertical / diagonal. Diagonal?
|
||||
|
@ -441,7 +444,7 @@ static void R_DrawRepeatMaskedColumn(column_t *col, unsigned lengthcol)
|
|||
{
|
||||
while (sprtopscreen < sprbotscreen) {
|
||||
R_DrawMaskedColumn(col, lengthcol);
|
||||
if ((INT64)sprtopscreen + dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow
|
||||
if ((INT64)sprtopscreen + (INT64)dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow
|
||||
sprtopscreen = INT32_MAX;
|
||||
else
|
||||
sprtopscreen += dc_texheight*spryscale;
|
||||
|
@ -505,6 +508,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
|
||||
void (*colfunc_2s) (column_t *, unsigned);
|
||||
|
||||
if (!cv_renderwalls.value)
|
||||
return;
|
||||
|
||||
// Calculate light table.
|
||||
// Use different light tables
|
||||
// for horizontal / vertical / diagonal. Diagonal?
|
||||
|
@ -1246,6 +1252,8 @@ static void R_RenderSegLoop (void)
|
|||
{
|
||||
// single sided line
|
||||
if (yl <= yh && yh >= 0 && yl < viewheight)
|
||||
{
|
||||
if (cv_renderwalls.value)
|
||||
{
|
||||
fixed_t offset = texturecolumn + rw_offsetx;
|
||||
|
||||
|
@ -1270,6 +1278,7 @@ static void R_RenderSegLoop (void)
|
|||
(INT32)mytotal);
|
||||
#endif
|
||||
//profile stuff ---------------------------------------------------------
|
||||
}
|
||||
|
||||
// dont draw anything more for this column, since
|
||||
// a midtexture blocks the view
|
||||
|
@ -1312,6 +1321,8 @@ static void R_RenderSegLoop (void)
|
|||
ceilingclip[rw_x] = (INT16)viewheight;
|
||||
}
|
||||
else if (mid >= 0) // safe to draw top texture
|
||||
{
|
||||
if (cv_renderwalls.value)
|
||||
{
|
||||
fixed_t offset = rw_offset_top;
|
||||
if (rw_toptexturescalex < 0)
|
||||
|
@ -1325,6 +1336,7 @@ static void R_RenderSegLoop (void)
|
|||
dc_source = R_GetColumn(toptexture, offset >> FRACBITS)->pixels;
|
||||
dc_texheight = textureheight[toptexture]>>FRACBITS;
|
||||
colfunc();
|
||||
}
|
||||
ceilingclip[rw_x] = (INT16)mid;
|
||||
}
|
||||
else if (!rw_ceilingmarked) // entirely off top of screen
|
||||
|
@ -1360,6 +1372,8 @@ static void R_RenderSegLoop (void)
|
|||
floorclip[rw_x] = -1;
|
||||
}
|
||||
else if (mid < viewheight) // safe to draw bottom texture
|
||||
{
|
||||
if (cv_renderwalls.value)
|
||||
{
|
||||
fixed_t offset = rw_offset_bottom;
|
||||
if (rw_bottomtexturescalex < 0)
|
||||
|
@ -1373,6 +1387,7 @@ static void R_RenderSegLoop (void)
|
|||
dc_source = R_GetColumn(bottomtexture, offset >> FRACBITS)->pixels;
|
||||
dc_texheight = textureheight[bottomtexture]>>FRACBITS;
|
||||
colfunc();
|
||||
}
|
||||
floorclip[rw_x] = (INT16)mid;
|
||||
}
|
||||
else if (!rw_floormarked) // entirely off bottom of screen
|
||||
|
|
|
@ -193,6 +193,8 @@ static void R_DrawBlendColumnInCache(column_t *column, UINT8 *cache, texpatch_t
|
|||
{
|
||||
for (; dest < cache + position + count; source++, dest++, is_opaque++)
|
||||
{
|
||||
if (originPatch->alpha <= ASTTextureBlendingThreshold[1] && !(*is_opaque))
|
||||
continue;
|
||||
*dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha);
|
||||
*is_opaque = true;
|
||||
}
|
||||
|
@ -237,6 +239,8 @@ static void R_DrawBlendFlippedColumnInCache(column_t *column, UINT8 *cache, texp
|
|||
{
|
||||
for (; dest < cache + position + count; --source, dest++, is_opaque++)
|
||||
{
|
||||
if (originPatch->alpha <= ASTTextureBlendingThreshold[1] && !(*is_opaque))
|
||||
continue;
|
||||
*dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha);
|
||||
*is_opaque = true;
|
||||
}
|
||||
|
|
|
@ -1528,6 +1528,9 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
if (!cv_renderthings.value)
|
||||
return;
|
||||
|
||||
// do interpolation
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
|
|
|
@ -784,9 +784,9 @@ static struct PaletteRemapParseResult *PaletteRemap_ParseString(tokenizer_t *sc)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct PaletteRemapParseResult *PaletteRemap_ParseTranslation(const char *translation)
|
||||
static struct PaletteRemapParseResult *PaletteRemap_ParseTranslation(const char *translation, size_t len)
|
||||
{
|
||||
tokenizer_t *sc = Tokenizer_Open(translation, 1);
|
||||
tokenizer_t *sc = Tokenizer_Open(translation, len, 1);
|
||||
struct PaletteRemapParseResult *result = PaletteRemap_ParseString(sc);
|
||||
Tokenizer_Close(sc);
|
||||
return result;
|
||||
|
@ -918,7 +918,7 @@ void R_ParseTrnslate(INT32 wadNum, UINT16 lumpnum)
|
|||
text[lumpLength] = '\0';
|
||||
Z_Free(lumpData);
|
||||
|
||||
sc = Tokenizer_Open(text, 1);
|
||||
sc = Tokenizer_Open(text, lumpLength, 1);
|
||||
tkn = sc->get(sc, 0);
|
||||
|
||||
struct NewTranslation *list = NULL;
|
||||
|
@ -963,7 +963,7 @@ void R_ParseTrnslate(INT32 wadNum, UINT16 lumpnum)
|
|||
|
||||
// Parse all of the translations
|
||||
do {
|
||||
struct PaletteRemapParseResult *parse_result = PaletteRemap_ParseTranslation(tkn);
|
||||
struct PaletteRemapParseResult *parse_result = PaletteRemap_ParseTranslation(tkn, strlen(tkn));
|
||||
if (parse_result->error)
|
||||
{
|
||||
PrintError(name, "%s", parse_result->error);
|
||||
|
|
|
@ -71,6 +71,9 @@ consvar_t cv_scr_height_w = CVAR_INIT ("scr_height_w", "400", CV_SAVE, CV_Unsign
|
|||
consvar_t cv_scr_depth = CVAR_INIT ("scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL);
|
||||
|
||||
consvar_t cv_renderview = CVAR_INIT ("renderview", "On", 0, CV_OnOff, NULL);
|
||||
consvar_t cv_renderwalls = CVAR_INIT ("renderwalls", "On", CV_NOTINNET|CV_CHEAT, CV_OnOff, NULL);
|
||||
consvar_t cv_renderfloors = CVAR_INIT ("renderfloors", "On", CV_NOTINNET|CV_CHEAT, CV_OnOff, NULL);
|
||||
consvar_t cv_renderthings = CVAR_INIT ("renderthings", "On", CV_NOTINNET|CV_CHEAT, CV_OnOff, NULL);
|
||||
|
||||
CV_PossibleValue_t cv_renderer_t[] = {
|
||||
{1, "Software"},
|
||||
|
|
|
@ -187,6 +187,7 @@ extern INT32 scr_bpp;
|
|||
extern UINT8 *scr_borderpatch; // patch used to fill the view borders
|
||||
|
||||
extern consvar_t cv_scr_width, cv_scr_height, cv_scr_width_w, cv_scr_height_w, cv_scr_depth, cv_fullscreen;
|
||||
extern consvar_t cv_renderwalls, cv_renderfloors, cv_renderthings;
|
||||
extern consvar_t cv_renderview, cv_renderer;
|
||||
extern consvar_t cv_renderhitbox, cv_renderhitboxinterpolation, cv_renderhitboxgldepth;
|
||||
// wait for page flipping to end or not
|
||||
|
|
|
@ -495,6 +495,7 @@
|
|||
<ClCompile Include="..\hardware\hw_md2load.c" />
|
||||
<ClCompile Include="..\hardware\hw_md3load.c" />
|
||||
<ClCompile Include="..\hardware\hw_model.c" />
|
||||
<ClCompile Include="..\hardware\hw_shaders.c" />
|
||||
<ClCompile Include="..\hardware\r_opengl\r_opengl.c" />
|
||||
<ClCompile Include="..\lua_colorlib.c" />
|
||||
<ClCompile Include="..\r_bbox.c" />
|
||||
|
|
|
@ -751,6 +751,12 @@
|
|||
<ClCompile Include="..\hardware\hw_model.c">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\hardware\hw_shaders.c">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\hardware\u_list.c">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\filesrch.c">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
@ -74,7 +74,7 @@ void *hwSym(const char *funcName,void *handle)
|
|||
{
|
||||
void *funcPointer = NULL;
|
||||
#ifdef HWRENDER
|
||||
if (0 == strcmp("SetPalette", funcName))
|
||||
if (0 == strcmp("SetTexturePalette", funcName))
|
||||
funcPointer = &OglSdlSetPalette;
|
||||
|
||||
GETFUNC(Init);
|
||||
|
@ -87,7 +87,7 @@ void *hwSym(const char *funcName,void *handle)
|
|||
GETFUNC(SetTexture);
|
||||
GETFUNC(UpdateTexture);
|
||||
GETFUNC(DeleteTexture);
|
||||
GETFUNC(ReadRect);
|
||||
GETFUNC(ReadScreenTexture);
|
||||
GETFUNC(GClipRect);
|
||||
GETFUNC(ClearMipMapCache);
|
||||
GETFUNC(SetSpecialState);
|
||||
|
@ -97,21 +97,23 @@ void *hwSym(const char *funcName,void *handle)
|
|||
GETFUNC(SetTransform);
|
||||
GETFUNC(PostImgRedraw);
|
||||
GETFUNC(FlushScreenTextures);
|
||||
GETFUNC(StartScreenWipe);
|
||||
GETFUNC(EndScreenWipe);
|
||||
GETFUNC(DoScreenWipe);
|
||||
GETFUNC(DrawIntermissionBG);
|
||||
GETFUNC(DrawScreenTexture);
|
||||
GETFUNC(MakeScreenTexture);
|
||||
GETFUNC(MakeScreenFinalTexture);
|
||||
GETFUNC(DrawScreenFinalTexture);
|
||||
|
||||
GETFUNC(CompileShaders);
|
||||
GETFUNC(CleanShaders);
|
||||
GETFUNC(InitShaders);
|
||||
GETFUNC(LoadShader);
|
||||
GETFUNC(CompileShader);
|
||||
GETFUNC(SetShader);
|
||||
GETFUNC(UnSetShader);
|
||||
|
||||
GETFUNC(SetShaderInfo);
|
||||
GETFUNC(LoadCustomShader);
|
||||
|
||||
GETFUNC(SetPaletteLookup);
|
||||
GETFUNC(CreateLightTable);
|
||||
GETFUNC(ClearLightTables);
|
||||
GETFUNC(SetScreenPalette);
|
||||
|
||||
#else //HWRENDER
|
||||
if (0 == strcmp("FinishUpdate", funcName))
|
||||
|
|
|
@ -109,6 +109,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
|
|||
#endif
|
||||
|
||||
#if defined (__unix__) || (defined (UNIXCOMMON) && !defined (__APPLE__))
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#define NEWSIGNALHANDLER
|
||||
|
@ -616,11 +617,21 @@ void I_GetConsoleEvents(void)
|
|||
// we use this when sending back commands
|
||||
event_t ev = {0};
|
||||
char key = 0;
|
||||
ssize_t d;
|
||||
struct pollfd pfd =
|
||||
{
|
||||
.fd = STDIN_FILENO,
|
||||
.events = POLLIN,
|
||||
.revents = 0,
|
||||
};
|
||||
|
||||
if (!consolevent)
|
||||
return;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (poll(&pfd, 1, 0) < 1 || !(pfd.revents & POLLIN))
|
||||
return;
|
||||
|
||||
ev.type = ev_console;
|
||||
ev.key = 0;
|
||||
if (read(STDIN_FILENO, &key, 1) == -1 || !key)
|
||||
|
@ -647,7 +658,7 @@ void I_GetConsoleEvents(void)
|
|||
tty_con.cursor = 0;
|
||||
ev.key = KEY_ENTER;
|
||||
}
|
||||
else return;
|
||||
else continue;
|
||||
}
|
||||
else if (tty_con.cursor < sizeof (tty_con.buffer))
|
||||
{
|
||||
|
@ -655,11 +666,11 @@ void I_GetConsoleEvents(void)
|
|||
ev.key = tty_con.buffer[tty_con.cursor] = key;
|
||||
tty_con.cursor++;
|
||||
// print the current line (this is differential)
|
||||
d = write(STDOUT_FILENO, &key, 1);
|
||||
write(STDOUT_FILENO, &key, 1);
|
||||
}
|
||||
if (ev.key) D_PostEvent(&ev);
|
||||
//tty_FlushIn();
|
||||
(void)d;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined (_WIN32)
|
||||
|
|
|
@ -1297,6 +1297,14 @@ void I_FinishUpdate(void)
|
|||
#ifdef HWRENDER
|
||||
else if (rendermode == render_opengl)
|
||||
{
|
||||
// Final postprocess step of palette rendering, after everything else has been drawn.
|
||||
if (HWR_ShouldUsePaletteRendering())
|
||||
{
|
||||
HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_GENERIC2);
|
||||
HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_PALETTE_POSTPROCESS));
|
||||
HWD.pfnDrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2, NULL, 0);
|
||||
HWD.pfnUnSetShader();
|
||||
}
|
||||
OglSdlFinishUpdate(cv_vidwait.value);
|
||||
}
|
||||
#endif
|
||||
|
@ -1958,32 +1966,34 @@ void VID_StartupOpenGL(void)
|
|||
HWD.pfnSetTexture = hwSym("SetTexture",NULL);
|
||||
HWD.pfnUpdateTexture = hwSym("UpdateTexture",NULL);
|
||||
HWD.pfnDeleteTexture = hwSym("DeleteTexture",NULL);
|
||||
HWD.pfnReadRect = hwSym("ReadRect",NULL);
|
||||
HWD.pfnReadScreenTexture= hwSym("ReadScreenTexture",NULL);
|
||||
HWD.pfnGClipRect = hwSym("GClipRect",NULL);
|
||||
HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL);
|
||||
HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL);
|
||||
HWD.pfnSetPalette = hwSym("SetPalette",NULL);
|
||||
HWD.pfnSetTexturePalette= hwSym("SetTexturePalette",NULL);
|
||||
HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL);
|
||||
HWD.pfnDrawModel = hwSym("DrawModel",NULL);
|
||||
HWD.pfnCreateModelVBOs = hwSym("CreateModelVBOs",NULL);
|
||||
HWD.pfnSetTransform = hwSym("SetTransform",NULL);
|
||||
HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL);
|
||||
HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL);
|
||||
HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL);
|
||||
HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL);
|
||||
HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL);
|
||||
HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL);
|
||||
HWD.pfnDrawScreenTexture= hwSym("DrawScreenTexture",NULL);
|
||||
HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL);
|
||||
HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL);
|
||||
HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL);
|
||||
|
||||
HWD.pfnCompileShaders = hwSym("CompileShaders",NULL);
|
||||
HWD.pfnCleanShaders = hwSym("CleanShaders",NULL);
|
||||
HWD.pfnInitShaders = hwSym("InitShaders",NULL);
|
||||
HWD.pfnLoadShader = hwSym("LoadShader",NULL);
|
||||
HWD.pfnCompileShader = hwSym("CompileShader",NULL);
|
||||
HWD.pfnSetShader = hwSym("SetShader",NULL);
|
||||
HWD.pfnUnSetShader = hwSym("UnSetShader",NULL);
|
||||
|
||||
HWD.pfnSetShaderInfo = hwSym("SetShaderInfo",NULL);
|
||||
HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",NULL);
|
||||
|
||||
HWD.pfnSetPaletteLookup = hwSym("SetPaletteLookup",NULL);
|
||||
HWD.pfnCreateLightTable = hwSym("CreateLightTable",NULL);
|
||||
HWD.pfnClearLightTables = hwSym("ClearLightTables",NULL);
|
||||
HWD.pfnSetScreenPalette = hwSym("SetScreenPalette",NULL);
|
||||
|
||||
vid.glstate = HWD.pfnInit() ? VID_GL_LIBRARY_LOADED : VID_GL_LIBRARY_ERROR; // let load the OpenGL library
|
||||
|
||||
|
|
|
@ -232,7 +232,9 @@ void OglSdlFinishUpdate(boolean waitvbl)
|
|||
|
||||
// Sryder: We need to draw the final screen texture again into the other buffer in the original position so that
|
||||
// effects that want to take the old screen can do so after this
|
||||
HWR_DrawScreenFinalTexture(realwidth, realheight);
|
||||
// Generic2 has the screen image without palette rendering brightness adjustments.
|
||||
// Using that here will prevent brightness adjustments being applied twice.
|
||||
DrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2, NULL, 0);
|
||||
}
|
||||
|
||||
EXPORT void HWRAPI(OglSdlSetPalette) (RGBA_t *palette)
|
||||
|
|
|
@ -227,8 +227,8 @@ void ST_doPaletteStuff(void)
|
|||
palette = 0;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
palette = 0; // No flashpals here in OpenGL
|
||||
if (rendermode == render_opengl && !HWR_ShouldUsePaletteRendering())
|
||||
palette = 0; // Don't set the palette to a flashpal in OpenGL's truecolor mode
|
||||
#endif
|
||||
|
||||
if (palette != st_palette)
|
||||
|
@ -1945,7 +1945,7 @@ static void ST_drawNiGHTSHUD(void)
|
|||
total_ringcount = stplyr->spheres;
|
||||
}
|
||||
|
||||
if (stplyr->capsule)
|
||||
if (!P_MobjWasRemoved(stplyr->capsule))
|
||||
{
|
||||
INT32 amount;
|
||||
const INT32 length = 88;
|
||||
|
@ -2893,7 +2893,7 @@ void ST_Drawer(void)
|
|||
//25/08/99: Hurdler: palette changes is done for all players,
|
||||
// not only player1! That's why this part
|
||||
// of code is moved somewhere else.
|
||||
if (rendermode == render_soft)
|
||||
if (rendermode == render_soft || HWR_ShouldUsePaletteRendering())
|
||||
#endif
|
||||
if (rendermode != render_none) ST_doPaletteStuff();
|
||||
|
||||
|
|
|
@ -821,10 +821,7 @@ static void W_ReadFileShaders(wadfile_t *wadfile)
|
|||
{
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED))
|
||||
{
|
||||
HWR_LoadCustomShadersFromFile(numwadfiles - 1, W_FileHasFolders(wadfile));
|
||||
HWR_CompileShaders();
|
||||
}
|
||||
#else
|
||||
(void)wadfile;
|
||||
#endif
|
||||
|
@ -1171,6 +1168,7 @@ UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup)
|
|||
numwadfiles++;
|
||||
|
||||
W_ReadFileShaders(wadfile);
|
||||
W_LoadTrnslateLumps(numwadfiles - 1);
|
||||
W_LoadDehackedLumpsPK3(numwadfiles - 1, mainfile);
|
||||
W_InvalidateLumpnumCache();
|
||||
|
||||
|
@ -2707,7 +2705,7 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
|
|||
UINT8 *wadData = W_CacheLumpNum(lumpnum, PU_LEVEL);
|
||||
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
|
||||
numlumps = ((wadinfo_t *)wadData)->numlumps;
|
||||
vlumps = Z_Malloc(sizeof(virtlump_t)*numlumps, PU_LEVEL, NULL);
|
||||
vlumps = Z_Calloc(sizeof(virtlump_t)*numlumps, PU_LEVEL, NULL);
|
||||
|
||||
// Build the lumps.
|
||||
for (i = 0; i < numlumps; i++)
|
||||
|
@ -2731,7 +2729,7 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
|
|||
break;
|
||||
numlumps++;
|
||||
|
||||
vlumps = Z_Malloc(sizeof(virtlump_t)*numlumps, PU_LEVEL, NULL);
|
||||
vlumps = Z_Calloc(sizeof(virtlump_t)*numlumps, PU_LEVEL, NULL);
|
||||
for (i = 0; i < numlumps; i++, lumpnum++)
|
||||
{
|
||||
vlumps[i].size = W_LumpLength(lumpnum);
|
||||
|
|
Loading…
Reference in a new issue