Compare commits

...
192 Commits
Author SHA1 Message Date
Alug 44ecb677ad fix merge conflicts texturehashing 2025-08-03 00:37:28 +02:00
Alug 3e99f4d142 Do not reload every texture when adding a wad (squashed)
port of https://git.do.srb2.org/STJr/SRB2/-/merge_requests/1725#c829d21709a4f5cd81d140271e883bc40dd00b1b
2025-08-03 00:35:46 +02:00
Alug a9d0e2154b clamp software lightlevels before shifting it
was a little oopsie porting this over
,after shifting we only get 32 lightlevels
decided to clamp this in range aswell, just incase
2025-08-02 19:13:23 +02:00
Alug 16a0953d1d fix the "is valid for C/ObjC but not for C++" warnings
fixes https://github.com/Indev450/SRB2Kart-Saturn/issues/192
2025-08-02 01:54:57 +02:00
Alug 737ae08355 dont need to reinit those ever 2025-08-02 01:01:06 +02:00
Alug 6d83a7e187 remove usefulness and volume from sfxinfo_struct struct
those are unused anyways, hope this doesent break shit lol
2025-08-02 01:00:58 +02:00
Alug 56df9b6af3 who tf needs 999999999 sound channels
:chaobaba:
even 255 are kinda overkill lol
2025-08-02 01:00:51 +02:00
Alug 7f2435d821 add an Accessibility options menu
still a work in progress, feel free to suggest more things to add!
2025-08-01 22:26:00 +02:00
Alug b180f29fd9 readd secbright to menu
into advanced video options menu
2025-08-01 21:27:38 +02:00
Alug 32c85f96a4 remove secbright from menu
need to slot it somewhere else but little too lazy atm
2025-08-01 21:27:35 +02:00
chromaticpipe ec83c60320 Configurable sector brightness in software 2025-08-01 21:27:32 +02:00
chromaticpipe fb4a912dba Clamp the lightlevel at the start of HWR_Lighting()
Allows secbright to work without shaders
2025-08-01 21:27:29 +02:00
James R 123b2aa60b lua_hooklib.c: refactor HUD hook call 2025-08-01 21:04:30 +02:00
Logan Aerl Arias bd82a8db29 Update lauxlib.h
lauxlib.h: mark luaL_error as a REPORT function
2025-08-01 21:04:27 +02:00
Alug 6f71fc17c2 mark this as unlikely
those will never run ever after displaying once
2025-08-01 21:04:24 +02:00
Alug d8c3e9f41c fix windows being unable to link with LTO and openmpt
idk why this works but it does, mirrors how it was before the new makefiles
2025-08-01 17:55:02 +01:00
Alug e10345b4de pass "-g" again for lto and asan on windows
for some weird reason it will omit all debug symbols otherwise, which we need for crashlogs and stuff
2025-08-01 17:31:12 +01:00
Alug 2ab66b113c we dont need cv_samplerate with sdl mixer 2025-08-01 04:51:00 +02:00
Alug f64263cf6f remove some unused stuff s_sound 2025-08-01 04:50:57 +02:00
Alug 55c72f32da rename buffersize to audiobuffersize
buffersize was not a good name lel
2025-08-01 04:50:54 +02:00
Alug 53bc12baad init "lenght" in S_AddSoundFx
seems like this never init this lel
2025-08-01 03:58:41 +02:00
Alug b391e763bc fix gme 2025-08-01 03:56:47 +02:00
Alug 2bae0bdb0f indent deez 2025-07-31 23:34:29 +02:00
Alug d42df54901 fix borderless sometimes not toggling on windows
idk why windoze is like this, but gotta call this after SDL_SetWindowFullscreen here
2025-07-31 23:34:28 +02:00
Alug e6256d448f TEST: banish LUA_Step
checking stuff there never seemed to be any garbage left here
so we can just skip this
2025-07-31 21:23:33 +02:00
Alug ad1a980eb1 memset listener outside the loop S_StartSoundAtVolume
same effect, but we dont need to call it multiple times and can be sure this is never unitialized
2025-07-31 19:55:29 +02:00
Alug 1b50858fa6 add a configurable same sound limit
inspired by dsda-doom
in alot of cases the game may play a crapton of the same sound at once, becoming unbearably loud
2025-07-31 19:42:56 +02:00
Alug 3276bbb7b6 restore mumble postional sounds for displayplayers
we essentially always passed 0 before lol
2025-07-31 19:42:53 +02:00
Alug dc00fa3429 fix passing garbage to mumble outside of levels
this just deadass passed the unitialized listener array into mumble
2025-07-31 19:42:37 +02:00
indev dc9276b73c Make 'visit mb.srb2.org/addons' text fit on default resolution ('& make' bit refers more to wiki than mb anyway) 2025-07-31 13:33:48 +03:00
Alug 271d70d6f3 inline HWR_GetTexturePalette
makes ui draw slightly faster from quick test
should be in hw_glob, but cant include hw_main there Zzz...
2025-07-30 15:29:56 +02:00
Alug e52a6c430b smol changes k_hud
nothing crazy mostly just smol reordering
2025-07-30 14:55:44 +02:00
Alug d77d25acf8 use hypotf for P_SegLengthFloat
well its hypot but for floats lel
2025-07-29 19:21:34 +02:00
Alug 9898809f0a remove erronous HWR_FreeExtraSubsectors call
this will be called from within HWR_CreatePlanePolygons anyways
2025-07-29 18:48:02 +02:00
Alug 48768aa13c fix the rare infinite loop hang in ogl (sunset hill map)
use new doom-legacies PointInSeg and add a selfref check to CutOutSubsecPoly
(somewhat related, but it appears this whole file is able to mess with the actual sector planes outside of rendering, this is not really good since it may actually lead to some super hard to debug desynchs)
2025-07-29 18:40:40 +02:00
Alug b1c01a763f cleanup hw_bsp a little
mostly just get rid of debug bloat that isnt even used
adding some branching hints for the I_errors (never seen any one of them happen tbh lel)
and remove some redundant checks
2025-07-29 18:40:02 +02:00
Alug d9bcd6007c move horizonline check to hw_bsp
to where maps also get checked for portals
should speed up levelload slightly
2025-07-29 15:37:14 +02:00
Alug d1b478b3b1 oop 2025-07-29 02:36:45 +02:00
Alug 14b421f533 camera noclip sec special is effectively unused in kart
its not even in the kart zb config
so mark it with unlikely
2025-07-29 02:35:58 +02:00
Alug 7310a8e4df add slope check here
not necessary but may skip more uneeded checks and stuff
2025-07-29 01:23:01 +02:00
Alug c1c3a7dc78 remove unecessary casts for colormap 2025-07-29 00:48:26 +02:00
chromaticpipe ff10b77414 Fix OpenGL flash palettes ignoring saturation 2025-07-29 00:31:10 +02:00
chromaticpipe 4667c332b4 Fix brightness issues with blend textures in Pallette Rendering 2025-07-29 00:31:07 +02:00
Alug 4a9f6b6a22 we dont need to clamp sprite lightlevels everywhere in ogl
theyre an int32 due to the directional light system stuff and get clamped in HWR_Lighting as a result
2025-07-29 00:31:04 +02:00
indev f1d78243d0 Move setting c++ standard bit below 2025-07-27 19:45:10 +03:00
Alug 6e41c8a2a0 readd std=c++17 to cxxflags 2025-07-27 18:42:16 +02:00
Alug 9c5955feb0 Store last ticcmd in a buffer rather than in netcmd
port of https://codeberg.org/srb2classic/srb2classic/commit/fe663f799e733e9a59a95dfd561e506571838554

testing this, since the faketic calc seems a bit "off" to me
2025-07-27 18:29:55 +02:00
Alug 0764b180f7 fixup! next branch
- remove a bunch of clutter
- Fix AATtree stuff by properly balancing it
- replace getcolumn calc with modulo calc
- use strlcpy for some things
- cache wadfile start and endfolders
2025-07-27 18:28:19 +02:00
Alug b883e4e4fe Merge branch 'Saturn-Testing' into Saturn-Next 2025-07-27 18:21:07 +02:00
Alug f78688b684 Merge pull request #189 from Indev450/mmenucleanup
Cleanup m_menu a bit
2025-07-27 17:18:07 +01:00
Alug 097cd5e2ca Merge remote-tracking branch 'origin/Saturn-Next' into mmenucleanup 2025-07-27 18:17:49 +02:00
Alug cd4836ae99 Merge pull request #187 from Indev450/emotes
Add emotes support
2025-07-27 17:16:23 +01:00
Alug f0acf179c2 Merge pull request #185 from Indev450/fixupnet
Cleanup netcode a bit
2025-07-27 17:16:16 +01:00
Alug 836ad12c40 Merge pull request #180 from Indev450/fixgnu23
Make codebase C23 compliant
2025-07-27 17:16:02 +01:00
Alug a147fa3100 Merge pull request #179 from Indev450/unnestmothink
Unnest mobj thinker stuff + cleanup p_mobj
2025-07-27 17:15:55 +01:00
Alug a68a05a838 fix conflict 2025-07-27 15:18:46 +02:00
Alug 95504547df add mobj islocal field
so we can skip the pushable trigger stuff for local mobjs for synch reasons
very sketchy
2025-07-27 15:17:51 +02:00
Alug ceb2a70664 reduce netbuffer scope even further 2025-07-27 15:17:17 +02:00
Alug 8593a1975c Merge branch 'Saturn-Next' into Saturn-Testing 2025-07-27 15:17:09 +02:00
Alug 48d9b2bc98 reduce netbuffer scope even further 2025-07-26 16:19:13 +02:00
Alug 939bf588b3 Merge branch 'Saturn-Next' into fixupnet 2025-07-26 16:19:09 +02:00
Alug a61b028e97 Merge branch 'Saturn-Next' into Saturn-Testing 2025-07-22 17:35:21 +02:00
Alug e29bdd09c5 Merge branch 'Saturn-Next' into Saturn-Testing 2025-07-21 19:45:01 +02:00
Alug 74b082760d abuse c++ templates for Hwr_AddSprites
test this, but we can avoid a bunch of branching and functions calls like this when drawdist is inifite
2025-07-21 11:56:00 +02:00
Alug 4460fa608b merge fix 2025-07-21 11:55:39 +02:00
Alug 949192c570 branch hints for nights and 2d stuff
gotta keep em for compat reasons Zzz..
2025-07-21 11:49:49 +02:00
Alug 4fa0ca2304 move a bunch of stuff after early returns
+ add some branching instrincts to stuff

maybe saves a bit of time if we dont need the thing
2025-07-21 11:49:44 +02:00
Alug d9d2f043fa use branch instrincts for P_MobjThinker
based on observations from kart stuff
2025-07-21 11:49:00 +02:00
Alug 1ea51f29c5 Merge branch 'Saturn-Next' into Saturn-Testing 2025-07-21 11:48:35 +02:00
Alug b0653416f6 Merge branch 'Saturn-Next' into fixupnet 2025-07-20 17:03:30 +02:00
Alug b4570cbdaa Merge branch 'mmenucleanup' into Saturn-Testing 2025-07-16 20:42:45 +02:00
Alug f2dc344bf8 copy paste oopsie 2025-07-15 19:55:13 +02:00
Alug c0654448f0 oop this was unsigned 2025-07-15 19:18:52 +02:00
Alug 2bf3912633 unmangle localskin menu mess a bit 2025-07-15 19:17:06 +02:00
Alug 4d71fb8409 few more things i missed 2025-07-15 18:59:28 +02:00
Alug 8543a099f4 split m_menu definitions to m_menudefs
idk if this is a good idea lel
2025-07-15 18:59:25 +02:00
Alug 9c6ec02b18 do some cleanup m_menu
gets rid of a bunch of duplicated splitscreen shit
unused srb2 stuff
commented out stuff aswell
we dont need any of this
this is def still far from tidy and itll never be like this
2025-07-15 18:59:22 +02:00
Alug bb9118ee32 Merge branch 'Saturn-Next' into Saturn-Testing 2025-07-15 18:57:23 +02:00
Alug 1847aac223 fix windoze for the 50 trillionth time
when do we finally remove windows support?
those two things do absolutely fucking nothing but shit dies without em for whatever reason
2025-07-08 17:06:06 +01:00
Alug 14be968089 fix for non pow2 width textures in software from doom-legacy 2025-07-08 16:52:56 +01:00
Alug 9f678263d0 Merge remote-tracking branch 'origin/Saturn-Next' into Saturn-Testing 2025-07-08 16:52:32 +01:00
Alug cb0667921e oop lmao 2025-07-04 12:07:56 +02:00
Alug 52ab27a825 Merge branch 'Saturn-Next' into Saturn-Testing 2025-07-04 11:23:26 +02:00
Alug 38b89093fa Merge remote-tracking branch 'origin/emotes' into Saturn-Testing 2025-07-01 19:22:07 +02:00
Alug 224ce007e1 Merge branch 'Saturn-Next' into Saturn-Testing 2025-07-01 19:21:58 +02:00
indev 2800685cfc Merge branch 'Saturn-Next' into emotes 2025-07-01 20:15:44 +03:00
Alug 0241d7fe00 Merge branch 'Saturn-Next' into Saturn-Testing 2025-07-01 15:27:39 +02:00
indev 5d8bb3223f No need for this now 2025-07-01 15:25:48 +03:00
indev 5e1f943a38 Merge branch 'Saturn-Next' into emotes 2025-07-01 15:24:42 +03:00
indev fca7b4a837 Use std::min 2025-07-01 15:15:36 +03:00
Alug 02ce2ff5ec Merge remote-tracking branch 'origin/emotes' into Saturn-Testing 2025-07-01 10:31:58 +02:00
indev d2bab80b29 Add emote suggestions and autocompletion 2025-06-30 16:43:14 +03:00
Alug 667a8bb166 "restrict" macro for c++
since it does not have it, use __restrict instead
2025-06-30 12:18:32 +02:00
Alug 76a18d001f friendship with constexpr started 2025-06-30 12:11:45 +02:00
Alug 78ab90c1a6 "restrict" macro for c++
since it does not have it, use __restrict instead
2025-06-30 12:54:15 +03:00
Alug 45b9aeb85a slightly cleanup addline stuff
no clue why i just didnt do this before lel
2025-06-30 08:17:41 +02:00
Alug d580306b8a fix hw_main compiler warning 2025-06-30 08:17:38 +02:00
indev 102e944fd5 Preview emotes in chat input 2025-06-30 00:28:14 +03:00
Alug 3748896ebc thanks michaelsoft very cool 2025-06-29 10:20:33 +01:00
Alug 79988dea3d this makes no sense lol 2025-06-29 10:13:00 +01:00
Alug 4409a5848f Merge branch 'Saturn-Next' into Saturn-Testing 2025-06-29 12:08:06 +02:00
Alug 07c13636fc ceepeepeefy hw_main, abuse templates for portal stuff
no idea if this is faster at all lmao
2025-06-29 11:49:36 +02:00
Alug 51cc706b1e Merge remote-tracking branch 'origin/emotes' into Saturn-Testing 2025-06-29 11:48:33 +02:00
Alug 54bd31c80a Merge branch 'Saturn-Next' into Saturn-Testing 2025-06-29 11:48:18 +02:00
Alug 61534d7356 Merge branch 'softwarecrap' into Saturn-Testing 2025-06-29 11:48:12 +02:00
indev 9bd4a933cf Check if text is inside chat log box for emotes 2025-06-29 00:30:24 +03:00
indev e233635783 huh? 2025-06-29 00:05:25 +03:00
indev da24ba20c7 Fix emotes having not enough 'background' rendered :chonkbunckle: 2025-06-28 22:39:44 +03:00
indev 74bdabc636 Load emotes from base wads too at boot (so it loads ones from -file wads) 2025-06-28 22:31:33 +03:00
indev 4b129314d3 Right that got removed in the end :chonkbunckle: 2025-06-28 21:04:09 +03:00
indev 3a55972997 Initial emote support 2025-06-28 21:03:15 +03:00
Alug 6e04e4171e fix the goddamn boolean 2025-06-28 19:21:45 +03:00
Alug cccfaaabfd proper init enterprecise 2025-06-19 17:48:12 +02:00
Alug eadbe9c2e5 delet this 2025-06-19 17:47:57 +02:00
Alug 9bbabcee06 delet this 2025-06-19 17:47:42 +02:00
Alug 7ca6fa6772 turn translation colormaps stuff into an enum 2025-06-19 17:44:04 +02:00
Alug 6317e9c510 cleanup colormap translation stuff
needs testing
2025-06-19 17:43:56 +02:00
Alug 0a80985771 check if player is local here 2025-06-19 17:41:49 +02:00
Alug 548d52cc60 simplify R_SetupAimingFrame 2025-06-19 17:41:42 +02:00
Alug 11c6c69a00 Merge branch 'softwarecrap' into Saturn-Testing 2025-06-19 17:41:33 +02:00
Alug 08025d2da3 ok git very cool 2025-06-19 17:41:12 +02:00
Gustaf Alhäll 4169e7bd71 Remove aligned allocation functions 2025-06-19 17:41:09 +02:00
Gustaf Alhäll bfb7a6b08d Fix potential NULL deference if memory runs out during cURL request 2025-06-19 17:41:06 +02:00
Alug 58abb0d4c3 Merge remote-tracking branch 'origin/softwarecrap' into Saturn-Testing 2025-06-19 17:40:42 +02:00
Alug 9658279cb1 Merge branch 'fixupnet' into Saturn-Testing 2025-06-19 17:40:34 +02:00
Alug d1a6394e52 Merge remote-tracking branch 'origin/Saturn-Next' into fixupnet 2025-06-19 15:55:22 +02:00
Alug 6f4e387061 Merge branch 'softwarecrap' into Saturn-Testing 2025-06-12 21:47:29 +02:00
Alug 33ef566fd2 Merge remote-tracking branch 'origin/Saturn-Next' into Saturn-Testing 2025-06-12 21:47:26 +02:00
Alug eeecd954e2 Merge branch 'softwarecrap' into Saturn-Testing 2025-06-12 17:19:38 +02:00
Alug ccb804a4ed Merge branch 'fixupnet' into Saturn-Testing 2025-06-12 17:18:09 +02:00
Alug a21029ee9e Merge branch 'Saturn-Next' into Saturn-Testing 2025-06-12 17:17:54 +02:00
Alug ccc90842a7 move CopyCaretColors to m_misc 2025-06-12 17:10:08 +02:00
Alug dc069d7bb5 unnest HandlePacketFromPlayer
+ some cleanup
2025-06-12 00:53:47 +02:00
Alug f4a827dfc2 fix conflicts 2025-06-12 00:02:55 +02:00
Alug 4f3232b6cc Merge branch 'Saturn-Next' into fixupnet 2025-06-12 00:02:05 +02:00
Alug 7393eb728c Merge branch 'Saturn-Next' into Saturn-Testing 2025-06-07 11:56:17 +02:00
Alug 1e715f8cd7 Merge branch 'newmakefiles' into Saturn-Testing 2025-06-07 11:56:13 +02:00
Alug 7aadc77a69 Merge remote-tracking branch 'origin/luamusicdef' into Saturn-Testing 2025-05-31 19:39:39 +02:00
Alug 27e1406e6d Merge branch 'Saturn-Next' into Saturn-Testing 2025-05-31 17:44:33 +02:00
Alug 796204d376 use memcmp during startup map check
prob not faster just looks a bit better tbh
2025-05-31 17:20:46 +02:00
Alug acabd1a03e Merge branch 'votebgstuff' into Saturn-Testing 2025-05-31 17:13:58 +02:00
Alug c08aae2622 Merge branch 'Saturn-Next' into Saturn-Testing 2025-05-31 17:13:00 +02:00
Alug 3eba512ad4 Merge branch 'newmakefiles' into Saturn-Testing 2025-05-29 19:35:34 +02:00
Alug c99115d552 thanks windoze very cool part 2 2025-05-29 17:27:38 +01:00
Alug bf6c682cc1 thanks windoze very cool 2025-05-29 17:16:51 +01:00
Alug dc2f0b5707 Merge branch 'Saturn-Next' into Saturn-Testing 2025-05-29 18:23:08 +02:00
Alug 9488d98cfd Merge branch 'Saturn-Next' into Saturn-Testing 2025-05-29 12:43:04 +01:00
Alug 906b8165d3 dont use stdbool´s bool type
this badly breaks everything
apparently the code assumes boolean to be an interger type or some shit
2025-05-29 12:41:56 +01:00
Alug 74c8325987 Merge branch 'updatewinlibs' into Saturn-Testing 2025-05-28 22:16:37 +02:00
Alug e30efbfe6c Revert "update lzf to 1.6"
This reverts commit 9899747a7f.
2025-05-28 22:16:30 +02:00
Alug 5d4bb0f5ce Merge branch 'Saturn-Next' into Saturn-Testing 2025-05-28 22:14:17 +02:00
Alug e63777c7d6 remove this
prob wrong assumption, our netcode sucks massive ass
2025-05-28 21:42:29 +02:00
Alug a34ca05bff this is testing lel 2025-05-28 20:45:26 +02:00
Alug af9ffc1f6f forgor the hw state lel 2025-05-28 16:37:37 +01:00
Alug 18816453f4 add wireframe mode for ogl 2025-05-28 18:31:21 +02:00
Alug 1eb8a75058 fix compiler warning bout playeringame 2025-05-28 18:30:26 +02:00
Alug 5abf42fe75 remove crappy memcpy redifine from md5 2025-05-28 18:29:18 +02:00
Alug 1306a233b8 Further improve sleep accuracy on UNIX systems
but not for dedis
https://git.srb2.org/STJr/SRB2/-/merge_requests/2583
2025-05-28 18:28:22 +02:00
Alug 46f8c6b7a5 remove forcing c17 from makefile 2025-05-28 18:26:47 +02:00
Alug face5cf447 Merge branch 'fixgnu23' into Saturn-Testing 2025-05-28 18:26:24 +02:00
Alug 603267b753 fix W_CheckNumForFolderStartPK3 2025-05-28 17:47:29 +02:00
Gustaf Alhäll 7cf3113d67 Fix long names using the wrong hash field 2025-05-28 17:47:25 +02:00
Alug 397fa962b1 Optimize lump searching
https://git.srb2.org/Hanicef/SRB2Classic/-/commit/dc608f084c76cf72de9fc3f3f347752f04acae42
2025-05-28 17:47:22 +02:00
Alug d2637ab71f Merge branch 'newmakefiles' into Saturn-Testing 2025-05-28 17:47:01 +02:00
Alug a6e020adeb Merge branch 'texloadstuff' into Saturn-Testing 2025-05-28 17:46:43 +02:00
Alug d50dcac0c0 Merge branch 'unnestmothink' into Saturn-Testing 2025-05-28 17:46:40 +02:00
Alug dd6bc23a8e Merge branch 'updatewinlibs' into Saturn-Testing 2025-05-28 17:46:35 +02:00
Alug 71575f5cf8 Revert "update sdl_mixer to 2.8.1"
This reverts commit b8ae656968.
2025-05-26 22:11:03 +01:00
Alug 3685502edf Revert "delet tic resending stuff"
This reverts commit 17bc8a4a36.
2025-05-26 18:10:03 +02:00
Alug 9899747a7f update lzf to 1.6 2025-05-26 18:02:21 +02:00
Alug d2a415380d oop we still need libgme.dll 2025-05-26 15:15:46 +01:00
Alug dd7ffd7dfe delet GETTEXT and translation stuff 2025-05-26 14:48:31 +01:00
Alug 770f9af5e1 cleanup some stuff 2025-05-26 14:31:53 +01:00
Alug c2ab5be8b8 Merge remote-tracking branch 'origin/winzlib-ng' into updatewinlibs 2025-05-26 13:21:03 +01:00
Alug b8ae656968 update sdl_mixer to 2.8.1
we can also get rid of a bunch of dlls now
2025-05-26 13:12:43 +01:00
Alug 553b61e1f5 update SDL2 to 2.32.6
also removes a bunch of files we dont need
2025-05-26 12:51:45 +01:00
Alug f87bcef079 try fixing some crash with bogus netxcmds 2025-05-23 16:55:47 +02:00
Alug c3458afe2b unglobalise holepunchpacket aswell 2025-05-23 16:53:42 +02:00
Alug 17bc8a4a36 delet tic resending stuff 2025-05-23 16:51:26 +02:00
Alug b04f017ab6 change ticqueue system to be more like srb 2.2
mostly just renaming lel
2025-05-23 16:51:10 +02:00
Alug 083ddb6396 Refactor netbuffer out of global namespace
https://git.do.srb2.org/Hanicef/SRB2Classic/-/commit/079fd2cef97a9cf22fb5d2b66a9b500914efbc72

+ move some things into functions
2025-05-23 16:48:34 +02:00
Alug c3129742c3 simplify cmpack 2025-05-23 16:44:52 +02:00
Alug 877bd640f3 fix destinationnode check in Processackpak 2025-05-23 16:43:52 +02:00
Alug 3233df9c6c do not resolve ipv4 in curl when using ipv6 2025-05-23 16:43:24 +02:00
Alug 9ad5f5189c split portnum retrieval into own function 2025-05-23 16:43:02 +02:00
Alug c7718dea79 fixup! i_tcp
technically make ipv6 work,, but its disabled by default
2025-05-23 16:40:38 +02:00
Alug 5a0fb59b26 Do not reload every texture when adding a wad (squashed)
port of https://git.do.srb2.org/STJr/SRB2/-/merge_requests/1725#c829d21709a4f5cd81d140271e883bc40dd00b1b
2025-05-23 16:16:10 +02:00
Alug 07c52e6af5 static link this to get rid of stinky extra dll
thx indev <3
2025-03-20 14:45:35 +01:00
Alug 405c566038 import zlib-ng in compat mode 2025-03-20 14:31:02 +01:00
Alug 78780799ea delet zlib from windoze 2025-03-20 14:15:38 +01:00
Alug 82b9457aa7 Merge branch 'Saturn-Testing' into winzlib-ng 2025-03-20 13:37:06 +01:00
Alug 4e6abb39dd Merge remote-tracking branch 'origin/rankingsrefactor' into winzlib-ng 2025-03-20 13:34:51 +01:00
75 changed files with 6957 additions and 10089 deletions

No files matched your search

+21 -6
View File
@@ -246,13 +246,25 @@ debug_opts=-DNDEBUG
opts+=-O3
ifdef USELTO
# compile with LTO
ifdef MINGW
opts+=-flto=auto -g
libs+=-flto=auto -g
else
opts+=-flto=auto
libs+=-flto=auto
endif
endif
endif
ifdef USEASAN
# compile with asan
ifdef MINGW
opts+=-fsanitize=address -g
libs+=-fsanitize=address -g
else
opts+=-fsanitize=address
libs+=-fsanitize=address
endif
opts+=-fsanitize=address
libs+=-fsanitize=address
endif
@@ -262,8 +274,11 @@ opts+=$(debug_opts)
opts+=$(foreach v,$(passthru_opts),$(if $($(v)),-D$(v)))
opts+=$(WFLAGS) $(CPPFLAGS) $(CFLAGS)
cxxopts:=$(opts) $(CXXFLAGS) -std=c++17
CXXFLAGS+=-std=c++17 # force c17 for c++ since most vpss run older ubuntu versions with old compilers
opts+=$(WFLAGS) $(CFLAGS)
cxxopts:=$(opts) $(CXXFLAGS)
opts+=$(CWFLAGS) # warning flags that shouldnt be passed to c++ compiler
libs+=$(LDFLAGS) -lstdc++ -lpthread
asflags:=$(ASFLAGS) -x assembler-with-cpp
@@ -375,12 +390,12 @@ ifdef Echo_name
@printf '%-20.20s\r' $$<
endif
endif
$(.)$(cc) -MM -MF $$@ -MT $(objdir)/$$*.o $(2) $$<
$(.)$(2) -MM -MF $$@ -MT $(objdir)/$$*.o $(3) $$<
endef
$(eval $(call _recipe,c))
$(eval $(call _recipe,cpp))
$(eval $(call _recipe,s,$(asflags)))
$(eval $(call _recipe,c,$(cc)))
$(eval $(call _recipe,cpp,$(cxx)))
$(eval $(call _recipe,s,$(cc),$(asflags)))
# compiling recipe template
# 1: target file suffix
+2 -3
View File
@@ -6,8 +6,7 @@ passthru_opts+=\
NOHW NOMD5 NOPOSTPROCESSING\
MOBJCONSISTANCY PACKETDROP ZDEBUG\
HAVE_MINIUPNPC\
HAVE_DISCORDRPC DEVELOP\
NOBLUAJIT
HAVE_DISCORDRPC DEVELOP
# build with debugging information
ifdef DEBUGMODE
@@ -98,7 +97,7 @@ opts+=-DHAVE_VALGRIND
endif
default_packages:=\
GME/libgme/LIBGME\
LIBGME/libgme/LIBGME\
OPENMPT/libopenmpt/LIBOPENMPT\
ZLIB/zlib\
+6 -8
View File
@@ -20,10 +20,6 @@ $(foreach v,$(join $(wordlist 2,$(_n),- $(gcc_versions)),\
CXXFLAGS+= -Wno-aggregate-return
# -W -Wno-unused
ifdef GCC150
opts+=-std=gnu17
endif
WFLAGS:=-Wall -Wno-trigraphs
ifndef GCC295
#WFLAGS+=-Wno-packed
@@ -45,7 +41,8 @@ ifdef GCC41
WFLAGS+=-Wshadow
endif
#WFLAGS+=-Wlarger-than-%len%
WFLAGS+=-Wpointer-arith -Wbad-function-cast
WFLAGS+=-Wpointer-arith
CWFLAGS+=-Wbad-function-cast
ifdef GCC45
#WFLAGS+=-Wc++-compat
endif
@@ -75,9 +72,10 @@ endif
endif
#WFLAGS+=-Wstrict-prototypes
ifdef GCC40
WFLAGS+=-Wold-style-definition
CWFLAGS+=-Wold-style-definition
endif
WFLAGS+=-Wmissing-prototypes -Wmissing-declarations
WFLAGS+=-Wmissing-declarations
CWFLAGS+=-Wmissing-prototypes
ifdef GCC40
WFLAGS+=-Wmissing-field-initializers
endif
@@ -88,7 +86,7 @@ endif
#WFLAGS+=-Wpacked
#WFLAGS+=-Wpadded
#WFLAGS+=-Wredundant-decls
WFLAGS+=-Wnested-externs
CWFLAGS+=-Wnested-externs
#WFLAGS+=-Wunreachable-code
WFLAGS+=-Winline
ifdef DEBUGMODE
+1 -1
View File
@@ -66,7 +66,7 @@ $(eval $(call _set,LIBGME))
lib:=../libs/libopenmpt
LIBOPENMPT_opts:=-I$(lib)/inc
LIBOPENMPT_libs:=-L$(lib)/lib/$(x86)/mingw -lopenmpt
LIBOPENMPT_libs:=-L$(lib)/lib/$(x86) -lopenmpt
$(eval $(call _set,LIBOPENMPT))
lib:=../libs/SDL2_mixer/$(mingw)
+1
View File
@@ -29,6 +29,7 @@ m_cond.c
m_fixed.c
m_menu.c
m_textinput.c
m_emotes.cpp
m_misc.c
m_perfstats.c
m_queue.c
+21 -1
View File
@@ -36,6 +36,26 @@ LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
/* extra error code for `luaL_load' */
#define LUA_ERRFILE (LUA_ERRERR+1)
/* Compiler-specific attributes and other macros */
#ifdef __GNUC__ // __attribute__ ((X))
#if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && defined (__MINGW32__) // MinGW, >= GCC 4.1
#if 0 //defined (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO > 0
#define FUNCREPORT __attribute__ ((format(gnu_printf, 2, 3)))
#elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) // >= GCC 4.4
#define FUNCREPORT __attribute__ ((format(ms_printf, 2, 3)))
#else
#define FUNCREPORT __attribute__ ((format(printf, 2, 3)))
#endif
#else
#define FUNCREPORT __attribute__ ((format(printf, 2, 3)))
#endif
#endif
#ifndef FUNCREPORT
#define FUNCREPORT
#endif
typedef struct luaL_Reg {
const char *name;
@@ -70,7 +90,7 @@ LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
LUALIB_API void (luaL_where) (lua_State *L, int lvl);
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
LUALIB_API FUNCREPORT int (luaL_error) (lua_State *L, const char *fmt, ...);
LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
const char *const lst[]);
+823 -728
View File
File diff suppressed because it is too large. Load diff
+2 -3
View File
@@ -42,8 +42,8 @@ applications may follow different packet versions.
#define VANILLA_GT_MATCH 3
// Networking and tick handling related.
#define BACKUPTICS 32
#define TICQUEUE 512 // more than enough for most timeouts....
#define BACKUPTICS 512 // more than enough for most timeouts....
#define CLIENTBACKUPTICS 32
#define MAXTEXTCMD 256
// No. of tics your controls can be delayed by.
@@ -533,7 +533,6 @@ extern UINT32 serverlistultimatecount;
extern INT32 mapchangepending;
// Points inside doomcom
extern doomdata_t *netbuffer;
extern consvar_t cv_stunserver;
extern consvar_t cv_httpsource;
extern consvar_t cv_kicktime;
+4 -1
View File
@@ -40,6 +40,7 @@
#include "g_game.h"
#include "g_input.h"
#include "hu_stuff.h"
#include "m_emotes.h"
#include "i_sound.h"
#include "i_system.h"
#include "i_time.h"
@@ -927,7 +928,7 @@ void D_SRB2Loop(void)
// consoleplayer -> displayplayers (hear sounds from viewpoint)
S_UpdateSounds(); // move positional sounds
LUA_Step();
//LUA_Step();
#ifdef HAVE_DISCORDRPC
if (!dedicated && renderisnewtic)
@@ -2036,6 +2037,8 @@ void D_SRB2Main(void)
S_InitMusicDefs();
M_InitEmotes();
CONS_Printf("ST_Init(): Init status bar.\n");
ST_Init();
+34 -29
View File
@@ -48,12 +48,6 @@ tic_t connectiontimeout = (10*TICRATE);
/// \brief network packet
doomcom_t *doomcom = NULL;
/// \brief network packet data, points inside doomcom
doomdata_t *netbuffer = NULL;
/// \brief hole punching packet, also points inside doomcom
#ifdef HOLEPUNCH
holepunch_t *holepunchpacket = NULL;
#endif
#ifdef DEBUGFILE
FILE *debugfile = NULL; // put some net info in a file during the game
@@ -209,13 +203,9 @@ static node_t nodes[MAXNETNODES];
// 0 if a = n (mod 256)
// >0 if a > b (mod 256)
// mnemonic: to use it compare to 0: cmpack(a,b)<0 is "a < b" ...
FUNCMATH static INT32 cmpack(UINT8 a, UINT8 b)
FUNCMATH static inline INT32 cmpack(UINT8 a, UINT8 b)
{
register INT32 d = a - b;
if (d >= 127 || d < -128)
return -d;
return d;
return (SINT8)(a - b);
}
/** Sets freeack to a free acknum and copies the netbuffer in the ackpak table
@@ -229,6 +219,8 @@ static boolean GetFreeAcknum(UINT8 *freeack)
node_t *node = &nodes[doomcom->remotenode];
INT32 i, numfreeslot = 0;
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
if (cmpack((UINT8)((node->remotefirstack + MAXACKTOSEND) % 256), node->nextacknum) < 0)
{
DEBFILE(va("too fast %d %d\n",node->remotefirstack,node->nextacknum));
@@ -298,6 +290,7 @@ static boolean Processackpak(void)
INT32 i;
boolean goodpacket = true;
node_t *node = &nodes[doomcom->remotenode];
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
// Received an ack return, so remove the ack in the list
if (netbuffer->ackreturn && cmpack(node->remotefirstack, netbuffer->ackreturn) < 0)
@@ -307,7 +300,7 @@ static boolean Processackpak(void)
// Search the ackbuffer and free it
for (i = 0; i < MAXACKPACKETS; i++)
{
if (ackpak[i].acknum && ackpak[i].destinationnode == node - nodes
if (ackpak[i].acknum && ackpak[i].destinationnode == doomcom->remotenode
&& cmpack(ackpak[i].acknum, netbuffer->ackreturn) <= 0)
{
RemoveAck(i);
@@ -423,6 +416,7 @@ void Net_SendAcks(INT32 node)
#ifdef NONET
(void)node;
#else
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
netbuffer->packettype = PT_NOTHING;
M_Memcpy(netbuffer->u.textcmd, nodes[node].acktosend, MAXACKTOSEND);
HSendPacket(node, false, 0, MAXACKTOSEND);
@@ -434,6 +428,8 @@ static void GotAcks(void)
{
INT32 i, j;
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
for (j = 0; j < MAXACKTOSEND; j++)
{
if (netbuffer->u.textcmd[j])
@@ -487,6 +483,8 @@ void Net_AckTicker(void)
#ifndef NONET
INT32 i;
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
for (i = 0; i < MAXACKPACKETS; i++)
{
const INT32 nodei = ackpak[i].destinationnode;
@@ -542,6 +540,7 @@ void Net_UnAcknowledgePacket(INT32 node)
#ifdef NONET
(void)node;
#else
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
INT32 hm1 = (nodes[node].acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND;
DEBFILE(va("UnAcknowledge node %d\n", node));
@@ -736,6 +735,7 @@ void Net_CloseConnection(INT32 node)
//
static UINT32 NetbufferChecksum(void)
{
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
UINT32 c = 0x1234567;
const INT32 l = doomcom->datalength - 4;
const UINT8 *buf = (UINT8 *)netbuffer + 4;
@@ -852,6 +852,8 @@ const char *Net_GetPacketName(UINT8 packettype)
static void DebugPrintpacket(const char *header)
{
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
fprintf(debugfile, "%-12s (node %d,ack %d,ackret %d,size %d) type(%d) : %s\n",
header, doomcom->remotenode, netbuffer->ack, netbuffer->ackreturn, doomcom->datalength,
netbuffer->packettype, Net_GetPacketName(netbuffer->packettype));
@@ -1021,6 +1023,7 @@ void Command_Droprate(void)
#ifndef NONET
static boolean ShouldDropPacket(void)
{
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
return (packetdropquantity[netbuffer->packettype])
|| (packetdroprate != 0 && rand() < (((double)RAND_MAX) * (packetdroprate / 100.f))) || packetdroprate == 100;
}
@@ -1032,6 +1035,7 @@ static boolean ShouldDropPacket(void)
//
boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlength)
{
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
doomcom->datalength = (INT16)(packetlength + BASEPACKETSIZE);
if (node == 0) // Packet is to go back to us
@@ -1132,7 +1136,7 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen
//
boolean HGetPacket(void)
{
//boolean nodejustjoined;
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
// Get a packet from self
if (rebound_tail != rebound_head)
@@ -1220,6 +1224,18 @@ static void Internal_FreeNodenum(INT32 nodenum)
(void)nodenum;
}
static char *I_NetSplitAddress(char *host, char **port)
{
boolean v4 = (host[0] != '[');
host = strtok(host, v4 ? ":" : "[]");
if (port)
*port = strtok(NULL, ":");
return host;
}
SINT8 I_NetMakeNode(const char *hostname)
{
SINT8 newnode = -1;
@@ -1227,20 +1243,14 @@ SINT8 I_NetMakeNode(const char *hostname)
if (I_NetMakeNodewPort)
{
char *localhostname = strdup(hostname);
char *t = localhostname;
const char *port;
char *port;
if (!localhostname)
return newnode;
// retrieve portnum from address!
strtok(localhostname, ":");
port = strtok(NULL, ":");
hostname = I_NetSplitAddress(localhostname, &port);
// remove the port in the hostname as we've it already
while ((*t != ':') && (*t != '\0'))
t++;
*t = '\0';
newnode = I_NetMakeNodewPort(localhostname, port);
newnode = I_NetMakeNodewPort(hostname, port);
free(localhostname);
}
return newnode;
@@ -1332,11 +1342,6 @@ boolean D_CheckNetGame(void)
if (doomcom->numnodes > MAXNETNODES)
I_Error("Too many nodes (%d), max:%d", doomcom->numnodes, MAXNETNODES);
netbuffer = (doomdata_t *)(void *)&doomcom->data;
#ifdef HOLEPUNCH
holepunchpacket = (holepunch_t *)(void *)&doomcom->data;
#endif
#ifdef DEBUGFILE
if (M_CheckParm("-debugfile"))
{
+3
View File
@@ -21,6 +21,7 @@
#include "i_system.h"
#include "g_game.h"
#include "hu_stuff.h"
#include "m_emotes.h"
#include "g_input.h"
#include "m_menu.h"
#include "r_local.h"
@@ -912,6 +913,8 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_keyboardlayout);
CV_RegisterVar(&cv_emotes);
// time attack ghost options are also saved to config
CV_RegisterVar(&cv_ghost_besttime);
CV_RegisterVar(&cv_ghost_bestlap);
+6
View File
@@ -142,6 +142,7 @@ UINT8 *PutFileNeeded(UINT16 firstfile)
{
size_t i;
UINT8 count = 0;
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
UINT8 *p_start = netbuffer->packettype == PT_MOREFILESNEEDED ? netbuffer->u.filesneededcfg.files : netbuffer->u.serverinfo.fileneeded;
UINT8 *p = p_start;
char wadfilename[MAX_WADPATH] = "";
@@ -323,6 +324,7 @@ boolean CL_SendRequestFile(void)
#ifdef MORELEGACYDOWNLOADER
boolean firstloop = true;
#endif
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
#ifdef PARANOIA
if (M_CheckParm("-nodownload"))
@@ -451,9 +453,11 @@ tryagain:
// returns false if a requested file was not found or cannot be sent
boolean Got_RequestFilePak(INT32 node)
{
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
char wad[MAX_WADPATH+1];
UINT8 *p = netbuffer->u.textcmd;
UINT8 id;
while (p < netbuffer->u.textcmd + MAXTEXTCMD) // Don't allow hacked client to overflow
{
id = READUINT8(p);
@@ -817,6 +821,7 @@ void SV_FileSendTicker(void)
size_t size;
filetx_t *f;
INT32 packetsent, ram, i, j;
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
if (!filestosend) // No file to send
return;
@@ -945,6 +950,7 @@ void SV_FileSendTicker(void)
void Got_Filetxpak(void)
{
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
INT32 filenum = netbuffer->u.filetxpak.fileid;
fileneeded_t *file = &fileneeded[filenum];
char *filename = file->filename;
-1
View File
@@ -1616,7 +1616,6 @@ actionpointer_t actionpointers[] =
{A_BrakLobShot, "A_BRAKLOBSHOT"},
{A_NapalmScatter, "A_NAPALMSCATTER"},
{A_SpawnFreshCopy, "A_SPAWNFRESHCOPY"},
//{A_InvincSparkleRotate, "A_INVINCSPARKLEROTATE"},
{NULL, "NONE"},
+4
View File
@@ -70,7 +70,11 @@ extern "C" {
#include <string.h>
#define _USE_MATH_DEFINES // fixes M_PI errors in r_plane.c for Visual Studio
#ifdef __cplusplus
#include <cmath>
#else
#include <math.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
+1 -1
View File
@@ -575,7 +575,7 @@ extern consvar_t cv_downloading; // allow clients to downloading WADs.
extern consvar_t cv_nettimeout; // SRB2Kart: Advanced server options menu
extern consvar_t cv_jointimeout;
extern consvar_t cv_maxping;
extern ticcmd_t netcmds[TICQUEUE][MAXPLAYERS];
extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS];
extern INT32 serverplayer;
extern INT32 adminplayers[MAXPLAYERS];
+11 -10
View File
@@ -365,8 +365,8 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
char searchpath[1024];
size_t *searchpathindex;
dirhandle = (DIR**) malloc(maxsearchdepth * sizeof (DIR*));
searchpathindex = (size_t *) malloc(maxsearchdepth * sizeof (size_t));
dirhandle = (DIR**) malloc(maxsearchdepth * sizeof(DIR*));
searchpathindex = (size_t *) malloc(maxsearchdepth * sizeof(size_t));
strcpy(searchpath,startpath);
searchpathindex[--depthleft] = strlen(searchpath) + 1;
@@ -410,14 +410,14 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
}
// okay, now we actually want searchpath to incorporate d_name
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
strcpy(&searchpath[searchpathindex[depthleft]], dent->d_name);
#if defined(__linux__) || defined(__FreeBSD__)
if (dent->d_type == DT_UNKNOWN && lstat(searchpath,&fsstat) == 0)
if (dent->d_type == DT_UNKNOWN && lstat(searchpath, &fsstat) == 0)
{
if (S_ISDIR(fsstat.st_mode))
dent->d_type = DT_DIR;
else if (S_ISLNK(fsstat.st_mode))
else if (S_ISLNK(fsstat.st_mode))
dent->d_type = DT_LNK;
}
@@ -439,11 +439,12 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
{
searchpathindex[--depthleft] = strlen(searchpath) + 1;
dirhandle[depthleft] = opendir(searchpath);
if (!dirhandle[depthleft])
{
// can't open it... maybe no read-permissions
// go back to previous dir
depthleft++;
// can't open it... maybe no read-permissions
// go back to previous dir
depthleft++;
}
searchpath[searchpathindex[depthleft]-1] = PATHSEP[0];
@@ -455,9 +456,9 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
{
case FS_FOUND:
if (completepath)
strcpy(filename,searchpath);
strcpy(filename, searchpath);
else
strcpy(filename,dent->d_name);
strcpy(filename, dent->d_name);
retval = FS_FOUND;
found = 1;
break;
+2 -2
View File
@@ -1051,7 +1051,7 @@ void G_ConsGhostTic(INT32 playernum)
mobj = NULL;
for (th = thinkercap.next; th != &thinkercap; th = th->next)
{
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
if (th->function != (actionf_p1)P_MobjThinker)
continue;
mobj = (mobj_t *)th;
if (mobj->type == (mobjtype_t)type && mobj->x == x && mobj->y == y && mobj->z == z)
@@ -3701,7 +3701,7 @@ void G_DoPlayMetal(void)
// find metal sonic
for (th = thinkercap.next; th != &thinkercap; th = th->next)
{
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
if (th->function != (actionf_p1)P_MobjThinker)
continue;
mo = (mobj_t *)th;
+1 -3939
View File
File diff suppressed because it is too large. Load diff
-2
View File
@@ -21,8 +21,6 @@ extern "C" {
#include "hw_data.h"
#include "hw_gl.h"
extern boolean currently_batching;
typedef struct
{
FSurfaceInfo surf;// surf also has its own polyflags for some reason, but it seems unused
+208 -136
View File
@@ -48,14 +48,20 @@ typedef struct
// if no portals are found, the portal scanning phase can be skipped while rendering, saving a bit of time.
boolean gl_maphasportals = false;
// Determine on mapload if current map has any Horizonlines present
// so we can avoid rather hot checks in HWR_Subsector
boolean gl_maphashorizonlines = false;
// ==========================================================================
// FLOOR & CEILING CONVEX POLYS GENERATION
// ==========================================================================
//debug counters
#ifdef DEBUG_HWBSP
static INT32 nobackpoly = 0;
static INT32 skipcut = 0;
static INT32 totalsubsecpolys = 0;
#endif
// --------------------------------------------------------------------------
// Polygon fast alloc / free
@@ -96,8 +102,8 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
double frac;
double num;
double den;
double v1x,v1y,v1dx,v1dy;
double v2x,v2y,v2dx,v2dy;
double v1x, v1y, v1dx, v1dy;
double v2x, v2y, v2dx, v2dy;
// a segment of a polygon
v1x = v1->x;
@@ -112,6 +118,7 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
v2dy = bsp->dy;
den = v2dy*v1dx - v2dx*v1dy;
if (fabsf((float)den) < 1.0E-36f) // avoid checking exactly for 0.0
return NULL; // parallel
@@ -119,6 +126,7 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
// (do not accept hit with the extensions)
num = (v2x - v1x)*v2dy + (v1y - v2y)*v2dx;
frac = num / den;
if (frac < 0.0l || frac > 1.0l)
return NULL;
@@ -128,7 +136,6 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
frac = num / den;
bspfrac = (float)frac;
// find the interception point along the partition line
pt.x = (float)(v2x + v2dx*frac);
pt.y = (float)(v2y + v2dy*frac);
@@ -136,37 +143,18 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
return &pt;
}
#define DIVLINE_VERTEX_DIFF 0.45f
// if two vertice coords have a x and/or y difference
// of less or equal than 1 FRACUNIT, they are considered the same
// point. Note: hardcoded value, 1.0f could be anything else.
static boolean SameVertice (polyvertex_t *p1, polyvertex_t *p2)
{
#if 0
float diff;
diff = p2->x - p1->x;
if (diff < -1.5f || diff > 1.5f)
if (fabsf( p2->x - p1->x ) > DIVLINE_VERTEX_DIFF)
return false;
diff = p2->y - p1->y;
if (diff < -1.5f || diff > 1.5f)
if (fabsf( p2->y - p1->y ) > DIVLINE_VERTEX_DIFF)
return false;
#elif 0
if (p1->x != p2->x)
return false;
if (p1->y != p2->y)
return false;
#elif 0
if (fabsf( p2->x - p1->x ) > 1.0E-36f )
return false;
if (fabsf( p2->y - p1->y ) > 1.0E-36f )
return false;
#else
#define DIVLINE_VERTEX_DIFF 0.45f
static const float ep = DIVLINE_VERTEX_DIFF;
if (fabsf( p2->x - p1->x ) > ep )
return false;
if (fabsf( p2->y - p1->y ) > ep )
return false;
#endif
// p1 and p2 are considered the same vertex
return true;
}
@@ -182,22 +170,23 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
poly_t **frontpoly, //return one poly here
poly_t **backpoly) //return the other here
{
INT32 i,j;
INT32 i, j;
polyvertex_t *pv;
INT32 ps = -1,pe = -1;
INT32 nptfront,nptback;
INT32 ps = -1, pe = -1;
INT32 nptfront, nptback;
polyvertex_t vs = {0,0,0};
polyvertex_t ve = {0,0,0};
polyvertex_t lastpv = {0,0,0};
float fracs = 0.0f,frace = 0.0f; //used to tell which poly is on
// the front side of the bsp partition line
INT32 psonline = 0, peonline = 0;
float fracs = 0.0f, frace = 0.0f; //used to tell which poly is on
// the front side of the bsp partition line
INT32 psonline = 0, peonline = 0;
for (i = 0; i < poly->numpts; i++)
{
j = i + 1;
if (j == poly->numpts) j = 0;
if (j == poly->numpts)
j = 0;
// start & end points
pv = fracdivline(bsp, &poly->pts[i], &poly->pts[j]);
@@ -284,7 +273,7 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
return;
}
if (pe <= ps)
if (UNLIKELY(pe <= ps))
I_Error("SplitPoly: invalid splitting line (%d %d)", ps, pe);
// number of points on each side, _not_ counting those
@@ -296,6 +285,7 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
*backpoly = HWR_AllocPoly(2 + nptback);
else
*backpoly = NULL;
if (nptfront > 0)
*frontpoly = HWR_AllocPoly(2 + nptfront);
else
@@ -308,10 +298,12 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
*pv++ = vs;
*pv++ = ve;
i = pe;
do
{
if (++i == poly->numpts)
i = 0;
*pv++ = poly->pts[i];
} while (i != ps && --nptfront);
}
@@ -323,10 +315,12 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
*pv++ = ve;
*pv++ = vs;
i = ps;
do
{
if (++i == poly->numpts)
i = 0;
*pv++ = poly->pts[i];
} while (i != pe && --nptback);
}
@@ -353,36 +347,48 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly)
{
INT32 i, j;
polyvertex_t *pv;
INT32 nump = 0, ps, pe;
polyvertex_t vs = {0, 0, 0}, ve = {0, 0, 0},
p1 = {0, 0, 0}, p2 = {0, 0, 0};
p1 = {0, 0, 0}, p2 = {0, 0, 0};
float fracs = 0.0f;
fdivline_t cutseg; // x, y, dx, dy as start of node_t struct
poly_t *temppoly;
// for each seg of the subsector
for (; count--; lseg++)
{
//x,y,dx,dy (like a divline)
// x, y, dx, dy (like a divline)
const line_t *line = lseg->linedef;
// portal check
if (!gl_maphasportals && line->special == PORTALSPECIAL && lseg->side == 0)
if (UNLIKELY(!gl_maphasportals && line->special == PORTALSPECIAL && lseg->side == 0))
{
// Find the other side!
INT32 line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->tag, -1);
if (line == &lines[line2])
line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->tag, line2);
if (line2 >= 0) // found it!
gl_maphasportals = 1;
}
if (!gl_maphashorizonlines && line->special == HORIZONSPECIAL)
gl_maphashorizonlines = true;
if (line->sidenum[1] != 0xffff)
{
if (sides[line->sidenum[0]].sector == sides[line->sidenum[1]].sector)
{
// Segs that are self-ref linedef do not cutout the subsector.
#ifdef DEBUG_HWBSP
CONS_Debug(DBG_RENDER, "CutOutSubsecPoly: self ref line %i\n", line - lines);
#endif
continue;
}
}
p1.x = FIXED_TO_FLOAT(lseg->side ? line->v2->x : line->v1->x);
p1.y = FIXED_TO_FLOAT(lseg->side ? line->v2->y : line->v1->y);
p2.x = FIXED_TO_FLOAT(lseg->side ? line->v1->x : line->v2->x);
@@ -396,6 +402,7 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly)
// see if it cuts the convex poly
ps = -1;
pe = -1;
for (i = 0; i < poly->numpts; i++)
{
j = i + 1;
@@ -438,6 +445,7 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly)
ve = vs;
vs = *pv;
}
//found 2nd point
break;
}
@@ -451,25 +459,32 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly)
{
// generate FRONT poly
temppoly = HWR_AllocPoly(nump);
pv = temppoly->pts;
*pv++ = vs;
*pv++ = ve;
do
{
if (++ps == poly->numpts)
ps = 0;
*pv++ = poly->pts[ps];
} while (ps != pe);
HWR_FreePoly(poly);
poly = temppoly;
}
//hmmm... maybe we should NOT accept this, but this happens
#ifdef DEBUG_HWBSP
// hmmm... maybe we should NOT accept this, but this happens
// only when the cut is not needed it seems (when the cut
// line is aligned to one of the borders of the poly, and
// only some times..)
else
{
skipcut++;
// I_Error("CutOutPoly: only one point for split line (%d %d) %d", ps, pe, debugpos);
I_Error("CutOutPoly: only one point for split line (%d %d) %d", ps, pe, debugpos);
}
#endif
}
}
return poly;
@@ -492,8 +507,10 @@ static inline void HWR_SubsecPoly(INT32 num, poly_t *poly)
if (poly)
{
poly = CutOutSubsecPoly (lseg,count,poly);
poly = CutOutSubsecPoly(lseg,count,poly);
#ifdef DEBUG_HWBSP
totalsubsecpolys++;
#endif
//extra data for this subsector
extrasubsectors[num].planepoly = poly;
}
@@ -503,8 +520,8 @@ static inline void HWR_SubsecPoly(INT32 num, poly_t *poly)
// search for the segs source of this divline
static inline void SearchDivline(node_t *bsp, fdivline_t *divline)
{
divline->x = FIXED_TO_FLOAT(bsp->x);
divline->y = FIXED_TO_FLOAT(bsp->y);
divline->x = FIXED_TO_FLOAT(bsp->x);
divline->y = FIXED_TO_FLOAT(bsp->y);
divline->dx = FIXED_TO_FLOAT(bsp->dx);
divline->dy = FIXED_TO_FLOAT(bsp->dy);
}
@@ -562,10 +579,12 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
if (poly && poly->numpts > 2)
{
CONS_Debug(DBG_RENDER, "Adding a new subsector\n");
if (addsubsector == numsubsectors + NEWSUBSECTORS)
if (UNLIKELY(addsubsector == numsubsectors + NEWSUBSECTORS))
I_Error("WalkBSPNode: not enough addsubsectors\n");
else if (addsubsector > 0x7fff)
else if (UNLIKELY(addsubsector > 0x7fff))
I_Error("WalkBSPNode: addsubsector > 0x7fff\n");
*leafnode = (UINT16)((UINT16)addsubsector | NF_SUBSECTOR);
extrasubsectors[addsubsector].planepoly = poly;
addsubsector++;
@@ -587,6 +606,7 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
}
#endif
}
M_ClearBox(bbox);
poly = extrasubsectors[bspnum & ~NF_SUBSECTOR].planepoly;
@@ -601,12 +621,14 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
SplitPoly(&fdivline, poly, &frontpoly, &backpoly);
poly = NULL;
#ifdef DEBUG_HWBSP
//debug
if (!backpoly)
nobackpoly++;
#endif
// Recursively divide front space.
if (frontpoly)
if (LIKELY(frontpoly))
{
WalkBSPNode(bsp->children[0], frontpoly, &bsp->children[0],bsp->bbox[0]);
@@ -641,53 +663,79 @@ void HWR_FreeExtraSubsectors(void)
#define MAXDIST 1.5f
// BP: can't move vertex: DON'T change polygon geometry! (convex)
//#define MOVEVERTEX
static boolean PointInSeg(polyvertex_t *a,polyvertex_t *v1,polyvertex_t *v2)
// Is vertex va within the seg v1, v2
static boolean PointInSeg(polyvertex_t *va,polyvertex_t *v1,polyvertex_t *v2)
{
register float ax,ay,bx,by,cx,cy,d,norm;
register polyvertex_t *p;
register float ax, ay, bx, by, cx, cy, d, norm;
// check bbox of the seg first
if (v1->x > v2->x)
// check bbox of the seg first (without altering v1, v2)
if (v2->x > v1->x)
{
p = v1;
v1 = v2;
v2 = p;
// check if x within seg box v1..v2
if ((va->x + MAXDIST) < v1->x) return false;
if ((va->x - MAXDIST) > v2->x) return false;
}
else
{
// check if x within seg box v2..v1
if ((va->x + MAXDIST) < v2->x) return false;
if ((va->x - MAXDIST) > v1->x) return false;
}
if (a->x < v1->x-MAXDIST || a->x > v2->x+MAXDIST)
return false;
if (v1->y > v2->y)
if (v2->y > v1->y)
{
p = v1;
v1 = v2;
v2 = p;
// check if x within seg box v1..v2
if ((va->y + MAXDIST) < v1->y) return false;
if ((va->y - MAXDIST) > v2->y) return false;
}
else
{
// check if x within seg box v2..v1
if ((va->y + MAXDIST) < v2->y) return false;
if ((va->y - MAXDIST) > v1->y) return false;
}
if (a->y < v1->y-MAXDIST || a->y > v2->y+MAXDIST)
return false;
// v1 = origine
ax= v2->x-v1->x;
ay= v2->y-v1->y;
norm = hypotf(ax, ay);
// v1 = origin
ax = v2->x-v1->x;
ay = v2->y-v1->y;
norm = hypotf(ax, ay); // length of seg
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
if (norm != 0) // yes, this can be exactly 0
#pragma GCC diagnostic pop
{
ax /= norm;
ay /= norm;
ay /= norm; // unit vector along seg, v1->v2
}
bx = a->x-v1->x;
by = a->y-v1->y;
//d = a.b
d =ax*bx+ay*by;
bx = va->x - v1->x;
by = va->y - v1->y; // vector v1->va
// d = (a DOT b), (product of lengths * cosine( angle ))
d = ax*bx+ay*by;
// bound of the seg
if (d < 0 || d > norm)
{
// Also excludes some va within MAXDIST of v1 or v2
return false;
//c = d.1a-b
}
// Cross product.
if (((by * ax) - (bx * ay)) <= 0)
{
// The vertex is to the rightside of the seg, so adding
// it to the polygon would worsen the crack.
return false;
}
// measure the error in vector bx,by as difference squared sum
//c= (d * unit_vector_seg) - b
cx = ax*d-bx;
cy = ay*d-by;
#ifdef MOVEVERTEX
if (cx*cx+cy*cy <= MAXDIST*MAXDIST)
{
@@ -708,7 +756,7 @@ static INT32 numsplitpoly;
static void SearchSegInBSP(INT32 bspnum,polyvertex_t *p,poly_t *poly)
{
poly_t *q;
INT32 j,k;
INT32 j,k;
if (bspnum & NF_SUBSECTOR)
{
@@ -716,47 +764,55 @@ static void SearchSegInBSP(INT32 bspnum,polyvertex_t *p,poly_t *poly)
{
bspnum &= ~NF_SUBSECTOR;
q = extrasubsectors[bspnum].planepoly;
if (poly == q || !q)
return;
for (j = 0; j < q->numpts; j++)
const INT32 numpts = q->numpts;
for (j = 0; j < numpts; j++)
{
k = j+1;
if (k == q->numpts) k = 0;
if (k == numpts)
k = 0;
if (!SameVertice(p, &q->pts[j])
&& !SameVertice(p, &q->pts[k])
&& PointInSeg(p, &q->pts[j],
&q->pts[k]))
&& PointInSeg(p, &q->pts[j], &q->pts[k]))
{
poly_t *newpoly = HWR_AllocPoly(q->numpts+1);
poly_t *newpoly = HWR_AllocPoly(numpts+1);
INT32 n;
for (n = 0; n <= j; n++)
newpoly->pts[n] = q->pts[n];
newpoly->pts[k] = *p;
for (n = k+1; n < newpoly->numpts; n++)
newpoly->pts[n] = q->pts[n-1];
numsplitpoly++;
extrasubsectors[bspnum].planepoly =
newpoly;
extrasubsectors[bspnum].planepoly = newpoly;
HWR_FreePoly(q);
return;
}
}
}
return;
}
if ((FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXBOTTOM])-MAXDIST <= p->y) &&
(FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXTOP ])+MAXDIST >= p->y) &&
(FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXLEFT ])-MAXDIST <= p->x) &&
(FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXRIGHT ])+MAXDIST >= p->x))
SearchSegInBSP(nodes[bspnum].children[0],p,poly);
(FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXTOP ])+MAXDIST >= p->y) &&
(FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXLEFT ])-MAXDIST <= p->x) &&
(FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXRIGHT ])+MAXDIST >= p->x))
SearchSegInBSP(nodes[bspnum].children[0], p, poly);
if ((FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXBOTTOM])-MAXDIST <= p->y) &&
(FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXTOP ])+MAXDIST >= p->y) &&
(FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXLEFT ])-MAXDIST <= p->x) &&
(FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXRIGHT ])+MAXDIST >= p->x))
SearchSegInBSP(nodes[bspnum].children[1],p,poly);
(FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXTOP ])+MAXDIST >= p->y) &&
(FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXLEFT ])-MAXDIST <= p->x) &&
(FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXRIGHT ])+MAXDIST >= p->x))
SearchSegInBSP(nodes[bspnum].children[1], p, poly);
}
// search for T-intersection problem
@@ -780,13 +836,18 @@ static INT32 SolveTProblem(void)
for (l = 0; l < addsubsector; l++)
{
p = extrasubsectors[l].planepoly;
if (!p)
continue;
for (i = 0; i < p->numpts; i++)
SearchSegInBSP((INT32)numnodes-1, &p->pts[i], p);
}
//CONS_Debug(DBG_RENDER, "numsplitpoly %d\n", numsplitpoly);
#ifdef DEBUG_HWBSP
CONS_Debug(DBG_RENDER, "numsplitpoly %d\n", numsplitpoly);
#endif
return numsplitpoly;
}
@@ -826,29 +887,31 @@ static void AdjustSegs(void)
if (lseg->polyseg)
continue;
if (p) {
for (j = 0; j < p->numpts; j++)
for (j = 0; j < p->numpts; j++)
{
distv1 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v1->x);
tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v1->y);
distv1 = distv1*distv1+tmp*tmp;
if (distv1 <= nearv1)
{
distv1 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v1->x);
tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v1->y);
distv1 = distv1*distv1+tmp*tmp;
if (distv1 <= nearv1)
{
v1found = j;
nearv1 = distv1;
}
// the same with v2
distv2 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v2->x);
tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v2->y);
distv2 = distv2*distv2+tmp*tmp;
if (distv2 <= nearv2)
{
v2found = j;
nearv2 = distv2;
}
v1found = j;
nearv1 = distv1;
}
// the same with v2
distv2 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v2->x);
tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v2->y);
distv2 = distv2*distv2+tmp*tmp;
if (distv2 <= nearv2)
{
v2found = j;
nearv2 = distv2;
}
}
if (p && nearv1 <= NEARDIST*NEARDIST)
if (nearv1 <= NEARDIST*NEARDIST)
// share vertice with segs
lseg->pv1 = &(p->pts[v1found]);
else
@@ -863,7 +926,8 @@ static void AdjustSegs(void)
pv->y = FIXED_TO_FLOAT(lseg->v1->y);
lseg->pv1 = pv;
}
if (p && nearv2 <= NEARDIST*NEARDIST)
if (nearv2 <= NEARDIST*NEARDIST)
lseg->pv2 = &(p->pts[v2found]);
else
{
@@ -876,11 +940,15 @@ static void AdjustSegs(void)
// recompute length
{
float x,y;
x = ((polyvertex_t *)lseg->pv2)->x - ((polyvertex_t *)lseg->pv1)->x
+ FIXED_TO_FLOAT(FRACUNIT/2);
y = ((polyvertex_t *)lseg->pv2)->y - ((polyvertex_t *)lseg->pv1)->y
+ FIXED_TO_FLOAT(FRACUNIT/2);
lseg->flength = (float)hypot(x, y);
const polyvertex_t *pv1 = (polyvertex_t *)lseg->pv1;
const polyvertex_t *pv2 = (polyvertex_t *)lseg->pv2;
x = pv2->x - pv1->x + 0.5f;
y = pv2->y - pv1->y + 0.5f;
lseg->flength = hypotf(x, y);
// BP: debug see this kind of segs
//if (nearv2 > NEARDIST*NEARDIST || nearv1 > NEARDIST*NEARDIST)
// lseg->length = 1;
@@ -906,29 +974,29 @@ void HWR_CreatePlanePolygons(INT32 bspnum)
I_FinishUpdate(); // page flip or blit buffer
#endif
// reset the portal flag
gl_maphasportals = 0;
// reset the portal and horizonline flag
gl_maphasportals = gl_maphashorizonlines = 0;
// find min/max boundaries of map
//CONS_Debug(DBG_RENDER, "Looking for boundaries of map...\n");
#ifdef DEBUG_HWBSP
CONS_Debug(DBG_RENDER, "Looking for boundaries of map...\n");
#endif
M_ClearBox(rootbbox);
for (i = 0;i < numvertexes; i++)
M_AddToBox(rootbbox, vertexes[i].x, vertexes[i].y);
//CONS_Debug(DBG_RENDER, "Generating subsector polygons... %d subsectors\n", numsubsectors);
#ifdef DEBUG_HWBSP
CONS_Debug(DBG_RENDER, "Generating subsector polygons... %d subsectors\n", numsubsectors);
#endif
HWR_FreeExtraSubsectors();
// allocate extra data for each subsector present in map
totsubsectors = numsubsectors + NEWSUBSECTORS;
extrasubsectors = calloc(totsubsectors, sizeof (*extrasubsectors));
if (extrasubsectors == NULL)
if (UNLIKELY(extrasubsectors == NULL))
I_Error("couldn't malloc extrasubsectors totsubsectors %s\n", sizeu1(totsubsectors));
// allocate table for back to front drawing of subsectors
/*gl_drawsubsectors = (INT16 *)malloc(sizeof (*gl_drawsubsectors) * totsubsectors);
if (!gl_drawsubsectors)
I_Error("couldn't malloc gl_drawsubsectors\n");*/
// number of the first new subsector that might be added
addsubsector = numsubsectors;
@@ -952,17 +1020,21 @@ void HWR_CreatePlanePolygons(INT32 bspnum)
WalkBSPNode(bspnum, rootp, NULL,rootbbox);
i = SolveTProblem();
//CONS_Debug(DBG_RENDER, "%d point divides a polygon line\n",i);
#ifdef DEBUG_HWBSP
CONS_Debug(DBG_RENDER, "%d point divides a polygon line\n",i);
#endif
AdjustSegs();
#ifdef DEBUG_HWBSP
//debug debug..
//if (nobackpoly)
// CONS_Debug(DBG_RENDER, "no back polygon %u times\n",nobackpoly);
if (nobackpoly)
CONS_Debug(DBG_RENDER, "no back polygon %u times\n",nobackpoly);
//"(should happen only with the deep water trick)"
//if (skipcut)
// CONS_Debug(DBG_RENDER, "%u cuts were skipped because of only one point\n",skipcut);
if (skipcut)
CONS_Debug(DBG_RENDER, "%u cuts were skipped because of only one point\n",skipcut);
//CONS_Debug(DBG_RENDER, "done: %u total subsector convex polygons\n", totalsubsecpolys);
CONS_Debug(DBG_RENDER, "done: %u total subsector convex polygons\n", totalsubsecpolys);
#endif
}
#endif //HWRENDER
-6
View File
@@ -38,12 +38,6 @@ 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)
{
switch (format)
+18 -6
View File
@@ -610,7 +610,7 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength)
}
else // Do TRANSMAP** fade.
{
RGBA_t *palette = HWR_GetTexturePalette();
const RGBA_t *palette = HWR_GetTexturePalette();
Surf.PolyColor.rgba = palette[color&0xFF].rgba;
if (HWR_ShouldUsePaletteRendering())
@@ -794,7 +794,7 @@ void HWR_drawAMline(const fline_t *fl, INT32 color)
{
F2DCoord v1, v2;
RGBA_t color_rgba;
RGBA_t *palette = HWR_GetTexturePalette();
const RGBA_t *palette = HWR_GetTexturePalette();
color_rgba = palette[color&0xFF];
@@ -815,7 +815,7 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
FOutVector v[4];
FSurfaceInfo Surf;
float fx, fy, fw, fh, fwait = 0;
RGBA_t *palette = HWR_GetTexturePalette();
RGBA_t *palette;
if (wh < 0)
return; // consistency w/ software
@@ -860,11 +860,13 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
if (fx >= vid.width || fy >= vid.height)
return;
if (fx < 0)
{
fw += fx;
fx = 0;
}
if (fy < 0)
{
fh += fy;
@@ -873,11 +875,13 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
if (fw <= 0 || fh <= 0)
return;
if (fx + fw > vid.width)
{
fwait = fw - (fvw- fx);
fw = fvw - fx;
}
if (fy + fh > vid.height)
fh = fvh - fy;
@@ -899,6 +903,8 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = 1.0f;
palette = HWR_GetTexturePalette();
Surf.PolyColor = palette[color&0xFF];
GL_DrawPolygon(&Surf, v, 4,
@@ -913,7 +919,6 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
FOutVector v[4];
FSurfaceInfo Surf;
float fx, fy, fw, fh;
RGBA_t *palette = HWR_GetTexturePalette();
if (w < 0 || h < 0)
return; // consistency w/ software
@@ -937,6 +942,7 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
{
RGBA_t *palette = HWR_GetTexturePalette();
RGBA_t rgbaColour = palette[color&0xFF];
FRGBAFloat clearColour;
clearColour.red = (float)rgbaColour.s.red / 255;
@@ -967,6 +973,7 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
else if (!(options & V_SNAPTOTOP))
fy += (fvh - (FLOATBASEVIDHEIGHT * dupy)) / 2;
}
if (options & V_SPLITSCREEN)
fy += (FLOATBASEVIDHEIGHT * dupy)/2;
if (options & V_HORZSCREEN)
@@ -976,11 +983,13 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
if (fx >= vid.width || fy >= vid.height)
return;
if (fx < 0)
{
fw += fx;
fx = 0;
}
if (fy < 0)
{
fh += fy;
@@ -989,8 +998,10 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
if (fw <= 0 || fh <= 0)
return;
if (fx + fw > vid.width)
fw = fvw - fx;
if (fy + fh > vid.height)
fh = fvh - fy;
@@ -1026,12 +1037,13 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
FOutVector v[4];
FSurfaceInfo Surf;
float fx, fy, fw, fh;
UINT8 alphalevel = ((color & V_ALPHAMASK) >> V_ALPHASHIFT);
RGBA_t *palette = HWR_GetTexturePalette();
if (w < 0 || h < 0)
return; // consistency w/ software
const UINT8 alphalevel = ((color & V_ALPHAMASK) >> V_ALPHASHIFT);
const RGBA_t *palette = HWR_GetTexturePalette();
// 3--2
// | /|
// |/ |
+3 -1
View File
@@ -60,6 +60,9 @@ void HWR_FreeExtraSubsectors(void);
// --------
// hw_cache.c
// --------
extern RGBA_t mapPalette[256];
void HWR_InitMapTextures(void);
void HWR_LoadMapTextures(size_t pnumtextures);
void HWR_FreeMapTextures(void);
@@ -85,7 +88,6 @@ void HWR_ClearAllTextures(void);
void HWR_FreeColormapCache(void);
void HWR_UnlockCachedPatch(GLPatch_t *gpatch);
RGBA_t *HWR_GetTexturePalette(void);
void HWR_SetPalette(RGBA_t *palette);
void HWR_SetMapPalette(void);
UINT32 HWR_CreateLightTable(UINT8 *lighttable);
+60 -77
View File
@@ -14,8 +14,6 @@
#ifdef HWRENDER
#include <algorithm>
#define _USE_MATH_DEFINES
#include <cmath>
#include "../doomstat.h"
#include "../doomdef.h"
@@ -99,8 +97,6 @@ line_t *gl_linedef;
sector_t *gl_frontsector;
sector_t *gl_backsector;
static boolean gl_maphashorizonlines = false;
// values for the far clipping plane
static constexpr float clipping_distances[] = {1024.0f, 2048.0f, 4096.0f, 6144.0f, 8192.0f, 12288.0f, 16384.0f};
// values for bsp culling
@@ -132,7 +128,17 @@ static void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, b
static void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, boolean noencore, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap);
static void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap);
static void HWR_AddSprites(sector_t *sec);
namespace
{
enum class AddSpritesType
{
kNoLimitDist,
kLimitDist,
};
template<AddSpritesType> static void HWR_AddSprites(sector_t *);
}
static void HWR_ProjectSprite(mobj_t *thing);
static void HWR_AddPrecipitationSprites(void);
static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing);
@@ -174,7 +180,6 @@ static void CV_glpalettedepth_OnChange(void);
static CV_PossibleValue_t glscreentextures_cons_t[] = {{0, "Off"}, {1, "Wipes Only"}, {2, "All"}, {0, NULL}};
static CV_PossibleValue_t glfakecontrast_cons_t[] = {{0, "Off"}, {1, "Standard"}, {2, "Smooth"}, {0, NULL}};
static CV_PossibleValue_t glshaders_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Ignore custom shaders"}, {0, NULL}};
static CV_PossibleValue_t secbright_cons_t[] = {{0, "MIN"}, {255, "MAX"}, {0, NULL}};
static CV_PossibleValue_t glfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"},
{HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"},
@@ -219,7 +224,6 @@ consvar_t cv_glslopecontrast = {"gr_slopecontrast", "Off", CV_SAVE, CV_OnOff, NU
consvar_t cv_glshaders = {"gr_shaders", "On", CV_CALL|CV_SAVE, glshaders_cons_t, CV_glshaders_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_gllightdither = {"gr_lightdithering", "Off", CV_CALL|CV_SAVE, CV_OnOff, CV_gllightdithering_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_glsecbright = {"secbright", "0", CV_SAVE, secbright_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_glfiltermode = {"gr_filtermode", "Nearest", CV_CALL|CV_SAVE, glfiltermode_cons_t, CV_filtermode_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_glanisotropicmode = {"gr_anisotropicmode", "1", CV_CALL|CV_SAVE, glanisotropicmode_cons_t, CV_anisotropic_OnChange, 0, NULL, NULL, 0, 0, NULL};
@@ -409,6 +413,9 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
tint_color.rgba = (colormap != NULL) ? (UINT32)colormap->rgba : GL_DEFAULTMIX;
fade_color.rgba = (colormap != NULL) ? (UINT32)colormap->fadergba : GL_DEFAULTFOG;
// Clamp the light level, since it can sometimes go out of the 0-255 range from animations
light_level = CLAMP(SOFTLIGHT(light_level), cv_secbright.value, 255);
// Crappy backup coloring if you can't do shaders
if (!HWR_UseShader())
{
@@ -446,9 +453,6 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
poly_color.s.blue = (UINT8)blue;
}
// Clamp the light level, since it can sometimes go out of the 0-255 range from animations
light_level = CLAMP(SOFTLIGHT(light_level), cv_glsecbright.value, 255);
// in palette rendering mode, this is not needed since it properly takes the changes to the palette itself
if (!HWR_ShouldUsePaletteRendering())
{
@@ -704,7 +708,8 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
for (i = 0, v3d = planeVerts; i < (INT32)nrPlaneVerts; i++,v3d++,pv++)
SETUP3DVERT(v3d, pv->x, pv->y);
lightlevel = HWR_CalcSlopeLight(lightlevel, slope, gl_frontsector, (FOFsector != NULL));
if (slope)
lightlevel = HWR_CalcSlopeLight(lightlevel, slope, gl_frontsector, (FOFsector != NULL));
HWR_Lighting(&Surf, lightlevel, planecolormap, P_SectorUsesDirectionalLighting(gl_frontsector));
@@ -3026,7 +3031,7 @@ static void HWR_Subsector(size_t num)
// rendering heights for bottom and top planes
// yes there were functions for this stuff, no idea why it wasnt used but bleh
bottomCullHeight = P_GetFFloorBottomZAt(rover, viewx, viewy);
topCullHeight = P_GetFFloorTopZAt(rover, viewx, viewy);
topCullHeight = P_GetFFloorTopZAt(rover, viewx, viewy);
if (gl_frontsector->cullheight)
{
@@ -3166,7 +3171,10 @@ doaddline:
{
// draw sprites first, coz they are clipped to the solidsegs of
// subsectors more 'in front'
HWR_AddSprites(gl_frontsector);
if (cv_drawdist.value || current_bsp_culling_distance)
HWR_AddSprites<AddSpritesType::kLimitDist>(gl_frontsector);
else
HWR_AddSprites<AddSpritesType::kNoLimitDist>(gl_frontsector);
//Hurdler: at this point validcount must be the same, but is not because
// gl_frontsector doesn't point anymore to sub->sector due to
@@ -3522,7 +3530,7 @@ static void HWR_DrawSpriteShadow(gl_vissprite_t *spr, patch_t *gpatch, GLPatch_t
// This is expecting a pointer to an array containing 4 wallVerts for a sprite
static void HWR_RotateSpritePolyToAim(gl_vissprite_t *spr, FOutVector *wallVerts, const boolean precip, const boolean papersprite)
{
if (!cv_glspritebillboarding.value || !spr || !spr->mobj || !wallVerts || papersprite)
if (!cv_glspritebillboarding.value || papersprite)
{
return;
}
@@ -3762,7 +3770,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
continue;
if (!lightset)
lightlevel = static_cast<INT32>(CLAMP(*list[i-1].lightlevel, 0, 255));
lightlevel = static_cast<INT32>(*list[i-1].lightlevel);
colormap = list[i-1].extra_colormap;
break;
@@ -3781,7 +3789,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
{
if (!lightset)
{
lightlevel = static_cast<INT32>(CLAMP(*list[i].lightlevel, 0, 255));
lightlevel = static_cast<INT32>(*list[i].lightlevel);
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, false);
}
@@ -3988,7 +3996,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
if (!lightset)
{
lightlevel = static_cast<INT32>(CLAMP(sector->lightlevel, 0, 255));
lightlevel = static_cast<INT32>(sector->lightlevel);
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, false);
}
@@ -4089,7 +4097,7 @@ static void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
// colormap test
sector_t *sector = sprmo->subsector->sector;
UINT8 lightlevel = 255;
INT32 lightlevel = 255;
extracolormap_t *colormap = sector->extra_colormap;
if (sector->numlights)
@@ -4099,7 +4107,7 @@ static void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
light = R_GetPlaneLight(sector, sprmo->z + sprmo->height, false); // Always use the light at the top instead of whatever I was doing before
if (!(sprmo->frame & FF_FULLBRIGHT))
lightlevel = static_cast<UINT8>(CLAMP(*sector->lightlist[light].lightlevel, 0, 255));
lightlevel = static_cast<INT32>(*sector->lightlist[light].lightlevel);
if (sector->lightlist[light].extra_colormap)
colormap = sector->lightlist[light].extra_colormap;
@@ -4107,7 +4115,7 @@ static void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
else
{
if (!(sprmo->frame & FF_FULLBRIGHT))
lightlevel = static_cast<UINT8>(CLAMP(sector->lightlevel, 0, 255));
lightlevel = static_cast<INT32>(sector->lightlevel);
if (sector->extra_colormap)
colormap = sector->extra_colormap;
@@ -4528,6 +4536,10 @@ static void HWR_DrawSprites(void)
// HWR_AddSprites
// During BSP traversal, this adds sprites by sector.
// --------------------------------------------------------------------------
namespace
{
template <AddSpritesType Type>
static void HWR_AddSprites(sector_t *sec)
{
mobj_t *thing;
@@ -4543,22 +4555,29 @@ static void HWR_AddSprites(sector_t *sec)
// Well, now it will be done.
sec->validcount = validcount;
limit_dist = cv_drawdist.value;
if (current_bsp_culling_distance)
if constexpr (Type == AddSpritesType::kLimitDist)
{
// Use the smaller setting
if (limit_dist)
limit_dist = std::min(current_bsp_culling_distance/mapobjectscale, limit_dist);
else
limit_dist = current_bsp_culling_distance/mapobjectscale;
limit_dist = cv_drawdist.value;
if (current_bsp_culling_distance)
{
// Use the smaller setting
if (limit_dist)
limit_dist = std::min(current_bsp_culling_distance/mapobjectscale, limit_dist);
else
limit_dist = current_bsp_culling_distance/mapobjectscale;
}
}
// Handle all things in sector.
for (thing = sec->thinglist; thing; thing = thing->snext)
{
if (!R_ThingWithinDist(thing, limit_dist))
continue;
// reduce branching in this rather tight loop
if constexpr (Type == AddSpritesType::kLimitDist)
{
if (!R_ThingWithinDist(thing, limit_dist))
continue;
}
if (!R_ThingVisible(thing))
continue;
@@ -4566,6 +4585,7 @@ static void HWR_AddSprites(sector_t *sec)
HWR_ProjectSprite(thing);
}
}
}
// --------------------------------------------------------------------------
// HWR_AddPrecipitationSprites
@@ -4949,24 +4969,24 @@ static void HWR_ProjectSprite(mobj_t *thing)
vis->mobj = thing;
//Hurdler: 25/04/2000: now support colormap in hardware mode
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
if (UNLIKELY((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1))) // Bosses "flash"
{
if (vis->mobj->type == MT_CYBRAKDEMON)
vis->colormap = static_cast<UINT8*>(R_GetTranslationColormap(TC_ALLWHITE, SKINCOLOR_NONE, GTC_CACHE));
vis->colormap = R_GetTranslationColormap(TC_ALLWHITE, SKINCOLOR_NONE, GTC_CACHE);
else if (vis->mobj->type == MT_METALSONIC_BATTLE)
vis->colormap = static_cast<UINT8*>(R_GetTranslationColormap(TC_METALSONIC, SKINCOLOR_NONE, GTC_CACHE));
vis->colormap = R_GetTranslationColormap(TC_METALSONIC, SKINCOLOR_NONE, GTC_CACHE);
else
vis->colormap = static_cast<UINT8*>(R_GetTranslationColormap(TC_BOSS, SKINCOLOR_NONE, GTC_CACHE));
vis->colormap = R_GetTranslationColormap(TC_BOSS, SKINCOLOR_NONE, GTC_CACHE);
}
else if (thing->color)
{
// New colormap stuff for skins Tails 06-07-2002
if (thing->colorized)
vis->colormap = static_cast<UINT8*>(R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolors_t>(thing->color), GTC_CACHE));
vis->colormap = R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolors_t>(thing->color), GTC_CACHE);
else if (thing->skin && thing->sprite == SPR_PLAY) // This thing is a player!
vis->colormap = static_cast<UINT8*>(R_GetLocalTranslationColormap(static_cast<skin_t*>(thing->skin), static_cast<skin_t*>(thing->localskin), static_cast<skincolors_t>(thing->color), GTC_CACHE, thing->skinlocal));
vis->colormap = R_GetLocalTranslationColormap(static_cast<skin_t*>(thing->skin), static_cast<skin_t*>(thing->localskin), static_cast<skincolors_t>(thing->color), GTC_CACHE, thing->skinlocal);
else
vis->colormap = static_cast<UINT8*>(R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolors_t>(thing->color), GTC_CACHE));
vis->colormap = R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolors_t>(thing->color), GTC_CACHE);
}
else
{
@@ -5725,42 +5745,7 @@ void HWR_RenderPlayerView(void)
HWR_RenderFrame(player, false);
}
// Determine on mapload if current map has any Horizonlines present
// so we can avoid rather hot checks in HWR_Subsector
static void HWR_CheckForHorizonLines(void)
{
size_t i;
INT32 h;
gl_maphashorizonlines = false;
if (!cv_glhorizonlines.value)
return;
for (i = 0; i < numsubsectors; i++)
{
subsector_t *subsec = &subsectors[i];
// sector checked already?
if (subsec->validcount == validcount)
continue;
subsec->validcount = validcount;
seg_t *line = &segs[subsec->firstline];
for (h = 0; h < subsec->numlines; h++, line++)
{
if (line->linedef->special != HORIZONSPECIAL)
continue;
gl_maphashorizonlines = true;
break;
}
}
}
void HWR_LoadLevel(boolean reloadinggamestate)
void HWR_LoadLevel(void)
{
HWR_CreatePlanePolygons((INT32)numnodes - 1);
@@ -5768,9 +5753,6 @@ void HWR_LoadLevel(boolean reloadinggamestate)
HWR_ClearSkyDome();
HWR_BuildSkyDome();
if (!reloadinggamestate)
HWR_CheckForHorizonLines();
if (HWR_ShouldUsePaletteRendering())
HWR_SetMapPalette();
}
@@ -5844,7 +5826,6 @@ void HWR_AddCommands(void)
CV_RegisterVar(&cv_glshaders);
CV_RegisterVar(&cv_gllightdither);
CV_RegisterVar(&cv_glsecbright);
CV_RegisterVar(&cv_glfiltermode);
CV_RegisterVar(&cv_glanisotropicmode);
@@ -6040,6 +6021,8 @@ static void HWR_DoPostProcessor(player_t *player)
Surf.PolyColor.s.alpha = 0xc0; // match software mode
V_CubeApply(&Surf.PolyColor.s.red, &Surf.PolyColor.s.green, &Surf.PolyColor.s.blue);
GL_DrawPolygon(&Surf, v, 4, PF_Modulated|PF_Translucent|PF_NoTexture|PF_NoDepthTest);
}
+7 -1
View File
@@ -175,6 +175,7 @@ void HWR_ProcessSeg(void); // Sort of like GLWall::Process in GZDoom
// hw_bsp.c
void HWR_CreatePlanePolygons(INT32 bspnum);
extern boolean gl_maphasportals;
extern boolean gl_maphashorizonlines;
// Console variables
extern CV_PossibleValue_t glanisotropicmode_cons_t[];
@@ -198,7 +199,6 @@ extern consvar_t cv_glslopecontrast;
extern consvar_t cv_glshaders;
extern consvar_t cv_gllightdither;
extern consvar_t cv_glsecbright;
extern consvar_t cv_glfiltermode;
extern consvar_t cv_glanisotropicmode;
@@ -233,6 +233,12 @@ FUNCINLINE static ATTRINLINE boolean HWR_PalRenderFlashpal(void)
return (cv_glflashpal.value && HWR_ShouldUsePaletteRendering());
}
// Returns a pointer to the palette which should be used for caching textures.
FUNCINLINE static ATTRINLINE RGBA_t *HWR_GetTexturePalette(void)
{
return HWR_ShouldUsePaletteRendering() ? mapPalette : pLocalPalette;
}
#ifdef __cplusplus
}// extern "C"
#endif
+7 -6
View File
@@ -695,6 +695,7 @@ static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMi
UINT16 w = gpatch->width, h = gpatch->height;
UINT32 size = w*h;
RGBA_t *image, *blendimage, *cur, blendcolor;
RGBA_t *palette = HWR_GetTexturePalette();
UINT8 translation[17]; // First the color index
UINT8 cutoff[17]; // Brightness cutoff before using the next color
UINT8 translen = 0;
@@ -702,7 +703,7 @@ static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMi
UINT8 colorbrightnesses[17];
UINT8 color_match_lookup[256]; // optimization attempt
blendcolor = V_GetColor(0); // initialize
blendcolor = palette[0]; // initialize
memset(translation, 0, sizeof(translation));
memset(cutoff, 0, sizeof(cutoff));
@@ -781,7 +782,7 @@ static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMi
for (i = 0; i < translen; i++) // moved from inside the loop to here
{
RGBA_t tempc = V_GetColor(translation[i]);
RGBA_t tempc = palette[translation[i]];
SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison
}
// generate lookup table for color brightness matching
@@ -958,11 +959,11 @@ static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMi
mul = cutoff[firsti] - brightness;
}
blendcolor = V_GetColor(translation[firsti]);
blendcolor = palette[translation[firsti]];
if (mul > 0) // If it's 0, then we only need the first color.
{
nextcolor = V_GetColor(translation[secondi]);
nextcolor = palette[translation[secondi]];
// Find difference between points
r = (INT32)(nextcolor.s.red - blendcolor.s.red);
@@ -1150,7 +1151,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel;
lightlevel = *sector->lightlist[light].lightlevel;
if (sector->lightlist[light].extra_colormap)
colormap = sector->lightlist[light].extra_colormap;
@@ -1158,7 +1159,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
else
{
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
lightlevel = sector->lightlevel;
if (sector->extra_colormap)
colormap = sector->extra_colormap;
+1 -2
View File
@@ -2031,8 +2031,7 @@ void GL_SetTexture(GLMipmap_t *pTexInfo)
{
if (pTexInfo->downloaded != tex_downloaded)
{
if (!currently_batching)
pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded);
pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded);
tex_downloaded = pTexInfo->downloaded;
}
}
+15 -3
View File
@@ -110,13 +110,21 @@ HMS_on_read (char *s, size_t _1, size_t n, void *userdata)
buffer = userdata;
if (n >= (size_t)( buffer->end - buffer->needle ))
while (n >= (size_t)( buffer->end - buffer->needle ))
{
/* resize to next multiple of buffer size */
blocks = ( n / DEFAULT_BUFFER_SIZE + 1 );
buffer->end += ( blocks * DEFAULT_BUFFER_SIZE );
buffer->buffer = realloc(buffer->buffer, buffer->end);
void *tmp = realloc(buffer->buffer, buffer->end);
if (tmp == NULL)
{
// not enough memory to read it, bail
free(buffer->buffer);
buffer->buffer = NULL;
return 0;
}
buffer->buffer = tmp;
}
memcpy(&buffer->buffer[buffer->needle], s, n);
@@ -220,7 +228,11 @@ HMS_connect (const char *format, ...)
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, (long)CURL_IPRESOLVE_V4);
#ifdef HAVE_IPV6
if (!M_CheckParm("-ipv6"))
#endif
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, (long)CURL_IPRESOLVE_V4);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)cv_masterserver_timeout.value);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read);
+100 -16
View File
@@ -17,6 +17,7 @@
#include "m_menu.h" // gametype_cons_t
#include "m_cond.h" // emblems
#include "m_emotes.h"
#include "d_clisrv.h"
@@ -94,6 +95,9 @@ static textinput_t w_chat;
static boolean headsupactive = false;
boolean hu_showscores; // draw rankings
static char hu_tick;
static tic_t hu_emoteanim = 0;
#define MAXEMOTESUGGESTIONS 8
static emote_t *emote_suggestions[MAXEMOTESUGGESTIONS] = {0};
static huddrawlist_h luahuddrawlist_scores;
@@ -1106,6 +1110,7 @@ void HU_Ticker(void)
return;
hu_tick++;
hu_emoteanim++;
hu_tick &= 7; // currently only to blink chat input cursor
if (PLAYER1INPUTDOWN(gc_scores))
@@ -1399,7 +1404,7 @@ boolean HU_Responder(event_t *ev)
&& ev->data1 != gamecontrol[0][gc_talkkey][1]))
return false;
M_TextInputHandle(&w_chat, c);
M_TextInputHandleEmotes(&w_chat, c, emote_suggestions, MAXEMOTESUGGESTIONS);
if (c == KEY_ENTER)
{
@@ -1439,6 +1444,8 @@ boolean HU_Responder(event_t *ev)
#ifndef NONET
#define HU_DrawEmote(x, y, emote, flags) M_DrawEmote((x), (y), (emote), hu_emoteanim, (flags))
// Precompile a wordwrapped string to any given width.
// This is a muuuch better method than V_WORDWRAP.
// again stolen and modified a bit from video.c, don't mind me, will need to rearrange this one day.
@@ -1450,6 +1457,8 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
size_t slen;
char *newstring = Z_StrDup(string);
INT32 spacewidth = (vid.width < 640) ? 8 : 4, charwidth = (vid.width < 640) ? 8 : 4;
emote_t *emote = NULL;
int emotelen = 0;
slen = strlen(string);
x = 0;
@@ -1471,7 +1480,12 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
c = toupper(c);
c -= HU_FONTSTART;
if (c < 0 || c >= HU_FONTSIZE || !hu_font[c])
if ((emote = M_VerifyEmote(string+i, &emotelen)))
{
chw = EMOTEWIDTH;
i += emotelen-1; // Will be incremented on next loop iteration, hence -1
}
else if (c < 0 || c >= HU_FONTSIZE || !hu_font[c])
{
chw = spacewidth;
lastusablespace = i;
@@ -1493,7 +1507,6 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
return newstring;
}
// 30/7/18: chaty is now the distance at which the lowest point of the chat will be drawn if that makes any sense.
INT16 chatx = 13, chaty = 169; // let's use this as our coordinates, shh
@@ -1526,6 +1539,8 @@ static void HU_drawMiniChat(void)
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
size_t j = 0;
INT32 linescount = 0;
emote_t *emote = NULL;
int emotelen = 0;
while(msg[j]) // iterate through msg
{
@@ -1550,6 +1565,11 @@ static void HU_drawMiniChat(void)
++j;
}
else if ((emote = M_VerifyEmote(msg+j, &emotelen)))
{
dx += EMOTEWIDTH - charwidth;
j += emotelen;
}
else
{
j++;
@@ -1595,6 +1615,8 @@ static void HU_drawMiniChat(void)
size_t j = 0;
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
UINT8 *colormap = NULL;
emote_t *emote = NULL;
int emotelen = 0;
while(msg[j]) // iterate through msg
{
@@ -1621,6 +1643,16 @@ static void HU_drawMiniChat(void)
++j;
}
else if ((emote = M_VerifyEmote(msg+j, &emotelen)))
{
if (cv_chatbacktint.value) // on request of wolfy
V_DrawFillConsoleMap(x + dx + 2, y+dy, EMOTEWIDTH, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
HU_DrawEmote(x+dx+2, y+dy, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag);
dx += EMOTEWIDTH - charwidth;
j += emotelen;
}
else
{
if (cv_chatbacktint.value) // on request of wolfy
@@ -1698,6 +1730,9 @@ static void HU_drawChatLog(INT32 offset)
INT32 j = 0;
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
UINT8 *colormap = NULL;
emote_t *emote = NULL;
int emotelen = 0;
while(msg[j]) // iterate through msg
{
if (msg[j] < HU_FONTSTART) // don't draw
@@ -1719,6 +1754,15 @@ static void HU_drawChatLog(INT32 offset)
++j;
}
else if ((emote = M_VerifyEmote(msg+j, &emotelen)))
{
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
{
HU_DrawEmote(x+dx+2, y+dy, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT);
dx += EMOTEWIDTH - charwidth;
}
j += emotelen;
}
else
{
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
@@ -1844,7 +1888,7 @@ static void HU_DrawChat(void)
typelines = 1;
if ((w_chat.cursor == 0 || w_chat.length == 0) && hu_tick < 4)
V_DrawChatCharacter(chatx+2+c+charwidth*w_chat.cursor, y+1, '_'|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
V_DrawChatCharacter(chatx+2+c, y+1, '_'|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
if (w_chat.select != w_chat.cursor)
{
@@ -1855,30 +1899,40 @@ static void HU_DrawChat(void)
while (w_chat_buf[i])
{
boolean skippedline = false;
if (w_chat.cursor == (i+1))
emote_t *emote = NULL;
int emotelen = 0;
int drawwidth = charwidth; // if we've drawn emote, selection needs to account for that
if ((emote = M_VerifyEmote(w_chat_buf+i, &emotelen)))
{
HU_DrawEmote(chatx + c + 2, y-1, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT|t);
c += EMOTEWIDTH - charwidth;
i += emotelen-1;
drawwidth = EMOTEWIDTH;
}
else if (w_chat_buf[i] >= HU_FONTSTART) //Hurdler: isn't it better like that?
V_DrawChatCharacter(chatx + c + 2, y, w_chat_buf[i] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL);
// Draw selection
if (i >= select_start && i < select_end)
V_DrawFill(chatx + c + 2 - (drawwidth-charwidth), y-1, drawwidth, charheight, 103|V_TRANSLUCENT|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t);
++i;
if (w_chat.cursor == i)
{
INT32 cursorx = (c+charwidth < boxw-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down.
INT32 cursory = (cursorx != chatx+1) ? (y) : (y+charheight);
if (hu_tick < 4)
V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
if (cursorx == chatx+1 && saylen == i) // a weirdo hack
if (cursorx == chatx+1 && saylen == i-1) // a weirdo hack
{
typelines += 1;
skippedline = true;
}
}
//Hurdler: isn't it better like that?
if (w_chat_buf[i] >= HU_FONTSTART)
V_DrawChatCharacter(chatx + c + 2, y, w_chat_buf[i] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL);
// Draw selection
if (i >= select_start && i < select_end)
V_DrawFill(chatx + c + 2, y-1, charwidth, charheight, 103|V_TRANSLUCENT|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t);
++i;
c += charwidth;
if (c > boxw-(charwidth*2) && !skippedline)
{
@@ -1888,6 +1942,36 @@ static void HU_DrawChat(void)
}
}
if (emote_suggestions[0])
{
// A bit of copy-paste from /pm code :p
INT32 suggesty = chaty - charheight - 1;
size_t longest_suggestion_length = 0;
for (i = 0; i < MAXEMOTESUGGESTIONS && emote_suggestions[i]; ++i)
{
longest_suggestion_length = max(longest_suggestion_length, strlen(emote_suggestions[i]->name));
}
#ifdef NETSPLITSCREEN
if (splitscreen)
{
suggesty -= BASEVIDHEIGHT/2;
if (splitscreen > 1)
suggesty += 16;
}
else
#endif
suggesty -= (cv_kartspeedometer.value ? 16 : 0);
for (i = 0; i < MAXEMOTESUGGESTIONS && emote_suggestions[i]; ++i)
{
V_DrawFillConsoleMap(chatx + boxw + 2, suggesty - (7*i), (longest_suggestion_length+2)*4 + EMOTEWIDTH, 6, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
V_DrawSmallString(chatx + boxw + 4 + EMOTEWIDTH, suggesty - (7*i), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va(":%s:", emote_suggestions[i]->name));
HU_DrawEmote(chatx + boxw + 2, suggesty - i*7, emote_suggestions[i], V_SNAPTOBOTTOM|V_SNAPTOLEFT);
}
}
// handle /pm list. It's messy, horrible and I don't care.
if (strnicmp(w_chat_buf, "/pm", 3) == 0 && vid.width >= 400 && !teamtalk) // 320x200 unsupported kthxbai
{
+4 -4
View File
@@ -82,6 +82,8 @@ typedef struct
char data[MAXPACKETLENGTH];
} ATTRPACK doomcom_t;
#define DOOMCOM_DATA(d) (doomdata_t *)&(d)->data
#ifdef HOLEPUNCH
typedef struct
{
@@ -89,6 +91,8 @@ typedef struct
INT32 addr;
INT16 port;
} ATTRPACK holepunch_t;
#define HOLEPUNCH_DATA(d) (holepunch_t *)&(d)->data
#endif
#if defined(_MSC_VER)
@@ -97,10 +101,6 @@ typedef struct
extern doomcom_t *doomcom;
#ifdef HOLEPUNCH
extern holepunch_t *holepunchpacket;
#endif
/** \brief return packet in doomcom struct
*/
extern boolean (*I_NetGet)(void);
+4 -3
View File
@@ -43,8 +43,9 @@ extern UINT8 sound_started;
/** \brief info of samplerate
*/
#if defined(HAVE_SDL) && SOUND==SOUND_SDL
extern consvar_t cv_samplerate;
//extern consvar_t cv_rndsoundpitch;
#endif
/** \brief The I_GetSfx function
@@ -83,7 +84,7 @@ void I_ShutdownSound(void);
\return sfx handle
*/
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel);
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, INT32 channel);
/** \brief Stops a sound channel.
@@ -114,7 +115,7 @@ boolean I_SoundIsPlaying(INT32 handle);
\return void
*/
void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch);
void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep);
/** \brief The I_SetSfxVolume function
+77 -21
View File
@@ -371,8 +371,16 @@ static inline void I_UPnP_rem(const char *port, const char * servicetype)
static const char *SOCK_AddrToStr(mysockaddr_t *sk)
{
static char s[64]; // 255.255.255.255:65535 or IPv6:65535
static char s[64]; // 255.255.255.255:65535 or
// [ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535
#ifdef HAVE_NTOP
#ifdef HAVE_IPV6
int v6 = (sk->any.sa_family == AF_INET6);
#else
int v6 = 0;
#endif
void *addr;
int e = 0; // save error code so it can't be modified later code and avoid calling WSAGetLastError() more then once
@@ -387,14 +395,20 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
if(addr == NULL)
sprintf(s, "No address");
else if(inet_ntop(sk->any.sa_family, addr, s, sizeof (s)) == NULL)
else if(inet_ntop(sk->any.sa_family, addr, &s[v6], sizeof (s) - v6) == NULL)
{
e = errno;
sprintf(s, "Unknown family type, error #%u: %s", e, strerror(e));
}
#ifdef HAVE_IPV6
else if(sk->any.sa_family == AF_INET6 && sk->ip6.sin6_port != 0)
strcat(s, va(":%d", ntohs(sk->ip6.sin6_port)));
else if(sk->any.sa_family == AF_INET6)
{
s[0] = '[';
strcat(s, "]");
if (sk->ip6.sin6_port != 0)
strcat(s, va(":%d", ntohs(sk->ip6.sin6_port)));
}
#endif
else if(sk->any.sa_family == AF_INET && sk->ip4.sin_port != 0)
strcat(s, va(":%d", ntohs(sk->ip4.sin_port)));
@@ -486,10 +500,30 @@ static time_t SOCK_GetUnbanTime(size_t ban)
}
#ifndef NONET
#ifdef HAVE_IPV6
static boolean SOCK_cmpipv6(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
{
UINT8 bitmask;
I_Assert(mask <= 128);
if (mask == 0)
mask = 128;
if (memcmp(&a->ip6.sin6_addr.s6_addr, &b->ip6.sin6_addr.s6_addr, mask / 8) != 0)
return false;
if (mask % 8 == 0)
return true;
bitmask = 255 << (mask % 8);
return (a->ip6.sin6_addr.s6_addr[mask / 8] & bitmask) == (b->ip6.sin6_addr.s6_addr[mask / 8] & bitmask);
}
#endif
static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
{
UINT32 bitmask = INADDR_NONE;
if (a->any.sa_family != b->any.sa_family)
return false;
if (mask && mask < 32)
bitmask = htonl((UINT32)(-1) << (32 - mask));
@@ -498,13 +532,14 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
&& (b->ip4.sin_port == 0 || (a->ip4.sin_port == b->ip4.sin_port));
#ifdef HAVE_IPV6
else if (b->any.sa_family == AF_INET6)
return memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, sizeof(b->ip6.sin6_addr))
return SOCK_cmpipv6(a, b, mask)
&& (b->ip6.sin6_port == 0 || (a->ip6.sin6_port == b->ip6.sin6_port));
#endif
else
return false;
}
// This is a hack. For some reason, nodes aren't being freed properly.
// This goes through and cleans up what nodes were supposed to be freed.
/** \warning This function causes the file downloading to stop if someone joins.
@@ -620,6 +655,7 @@ is_external_address (UINT32 p)
static boolean hole_punch(ssize_t c)
{
holepunch_t *holepunchpacket = HOLEPUNCH_DATA(doomcom);
/* See ../doc/Holepunch-Protocol.txt */
if (cv_rendezvousserver.string[0] &&
@@ -659,6 +695,7 @@ static boolean SOCK_Get(void)
fromlen = (socklen_t)sizeof(fromaddress);
c = recvfrom(mysockets[n], (char *)&doomcom->data, MAXPACKETLENGTH, 0,
(void *)&fromaddress, &fromlen);
if (c > 0)
{
#ifdef USE_STUN
@@ -868,11 +905,11 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
unsigned long trueval = true;
#endif
mysockaddr_t straddr;
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
socklen_t len = sizeof(straddr);
if (s == (SOCKET_TYPE)ERRSOCKET)
return (SOCKET_TYPE)ERRSOCKET;
#ifdef USE_WINSOCK
{ // Alam_GBC: disable the new UDP connection reset behavior for Win2k and up
#ifdef USE_WINSOCK2
@@ -892,14 +929,12 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
}
#endif
straddr.any = *addr;
memcpy(&straddr, addr, addrlen);
I_OutputMsg("Binding to %s\n", SOCK_AddrToStr(&straddr));
if (family == AF_INET)
{
mysockaddr_t tmpaddr;
tmpaddr.any = *addr ;
if (tmpaddr.ip4.sin_addr.s_addr == htonl(INADDR_ANY))
if (straddr.ip4.sin_addr.s_addr == htonl(INADDR_ANY))
{
opt = true;
opts = (socklen_t)sizeof(opt);
@@ -924,7 +959,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
#ifdef HAVE_IPV6
else if (family == AF_INET6)
{
if (memcmp(addr, &in6addr_any, sizeof(in6addr_any)) == 0) //IN6_ARE_ADDR_EQUAL
if (memcmp(&straddr.ip6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0) //IN6_ARE_ADDR_EQUAL
{
opt = true;
opts = (socklen_t)sizeof(opt);
@@ -939,7 +974,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
// make it IPv6 ony
opt = true;
opts = (socklen_t)sizeof(opt);
rc = setsockopt(s, SOL_SOCKET, IPV6_V6ONLY, (char *)&opt, opts);
rc = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&opt, opts);
if (rc <= -1)
{
e = errno;
@@ -969,7 +1004,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
inet_pton(AF_INET6, IPV6_MULTICAST_ADDRESS, &maddr.ipv6mr_multiaddr);
maddr.ipv6mr_interface = 0;
rc = setsockopt(s, SOL_SOCKET, IPV6_JOIN_GROUP, (const char *)&maddr, sizeof(maddr));
rc = setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, (const char *)&maddr, sizeof(maddr));
if (rc <= -1)
{
e = errno;
@@ -1032,7 +1067,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10);
}
rc = getsockname(s, (struct sockaddr *)&sin, &len);
rc = getsockname(s, &straddr.any, &len);
if (rc != 0)
{
e = errno;
@@ -1040,7 +1075,14 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
I_OutputMsg("getsockname failed: #%u, %s\n", e, strerror(e));
}
else
current_port = (UINT16)ntohs(sin.sin_port);
{
if (family == AF_INET)
current_port = (UINT16)ntohs(straddr.ip4.sin_port);
#ifdef HAVE_IPV6
else if (family == AF_INET6)
current_port = (UINT16)ntohs(straddr.ip6.sin6_port);
#endif
}
return s;
}
@@ -1121,6 +1163,7 @@ static boolean UDP_Socket(void)
I_freeaddrinfo(ai);
}
}
#ifdef HAVE_IPV6
if (b_ipv6)
{
@@ -1319,12 +1362,13 @@ static boolean SOCK_GetAddr(struct sockaddr_in *sin, const char *address, const
{
struct my_addrinfo *ai = NULL, *runp, hints;
int gaie;
size_t i;
if (!port || !port[0])
port = DEFAULTPORT;
memset (&hints, 0x00, sizeof (hints));
hints.ai_flags = 0;
hints.ai_flags = AI_ADDRCONFIG;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
@@ -1343,10 +1387,19 @@ static boolean SOCK_GetAddr(struct sockaddr_in *sin, const char *address, const
{
while (runp != NULL)
{
if (sendto(mysockets[0], NULL, 0, 0, runp->ai_addr, runp->ai_addrlen) == 0)
break;
// test ip address of server
for (i = 0; i < mysocketses; ++i)
{
if (runp->ai_addr->sa_family == myfamily[i])
{
break;
}
}
runp = runp->ai_next;
if (i >= mysocketses)
runp = runp->ai_next;
else
break;
}
}
@@ -1390,6 +1443,8 @@ static void rendezvous(int size)
tic_t tic = I_GetTime();
holepunch_t *holepunchpacket = HOLEPUNCH_DATA(doomcom);
if (tic != refreshtic)
{
if (SOCK_GetAddr(&rzv.ip4, host, (port ? port : "7777"), false))
@@ -1415,6 +1470,7 @@ static void rendezvous(int size)
static void SOCK_RequestHolePunch(INT32 node)
{
mysockaddr_t * addr = &clientaddress[node];
holepunch_t *holepunchpacket = HOLEPUNCH_DATA(doomcom);
holepunchpacket->addr = addr->ip4.sin_addr.s_addr;
holepunchpacket->port = addr->ip4.sin_port;
@@ -1736,7 +1792,7 @@ boolean I_InitTcpNetwork(void)
// server address only in ip
if (serverhostname[0])
{
{
CONS_Printf("SERVERNAME: %s\n", serverhostname);
COM_BufAddText("connect \"");
COM_BufAddText(serverhostname);
+1 -1
View File
@@ -2563,7 +2563,7 @@ state_t states[NUMSTATES] =
{SPR_KINV, FF_FULLBRIGHT|2, 1, NULL, 0, 0, S_KARTINVULN_LARGE3}, // S_KARTINVULN_LARGE2
{SPR_KINV, FF_FULLBRIGHT|5, 1, NULL, 0, 0, S_KARTINVULN_LARGE4}, // S_KARTINVULN_LARGE3
{SPR_KINV, FF_FULLBRIGHT|6, 1, NULL, 0, 0, S_KARTINVULN_LARGE5}, // S_KARTINVULN_LARGE4
{SPR_KINV, FF_FULLBRIGHT|7, 1, NULL, 0, 0, S_NULL}, // S_KARTINVULN_LARGE5
{SPR_KINV, FF_FULLBRIGHT|7, 1, NULL, 0, 0, S_NULL}, // S_KARTINVULN_LARGE5
{SPR_KINF, FF_FULLBRIGHT|FF_TRANS90, 1, NULL, 0, 0, S_INVULNFLASH2}, // S_INVULNFLASH1
{SPR_NULL, FF_FULLBRIGHT|FF_TRANS90, 1, NULL, 0, 0, S_INVULNFLASH3}, // S_INVULNFLASH2
+25 -36
View File
@@ -1315,14 +1315,6 @@ static void K_drawKartStats(void)
flags = V_SNAPTOBOTTOM|V_SNAPTOLEFT;
UINT8 splitnum = 0;
for (; splitnum < MAXSPLITSCREENPLAYERS; ++splitnum)
{
if (stplyrnum == splitnum)
break;
}
if (!LUA_HudEnabled(hud_statdisplay))
return;
@@ -1362,7 +1354,7 @@ static void K_drawKartStats(void)
// If we are in 2-player splitscreen, for player 1 we move hud to up and remove snapping
// to bottom
if (splitnum == 0)
if (stplyrnum == 0)
{
y /= 2;
flags = V_SNAPTOLEFT;
@@ -1375,28 +1367,28 @@ static void K_drawKartStats(void)
}
else
{
if (splitnum == 0 || splitnum == 2) // If we are P1 or P3...
if (stplyrnum == 0 || stplyrnum == 2) // If we are P1 or P3...
{
// ye i just align it to position number lol
x = POSI_X + 19;
y = POSI_Y - 6;
flags = V_SNAPTOLEFT|((splitnum == 2) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P3 to the bottom.
flags = V_SNAPTOLEFT|((stplyrnum == 2) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P3 to the bottom.
}
else // else, that means we're P2 or P4.
{
x = POSI2_X - 75;
y = POSI2_Y - 6;
flags = V_SNAPTORIGHT|((splitnum == 3) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P4 to the bottom
flags = V_SNAPTORIGHT|((stplyrnum == 3) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P4 to the bottom
}
}
flags |= V_HUDTRANS;
skin_t *fakeskin;
fakeskin = K_GetPlayerSkin(stplyr);
if (!splitscreen)
{
skin_t *fakeskin;
fakeskin = K_GetPlayerSkin(stplyr);
// Skin name
if (K_IsHighResolution()) // V_DrawSmallString becomes a mess at low resolutions lel
{
@@ -1812,6 +1804,7 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
if (!mode)
{
splitflags = V_HUDTRANS|K_calcSplitFlags(V_SNAPTOTOP|V_SNAPTORIGHT);
if (cv_timelimit.value && timelimitintics > 0)
{
if (drawtime >= timelimitintics)
@@ -2175,9 +2168,7 @@ static boolean K_drawKartPositionFaces(void)
if (!playeringame[rankplayer[i]])
continue;
if (player->spectator)
continue;
if (!player->mo)
if (player->spectator || !player->mo)
continue;
const UINT8 mocolor = player->mo->color;
@@ -2186,9 +2177,10 @@ static boolean K_drawKartPositionFaces(void)
if (mocolor)
{
colormap = R_GetTranslationColormap(player->skin, mocolor, GTC_CACHE);
if (player->mo->colorized)
colormap = R_GetTranslationColormap(TC_RAINBOW, mocolor, GTC_CACHE);
else
colormap = R_GetTranslationColormap(player->skin, mocolor, GTC_CACHE);
if (K_UseHighResPortraits())
V_DrawSmallMappedPatch(FACE_X, Y, V_HUDTRANS|V_SNAPTOLEFT, R_GetSkinFaceWant(player), colormap);
@@ -2217,8 +2209,10 @@ static boolean K_drawKartPositionFaces(void)
else
{
INT32 pos = player->kartstuff[k_position];
if (pos < 0 || pos > MAXPLAYERS)
pos = 0;
// Draws the little number over the face
V_DrawScaledPatch(FACE_X-5, Y+10, V_HUDTRANS|V_SNAPTOLEFT, kp_facenum[pos]);
}
@@ -2244,6 +2238,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
//I_Assert(scorelines <= 9); -- not today bitch, kart fixed it up
V_DrawFill(1-duptweak, 26, dupadjust-2, 1, 0); // Draw a horizontal line because it looks nice!
if (scorelines > 8)
{
V_DrawFill(160, 26, 1, 147, 0); // Draw a vertical line to separate the two sides.
@@ -3168,7 +3163,7 @@ static void K_drawDriftGauge(void)
SKINCOLOR_SALMON,
};
static UINT8 driftrainbow[18] = {
static const UINT8 driftrainbow[18] = {
0, 31, 47, 63, 79, 95, 111, 119, 127, 143, 159, 175, 183, 191, 199, 207, 223, 247
};
@@ -3274,7 +3269,6 @@ skipcrap:
}
// right, also draw a cool number
//SG_DrawPaddedNum(v, basex + (dup*32), basey, driftcharge*100 / driftval, 3, "PINGN", V_NOSCALESTART|V_OFFSET|drifttrans, cmap)
if (cv_driftgaugestyle.value == 3)
V_DrawPaddedTallColorNum(basex + (dup*32), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, 3, cmap);
else
@@ -3283,10 +3277,10 @@ skipcrap:
break;
case 4:
{
cmap = R_GetTranslationColormap(TC_RAINBOW, driftskins[driftlevel],GTC_CACHE);
if (driftcharge >= driftval*4)
cmap = R_GetTranslationColormap(TC_RAINBOW, 1 + leveltime % (MAXSKINCOLORS-1),GTC_CACHE);
else
cmap = R_GetTranslationColormap(TC_RAINBOW, driftskins[driftlevel],GTC_CACHE);
V_DrawPaddedTallColorNum(basex + (dup*16), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, 3, cmap);
}
@@ -3305,6 +3299,7 @@ static fixed_t K_FindCheckX(fixed_t px, fixed_t py, angle_t ang, fixed_t mx, fix
range *= gamespeed+1;
dist = abs(R_PointToDist2(px, py, mx, my));
if (dist > range)
return -BASEVIDWIDTH;
@@ -3404,17 +3399,14 @@ static void K_drawKartPlayerCheck(void)
UINT8 *colormap;
INT32 x;
const INT32 splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM);
if (!stplyr->mo || stplyr->spectator)
return;
if (stplyr->awayviewtics)
if (!stplyr->mo || stplyr->spectator || stplyr->awayviewtics)
return;
if (camspin[0])
return;
const INT32 splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM);
for (i = 0; i < MAXPLAYERS; i++)
{
UINT8 pnum = 0;
@@ -3532,7 +3524,7 @@ static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags)
skin = K_GetMobjSkin(mo);
minimaphead = (skinlocal ? localfacemmapprefix : facemmapprefix)[K_GetMobjSkinNum(skin, skinlocal)];
amnumxpos = (FixedMul(lerp(mo->old_x, mo->x), minimapinfo.zoom) - minimapinfo.offs_x);
amnumxpos = (FixedMul(lerp(mo->old_x, mo->x), minimapinfo.zoom) - minimapinfo.offs_x);
amnumypos = -(FixedMul(lerp(mo->old_y, mo->y), minimapinfo.zoom) - minimapinfo.offs_y);
if (encoremode)
@@ -3965,7 +3957,7 @@ static void K_drawBattleFullscreen(void)
}
}
if (netgame && !stplyr->spectator && timeinmap > 113) // FREE PLAY?
if (netgame && cv_showfreeplay.value && !stplyr->spectator && timeinmap > 113) // FREE PLAY?
{
UINT8 i;
@@ -4386,10 +4378,6 @@ static void K_drawLapStartAnim(void)
void K_drawKartFreePlay(UINT32 flashtime)
{
// no splitscreen support because it's not FREE PLAY if you have more than one player in-game
if (!cv_showfreeplay.value)
return;
if ((flashtime % TICRATE) < TICRATE/2)
return;
@@ -4503,6 +4491,7 @@ static void K_drawCheckpointDebugger(void)
V_DrawString(8, 184, 0, va("Checkpoint: %d / %d (Can finish)", stplyr->starpostnum, numstarposts));
else
V_DrawString(8, 184, 0, va("Checkpoint: %d / %d (Skip: %d)", stplyr->starpostnum, numstarposts, ((numstarposts/2) + stplyr->starpostnum)));
V_DrawString(8, 192, 0, va("Waypoint dist: Prev %d, Next %d", stplyr->kartstuff[k_prevcheck], stplyr->kartstuff[k_nextcheck]));
}
@@ -4765,7 +4754,7 @@ void K_drawKartHUD(void)
V_DrawScaledPatch(BASEVIDWIDTH/2 - (kp_yougotem->width/2), 32, V_HUDTRANS, kp_yougotem);
// Draw FREE PLAY.
if (isfreeplay && !stplyr->spectator && timeinmap > 113)
if (isfreeplay && cv_showfreeplay.value && !stplyr->spectator && timeinmap > 113)
{
if (LUA_HudEnabled(hud_freeplay))
K_drawKartFreePlay(leveltime);
+92 -42
View File
@@ -551,26 +551,41 @@ void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor)
*/
void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color, boolean local)
{
INT32 i;
INT32 starttranscolor;
INT32 i, starttranscolor;
// Handle a couple of simple special cases
if (skinnum == TC_BOSS
|| skinnum == TC_ALLWHITE
|| skinnum == TC_METALSONIC
|| skinnum == TC_BLINK
|| color == SKINCOLOR_NONE)
if (skinnum < TC_DEFAULT)
{
for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
switch (skinnum)
{
if (skinnum == TC_ALLWHITE)
dest_colormap[i] = 0;
else if (skinnum == TC_BLINK)
dest_colormap[i] = colortranslations[color][3];
else
dest_colormap[i] = (UINT8)i;
case TC_ALLWHITE:
memset(dest_colormap, 0, NUM_PALETTE_ENTRIES * sizeof(UINT8));
return;
case TC_RAINBOW:
if (color >= MAXTRANSLATIONS)
I_Error("Invalid skin color #%hu.", (UINT16)color);
if (color != SKINCOLOR_NONE)
{
K_RainbowColormap(dest_colormap, color);
return;
}
break;
case TC_BLINK:
if (color >= MAXTRANSLATIONS)
I_Error("Invalid skin color #%hu.", (UINT16)color);
if (color != SKINCOLOR_NONE)
{
memset(dest_colormap, colortranslations[color][3], NUM_PALETTE_ENTRIES * sizeof(UINT8));
return;
}
break;
default:
break;
}
for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
dest_colormap[i] = (UINT8)i;
// White!
if (skinnum == TC_BOSS)
dest_colormap[31] = 0;
@@ -579,14 +594,25 @@ void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color, bo
return;
}
else if (skinnum == TC_RAINBOW)
else if (color == SKINCOLOR_NONE)
{
K_RainbowColormap(dest_colormap, color);
for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
dest_colormap[i] = (UINT8)i;
return;
}
if (color >= MAXTRANSLATIONS)
I_Error("Invalid skin color #%hu.", (UINT16)color);
if (skinnum < 0 && skinnum > TC_DEFAULT)
I_Error("Invalid translation colormap index %d.", skinnum);
starttranscolor = (skinnum != TC_DEFAULT) ? K_GetSkinArray(local)[skinnum].starttranscolor : DEFAULT_STARTTRANSCOLOR;
if (starttranscolor >= NUM_PALETTE_ENTRIES)
I_Error("Invalid startcolor #%d.", starttranscolor);
// Fill in the entries of the palette that are fixed
for (i = 0; i < starttranscolor; i++)
dest_colormap[i] = (UINT8)i;
@@ -1586,7 +1612,7 @@ static UINT8 K_CheckOffroadCollide(mobj_t *mo)
// we will do essentially the same checks as above instead of bothering with top/bottom height of the FOF.
// Reminder that an FOF's floor is its bottom, silly!
if ( ((s2->flags & SF_FLIPSPECIAL_FLOOR) && mo->z == cel) // "floor" check
if ( ((s2->flags & SF_FLIPSPECIAL_FLOOR) && mo->z == cel) // "floor" check
|| ((s2->flags & SF_FLIPSPECIAL_CEILING) && (mo->z + mo->height) == flr) ) // "ceiling" check.
for (i = 2; i < 5; i++) // check for sector special
@@ -1670,10 +1696,10 @@ static void K_SpawnDashDustRelease(player_t *player)
I_Assert(player->mo != NULL);
I_Assert(!P_MobjWasRemoved(player->mo));
if (!P_IsObjectOnGround(player->mo))
if (!player->speed && !player->kartstuff[k_startboost])
return;
if (!player->speed && !player->kartstuff[k_startboost])
if (!P_IsObjectOnGround(player->mo))
return;
travelangle = player->mo->angle;
@@ -1903,11 +1929,11 @@ static void K_PlayGenericCombatSound(mobj_t *source, mobj_t *other, sfxenum_t sf
boolean alwaysHear = false;
if (other != NULL && P_MobjWasRemoved(other) == false && other->player != NULL)
if (cv_kartvoices.value && !P_MobjWasRemoved(other) && other->player != NULL)
{
alwaysHear = P_IsDisplayPlayer(other->player);
if (cv_kartvoices.value)
S_StartSound(alwaysHear ? NULL : source, skin->soundsid[S_sfx[sfx_id].skinsound]);
}
K_RegularVoiceTimers(source->player);
}
@@ -1929,7 +1955,7 @@ void K_PlayAttackTaunt(mobj_t *source)
void K_PlayBoostTaunt(mobj_t *source)
{
sfxenum_t pick = P_RandomKey(2); // Gotta roll the RNG every time this is called for sync reasons
boolean tasteful = (!source->player || !source->player->kartstuff[k_tauntvoices]);
const boolean tasteful = (!source->player || !source->player->kartstuff[k_tauntvoices]);
if (cv_kartvoices.value && (tasteful || cv_kartvoices.value == 2))
S_StartSound(source, sfx_kbost1+pick);
@@ -1942,8 +1968,6 @@ void K_PlayBoostTaunt(mobj_t *source)
void K_PlayOvertakeSound(mobj_t *source)
{
boolean tasteful = (!source->player || !source->player->kartstuff[k_voices]);
if (!G_RaceGametype()) // Only in race
return;
@@ -1951,6 +1975,8 @@ void K_PlayOvertakeSound(mobj_t *source)
if (leveltime < starttime+(10*TICRATE))
return;
const boolean tasteful = (!source->player || !source->player->kartstuff[k_voices]);
if (cv_kartvoices.value && (tasteful || cv_kartvoices.value == 2))
S_StartSound(source, sfx_kslow);
@@ -2186,6 +2212,7 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower)
if (doboostpower)
return FixedMul(finalspeed, player->kartstuff[k_boostpower]+player->kartstuff[k_speedboost]);
return finalspeed;
}
@@ -2222,10 +2249,14 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove
{
fixed_t accelmax = 4000;
fixed_t newspeed, oldspeed, finalspeed;
fixed_t p_speed = K_GetKartSpeed(player, true);
fixed_t p_accel = K_GetKartAccel(player);
fixed_t p_speed, p_accel;
if (!onground) return 0; // If the player isn't on the ground, there is no change in speed
// If the player isn't on the ground, there is no change in speed
if (!onground)
return 0;
p_speed = K_GetKartSpeed(player, true);
p_accel = K_GetKartAccel(player);
// ACCELCODE!!!1!11!
oldspeed = R_PointToDist2(0, 0, player->rmomx, player->rmomy); // FixedMul(P_AproxDistance(player->rmomx, player->rmomy), player->mo->scale);
@@ -2329,6 +2360,7 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto
if (P_MobjWasRemoved(player->mo))
return; // mobj was removed (in theory that shouldn't happen)
if (shouldForce == 1)
force = true;
else if (shouldForce == 2)
@@ -2469,8 +2501,10 @@ void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor)
// PS: Inflictor is unused for all purposes here and is actually only ever relevant to Lua. It may be nil too.
boolean force = false; // Used to check if Lua ShouldSquish should get us damaged reguardless of flashtics or heck knows what.
UINT8 shouldForce = LUA_HookShouldSquish(player, inflictor, source);
if (P_MobjWasRemoved(player->mo))
return; // mobj was removed (in theory that shouldn't happen)
if (shouldForce == 1)
force = true;
else if (shouldForce == 2)
@@ -2583,6 +2617,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b
if (P_MobjWasRemoved(player->mo))
return; // mobj was removed (in theory that shouldn't happen)
if (shouldForce == 1)
force = true;
else if (shouldForce == 2)
@@ -2668,6 +2703,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b
player->powers[pw_flashing] = K_GetKartFlashing(player);
upgoer = (18*mapobjectscale*P_MobjFlip(player->mo));
if (player->mo->eflags & MFE_UNDERWATER)
upgoer = (117 * upgoer) / 200;
@@ -3540,11 +3576,14 @@ void K_SpawnSparkleTrail(mobj_t *mo)
fixed_t newz = mo->z + mo->momz + (P_RandomRange(0, mo->height>>FRACBITS)<<FRACBITS);
sparkle = P_SpawnMobj(newx, newy, newz, MT_SPARKLETRAIL);
K_FlipFromObject(sparkle, mo);
P_SetTarget(&sparkle->target, mo);
sparkle->destscale = mo->destscale;
P_SetScale(sparkle, mo->scale);
sparkle->color = mo->color;
if (cv_playerblendeffects.value && mo->player && K_SpeedLinesShouldBlend(mo->player))
@@ -3603,7 +3642,6 @@ void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent)
void K_DriftDustHandling(mobj_t *spawner)
{
angle_t anglediff;
const INT16 spawnrange = spawner->radius>>FRACBITS;
if (!P_IsObjectOnGround(spawner) || leveltime % 2 != 0)
return;
@@ -3640,6 +3678,8 @@ void K_DriftDustHandling(mobj_t *spawner)
if (anglediff > ANGLE_180)
anglediff = InvAngle(anglediff);
const INT16 spawnrange = spawner->radius>>FRACBITS;
if (anglediff > ANG10*4) // Trying to turn further than 40 degrees
{
fixed_t spawnx = P_RandomRange(-spawnrange, spawnrange)<<FRACBITS;
@@ -3899,9 +3939,8 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
void K_PuntMine(mobj_t *thismine, mobj_t *punter)
{
angle_t fa = R_PointToAngle2(0, 0, punter->momx, punter->momy) >> ANGLETOFINESHIFT;
fixed_t z = 30*mapobjectscale + punter->momz;
fixed_t spd;
angle_t fa;
fixed_t z, spd;
mobj_t *mine;
if (P_MobjWasRemoved(thismine))
@@ -3936,6 +3975,9 @@ void K_PuntMine(mobj_t *thismine, mobj_t *punter)
if (P_MobjWasRemoved(mine))
return;
fa = R_PointToAngle2(0, 0, punter->momx, punter->momy) >> ANGLETOFINESHIFT;
z = 30*mapobjectscale + punter->momz;
spd = K_GetProjectileSpeed();
mine->flags |= MF_NOCLIPTHING;
@@ -4147,8 +4189,10 @@ static void K_DoShrink(player_t *user)
{
if (!playeringame[i] || players[i].spectator || !players[i].mo)
continue;
if (&players[i] == user)
continue;
if (players[i].kartstuff[k_position] < user->kartstuff[k_position])
{
//P_FlashPal(&players[i], PAL_NUKE, 10);
@@ -5033,6 +5077,7 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source)
// Find the angle, see who's got the best.
thisang = actor->angle - R_PointToAngle2(actor->x, actor->y, player->mo->x, player->mo->y);
if (thisang > ANGLE_180)
thisang = InvAngle(thisang);
@@ -5229,10 +5274,11 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd)
static void K_UpdateInvincibilitySounds(player_t *player)
{
INT32 sfxnum = sfx_None;
const boolean localplayer = P_IsLocalPlayer(player);
if (player->mo->health > 0)
{
const boolean localplayer = P_IsLocalPlayer(player);
if (player->kartstuff[k_growshrinktimer] > 0 && (!localplayer || cv_growmusic.value == 2)) // Prioritize Grow
sfxnum = cv_kartinvinsfx.value ? sfx_alarmg : sfx_kgrow;
else if (player->kartstuff[k_invincibilitytimer] > 0 && (!localplayer || cv_supermusic.value == 2))
@@ -5772,7 +5818,7 @@ boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y)
static INT16 K_GetKartDriftValue(player_t *player, fixed_t countersteer)
{
INT16 basedrift, driftangle;
fixed_t driftweight = player->kartweight*14; // 12
fixed_t driftweight;
// If they aren't drifting or on the ground this doesn't apply
if (player->kartstuff[k_drift] == 0 || !P_IsObjectOnGround(player->mo))
@@ -5783,6 +5829,8 @@ static INT16 K_GetKartDriftValue(player_t *player, fixed_t countersteer)
return -266*player->kartstuff[k_drift]; // Drift has ended and we are tweaking their angle back a bit
}
driftweight = player->kartweight*14; // 12
//basedrift = 90*player->kartstuff[k_drift]; // 450
//basedrift = 93*player->kartstuff[k_drift] - driftweight*3*player->kartstuff[k_drift]/10; // 447 - 303
basedrift = 83*player->kartstuff[k_drift] - (driftweight - 14)*player->kartstuff[k_drift]/5; // 415 - 303
@@ -5793,6 +5841,9 @@ static INT16 K_GetKartDriftValue(player_t *player, fixed_t countersteer)
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
{
fixed_t p_topspeed, p_curspeed, p_maxspeed;
fixed_t adjustangle;
if (player->spectator)
return turnvalue;
@@ -5811,10 +5862,10 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
return turnvalue;
}
fixed_t p_topspeed = K_GetKartSpeed(player, false);
fixed_t p_curspeed = min(player->speed, p_topspeed * 2);
fixed_t p_maxspeed = p_topspeed * 3;
fixed_t adjustangle = FixedDiv((p_maxspeed>>16) - (p_curspeed>>16), (p_maxspeed>>16) + player->kartweight);
p_topspeed = K_GetKartSpeed(player, false);
p_curspeed = min(player->speed, p_topspeed * 2);
p_maxspeed = p_topspeed * 3;
adjustangle = FixedDiv((p_maxspeed>>16) - (p_curspeed>>16), (p_maxspeed>>16) + player->kartweight);
turnvalue = FixedMul(turnvalue, adjustangle); // Weight has a small effect on turning
@@ -6216,7 +6267,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_KartUpdatePosition(player);
if (!player->exiting)
if (LIKELY(!player->exiting))
{
if (player->kartstuff[k_oldposition] < player->kartstuff[k_position]) // But first, if you lost a place,
{
@@ -6796,10 +6847,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_KartDrift(player, onground);
if ((!player->kartstuff[k_aizdriftstrat]) || (!P_IsObjectOnGround(player->mo)) || (player->kartstuff[k_drift]))
if (player->sliproll && ((!player->kartstuff[k_aizdriftstrat]) || (!P_IsObjectOnGround(player->mo)) || (player->kartstuff[k_drift])))
{
if (player->sliproll && (player->sliproll > 0))
player->sliproll -= (4*ANG1);
player->sliproll -= (4*ANG1);
}
// funneh Saturn sprite stuff
+12 -6
View File
@@ -393,6 +393,16 @@ FUNCINLINE static ATTRINLINE boolean prepare_string_hook
return false;
}
static boolean prepare_hud_hook
(
Hook_State * hook,
int hook_type
){
return init_hook_type(hook, 0,
hook_type, 0, NULL,
hudHookIds[hook_type].numHooks);
}
FUNCINLINE static ATTRINLINE void init_hook_call
(
Hook_State * hook,
@@ -663,20 +673,16 @@ int LUA_HookTiccmd(player_t *player, ticcmd_t *cmd, int hook_type)
void LUA_HookHUD(int hook_type, huddrawlist_h list)
{
const hook_t * map = &hudHookIds[hook_type];
Hook_State hook;
if (map->numHooks > 0)
if (prepare_hud_hook(&hook, hook_type))
{
start_hook_stack();
begin_hook_values(&hook);
LUA_SetHudHook(hook_type, list);
hud_running = true; // local hook
hud_interpcounter = 0;
hud_interpolate = hud_interpstring = hud_interplatch = false;
init_hook_call(&hook, 1, res_hud);
call_mapped(&hook, map);
call_mapped(&hook, &hudHookIds[hook_type]);
lua_settop(gL, 0); // destroy le stack!! >:3
hud_running = false;
+3 -3
View File
@@ -1189,7 +1189,7 @@ static void UnArchiveTables(UINT8 **p, boolean network)
}
}
void LUA_Step(void)
/*void LUA_Step(void)
{
if (!gL)
return;
@@ -1200,7 +1200,7 @@ void LUA_Step(void)
lua_settop(gL, 0);
lua_gc(gL, LUA_GCSTEP, 1);
}
}
}*/
void LUA_Archive(savebuffer_t *save, boolean network)
{
@@ -1212,7 +1212,7 @@ void LUA_Archive(savebuffer_t *save, boolean network)
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] && i > 0) // NEVER skip player 0, this is for dedi servs.
if (!playeringame[i] && i > 0) // NEVER skip player 0, this is for dedi servs.
continue;
// all players in game will be archived, even if they just add a 0.
ArchiveExtVars(&save->p, &players[i], "player");
+9 -4
View File
@@ -10,6 +10,9 @@
/// \file lua_script.h
/// \brief Lua scripting basics
#ifndef LUA_SCRIPT_H
#define LUA_SCRIPT_H
#include "m_fixed.h"
#include "doomtype.h"
#include "d_player.h"
@@ -55,7 +58,7 @@ void LUA_InvalidateUserdata(void *data);
void LUA_InvalidateLevel(void);
void LUA_InvalidateMapthings(void);
void LUA_InvalidatePlayer(player_t *player);
void LUA_Step(void);
//void LUA_Step(void);
void LUA_Archive(savebuffer_t *save, boolean network);
void LUA_UnArchive(savebuffer_t *save, boolean network);
@@ -75,7 +78,7 @@ void COM_Lua_f(void);
#define LUA_Deprecated(L,this_func,use_instead)\
{\
static UINT8 seen = 0;\
if (!seen) {\
if (UNLIKELY(!seen)) {\
seen = 1;\
CONS_Alert(CONS_WARNING,"\"%s\" is deprecated and will be removed.\nUse \"%s\" instead.\n", this_func, use_instead);\
}\
@@ -84,7 +87,7 @@ void COM_Lua_f(void);
#define LUA_LogDeprecated(L,this_func,use_instead)\
{\
static UINT8 seen = 0;\
if (!seen) {\
if (UNLIKELY(!seen)) {\
seen = 1;\
CON_LogMessage(va("\"%s\" is deprecated and will be removed.\nUse \"%s\" instead.\n", this_func, use_instead));\
}\
@@ -95,8 +98,10 @@ void COM_Lua_f(void);
#define LUA_UsageWarning(L, warningmsg)\
{\
static UINT8 seen = 0;\
if (!seen) {\
if (UNLIKELY(!seen)) {\
seen = 1;\
CONS_Alert(CONS_WARNING,"%s\n", warningmsg);\
}\
}
#endif/*LUA_SCRIPT_H*/
+51 -34
View File
@@ -20,17 +20,17 @@
typedef struct aatree_node_s
{
INT32 level;
INT32 key;
void* value;
INT32 key;
INT32 depth;
void *value;
struct aatree_node_s *left, *right;
} aatree_node_t;
struct aatree_s
{
aatree_node_t *root;
UINT32 flags;
aatree_node_t *root;
UINT32 flags;
};
aatree_t *M_AATreeAlloc(UINT32 flags)
@@ -56,40 +56,48 @@ void M_AATreeFree(aatree_t *aatree)
Z_Free(aatree);
}
static aatree_node_t *M_AATreeSkew(aatree_node_t *node)
static aatree_node_t *M_AATreeRotateRight(aatree_node_t *node)
{
if (node && node->left && node->left->level == node->level)
{
// Not allowed: horizontal left-link. Reverse the
// horizontal link and hook the orphan back in.
aatree_node_t *oldleft = node->left;
node->left = oldleft->right;
oldleft->right = node;
return oldleft;
}
// No change needed.
return node;
aatree_node_t *newnode = node->left;
aatree_node_t *tmp = newnode->right;
newnode->right = node;
node->left = tmp;
return newnode;
}
static aatree_node_t *M_AATreeSplit(aatree_node_t *node)
static aatree_node_t *M_AATreeRotateLeft(aatree_node_t *node)
{
if (node && node->right && node->right->right && node->level == node->right->right->level)
aatree_node_t *newnode = node->right;
aatree_node_t *tmp = newnode->left;
newnode->left = node;
node->right = tmp;
return newnode;
}
static aatree_node_t *M_AATreeRebalance(aatree_node_t *node)
{
INT32 balance;
if (node->left == NULL && node->right == NULL)
return node;
if (node->left == NULL)
balance = -node->right->depth;
else if (node->right == NULL)
balance = node->left->depth;
else
{
// Not allowed: two consecutive horizontal right-links.
// The middle one becomes the new root at this point,
// with suitable adjustments below.
I_Assert(node->left->key < node->right->key);
balance = node->left->depth - node->right->depth;
}
aatree_node_t *oldright = node->right;
node->right = oldright->left;
oldright->left = node;
oldright->level++;
return oldright;
if (balance > 1)
{
return M_AATreeRotateRight(node);
}
else if (balance < -1)
{
return M_AATreeRotateLeft(node);
}
// No change needed.
return node;
}
@@ -99,11 +107,11 @@ static aatree_node_t *M_AATreeSet_Node(aatree_node_t *node, UINT32 flags, INT32
{
// Nothing here, so just add where we are
node = Z_Malloc(sizeof (aatree_node_t), PU_STATIC, NULL);
node->level = 1;
node->key = key;
if (value && (flags & AATREE_ZUSER)) Z_SetUser(value, &node->value);
else node->value = value;
node->left = node->right = NULL;
node->depth = 1;
}
else
{
@@ -117,8 +125,17 @@ static aatree_node_t *M_AATreeSet_Node(aatree_node_t *node, UINT32 flags, INT32
else node->value = value;
}
node = M_AATreeSkew(node);
node = M_AATreeSplit(node);
node = M_AATreeRebalance(node);
if (node->left == NULL && node->right == NULL)
node->depth = 1;
else if (node->left == NULL)
node->depth = node->right->depth + 1;
else if (node->right == NULL)
node->depth = node->left->depth + 1;
else if (node->left->depth > node->right->depth)
node->depth = node->left->depth + 1;
else
node->depth = node->right->depth + 1;
}
return node;
+262
View File
@@ -0,0 +1,262 @@
#include <map>
#include <string>
#include <sstream>
#include <cstring>
#include "m_emotes.h"
extern "C" {
#include "w_wad.h"
#include "z_zone.h"
#include "hu_stuff.h"
#include "v_video.h"
}
consvar_t cv_emotes = {"emotes", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};;
static std::map<std::string, emote_t> emotes;
// TODO - Would be really nice to generalize soc-like file parsing and not reimplement it 100 times :)))))
void M_LoadEmotes(UINT16 wadnum)
{
UINT16 lumpnum = W_CheckNumForNamePwad("EMOTES", wadnum, 0);
if (lumpnum == INT16_MAX)
return;
char *lump = static_cast<char*>(W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE));
size_t size = W_LumpLengthPwad(wadnum, lumpnum);
std::istringstream file(std::string(lump, size));
std::string line;
emote_t *emote = nullptr;
std::string emote_name;
// Just smol lambda to remove all the trailing chars we might not want
auto trim = [](std::string &str) {
str.erase(0, str.find_first_not_of(" \t\n\r\f\v"));
str.erase(str.find_last_not_of(" \t\n\r\f\v")+1);
};
int numemotes = 0;
int linenum = 0;
while (std::getline(file, line))
{
++linenum;
trim(line);
if (line.empty())
continue;
size_t split = line.find('=');
// Didn't find the =, means we're about to parse `Emote <name>`
if (split == line.npos)
{
split = line.find(' ');
if (split == line.npos)
{
CONS_Alert(CONS_WARNING, "EMOTES: Unrecognized line. (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
continue;
}
if (strnicmp(line.c_str(), "emote", 5))
{
CONS_Alert(CONS_WARNING, "EMOTES: 'Emote' expected. (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
continue;
}
emote_name = line.substr(split+1);
if (emote_name.find_first_of(" \t\n\r\f\v:") != emote_name.npos)
{
CONS_Alert(CONS_WARNING, "EMOTES: Emote name cannot contain spaces or ':' symbols. (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
continue;
}
if (emote_name.size() > MAXEMOTENAME)
{
CONS_Alert(CONS_WARNING, "EMOTES: Emote name is too long, truncating. (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
emote_name = emote_name.substr(0, MAXEMOTENAME);
}
emote = &emotes[emote_name];
strlcpy(emote->name, emote_name.c_str(), MAXEMOTENAME);
emote->timeperframe = 1;
emote->numframes = 0;
std::memset(emote->frames, 0, sizeof(emote->frames));
++numemotes;
}
else if (emote)
{
std::string field = line.substr(0, split);
std::string value = line.substr(split+1);
trim(field);
trim(value);
if (stricmp(field.c_str(), "frames") == 0)
{
UINT8 numframes = 0;
auto copy_frame = [&] {
if (numframes == MAXEMOTEFRAMES)
{
CONS_Alert(CONS_WARNING, "EMOTES: Too many frames. (file %s, line %d)", wadfiles[wadnum]->filename, linenum);
return false;
}
size_t list_split = value.find(',');
std::string framelumpname = value.substr(0, list_split);
trim(framelumpname);
if (list_split == value.npos)
value = "";
else
value = value.substr(list_split+1, value.npos);
// End of list of frames
if (framelumpname.size() == 0)
return false;
if (framelumpname.size() > 8)
{
CONS_Alert(CONS_WARNING, "EMOTES: Frame %d name is too long. (file %s, line %d)", numframes, wadfiles[wadnum]->filename, linenum);
framelumpname = framelumpname.substr(0, 8);
}
std::strncpy(emote->frames[numframes], framelumpname.c_str(), framelumpname.size()+1);
++numframes;
return true;
};
while (copy_frame()) {}
if (numframes == 0)
{
CONS_Alert(CONS_WARNING, "EMOTES: Expected list of frames. (file %s, line %d)", wadfiles[wadnum]->filename, linenum);
}
emote->numframes = numframes;
}
else if (stricmp(field.c_str(), "timeperframe") == 0)
{
emote->timeperframe = std::stoi(value);
if (emote->timeperframe <= 0)
{
emote->timeperframe = 1;
CONS_Alert(CONS_WARNING, "EMOTES: Bad value for 'timeperframe'. (file %s, line %d)", wadfiles[wadnum]->filename, linenum);
}
}
else
{
CONS_Alert(CONS_WARNING, "EMOTES: Unrecognized field '%s'. (file %s, line %d)", field.c_str(), wadfiles[wadnum]->filename, linenum);
}
}
else
{
CONS_Alert(CONS_WARNING, "EMOTES: Unrecognized line. (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
}
}
CONS_Printf("Added %d emotes\n", numemotes);
}
void M_InitEmotes(void)
{
UINT16 i;
for (i = 0; i < numwadfiles; i++)
M_LoadEmotes(i);
}
emote_t *M_FindEmote(const char *name, int len, int skip)
{
if (!cv_emotes.value)
return nullptr;
char query[MAXEMOTENAME+1] = {0};
std::strncpy(query, name, std::min(len, MAXEMOTENAME));
for (auto &pair: emotes)
{
if (pair.first.rfind(query, 0, std::min(len, MAXEMOTENAME)) != 0)
continue;
if (skip > 0)
{
--skip;
continue;
}
return &pair.second;
}
return nullptr;
}
emote_t *M_VerifyEmote(const char *name, int *emotelen)
{
if (*name != ':')
return nullptr;
if (!cv_emotes.value)
return nullptr;
const char *p = name+1; // skip ':'
emote_t *match = nullptr;
while (*p && (p - name) < MAXEMOTENAME)
{
if (*p == ':')
{
std::string checkname = std::string(name+1, (p-name)-1);
auto it = emotes.find(checkname);
if (it != emotes.end())
match = &it->second;
break;
}
++p;
}
if (match && emotelen)
*emotelen = p-name+1;
return match;
}
void M_DrawEmote(INT32 x, INT32 y, emote_t *emote, tic_t anim, INT32 flags)
{
if (emote->numframes == 0)
return;
const char *lumpname = emote->frames[(anim/emote->timeperframe) % emote->numframes];
patch_t *emotepatch = (patch_t*)W_CachePatchName(lumpname, PU_CACHE);
const int CHARHEIGHT = 6;
fixed_t scale = FRACUNIT;
x *= FRACUNIT;
y *= FRACUNIT;
if (emotepatch->width > EMOTEWIDTH)
scale = (FRACUNIT/emotepatch->width)*EMOTEWIDTH;
else if (emotepatch->width < EMOTEWIDTH)
x += (EMOTEWIDTH-emotepatch->width)*FRACUNIT/2;
y -= (scale*emotepatch->height-CHARHEIGHT*FRACUNIT)/2;
V_DrawFixedPatch(x, y, scale, flags, emotepatch, NULL);
}
+48
View File
@@ -0,0 +1,48 @@
#ifndef __M_EMOTES__
#define __M_EMOTES__
#ifdef __cplusplus
extern "C" {
#endif
#include "doomdef.h"
#include "command.h"
extern consvar_t cv_emotes;
#define MAXEMOTENAME 32
#define MAXEMOTEFRAMES 32
#define EMOTEWIDTH 6
typedef struct emote_s {
char name[MAXEMOTENAME+1];
char frames[MAXEMOTEFRAMES][9];
UINT8 numframes;
tic_t timeperframe;
} emote_t;
// Reads and adds emotes from EMOTES lump, with syntax similar to soc
void M_LoadEmotes(UINT16 wadnum);
// Load emotes from all base wads
void M_InitEmotes(void);
// Finds first matching emote, ignoring first few matches
emote_t *M_FindEmote(const char *name, int len, int skips);
// If first character is not ':', instantly returns null
// Starts from ':' character, goes until it finds ':' or end of string
// If end of string is found, or closing ':' is found but resulting emote name doesn't exist,
// it returns null, otherwise it returns emote and stores into *emotelen how much characters
// needs to be skipped to get past emote name
emote_t *M_VerifyEmote(const char *name, int *emotelen);
// Draw the emote, anim should be some kind of timer ticking every game tic
// for animated emotes
void M_DrawEmote(INT32 x, INT32 y, emote_t *emote, tic_t anim, INT32 flags);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // __M_EMOTES__
+288 -3596
View File
File diff suppressed because it is too large. Load diff
+2946
View File
File diff suppressed because it is too large. Load diff
+44
View File
@@ -2294,6 +2294,50 @@ void M_MkdirEach(const char *path, int start, int mode)
M_MkdirEachUntil(path, start, -1, mode);
}
// Hashes some message using FNV-1a
#define FNV1A_OFFSET_BASIS 0x811C9DC5
#define FNV1A_PRIME 0x01000193
UINT32 FNV1a_Hash(const char *message, size_t size)
{
UINT32 hash = FNV1A_OFFSET_BASIS;
for (size_t i = 0; i < size; i++)
{
hash ^= message[i];
hash *= FNV1A_PRIME;
}
return hash;
}
UINT32 FNV1a_HashString(const char *message)
{
UINT32 hash = FNV1A_OFFSET_BASIS;
while (*message)
{
hash ^= *message;
hash *= FNV1A_PRIME;
message++;
}
return hash;
}
UINT32 FNV1a_HashLowercaseString(const char *message)
{
UINT32 hash = FNV1A_OFFSET_BASIS;
while (*message)
{
hash ^= tolower(*message);
hash *= FNV1A_PRIME;
message++;
}
return hash;
}
#ifdef __cplusplus
} // extern "C"
+5
View File
@@ -124,6 +124,11 @@ const char * M_Ftrim (double);
// counting bits, for weapon ammo code, usually
FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size);
// Hashes some message using FNV-1a
UINT32 FNV1a_Hash(const char *message, size_t size);
UINT32 FNV1a_HashString(const char *message);
UINT32 FNV1a_HashLowercaseString(const char *message);
#include "w_wad.h"
extern char configfile[MAX_WADPATH];
+169 -5
View File
@@ -130,6 +130,82 @@ static void M_TextInputPaste(textinput_t *input)
M_TextInputAddString(input, paste);
}
static void M_TextInputLeft(textinput_t *input, boolean emotes)
{
// Just do it simple way if possible
if (!emotes || input->cursor < 2 || input->buffer[input->cursor-1] != ':')
{
if (input->cursor != 0)
--input->cursor;
return;
}
// Otherwise we need to check if we have to skip emote
size_t start = input->cursor-2;
while (input->buffer[start] != ':')
{
// We reached start of string and didn't find ':' symbol, thats definitely not an emote
// so just do it simple way
if (start == 0)
{
M_TextInputLeft(input, false);
return;
}
--start;
}
int emotelen = 0;
if (M_VerifyEmote(input->buffer+start, &emotelen))
input->cursor -= emotelen; // also skip the :
else
M_TextInputLeft(input, false); // Not a valid emote, do the simple thing
}
static void M_TextInputRight(textinput_t *input, boolean emotes)
{
// Just do it simple way if possible
if (!emotes || input->cursor == input->length || input->buffer[input->cursor] != ':')
{
if (input->cursor < input->length)
++input->cursor;
return;
}
int emotelen = 0;
if (M_VerifyEmote(input->buffer+input->cursor, &emotelen))
input->cursor += emotelen; // Also skip the :
else
M_TextInputRight(input, false); // Not a valid emote, do the simple thing
}
// Check if we're inside a valid emote
static boolean M_TextInputCheckEmote(textinput_t *input)
{
int start = input->cursor;
// Definitely not an emote
if (start == 0)
return false;
// Might be closing :, need to skip it just in case
if (input->buffer[start] == ':')
--start;
while (input->buffer[start] != ':')
{
// No ':' found, definitely not inside emote
if (start == 0)
return false;
--start;
}
// Found what may be emote start, now we can check
return M_VerifyEmote(input->buffer+start, NULL) != NULL;
}
void M_TextInputInit(textinput_t *input, char *buffer, size_t buffer_size)
{
input->buffer = buffer;
@@ -156,7 +232,7 @@ void M_TextInputSetString(textinput_t *input, const char *c)
input->cursor = input->select = input->length = strlen(c);
}
boolean M_TextInputHandle(textinput_t *input, INT32 key)
static boolean M_TextInputHandleBase(textinput_t *input, INT32 key, boolean emotes)
{
if (key == KEY_LSHIFT || key == KEY_RSHIFT
|| key == KEY_LCTRL || key == KEY_RCTRL
@@ -241,16 +317,14 @@ boolean M_TextInputHandle(textinput_t *input, INT32 key)
if (key == KEY_LEFTARROW)
{
if (input->cursor != 0)
--input->cursor;
M_TextInputLeft(input, emotes);
if (!shiftdown)
input->select = input->cursor;
return true;
}
else if (key == KEY_RIGHTARROW)
{
if (input->cursor < input->length)
++input->cursor;
M_TextInputRight(input, emotes);
if (!shiftdown)
input->select = input->cursor;
return true;
@@ -320,6 +394,96 @@ boolean M_TextInputHandle(textinput_t *input, INT32 key)
return true;
}
// Just an alias, more or less
boolean M_TextInputHandle(textinput_t *input, INT32 key)
{
return M_TextInputHandleBase(input, key, false);
}
boolean M_TextInputHandleEmotes(textinput_t *input, INT32 key, emote_t *suggestions[], int maxsuggestions)
{
boolean ret = M_TextInputHandleBase(input, key, true);
// After this handled key we ended up inside an emote, lets fix that
if (M_TextInputCheckEmote(input))
M_TextInputToWordEnd(input, !shiftdown);
// Always clear the first entry
suggestions[0] = NULL;
// For autocomplete
int emotestart = 0;
// Try find suggestions for emote names
for (int i = input->cursor-1; i >= 0 && input->cursor-i <= MAXEMOTENAME; --i)
{
// Space can't be part of emote name
if (isspace(input->buffer[i]))
break;
// Found a :, try suggest emotes
if (input->buffer[i] == ':')
{
emotestart = i+1;
// ...But only if we typed at least something
if ((int)input->cursor-(i-1) < 3)
break;
for (int skip = 0; skip < maxsuggestions; ++skip)
{
suggestions[skip] = M_FindEmote(input->buffer+i+1, input->cursor-i-1, skip);
// No more suggestions
if (!suggestions[skip])
break;
}
// In any case, we found what we wanted, can exit the loop now
break;
}
}
// If we suggest emotes, try autocomplete
if (key == '\t' && suggestions[0])
{
int pos = (input->cursor-emotestart);
boolean autocomplete = true;
while (autocomplete)
{
// Check if current character matches for all suggestions
char c = suggestions[0]->name[pos];
// End of string reached
if (!c)
break;
for (int i = 1; i < maxsuggestions && suggestions[i]; ++i)
{
if (suggestions[i]->name[pos] != c)
{
autocomplete = false;
break;
}
}
++pos;
if (autocomplete)
M_TextInputAddChar(input, c);
}
// This was the only suggestion, finish autocomplete with a ':' and clear suggestions
if (maxsuggestions == 1 || !suggestions[1])
{
M_TextInputAddChar(input, ':');
suggestions[0] = NULL;
}
}
return ret;
}
void M_DrawTextInputScroll(INT32 x, INT32 y, textinput_t *input, INT32 flags, INT32 MAXINPUTWIDTH)
{
if (renderisnewtic)
+5
View File
@@ -2,6 +2,7 @@
#define __M_TEXTINPUT__
#include "doomtype.h"
#include "m_emotes.h" // M_VerifyEmote, M_FindEmote
typedef struct textinput_s {
size_t cursor;
@@ -22,6 +23,10 @@ void M_TextInputSetString(textinput_t *input, const char *c);
boolean M_TextInputHandle(textinput_t *input, INT32 key);
// Does everything same as M_TextInputHandle, but also handles emotes in input string
// If currently typing something that looks like an existing emote, return suggestions for it
boolean M_TextInputHandleEmotes(textinput_t *input, INT32 key, emote_t *suggestions[], int maxsuggestions);
#define M_DrawTextInput(x, y, input, flags) M_DrawTextInputScroll((x), (y), (input), (flags), ((input)->buffer_size-1)*8)
void M_DrawTextInputScroll(INT32 x, INT32 y, textinput_t *input, INT32 flags, INT32 MAXINPUTWIDTH);
+4
View File
@@ -30,7 +30,11 @@ typedef union
typedef struct
{
msg_header_t header;
#ifndef HAVE_IPV6
char ip[16];
#else
char ip[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
#endif
char port[8];
char contact[32];
char version[8]; // format is: x.yy.z (like 1.30.2 or 1.31)
+3 -2
View File
@@ -250,7 +250,7 @@ boolean P_Move(mobj_t *actor, fixed_t speed)
I_Assert(movedir < NUMDIRS);
tryx = actor->x + FixedMul(speed*xspeed[movedir], actor->scale);
if (twodlevel || actor->flags2 & MF2_TWOD)
if (UNLIKELY(twodlevel || actor->flags2 & MF2_TWOD))
tryy = actor->y;
else
tryy = actor->y + FixedMul(speed*yspeed[movedir], actor->scale);
@@ -481,6 +481,7 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
if (!allaround)
{
an = R_PointToAngle2(actor->x, actor->y, player->mo->x, player->mo->y) - actor->angle;
if (an > ANGLE_90 && an < ANGLE_270)
{
dist = P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y);
@@ -4387,7 +4388,7 @@ void A_MouseThink(void *thing)
|| (actor->eflags & MFE_VERTICALFLIP && actor->z + actor->height == actor->ceilingz))
&& !actor->reactiontime)
{
if (twodlevel || actor->flags2 & MF2_TWOD)
if (UNLIKELY(twodlevel || actor->flags2 & MF2_TWOD))
{
if (P_RandomChance(FRACUNIT/2))
actor->angle += ANGLE_180;
+14 -13
View File
@@ -587,7 +587,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
special->momx = special->momy = special->momz = 0;
P_GivePlayerRings(player, 1);
if ((maptol & TOL_NIGHTS) && special->type != MT_FLINGRING)
if (UNLIKELY((maptol & TOL_NIGHTS) && special->type != MT_FLINGRING))
P_DoNightsScore(player);
break;
@@ -599,7 +599,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
special->momx = special->momy = 0;
P_GivePlayerRings(player, 1);
if ((maptol & TOL_NIGHTS) && special->type != MT_FLINGCOIN)
if (UNLIKELY((maptol & TOL_NIGHTS) && special->type != MT_FLINGCOIN))
P_DoNightsScore(player);
break;
case MT_BLUEBALL:
@@ -615,7 +615,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
else
special->scalespeed = 4*FRACUNIT/5;
if (maptol & TOL_NIGHTS)
if (UNLIKELY(maptol & TOL_NIGHTS))
P_DoNightsScore(player);
break;
case MT_AUTOPICKUP:
@@ -832,6 +832,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (player->bumpertime < TICRATE/4)
{
S_StartSound(toucher, special->info->seesound);
if (player->pflags & PF_NIGHTSMODE)
{
player->bumpertime = TICRATE/2;
@@ -1226,9 +1227,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return; // SRB2kart - don't need bubbles mucking with the player
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)
return;
if (maptol & TOL_NIGHTS)
if (UNLIKELY(maptol & TOL_NIGHTS))
return;
if (mariomode)
if (UNLIKELY(mariomode))
return;
else if (toucher->eflags & MFE_VERTICALFLIP)
{
@@ -2352,11 +2353,11 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (player->exiting)
return false;
if (!(target->player->pflags & (PF_NIGHTSMODE|PF_NIGHTSFALL)) && (maptol & TOL_NIGHTS))
if (UNLIKELY(!(target->player->pflags & (PF_NIGHTSMODE|PF_NIGHTSFALL)) && (maptol & TOL_NIGHTS)))
return false;
}
if (player->pflags & PF_NIGHTSMODE) // NiGHTS damage handling
if (UNLIKELY(player->pflags & PF_NIGHTSMODE)) // NiGHTS damage handling
{
if (!force)
{
@@ -2601,7 +2602,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
ns = FixedMul(((i*FRACUNIT)/16)+2*FRACUNIT, mo->scale);
mo->momx = FixedMul(FINECOSINE(fa),ns);
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
mo->momy = FixedMul(FINESINE(fa),ns);
P_SetObjectMomZ(mo, 8*FRACUNIT, false);
@@ -2625,7 +2626,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
ns = FixedMul(momxy, mo->scale);
mo->momx = FixedMul(FINECOSINE(fa),ns);
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
mo->momy = FixedMul(FINESINE(fa),ns);
ns = momz;
@@ -2732,7 +2733,7 @@ void P_PlayerWeaponPanelBurst(player_t *player)
ns = FixedMul(3*FRACUNIT, mo->scale);
mo->momx = FixedMul(FINECOSINE(fa),ns);
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
mo->momy = FixedMul(FINESINE(fa),ns);
P_SetObjectMomZ(mo, 4*FRACUNIT, false);
@@ -2816,7 +2817,7 @@ void P_PlayerWeaponAmmoBurst(player_t *player)
ns = FixedMul(2*FRACUNIT, mo->scale);
mo->momx = FixedMul(FINECOSINE(fa), ns);
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
mo->momy = FixedMul(FINESINE(fa),ns);
P_SetObjectMomZ(mo, 3*FRACUNIT, false);
@@ -2932,7 +2933,7 @@ void P_PlayerEmeraldBurst(player_t *player, boolean toss)
momx = FixedMul(FINECOSINE(fa), ns);
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
momy = FixedMul(FINESINE(fa),ns);
else
momy = 0;
@@ -2989,7 +2990,7 @@ void P_PlayerFlagBurst(player_t *player, boolean toss)
{
angle_t fa = P_RandomByte()*FINEANGLES/256;
flag->momx = FixedMul(FINECOSINE(fa), FixedMul(6*FRACUNIT, player->mo->scale));
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
flag->momy = FixedMul(FINESINE(fa), FixedMul(6*FRACUNIT, player->mo->scale));
}
+9 -9
View File
@@ -140,7 +140,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
if (object->player && object->player->spectator)
return false;
if (object->player && (object->player->pflags & PF_NIGHTSMODE))
if (UNLIKELY(object->player && (object->player->pflags & PF_NIGHTSMODE)))
{
/*Someone want to make these work like bumpers?*/
return false;
@@ -335,7 +335,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
#ifdef SEENAMES
// Do name checks all the way up here
// So that NOTHING ELSE can see MT_NAMECHECK because it is client-side.
if (tmthing->type == MT_NAMECHECK)
if (UNLIKELY(tmthing->type == MT_NAMECHECK))
{
// Ignore things that aren't players, ignore spectators, ignore yourself.
// (also don't bother to check that tmthing->target->player is non-NULL because we're not actually using it here.)
@@ -361,8 +361,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true;
// Don't collide with your buddies while NiGHTS-flying.
if (tmthing->player && thing->player && (maptol & TOL_NIGHTS)
&& ((tmthing->player->pflags & PF_NIGHTSMODE) || (thing->player->pflags & PF_NIGHTSMODE)))
if (UNLIKELY(tmthing->player && thing->player && (maptol & TOL_NIGHTS)
&& ((tmthing->player->pflags & PF_NIGHTSMODE) || (thing->player->pflags & PF_NIGHTSMODE))))
return true;
blockdist = thing->radius + tmthing->radius;
@@ -2004,7 +2004,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
mapcampointer = thiscam;
if (GETSECSPECIAL(newsec->special, 4) == 12)
if (UNLIKELY(GETSECSPECIAL(newsec->special, 4) == 12))
{ // Camera noclip on entire sector.
tmfloorz = tmdropoffz = thiscam->z;
tmceilingz = tmdrpoffceilz = thiscam->z + thiscam->height;
@@ -2045,10 +2045,10 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
continue;
topheight = P_CameraGetFOFTopZ(thiscam, newsec, rover, x, y, NULL);
topheight = P_CameraGetFOFTopZ(thiscam, newsec, rover, x, y, NULL);
bottomheight = P_CameraGetFOFBottomZ(thiscam, newsec, rover, x, y, NULL);
delta1 = thiscam->z - (bottomheight
@@ -2120,7 +2120,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
// We're inside it! Yess...
polysec = po->lines[0]->backsector;
if (GETSECSPECIAL(polysec->special, 4) == 12)
if (UNLIKELY(GETSECSPECIAL(polysec->special, 4) == 12))
{ // Camera noclip polyobj.
plink = (polymaplink_t *)(plink->link.next);
continue;
@@ -3183,7 +3183,7 @@ stairstep:
P_HitSlideLine(bestslideline); // clip the moves
if ((twodlevel || (mo->flags2 & MF2_TWOD)) && mo->player)
if (UNLIKELY((twodlevel || (mo->flags2 & MF2_TWOD)) && mo->player))
{
mo->momx = tmxmove;
tmymove = 0;
+2 -2
View File
@@ -366,7 +366,7 @@ void P_CameraLineOpening(line_t *linedef)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
continue;
topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef);
@@ -394,7 +394,7 @@ void P_CameraLineOpening(line_t *linedef)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
continue;
topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef);
+53 -41
View File
@@ -371,7 +371,7 @@ static boolean P_SetPrecipMobjState(precipmobj_t *mobj, statenum_t state)
//
boolean P_WeaponOrPanel(mobjtype_t type)
{
if (type >= MT_BOUNCERING && type <= MT_GRENADEPICKUP)
if (UNLIKELY(type >= MT_BOUNCERING && type <= MT_GRENADEPICKUP)) // doubt those get used at all in kart tbh
return true;
return false;
@@ -461,6 +461,7 @@ void P_ExplodeMissile(mobj_t *mo)
boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
return false;
@@ -891,7 +892,7 @@ static void P_PlayerFlip(mobj_t *mo)
G_GhostAddFlip((INT32) (mo->player - players));
// Flip aiming to match!
if (mo->player->pflags & PF_NIGHTSMODE) // NiGHTS doesn't use flipcam
if (UNLIKELY(mo->player->pflags & PF_NIGHTSMODE)) // NiGHTS doesn't use flipcam
{
if (mo->tracer)
mo->tracer->eflags ^= MFE_VERTICALFLIP;
@@ -989,7 +990,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
//|| (mo->player->charability == CA_FLY && (mo->player->powers[pw_tailsfly]
// || (mo->state >= &states[S_PLAY_SPC1] && mo->state <= &states[S_PLAY_SPC4]))))
// gravityadd = gravityadd/3; // less gravity while flying/gliding
if (mo->player->climbing || (mo->player->pflags & PF_NIGHTSMODE))
if (UNLIKELY(mo->player->climbing || (mo->player->pflags & PF_NIGHTSMODE)))
return 0;
if (!(mo->flags2 & MF2_OBJECTFLIP) != !(mo->player->powers[pw_gravityboots])) // negated to turn numeric into bool - would be double negated, but not needed if both would be
@@ -1607,7 +1608,7 @@ void P_XYMovement(mobj_t *mo)
// Check the gravity status.
P_CheckGravity(mo, false);
if (player && !moved && player->pflags & PF_NIGHTSMODE && mo->target)
if (UNLIKELY(player && !moved && player->pflags & PF_NIGHTSMODE && mo->target))
{
angle_t fa;
@@ -1652,7 +1653,7 @@ void P_XYMovement(mobj_t *mo)
if (player && player->homing) // no friction for homing
return;
if (player && player->pflags & PF_NIGHTSMODE)
if (UNLIKELY(player && player->pflags & PF_NIGHTSMODE))
return; // no friction for NiGHTS players
if ((mo->type == MT_BIGTUMBLEWEED || mo->type == MT_LITTLETUMBLEWEED)
@@ -1735,9 +1736,6 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
if (!(rover->flags & FF_EXISTS))
continue;
topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL);
bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL);
if (mo->player && P_CheckSolidLava(mo, rover)) // only the player should be affected
;
else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only
@@ -1747,6 +1745,10 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
else if (!((rover->flags & FF_BLOCKPLAYER && mo->player) // solid to players?
|| (rover->flags & FF_BLOCKOTHERS && !mo->player))) // solid to others?
continue;
topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL);
bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL);
if (rover->flags & FF_QUICKSAND)
{
switch (motype)
@@ -1770,6 +1772,7 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
delta1 = mo->z - (bottomheight + ((topheight - bottomheight)/2));
delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2));
if (topheight > mo->floorz && abs(delta1) < abs(delta2)
&& !(rover->flags & FF_REVERSEPLATFORM)
&& ((P_MobjFlip(mo)*mo->momz >= 0) || (!(rover->flags & FF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference)
@@ -1803,7 +1806,7 @@ static void P_AdjustMobjFloorZ_PolyObjs(mobj_t *mo, subsector_t *subsec)
thingtop = mo->z + mo->height;
while(po)
while (po)
{
if (!P_MobjInsidePolyobj(po, mo) || !(po->flags & POF_SOLID))
{
@@ -1855,6 +1858,7 @@ static void P_RingZMovement(mobj_t *mo)
mo->momz += mo->pmomz;
mo->eflags &= ~MFE_APPLYPMOMZ;
}
mo->z += mo->momz;
// clip movement
@@ -1925,6 +1929,7 @@ static boolean P_ZMovement(mobj_t *mo)
mo->momz += mo->pmomz;
mo->eflags &= ~MFE_APPLYPMOMZ;
}
mo->z += mo->momz;
if (mo->standingslope)
@@ -2209,7 +2214,7 @@ static boolean P_ZMovement(mobj_t *mo)
|| mo->type == MT_CANNONBALLDECOR
|| mo->type == MT_FALLINGROCK)
{
if (maptol & TOL_NIGHTS)
if (UNLIKELY(maptol & TOL_NIGHTS))
mom.z = -FixedDiv(mom.z, 10*FRACUNIT);
else
mom.z = -FixedMul(mom.z, FixedDiv(17*FRACUNIT,20*FRACUNIT));
@@ -2349,9 +2354,9 @@ static boolean P_ZMovement(mobj_t *mo)
mo->momz = -mo->momz;
else
// Flags bounce
if (mo->type == MT_REDFLAG || mo->type == MT_BLUEFLAG)
if (UNLIKELY(mo->type == MT_REDFLAG || mo->type == MT_BLUEFLAG))
{
if (maptol & TOL_NIGHTS)
if (UNLIKELY(maptol & TOL_NIGHTS))
mo->momz = -FixedDiv(mo->momz, 10*FRACUNIT);
else
mo->momz = -FixedMul(mo->momz, FixedDiv(17*FRACUNIT,20*FRACUNIT));
@@ -2418,7 +2423,7 @@ static void P_PlayerZMovement(mobj_t *mo)
else
mo->z = mo->floorz;
if (mo->player->pflags & PF_NIGHTSMODE)
if (UNLIKELY(mo->player->pflags & PF_NIGHTSMODE))
{
// bounce off floor if you were flying towards it
if ((mo->eflags & MFE_VERTICALFLIP && mo->player->flyangle > 0 && mo->player->flyangle < 180)
@@ -2608,7 +2613,7 @@ nightsdone:
else
mo->z = mo->ceilingz - mo->height;
if (mo->player->pflags & PF_NIGHTSMODE)
if (UNLIKELY(mo->player->pflags & PF_NIGHTSMODE))
{
// bounce off ceiling if you were flying towards it
if ((mo->eflags & MFE_VERTICALFLIP && mo->player->flyangle > 180 && mo->player->flyangle <= 359)
@@ -2653,7 +2658,7 @@ nightsdone:
}
// hit the ceiling
if (mariomode)
if (UNLIKELY(mariomode))
S_StartSound(mo, sfx_mario1);
if (!mo->player->climbing)
@@ -3114,8 +3119,6 @@ static boolean P_CameraCheckHeat(camera_t *thiscam)
if (!thiscam || !thiscam->subsector)
return false;
halfheight = thiscam->z + (thiscam->height >> 1);
// see if we are in water
sector = thiscam->subsector->sector;
@@ -3126,6 +3129,8 @@ static boolean P_CameraCheckHeat(camera_t *thiscam)
{
ffloor_t *rover;
halfheight = thiscam->z + (thiscam->height >> 1);
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS))
@@ -3152,8 +3157,6 @@ static boolean P_CameraCheckWater(camera_t *thiscam)
if (!thiscam || !thiscam->subsector)
return false;
halfheight = thiscam->z + (thiscam->height >> 1);
// see if we are in water
sector = thiscam->subsector->sector;
@@ -3161,6 +3164,8 @@ static boolean P_CameraCheckWater(camera_t *thiscam)
{
ffloor_t *rover;
halfheight = thiscam->z + (thiscam->height >> 1);
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS)
@@ -3489,15 +3494,18 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
}
else
{
if (!(mobj->player->pflags & PF_NIGHTSMODE)) // "jumping" is used for drilling
if (LIKELY(!(mobj->player->pflags & PF_NIGHTSMODE))) // "jumping" is used for drilling
mobj->player->jumping = 0;
mobj->player->pflags &= ~PF_JUMPED;
if (mobj->player->secondjump || mobj->player->powers[pw_tailsfly])
{
mobj->player->secondjump = 0;
mobj->player->powers[pw_tailsfly] = 0;
P_SetPlayerMobjState(mobj, S_KART_WALK1); // SRB2kart - was S_PLAY_RUN1
}
mobj->eflags &= ~MFE_JUSTHITFLOOR;
}
@@ -4185,7 +4193,7 @@ static void P_Boss3Thinker(mobj_t *mobj)
// Move Boss4's sectors by delta.
static boolean P_Boss4MoveCage(fixed_t delta)
{
const UINT16 tag = 65534;
static const UINT16 tag = 65534;
INT32 snum;
sector_t *sector;
for (snum = sectors[tag%numsectors].firsttag; snum != -1; snum = sector->nexttag)
@@ -4234,7 +4242,7 @@ static void P_Boss4PinchSpikeballs(mobj_t *mobj, angle_t angle, fixed_t fz)
// Destroy cage FOFs.
static void P_Boss4DestroyCage(void)
{
const UINT16 tag = 65534;
static const UINT16 tag = 65534;
INT32 snum, next;
size_t a;
sector_t *sector, *rsec;
@@ -5403,8 +5411,6 @@ static void P_GimmeAxisXYPos(mobj_t *closestaxis, degenmobj_t *mobj)
static void P_MoveHoop(mobj_t *mobj)
{
const fixed_t fuse = (mobj->fuse*mobj->extravalue2);
const angle_t fa = mobj->movedir*(FINEANGLES/mobj->extravalue1);
TVector v;
TVector *res;
fixed_t finalx, finaly, finalz;
@@ -5414,6 +5420,9 @@ static void P_MoveHoop(mobj_t *mobj)
if (!mobj->target) /// \todo DEBUG ME! Target was P_RemoveMobj'd at some point, and therefore no longer valid!
return;
const fixed_t fuse = (mobj->fuse*mobj->extravalue2);
const angle_t fa = mobj->movedir*(FINEANGLES/mobj->extravalue1);
x = mobj->target->x;
y = mobj->target->y;
z = mobj->target->z+mobj->target->height/2;
@@ -8967,7 +8976,7 @@ void P_MobjThinker(mobj_t *mobj)
I_Assert(mobj != NULL);
I_Assert(!P_MobjWasRemoved(mobj));
if (mobj->flags & MF_NOTHINK)
if (UNLIKELY(mobj->flags & MF_NOTHINK))
return;
// Remove dead target/tracer.
@@ -8986,11 +8995,12 @@ void P_MobjThinker(mobj_t *mobj)
tmfloorthing = tmhitthing = NULL;
const sector_t *sec1 = mobj->subsector ? mobj->subsector->sector : NULL;
// 970 allows ANY mobj to trigger a linedef exec
if (UNLIKELY(!mobj->islocal && sec1 && GETSECSPECIAL(sec1->special, 2) == 8)) // BEWARE: islocal does not exist in vanilla
{
sector_t *sec2;
sec2 = P_ThingOnSpecial3DFloor(mobj);
if (sec2 && GETSECSPECIAL(sec2->special, 2) == 1)
P_LinedefExecute(sec2->tag, mobj, sec2);
@@ -9054,7 +9064,7 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->flags2 & MF2_FIRING && mobj->target && mobj->health > 0)
P_FiringThink(mobj);
if (mobj->flags & MF_AMBIENT)
if (UNLIKELY(mobj->flags & MF_AMBIENT))
{
if (leveltime % mobj->health)
return;
@@ -9104,7 +9114,7 @@ void P_MobjThinker(mobj_t *mobj)
|| mobj->type == MT_FLINGEMERALD
|| mobj->type == MT_BIGTUMBLEWEED
|| mobj->type == MT_LITTLETUMBLEWEED
|| mobj->type == MT_CANNONBALLDECOR
|| mobj->type == MT_CANNONBALLDECOR)
|| mobj->type == MT_FALLINGROCK)
{
P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly
@@ -9195,6 +9205,9 @@ void P_PushableThinker(mobj_t *mobj)
I_Assert(mobj != NULL);
I_Assert(!P_MobjWasRemoved(mobj));
if (!mobj)
return;
sec = mobj->subsector->sector;
if (GETSECSPECIAL(sec->special, 2) == 1 && mobj->z == sec->floorheight)
@@ -9211,9 +9224,6 @@ void P_PushableThinker(mobj_t *mobj)
if (mobj->flags & MF_PUSHABLE && !(mobj->momx || mobj->momy))
P_TryMove(mobj, mobj->x, mobj->y, true);
if (!mobj)
return;
if (mobj->fuse == 1) // it would explode in the MobjThinker code
{
mobj_t *spawnmo;
@@ -9982,6 +9992,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
else
{
const INT32 special = GETSECSPECIAL(mobj->subsector->sector->special, 1);
if (special == 7 || special == 6 || mobj->subsector->sector->floorpic == skyflatnum)
mobj->precipflags |= PCF_PIT;
}
@@ -10313,9 +10324,11 @@ void P_PrecipitationEffects(void)
P_SpawnLightningFlash(ss); // Spawn a quick flash thinker
}
const mobj_t *pmo = players[displayplayers[0]].mo;
// Local effects from here on out!
// If we're not in game fully yet, we don't worry about them.
if (!playeringame[displayplayers[0]] || !players[displayplayers[0]].mo)
if (!playeringame[displayplayers[0]] || !pmo)
return;
if (sound_disabled)
@@ -10324,7 +10337,7 @@ void P_PrecipitationEffects(void)
if (!sounds_rain && !sounds_thunder)
return; // no need to calculate volume at ALL
if (players[displayplayers[0]].mo->subsector->sector->ceilingpic == skyflatnum)
if (pmo->subsector->sector->ceilingpic == skyflatnum)
volume = 255; // Sky above? We get it full blast.
else
{
@@ -10335,7 +10348,7 @@ void P_PrecipitationEffects(void)
// Essentially check in a 1024 unit radius of the player for an outdoor area.
#define RADIUSSTEP (64*FRACUNIT)
#define SEARCHRADIUS (16*RADIUSSTEP)
yl = yh = players[displayplayers[0]].mo->y;
yl = yh = pmo->y;
yl -= SEARCHRADIUS;
while (yl < INT32_MIN)
yl += RADIUSSTEP;
@@ -10343,7 +10356,7 @@ void P_PrecipitationEffects(void)
while (yh > INT32_MAX)
yh -= RADIUSSTEP;
xl = xh = players[displayplayers[0]].mo->x;
xl = xh = pmo->x;
xl -= SEARCHRADIUS;
while (xl < INT32_MIN)
xl += RADIUSSTEP;
@@ -10359,20 +10372,19 @@ void P_PrecipitationEffects(void)
if (R_PointInSubsectorFast((fixed_t)x, (fixed_t)y)->sector->ceilingpic != skyflatnum) // Found the outdoors!
continue;
newdist = S_CalculateSoundDistance(players[displayplayers[0]].mo->x, players[displayplayers[0]].mo->y, 0, (fixed_t)x, (fixed_t)y, 0);
newdist = S_CalculateSoundDistance(pmo->x, pmo->y, 0, (fixed_t)x, (fixed_t)y, 0);
if (newdist < closedist)
closedist = newdist;
}
volume = 255 - (closedist>>(FRACBITS+2));
volume = CLAMP(volume, 0, 255);
}
#undef RADIUSSTEP
volume = CLAMP(volume, 0, 255);
if (sounds_rain)
S_StartSoundAtVolume(players[displayplayers[0]].mo, sfx_rainin, volume);
S_StartSoundAtVolume(pmo, sfx_rainin, volume);
if (!sounds_thunder)
return;
@@ -10380,7 +10392,7 @@ void P_PrecipitationEffects(void)
if (effects_lightning && lightningStrike && volume)
{
// Large, close thunder sounds to go with our lightning.
S_StartSoundAtVolume(players[displayplayers[0]].mo, sfx_litng1 + M_RandomKey(4), volume);
S_StartSoundAtVolume(pmo, sfx_litng1 + M_RandomKey(4), volume);
}
else if (thunderchance < 20)
{
@@ -10388,7 +10400,7 @@ void P_PrecipitationEffects(void)
if (volume < 80)
volume = 80;
S_StartSoundAtVolume(players[displayplayers[0]].mo, sfx_athun1 + M_RandomKey(2), volume);
S_StartSoundAtVolume(pmo, sfx_athun1 + M_RandomKey(2), volume);
}
}
+21 -15
View File
@@ -34,6 +34,7 @@
#include "r_fps.h" // R_ResetViewInterpolation in level load
#include "s_sound.h"
#include "m_emotes.h"
#include "st_stuff.h"
#include "w_wad.h"
#include "z_zone.h"
@@ -411,7 +412,7 @@ static inline float P_SegLengthFloat(seg_t *seg)
dx = FIXED_TO_FLOAT(seg->v2->x - seg->v1->x);
dy = FIXED_TO_FLOAT(seg->v2->y - seg->v1->y);
return (float)hypot(dx, dy);
return hypotf(dx, dy);
}
#endif
@@ -2344,9 +2345,7 @@ static void P_RunLevelScript(const char *scriptname)
lumpnum_t lumpnum;
char newname[9];
strncpy(newname, scriptname, 8);
newname[8] = '\0';
strlcpy(newname, scriptname, sizeof(newname));
lumpnum = W_CheckNumForName(newname);
@@ -2572,6 +2571,7 @@ static void P_InitMinimapInfo(void)
lumpnum_t lumpnum;
fixed_t a;
fixed_t b;
node_t *bsp = &nodes[numnodes-1];
minimapinfo.minimap_pic = NULL;
@@ -3008,9 +3008,8 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
#ifdef HWRENDER // not win32 only 19990829 by Kin
if (rendermode == render_opengl)
{
HWR_FreeExtraSubsectors();
// Create plane polygons.
HWR_LoadLevel(reloadinggamestate);
HWR_LoadLevel();
}
#endif
@@ -3071,7 +3070,7 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
if (!fromnetsave) // uglier hack
{ // to make a newly loaded level start on the second frame.
INT32 buf = gametic % TICQUEUE;
INT32 buf = gametic % BACKUPTICS;
for (i = 0; i < MAXPLAYERS; i++)
{
@@ -3313,6 +3312,12 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
if (!mapsadded)
CONS_Printf(M_GetText("No maps added\n"));
#ifdef HWRENDER
// Free GPU textures before freeing patches.
if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED))
HWR_ClearAllTextures();
#endif
//
// search for sprite replacements
//
@@ -3323,7 +3328,7 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
// Reload it all anyway, just in case they
// added some textures but didn't insert a
// TEXTURES/etc. list.
//R_LoadTexturesPwad(wadnum);
R_LoadTexturesPwad(wadnum);
// everything from MultiSetupWadFile until ST_Start was here originally
@@ -3337,6 +3342,11 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
//
S_LoadMusicDefs(wadnum);
//
// look for emotes
//
M_LoadEmotes(wadnum);
// TODO: Experimental SPRTINFO support, test first
R_LoadSpriteInfoLumps(wadnum, wadfiles[wadnum]->numlumps);
@@ -3347,7 +3357,8 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
// Only exists to make sure there's no way to overwrite partadd_stage externally
// unless you really push yourself.
SINT8 P_PartialAddGetStage(void) {
SINT8 P_PartialAddGetStage(void)
{
return partadd_stage;
}
@@ -3381,13 +3392,8 @@ boolean P_MultiSetupWadFiles(boolean fullsetup)
if (partadd_stage == 1)
{
#ifdef HWRENDER
// Free GPU textures before freeing patches.
if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED))
HWR_ClearAllTextures();
#endif
// Reload all textures, unconditionally for better or worse.
R_LoadTextures();
//R_LoadTextures();
if (fullsetup)
++partadd_stage;
+1 -1
View File
@@ -68,7 +68,7 @@ void P_SetupLevelSky(INT32 skynum, boolean global);
boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate);
#ifdef HWRENDER
void HWR_LoadLevel(boolean reloadinggamestate);
void HWR_LoadLevel(void);
#endif
boolean P_AddWadFile(const char *wadfilename, boolean local);
+3 -3
View File
@@ -3913,7 +3913,7 @@ DoneSection2:
player->kartstuff[k_lapanimation] = 80;
if (player->pflags & PF_NIGHTSMODE)
if (UNLIKELY(player->pflags & PF_NIGHTSMODE))
player->drillmeter += 48*20;
if (netgame && player->laps >= (UINT8)cv_numlaps.value)
@@ -7103,7 +7103,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
return false;
// Allow this to affect pushable objects at some point?
if (thing->player && (!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) || thing->player->pflags & PF_NIGHTSMODE))
if (thing->player && (!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) || UNLIKELY(thing->player->pflags & PF_NIGHTSMODE)))
{
INT32 dist;
INT32 speed;
@@ -7134,7 +7134,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
// Written with bits and pieces of P_HomingAttack
if ((speed > 0) && (P_CheckSight(thing, tmpusher->source)))
{
if (!(thing->player->pflags & PF_NIGHTSMODE))
if (LIKELY(!(thing->player->pflags & PF_NIGHTSMODE)))
{
// only push wrt Z if health & 1 (mapthing has ambush flag)
if (tmpusher->source->health & 1)
+47 -27
View File
@@ -190,7 +190,7 @@ void Command_CountMobjs_f(void)
void P_InitThinkers(void)
{
thinkercap.prev = thinkercap.next = &thinkercap;
precipcap.prev = precipcap.next = &precipcap;
precipcap.prev = precipcap.next = &precipcap;
waypointcap = NULL;
}
@@ -461,6 +461,9 @@ static inline void P_RunThinkers(void)
}
}
// Controller rumble!
// this keeps track of a bunch of things
// and makes your controller rumble accordingly
static void P_DeviceRumbleTick(void)
{
UINT8 i;
@@ -472,27 +475,31 @@ static void P_DeviceRumbleTick(void)
for (i = 0; i <= splitscreen; i++)
{
UINT16 low = 0;
UINT16 high = 0;
if (!cv_usejoystick[i].value || !cv_rumble[i].value)
{
continue;
}
player_t *player = ((i == 0) ? &players[consoleplayer] : &players[displayplayers[i]]);
if (player->spectator || !player->mo)
{
continue;
}
if (camera[i].freecam)
{
continue;
}
if (player->exiting)
UINT16 low = 0, high = 0;
UINT16 lenght = 57; // in ms
const player_t *player = ((i == 0) ? &players[consoleplayer] : &players[displayplayers[i]]);
// allow lua to do some crap for spectators
if (player->spectator || !player->mo)
{
continue;
}
// reset the rumble if you exit or are ded lel
if (player->exiting ||
player->playerstate == PST_DEAD ||
player->kartstuff[k_respawn] > 1)
{
G_PlayerDeviceRumble(i, low, high, 0);
continue;
@@ -501,15 +508,17 @@ static void P_DeviceRumbleTick(void)
if (player->kartstuff[k_spinouttimer])
{
//low = high = FRACUNIT / 6;
low = high = FixedMul((FRACUNIT / 4), (FixedDiv(player->kartstuff[k_spinouttimer], (3*TICRATE / 2))));
low = high = FixedMul((FRACUNIT / 4), (FixedDiv(player->kartstuff[k_spinouttimer], (3*TICRATE / 2)))); // try do some some kinda fadeout
}
else if (player->kartstuff[k_sneakertimer] > (sneakertime-(TICRATE/2)))
{
low = high = FRACUNIT / 8;
}
else if ((player->kartstuff[k_offroad])
&& P_IsObjectOnGround(player->mo) && player->speed != 0)
&& player->speed != 0
&& P_IsObjectOnGround(player->mo))
{
// weaken this depending on if you got hyu or invinc
if (player->kartstuff[k_hyudorotimer])
{
high = FRACUNIT / 128;
@@ -524,7 +533,8 @@ static void P_DeviceRumbleTick(void)
}
}
else if ((player->kartstuff[k_bananadrag] > TICRATE)
&& P_IsObjectOnGround(player->mo) && player->speed != 0)
&& player->speed != 0
&& P_IsObjectOnGround(player->mo))
{
if (leveltime & 1) // this is actually funny lel
high = FRACUNIT / 64;
@@ -541,7 +551,7 @@ static void P_DeviceRumbleTick(void)
continue;
}
G_PlayerDeviceRumble(i, low, high, 57);
G_PlayerDeviceRumble(i, low, high, lenght);
}
}
@@ -556,7 +566,11 @@ void P_RunChaseCameras(void)
player_t *p = &players[displayplayers[i]];
camera_t *cam = &camera[i];
if (cv_verticallook[i].value && leveltime > starttime && p->mo && p->kartstuff[k_respawn] == 0 && p->kartstuff[k_throwdir] != 0)
if (cv_verticallook[i].value &&
leveltime > starttime
&& p->mo
&& p->kartstuff[k_respawn] == 0
&& p->kartstuff[k_throwdir] != 0)
{
if (p->speed < 6 * p->mo->scale && abs(cam->dpad_y_held) < 2*TICRATE)
cam->dpad_y_held += p->kartstuff[k_throwdir];
@@ -599,6 +613,11 @@ static void P_RunQuakes(void)
--quake.time;
}
// Reset our Sprite scales and offsets
// at the start of our tic
// this is just to make things simpler
// as we dont have to reset it ourselves after use
// done at the start so lua can still overwrite everything
static inline void P_ResetSpriteStuff(void)
{
thinker_t *th;
@@ -735,8 +754,10 @@ void P_Ticker(boolean run)
PS_START_TIMING(ps_playerthink_time);
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && !P_MobjWasRemoved(players[i].mo))
P_PlayerThink(&players[i]);
if (!playeringame[i] || P_MobjWasRemoved(players[i].mo))
continue;
P_PlayerThink(&players[i]);
}
PS_STOP_TIMING(ps_playerthink_time);
}
@@ -757,8 +778,10 @@ void P_Ticker(boolean run)
// Run any "after all the other thinkers" stuff
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && !P_MobjWasRemoved(players[i].mo))
P_PlayerAfterThink(&players[i]);
if (!playeringame[i] || P_MobjWasRemoved(players[i].mo))
continue;
P_PlayerAfterThink(&players[i]);
}
// Apply rumble to local players
@@ -837,12 +860,12 @@ void P_Ticker(boolean run)
if (demo.recording)
{
INT32 axis = JoyAxis(AXISLOOKBACK, 1);
G_WriteAllGhostTics();
if (cv_recordmultiplayerdemos.value)
{
const INT32 axis = JoyAxis(AXISLOOKBACK, 1);
if (demo.savemode == DSM_NOTSAVING || demo.savemode == DSM_WILLAUTOSAVE)
if (demo.savebutton && demo.savebutton + 3*TICRATE < leveltime && (InputDown(gc_lookback, 1) || (cv_usejoystick[0].value && axis > 0)))
demo.savemode = DSM_TITLEENTRY;
@@ -958,10 +981,7 @@ void P_PreTicker(INT32 frames)
// Run any "after all the other thinkers" stuff
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
if (P_MobjWasRemoved(players[i].mo))
if (!playeringame[i] || P_MobjWasRemoved(players[i].mo))
continue;
P_PlayerAfterThink(&players[i]);
+37 -35
View File
@@ -73,7 +73,7 @@ void P_Thrust(mobj_t *mo, angle_t angle, fixed_t move)
mo->momx += FixedMul(move, FINECOSINE(angle));
if (!(twodlevel || (mo->flags2 & MF2_TWOD)))
if (LIKELY(!(twodlevel || (mo->flags2 & MF2_TWOD))))
mo->momy += FixedMul(move, FINESINE(angle));
}
@@ -90,7 +90,7 @@ void P_InstaThrust(mobj_t *mo, angle_t angle, fixed_t move)
mo->momx = FixedMul(move, FINECOSINE(angle));
if (!(twodlevel || (mo->flags2 & MF2_TWOD)))
if (LIKELY(!(twodlevel || (mo->flags2 & MF2_TWOD))))
mo->momy = FixedMul(move,FINESINE(angle));
}
@@ -498,9 +498,9 @@ void P_PlayLivesJingle(player_t *player)
if (player && !P_IsLocalPlayer(player))
return;
if (use1upSound)
if (UNLIKELY(use1upSound))
S_StartSound(NULL, sfx_oneup);
else if (mariomode)
else if (UNLIKELY(mariomode))
S_StartSound(NULL, sfx_marioa);
else
{
@@ -528,7 +528,7 @@ void P_PlayRinglossSound(mobj_t *source, mobj_t *damager)
S_StartSound(NULL, sfx);
}
else
S_StartSound(source, (mariomode) ? sfx_mario8 : sfx_khurt1 + key);
S_StartSound(source, UNLIKELY(mariomode) ? sfx_mario8 : sfx_khurt1 + key);
}
else
S_StartSound(source, sfx_slip);
@@ -1287,13 +1287,14 @@ boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand
{
sector_t *sector = mo->subsector->sector;
fixed_t topheight, bottomheight;
fixed_t flipoffset = ((mo->eflags & MFE_VERTICALFLIP) ? (mo->height/2) : 0);
fixed_t flipoffset;
if (sector->ffloors)
{
ffloor_t *rover;
flipoffset = ((mo->eflags & MFE_VERTICALFLIP) ? (mo->height/2) : 0);
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS))
@@ -1682,6 +1683,7 @@ static void P_DoBubbleBreath(player_t *player)
bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_SMALLBUBBLE);
else if (P_RandomChance(3*FRACUNIT/256))
bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_MEDIUMBUBBLE);
if (bubble)
{
bubble->threshold = 42;
@@ -1689,8 +1691,8 @@ static void P_DoBubbleBreath(player_t *player)
P_SetScale(bubble, bubble->destscale);
}
if (player->pflags & PF_NIGHTSMODE) // NiGHTS Super doesn't spawn flight bubbles
return;
//if (player->pflags & PF_NIGHTSMODE) // NiGHTS Super doesn't spawn flight bubbles
//return;
}
//
@@ -2159,7 +2161,7 @@ static void P_MovePlayer(player_t *player)
}
// note: don't unset stasis here
if (!player->spectator && G_TagGametype())
if (UNLIKELY(!player->spectator && G_TagGametype()))
{
// If we have stasis already here, it's because it's forced on us
// by a linedef executor or what have you
@@ -2219,7 +2221,7 @@ static void P_MovePlayer(player_t *player)
player->lturn_max[leveltime%MAXPREDICTTICS] = player->rturn_max[leveltime%MAXPREDICTTICS] = 0;
}
if (leveltime >= starttime)
if (LIKELY(leveltime >= starttime))
{
// KART: Don't directly apply angleturn! It may have been either A) forged by a malicious client, or B) not be a smooth turn due to a player dropping frames.
// Instead, turn the player only up to the amount they're supposed to turn accounting for latency. Allow exactly 1 extra turn unit to try to keep old replays synced.
@@ -2258,7 +2260,7 @@ static void P_MovePlayer(player_t *player)
P_3dMovement(player);
}
if (maptol & TOL_2D)
if (UNLIKELY(maptol & TOL_2D)) // psure this doesent even work at all
runspd = FixedMul(runspd, 2*FRACUNIT/3);
/////////////////////////
@@ -2319,10 +2321,10 @@ static void P_MovePlayer(player_t *player)
// Drifting sound
// Start looping the sound now.
if (leveltime % 50 == 0 && onground && player->kartstuff[k_drift] != 0)
if (onground && leveltime % 50 == 0 && player->kartstuff[k_drift] != 0)
S_StartSound(player->mo, sfx_drift);
// Leveltime being 50 might take a while at times. We'll start it up once, isntantly.
else if (!S_SoundPlaying(player->mo, sfx_drift) && onground && player->kartstuff[k_drift] != 0)
else if (onground && !S_SoundPlaying(player->mo, sfx_drift) && player->kartstuff[k_drift] != 0)
S_StartSound(player->mo, sfx_drift);
// Ok, we'll stop now.
else if (player->kartstuff[k_drift] == 0 || !onground)
@@ -2347,7 +2349,7 @@ static void P_MovePlayer(player_t *player)
P_SetPlayerMobjState(player->mo, S_KART_STND1); // SRB2kart - was S_PLAY_STND
}
if (player->gotflag) // If you can't glide, then why the heck would you be gliding?
if (UNLIKELY(player->gotflag)) // If you can't glide, then why the heck would you be gliding?
{
player->pflags &= ~PF_GLIDING;
player->glidetime = 0;
@@ -2708,8 +2710,8 @@ boolean P_LookForEnemies(player_t *player)
player->mo->z-mo->z) > FixedMul(RING_DIST, player->mo->scale))
continue; // out of range
if ((twodlevel || player->mo->flags2 & MF2_TWOD)
&& abs(player->mo->y-mo->y) > player->mo->radius)
if (UNLIKELY((twodlevel || player->mo->flags2 & MF2_TWOD)
&& abs(player->mo->y-mo->y) > player->mo->radius))
continue; // not in your 2d plane
if (mo->type == MT_PLAYER) // Don't chase after other players!
@@ -3514,7 +3516,7 @@ static boolean P_CheckNoclipCameraPosition(player_t *player, camera_t *thiscam,
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
continue;
topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
@@ -3579,7 +3581,7 @@ static boolean P_CheckNoclipCameraPosition(player_t *player, camera_t *thiscam,
// We're inside it! Yess...
polysec = po->lines[0]->backsector;
if (GETSECSPECIAL(polysec->special, 4) == 12)
if (UNLIKELY(GETSECSPECIAL(polysec->special, 4) == 12))
{ // Camera noclip polyobj.
plink = (polymaplink_t *)(plink->link.next);
continue;
@@ -3635,7 +3637,7 @@ static boolean P_CheckNoclipCameraPosition(player_t *player, camera_t *thiscam,
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if ((rover->flags & FF_BLOCKOTHERS) && (rover->flags & FF_RENDERALL) && (rover->flags & FF_EXISTS) && GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
if (UNLIKELY((rover->flags & FF_BLOCKOTHERS) && (rover->flags & FF_RENDERALL) && (rover->flags & FF_EXISTS) && GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
{
topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
@@ -4081,7 +4083,7 @@ boolean P_SpectatorJoinGame(player_t *player)
// Team changing in Team Match and CTF
// Pressing fire assigns you to a team that needs players if allowed.
// Partial code reproduction from p_tick.c autobalance code.
else if (G_GametypeHasTeams())
else if (UNLIKELY(G_GametypeHasTeams()))
{
INT32 changeto = 0;
INT32 z, numplayersred = 0, numplayersblue = 0;
@@ -4323,10 +4325,10 @@ static INT32 Quaketilt(player_t *player)
if (abs(delta) > ANGLE_90)
delta = (INT32)(( moma + ANGLE_180 ) - player->mo->angle );
const boolean sliptiding = player->kartstuff[k_drift] ? 0 : player->kartstuff[k_aizdriftstrat];
if (P_IsObjectOnGround(player->mo))
{
const boolean sliptiding = player->kartstuff[k_drift] ? 0 : player->kartstuff[k_aizdriftstrat];
if (sliptiding)
{
tilt = ANGLE_45;
@@ -4479,8 +4481,8 @@ void P_PlayerThink(player_t *player)
{
seenplayer = NULL;
if (cv_seenames.value && cv_allowseenames.value &&
!(G_TagGametype() && (player->pflags & PF_TAGIT)))
if (UNLIKELY(cv_seenames.value && cv_allowseenames.value &&
!(G_TagGametype() && (player->pflags & PF_TAGIT))))
{
mobj_t *mo = P_SpawnNameFinder(player->mo, MT_NAMECHECK);
@@ -4769,8 +4771,8 @@ void P_PlayerThink(player_t *player)
}
// Even if not NiGHTS, pull in nearby objects when walking around as John Q. Elliot.
if (!objectplacing && !((netgame || multiplayer) && player->spectator)
&& maptol & TOL_NIGHTS && (!(player->pflags & PF_NIGHTSMODE) || player->powers[pw_nights_helper]))
if (UNLIKELY(!objectplacing && !((netgame || multiplayer) && player->spectator)
&& maptol & TOL_NIGHTS && (!(player->pflags & PF_NIGHTSMODE) || player->powers[pw_nights_helper])))
{
thinker_t *th;
mobj_t *mo2;
@@ -4835,7 +4837,7 @@ void P_PlayerThink(player_t *player)
player->pflags &= ~PF_FULLSTASIS;
if (player->onconveyor == 1)
player->cmomy = player->cmomx = 0;
player->cmomy = player->cmomx = 0;
P_DoBubbleBreath(player); // Spawn Sonic's bubbles
P_CheckInvincibilityTimer(player); // Spawn Invincibility Sparkles
@@ -4872,7 +4874,7 @@ void P_PlayerThink(player_t *player)
#endif
// check for use
if (!(player->pflags & PF_NIGHTSMODE))
if (LIKELY(!(player->pflags & PF_NIGHTSMODE)))
{
if (cmd->buttons & BT_BRAKE)
player->pflags |= PF_USEDOWN;
@@ -5044,6 +5046,11 @@ void P_PlayerAfterThink(player_t *player)
P_PlayerInSpecialSector(player);
#endif
if (player->playerstate == PST_DEAD)
{
return;
}
for (i = 0; i <= splitscreen; i++)
{
if (player == &players[displayplayers[i]])
@@ -5053,12 +5060,7 @@ void P_PlayerAfterThink(player_t *player)
}
}
if (player->playerstate == PST_DEAD)
{
return;
}
if (player->pflags & PF_NIGHTSMODE)
if (UNLIKELY(player->pflags & PF_NIGHTSMODE))
{
player->powers[pw_gravityboots] = 0;
}
+243 -152
View File
@@ -235,6 +235,7 @@ UINT32 ASTBlendTexturePixel(RGBA_t background, RGBA_t foreground, int style, UIN
// Painfully simple texture id cacheing to make maps load faster. :3
static struct {
char name[9];
UINT32 hash;
INT32 id;
} *tidcache = NULL;
static INT32 tidcachelen = 0;
@@ -484,9 +485,7 @@ UINT8 *R_GetColumn(fixed_t tex, INT32 col)
// Odd width texture, cannot just mask.
// Sometime gets colnum = -1 or = width, even without tiling.
// Test LostCiv, Map 20, crates.
col = ( col < 0 ) ?
texwidth - (((-col - 1) % texwidth) + 1)
: col % texwidth;
col = ((col % texwidth) + texwidth) % texwidth;
}
if (!data)
@@ -522,32 +521,151 @@ void R_FlushTextureCache(void)
int R_CountTexturesInTEXTURESLump(UINT16 wadNum, UINT16 lumpNum);
void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *index);
//
// R_LoadTextures
// Initializes the texture list with the textures from the world map.
//
#define TX_START "TX_START"
#define TX_END "TX_END"
void R_LoadTextures(void)
static INT32
Rloadtextures (INT32 i, INT32 w)
{
INT32 i, k, w;
UINT16 j;
INT32 k;
UINT16 texstart, texend, texturesLumpPos;
softwarepatch_t *patchlump;
texpatch_t *patch;
texture_t *texture;
// Free previous memory before numtextures change.
if (numtextures)
// Get the lump numbers for the markers in the WAD, if they exist.
if (W_FileHasFolders(wadfiles[w]))
{
for (i = 0; i < numtextures; i++)
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
while (texturesLumpPos != INT16_MAX)
{
Z_Free(textures[i]);
Z_Free(texturecache[i]);
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
}
Z_Free(texturetranslation);
Z_Free(textures);
}
else
{
texstart = W_CheckNumForMarkerStartPwad(TX_START, (UINT16)w, 0);
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
if (texturesLumpPos != INT16_MAX)
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
}
if (texstart == INT16_MAX || texend == INT16_MAX)
return i;
// Work through each lump between the markers in the WAD.
for (j = 0; j < (texend - texstart); j++)
{
UINT16 wadnum = (UINT16)w;
lumpnum_t lumpnum = texstart + j;
if (W_FileHasFolders(wadfiles[w]))
{
if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder
continue; // If it is then SKIP IT
}
patchlump = (softwarepatch_t *)W_CacheLumpNumPwad(wadnum, lumpnum, PU_STATIC);
//CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((wadnum, lumpnum), patchlump->width, patchlump->height);
texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL);
// Set texture properties.
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
texture->hash = quickncasehash(texture->name, 8);
texture->width = SHORT(patchlump->width);
texture->height = SHORT(patchlump->height);
texture->type = TEXTURETYPE_SINGLEPATCH;
texture->patchcount = 1;
texture->holes = false;
// Allocate information for the texture's patches.
patch = &texture->patches[0];
patch->originx = patch->originy = 0;
patch->wad = wadnum;
patch->lump = texstart + j;
Z_Free(patchlump);
// determine width power of 2
#if 1
// [WDJ] only need to determine if exact power of 2.
k = 1;
while (k < texture->width)
k<<=1;
#else
// Largest power of 2 that fits within width.
k = 1;
while (k << 1 <= texture->width)
k <<= 1;
#endif
if (k != texture->width)
{
// Odd width
k = 1; // make texturewidthmask = 0
}
texturewidthmask[i] = k - 1;
textureheight[i] = texture->height << FRACBITS;
i++;
}
return i;
}
static INT32
count_range
( const char * marker_start,
const char * marker_end,
const char * folder,
UINT16 wadnum)
{
UINT16 j;
UINT16 texstart, texend;
INT32 count = 0;
// Count flats
if (W_FileHasFolders(wadfiles[wadnum]))
{
texstart = W_CheckNumForFolderStartPK3(folder, wadnum, 0);
texend = W_CheckNumForFolderEndPK3(folder, wadnum, texstart);
}
else
{
texstart = W_CheckNumForMarkerStartPwad(marker_start, wadnum, 0);
texend = W_CheckNumForNamePwad(marker_end, wadnum, texstart);
}
if (texstart != INT16_MAX && texend != INT16_MAX)
{
// PK3s have subfolders, so we can't just make a simple sum
if (W_FileHasFolders(wadfiles[wadnum]))
{
for (j = texstart; j < texend; j++)
{
if (!W_IsLumpFolder(wadnum, j)) // Check if lump is a folder; if not, then count it
count++;
}
}
else // Add all the textures between markers
{
count += (texend - texstart);
}
}
return count;
}
static INT32 R_CountTextures(UINT16 wadnum)
{
UINT16 texturesLumpPos;
INT32 count = 0;
// Load patches and textures.
@@ -556,159 +674,127 @@ void R_LoadTextures(void)
// the markers.
// This system will allocate memory for all duplicate/patched textures even if it never uses them,
// but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures.
for (w = 0, numtextures = 0; w < numwadfiles; w++)
// Count the textures from TEXTURES lumps
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", wadnum, 0);
while (texturesLumpPos != INT16_MAX)
{
if (W_FileHasFolders(wadfiles[w]))
{
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
}
else
{
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
}
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
while (texturesLumpPos != INT16_MAX)
{
numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos);
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
}
// Add all the textures between TX_START and TX_END
if (texstart == INT16_MAX || texend == INT16_MAX)
continue;
// PK3s have subfolders, so we can't just make a simple sum
if (W_FileHasFolders(wadfiles[w]))
{
for (j = texstart; j < texend; j++)
{
if (W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it
continue;
numtextures++;
}
}
else
{
numtextures += (UINT32)(texend - texstart);
}
count += R_CountTexturesInTEXTURESLump(wadnum, texturesLumpPos);
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", wadnum, texturesLumpPos + 1);
}
// If no textures found by this point, bomb out
if (!numtextures)
I_Error("No textures detected in any WADs!\n");
// Count single-patch textures
count += count_range(TX_START, TX_END, "textures/", wadnum);
return count;
}
static void
recallocuser
( void * user,
size_t old,
size_t new)
{
char *p = Z_Realloc(*(void**)user,
new, PU_STATIC, user);
if (new > old)
memset(&p[old], 0, (new - old));
}
static void R_AllocateTextures(INT32 add)
{
const INT32 newtextures = (numtextures + add);
const size_t newsize = newtextures * sizeof (void*);
const size_t oldsize = numtextures * sizeof (void*);
INT32 i;
// Allocate memory and initialize to 0 for all the textures we are initialising.
// There are actually 5 buffers allocated in one for convenience.
textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL);
recallocuser(&textures, oldsize, newsize);
// Allocate texture column offset table.
texturecolumnofs = (void *)((UINT8 *)textures + (numtextures * sizeof(void *)));
recallocuser(&texturecolumnofs, oldsize, newsize);
// Allocate texture referencing cache.
texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2));
// Allocate texture width mask table.
texturewidthmask = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 3));
// Allocate texture height mask table.
textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4));
recallocuser(&texturecache, oldsize, newsize);
// Allocate texture width table.
recallocuser(&texturewidthmask, oldsize, newsize);
// Allocate texture height table.
recallocuser(&textureheight, oldsize, newsize);
// Create translation table for global animation.
texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, NULL);
Z_Realloc(texturetranslation, (newtextures + 1) * sizeof(*texturetranslation), PU_STATIC, &texturetranslation);
for (i = 0; i < numtextures; i++)
texturetranslation[i] = i;
for (i = 0, w = 0; w < numwadfiles; w++)
for (i = 0; i < numtextures; ++i)
{
// Get the lump numbers for the markers in the WAD, if they exist.
if (W_FileHasFolders(wadfiles[w]))
{
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
while (texturesLumpPos != INT16_MAX)
{
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
}
}
else
{
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
if (texturesLumpPos != INT16_MAX)
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
}
if (texstart == INT16_MAX || texend == INT16_MAX)
continue;
// Work through each lump between the markers in the WAD.
for (j = 0; j < (texend - texstart); j++)
{
UINT16 wadnum = (UINT16)w;
lumpnum_t lumpnum = texstart + j;
if (W_FileHasFolders(wadfiles[w]))
{
if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder
continue; // If it is then SKIP IT
}
patchlump = (softwarepatch_t *)W_CacheLumpNumPwad(wadnum, lumpnum, PU_STATIC);
//CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad(wadnum, lumpnum), patchlump->width, patchlump->height);
texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL);
// Set texture properties.
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
texture->width = SHORT(patchlump->width);
texture->height = SHORT(patchlump->height);
texture->type = TEXTURETYPE_SINGLEPATCH;
texture->patchcount = 1;
texture->holes = false;
// Allocate information for the texture's patches.
patch = &texture->patches[0];
patch->originx = patch->originy = 0;
patch->wad = wadnum;
patch->lump = texstart + j;
Z_Free(patchlump);
// determine width power of 2
#if 1
// [WDJ] only need to determine if exact power of 2.
k = 1;
while (k < texture->width)
k<<=1;
#else
// Largest power of 2 that fits within width.
k = 1;
while (k << 1 <= texture->width)
k <<= 1;
#endif
if (k != texture->width)
{
// Odd width
k = 1; // make texturewidthmask = 0
}
texturewidthmask[i] = k - 1;
textureheight[i] = texture->height << FRACBITS;
i++;
}
// R_FlushTextureCache relies on the user for
// Z_Free, texturecache has been reallocated so the
// user is now garbage memory.
Z_SetUser(texturecache[i], (void**)&texturecache[i]);
}
while (i < newtextures)
{
texturetranslation[i] = i;
i++;
}
}
static INT32 R_DefineTextures(INT32 i, UINT16 w)
{
return Rloadtextures(i, w);
}
static void R_FinishLoadingTextures(INT32 add)
{
numtextures += add;
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_LoadMapTextures(numtextures);
#endif
}
//
// R_LoadTextures
// Initializes the texture list with the textures from the world map.
//
void R_LoadTextures(void)
{
INT32 i, w;
INT32 newtextures = 0;
for (w = 0; w < numwadfiles; w++)
{
newtextures += R_CountTextures((UINT16)w);
}
// If no textures found by this point, bomb out
if (!newtextures)
I_Error("No textures detected in any WADs!\n");
R_AllocateTextures(newtextures);
for (i = 0, w = 0; w < numwadfiles; w++)
{
i = R_DefineTextures(i, w);
}
R_FinishLoadingTextures(i);
}
void R_LoadTexturesPwad(UINT16 wadnum)
{
INT32 newtextures = R_CountTextures(wadnum);
if (!newtextures)
return;
R_AllocateTextures(newtextures);
newtextures = R_DefineTextures(numtextures, wadnum) - numtextures;
R_FinishLoadingTextures(newtextures);
}
static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch)
{
char *texturesToken;
@@ -960,6 +1046,7 @@ static texture_t *R_ParseTexture(boolean actuallyLoadTexture)
// Allocate memory for a zero-patch texture. Obviously, we'll be adding patches momentarily.
resultTexture = (texture_t *)Z_Calloc(sizeof(texture_t), PU_STATIC, NULL);
M_Memcpy(resultTexture->name, newTextureName, 8);
resultTexture->hash = quickncasehash(newTextureName, 8);
resultTexture->width = newTextureWidth;
resultTexture->height = newTextureHeight;
resultTexture->type = TEXTURETYPE_COMPOSITE;
@@ -1743,19 +1830,22 @@ void R_ClearTextureNumCache(boolean btell)
INT32 R_CheckTextureNumForName(const char *name)
{
INT32 i;
UINT32 hash;
// "NoTexture" marker.
if (name[0] == '-')
return 0;
hash = quickncasehash(name, 8);
for (i = 0; i < tidcachelen; i++)
if (!strncasecmp(tidcache[i].name, name, 8))
if (tidcache[i].hash == hash && !strncasecmp(tidcache[i].name, name, 8))
return tidcache[i].id;
// Need to parse the list backwards, so textures loaded more recently are used in lieu of ones loaded earlier
//for (i = 0; i < numtextures; i++) <- old
for (i = (numtextures - 1); i >= 0; i--) // <- new
if (!strncasecmp(textures[i]->name, name, 8))
if (textures[i]->hash == hash && !strncasecmp(textures[i]->name, name, 8))
{
tidcachelen++;
Z_Realloc(tidcache, tidcachelen * sizeof(*tidcache), PU_STATIC, &tidcache);
@@ -1764,6 +1854,7 @@ INT32 R_CheckTextureNumForName(const char *name)
#ifndef ZDEBUG
CONS_Debug(DBG_SETUP, "texture #%s: %s\n", sizeu1(tidcachelen), tidcache[tidcachelen-1].name);
#endif
tidcache[tidcachelen-1].hash = hash;
tidcache[tidcachelen-1].id = i;
return i;
}
+2
View File
@@ -53,6 +53,7 @@ typedef struct
// Keep name for switch changing, etc.
char name[8];
UINT8 type; // TEXTURETYPE_
UINT32 hash;
INT16 width, height;
boolean holes;
// All the patches[patchcount] are drawn back to front into the cached texture.
@@ -76,6 +77,7 @@ extern CV_PossibleValue_t Color_cons_t[];
// Load TEXTURE1/TEXTURE2/PNAMES definitions, create lookup tables
void R_LoadTextures(void);
void R_LoadTexturesPwad(UINT16 wadnum);
void R_FlushTextureCache(void);
UINT8 *R_GenerateTexture(size_t texnum);
+4
View File
@@ -151,6 +151,7 @@ static CV_PossibleValue_t fov_cons_t[] = {{MINFOV*FRACUNIT, "MIN"}, {MAXFOV*FRAC
static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}}; // lmao rendering 32 portals, you're a card
static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}};
static CV_PossibleValue_t secbright_cons_t[] = {{0, "MIN"}, {255, "MAX"}, {0, NULL}};
static void R_SetFov(fixed_t playerfov);
@@ -201,6 +202,8 @@ consvar_t cv_ripplewater = {"waterripples", "On", CV_SAVE, CV_OnOff, NULL, 0
// Okay, whoever said homremoval causes a performance hit should be shot.
consvar_t cv_homremoval = {"homremoval", "Yes", CV_SAVE, homremoval_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_secbright = {"r_secbright", "0", CV_SAVE, secbright_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_maxportals = {"maxportals", "2", CV_SAVE, maxportals_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// cap fov, fov too high tears software apart.
@@ -1558,6 +1561,7 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_skybox);
CV_RegisterVar(&cv_ffloorclip);
CV_RegisterVar(&cv_spriteclip);
CV_RegisterVar(&cv_secbright);
CV_RegisterVar(&cv_softcyancut);
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
+6
View File
@@ -197,9 +197,15 @@ extern consvar_t cv_tailspickup;
extern consvar_t cv_maxinterpdist;
extern consvar_t cv_playerfade;
extern consvar_t cv_ripplewater;
extern consvar_t cv_secbright;
extern consvar_t cv_randomdirlight;
static inline INT32 R_GetSoftLightlevel(INT32 llevel)
{
return CLAMP(llevel, cv_secbright.value, 255) >> LIGHTSEGSHIFT;
}
// Called by startup code.
void R_Init(void);
+7 -5
View File
@@ -1059,7 +1059,7 @@ void R_DrawSinglePlane(drawspandata_t* ds, visplane_t *pl, boolean allow_paralle
#else
if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2))
#endif
light = (pl->lightlevel >> LIGHTSEGSHIFT);
light = R_GetSoftLightlevel(pl->lightlevel);
else
light = LIGHTLEVELS-1;
}
@@ -1111,16 +1111,17 @@ void R_DrawSinglePlane(drawspandata_t* ds, visplane_t *pl, boolean allow_paralle
#else
if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2))
#endif
light = (pl->lightlevel >> LIGHTSEGSHIFT);
light = R_GetSoftLightlevel(pl->lightlevel);
else
light = LIGHTLEVELS-1;
}
else if (pl->ffloor->flags & FF_FOG)
{
spanfunctype = SPANDRAWFUNC_FOG;
light = (pl->lightlevel >> LIGHTSEGSHIFT);
light = R_GetSoftLightlevel(pl->lightlevel);
}
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
else
light = R_GetSoftLightlevel(pl->lightlevel);
if (pl->ffloor->flags & FF_RIPPLE && cv_ripplewater.value)
{
@@ -1172,7 +1173,8 @@ void R_DrawSinglePlane(drawspandata_t* ds, visplane_t *pl, boolean allow_paralle
}
}
}
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
else
light = R_GetSoftLightlevel(pl->lightlevel);
}
ds->currentplane = pl;
+10 -11
View File
@@ -209,11 +209,11 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
rlight->flags = static_cast<ffloortype_e>(light->flags);
if (rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog))
lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
lightnum = R_GetSoftLightlevel(rlight->lightlevel);
else if (R_CheckColumnFunc(COLDRAWFUNC_FUZZY))
lightnum = LIGHTLEVELS - 1;
else
lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
lightnum = R_GetSoftLightlevel(rlight->lightlevel);
if (rlight->extra_colormap && rlight->extra_colormap->fog)
;
@@ -227,7 +227,7 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
{
if ((R_CheckColumnFunc(COLDRAWFUNC_FUZZY) == false)
|| (frontsector->extra_colormap && frontsector->extra_colormap->fog))
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
lightnum = R_GetSoftLightlevel(frontsector->lightlevel);
else
lightnum = LIGHTLEVELS - 1;
@@ -764,9 +764,9 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
// Check if the current light effects the colormap/lightlevel
if (pfloor->flags & FF_FOG)
rlight->lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
rlight->lightnum = R_GetSoftLightlevel(pfloor->master->frontsector->lightlevel);
else
rlight->lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
rlight->lightnum = R_GetSoftLightlevel(rlight->lightlevel);
if (pfloor->flags & FF_FOG || rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog))
;
@@ -782,14 +782,13 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
{
// Get correct light level!
if ((frontsector->extra_colormap && frontsector->extra_colormap->fog))
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
lightnum = R_GetSoftLightlevel(frontsector->lightlevel);
else if (fog)
lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
lightnum = R_GetSoftLightlevel(pfloor->master->frontsector->lightlevel);
else if (fuzzy)
lightnum = LIGHTLEVELS-1;
else
lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false)
->lightlevel >> LIGHTSEGSHIFT;
lightnum = R_GetSoftLightlevel(R_FakeFlat(frontsector, &tempsec, &templight, &templight, false)->lightlevel);
if (pfloor->flags & FF_FOG || (frontsector->extra_colormap && frontsector->extra_colormap->fog))
;
@@ -1385,7 +1384,7 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
for (i = 0; i < dc->numlights; i++)
{
INT32 lightnum;
lightnum = (dc->lightlist[i].lightlevel >> LIGHTSEGSHIFT);
lightnum = R_GetSoftLightlevel(dc->lightlist[i].lightlevel);
if (dc->lightlist[i].extra_colormap)
;
@@ -2443,7 +2442,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// use different light tables
// for horizontal / vertical / diagonal
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
lightnum = R_GetSoftLightlevel(frontsector->lightlevel);
if (P_ApplyLightOffset(lightnum, frontsector))
lightnum += curline->lightOffset;
+3 -3
View File
@@ -1061,7 +1061,7 @@ static void R_SplitSprite(vissprite_t *sprite)
if (!(sector->lightlist[i].caster->flags & FF_NOSHADE))
{
INT32 lightnum = (*sector->lightlist[i].lightlevel >> LIGHTSEGSHIFT);
INT32 lightnum = R_GetSoftLightlevel(*sector->lightlist[i].lightlevel);
if (lightnum < 0)
spritelights = scalelight[0];
@@ -1660,7 +1660,7 @@ static void R_ProjectSprite(mobj_t *thing)
lightnum = thing->subsector->sector->lightlevel;
}
lightnum = (lightnum + R_ThingLightLevel(thing)) >> LIGHTSEGSHIFT;
lightnum = R_GetSoftLightlevel(lightnum + R_ThingLightLevel(thing));
if (maplighting.directional && P_SectorUsesDirectionalLighting(thing->subsector->sector))
{
@@ -2057,7 +2057,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
{
if (sec->heightsec == -1) lightlevel = sec->lightlevel;
lightnum = (lightlevel >> LIGHTSEGSHIFT);
lightnum = R_GetSoftLightlevel(lightlevel);
if (lightnum < 0)
spritelights = scalelight[0];
+80 -68
View File
@@ -34,7 +34,7 @@
#include "lua_hook.h" // MusicChange hook
#include "lua_hud.h" // LUA_HudEnabled(hud_musiccredit)
static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo);
static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, sfxinfo_t *sfxinfo);
static void SetChannelsNum(void);
static void Command_Tunes_f(void);
static void Command_RestartAudio_f(void);
@@ -59,10 +59,12 @@ static void AmigaType_OnChange(void);
#endif
#endif
#if defined(HAVE_SDL) && SOUND==SOUND_SDL
consvar_t cv_samplerate = {"samplerate", "44100", 0, CV_Unsigned, NULL, 22050, NULL, NULL, 0, 0, NULL}; //Alam: For easy hacking?
#endif
static CV_PossibleValue_t audbuffersize_cons_t[] = {{256, "256"}, {512, "512"}, {1024, "1024"}, {2048, "2048"}, {4096, "4096"}, {0, NULL}};
consvar_t cv_audbuffersize = {"buffersize", "2048", CV_SAVE, audbuffersize_cons_t, BufferSize_OnChange, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t audbuffersize_cons_t[] = {{128, "128"}, {256, "256"}, {512, "512"}, {1024, "1024"}, {2048, "2048"}, {4096, "4096"}, {0, NULL}};
consvar_t cv_audbuffersize = {"audiobuffersize", "2048", CV_SAVE, audbuffersize_cons_t, BufferSize_OnChange, 0, NULL, NULL, 0, 0, NULL};
// stereo reverse
consvar_t stereoreverse = {"stereoreverse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -79,7 +81,11 @@ consvar_t cv_midimusicvolume = {"midimusicvolume", "18", CV_SAVE, soundvolume_co
#endif
// number of channels available
consvar_t cv_numChannels = {"snd_channels", "64", CV_SAVE|CV_CALL, CV_Unsigned, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t numChannels_cons_t[] = {{0, "MIN"}, {255, "MAX"}, {0, NULL}};
consvar_t cv_numChannels = {"snd_channels", "64", CV_SAVE|CV_CALL, numChannels_cons_t, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t samesoundlimit_cons_t[] = {{0, "MIN"}, {64, "MAX"}, {0, NULL}};
consvar_t cv_samesoundlimit = {"samesoundlimit", "0", CV_SAVE, samesoundlimit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
//consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE|CV_NOSHOWHELP, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -274,7 +280,9 @@ void S_RegisterSoundStuff(void)
CV_RegisterVar(&stereoreverse);
CV_RegisterVar(&precachesound);
#if defined(HAVE_SDL) && SOUND==SOUND_SDL
CV_RegisterVar(&cv_samplerate);
#endif
//CV_RegisterVar(&cv_resetmusic);
CV_RegisterVar(&cv_gamesounds);
CV_RegisterVar(&cv_gamedigimusic);
@@ -282,6 +290,8 @@ void S_RegisterSoundStuff(void)
CV_RegisterVar(&cv_gamemidimusic);
#endif
CV_RegisterVar(&cv_samesoundlimit);
// bird music stuff
CV_RegisterVar(&cv_playmusicifunfocused);
CV_RegisterVar(&cv_playsoundifunfocused);
@@ -324,9 +334,6 @@ static void SetChannelsNum(void)
Z_Free(channels);
channels = NULL;
if (cv_numChannels.value == 999999999) //Alam_GBC: OH MY ROD!(ROD rimmiced with GOD!)
CV_StealthSet(&cv_numChannels,cv_numChannels.defaultvalue);
if (cv_numChannels.value)
channels = (channel_t *)Z_Calloc(cv_numChannels.value * sizeof (channel_t), PU_STATIC, NULL);
numofchannels = (channels ? cv_numChannels.value : 0);
@@ -427,6 +434,25 @@ static INT32 S_ScaleVolumeWithSplitscreen(INT32 volume)
return FixedDiv(volume * FRACUNIT, root) / FRACUNIT;
}
static boolean S_CheckSameSoundLimit(sfxenum_t sfx_id)
{
INT32 cnum, scount = 0;
if (!cv_samesoundlimit.value)
return true;
for (cnum = 0; cnum < numofchannels; cnum++)
if ((size_t)(channels[cnum].sfxinfo - S_sfx) == (size_t)sfx_id)
scount++;
//CONS_Printf("same sound count: %d for sfx: %d\n", scount, sfx_id);
if (scount >= cv_samesoundlimit.value)
return false;
return true;
}
void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
{
const mobj_t *origin = (const mobj_t *)origin_p;
@@ -434,7 +460,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
INT32 initial_volume;
sfxinfo_t *sfx;
INT32 sep, pitch, priority, cnum;
INT32 sep, cnum;
boolean anyListeners = false;
boolean itsUs = false;
INT32 i;
@@ -449,13 +475,16 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
if (sfx_id == sfx_None)
return;
initial_volume = (origin ? S_ScaleVolumeWithSplitscreen(volume) : volume);
// reached same sound limit?
if (!S_CheckSameSoundLimit(sfx_id))
return;
memset(listener, 0, sizeof(listener));
for (i = 0; i <= splitscreen; i++)
{
player_t *player = &players[displayplayers[i]];
memset(&listener[i], 0, sizeof (listener[i]));
listenmobj[i] = NULL;
if (player->awayviewtics)
@@ -471,11 +500,6 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
{
itsUs = true;
}
}
for (i = 0; i <= splitscreen; i++)
{
player_t *player = &players[displayplayers[i]];
if (camera[i].chase && !player->awayviewtics)
{
@@ -514,9 +538,9 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
sfx = &S_sfx[sfx_id];
}
initial_volume = (origin ? S_ScaleVolumeWithSplitscreen(volume) : volume);
// Initialize sound parameters
pitch = NORM_PITCH;
priority = NORM_PRIORITY;
sep = NORM_SEP;
i = 0; // sensible default
@@ -554,7 +578,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
if (listenmobj[i])
{
audible = S_AdjustSoundParams(listenmobj[i], origin, &volume, &sep, &pitch, sfx);
audible = S_AdjustSoundParams(listenmobj[i], origin, &volume, &sep, sfx);
}
if (!audible)
@@ -574,12 +598,6 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
sfx->data = I_GetSfx(sfx);
}
// increase the usefulness
if (sfx->usefulness++ < 0)
{
sfx->usefulness = -1;
}
// Avoid channel reverse if surround
if (reverse)
{
@@ -598,7 +616,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
channels[cnum].sfxinfo = sfx;
channels[cnum].origin = origin;
channels[cnum].volume = initial_volume;
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, cnum);
}
}
@@ -607,7 +625,7 @@ void S_StartSound(const void *origin, sfxenum_t sfx_id)
if (S_SoundDisabled())
return;
if (mariomode) // Sounds change in Mario mode!
if (UNLIKELY(mariomode)) // Sounds change in Mario mode!
{
switch (sfx_id)
{
@@ -630,7 +648,8 @@ void S_StartSound(const void *origin, sfxenum_t sfx_id)
break;
}
}
if (maptol & TOL_XMAS) // Some sounds change for xmas
if (UNLIKELY(maptol & TOL_XMAS)) // Some sounds change for xmas
{
switch (sfx_id)
{
@@ -677,7 +696,7 @@ static INT32 actualmidimusicvolume;
void S_UpdateSounds(void)
{
INT32 cnum, volume, sep, pitch;
INT32 cnum, volume, sep;
boolean audible = false;
channel_t *c;
INT32 i;
@@ -687,14 +706,16 @@ void S_UpdateSounds(void)
// Update sound/music volumes, if changed manually at console
if (actualsfxvolume != cv_soundvolume.value)
S_SetSfxVolume (cv_soundvolume.value);
S_SetSfxVolume(cv_soundvolume.value);
if (actualdigmusicvolume != cv_digmusicvolume.value)
S_SetDigMusicVolume (cv_digmusicvolume.value);
S_SetDigMusicVolume(cv_digmusicvolume.value);
#ifndef NO_MIDI
if (actualmidimusicvolume != cv_midimusicvolume.value)
S_SetMIDIMusicVolume (cv_midimusicvolume.value);
S_SetMIDIMusicVolume(cv_midimusicvolume.value);
#endif
memset(listener, 0, sizeof(listener));
// We're done now, if we're not in a level.
if (gamestate != GS_LEVEL)
{
@@ -714,7 +735,6 @@ void S_UpdateSounds(void)
{
player_t *player = &players[displayplayers[i]];
memset(&listener[i], 0, sizeof (listener[i]));
listenmobj[i] = NULL;
if (player->awayviewtics)
@@ -725,15 +745,6 @@ void S_UpdateSounds(void)
{
listenmobj[i] = player->mo;
}
}
#ifndef NOMUMBLE
I_UpdateMumble(players[consoleplayer].mo, listener[0]);
#endif
for (i = 0; i <= splitscreen; i++)
{
player_t *player = &players[displayplayers[i]];
if (camera[i].chase && !player->awayviewtics)
{
@@ -751,6 +762,10 @@ void S_UpdateSounds(void)
}
}
#ifndef NOMUMBLE
I_UpdateMumble(players[consoleplayer].mo, listener[0]);
#endif
for (cnum = 0; cnum < numofchannels; cnum++)
{
c = &channels[cnum];
@@ -761,7 +776,6 @@ void S_UpdateSounds(void)
{
// initialize parameters
volume = c->volume; // 8 bits internal volume precision
pitch = NORM_PITCH;
sep = NORM_SEP;
// check non-local sounds for distance clipping
@@ -817,13 +831,13 @@ void S_UpdateSounds(void)
{
audible = S_AdjustSoundParams(
listenmobj[i], c->origin,
&volume, &sep, &pitch,
&volume, &sep,
c->sfxinfo
);
}
if (audible)
I_UpdateSoundParams(c->handle, volume, sep, pitch);
I_UpdateSoundParams(c->handle, volume, sep);
else
S_StopChannel(cnum);
}
@@ -876,8 +890,6 @@ static void S_StopChannel(INT32 cnum)
if (cnum != i && c->sfxinfo == channels[i].sfxinfo)
break;
// degrade usefulness of sound data
c->sfxinfo->usefulness--;
c->sfxinfo = 0;
}
@@ -918,8 +930,7 @@ fixed_t S_CalculateSoundDistance(fixed_t sx1, fixed_t sy1, fixed_t sz1, fixed_t
// If the sound is not audible, returns a 0.
// Otherwise, modifies parameters and returns 1.
//
boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch,
sfxinfo_t *sfxinfo)
static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, sfxinfo_t *sfxinfo)
{
const boolean reverse = (stereoreverse.value ^ encoremode);
@@ -928,8 +939,6 @@ boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32
listener_t listensource;
INT32 i;
(void)pitch;
if (!listener)
return false;
@@ -962,13 +971,16 @@ boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32
else
{
// Essentially check in a 1024 unit radius of the player for an outdoor area.
yl = listensource.y - 1024*FRACUNIT;
yh = listensource.y + 1024*FRACUNIT;
xl = listensource.x - 1024*FRACUNIT;
xh = listensource.x + 1024*FRACUNIT;
approx_dist = 1024*FRACUNIT;
for (y = yl; y <= yh; y += FRACUNIT*64)
for (x = xl; x <= xh; x += FRACUNIT*64)
#define RADIUSSTEP (64*FRACUNIT)
#define SEARCHRADIUS (16*RADIUSSTEP)
yl = listensource.y - SEARCHRADIUS;
yh = listensource.y + SEARCHRADIUS;
xl = listensource.x - SEARCHRADIUS;
xh = listensource.x + SEARCHRADIUS;
approx_dist = SEARCHRADIUS;
#undef SEARCHRADIUS
for (y = yl; y <= yh; y += RADIUSSTEP)
for (x = xl; x <= xh; x += RADIUSSTEP)
{
if (R_PointInSubsectorFast(x, y)->sector->ceilingpic == skyflatnum)
{
@@ -980,6 +992,7 @@ boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32
}
}
}
#undef RADIUSSTEP
}
}
else
@@ -990,14 +1003,14 @@ boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32
// Ring loss, deaths, etc, should all be heard louder.
if (sfxinfo->pitch & SF_X8AWAYSOUND)
approx_dist = FixedDiv(approx_dist,8*FRACUNIT);
approx_dist = FixedDiv(approx_dist, 8*FRACUNIT);
// Combine 8XAWAYSOUND with 4XAWAYSOUND and get.... 32XAWAYSOUND?
if (sfxinfo->pitch & SF_X4AWAYSOUND)
approx_dist = FixedDiv(approx_dist,4*FRACUNIT);
approx_dist = FixedDiv(approx_dist, 4*FRACUNIT);
if (sfxinfo->pitch & SF_X2AWAYSOUND)
approx_dist = FixedDiv(approx_dist,2*FRACUNIT);
approx_dist = FixedDiv(approx_dist, 2*FRACUNIT);
if (approx_dist > S_CLIPPING_DIST)
return false;
@@ -1030,7 +1043,7 @@ boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32
if (approx_dist >= S_CLOSE_DIST)
{
// distance effect
INT32 n = (15 * ((S_CLIPPING_DIST - approx_dist)>>FRACBITS));
const INT32 n = (15 * ((S_CLIPPING_DIST - approx_dist)>>FRACBITS));
*vol = FixedMul(*vol * FRACUNIT / 255, n) / S_ATTENUATOR;
}
@@ -1146,7 +1159,6 @@ void S_InitSfxChannels(INT32 sfxVolume)
// Note that sounds have not been cached (yet).
for (i = 1; i < NUMSFX; i++)
{
S_sfx[i].usefulness = -1; // for I_GetSfx()
S_sfx[i].lumpnum = LUMPERROR;
}
@@ -1906,12 +1918,12 @@ void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume)
}
}
void S_SetRestoreMusicFadeInCvar (consvar_t *cv)
void S_SetRestoreMusicFadeInCvar(consvar_t *cv)
{
music_refade_cv = cv_birdmusic.value ? cv : 0;
}
int S_GetRestoreMusicFadeIn (void)
int S_GetRestoreMusicFadeIn(void)
{
if (music_refade_cv && cv_fading.value)
return music_refade_cv->value;
@@ -2020,7 +2032,6 @@ void S_KeepMusic(void)
if (oldmap == gamemap && oldencore == encoremode)
{
const boolean musicchanged = S_CheckMusicException();
resumekeepmusic = (musicchanged && keepmusic.resume);
keepmapmusic = (!musicchanged || resumekeepmusic);
}
@@ -2187,6 +2198,7 @@ static void Command_Tunes_f(void)
mapmusic.name, (mapmusic.flags & MUSIC_TRACKMASK));
return;
}
if (!strcasecmp(tunearg, "-none"))
{
S_StopMusic();
@@ -2205,6 +2217,7 @@ static void Command_Tunes_f(void)
CONS_Alert(CONS_NOTICE, M_GetText("Valid music slots are 1 to 1035.\n"));
return;
}
if (!tunenum && strlen(tunearg) > 6) // This is automatic -- just show the error just in case
CONS_Alert(CONS_NOTICE, M_GetText("Music name too long - truncated to six characters.\n"));
@@ -2214,12 +2227,11 @@ static void Command_Tunes_f(void)
if (tunenum)
snprintf(mapmusic.name, 7, "%sM", G_BuildMapName(tunenum));
else
strncpy(mapmusic.name, tunearg, 7);
strlcpy(mapmusic.name, tunearg, sizeof(mapmusic.name));
if (argc > 4)
position = (UINT32)atoi(COM_Argv(4));
mapmusic.name[6] = 0;
mapmusic.flags = (track & MUSIC_TRACKMASK);
mapmusic.position = position;
mapmusic.resume = 0;
@@ -2246,7 +2258,7 @@ static void Command_RestartAudio_f(void)
I_StartupSound();
I_InitMusic();
// These must be called or no sound and music until manually set.
// These must be called or no sound and music until manually set.
I_SetSfxVolume(cv_soundvolume.value);
#ifdef NO_MIDI
+2
View File
@@ -32,6 +32,8 @@ extern consvar_t stereoreverse;
extern consvar_t cv_soundvolume, cv_digmusicvolume;//, cv_midimusicvolume;
extern consvar_t cv_numChannels;
extern consvar_t cv_samesoundlimit;
extern consvar_t cv_audbuffersize;
//extern consvar_t cv_resetmusic;
extern consvar_t cv_gamedigimusic;
+14 -5
View File
@@ -1806,13 +1806,22 @@ void I_SleepDuration(precise_t duration)
{
#if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__)
UINT64 precision = I_GetPrecisePrecision();
struct timespec ts = {
precise_t dest = I_GetPreciseTime() + duration;
precise_t slack = (precision / 5000); // 0.2 ms slack
if (duration > slack)
{
duration -= slack;
struct timespec ts = {
.tv_sec = static_cast<__time_t>(duration / precision),
.tv_nsec = static_cast<__syscall_slong_t>(duration * 1000000000 / precision % 1000000000),
};
int status;
do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
while (status == EINTR);
};
int status;
do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
while (status == EINTR);
}
// busy-wait the rest
while (((INT64)dest - (INT64)I_GetPreciseTime()) > 0);
#elif defined (MIN_SLEEP_DURATION_MS)
UINT64 precision = I_GetPrecisePrecision();
INT32 sleepvalue = cv_sleep.value;
+2
View File
@@ -1361,6 +1361,7 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
{
wasfullscreen = SDL_FALSE;
SDL_SetWindowFullscreen(window, 0);
I_SetBorderlessWindow();
}
// Reposition window only in windowed mode
@@ -1380,6 +1381,7 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
if (fullscreen)
{
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
I_SetBorderlessWindow();
}
}
+2 -5
View File
@@ -528,14 +528,12 @@ void I_FreeSfx(sfxinfo_t *sfx)
sfx->lumpnum = LUMPERROR;
}
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, INT32 channel)
{
UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127
INT32 handle = Mix_PlayChannel(channel, S_sfx[id].data, 0);
Mix_Volume(handle, volume);
Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff));
(void)pitch; // Mixer can't handle pitch
(void)priority; // priority and channel management is handled by SRB2...
return handle;
}
@@ -549,12 +547,11 @@ boolean I_SoundIsPlaying(INT32 handle)
return Mix_Playing(handle);
}
void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch)
void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep)
{
UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127
Mix_Volume(handle, volume);
Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff));
(void)pitch;
}
void I_SetSfxVolume(UINT8 volume)
+1 -1
View File
@@ -1079,7 +1079,7 @@ void I_StartupSound(void)
{
#ifndef HAVE_MIXER
#ifndef NO_MIDI
midi_disabled =
midi_disabled =
#endif
digital_disabled = true;
#endif
+888 -891
View File
File diff suppressed because it is too large. Load diff
-8
View File
@@ -78,9 +78,6 @@ struct sfxinfo_struct
// pitch if a link
INT32 pitch;
// volume if a link
INT32 volume;
// sound data
void *data;
@@ -91,11 +88,6 @@ struct sfxinfo_struct
// 0 up to (NUMSKINSOUNDS-1), -1 = not skin specifc
INT32 skinsound;
// this is checked every second to see if sound
// can be thrown out (if 0, then decrement, if -1,
// then throw out, if > 0, then it is in use)
INT32 usefulness;
// lump number of sfx
lumpnum_t lumpnum;
};
+75 -47
View File
@@ -126,6 +126,10 @@ void W_Shutdown(void)
Z_Free(wad->lumpinfo[wad->numlumps].longname);
Z_Free(wad->lumpinfo[wad->numlumps].fullname);
}
M_AATreeFree(wad->startfolders);
M_AATreeFree(wad->endfolders);
Z_Free(wad->lumpinfo);
Z_Free(wad);
}
@@ -338,6 +342,11 @@ static void W_InvalidateLumpnumCache(void)
memset(lumpnumcache, 0, sizeof (lumpnumcache));
}
UINT32 W_HashLumpName(const char *name)
{
return FNV1a_HashLowercaseString(name);
}
/** Detect a file type.
* \todo Actually detect the wad/pkzip headers and whatnot, instead of just checking the extensions.
*/
@@ -362,11 +371,24 @@ static lumpinfo_t* ResGetLumpsStandalone (FILE* handle, UINT16* numlumps, const
fseek(handle, 0, SEEK_END);
lumpinfo->size = ftell(handle);
fseek(handle, 0, SEEK_SET);
strlcpy(lumpinfo->name, lumpname, 9);
// Allocate the lump's full and long name.
lumpinfo->fullname = Z_StrDup(lumpname);
lumpinfo->longname = Z_StrDup(lumpname);
strlcpy(lumpinfo->name, lumpname, sizeof(lumpinfo->name));
lumpinfo->namelength = strlen(lumpinfo->name);
lumpinfo->hash.name = W_HashLumpName(lumpname);
// Allocate the lump's long name.
lumpinfo->longname = Z_Malloc((lumpinfo->namelength + 1) * sizeof(char), PU_STATIC, NULL);
strcpy(lumpinfo->longname, lumpname);
lumpinfo->longname[lumpinfo->namelength] = '\0';
lumpinfo->longnamelength = lumpinfo->namelength;
lumpinfo->hash.longname = lumpinfo->hash.name;
// Allocate the lump's full name.
lumpinfo->fullname = Z_Malloc((lumpinfo->namelength + 1) * sizeof(char), PU_STATIC, NULL);
strcpy(lumpinfo->fullname, lumpname);
lumpinfo->fullname[lumpinfo->namelength] = '\0';
lumpinfo->fullnamelength = lumpinfo->namelength;
lumpinfo->hash.fullname = lumpinfo->hash.name;
*numlumps = 1;
return lumpinfo;
@@ -454,16 +476,22 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
lump_p->compression = CM_NOCOMPRESSION;
memset(lump_p->name, 0x00, 9);
strncpy(lump_p->name, fileinfo->name, 8);
lump_p->namelength = strlen(lump_p->name);
lump_p->hash.name = W_HashLumpName(lump_p->name);
// Allocate the lump's long name.
lump_p->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
strncpy(lump_p->longname, fileinfo->name, 8);
lump_p->longname[8] = '\0';
lump_p->longnamelength = lump_p->namelength;
lump_p->hash.longname = lump_p->hash.name;
// Allocate the lump's full name.
lump_p->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
strncpy(lump_p->fullname, fileinfo->name, 8);
lump_p->fullname[8] = '\0';
lump_p->fullnamelength = lump_p->namelength;
lump_p->hash.fullname = lump_p->hash.name;
}
free(fileinfov);
*nlmp = numlumps;
@@ -656,12 +684,18 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
memset(lump_p->name, '\0', 9); // Making sure they're initialized to 0. Is it necessary?
strncpy(lump_p->name, trimname, min(8, dotpos - trimname));
lump_p->namelength = strlen(lump_p->name);
lump_p->hash.name = W_HashLumpName(lump_p->name);
lump_p->longname = Z_Calloc(dotpos - trimname + 1, PU_STATIC, NULL);
strlcpy(lump_p->longname, trimname, dotpos - trimname + 1);
lump_p->longnamelength = strlen(lump_p->longname);
lump_p->hash.longname = W_HashLumpName(lump_p->longname);
lump_p->fullname = (char*)(Z_Calloc(SHORT(zentry->namelen) + 1, PU_STATIC, NULL));
strncpy(lump_p->fullname, fullname, SHORT(zentry->namelen));
lump_p->fullnamelength = zentry->namelen;
lump_p->hash.fullname = W_HashLumpName(lump_p->fullname);
switch(SHORT(zentry->compression))
{
@@ -817,6 +851,8 @@ UINT16 W_InitFile(const char *filename, boolean local)
fseek(handle, 0, SEEK_END);
wadfile->filesize = (unsigned)ftell(handle);
wadfile->type = type;
wadfile->startfolders = M_AATreeAlloc(0);
wadfile->endfolders = M_AATreeAlloc(0);
// already generated, just copy it over
M_Memcpy(&wadfile->md5sum, &md5sum, 16);
@@ -872,7 +908,6 @@ UINT16 W_InitFile(const char *filename, boolean local)
return wadfile->numlumps;
}
/** Tries to load a series of files.
* All files are wads unless they have an extension of ".soc" or ".lua".
*
@@ -976,6 +1011,8 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
{
UINT16 i;
static char uname[9];
UINT32 hash;
size_t namelen;
if (!TestValidLump(wad,0))
return INT16_MAX;
@@ -983,6 +1020,8 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
memset(uname, 0, sizeof uname);
strncpy(uname, name, sizeof(uname)-1);
strupr(uname);
namelen = strlen(uname);
hash = W_HashLumpName(uname);
//
// scan forward
@@ -993,7 +1032,9 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
{
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
if (memcmp(lump_p->name, uname, sizeof(uname) - 1) == 0)
if (lump_p->namelength == namelen
&& lump_p->hash.name == hash
&& !memcmp(lump_p->name, uname, sizeof(uname) - 1))
return i;
}
@@ -1010,13 +1051,12 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump)
{
UINT16 i;
static char uname[256 + 1];
if (!TestValidLump(wad,0))
return INT16_MAX;
strlcpy(uname, name, sizeof uname);
strupr(uname);
size_t namelen = strlen(name);
UINT32 hash = W_HashLumpName(name);
//
// scan forward
@@ -1027,7 +1067,9 @@ UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump)
{
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
if (!strcmp(lump_p->longname, uname))
if (lump_p->longnamelength == namelen
&& lump_p->hash.longname == hash
&& !stricmp(lump_p->longname, name))
return i;
}
@@ -1051,6 +1093,12 @@ UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlum
INT32 i;
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
name_length = strlen(name);
UINT32 hash = quickncasehash(name, name_length);
void *val = M_AATreeGet(wadfiles[wad]->startfolders, hash);
if (val != NULL)
return (uintptr_t)val;
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
{
if (strnicmp(name, lump_p->fullname, name_length) == 0)
@@ -1058,10 +1106,16 @@ UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlum
/* SLADE is special and puts a single directory entry. Skip that. */
if (strlen(lump_p->fullname) == name_length)
i++;
break;
M_AATreeSet(wadfiles[wad]->startfolders, hash, (void *)(uintptr_t)i);
return i;
}
}
return i;
M_AATreeSet(wadfiles[wad]->startfolders, hash, (void *)INT16_MAX);
return INT16_MAX;
}
// In a PK3 type of resource file, it looks for the next lumpinfo entry that doesn't share the specified pathfile.
@@ -1072,11 +1126,20 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump)
INT32 i;
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
size_t name_length = strlen(name);
UINT32 hash = quickncasehash(name, name_length);
void *val = M_AATreeGet(wadfiles[wad]->endfolders, hash);
if (val != NULL)
return (uintptr_t)val;
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
{
if (strnicmp(name, lump_p->fullname, name_length))
break;
}
M_AATreeSet(wadfiles[wad]->endfolders, hash, (void *)(uintptr_t)i);
return i;
}
@@ -1201,41 +1264,6 @@ lumpnum_t W_CheckNumForLongName(const char *name)
}
}
// Look for valid map data through all added files in descendant order.
// Get a map marker for WADs, and a standalone WAD file lump inside PK3s.
// TODO: Make it search through cache first, maybe...?
lumpnum_t W_CheckNumForMap(const char *name)
{
UINT16 lumpNum, end;
UINT32 i;
for (i = numwadfiles - 1; i < numwadfiles; i--)
{
if (wadfiles[i]->type == RET_WAD)
{
for (lumpNum = 0; lumpNum < wadfiles[i]->numlumps; lumpNum++)
if (!strncmp(name, (wadfiles[i]->lumpinfo + lumpNum)->name, 8))
return (i<<16) + lumpNum;
}
else if (wadfiles[i]->type == RET_PK3)
{
lumpNum = W_CheckNumForFolderStartPK3("maps/", i, 0);
if (lumpNum != INT16_MAX)
end = W_CheckNumForFolderEndPK3("maps/", i, lumpNum);
else
continue;
// Now look for the specified map.
for (; lumpNum < end; lumpNum++)
if (!strnicmp(name, (wadfiles[i]->lumpinfo + lumpNum)->name, 8))
{
const char *extension = strrchr(wadfiles[i]->lumpinfo[lumpNum].fullname, '.');
if (!(extension && stricmp(extension, ".wad")))
return (i<<16) + lumpNum;
}
}
}
return LUMPERROR;
}
//
// W_GetNumForName
//
+17 -1
View File
@@ -22,6 +22,8 @@ extern "C" {
#include "hardware/hw_data.h"
#endif
#include "m_aatree.h"
#ifdef __GNUG__
#pragma interface
#endif
@@ -75,8 +77,19 @@ typedef struct
char name[9]; // filelump_t name[] e.g. "LongEntr"
char *longname; // e.g. "LongEntryName"
char *fullname; // e.g. "Folder/Subfolder/LongEntryName.extension"
size_t namelength; // length of name
size_t longnamelength; // length of longname
size_t fullnamelength; // length of fullname
size_t size; // real (uncompressed) size
compmethod compression; // lump compression method
struct {
UINT32 name; // hash of name
UINT32 longname; // hash of longname
UINT32 fullname; // hash of fullname
} hash;
} lumpinfo_t;
// =========================================================================
@@ -131,6 +144,8 @@ typedef struct wadfile_s
#ifdef ROTSPRITE
lumpcache_t *rotcache; // Cache rotsprites for rotating patches.
#endif
aatree_t *startfolders;
aatree_t *endfolders;
UINT16 numlumps; // this wad's number of resources
FILE *handle;
UINT32 filesize; // for network
@@ -167,6 +182,8 @@ INT32 W_AddAutoloadedLocalFiles(char **filenames);
#define W_FileHasFolders(wadfile) ((wadfile)->type == RET_PK3)
UINT32 W_HashLumpName(const char *name);
const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump);
const char *W_CheckNameForNum(lumpnum_t lumpnum);
@@ -180,7 +197,6 @@ UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump);
UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump);
UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump);
lumpnum_t W_CheckNumForMap(const char *name);
lumpnum_t W_CheckNumForName(const char *name);
lumpnum_t W_CheckNumForLongName(const char *name);
lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR