Merge branch 'next' into texture-scaling-fixes

This commit is contained in:
Lactozilla 2024-02-24 14:22:41 -03:00
commit 2d3dd624f5
84 changed files with 3042 additions and 6704 deletions

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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

Binary file not shown.

View file

@ -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

View file

@ -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 :)

View file

@ -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>

View file

@ -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

View file

@ -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.

File diff suppressed because it is too large Load diff

311
doc/specs/udmf_srb2.txt Normal file
View 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
===============================================================================

View file

@ -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()

View file

@ -11,8 +11,6 @@
rendermode_t rendermode = render_soft;
rendermode_t chosenrendermode = render_none;
boolean highcolor = false;
boolean allow_fullscreen = false;

View file

@ -70,14 +70,9 @@ static boolean consoleready; // console prompt is ready
INT32 con_destlines; // vid lines used by console at final position
static INT32 con_curlines; // vid lines currently used by console
INT32 con_clipviewtop; // (useless)
static UINT8 con_hudlines; // number of console heads up message lines
static UINT32 con_hudtime[MAXHUDLINES]; // remaining time of display for hud msg lines
INT32 con_clearlines; // top screen lines to refresh when view reduced
boolean con_hudupdate; // when messages scroll, we need a backgrnd refresh
// console text output
static char *con_line; // console text output current line
static size_t con_cx; // cursor position in current line
@ -120,7 +115,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];
@ -473,9 +468,6 @@ void CON_Init(void)
Lock_state();
//note: CON_Ticker should always execute at least once before D_Display()
con_clipviewtop = -1; // -1 does not clip
con_hudlines = atoi(cons_hudlines.defaultvalue);
Unlock_state();
@ -751,7 +743,6 @@ void CON_ToggleOff(void)
con_curlines = 0;
CON_ClearHUD();
con_forcepic = 0;
con_clipviewtop = -1; // remove console clipping of view
I_UpdateMouseGrab();
@ -800,18 +791,6 @@ void CON_Ticker(void)
CON_ChangeHeight();
}
// clip the view, so that the part under the console is not drawn
con_clipviewtop = -1;
if (cons_backpic.value) // clip only when using an opaque background
{
if (con_curlines > 0)
con_clipviewtop = con_curlines - viewwindowy - 1 - 10;
// NOTE: BIG HACK::SUBTRACT 10, SO THAT WATER DON'T COPY LINES OF THE CONSOLE
// WINDOW!!! (draw some more lines behind the bottom of the console)
if (con_clipviewtop < 0)
con_clipviewtop = -1; // maybe not necessary, provided it's < 0
}
// check if console ready for prompt
if (con_destlines >= minheight)
consoleready = true;
@ -1358,9 +1337,6 @@ static void CON_Linefeed(void)
con_line = &con_buffer[(con_cy%con_totallines)*con_width];
memset(con_line, ' ', con_width);
// make sure the view borders are refreshed if hud messages scroll
con_hudupdate = true; // see HU_Erase()
}
// Outputs text into the console text buffer
@ -1749,9 +1725,6 @@ static void CON_DrawHudlines(void)
//V_DrawCharacter(x, y, (p[c]&0xff) | cv_constextsize.value | V_NOSCALESTART, true);
y += charheight;
}
// top screen lines that might need clearing when view is reduced
con_clearlines = y; // this is handled by HU_Erase();
}
// Lactozilla: Draws the console's background picture.
@ -1817,10 +1790,6 @@ static void CON_DrawConsole(void)
if (con_curlines <= 0)
return;
//FIXME: refresh borders only when console bg is translucent
con_clearlines = con_curlines; // clear console draw from view borders
con_hudupdate = true; // always refresh while console is on
// draw console background
if (cons_backpic.value || con_forcepic)
CON_DrawBackpic();

View file

@ -34,14 +34,9 @@ extern boolean con_startup;
// needs explicit screen refresh until we are in the main game loop
extern boolean con_refresh;
// top clip value for view render: do not draw part of view hidden by console
extern INT32 con_clipviewtop;
// 0 means console if off, or moving out
extern INT32 con_destlines;
extern INT32 con_clearlines; // lines of top of screen to refresh
extern boolean con_hudupdate; // hud messages have changed, need refresh
extern UINT32 con_scalefactor; // console text scale factor
extern consvar_t cons_backcolor;

View file

@ -408,13 +408,11 @@ static void D_Display(void)
case GS_LEVEL:
if (!gametic)
break;
HU_Erase();
AM_Drawer();
break;
case GS_INTERMISSION:
Y_IntermissionDrawer();
HU_Erase();
HU_Drawer();
break;
@ -429,13 +427,11 @@ static void D_Display(void)
case GS_ENDING:
F_EndingDrawer();
HU_Erase();
HU_Drawer();
break;
case GS_CUTSCENE:
F_CutsceneDrawer();
HU_Erase();
HU_Drawer();
break;
@ -445,7 +441,6 @@ static void D_Display(void)
case GS_EVALUATION:
F_GameEvaluationDrawer();
HU_Erase();
HU_Drawer();
break;
@ -455,7 +450,6 @@ static void D_Display(void)
case GS_CREDITS:
F_CreditDrawer();
HU_Erase();
HU_Drawer();
break;
@ -465,7 +459,6 @@ static void D_Display(void)
{
// I don't think HOM from nothing drawing is independent...
F_WaitingPlayersDrawer();
HU_Erase();
HU_Drawer();
}
case GS_DEDICATEDSERVER:
@ -480,8 +473,6 @@ static void D_Display(void)
{
wipegamestate = gamestate;
// clean up border stuff
// see if the border needs to be initially drawn
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide && (!hidetitlemap)))
{
// draw the view directly
@ -506,23 +497,21 @@ static void D_Display(void)
// render the second screen
if (splitscreen && players[secondarydisplayplayer].mo)
{
#ifdef HWRENDER
if (rendermode != render_soft)
viewwindowy = vid.height / 2;
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_RenderPlayerView(1, &players[secondarydisplayplayer]);
else
#endif
#endif
if (rendermode != render_none)
{
viewwindowy = vid.height / 2;
M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0]));
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
R_RenderPlayerView(&players[secondarydisplayplayer]);
viewwindowy = 0;
M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
}
viewwindowy = 0;
}
// Image postprocessing effect
@ -1512,9 +1501,7 @@ void D_SRB2Main(void)
G_LoadGameData(clientGamedata);
M_CopyGameData(serverGamedata, clientGamedata);
#if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL)
VID_PrepareModeList(); // Regenerate Modelist according to cv_fullscreen
#endif
// set user default mode or mode set at cmdline
SCR_CheckDefaultMode();

View file

@ -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,50 +856,60 @@ 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;
ev.type = ev_console;
ev.key = 0;
if (read(STDIN_FILENO, &key, 1) == -1 || !key)
return;
for (;;)
{
if (poll(&pfd, 1, 0) < 1 || !(pfd.revents & POLLIN))
return;
// we have something
// backspace?
// NOTE TTimo testing a lot of values .. seems it's the only way to get it to work everywhere
if ((key == tty_erase) || (key == 127) || (key == 8))
{
if (tty_con.cursor > 0)
ev.type = ev_console;
ev.key = 0;
if (read(STDIN_FILENO, &key, 1) == -1 || !key)
return;
// we have something
// backspace?
// NOTE TTimo testing a lot of values .. seems it's the only way to get it to work everywhere
if ((key == tty_erase) || (key == 127) || (key == 8))
{
tty_con.cursor--;
tty_con.buffer[tty_con.cursor] = '\0';
tty_Back();
if (tty_con.cursor > 0)
{
tty_con.cursor--;
tty_con.buffer[tty_con.cursor] = '\0';
tty_Back();
}
ev.key = KEY_BACKSPACE;
}
ev.key = KEY_BACKSPACE;
}
else if (key < ' ') // check if this is a control char
{
if (key == '\n')
else if (key < ' ') // check if this is a control char
{
tty_Clear();
tty_con.cursor = 0;
ev.key = KEY_ENTER;
if (key == '\n')
{
tty_Clear();
tty_con.cursor = 0;
ev.key = KEY_ENTER;
}
else continue;
}
else return;
else if (tty_con.cursor < sizeof(tty_con.buffer))
{
// push regular character
ev.key = tty_con.buffer[tty_con.cursor] = key;
tty_con.cursor++;
// print the current line (this is differential)
write(STDOUT_FILENO, &key, 1);
}
if (ev.key) D_PostEvent(&ev);
//tty_FlushIn();
}
else if (tty_con.cursor < sizeof(tty_con.buffer))
{
// push regular character
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);
}
if (ev.key) D_PostEvent(&ev);
//tty_FlushIn();
(void)d;
}
#elif defined (_WIN32)

View file

@ -5,8 +5,6 @@
rendermode_t rendermode = render_none;
rendermode_t chosenrendermode = render_none;
boolean highcolor = false;
boolean allow_fullscreen = false;
consvar_t cv_vidwait = CVAR_INIT ("vid_wait", "On", CV_SAVE, CV_OnOff, NULL);

View file

@ -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);
@ -709,13 +709,6 @@ extern int
/// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls.
//#define PAPER_COLLISIONCORRECTION
/// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up
/// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down)
/// on the bright side it fixes some weird issues with translucent walls
/// \note SRB2CB port.
/// SRB2CB itself ported this from PrBoom+
#define NEWCLIP
/// OpenGL shaders
#define GL_SHADERS

View file

@ -5,8 +5,6 @@
rendermode_t rendermode = render_none;
rendermode_t chosenrendermode = render_none;
boolean highcolor = false;
boolean allow_fullscreen = false;
consvar_t cv_vidwait = CVAR_INIT ("vid_wait", "On", CV_SAVE, CV_OnOff, NULL);

View file

@ -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;

View file

@ -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

View file

@ -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
)

View file

@ -9,4 +9,5 @@ hw_md2load.c
hw_md3load.c
hw_model.c
hw_batching.c
hw_shaders.c
r_opengl/r_opengl.c

View file

@ -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,10 +151,9 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
}
else
{
if (shader)
HWD.pfnSetShader(shader);
HWD.pfnDrawPolygon(pSurf, pOutVerts, iNumPts, PolyFlags);
}
HWD.pfnSetShader((shader_target != SHADER_NONE) ? HWR_GetShaderFromTarget(shader_target) : shader_target);
HWD.pfnDrawPolygon(pSurf, pOutVerts, iNumPts, PolyFlags);
}
}
static int comparePolygons(const void *p1, const void *p2)

View file

@ -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,7 +464,10 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
grtex->mipmap.width = (UINT16)texture->width;
grtex->mipmap.height = (UINT16)texture->height;
grtex->mipmap.format = textureformat;
if (skyspecial)
grtex->mipmap.format = GL_TEXFMT_RGBA; // that skyspecial code below assumes this format ...
else
grtex->mipmap.format = textureformat;
blockwidth = texture->width;
blockheight = texture->height;
@ -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;
@ -997,6 +999,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 +1017,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 +1089,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

View file

@ -320,16 +320,13 @@ void gld_clipper_Clear(void)
#define RMUL (1.6f/1.333333f)
angle_t gld_FrustumAngle(angle_t tiltangle)
angle_t gld_FrustumAngle(float render_fov, angle_t tiltangle)
{
double floatangle;
angle_t a1;
float tilt = (float)fabs(((double)(int)tiltangle) / ANG1);
// NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function
float render_fov = FIXED_TO_FLOAT(cv_fov.value);
float render_fovratio = (float)BASEVIDWIDTH / (float)BASEVIDHEIGHT; // SRB2CBTODO: NEWCLIPTODO: Is this right?
float render_multiplier = 64.0f / render_fovratio / RMUL;

View file

@ -17,7 +17,7 @@
boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle);
void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle);
void gld_clipper_Clear(void);
angle_t gld_FrustumAngle(angle_t tiltangle);
angle_t gld_FrustumAngle(float render_fov, angle_t tiltangle);
#ifdef HAVE_SPHEREFRUSTRUM
void gld_FrustrumSetup(void);
boolean gld_SphereInFrustum(float x, float y, float z, float radius);

View file

@ -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_

View file

@ -22,7 +22,6 @@
#include "hw_drv.h"
#include "../m_misc.h" //FIL_WriteFile()
#include "../r_draw.h" //viewborderlump
#include "../r_main.h"
#include "../w_wad.h"
#include "../z_zone.h"
@ -30,13 +29,10 @@
#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
#ifndef O_BINARY
#define O_BINARY 0
#endif
#include "../i_video.h"
#if defined(_MSC_VER)
#pragma pack(1)
@ -62,63 +58,6 @@ static UINT8 softwaretranstogl[11] = { 0, 25, 51, 76,102,127,153,178,204,229
static UINT8 softwaretranstogl_hi[11] = { 0, 51,102,153,204,255,255,255,255,255,255};
static UINT8 softwaretranstogl_lo[11] = { 0, 12, 24, 36, 48, 60, 71, 83, 95,111,127};
//
// -----------------+
// HWR_DrawPatch : Draw a 'tile' graphic
// Notes : x,y : positions relative to the original Doom resolution
// : textes(console+score) + menus + status bar
// -----------------+
void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option)
{
FOutVector v[4];
FBITFIELD flags;
GLPatch_t *hwrPatch;
// 3--2
// | /|
// |/ |
// 0--1
float sdup = FIXED_TO_FLOAT(vid.fdup)*2.0f;
float pdup = FIXED_TO_FLOAT(vid.fdup)*2.0f;
// make patch ready in hardware cache
HWR_GetPatch(gpatch);
hwrPatch = ((GLPatch_t *)gpatch->hardware);
switch (option & V_SCALEPATCHMASK)
{
case V_NOSCALEPATCH:
pdup = 2.0f;
break;
case V_SMALLSCALEPATCH:
pdup = 2.0f * FIXED_TO_FLOAT(vid.fsmalldup);
break;
case V_MEDSCALEPATCH:
pdup = 2.0f * FIXED_TO_FLOAT(vid.fmeddup);
break;
}
if (option & V_NOSCALESTART)
sdup = 2.0f;
v[0].x = v[3].x = (x*sdup-(gpatch->leftoffset)*pdup)/vid.width - 1;
v[2].x = v[1].x = (x*sdup+(gpatch->width-gpatch->leftoffset)*pdup)/vid.width - 1;
v[0].y = v[1].y = 1-(y*sdup-(gpatch->topoffset)*pdup)/vid.height;
v[2].y = v[3].y = 1-(y*sdup+(gpatch->height-gpatch->topoffset)*pdup)/vid.height;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].s = v[3].s = 0.0f;
v[2].s = v[1].s = hwrPatch->max_s;
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = hwrPatch->max_t;
flags = PF_Translucent|PF_NoDepthTest;
// clip it since it is used for bunny scroll in doom I
HWD.pfnDrawPolygon(NULL, v, 4, flags);
}
void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap)
{
FOutVector v[4];
@ -707,6 +646,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 +659,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
{
Surf.PolyColor.rgba = UINT2RGBA(0x01010160);
Surf.PolyColor.s.alpha = (strength*8);
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 +879,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);
@ -960,136 +943,6 @@ void HWR_DrawTutorialBack(UINT32 color, INT32 boxheight)
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
}
// ==========================================================================
// R_DRAW.C STUFF
// ==========================================================================
// ------------------
// HWR_DrawViewBorder
// Fill the space around the view window with a Doom flat texture, draw the
// beveled edges.
// 'clearlines' is useful to clear the heads up messages, when the view
// window is reduced, it doesn't refresh all the view borders.
// ------------------
void HWR_DrawViewBorder(INT32 clearlines)
{
INT32 x, y;
INT32 top, side;
INT32 baseviewwidth, baseviewheight;
INT32 basewindowx, basewindowy;
patch_t *patch;
// if (gl_viewwidth == vid.width)
// return;
if (!clearlines)
clearlines = BASEVIDHEIGHT; // refresh all
// calc view size based on original game resolution
baseviewwidth = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewwidth), vid.fdup)); //(cv_viewsize.value * BASEVIDWIDTH/10)&~7;
baseviewheight = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewheight), vid.fdup));
top = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_baseviewwindowy), vid.fdup));
side = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewwindowx), vid.fdup));
// top
HWR_DrawFlatFill(0, 0,
BASEVIDWIDTH, (top < clearlines ? top : clearlines),
st_borderpatchnum);
// left
if (top < clearlines)
HWR_DrawFlatFill(0, top, side,
(clearlines-top < baseviewheight ? clearlines-top : baseviewheight),
st_borderpatchnum);
// right
if (top < clearlines)
HWR_DrawFlatFill(side + baseviewwidth, top, side,
(clearlines-top < baseviewheight ? clearlines-top : baseviewheight),
st_borderpatchnum);
// bottom
if (top + baseviewheight < clearlines)
HWR_DrawFlatFill(0, top + baseviewheight,
BASEVIDWIDTH, BASEVIDHEIGHT, st_borderpatchnum);
//
// draw the view borders
//
basewindowx = (BASEVIDWIDTH - baseviewwidth)>>1;
if (baseviewwidth == BASEVIDWIDTH)
basewindowy = 0;
else
basewindowy = top;
// top edge
if (clearlines > basewindowy - 8)
{
patch = W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH);
for (x = 0; x < baseviewwidth; x += 8)
HWR_DrawPatch(patch, basewindowx + x, basewindowy - 8,
0);
}
// bottom edge
if (clearlines > basewindowy + baseviewheight)
{
patch = W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH);
for (x = 0; x < baseviewwidth; x += 8)
HWR_DrawPatch(patch, basewindowx + x,
basewindowy + baseviewheight, 0);
}
// left edge
if (clearlines > basewindowy)
{
patch = W_CachePatchNum(viewborderlump[BRDR_L], PU_PATCH);
for (y = 0; y < baseviewheight && basewindowy + y < clearlines;
y += 8)
{
HWR_DrawPatch(patch, basewindowx - 8, basewindowy + y,
0);
}
}
// right edge
if (clearlines > basewindowy)
{
patch = W_CachePatchNum(viewborderlump[BRDR_R], PU_PATCH);
for (y = 0; y < baseviewheight && basewindowy+y < clearlines;
y += 8)
{
HWR_DrawPatch(patch, basewindowx + baseviewwidth,
basewindowy + y, 0);
}
}
// Draw beveled corners.
if (clearlines > basewindowy - 8)
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TL],
PU_PATCH),
basewindowx - 8, basewindowy - 8, 0);
if (clearlines > basewindowy - 8)
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TR],
PU_PATCH),
basewindowx + baseviewwidth, basewindowy - 8, 0);
if (clearlines > basewindowy+baseviewheight)
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BL],
PU_PATCH),
basewindowx - 8, basewindowy + baseviewheight, 0);
if (clearlines > basewindowy + baseviewheight)
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BR],
PU_PATCH),
basewindowx + baseviewwidth,
basewindowy + baseviewheight, 0);
}
// ==========================================================================
// AM_MAP.C DRAWING STUFF
// ==========================================================================
@ -1102,8 +955,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 +1142,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 +1229,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 +1306,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)
{
@ -1499,7 +1354,7 @@ static inline boolean saveTGA(const char *file_name, void *buffer,
INT32 i;
UINT8 *buf8 = buffer;
fd = open(file_name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
fd = open(file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd < 0)
return false;
@ -1539,11 +1394,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 +1407,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 +1416,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);

View file

@ -29,10 +29,7 @@ EXPORT boolean HWRAPI(Init) (void);
#ifndef HAVE_SDL
EXPORT void HWRAPI(Shutdown) (void);
#endif
#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 +40,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 +53,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 +83,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 +94,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 +110,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;

View file

@ -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);
@ -117,7 +119,6 @@ patch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum);
void HWR_GetPatch(patch_t *patch);
void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap);
void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
patch_t *HWR_GetPic(lumpnum_t lumpnum);
GLMapTexture_t *HWR_GetTexture(INT32 tex);
void HWR_GetLevelFlat(levelflat_t *levelflat);
@ -131,6 +132,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 +144,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_

View file

@ -1055,7 +1055,7 @@ void HWR_DoCoronasLighting(FOutVector *outVerts, gl_vissprite_t *spr)
light[3].y = cy+size*1.33f+p_lspr->light_yoffset;
light[3].s = 0.0f; light[3].t = 1.0f;
HWR_GetPic(coronalumpnum); /// \todo use different coronas
// HWR_GetPic(coronalumpnum); /// \todo use different coronas
HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_Additive | PF_Corona | PF_NoDepthTest);
}
@ -1071,7 +1071,7 @@ void HWR_DrawCoronas(void)
if (!cv_glcoronas.value || dynlights->nb <= 0 || coronalumpnum == LUMPERROR)
return;
HWR_GetPic(coronalumpnum); /// \todo use different coronas
// HWR_GetPic(coronalumpnum); /// \todo use different coronas
for (j = 0;j < dynlights->nb;j++)
{
FOutVector light[4];

File diff suppressed because it is too large Load diff

View file

@ -35,11 +35,8 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player);
void HWR_RenderPlayerView(INT32 viewnumber, player_t *player);
void HWR_ClearSkyDome(void);
void HWR_BuildSkyDome(void);
void HWR_DrawViewBorder(INT32 clearlines);
void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum);
void HWR_InitTextureMapping(void);
void HWR_SetViewSize(void);
void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option);
void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap);
void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h);
void HWR_MakePatch(const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap);
@ -48,7 +45,6 @@ void HWR_CreateStaticLightmaps(INT32 bspnum);
void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color);
void HWR_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT16 actualcolor, UINT8 strength);
void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT32 actualcolor); // Lat: separate flags from color since color needs to be an uint to work right.
void HWR_DrawPic(INT32 x,INT32 y,lumpnum_t lumpnum);
UINT8 *HWR_GetScreenshot(void);
boolean HWR_Screenshot(const char *pathname);
@ -61,11 +57,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 +70,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,21 +93,17 @@ 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;
extern float gl_viewwidth, gl_viewheight, gl_baseviewwindowy;
extern float gl_viewwindowx, gl_basewindowcentery;
// BP: big hack for a test in lighting ref : 1249753487AB
extern fixed_t *hwbbox;
extern FTransform atransform;
extern float gl_viewsin, gl_viewcos;
// Render stats
extern ps_metric_t ps_hw_skyboxtime;
extern ps_metric_t ps_hw_nodesorttime;

View file

@ -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,13 +410,19 @@ static void md2_loadTexture(md2_t *model)
grPatch->mipmap->width = (UINT16)w;
grPatch->mipmap->height = (UINT16)h;
// Lactozilla: Apply colour cube
image = grPatch->mipmap->data;
size = w*h;
while (size--)
// for palette rendering, color cube is applied in post-processing instead of here
if (!HWR_ShouldUsePaletteRendering())
{
V_CubeApply(&image->s.red, &image->s.green, &image->s.blue);
image++;
UINT32 size;
RGBA_t *image;
// Lactozilla: Apply colour cube
image = grPatch->mipmap->data;
size = w*h;
while (size--)
{
V_CubeApply(&image->s.red, &image->s.green, &image->s.blue);
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
View 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
View 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

View file

@ -46,6 +46,7 @@
#define _CREATE_DLL_ // necessary for Unix AND Windows
#include "../../doomdef.h"
#include "../hw_drv.h"
#include "../../z_zone.h"
// ==========================================================================
// DEFINITIONS

View file

@ -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.
@ -2044,76 +2044,6 @@ void HU_Drawer(void)
}
}
//======================================================================
// HUD MESSAGES CLEARING FROM SCREEN
//======================================================================
// Clear old messages from the borders around the view window
// (only for reduced view, refresh the borders when needed)
//
// startline: y coord to start clear,
// clearlines: how many lines to clear.
//
static INT32 oldclearlines;
void HU_Erase(void)
{
INT32 topline, bottomline;
INT32 y, yoffset;
#ifdef HWRENDER
// clear hud msgs on double buffer (OpenGL mode)
boolean secondframe;
static INT32 secondframelines;
#endif
if (con_clearlines == oldclearlines && !con_hudupdate && !chat_on)
return;
#ifdef HWRENDER
// clear the other frame in double-buffer modes
secondframe = (con_clearlines != oldclearlines);
if (secondframe)
secondframelines = oldclearlines;
#endif
// clear the message lines that go away, so use _oldclearlines_
bottomline = oldclearlines;
oldclearlines = con_clearlines;
if (chat_on && OLDCHAT)
if (bottomline < 8)
bottomline = 8; // only do it for consolechat. consolechat is gay.
if (automapactive || viewwindowx == 0) // hud msgs don't need to be cleared
return;
// software mode copies view border pattern & beveled edges from the backbuffer
if (rendermode == render_soft)
{
topline = 0;
for (y = topline, yoffset = y*vid.width; y < bottomline; y++, yoffset += vid.width)
{
if (y < viewwindowy || y >= viewwindowy + viewheight)
R_VideoErase(yoffset, vid.width); // erase entire line
else
{
R_VideoErase(yoffset, viewwindowx); // erase left border
// erase right border
R_VideoErase(yoffset + viewwindowx + viewwidth, viewwindowx);
}
}
con_hudupdate = false; // if it was set..
}
#ifdef HWRENDER
else if (rendermode != render_none)
{
// refresh just what is needed from the view borders
HWR_DrawViewBorder(secondframelines);
con_hudupdate = secondframe;
}
#endif
}
//======================================================================
// IN-LEVEL MULTIPLAYER RANKINGS
//======================================================================

View file

@ -111,7 +111,6 @@ boolean HU_Responder(event_t *ev);
void HU_Ticker(void);
void HU_Drawer(void);
char HU_dequeueChatChar(void);
void HU_Erase(void);
void HU_clearChatChars(void);
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, boolean notext, INT32 flags); // Lat': Ping drawer for scoreboard.
void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);

View file

@ -40,10 +40,6 @@ extern rendermode_t rendermode;
*/
extern rendermode_t chosenrendermode;
/** \brief use highcolor modes if true
*/
extern boolean highcolor;
/** \brief setup video mode
*/
void I_StartupGraphics(void);
@ -108,8 +104,8 @@ void VID_CheckGLLoaded(rendermode_t oldrender);
\return name of video mode
*/
const char *VID_GetModeName(INT32 modenum);
void VID_PrepareModeList(void); /// note hack for SDL
void VID_PrepareModeList(void);
/** \brief can video system do fullscreen
*/

View file

@ -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);

View file

@ -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;
}

View file

@ -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
};
@ -4098,53 +4099,6 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines)
{
// Solid color textbox.
V_DrawFill(x+5, y+5, width*8+6, boxlines*8+6, 159);
//V_DrawFill(x+8, y+8, width*8, boxlines*8, 31);
/*
patch_t *p;
INT32 cx, cy, n;
INT32 step, boff;
step = 8;
boff = 8;
// draw left side
cx = x;
cy = y;
V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TL], PU_PATCH));
cy += boff;
p = W_CachePatchNum(viewborderlump[BRDR_L], PU_PATCH);
for (n = 0; n < boxlines; n++)
{
V_DrawScaledPatch(cx, cy, 0, p);
cy += step;
}
V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BL], PU_PATCH));
// draw middle
V_DrawFlatFill(x + boff, y + boff, width*step, boxlines*step, st_borderpatchnum);
cx += boff;
cy = y;
while (width > 0)
{
V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH));
V_DrawScaledPatch(cx, y + boff + boxlines*step, 0, W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH));
width--;
cx += step;
}
// draw right side
cy = y;
V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TR], PU_PATCH));
cy += boff;
p = W_CachePatchNum(viewborderlump[BRDR_R], PU_PATCH);
for (n = 0; n < boxlines; n++)
{
V_DrawScaledPatch(cx, cy, 0, p);
cy += step;
}
V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BR], PU_PATCH));
*/
}
//
@ -13672,23 +13626,14 @@ static void M_VideoModeMenu(INT32 choice)
memset(modedescs, 0, sizeof(modedescs));
#if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL)
VID_PrepareModeList(); // FIXME: hack
#endif
vidm_nummodes = 0;
vidm_selected = 0;
nummodes = VID_NumModes();
#ifdef _WINDOWS
// clean that later: skip windowed mode 0, video modes menu only shows FULL SCREEN modes
if (nummodes <= NUMSPECIALMODES)
i = 0; // unless we have nothing
else
i = NUMSPECIALMODES;
#else
// DOS does not skip mode 0, because mode 0 is ALWAYS present
i = 0;
#endif
for (; i < nummodes && vidm_nummodes < MAXMODEDESCS; i++)
{
desc = VID_GetModeName(i);

View file

@ -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)

View file

@ -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);
}

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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);
}
@ -1267,7 +1268,8 @@ 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);
P_FaceStabFlume(actor);
if (!P_MobjWasRemoved(actor))
P_FaceStabFlume(actor);
}
}
}
@ -1333,8 +1335,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;
@ -1343,6 +1346,20 @@ void A_FaceStabHurl(mobj_t *actor)
P_SetScale(hwork, hwork->destscale);
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;
}
@ -1359,11 +1376,14 @@ void A_FaceStabHurl(mobj_t *actor)
#undef NUMGRADS
#undef NUMSTEPS
}
if (P_MobjWasRemoved(actor))
return;
}
}
P_SetMobjState(actor, locvar2);
actor->reactiontime = actor->info->reactiontime;
if (!P_MobjWasRemoved(actor))
actor->reactiontime = actor->info->reactiontime;
}
// Function: A_FaceStabMiss
@ -1393,6 +1413,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);
}
@ -1425,6 +1447,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);
@ -1520,7 +1544,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);
}
@ -1941,14 +1965,15 @@ 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);
S_StartSound(actor, actor->info->attacksound);
if (!P_MobjWasRemoved(actor))
S_StartSound(actor, actor->info->attacksound);
}
}
@ -2034,6 +2059,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);
@ -2215,6 +2242,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);
@ -2223,6 +2252,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)))
{
@ -2648,7 +2679,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);
}
@ -5788,7 +5819,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.
@ -5796,6 +5831,8 @@ void A_MinusDigging(mobj_t *actor)
if (P_MobjWasRemoved(par))
return;
P_SetMobjState(par, actor->info->raisestate);
if (P_MobjWasRemoved(par))
return;
P_SetScale(par, actor->scale*2);
if (actor->eflags & MFE_VERTICALFLIP)
par->eflags |= MFE_VERTICALFLIP;
@ -5809,6 +5846,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)
@ -5832,7 +5871,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);
}
}
@ -7304,7 +7343,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.
@ -7661,7 +7700,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);
}
}
@ -8119,6 +8158,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)
@ -8135,6 +8176,8 @@ void A_GuardChase(mobj_t *actor)
break;
}
}
if (P_MobjWasRemoved(actor))
return;
if (actor->extravalue1 < actor->info->speed)
actor->extravalue1++;
@ -8171,7 +8214,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.
}
}
@ -8641,6 +8688,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);
}
@ -11735,7 +11785,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)
@ -13314,6 +13370,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;
@ -13856,6 +13914,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.
@ -14260,6 +14320,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.
@ -14281,6 +14343,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
@ -14424,6 +14488,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)

View file

@ -1397,11 +1397,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
i = 0;
for (; special->type == MT_HOOP; special = special->hnext)
{
special->fuse = 11;
special->movedir = i;
special->extravalue1 = special->target->extravalue1;
special->extravalue2 = special->target->extravalue2;
special->target->threshold = 4242;
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.

View file

@ -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);
}

View file

@ -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,12 +2331,15 @@ 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->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))
|| (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))
return true;
return false;
@ -3914,6 +3919,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);
@ -4708,6 +4715,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;
}
@ -4945,6 +4954,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);
@ -5514,6 +5525,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))
{
@ -5862,6 +5875,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);
@ -5902,6 +5917,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);
@ -7501,6 +7518,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;
@ -8064,7 +8083,8 @@ static void P_MobjSceneryThink(mobj_t *mobj)
break;
}
P_SceneryThinker(mobj);
if (!P_MobjWasRemoved(mobj))
P_SceneryThinker(mobj);
}
static boolean P_MobjPushableThink(mobj_t *mobj)
@ -10294,6 +10314,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);
@ -10424,6 +10446,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);
}
@ -10525,6 +10549,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)
{
@ -10867,9 +10893,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.
@ -10879,6 +10902,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++;
@ -14027,7 +14053,8 @@ boolean P_CheckMissileSpawn(mobj_t *th)
if (!P_TryMove(th, th->x, th->y, true))
{
P_ExplodeMissile(th);
if (!P_MobjWasRemoved(th))
P_ExplodeMissile(th);
return false;
}
return true;

View file

@ -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();

View file

@ -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);

View file

@ -11105,7 +11105,8 @@ 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))
{
P_KillMobj(minecart, NULL, NULL, 0);
if (!P_MobjWasRemoved(minecart))
P_KillMobj(minecart, NULL, NULL, 0);
return;
}
@ -12459,7 +12460,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!
}
}

View file

@ -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
@ -50,10 +54,6 @@ lighttable_t *fadecolormap;
// for debugging/info purposes
size_t flatmemory, spritememory, texturememory;
// highcolor stuff
INT16 color8to16[256]; // remap color index to highcolor rgb value
INT16 *hicolormaps; // test a 32k colormap remaps high -> high
// Blends two pixels together, using the equation
// that matches the specified alpha style.
UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha)
@ -426,6 +426,9 @@ void R_ClearColormaps(void)
{
// Purged by PU_LEVEL, just overwrite the pointer
extra_colormaps = R_CreateDefaultColormap(true);
#ifdef HWRENDER
HWR_ClearLightTables();
#endif
}
//
@ -1170,40 +1173,6 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap)
}
#endif
//
// build a table for quick conversion from 8bpp to 15bpp
//
//
// added "static inline" keywords, linking with the debug version
// of allegro, it have a makecol15 function of it's own, now
// with "static inline" keywords,it sloves this problem ;)
//
FUNCMATH static inline int makecol15(int r, int g, int b)
{
return (((r >> 3) << 10) | ((g >> 3) << 5) | ((b >> 3)));
}
static void R_Init8to16(void)
{
UINT8 *palette;
int i;
palette = W_CacheLumpName("PLAYPAL",PU_CACHE);
for (i = 0; i < 256; i++)
{
// PLAYPAL uses 8 bit values
color8to16[i] = (INT16)makecol15(palette[0], palette[1], palette[2]);
palette += 3;
}
// test a big colormap
hicolormaps = Z_Malloc(16384*sizeof(*hicolormaps), PU_STATIC, NULL);
for (i = 0; i < 16384; i++)
hicolormaps[i] = (INT16)(i<<1);
}
//
// R_InitData
//
@ -1212,12 +1181,6 @@ static void R_Init8to16(void)
//
void R_InitData(void)
{
if (highcolor)
{
CONS_Printf("InitHighColor...\n");
R_Init8to16();
}
CONS_Printf("R_LoadParsedTranslations()...\n");
R_LoadParsedTranslations();

View file

@ -36,9 +36,6 @@ UINT8 ASTBlendPaletteIndexes(UINT8 background, UINT8 foreground, int style, UINT
extern INT32 ASTTextureBlendingThreshold[2];
extern INT16 color8to16[256]; // remap color index to highcolor
extern INT16 *hicolormaps; // remap high colors to high colors..
extern CV_PossibleValue_t Color_cons_t[];
// I/O, setting up the stuff.

View file

@ -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
@ -840,15 +849,6 @@ typedef struct drawseg_s
vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes
} drawseg_t;
typedef enum
{
PALETTE = 0, // 1 byte is the index in the doom palette (as usual)
INTENSITY = 1, // 1 byte intensity
INTENSITY_ALPHA = 2, // 2 byte: alpha then intensity
RGB24 = 3, // 24 bit rgb
RGBA32 = 4, // 32 bit rgba
} pic_mode_t;
#ifdef ROTSPRITE
typedef struct
{

View file

@ -40,23 +40,6 @@
*/
INT32 viewwidth, scaledviewwidth, viewheight, viewwindowx, viewwindowy;
/** \brief pointer to the start of each line of the screen,
*/
UINT8 *ylookup[MAXVIDHEIGHT*4];
/** \brief pointer to the start of each line of the screen, for view1 (splitscreen)
*/
UINT8 *ylookup1[MAXVIDHEIGHT*4];
/** \brief pointer to the start of each line of the screen, for view2 (splitscreen)
*/
UINT8 *ylookup2[MAXVIDHEIGHT*4];
/** \brief x byte offset for columns inside the viewwindow,
so the first column starts at (SCRWIDTH - VIEWWIDTH)/2
*/
INT32 columnofs[MAXVIDWIDTH*4];
UINT8 *topleft;
// =========================================================================
@ -67,8 +50,6 @@ lighttable_t *dc_colormap;
INT32 dc_x = 0, dc_yl = 0, dc_yh = 0;
fixed_t dc_iscale, dc_texturemid;
UINT8 dc_hires; // under MSVC boolean is a byte, while on other systems, it a bit,
// soo lets make it a byte on all system for the ASM code
UINT8 *dc_source;
// -----------------------
@ -677,7 +658,7 @@ UINT16 R_GetSuperColorByName(const char *name)
void R_InitViewBuffer(INT32 width, INT32 height)
{
INT32 i, bytesperpixel = vid.bpp;
INT32 bytesperpixel = vid.bpp;
if (width > MAXVIDWIDTH)
width = MAXVIDWIDTH;
@ -689,118 +670,13 @@ void R_InitViewBuffer(INT32 width, INT32 height)
// Handle resize, e.g. smaller view windows with border and/or status bar.
viewwindowx = (vid.width - width) >> 1;
// Column offset for those columns of the view window, but relative to the entire screen
for (i = 0; i < width; i++)
columnofs[i] = (viewwindowx + i) * bytesperpixel;
// Same with base row offset.
if (width == vid.width)
viewwindowy = 0;
else
viewwindowy = (vid.height - height) >> 1;
// Precalculate all row offsets.
for (i = 0; i < height; i++)
{
ylookup[i] = ylookup1[i] = screens[0] + (i+viewwindowy)*vid.width*bytesperpixel;
ylookup2[i] = screens[0] + (i+(vid.height>>1))*vid.width*bytesperpixel; // for splitscreen
}
}
/** \brief viewborder patches lump numbers
*/
lumpnum_t viewborderlump[8];
/** \brief Store the lumpnumber of the viewborder patches
*/
void R_InitViewBorder(void)
{
viewborderlump[BRDR_T] = W_GetNumForName("brdr_t");
viewborderlump[BRDR_B] = W_GetNumForName("brdr_b");
viewborderlump[BRDR_L] = W_GetNumForName("brdr_l");
viewborderlump[BRDR_R] = W_GetNumForName("brdr_r");
viewborderlump[BRDR_TL] = W_GetNumForName("brdr_tl");
viewborderlump[BRDR_BL] = W_GetNumForName("brdr_bl");
viewborderlump[BRDR_TR] = W_GetNumForName("brdr_tr");
viewborderlump[BRDR_BR] = W_GetNumForName("brdr_br");
}
#if 0
/** \brief R_FillBackScreen
Fills the back screen with a pattern for variable screen sizes
Also draws a beveled edge.
*/
void R_FillBackScreen(void)
{
UINT8 *src, *dest;
patch_t *patch;
INT32 x, y, step, boff;
// quickfix, don't cache lumps in both modes
if (rendermode != render_soft)
return;
// draw pattern around the status bar too (when hires),
// so return only when in full-screen without status bar.
if (scaledviewwidth == vid.width && viewheight == vid.height)
return;
src = scr_borderpatch;
dest = screens[1];
for (y = 0; y < vid.height; y++)
{
for (x = 0; x < vid.width/128; x++)
{
M_Memcpy (dest, src+((y&127)<<7), 128);
dest += 128;
}
if (vid.width&127)
{
M_Memcpy(dest, src+((y&127)<<7), vid.width&127);
dest += (vid.width&127);
}
}
// don't draw the borders when viewwidth is full vid.width.
if (scaledviewwidth == vid.width)
return;
step = 8;
boff = 8;
patch = W_CacheLumpNum(viewborderlump[BRDR_T], PU_CACHE);
for (x = 0; x < scaledviewwidth; x += step)
V_DrawPatch(viewwindowx + x, viewwindowy - boff, 1, patch);
patch = W_CacheLumpNum(viewborderlump[BRDR_B], PU_CACHE);
for (x = 0; x < scaledviewwidth; x += step)
V_DrawPatch(viewwindowx + x, viewwindowy + viewheight, 1, patch);
patch = W_CacheLumpNum(viewborderlump[BRDR_L], PU_CACHE);
for (y = 0; y < viewheight; y += step)
V_DrawPatch(viewwindowx - boff, viewwindowy + y, 1, patch);
patch = W_CacheLumpNum(viewborderlump[BRDR_R],PU_CACHE);
for (y = 0; y < viewheight; y += step)
V_DrawPatch(viewwindowx + scaledviewwidth, viewwindowy + y, 1,
patch);
// Draw beveled corners.
V_DrawPatch(viewwindowx - boff, viewwindowy - boff, 1,
W_CacheLumpNum(viewborderlump[BRDR_TL], PU_CACHE));
V_DrawPatch(viewwindowx + scaledviewwidth, viewwindowy - boff, 1,
W_CacheLumpNum(viewborderlump[BRDR_TR], PU_CACHE));
V_DrawPatch(viewwindowx - boff, viewwindowy + viewheight, 1,
W_CacheLumpNum(viewborderlump[BRDR_BL], PU_CACHE));
V_DrawPatch(viewwindowx + scaledviewwidth, viewwindowy + viewheight, 1,
W_CacheLumpNum(viewborderlump[BRDR_BR], PU_CACHE));
}
#endif
/** \brief The R_VideoErase function
Copy a screen buffer.
@ -822,55 +698,6 @@ void R_VideoErase(size_t ofs, INT32 count)
M_Memcpy(screens[0] + ofs, screens[1] + ofs, count);
}
#if 0
/** \brief The R_DrawViewBorder
Draws the border around the view
for different size windows?
*/
void R_DrawViewBorder(void)
{
INT32 top, side, ofs;
if (rendermode == render_none)
return;
#ifdef HWRENDER
if (rendermode != render_soft)
{
HWR_DrawViewBorder(0);
return;
}
else
#endif
#ifdef DEBUG
fprintf(stderr,"RDVB: vidwidth %d vidheight %d scaledviewwidth %d viewheight %d\n",
vid.width, vid.height, scaledviewwidth, viewheight);
#endif
if (scaledviewwidth == vid.width)
return;
top = (vid.height - viewheight)>>1;
side = (vid.width - scaledviewwidth)>>1;
// copy top and one line of left side
R_VideoErase(0, top*vid.width+side);
// copy one line of right side and bottom
ofs = (viewheight+top)*vid.width - side;
R_VideoErase(ofs, top*vid.width + side);
// copy sides using wraparound
ofs = top*vid.width + vid.width-side;
side <<= 1;
// simpler using our VID_Blit routine
VID_BlitLinearScreen(screens[1] + ofs, screens[0] + ofs, side, viewheight - 1,
vid.width, vid.width);
}
#endif
// R_CalcTiltedLighting
// Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly.
static INT32 tiltlighting[MAXVIDWIDTH];
@ -912,11 +739,3 @@ static void R_CalcSlopeLight(void)
#include "r_draw8.c"
#include "r_draw8_npo2.c"
// ==========================================================================
// INCLUDE 16bpp DRAWING CODE HERE
// ==========================================================================
#ifdef HIGHCOLOR
#include "r_draw16.c"
#endif

View file

@ -19,10 +19,6 @@
// -------------------------------
// COMMON STUFF FOR 8bpp AND 16bpp
// -------------------------------
extern UINT8 *ylookup[MAXVIDHEIGHT*4];
extern UINT8 *ylookup1[MAXVIDHEIGHT*4];
extern UINT8 *ylookup2[MAXVIDHEIGHT*4];
extern INT32 columnofs[MAXVIDWIDTH*4];
extern UINT8 *topleft;
// -------------------------
@ -32,7 +28,6 @@ extern UINT8 *topleft;
extern lighttable_t *dc_colormap;
extern INT32 dc_x, dc_yl, dc_yh;
extern fixed_t dc_iscale, dc_texturemid;
extern UINT8 dc_hires;
extern UINT8 *dc_source; // first pixel in a column
@ -77,25 +72,6 @@ extern UINT32 nflatyshift;
extern UINT32 nflatshiftup;
extern UINT32 nflatmask;
/// \brief Top border
#define BRDR_T 0
/// \brief Bottom border
#define BRDR_B 1
/// \brief Left border
#define BRDR_L 2
/// \brief Right border
#define BRDR_R 3
/// \brief Topleft border
#define BRDR_TL 4
/// \brief Topright border
#define BRDR_TR 5
/// \brief Bottomleft border
#define BRDR_BL 6
/// \brief Bottomright border
#define BRDR_BR 7
extern lumpnum_t viewborderlump[8];
// ------------------------------------------------
// r_draw.c COMMON ROUTINES FOR BOTH 8bpp and 16bpp
// ------------------------------------------------
@ -169,17 +145,8 @@ boolean R_BlendLevelVisible(INT32 blendmode, INT32 alphalevel);
extern boolean skincolor_modified[];
void R_InitViewBuffer(INT32 width, INT32 height);
void R_InitViewBorder(void);
void R_VideoErase(size_t ofs, INT32 count);
// Rendering function.
#if 0
void R_FillBackScreen(void);
// If the view size is not full screen, draws a border around it.
void R_DrawViewBorder(void);
#endif
#define TRANSPARENTPIXEL 255
// -----------------
@ -240,17 +207,5 @@ void R_DrawTiltedTransSolidColorSpan_8(void);
void R_DrawWaterSolidColorSpan_8(void);
void R_DrawTiltedWaterSolidColorSpan_8(void);
// ------------------
// 16bpp DRAWING CODE
// ------------------
#ifdef HIGHCOLOR
void R_DrawColumn_16(void);
void R_DrawWallColumn_16(void);
void R_DrawTranslucentColumn_16(void);
void R_DrawTranslatedColumn_16(void);
void R_DrawSpan_16(void);
#endif
// =========================================================================
#endif // __R_DRAW__

View file

@ -1,214 +0,0 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 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 r_draw16.c
/// \brief 16bpp (HIGHCOLOR) span/column drawer functions
/// \note no includes because this is included as part of r_draw.c
// ==========================================================================
// COLUMNS
// ==========================================================================
/// \brief kick out the upper bit of each component (we're in 5 : 5 : 5)
#define HIMASK1 0x7bde
/** \brief The R_DrawColumn_16 function
standard upto 128high posts column drawer
*/
void R_DrawColumn_16(void)
{
INT32 count;
INT16 *dest;
fixed_t frac, fracstep;
count = dc_yh - dc_yl + 1;
// Zero length, column does not exceed a pixel.
if (count <= 0)
return;
#ifdef RANGECHECK
if (dc_x >= vid.width || dc_yl < 0 || dc_yh >= vid.height)
I_Error("R_DrawColumn_16: %d to %d at %d", dc_yl, dc_yh, dc_x);
#endif
// Framebuffer destination address.
// Use ylookup LUT to avoid multiply with ScreenWidth.
// Use columnofs LUT for subwindows?
dest = (INT16 *)(void *)(ylookup[dc_yl] + columnofs[dc_x]);
// Determine scaling, which is the only mapping to be done.
fracstep = dc_iscale;
frac = dc_texturemid + (dc_yl - centery)*fracstep;
// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
// This is as fast as it gets.
do
{
// Re-map color indices from wall texture column using a lighting/special effects LUT.
*dest = hicolormaps[((INT16 *)(void *)dc_source)[(frac>>FRACBITS)&127]>>1];
dest += vid.width;
frac += fracstep;
} while (--count);
}
/** \brief The R_DrawWallColumn_16 function
LAME cutnpaste: same as R_DrawColumn_16 but wraps around 256
instead of 128 for the tall sky textures (256x240)
*/
void R_DrawWallColumn_16(void)
{
INT32 count;
INT16 *dest;
fixed_t frac, fracstep;
count = dc_yh - dc_yl + 1;
// Zero length, column does not exceed a pixel.
if (count <= 0)
return;
#ifdef RANGECHECK
if (dc_x >= vid.width || dc_yl < 0 || dc_yh >= vid.height)
I_Error("R_DrawWallColumn_16: %d to %d at %d", dc_yl, dc_yh, dc_x);
#endif
dest = (INT16 *)(void *)(ylookup[dc_yl] + columnofs[dc_x]);
fracstep = dc_iscale;
frac = dc_texturemid + (dc_yl - centery)*fracstep;
do
{
*dest = hicolormaps[((INT16 *)(void *)dc_source)[(frac>>FRACBITS)&255]>>1];
dest += vid.width;
frac += fracstep;
} while (--count);
}
/** \brief The R_DrawTranslucentColumn_16 function
LAME cutnpaste: same as R_DrawColumn_16 but does
translucent
*/
void R_DrawTranslucentColumn_16(void)
{
INT32 count;
INT16 *dest;
fixed_t frac, fracstep;
// check out coords for src*
if ((dc_yl < 0) || (dc_x >= vid.width))
return;
count = dc_yh - dc_yl;
if (count < 0)
return;
#ifdef RANGECHECK
if (dc_x >= vid.width || dc_yl < 0 || dc_yh >= vid.height)
I_Error("R_DrawTranslucentColumn_16: %d to %d at %d", dc_yl, dc_yh, dc_x);
#endif
// FIXME. As above.
dest = (INT16 *)(void *)(ylookup[dc_yl] + columnofs[dc_x]);
// Looks familiar.
fracstep = dc_iscale;
frac = dc_texturemid + (dc_yl - centery)*fracstep;
// Here we do an additional index re-mapping.
do
{
*dest = (INT16)((INT16)((color8to16[dc_source[frac>>FRACBITS]]>>1) & 0x39ce)
+ (INT16)(((*dest & HIMASK1)) & 0x7fff));
dest += vid.width;
frac += fracstep;
} while (count--);
}
/** \brief The R_DrawTranslatedColumn_16 function
?
*/
void R_DrawTranslatedColumn_16(void)
{
INT32 count;
INT16 *dest;
fixed_t frac, fracstep;
count = dc_yh - dc_yl;
if (count < 0)
return;
#ifdef RANGECHECK
if (dc_x >= vid.width || dc_yl < 0 || dc_yh >= vid.height)
I_Error("R_DrawTranslatedColumn_16: %d to %d at %d", dc_yl, dc_yh, dc_x);
#endif
dest = (INT16 *)(void *)(ylookup[dc_yl] + columnofs[dc_x]);
// Looks familiar.
fracstep = dc_iscale;
frac = dc_texturemid + (dc_yl - centery)*fracstep;
// Here we do an additional index re-mapping.
do
{
*dest = color8to16[dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]];
dest += vid.width;
frac += fracstep;
} while (count--);
}
// ==========================================================================
// SPANS
// ==========================================================================
/** \brief The R_*_16 function
Draws the actual span.
*/
void R_DrawSpan_16(void)
{
fixed_t xfrac, yfrac;
INT16 *dest;
INT32 count, spot;
#ifdef RANGECHECK
if (ds_x2 < ds_x1 || ds_x1 < 0 || ds_x2 >= vid.width || ds_y > vid.height)
I_Error("R_DrawSpan_16: %d to %d at %d", ds_x1, ds_x2, ds_y);
#endif
xfrac = ds_xfrac;
yfrac = ds_yfrac;
dest = (INT16 *)(void *)(ylookup[ds_y] + columnofs[ds_x1]);
// We do not check for zero spans here?
count = ds_x2 - ds_x1;
if (count <= 0) // We do now!
return;
do
{
// Current texture index in u, v.
spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
// Lookup pixel from flat texture tile, re-index using light/colormap.
*dest++ = hicolormaps[((INT16 *)(void *)ds_source)[spot]>>1];
// Next step in u, v.
xfrac += ds_xstep;
yfrac += ds_ystep;
} while (count--);
}

View file

@ -40,18 +40,13 @@ void R_DrawColumn_8(void)
#endif
// Framebuffer destination address.
// Use ylookup LUT to avoid multiply with ScreenWidth.
// Use columnofs LUT for subwindows?
//dest = ylookup[dc_yl] + columnofs[dc_x];
dest = &topleft[dc_yl*vid.width + dc_x];
count++;
// Determine scaling, which is the only mapping to be done.
fracstep = dc_iscale;
//frac = dc_texturemid + (dc_yl - centery)*fracstep;
frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires);
frac = dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep);
// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
// This is as fast as it gets.
@ -127,14 +122,11 @@ void R_DrawShadeColumn_8(void)
I_Error("R_DrawShadeColumn_8: %d to %d at %d", dc_yl, dc_yh, dc_x);
#endif
// FIXME. As above.
//dest = ylookup[dc_yl] + columnofs[dc_x];
dest = &topleft[dc_yl*vid.width + dc_x];
// Looks familiar.
fracstep = dc_iscale;
//frac = dc_texturemid + (dc_yl - centery)*fracstep;
frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires);
frac = dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep);
// Here we do an additional index re-mapping.
do
@ -166,14 +158,11 @@ void R_DrawTranslucentColumn_8(void)
I_Error("R_DrawTranslucentColumn_8: %d to %d at %d", dc_yl, dc_yh, dc_x);
#endif
// FIXME. As above.
//dest = ylookup[dc_yl] + columnofs[dc_x];
dest = &topleft[dc_yl*vid.width + dc_x];
// Looks familiar.
fracstep = dc_iscale;
//frac = dc_texturemid + (dc_yl - centery)*fracstep;
frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires);
frac = dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep);
// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
// This is as fast as it gets.
@ -271,14 +260,11 @@ void R_DrawTranslatedTranslucentColumn_8(void)
if (count <= 0) // Zero length, column does not exceed a pixel.
return;
// FIXME. As above.
//dest = ylookup[dc_yl] + columnofs[dc_x];
dest = &topleft[dc_yl*vid.width + dc_x];
// Looks familiar.
fracstep = dc_iscale;
//frac = dc_texturemid + (dc_yl - centery)*fracstep;
frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires);
frac = dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep);
// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
// This is as fast as it gets.
@ -347,14 +333,11 @@ void R_DrawTranslatedColumn_8(void)
I_Error("R_DrawTranslatedColumn_8: %d to %d at %d", dc_yl, dc_yh, dc_x);
#endif
// FIXME. As above.
//dest = ylookup[dc_yl] + columnofs[dc_x];
dest = &topleft[dc_yl*vid.width + dc_x];
// Looks familiar.
fracstep = dc_iscale;
//frac = dc_texturemid + (dc_yl-centery)*fracstep;
frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires);
frac = dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep);
// Here we do an additional index re-mapping.
do
@ -410,7 +393,7 @@ void R_DrawSpan_8 (void)
source = ds_source;
colormap = ds_colormap;
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
if (dest+8 > deststop)
return;
@ -489,7 +472,7 @@ void R_DrawTiltedSpan_8(void)
R_CalcSlopeLight();
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
source = ds_source;
//colormap = ds_colormap;
@ -611,7 +594,7 @@ void R_DrawTiltedTranslucentSpan_8(void)
R_CalcSlopeLight();
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
source = ds_source;
//colormap = ds_colormap;
@ -733,7 +716,7 @@ void R_DrawTiltedWaterSpan_8(void)
R_CalcSlopeLight();
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1;
source = ds_source;
//colormap = ds_colormap;
@ -854,7 +837,7 @@ void R_DrawTiltedSplat_8(void)
R_CalcSlopeLight();
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
source = ds_source;
//colormap = ds_colormap;
@ -991,7 +974,7 @@ void R_DrawSplat_8 (void)
source = ds_source;
colormap = ds_colormap;
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
while (count >= 8)
{
@ -1111,7 +1094,7 @@ void R_DrawTranslucentSplat_8 (void)
source = ds_source;
colormap = ds_colormap;
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
while (count >= 8)
{
@ -1214,7 +1197,7 @@ void R_DrawFloorSprite_8 (void)
source = (UINT16 *)ds_source;
colormap = ds_colormap;
translation = ds_translation;
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
while (count >= 8)
{
@ -1325,7 +1308,7 @@ void R_DrawTranslucentFloorSprite_8 (void)
source = (UINT16 *)ds_source;
colormap = ds_colormap;
translation = ds_translation;
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
while (count >= 8)
{
@ -1420,7 +1403,7 @@ void R_DrawTiltedFloorSprite_8(void)
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
source = (UINT16 *)ds_source;
colormap = ds_colormap;
translation = ds_translation;
@ -1529,7 +1512,7 @@ void R_DrawTiltedTranslucentFloorSprite_8(void)
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
source = (UINT16 *)ds_source;
colormap = ds_colormap;
translation = ds_translation;
@ -1644,7 +1627,7 @@ void R_DrawTranslucentSpan_8 (void)
source = ds_source;
colormap = ds_colormap;
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
while (count >= 8)
{
@ -1721,7 +1704,7 @@ void R_DrawWaterSpan_8(void)
source = ds_source;
colormap = ds_colormap;
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1;
count = ds_x2 - ds_x1 + 1;
@ -1784,7 +1767,6 @@ void R_DrawFogSpan_8(void)
size_t count;
colormap = ds_colormap;
//dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y *vid.width + ds_x1];
count = ds_x2 - ds_x1 + 1;
@ -1814,7 +1796,7 @@ void R_DrawTiltedFogSpan_8(void)
{
int width = ds_x2 - ds_x1;
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
UINT8 *dest = &topleft[ds_y*vid.width + ds_x1];
R_CalcSlopeLight();
@ -1834,7 +1816,7 @@ void R_DrawSolidColorSpan_8(void)
size_t count = (ds_x2 - ds_x1 + 1);
UINT8 source = ds_colormap[ds_source[0]];
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
UINT8 *dest = &topleft[ds_y*vid.width + ds_x1];
memset(dest, source, count);
}
@ -1847,7 +1829,7 @@ void R_DrawTransSolidColorSpan_8(void)
size_t count = (ds_x2 - ds_x1 + 1);
UINT8 source = ds_colormap[ds_source[0]];
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
UINT8 *dest = &topleft[ds_y*vid.width + ds_x1];
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
@ -1866,7 +1848,7 @@ void R_DrawTiltedSolidColorSpan_8(void)
int width = ds_x2 - ds_x1;
UINT8 source = ds_source[0];
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
UINT8 *dest = &topleft[ds_y*vid.width + ds_x1];
R_CalcSlopeLight();
@ -1885,7 +1867,7 @@ void R_DrawTiltedTransSolidColorSpan_8(void)
int width = ds_x2 - ds_x1;
UINT8 source = ds_source[0];
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
UINT8 *dest = &topleft[ds_y*vid.width + ds_x1];
R_CalcSlopeLight();
@ -1904,7 +1886,7 @@ void R_DrawWaterSolidColorSpan_8(void)
{
UINT8 source = ds_source[0];
UINT8 *colormap = ds_colormap;
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
UINT8 *dest = &topleft[ds_y*vid.width + ds_x1];
UINT8 *dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1;
size_t count = (ds_x2 - ds_x1 + 1);
@ -1925,7 +1907,7 @@ void R_DrawTiltedWaterSolidColorSpan_8(void)
int width = ds_x2 - ds_x1;
UINT8 source = ds_source[0];
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
UINT8 *dest = &topleft[ds_y*vid.width + ds_x1];
UINT8 *dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1;
R_CalcSlopeLight();
@ -1957,9 +1939,6 @@ void R_DrawFogColumn_8(void)
#endif
// Framebuffer destination address.
// Use ylookup LUT to avoid multiply with ScreenWidth.
// Use columnofs LUT for subwindows?
//dest = ylookup[dc_yl] + columnofs[dc_x];
dest = &topleft[dc_yl*vid.width + dc_x];
// Determine scaling, which is the only mapping to be done.

View file

@ -46,7 +46,7 @@ void R_DrawSpan_NPO2_8 (void)
source = ds_source;
colormap = ds_colormap;
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
if (dest+8 > deststop)
return;
@ -120,7 +120,7 @@ void R_DrawTiltedSpan_NPO2_8(void)
R_CalcSlopeLight();
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
source = ds_source;
//colormap = ds_colormap;
@ -309,7 +309,7 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void)
R_CalcSlopeLight();
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
source = ds_source;
//colormap = ds_colormap;
@ -496,7 +496,7 @@ void R_DrawTiltedSplat_NPO2_8(void)
R_CalcSlopeLight();
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
source = ds_source;
//colormap = ds_colormap;
@ -690,7 +690,7 @@ void R_DrawSplat_NPO2_8 (void)
source = ds_source;
colormap = ds_colormap;
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
fixedwidth = ds_flatwidth << FRACBITS;
fixedheight = ds_flatheight << FRACBITS;
@ -758,7 +758,7 @@ void R_DrawTranslucentSplat_NPO2_8 (void)
source = ds_source;
colormap = ds_colormap;
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
fixedwidth = ds_flatwidth << FRACBITS;
fixedheight = ds_flatheight << FRACBITS;
@ -828,7 +828,7 @@ void R_DrawFloorSprite_NPO2_8 (void)
source = (UINT16 *)ds_source;
colormap = ds_colormap;
translation = ds_translation;
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
fixedwidth = ds_flatwidth << FRACBITS;
fixedheight = ds_flatheight << FRACBITS;
@ -898,7 +898,7 @@ void R_DrawTranslucentFloorSprite_NPO2_8 (void)
source = (UINT16 *)ds_source;
colormap = ds_colormap;
translation = ds_translation;
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
fixedwidth = ds_flatwidth << FRACBITS;
fixedheight = ds_flatheight << FRACBITS;
@ -971,7 +971,7 @@ void R_DrawTiltedFloorSprite_NPO2_8(void)
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
source = (UINT16 *)ds_source;
colormap = ds_colormap;
translation = ds_translation;
@ -1127,7 +1127,7 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void)
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
source = (UINT16 *)ds_source;
colormap = ds_colormap;
translation = ds_translation;
@ -1278,7 +1278,7 @@ void R_DrawTranslucentSpan_NPO2_8 (void)
source = ds_source;
colormap = ds_colormap;
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
fixedwidth = ds_flatwidth << FRACBITS;
fixedheight = ds_flatheight << FRACBITS;
@ -1342,7 +1342,7 @@ void R_DrawWaterSpan_NPO2_8(void)
source = ds_source;
colormap = ds_colormap;
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1;
fixedwidth = ds_flatwidth << FRACBITS;
@ -1414,7 +1414,7 @@ void R_DrawTiltedWaterSpan_NPO2_8(void)
R_CalcSlopeLight();
dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds_y*vid.width + ds_x1];
dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1;
source = ds_source;
//colormap = ds_colormap;

View file

@ -970,8 +970,6 @@ void R_Init(void)
//I_OutputMsg("\nR_InitData");
R_InitData();
//I_OutputMsg("\nR_InitViewBorder");
R_InitViewBorder();
R_SetViewSize(); // setsizeneeded is set true
// this is now done by SCR_Recalc() at the first mode set
@ -1332,7 +1330,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;

View file

@ -603,6 +603,9 @@ void R_DrawPlanes(void)
visplane_t *pl;
INT32 i;
if (!cv_renderfloors.value)
return;
R_UpdatePlaneRipple();
for (i = 0; i < MAXVISPLANES; i++, pl++)
@ -626,7 +629,7 @@ static void R_DrawSkyPlane(visplane_t *pl)
{
INT32 texture = texturetranslation[skytexture];
// Reset column drawer function (note: couldn't we just call walldrawerfunc directly?)
// Reset column drawer function (note: couldn't we just call colfuncs[BASEDRAWFUNC] directly?)
// (that is, unless we'll need to switch drawers in future for some reason)
colfunc = colfuncs[BASEDRAWFUNC];

View file

@ -447,7 +447,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;
@ -1014,6 +1014,12 @@ static void R_DrawFlippedWall(UINT8 *source, INT32 height)
R_DrawFlippedPost(source, (unsigned)height, colfunc);
}
static void R_DrawNoWall(UINT8 *source, INT32 height)
{
(void)source;
(void)height;
}
static void R_RenderSegLoop (void)
{
angle_t angle;
@ -1060,6 +1066,13 @@ static void R_RenderSegLoop (void)
drawbottom = R_DrawFlippedWall;
}
if (!cv_renderwalls.value)
{
drawtop = R_DrawNoWall;
drawmiddle = R_DrawNoWall;
drawbottom = R_DrawNoWall;
}
if (midtexture)
R_CheckTextureCache(midtexture);
if (toptexture)

View file

@ -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;
}

View file

@ -951,7 +951,6 @@ static void R_DrawVisSprite(vissprite_t *vis)
}
colfunc = colfuncs[BASEDRAWFUNC];
dc_hires = 0;
vis->x1 = x1;
vis->x2 = x2;
@ -1538,6 +1537,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)
{
@ -2692,7 +2694,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
// Add the 3D floors, thicksides, and masked textures...
for (ds = drawsegs + mask->drawsegs[1]; ds-- > drawsegs + mask->drawsegs[0];)
{
if (ds->numthicksides)
if (ds->numthicksides && cv_renderwalls.value)
{
for (i = 0; i < ds->numthicksides; i++)
{
@ -2711,17 +2713,19 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
else {
// Put it in!
entry = R_CreateDrawNode(head);
entry->plane = plane;
entry->seg = ds;
if (cv_renderwalls.value)
entry->seg = ds;
if (cv_renderfloors.value)
entry->plane = plane;
}
ds->curline->polyseg->visplane = NULL;
}
if (ds->maskedtexturecol)
if (ds->maskedtexturecol && cv_renderwalls.value)
{
entry = R_CreateDrawNode(head);
entry->seg = ds;
}
if (ds->numffloorplanes)
if (ds->numffloorplanes && cv_renderfloors.value)
{
for (i = 0; i < ds->numffloorplanes; i++)
{
@ -3021,9 +3025,6 @@ void R_InitDrawNodes(void)
//
// R_DrawSprite
//
//Fab : 26-04-98:
// NOTE : uses con_clipviewtop, so that when console is on,
// don't draw the part of sprites hidden under the console
static void R_DrawSprite(vissprite_t *spr)
{
mfloorclip = spr->clipbot;
@ -3191,9 +3192,6 @@ static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, portal_t* port
(lowscale < spr->sortscale &&
!R_PointOnSegSide (spr->gx, spr->gy, ds->curline)))
{
// masked mid texture?
/*if (ds->maskedtexturecol)
R_RenderMaskedSegRange (ds, r1, r2);*/
// seg is behind sprite
continue;
}

View file

@ -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);

View file

@ -8,7 +8,7 @@
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file screen.c
/// \brief Handles multiple resolutions, 8bpp/16bpp(highcolor) modes
/// \brief Handles multiple resolutions
#include "doomdef.h"
#include "doomstat.h"
@ -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"},
@ -91,19 +94,15 @@ consvar_t cv_fullscreen = CVAR_INIT ("fullscreen", "Yes", CV_SAVE|CV_CALL, CV_Ye
// =========================================================================
INT32 scr_bpp; // current video mode bytes per pixel
UINT8 *scr_borderpatch; // flat used to fill the reduced view borders set at ST_Init()
// =========================================================================
// Short and Tall sky drawer, for the current color mode
void (*walldrawerfunc)(void);
void SCR_SetDrawFuncs(void)
{
//
// setup the right draw routines for either 8bpp or 16bpp
// setup the right draw routines
//
if (true)//vid.bpp == 1) //Always run in 8bpp. todo: remove all 16bpp code?
if (vid.bpp == 1) //Always run in 8bpp.
{
colfuncs[BASEDRAWFUNC] = R_DrawColumn_8;
spanfuncs[BASEDRAWFUNC] = R_DrawSpan_8;
@ -139,7 +138,6 @@ void SCR_SetDrawFuncs(void)
spanfuncs[SPANDRAWFUNC_FOG] = R_DrawFogSpan_8;
spanfuncs[SPANDRAWFUNC_TILTEDFOG] = R_DrawTiltedFogSpan_8;
// Lactozilla: Non-powers-of-two
spanfuncs_npo2[BASEDRAWFUNC] = R_DrawSpan_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_TILTED] = R_DrawTiltedSpan_NPO2_8;
@ -153,26 +151,9 @@ void SCR_SetDrawFuncs(void)
spanfuncs_npo2[SPANDRAWFUNC_TILTEDTRANSSPRITE] = R_DrawTiltedTranslucentFloorSprite_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_WATER] = R_DrawWaterSpan_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_TILTEDWATER] = R_DrawTiltedWaterSpan_NPO2_8;
}
/* else if (vid.bpp > 1)
{
I_OutputMsg("using highcolor mode\n");
spanfunc = basespanfunc = R_DrawSpan_16;
transcolfunc = R_DrawTranslatedColumn_16;
transtransfunc = R_DrawTranslucentColumn_16; // No 16bit operation for this function
colfunc = basecolfunc = R_DrawColumn_16;
shadecolfunc = NULL; // detect error if used somewhere..
fuzzcolfunc = R_DrawTranslucentColumn_16;
walldrawerfunc = R_DrawWallColumn_16;
}*/
else
I_Error("unknown bytes per pixel mode %d\n", vid.bpp);
/*
if (SCR_IsAspectCorrect(vid.width, vid.height))
CONS_Alert(CONS_WARNING, M_GetText("Resolution is not aspect-correct!\nUse a multiple of %dx%d\n"), BASEVIDWIDTH, BASEVIDHEIGHT);
*/
}
void SCR_SetMode(void)

View file

@ -8,7 +8,7 @@
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file screen.h
/// \brief Handles multiple resolutions, 8bpp/16bpp(highcolor) modes
/// \brief Handles multiple resolutions
#ifndef __SCREEN_H__
#define __SCREEN_H__
@ -61,7 +61,7 @@ typedef struct viddef_s
UINT8 *direct; // linear frame buffer, or vga base mem.
INT32 dup; // scale 1, 2, 3 value for menus & overlays
INT32/*fixed_t*/ fdup; // same as dup, but exact value when aspect ratio isn't 320/200
INT32 bpp; // BYTES per pixel: 1 = 256color, 2 = highcolor
INT32 bpp; // BYTES per pixel: 1 = 256color
INT32 baseratio; // Used to get the correct value for lighting walls
@ -83,35 +83,6 @@ enum
VID_GL_LIBRARY_ERROR = -1,
};
// internal additional info for vesa modes only
typedef struct
{
INT32 vesamode; // vesa mode number plus LINEAR_MODE bit
void *plinearmem; // linear address of start of frame buffer
} vesa_extra_t;
// a video modes from the video modes list,
// note: video mode 0 is always standard VGA320x200.
typedef struct vmode_s
{
struct vmode_s *pnext;
char *name;
UINT32 width, height;
UINT32 rowbytes; // bytes per scanline
UINT32 bytesperpixel; // 1 for 256c, 2 for highcolor
INT32 windowed; // if true this is a windowed mode
INT32 numpages;
vesa_extra_t *pextradata; // vesa mode extra data
#ifdef _WIN32
INT32 (WINAPI *setmode)(viddef_t *lvid, struct vmode_s *pcurrentmode);
#else
INT32 (*setmode)(viddef_t *lvid, struct vmode_s *pcurrentmode);
#endif
INT32 misc; // misc for display driver (r_opengl.dll etc)
} vmode_t;
#define NUMSPECIALMODES 4
extern vmode_t specialmodes[NUMSPECIALMODES];
// ---------------------------------------------
// color mode dependent drawer function pointers
// ---------------------------------------------
@ -184,9 +155,9 @@ void SCR_ChangeRenderer(void);
extern CV_PossibleValue_t cv_renderer_t[];
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

View file

@ -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" />
@ -572,9 +573,6 @@
<ClCompile Include="..\r_bsp.c" />
<ClCompile Include="..\r_data.c" />
<ClCompile Include="..\r_draw.c" />
<ClCompile Include="..\r_draw16.c">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\r_draw8.c">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>

View file

@ -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>
@ -976,9 +982,6 @@
<ClCompile Include="..\r_draw.c">
<Filter>R_Rend</Filter>
</ClCompile>
<ClCompile Include="..\r_draw16.c">
<Filter>R_Rend</Filter>
</ClCompile>
<ClCompile Include="..\r_draw8.c">
<Filter>R_Rend</Filter>
</ClCompile>

View file

@ -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))

View file

@ -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,50 +617,60 @@ 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;
ev.type = ev_console;
ev.key = 0;
if (read(STDIN_FILENO, &key, 1) == -1 || !key)
return;
for (;;)
{
if (poll(&pfd, 1, 0) < 1 || !(pfd.revents & POLLIN))
return;
// we have something
// backspace?
// NOTE TTimo testing a lot of values .. seems it's the only way to get it to work everywhere
if ((key == tty_erase) || (key == 127) || (key == 8))
{
if (tty_con.cursor > 0)
ev.type = ev_console;
ev.key = 0;
if (read(STDIN_FILENO, &key, 1) == -1 || !key)
return;
// we have something
// backspace?
// NOTE TTimo testing a lot of values .. seems it's the only way to get it to work everywhere
if ((key == tty_erase) || (key == 127) || (key == 8))
{
tty_con.cursor--;
tty_con.buffer[tty_con.cursor] = '\0';
tty_Back();
if (tty_con.cursor > 0)
{
tty_con.cursor--;
tty_con.buffer[tty_con.cursor] = '\0';
tty_Back();
}
ev.key = KEY_BACKSPACE;
}
ev.key = KEY_BACKSPACE;
}
else if (key < ' ') // check if this is a control char
{
if (key == '\n')
else if (key < ' ') // check if this is a control char
{
tty_Clear();
tty_con.cursor = 0;
ev.key = KEY_ENTER;
if (key == '\n')
{
tty_Clear();
tty_con.cursor = 0;
ev.key = KEY_ENTER;
}
else continue;
}
else return;
else if (tty_con.cursor < sizeof (tty_con.buffer))
{
// push regular character
ev.key = tty_con.buffer[tty_con.cursor] = key;
tty_con.cursor++;
// print the current line (this is differential)
write(STDOUT_FILENO, &key, 1);
}
if (ev.key) D_PostEvent(&ev);
//tty_FlushIn();
}
else if (tty_con.cursor < sizeof (tty_con.buffer))
{
// push regular character
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);
}
if (ev.key) D_PostEvent(&ev);
//tty_FlushIn();
(void)d;
}
#elif defined (_WIN32)

View file

@ -100,8 +100,6 @@ static char vidModeName[33][32]; // allow 33 different modes
rendermode_t rendermode = render_soft;
rendermode_t chosenrendermode = render_none; // set by command line arguments
boolean highcolor = false;
static void VidWaitChanged(void);
// synchronize page flipping with screen refresh
@ -1297,6 +1295,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
@ -1395,103 +1401,12 @@ INT32 VID_GetModeForSize(INT32 w, INT32 h)
}
}
return -1;
#if 0
INT32 matchMode = -1, i;
VID_PrepareModeList();
if (USE_FULLSCREEN && numVidModes != -1)
{
for (i=firstEntry; i<numVidModes; i++)
{
if (modeList[i]->w == w &&
modeList[i]->h == h)
{
matchMode = i;
break;
}
}
if (-1 == matchMode) // use smaller mode
{
w -= w%BASEVIDWIDTH;
h -= h%BASEVIDHEIGHT;
for (i=firstEntry; i<numVidModes; i++)
{
if (modeList[i]->w == w &&
modeList[i]->h == h)
{
matchMode = i;
break;
}
}
if (-1 == matchMode) // use smallest mode
matchMode = numVidModes-1;
}
matchMode -= firstEntry;
}
else
{
for (i=0; i<MAXWINMODES; i++)
{
if (windowedModes[i][0] == w &&
windowedModes[i][1] == h)
{
matchMode = i;
break;
}
}
if (-1 == matchMode) // use smaller mode
{
w -= w%BASEVIDWIDTH;
h -= h%BASEVIDHEIGHT;
for (i=0; i<MAXWINMODES; i++)
{
if (windowedModes[i][0] == w &&
windowedModes[i][1] == h)
{
matchMode = i;
break;
}
}
if (-1 == matchMode) // use smallest mode
matchMode = MAXWINMODES-1;
}
}
return matchMode;
#endif
}
void VID_PrepareModeList(void)
{
// Under SDL2, we just use the windowed modes list, and scale in windowed fullscreen.
allow_fullscreen = true;
#if 0
INT32 i;
firstEntry = 0;
#ifdef HWRENDER
if (rendermode == render_opengl)
modeList = SDL_ListModes(NULL, SDL_OPENGL|SDL_FULLSCREEN);
else
#endif
modeList = SDL_ListModes(NULL, surfaceFlagsF|SDL_HWSURFACE); //Alam: At least hardware surface
if (disable_fullscreen?0:cv_fullscreen.value) // only fullscreen needs preparation
{
if (-1 != numVidModes)
{
for (i=0; i<numVidModes; i++)
{
if (modeList[i]->w <= MAXVIDWIDTH &&
modeList[i]->h <= MAXVIDHEIGHT)
{
firstEntry = i;
break;
}
}
}
}
allow_fullscreen = true;
#endif
}
static SDL_bool Impl_CreateContext(void)
@ -1958,32 +1873,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

View file

@ -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)

View file

@ -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)
@ -253,10 +253,6 @@ void ST_LoadGraphics(void)
{
int i;
// SRB2 border patch
// st_borderpatchnum = W_GetNumForName("GFZFLR01");
// scr_borderpatch = W_CacheLumpNum(st_borderpatchnum, PU_HUDGFX);
// the original Doom uses 'STF' as base name for all face graphics
// Graue 04-08-2004: face/name graphics are now indexed by skins
// but load them in R_AddSkins, that gets called
@ -1945,7 +1941,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 +2889,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();

View file

@ -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);