Compare commits

...
256 Commits
Author SHA1 Message Date
Alug 677e381a2c dont send server icon if current map is supposed to be hidden
in line with kart not sending maptitle to ms in the same case
2025-09-15 16:16:43 +02:00
Gustaf Alhäll 01b24e5417 Fix use-after-free when listing servers 2025-09-08 18:08:45 +02:00
Alug f86a99cd1b Merge branch 'Saturn-Next' into servericonpack 2025-09-03 12:33:56 +02:00
Alug 85cac497ea fixup building map title string for serverinfo
fixes numerous issues, like zonetitle not appearing on bots and serverinfo screen
and generally making this more sane by appending stuff if needed
also fixes "Zone" not displaying in serverinfo screen
2025-09-03 12:33:49 +02:00
Alug 92d6c2b7b0 make patch/pixel conversion account for padding data/no data
just set everything to transparent pixel 247 (0xf7)
so we neither write nor read garbage data and just can cut it out as transparent during pixel to patch conversion
2025-09-03 12:32:32 +02:00
Alug f67f8e7dbf cache patch width
just to avoid some cache misses in a somewhat tight lööp
2025-09-02 22:20:37 +02:00
indev 6adf39b460 Don't check for opengl in NOHW/DEDICATED builds 2025-09-02 23:01:07 +03:00
Alug e160427108 add smol comment 2025-09-02 21:38:10 +02:00
Alug 275d28c9c6 implement map icon request counter/limit
tries 5 times then gives up
this is just since vanilla clients do not send anything back to us so this would endlessly retry which is pointless
can be adjusted if needed
2025-09-02 21:27:32 +02:00
Alug 2a848e32e4 port map icon packet for serverinfo screen
based on https://codeberg.org/srb2classic/srb2classic/pulls/134

with adjustments
many thanks for the help @indev450 ! <3
2025-09-02 21:27:28 +02:00
indev 6af09bd215 Add offset for small nametags in opengl without shearing enabled 2025-09-01 19:56:42 +03:00
Gustaf Alhäll 015d9208e3 Refactor software blitting logic 2025-09-01 18:24:53 +02:00
Alug 94d01d1ee9 check clientcfg packet length to skip potential garbage data
dont think this ever broke, but better safe than sorry
2025-08-30 14:43:04 +02:00
indev 7e5acd72c1 Make replay search textbox fit on all resolutions 2025-08-28 15:37:03 +03:00
Alug 6017543666 dont try to make glpatch from nothing 2025-08-24 23:01:48 +02:00
indev 3af0009453 Fix off-by-one in M_FindFirstMap 2025-08-20 16:18:33 +03:00
Alug 145eecf8a4 move sprite reset stuff into R_ResetMobjInterpolationState
this also gets called at the start of the tic
and sets a bunch of rendering crap eitherways
so we can save another thinker loop and a bunch of checks with this
bit of perf gain, 3-4fps on that awful hadal trench timedemo
2025-08-19 11:49:29 +02:00
Alug 684a43a95c fix software extra 3d floors
lmao was a copy paste oopsie from ages ago
shoutout to phoenix´s new map making me find this
2025-08-18 16:49:36 +02:00
Alug 4fcb41f659 mark stuff for blitting loop as const and with register
gives another 5-7fps or so for me
2025-08-17 18:19:20 +02:00
Alug 8d1ef1721f port srb2classic´s sdl blitting stuff for software
all credits to hanicef
mostly from https://codeberg.org/srb2classic/srb2classic/commit/a1fa0b89dbf75ef8be17c9ca5c728cc9c1848582
and
https://codeberg.org/srb2classic/srb2classic/commit/a1cf54e66ad1cb66af99056bc940fc68dce24224

boosts my fps around 20-25 fps
2025-08-16 22:20:58 +02:00
Alug 02ffceb300 fix rotating polyobject interpolation 2025-08-16 22:20:55 +02:00
Alug 44fe156751 update comment for lightcontrast 2025-08-16 22:20:52 +02:00
Alug aca48d69cd style fixes 2025-08-16 22:20:48 +02:00
Alug 294ce055cd mark this with restrict 2025-08-16 22:20:33 +02:00
Alug 4117eb5b40 fix Paranoia compile 2025-08-16 22:20:30 +02:00
Alug a9068ee162 mark this with "noreturn"
clang kept yelling for some reason
2025-08-16 22:20:27 +02:00
indev 9549a204a5 Add tooltip for centered chat text 2025-08-15 22:57:09 +03:00
indev c276736002 Add option to center text in chat (chatcentertext) 2025-08-15 21:51:58 +03:00
Alug b5dfe74cfe add USECLANG compile flag to force building with clang 2025-08-15 08:01:58 +02:00
Alug 6c891f1146 supress align and unkown pragma warnings in clang 2025-08-15 08:01:56 +02:00
Alug 7d06f59da5 append those to LDFLAGS instead of libs
so they may be passed to other things
2025-08-15 08:01:47 +02:00
Alug 9dee0f0ea8 fix restrict being in wrong place in declaration R_DrawColumnPixel 2025-08-15 08:01:37 +02:00
Alug 9338b5b10f dont need to realloc this
didnt see when i added realloc everywhere this doesent need to keep old data
2025-08-14 16:19:17 +02:00
Gustaf Alhäll b7ecffedcd Fix pixel shift caused by negative pixel positioning in software 2025-08-13 22:44:25 +02:00
Alug 7deeb4486f port RR camera slope pitch stuff + make it toggable
"cam_pitch" this makes the camera pitch on upwards and downwards slopes a bit
2025-08-13 18:01:00 +02:00
Alug 602bd1a010 fix directional light stuff 2025-08-12 20:29:13 +02:00
Alug f57b8092fc dont need to reinit those gl vars 2025-08-12 20:29:10 +02:00
Alug ca04e084a2 link stdc++. pthread and gcclib statically on windows
fixes the game throwing super cryptic errors when you dont have the right dlls
2025-08-09 23:32:03 +01:00
Alug ff6279a406 add P_GetLocalPlayerForNum
just to get rid of ternaries lel
2025-08-09 17:21:08 +02:00
Alug c36f64e97b use memcmp for legacy sky check
just gotta know if first three letters match it
2025-08-09 17:21:05 +02:00
Alug 7b776f01bd change flow of K_drawKartStats a bit
nothing notable, just the non splitscreen path will return early now
2025-08-08 22:43:43 +02:00
Alug 43b7492300 disable pointless "Couldn't read mobj_t" warnings in replays
mobjs just cannot be unarchived in replays ever
so this will always spam those for something that WILL never work in kart
maybe if i decide to fix this for 32p or smth those become useful again
2025-08-08 22:29:29 +02:00
indev 1fe79fe236 Add -strict, -strict-soc and -strict-lua cli params
Both trigger I_Error if a warning occurs during addon load in a SOC or lua
script
2025-08-08 18:59:07 +03:00
Alug 222b63d2c3 move the windoze thing to windoze makefile 2025-08-08 17:53:25 +02:00
indev a7c41b458a Use NOLIBGME instead of NOGME 2025-08-08 18:33:24 +03:00
indev 3901c7c7da Revert "Fix makefiles checking for NOLIBGME instead of NOGME"
This reverts commit 932a08b2da.
2025-08-08 18:31:45 +03:00
indev 932a08b2da Fix makefiles checking for NOLIBGME instead of NOGME 2025-08-08 18:29:05 +03:00
indev 4c97a4f9e0 Fix potential buffer overflow in DEH_LoadDehackedFile 2025-08-08 17:53:46 +03:00
indev a1d16b4613 Update dedicated/i_sound.c I_StartSound and I_UpdateSoundParams 2025-08-08 17:43:40 +03:00
Alug 16e1e00c67 "reenable" midi support
well it was never really disabled, but like this we can atleast change its volume lel
menu entry is still disabled, i dont think theres a single map with midi music, so this would just clutter the menu
2025-08-08 00:55:06 +02:00
Alug b76fc9699a fixup midi menu stuff
i love M_DrawSkyRoom
2025-08-08 00:55:03 +02:00
indev cb3638e3ab Add SetupVote hook 2025-08-07 23:48:11 +03:00
Alug e85d91e682 save a few checks for st debug drawer
if we dont use it
2025-08-07 22:27:28 +02:00
Alug 2653b59af4 dont double free our vote patches
those may point to the same thing so uhhhh
PU_PATCH_LOWPRIORITY will ensure the memory will be freed on mapload
2025-08-07 22:26:27 +02:00
Alug caff071a1b fix spacing in Z_CheckHeap errors 2025-08-07 22:10:03 +02:00
Alug 40165fd6db make leveltitlecard be affected by colour hud 2025-08-07 19:42:39 +02:00
Alug c701e1fe7e make inputdisplay colour match the rest of colourhud better 2025-08-07 19:38:03 +02:00
Alug 525e19566e smol refactor hwr precache
not faster or anything
real time consuming thing is he actual calls to getetxture and getflat
2025-08-07 19:38:00 +02:00
Alug 27e734bde0 make music toggle/volume handling less of a mess
based on work in srb2 from sphere
this gets rid of all the duplicated midi stuff
since we dont really have a whole midi soundtrack like srb2, S_GetMusicLumpNum will always prefer non midi music
2025-08-06 19:49:35 +02:00
Alug bd53786887 fix LoadElevatorThinker interp oopsie 2025-08-06 00:12:34 +02:00
Alug ad1b1eabe4 fix levelstuff not being interpolated on netgame join or resynch
i love polyobjects
2025-08-06 00:10:47 +02:00
Alug e120907e0f make driftgauge stuff a bit more readable 2025-08-03 20:12:13 +02:00
Alug b0c217201e move flat cyan check into a function
and also limit it to software renderer only
we dont need this anywhere else, so can save a bit of work
2025-08-03 15:59:57 +02:00
Alug dac7026739 use R_GetFlat here
does the exact same thing
2025-08-03 15:59:23 +02:00
Alug 91a4646f19 dont PU_CACHE our planeflats 2025-08-03 15:51:52 +02:00
Alug eba5965220 move rainbow color calc into K_Rainbowcolor 2025-08-03 14:42:49 +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
100 changed files with 8153 additions and 10864 deletions

No files matched your search

+12
View File
@@ -192,6 +192,18 @@ from `0` to `#musicdefs-1`, or string indices (which is equal to calling `S_Find
Hook is called whenever `S_ShowMusicCredit` (either from game or mod) is called. Takes musicdef as only argument, returning true
will overwrite vanilla behavior (not show music credit), can be used to implement custom music credit pop-ups.
## addHook("SetupVote", function(result, gt, secondgt, prevmap))
Hook is called whenever server sets up options for vote screen. `result` is table where lua can store options to,
(for example, `result[1] = 1` will force green hills as first option), gt is current gametype, secondgt is
alternative gametype picked for 3rd entry (for example, gt can be `GT_RACE`, and secondgt can be `GT_MATCH`)
prevmap is the previous map that was played (small note - in game code, it is offset by -1, but for lua its offset back,
so if previous gamemap was 1, prevmap would also be 1. Which means you can safely do mapheaderinfo[prevmap] to get info on previous map)
Limitations: currently, game can only change gametype for 3rd option in map (meaning for example, if current gametype is race, and you
put battle map in first option, when it gets picked that map will be still run in race gametype). That means, game will only handle maps with
different gametype if it is put in 3rd vote option.
# Other changes
## P_PlayRinglossSound(source, damager)
+18
View File
@@ -30,6 +30,24 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
0-Clause BSD License
applies to:
- qs22k
Copyright (c) 2022, Raymond Gardner
--------------------------------------------------------------------------------
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--------------------------------------------------------------------------------
curl License
applies to:
+37 -9
View File
@@ -49,7 +49,7 @@
# Already enabled by default for 32-bit
# Windows.
# NOCURL=1 - Disable libcurl--HTTP capability.
# NOGME=1 - Disable game music emu, retro VGM support.
# NOLIBGME=1 - Disable game music emu, retro VGM support.
# NOOPENMPT=1 - Disable module (tracker) music support.
# NOMIXER=1 - Disable SDL Mixer (audio playback).
# NOTHREADS=1 - Disable multithreading.
@@ -131,9 +131,19 @@ endif
include Makefile.d/util.mk
ifdef PREFIX
ifdef USECLANG
CC:=$(PREFIX)-clang
CXX:=$(PREFIX)-clang++
else
CC:=$(PREFIX)-gcc
CXX:=$(PREFIX)-g++
endif
endif
ifdef USECLANG
CC=clang
CXX=clang++
endif
OBJDUMP_OPTS?=--wide --source --line-numbers
@@ -236,7 +246,7 @@ endif
# build with profiling information
ifdef PROFILEMODE
opts+=-pg
libs+=-pg
LDFLAGS+=-pg
endif
ifdef DEBUGMODE
@@ -246,26 +256,44 @@ debug_opts=-DNDEBUG
opts+=-O3
ifdef USELTO
# compile with LTO
ifdef MINGW
opts+=-flto=auto -g
LDFLAGS+=-flto=auto -g
else
opts+=-flto=auto
libs+=-flto=auto
LDFLAGS+=-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
endif
ifeq ($(CC),clang)
LDFLAGS+= -fuse-ld=lld
endif
# debug_opts also get passed to windres
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
cc=$(CC)
@@ -375,12 +403,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
+1 -1
View File
@@ -14,6 +14,6 @@ sources+=dedicated/i_threads.c
endif
NOOPENMPT=1
NOGME=1
NOLIBGME=1
NOHW=1
NOUPNP=1
+2 -10
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
@@ -74,13 +73,6 @@ libs+=-lbacktrace
opts+=-DHAVE_LIBBACKTRACE
endif
#windoze hack
ifdef MINGW
ifndef NODISCORDRPC
HAVE_DISCORDRPC=1
endif
endif
ifdef HAVE_DISCORDRPC
$(eval $(call Propogate_flags,DISCORDRPC))
libs+=-ldiscord-rpc
@@ -98,7 +90,7 @@ opts+=-DHAVE_VALGRIND
endif
default_packages:=\
GME/libgme/LIBGME\
LIBGME/libgme/LIBGME\
OPENMPT/libopenmpt/LIBOPENMPT\
ZLIB/zlib\
+10 -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
@@ -146,6 +144,10 @@ ifdef GCC81
WFLAGS+=-Wno-error=multistatement-macros
endif
ifeq ($(CC),clang)
WFLAGS+= -Wno-unknown-pragmas -Wno-cast-align
endif
ifdef NONX86
ifdef X86_64 # yeah that SEEMS contradictory
opts+=-march=nocona
+6 -1
View File
@@ -15,6 +15,7 @@ endif
sources+=win32/Srb2win.rc
opts+=-DSTDC_HEADERS
libs+=-Wl,-Bstatic -lstdc++ -lpthread -lgcc -Wl,-Bdynamic
libs+=-ladvapi32 -lkernel32 -lmsvcrt -luser32
ifndef DEDICATED
@@ -42,6 +43,10 @@ libs+=-Wl,--large-address-aware
NOLIBBACKTRACE=1
endif
ifndef NODISCORDRPC
HAVE_DISCORDRPC=1
endif
ifndef MINGW64
32=32
x86=x86
@@ -66,7 +71,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[]);
+1 -1
View File
@@ -61,7 +61,7 @@ struct SourceLocation {
class IErrorAssertHandler {
public:
static void handle(const SourceLocation& source_location, const char* expression) {
[[ noreturn ]] static void handle(const SourceLocation& source_location, const char* expression) {
I_Error("Assertion failed at %s:%u: %s != true",
source_location.file_name,
source_location.line_number,
+1129 -779
View File
File diff suppressed because it is too large. Load diff
+5 -4
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.
@@ -120,6 +120,8 @@ typedef enum
PT_ISSATURN, // Saturn specific identifier packet
#endif
PT_MAPICON, // Send map image icon (gamespy).
PT_NEEDMAPICON, // Request missed map icon (gamespy).
NUMPACKETTYPE
} packettype_t;
@@ -513,6 +515,7 @@ typedef struct
INT32 filesneedednum; // 4 bytes
filesneededconfig_pak filesneededcfg; // ??? bytes
UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes
UINT8 mapicondata[0];
} u; // This is needed to pack diff packet types data together
} ATTRPACK doomdata_t;
@@ -533,7 +536,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;
@@ -565,7 +567,6 @@ typedef enum
KR_TIMEOUT, //Connection Timeout
KR_BAN, //Banned by server
KR_LEAVE, //Quit the game
} kickreason_t;
/* the max number of name changes in some time period */
+13 -35
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"
@@ -120,11 +121,8 @@ INT32 postimgparam[MAXSPLITSCREENPLAYERS];
// These variables are only true if
// whether the respective sound system is disabled
// or they're init'ed, but the player just toggled them
#ifndef NO_MIDI
boolean midi_disabled = false;
#endif
boolean sound_disabled = false;
boolean digital_disabled = false;
boolean music_disabled = false;
#ifdef DEBUGFILE
INT32 debugload = 0;
@@ -927,7 +925,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)
@@ -935,7 +933,6 @@ void D_SRB2Loop(void)
Discord_RunCallbacks();
}
#endif
// Fully completed frame made.
finishprecise = I_GetPreciseTime();
@@ -973,6 +970,7 @@ void D_SRB2Loop(void)
I_SleepDuration(capbudget - elapsed);
}
}
// Capture the time once more to get the real delta time.
finishprecise = I_GetPreciseTime();
deltasecs = (double)((INT64)(finishprecise - enterprecise)) / I_GetPrecisePrecision();
@@ -1988,45 +1986,23 @@ void D_SRB2Main(void)
if (dedicated)
{
sound_disabled = true;
digital_disabled = true;
#ifndef NO_MIDI
midi_disabled = true;
#endif
music_disabled = true;
}
if (M_CheckParm("-noaudio")) // combines -nosound and -nomusic
{
sound_disabled = true;
digital_disabled = true;
#ifndef NO_MIDI
midi_disabled = true;
#endif
music_disabled = true;
}
else
{
if (M_CheckParm("-nosound"))
sound_disabled = true;
if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic
{
digital_disabled = true;
#ifndef NO_MIDI
midi_disabled = true;
#endif
}
else
{
#ifndef NO_MIDI
if (M_CheckParm("-nomidimusic"))
midi_disabled = true; // WARNING: DOS version initmusic in I_StartupSound
#endif
if (M_CheckParm("-nodigmusic"))
digital_disabled = true; // WARNING: DOS version initmusic in I_StartupSound
}
if (M_CheckParm("-nomusic"))
music_disabled = true;
}
if (!( sound_disabled && digital_disabled
#ifndef NO_MIDI
&& midi_disabled
#endif
))
if (!(sound_disabled && music_disabled))
{
CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n");
I_StartupSound();
@@ -2036,6 +2012,8 @@ void D_SRB2Main(void)
S_InitMusicDefs();
M_InitEmotes();
CONS_Printf("ST_Init(): Init status bar.\n");
ST_Init();
+35 -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)
@@ -1197,6 +1201,7 @@ boolean HGetPacket(void)
GotAcks();
continue;
}
doomcom->datalength -= BASEPACKETSIZE;
break;
}
#endif // ifndef NONET
@@ -1220,6 +1225,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 +1244,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 +1343,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"))
{
+16 -1
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);
@@ -934,6 +937,7 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_consolechat);
CV_RegisterVar(&cv_chatnotifications);
CV_RegisterVar(&cv_chatbacktint);
CV_RegisterVar(&cv_chatcentertext);
CV_RegisterVar(&cv_songcredits);
CV_RegisterVar(&cv_showfreeplay);
CV_RegisterVar(&cv_skinselectspin);
@@ -2502,6 +2506,14 @@ void D_SetupVote(void)
UINT8 gt = (cv_kartgametypepreference.value == -1) ? gametype : cv_kartgametypepreference.value;
UINT8 secondgt = G_SometimesGetDifferentGametype(gt);
INT16 votebuffer[4] = {-1,-1,-1,0};
INT16 luamaps[4] = {0, 0, 0, 0};
LUA_HookSetupVote(luamaps, sizeof(luamaps)/sizeof(luamaps[0]), gt, secondgt);
// Correct secondgt if needed
UINT8 typeoflevel = mapheaderinfo[luamaps[2]-1]->typeoflevel;
if (luamaps[2] && (typeoflevel & G_TOLFlag(secondgt&(~0x80))) == 0)
secondgt = ((typeoflevel & TOL_RACE) ? GT_RACE : GT_MATCH)|(secondgt&0x80);
if (cv_kartencore.value && gt == GT_RACE)
WRITEUINT8(p, (gt|0x80));
@@ -2510,10 +2522,13 @@ void D_SetupVote(void)
WRITEUINT8(p, secondgt);
secondgt &= ~0x80;
for (i = 0; i < 4; i++)
{
UINT16 m;
if (i == 2) // sometimes a different gametype
if (luamaps[i])
m = luamaps[i]-1;
else if (i == 2) // sometimes a different gametype
m = G_RandMap(G_TOLFlag(secondgt), prevmap, false, 0, true, votebuffer);
else if (i >= 3) // unknown-random and force-unknown MAP HELL
m = G_RandMap(G_TOLFlag(gt), prevmap, false, (i-2), (i < 4), votebuffer);
+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;
+2 -5
View File
@@ -69,13 +69,11 @@ 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)
{
(void)id;
(void)vol;
(void)sep;
(void)pitch;
(void)priority;
(void)channel;
return 0;
}
@@ -116,12 +114,11 @@ 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)
{
(void)handle;
(void)vol;
(void)sep;
(void)pitch;
}
/** \brief The I_SetSfxVolume function
+10 -2
View File
@@ -178,6 +178,9 @@ FUNCPRINTF static void deh_warning(const char *first, ...)
else
CONS_Alert(CONS_WARNING, "Line %u: %s\n", dbg_line, buf);
if (dbg_line != -1 && (M_CheckParm("-strict") || M_CheckParm("-strict-soc")))
I_Error("deh_warning: %s", buf);
deh_num_warning++;
Z_Free(buf);
@@ -1616,7 +1619,6 @@ actionpointer_t actionpointers[] =
{A_BrakLobShot, "A_BRAKLOBSHOT"},
{A_NapalmScatter, "A_NAPALMSCATTER"},
{A_SpawnFreshCopy, "A_SPAWNFRESHCOPY"},
//{A_InvincSparkleRotate, "A_INVINCSPARKLEROTATE"},
{NULL, "NONE"},
@@ -2856,7 +2858,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
dbg_line = -1; // start at -1 so the first line is 0.
while (!myfeof(f))
{
char origpos[128];
char origpos[256];
INT32 size = 0;
char *traverse;
@@ -2872,6 +2874,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
size++;
}
if (size > (int)sizeof(origpos))
{
deh_warning("Line is too long");
size = sizeof(origpos)-1;
}
strncpy(origpos, s, size);
origpos[size] = '\0';
+6 -1
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>
@@ -646,7 +650,8 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
#define NOCLIPCAM
/// SRB2Kart: MIDI support is shitty and busted and we don't want it, lets throw it behind a define
#define NO_MIDI
// yall didnt properly disable it so it always worked lol (:
//#define NO_MIDI
/// Sprite rotation
#define ROTSPRITE
+2 -7
View File
@@ -102,13 +102,8 @@ extern boolean forceresetplayers, deferencoremode;
// Internal parameters for sound rendering.
// ========================================
#ifdef NO_MIDI
#define midi_disabled true
#else
extern boolean midi_disabled;
#endif
extern boolean sound_disabled;
extern boolean digital_disabled;
extern boolean music_disabled;
// =========================
// Status flags for refresh.
@@ -575,7 +570,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;
+6 -3942
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -49,7 +49,7 @@ extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard di
extern INT16 rw_maximums[NUM_WEAPONS];
// used in game menu
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection/*, cv_compactscoreboard*/;
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_chatcentertext/*, cv_compactscoreboard*/;
extern consvar_t cv_songcredits;
extern consvar_t cv_showfreeplay;
extern consvar_t cv_growmusic, cv_supermusic;
+2 -1
View File
@@ -99,7 +99,8 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
polygonArrayAllocSize *= 2;
polygonArray = realloc(polygonArray, polygonArrayAllocSize * sizeof(PolygonArrayEntry));
// also need to redo the index array, dont need to copy it though
polygonArraySorted = realloc(polygonArraySorted, polygonArrayAllocSize * sizeof(PolygonArrayEntry*));
free(polygonArraySorted);
polygonArraySorted = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry *));
}
while (unsortedVertexArraySize + (int)iNumPts > unsortedVertexArrayAllocSize)
-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
+52 -90
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)
@@ -334,7 +328,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *gltex, boolean noe
gltex->mipmap.format = textureformat;
// hack the Legacy skies..
if (UNLIKELY(strncmp(texture->name, "SKY", 3) == 0 &&
if (UNLIKELY(memcmp(texture->name, "SKY", 3) == 0 &&
(texture->name[4] == 0 || texture->name[5] == 0)))
{
skyspecial = true;
@@ -606,7 +600,6 @@ void HWR_FreeMapTextures(void)
static void HWR_PrecacheLevelFlats(void)
{
levelflat_t levelflat;
lumpnum_t lump;
size_t i, j;
INT32 k;
@@ -620,28 +613,22 @@ static void HWR_PrecacheLevelFlats(void)
{
sector_t *sec = &sectors[i];
// sector checked already?
if (sec->validcount == validcount)
continue;
sec->validcount = validcount;
// gotta check sector floor and ceiling
for (j = 0; j < 2; j++)
{
const boolean ceiling = (j == 0);
INT32 pic = ceiling ? sec->ceilingpic : sec->floorpic;
const INT32 pic = ceiling ? sec->ceilingpic : sec->floorpic;
levelflat = levelflats[pic];
const levelflat_t *levelflat = &levelflats[pic];
lump = levelflat.lumpnum;
lump = levelflat->lumpnum;
HWR_GetFlat(lump, R_NoEncore(sec, ceiling));
if (levelflat.speed) // it is an animated flat
if (levelflat->speed) // it is an animated flat
{
for (k = 1; k < levelflat.numpics; k++)
for (k = 1; k < levelflat->numpics; k++)
{
lump = levelflat.baselumpnum + k;
lump = levelflat->baselumpnum + k;
HWR_GetFlat(lump, R_NoEncore(sec, ceiling));
}
}
@@ -655,18 +642,18 @@ static void HWR_PrecacheLevelFlats(void)
// just load every flat in the level
for (i = 0; i < numlevelflats; i++)
{
levelflat = levelflats[i];
lump = levelflat.lumpnum;
const levelflat_t *levelflat = &levelflats[i];
lump = levelflat->lumpnum;
HWR_GetFlat(lump, false);
if (levelflat.speed) // it is an animated flat
if (!levelflat->speed) // is it an animated flat ?
continue;
for (k = 1; k < levelflat->numpics; k++)
{
for (k = 1; k < levelflat.numpics; k++)
{
lump = levelflat.baselumpnum + k;
HWR_GetFlat(lump, false);
}
lump = levelflat->baselumpnum + k;
HWR_GetFlat(lump, false);
}
}
}
@@ -676,52 +663,55 @@ static void HWR_PrecacheLevelTextures(void)
{
char *texturepresent;
anim_t *anim;
size_t i, j;
size_t i, j, f;
INT32 h;
texturepresent = calloc(numtextures, sizeof (*texturepresent));
if (texturepresent == NULL) I_Error("%s: Out of memory looking up textures", "HWR_PrecacheLevel");
if (texturepresent == NULL)
I_Error("%s: Out of memory looking up textures", "HWR_PrecacheLevel");
// Sky texture is always present.
// Note that F_SKY1 is the name used to indicate a sky floor/ceiling as a flat,
// while the sky texture is stored like a wall texture, with a skynum dependent name.
texturepresent[skytexture] = 1;
HWR_GetTexture(skytexture, false);
for (i = 0; i < numlines; i++)
{
line_t *line = &lines[i];
const line_t *line = &lines[i];
#ifdef GLENCORE
const int noencoremap = ((line->flags & ML_TFERLINE) ? 2 : 1);
const int noencoremap = ((encoremap && (line->flags & ML_TFERLINE)) ? 2 : 1);
#else
const int noencoremap = 1;
#endif
// line checked already?
if (line->validcount == validcount)
continue;
line->validcount = validcount;
// two sides
for (j = 0; j < 2; j++)
{
side_t *side = &sides[line->sidenum[j]];
// Single-side linedef
// check if single-sided linedef
if (line->sidenum[j] == 0xffff)
continue;
if (side->toptexture >= 0 && side->toptexture < numtextures)
const side_t *side = &sides[line->sidenum[j]];
const INT32 sidetex[] = {side->toptexture, side->midtexture, side->bottomtexture};
// gotta check from top to bottom uwu
for (f = 0; f < 3; f++)
{
texturepresent[side->toptexture] = 1|noencoremap;
}
if (side->midtexture >= 0 && side->midtexture < numtextures)
{
texturepresent[side->midtexture] = 1|noencoremap;
}
if (side->bottomtexture >= 0 && side->bottomtexture < numtextures)
{
texturepresent[side->bottomtexture] = 1|noencoremap;
const INT32 texnum = sidetex[f];
if (texnum < 0 || texnum >= numtextures || texturepresent[texnum])
continue;
texturepresent[texnum] = 1|noencoremap;
HWR_GetTexture(texnum, false);
#ifdef GLENCORE
if (noencoremap & 2)
HWR_GetTexture(texnum, true);
#endif
}
}
}
// check for animated textures
for (anim = anims; anim < lastanim; anim++)
{
if (!anim->istexture)
@@ -732,47 +722,21 @@ static void HWR_PrecacheLevelTextures(void)
if (!texpresent)
continue;
if (texpresent & 1)
for (h = 1; h < anim->numpics; h++)
{
for (h = 1; h < anim->numpics; h++)
if (texpresent & 1)
{
HWR_GetTexture(anim->basepic+h, false);
}
}
#ifdef GLENCORE
if (texpresent & 2)
{
for (h = 1; h < anim->numpics; h++)
if (texpresent & 2)
{
HWR_GetTexture(anim->basepic+h, true);
}
}
#endif
}
}
// Sky texture is always present.
// Note that F_SKY1 is the name used to indicate a sky floor/ceiling as a flat,
// while the sky texture is stored like a wall texture, with a skynum dependent name.
texturepresent[skytexture] = 1;
for (i = 0; i < (unsigned)numtextures; i++)
{
const char texpresent = texturepresent[i];
if (!texpresent)
continue;
if (texpresent & 1)
{
HWR_GetTexture(i, false);
}
#ifdef GLENCORE
if (texpresent & 2)
{
HWR_GetTexture(i, true);
}
#endif
}
free(texturepresent);
}
@@ -781,21 +745,19 @@ static void HWR_PrecacheLevelSprites(void)
patch_t *spritepatch;
char *spritepresent;
size_t i, j, k;
lumpnum_t lump;
thinker_t *th;
mobj_t *mo;
spriteframe_t *sf;
spritepresent = calloc(numsprites, sizeof (*spritepresent));
if (spritepresent == NULL) I_Error("%s: Out of memory looking up sprites", "HWR_PrecacheLevel");
if (spritepresent == NULL)
I_Error("%s: Out of memory looking up sprites", "HWR_PrecacheLevel");
for (th = thinkercap.next; th != &thinkercap; th = th->next)
{
if (th->function != (actionf_p1)P_MobjThinker)
continue;
mo = (mobj_t *)th;
const mobj_t *mo = (mobj_t *)th;
// ogl is weird
// for some reason it does not want to preload sprites with colormaps
@@ -813,10 +775,10 @@ static void HWR_PrecacheLevelSprites(void)
for (j = 0; j < sprites[i].numframes; j++)
{
sf = &sprites[i].spriteframes[j];
const spriteframe_t *sf = &sprites[i].spriteframes[j];
#define cacheang(a) {\
lump = sf->lumppat[a];\
const lumpnum_t lump = sf->lumppat[a];\
spritepatch = (patch_t *)W_CachePatchNum(lump, PU_SPRITE);\
if (spritepatch != NULL)\
HWR_GetPatch(spritepatch);\
+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);
+87 -107
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};
@@ -374,7 +378,7 @@ void HWR_ObjectLightLevelPost(gl_vissprite_t *spr, const sector_t *sector, INT32
fixed_t extralight = R_GetSpriteDirectionalLighting(R_PointToAngle(spr->mobj->x, spr->mobj->y));
// Less change in contrast in dark sectors
extralight = FixedMul(extralight, CLAMP(*lightlevel, 0, 255) * FRACUNIT / 255);
extralight = FixedMul(extralight, std::min(std::max(0, *lightlevel), 255) * FRACUNIT / 255);
// simple OGL approximation
fixed_t tr = R_QuickCamDist(spr->mobj->x, spr->mobj->y) << FRACBITS;
@@ -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,15 +453,13 @@ 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())
{
V_CubeApply(&tint_color.s.red, &tint_color.s.green, &tint_color.s.blue);
V_CubeApply(&fade_color.s.red, &fade_color.s.green, &fade_color.s.blue);
}
Surface->PolyColor.rgba = poly_color.rgba;
Surface->TintColor.rgba = tint_color.rgba;
Surface->FadeColor.rgba = fade_color.rgba;
@@ -544,9 +549,9 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
INT32 i;
float height; // constant y for all points on the convex flat polygon
float flatxref, flatyref = 0.0f;
float fflatsize = 64.0f;
INT32 flatflag = 63;
static float flatxref = 0.0f, flatyref = 0.0f;
static float fflatsize = 64.0f;
static INT32 flatflag = 63;
size_t len;
float tempxsow, tempytow;
@@ -704,7 +709,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));
@@ -1008,10 +1014,10 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
float diff;
fixed_t v1x = FloatToFixed(wallVerts[0].x);
fixed_t v1y = FloatToFixed(wallVerts[0].z);
fixed_t v2x = FloatToFixed(wallVerts[1].x);
fixed_t v2y = FloatToFixed(wallVerts[1].z);
const fixed_t v1x = FloatToFixed(wallVerts[0].x);
const fixed_t v1y = FloatToFixed(wallVerts[0].z);
const fixed_t v2x = FloatToFixed(wallVerts[1].x);
const fixed_t v2y = FloatToFixed(wallVerts[1].z);
const UINT8 alpha = Surf->PolyColor.s.alpha;
FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, gl_curline, NULL);
@@ -1217,6 +1223,7 @@ static void HWR_DrawSkyWallList(void)
HWR_SetCurrentTexture(NULL);
GL_UnSetShader();
for (i = 0; i < skyWallVertexArraySize; i++)
{
GL_DrawPolygon(&surf, skyWallVertexArray + i * 4, 4, PF_Occlude|PF_Invisible|PF_NoTexture|PF_Skydecal);
@@ -3026,7 +3033,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 +3173,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 +3532,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 +3772,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 +3791,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 +3998,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 +4099,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 +4109,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 +4117,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 +4538,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 +4557,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 +4587,7 @@ static void HWR_AddSprites(sector_t *sec)
HWR_ProjectSprite(thing);
}
}
}
// --------------------------------------------------------------------------
// HWR_AddPrecipitationSprites
@@ -4949,24 +4971,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
{
@@ -5284,19 +5306,14 @@ static void HWR_DrawSkyBackground(void)
{
FTransform dometransform;
if (drewsky)
return;
if (HWR_IsWireframeMode())
if (drewsky || HWR_IsWireframeMode())
return;
GL_SetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated);
memcpy(&dometransform, &atransform, sizeof(FTransform));
dometransform.x = 0.0;
dometransform.y = 0.0;
dometransform.z = 0.0;
dometransform.x = dometransform.y = dometransform.z = 0.0;
//04/01/2000: Hurdler: added for T&L
// It should replace all other gl_viewxxx when finished
@@ -5313,6 +5330,7 @@ static void HWR_DrawSkyBackground(void)
if (HWR_UseShader())
GL_SetShader(HWR_GetShaderFromTarget(SHADER_SKY));
GL_SetTransform(&dometransform);
GL_RenderSkyDome(&gl_sky);
}
@@ -5330,7 +5348,6 @@ static inline void HWR_ClearView(void)
GL_ClearBuffer(false, true, true, NULL);
}
// -----------------+
// HWR_SetViewSize : set projection and scaling values
// -----------------+
@@ -5561,7 +5578,7 @@ void HWR_RenderViewpoint(gl_portal_t *rootportal, player_t *player, int stencil_
drewsky = false;
HWR_DrawSkyBackground();
HWR_SetStencilState(HWR_STENCIL_NORMAL, 0);
GL_ClearBuffer(false, false, true, 0);// clear skywall markings from the stencil buffer
GL_ClearBuffer(false, false, true, NULL);// clear skywall markings from the stencil buffer
HWR_SetTransform(fpov);// restore transform
}
}
@@ -5680,13 +5697,7 @@ void HWR_RenderPlayerView(void)
// Clear the color buffer, stops HOMs. Also seems to fix the skybox issue on Intel GPUs.
if (viewssnum == 0) // Only do it if it's the first screen being rendered
{
FRGBAFloat ClearColor;
ClearColor.red = 0.0f;
ClearColor.green = 0.0f;
ClearColor.blue = 0.0f;
ClearColor.alpha = 1.0f;
static FRGBAFloat ClearColor = {0.0f, 0.0f, 0.0f, 1.0f};
GL_ClearBuffer(true, false, false, &ClearColor);
}
@@ -5695,13 +5706,19 @@ void HWR_RenderPlayerView(void)
if (cv_ripplewater.value)
GL_SetShaderInfo(HWD_SHADERINFO_LEVELTIME, (INT32)leveltime); // The water surface shader needs the leveltime.
const angle_t light_angle = maplighting.angle - viewangle + ANGLE_90; // I fucking hate OGL's coordinate system
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_X, FINECOSINE(light_angle >> ANGLETOFINESHIFT));
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_Y, 0);
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_Z, -FINESINE(light_angle >> ANGLETOFINESHIFT));
if (cv_glmdls.value)
{
if (maplighting.directional)
{
const angle_t light_angle = maplighting.angle - viewangle + ANGLE_90; // I fucking hate OGL's coordinate system
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_X, FINECOSINE(light_angle >> ANGLETOFINESHIFT));
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_Y, 0);
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_Z, -FINESINE(light_angle >> ANGLETOFINESHIFT));
}
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_CONTRAST, maplighting.contrast);
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_BACKLIGHT, maplighting.backlight);
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_CONTRAST, maplighting.contrast);
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_BACKLIGHT, maplighting.backlight);
}
}
if (viewssnum > 3)
@@ -5725,42 +5742,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 +5750,6 @@ void HWR_LoadLevel(boolean reloadinggamestate)
HWR_ClearSkyDome();
HWR_BuildSkyDome();
if (!reloadinggamestate)
HWR_CheckForHorizonLines();
if (HWR_ShouldUsePaletteRendering())
HWR_SetMapPalette();
}
@@ -5844,7 +5823,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 +6018,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 -1
View File
@@ -35,7 +35,7 @@ static struct {
// Sprite shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
// Model shader
// Model shader + diffuse lighting from above
{GLSL_MODEL_LIGHTING_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
// Water shader
+2 -3
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;
}
}
@@ -2113,7 +2112,7 @@ static void GL_Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRG
UNIFORM_1(shader->uniforms[gluniform_lighting], (GLfloat)Surface->LightInfo.light_level, pglUniform1f);
UNIFORM_1(shader->uniforms[gluniform_fade_start], (GLfloat)Surface->LightInfo.fade_start, pglUniform1f);
UNIFORM_1(shader->uniforms[gluniform_fade_end], (GLfloat)Surface->LightInfo.fade_end, pglUniform1f);
directional = Surface->LightInfo.directional;
directional = cv_glmdls.value && Surface->LightInfo.directional;
}
else
{
+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);
+101 -17
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,12 +1643,22 @@ 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
V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap);
V_DrawChatCharacter(x + dx + 2, y+dy+cv_chatcentertext.value, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap);
}
dx += charwidth;
@@ -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
+150 -110
View File
@@ -1138,6 +1138,33 @@ static boolean K_UseColorSpeedo(int speedostyle)
}
}
enum
{
GAUGE_DEFAULT = 1,
GAUGE_SMALL,
GAUGE_BIGNUM,
GAUGE_NUMONLY,
GAUGE_EXTRA,
};
static SINT8 K_GetDriftgaugeStyle(void)
{
if (driftgaugegfx)
{
if (cv_driftgaugestyle.value == 1)
return GAUGE_DEFAULT;
else if (cv_driftgaugestyle.value == 2)
return GAUGE_SMALL;
else if (cv_driftgaugestyle.value == 3)
return GAUGE_BIGNUM;
else if (cv_driftgaugestyle.value == 5 && xtra_speedo3)
return GAUGE_EXTRA;
}
// Fallback
return GAUGE_NUMONLY; // (cv_driftgaugestyle.value == 4)
}
static boolean K_IsHighResolution(void)
{
return (vid.width >= 640 && vid.height >= 400);
@@ -1313,48 +1340,76 @@ static void K_drawKartStats(void)
spdxoffset = 0;
spdoffset = 0;
flags = V_SNAPTOBOTTOM|V_SNAPTOLEFT;
UINT8 splitnum = 0;
for (; splitnum < MAXSPLITSCREENPLAYERS; ++splitnum)
{
if (stplyrnum == splitnum)
break;
}
if (!LUA_HudEnabled(hud_statdisplay))
return;
flags = V_SNAPTOBOTTOM|V_SNAPTOLEFT;
//Internal offset for speedometer
const UINT8 speedostyle = K_GetSpeedometerStyle();
if (cv_kartspeedometer.value && (!splitscreen))
{
if ((speedostyle == SPEEDO_EXTRA) || (speedostyle == SPEEDO_ACHII) || (speedostyle == SPEEDO_EXTRA3))
spdoffset = -10;
else if (speedostyle == SPEEDO_DIAL)
switch (speedostyle)
{
spdxoffset = 11;
spdoffset = 14;
case SPEEDO_EXTRA:
case SPEEDO_ACHII:
case SPEEDO_EXTRA3:
spdoffset = -10;
break;
case SPEEDO_DIAL:
spdxoffset = 11;
spdoffset = 14;
break;
default:
spdoffset = -14;
break;
}
else
spdoffset = -14;
}
else
spdoffset = 0;
if ((speedostyle != SPEEDO_DIAL) || (splitscreen))
spdoffset += (G_BattleGametype() ? (stplyr->kartstuff[k_bumper] ? -5 : -8) : 0);
if (G_BattleGametype() && ((speedostyle != SPEEDO_DIAL) || splitscreen))
spdoffset += ((stplyr->kartstuff[k_bumper] ? -5 : -8));
// Customizations c:
if (!splitscreen)
{
skin_t *fakeskin;
INT32 flags2;
x += 18 + cv_stat_xoffset.value + spdxoffset;
y += cv_stat_yoffset.value + spdoffset;
flags |= V_HUDTRANS;
flags2 = flags|V_ALLOWLOWERCASE|V_SkinColorToHighlightcolor(stplyr->skincolor);
fakeskin = K_GetPlayerSkin(stplyr);
// Skin name
if (K_IsHighResolution()) // V_DrawSmallString becomes a mess at low resolutions lel
{
V_DrawSmallString(x+20, y+12, flags2, fakeskin->realname);
}
else
{
V_DrawThinString(x+20, y+7, flags2, fakeskin->realname);
}
// Icon and stats
if (K_UseHighResPortraits())
V_DrawSmallMappedPatch(x, y, flags, R_GetSkinFaceWant(stplyr), R_GetLocalTranslationColormap(fakeskin, fakeskin, stplyr->skincolor, GTC_CACHE, stplyr->skinlocal));
else
V_DrawMappedPatch(x, y, flags, R_GetSkinFaceRank(stplyr), R_GetLocalTranslationColormap(fakeskin, fakeskin, stplyr->skincolor, GTC_CACHE, stplyr->skinlocal));
V_DrawMappedPatch(x-3, y-2, flags, kp_facenum[min(9, max(1, stplyr->kartspeed))], R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_BLUEBERRY, GTC_CACHE));
V_DrawMappedPatch(x+10, y+10, flags, kp_facenum[min(9, max(1, stplyr->kartweight))], R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_BURGUNDY, GTC_CACHE));
return;
}
else if (splitscreen == 1) // I tried my best, but this is still mess :/ < :Blobcatpats: c:
if (splitscreen == 1) // I tried my best, but this is still mess :/ < :Blobcatpats: c:
{
x -= 10;
y -= 40;
@@ -1362,7 +1417,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,52 +1430,25 @@ 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 name
if (K_IsHighResolution()) // V_DrawSmallString becomes a mess at low resolutions lel
{
V_DrawSmallString(x+20, y+12, flags|V_ALLOWLOWERCASE|V_SkinColorToHighlightcolor(stplyr->skincolor), fakeskin->realname);
}
else
{
V_DrawThinString(x+20, y+7, flags|V_ALLOWLOWERCASE|V_SkinColorToHighlightcolor(stplyr->skincolor), fakeskin->realname);
}
// Icon and stats
if (K_UseHighResPortraits())
V_DrawSmallMappedPatch(x, y, flags, R_GetSkinFaceWant(stplyr), R_GetLocalTranslationColormap(fakeskin, fakeskin, stplyr->skincolor, GTC_CACHE, stplyr->skinlocal));
else
V_DrawMappedPatch(x, y, flags, R_GetSkinFaceRank(stplyr), R_GetLocalTranslationColormap(fakeskin, fakeskin, stplyr->skincolor, GTC_CACHE, stplyr->skinlocal));
V_DrawMappedPatch(x-3, y-2, flags, kp_facenum[min(9, max(1, stplyr->kartspeed))], R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_BLUEBERRY, GTC_CACHE));
V_DrawMappedPatch(x+10, y+10, flags, kp_facenum[min(9, max(1, stplyr->kartweight))], R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_BURGUNDY, GTC_CACHE));
}
else
{
// In splitscreen, just draw a string with stats
V_DrawString(x, y+10, flags, va("\x84%dS \x87%dW", stplyr->kartspeed, stplyr->kartweight));
}
// In splitscreen, just draw a string with stats
V_DrawString(x, y+10, flags, va("\x84%dS \x87%dW", stplyr->kartspeed, stplyr->kartweight));
}
static void K_drawKartItem(void)
@@ -1707,7 +1735,7 @@ static void K_drawKartItem(void)
switch (stplyr->kartstuff[k_itemblinkmode])
{
case 2:
localcolor = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
localcolor = K_RainbowColor();
break;
case 1:
localcolor = SKINCOLOR_RED;
@@ -1812,6 +1840,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 +2204,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 +2213,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 +2245,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 +2274,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.
@@ -3043,6 +3074,12 @@ static void K_drawNameTags(void)
else
flipped = players[i].mo->eflags & MFE_VERTICALFLIP;
#ifdef HWRENDER
// Needs extra offset. Not perfect but this will do for now
if (rendermode == render_opengl && !cv_glshearing.value && cv_smallnametags.value)
namey -= dup*6;
#endif
if (cv_smallnametags.value || !nametaggfx)
{
if (flipped)
@@ -3154,7 +3191,7 @@ static void K_drawDriftGauge(void)
fixed_t basex, basey;
const int dup = vid.dupx;
int i;
UINT8 *cmap;
UINT8 *colormap = NULL;
static const UINT8 driftcolors[3][4] = {
{0, 0, 10, 16}, // no drift
@@ -3168,7 +3205,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
};
@@ -3200,23 +3237,21 @@ skipcrap:
const INT32 driftcharge = min(driftval*4, stplyr->kartstuff[k_driftcharge]);
const INT32 driftlevel = min(driftcharge / driftval, 2);
const INT32 drifttrans = ((cv_driftgaugetrans.value) ? V_LocalTransFlag() : 0);
const SINT8 gaugestyle = K_GetDriftgaugeStyle();
basex = pos.x>>FRACBITS;
basey = pos.y>>FRACBITS;
switch (cv_driftgaugestyle.value)
switch (gaugestyle)
{
case 1:
case 2:
case 3:
case 5:
case GAUGE_DEFAULT:
case GAUGE_SMALL:
case GAUGE_EXTRA:
case GAUGE_BIGNUM:
{
if (!driftgaugegfx)
break;
patch_t *driftpatch = NULL;
const boolean usescaledpatch = (cv_driftgaugestyle.value == 5 && xtra_speedo3);
if (cv_driftgaugestyle.value == 1 || cv_driftgaugestyle.value == 3 || usescaledpatch)
if (gaugestyle == GAUGE_DEFAULT || gaugestyle == GAUGE_BIGNUM || gaugestyle == GAUGE_EXTRA)
{
barx = basex - dup*23;
BAR_WIDTH = dup*47;
@@ -3229,40 +3264,44 @@ skipcrap:
bary = basey - dup*2;
if (usescaledpatch) // i hate hud code i hate hud code i hate hud code i hate hud code i hate hud code.....
if (gaugestyle == GAUGE_EXTRA) // i hate hud code i hate hud code i hate hud code i hate hud code i hate hud code.....
{
if (K_UseColorSpeedo(SPEEDO_EXTRA3)) // Colourized hud
if (K_UseColorSpeedo(SPEEDO_EXTRA3)) // We reuse the extra speedometer patch hence this check
{
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE);
V_DrawStretchyFixedPatch((basex - dup*30)<<FRACBITS, ((basey<<FRACBITS) - FixedMul(dup<<FRACBITS, 21*FRACUNIT/10)), XTRA3PSCALE, XTRA3VSCALE, V_NOSCALESTART|V_OFFSET|drifttrans, skp_smallstickerclr3, colormap, 0);
colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE);
driftpatch = skp_smallstickerclr3;
}
else
V_DrawStretchyFixedPatch((basex - dup*30)<<FRACBITS, ((basey<<FRACBITS) - FixedMul(dup<<FRACBITS, 21*FRACUNIT/10)), XTRA3PSCALE, XTRA3VSCALE, V_NOSCALESTART|V_OFFSET|drifttrans, skp_smallsticker3, NULL, 0);
driftpatch = skp_smallsticker3;
V_DrawStretchyFixedPatch((basex - dup*30)<<FRACBITS, ((basey<<FRACBITS) - FixedMul(dup<<FRACBITS, 21*FRACUNIT/10)), XTRA3PSCALE, XTRA3VSCALE, V_NOSCALESTART|V_OFFSET|drifttrans, driftpatch, colormap, 0);
}
else
{
if (K_UseColorHud()) // Colourized hud
{
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE);
V_DrawMappedPatch(cv_driftgaugestyle.value == 2 ? basex + dup*11 : basex, basey, V_NOSCALESTART|V_OFFSET|drifttrans, cv_driftgaugestyle.value == 2 ? driftgaugesmallcolor : driftgaugecolor, colormap);
colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE);
driftpatch = (gaugestyle == GAUGE_SMALL ? driftgaugesmallcolor : driftgaugecolor);
}
else
V_DrawMappedPatch(cv_driftgaugestyle.value == 2 ? basex + dup*11 : basex, basey, V_NOSCALESTART|V_OFFSET|drifttrans, cv_driftgaugestyle.value == 2 ? driftgaugesmall : driftgauge, NULL);
driftpatch = (gaugestyle == GAUGE_SMALL ? driftgaugesmall : driftgauge);
V_DrawMappedPatch(gaugestyle == GAUGE_SMALL ? basex + dup*11 : basex, basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftpatch, colormap);
}
if (driftcharge >= driftval*4) // rainbow sparks
{
cmap = R_GetTranslationColormap(TC_RAINBOW, 1 + leveltime % (MAXSKINCOLORS-1),GTC_CACHE);
colormap = R_GetTranslationColormap(TC_RAINBOW, K_RainbowColor(), GTC_CACHE);
for (i = 0; i < 4; i++)
V_DrawFill(barx, bary+dup*1+dup*i, BAR_WIDTH, dup, (driftrainbow[min((leveltime % 18) + 1, 18 - 1)] + i*2) | V_NOSCALESTART|drifttrans);
V_DrawFill(barx, bary+dup*1+dup*i, BAR_WIDTH, dup, (driftrainbow[min((leveltime % 18) + 1, 17)] + i*2) | V_NOSCALESTART|drifttrans);
}
else // none/blue/red
{
const INT32 limit = (driftval * (driftcharge >= driftval*2 ? 2 : 1));
const INT32 width = ((driftcharge - (driftcharge >= driftval ? limit : 0)) * BAR_WIDTH) / limit;
cmap = R_GetTranslationColormap(TC_RAINBOW, driftskins[driftlevel],GTC_CACHE);
colormap = R_GetTranslationColormap(TC_RAINBOW, driftskins[driftlevel], GTC_CACHE);
for (i = 0; i < 4; i++)
{
@@ -3274,21 +3313,20 @@ 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);
if (gaugestyle == GAUGE_BIGNUM)
V_DrawPaddedTallColorNum(basex + (dup*32), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, 3, colormap);
else
V_DrawPingNum(cv_driftgaugestyle.value == 2 ? basex + (dup*22) : basex + (dup*32), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, cmap);
V_DrawPingNum((gaugestyle == GAUGE_SMALL ? basex + (dup*22) : basex + (dup*32)), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, colormap);
}
break;
case 4:
case GAUGE_NUMONLY:
{
cmap = R_GetTranslationColormap(TC_RAINBOW, driftskins[driftlevel],GTC_CACHE);
if (driftcharge >= driftval*4)
cmap = R_GetTranslationColormap(TC_RAINBOW, 1 + leveltime % (MAXSKINCOLORS-1),GTC_CACHE);
colormap = R_GetTranslationColormap(TC_RAINBOW, K_RainbowColor(), GTC_CACHE);
else
colormap = R_GetTranslationColormap(TC_RAINBOW, driftskins[driftlevel], GTC_CACHE);
V_DrawPaddedTallColorNum(basex + (dup*16), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, 3, cmap);
V_DrawPaddedTallColorNum(basex + (dup*16), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, 3, colormap);
}
break;
default:
@@ -3305,6 +3343,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;
@@ -3348,6 +3387,7 @@ static void K_drawKartWanted(void)
{
basex = WANT_X;
basey = WANT_Y;
if (splitscreen == 2)
{
basey += 16; // slight adjust for 3P
@@ -3404,17 +3444,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 +3569,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 +4002,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;
@@ -4100,17 +4137,23 @@ static void K_drawKartFirstPerson(void)
x -= xoffs;
else
x += xoffs;
if (!splitscreen)
y += yoffs;
}
const INT32 driftcharge = stplyr->kartstuff[k_driftcharge];
// drift sparks!
if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dsthree))
colmap = R_GetTranslationColormap(TC_RAINBOW, (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))), GTC_CACHE);
else if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dstwo))
colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_KETCHUP, GTC_CACHE);
else if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dsone))
colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SAPPHIRE, GTC_CACHE);
if ((leveltime & 1) && driftcharge)
{
if (driftcharge >= dsthree)
colmap = R_GetTranslationColormap(TC_RAINBOW, K_RainbowColor(), GTC_CACHE);
else if (driftcharge >= dstwo)
colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_KETCHUP, GTC_CACHE);
else if (driftcharge >= dsone)
colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SAPPHIRE, GTC_CACHE);
}
else
#endif
// invincibility/grow/shrink!
@@ -4139,7 +4182,7 @@ static void K_drawInput(void)
const UINT8 hudcolor = K_GetHudColor();
const INT32 accent1 = splitflags|colortranslations[hudcolor][5];
const INT32 accent2 = splitflags|colortranslations[hudcolor][9];
const INT32 accent2 = splitflags|colortranslations[hudcolor][7];
const UINT8 *hudcolormap = R_GetTranslationColormap(0, hudcolor, GTC_CACHE);
const ticcmd_t *cmd = &stplyr->cmd;
@@ -4386,10 +4429,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 +4542,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 +4805,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);
+113 -44
View File
@@ -484,6 +484,15 @@ UINT8 colortranslations[MAXTRANSLATIONS][16] = {
{120, 120, 96, 96, 97, 98, 98, 99, 81, 81, 69, 71, 73, 75, 77, 79}, // SKINCOLOR_CSUPER5
};
//
// Gives you a color to use for rainbow effects (like invincibility).
// Return: Skincolor value.
//
UINT8 K_RainbowColor(void)
{
return (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
}
// Define for getting accurate color brightness readings according to how the human eye sees them.
// https://en.wikipedia.org/wiki/Relative_luminance
// 0.2126 to red
@@ -551,26 +560,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 +603,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;
@@ -619,36 +654,46 @@ UINT8 K_GetKartColorByName(const char *name)
return 0;
}
//
// returns the players skinnumber
// accounts for localskins
//
INT32 K_GetSkinNum(player_t *player)
{
return player->localskin ? (player->localskin - 1) : player->skin;
}
//
// returns the mobj skinnumber
// accounts for localskins
//
INT32 K_GetMobjSkinNum(const skin_t *skin, boolean local)
{
return skin - K_GetSkinArray(local);
}
//
// returns the players skinnumber
// accounts for localskins
//
skin_t *K_GetMobjSkin(const mobj_t *mobj)
{
return mobj->localskin ? mobj->localskin : mobj->skin;
}
//
// returns the skin array to use
// accounts for localskins
//
skin_t *K_GetSkinArray(boolean local)
{
return local ? localskins : skins;
}
//
// returns the players skin
// accounts for localskins
//
skin_t *K_GetPlayerSkin(player_t *player)
{
return &K_GetSkinArray(player->skinlocal)[K_GetSkinNum(player)];
@@ -1586,7 +1631,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 +1715,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 +1948,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 +1974,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 +1987,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 +1994,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 +2231,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 +2268,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 +2379,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 +2520,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 +2636,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 +2722,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;
@@ -3048,7 +3103,7 @@ static UINT16 K_DriftSparkColor(player_t *player, INT32 charge)
if (charge >= K_GetKartDriftSparkValue(player)*4)
{
color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
color = K_RainbowColor();
}
else if (charge >= K_GetKartDriftSparkValue(player)*2)
{
@@ -3540,11 +3595,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 +3661,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 +3697,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 +3958,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 +3994,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 +4208,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 +5096,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 +5293,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))
@@ -5325,7 +5390,7 @@ static UINT8 K_GetSpeedLineColor(player_t *player, boolean colorSpeed)
else if (player->kartstuff[k_driftboost] <= 50)
speedcolor = SKINCOLOR_RASPBERRY;
else if (player->kartstuff[k_driftboost] <= 125)
speedcolor = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
speedcolor = K_RainbowColor();
if (cv_coloredspeedlines.value == 2)
speedcolor = (leveltime & 1) ? playercolor : speedcolor;
@@ -5772,7 +5837,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 +5848,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 +5860,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 +5881,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 +6286,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 +6866,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
+1
View File
@@ -19,6 +19,7 @@ extern "C" {
extern UINT8 colortranslations[MAXTRANSLATIONS][16];
extern const char *KartColor_Names[MAXSKINCOLORS];
extern const UINT8 KartColor_Opposite[MAXSKINCOLORS*2];
UINT8 K_RainbowColor(void);
void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor);
void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color, boolean local);
UINT8 K_GetKartColorByName(const char *name);
+6
View File
@@ -66,6 +66,7 @@
X (IntermissionThinker),/* Y_Ticker */\
X (VoteThinker),/*SRB2KART*/\
X (ServerJoin),/* SRB2KART - Saturn 32p*/\
X (SetupVote),/*SRB2KART - Saturn*/
#define STRING_HOOK_LIST(X) \
X (BotAI),/* B_BuildTailsTiccmd by skin name */\
@@ -140,3 +141,8 @@ int LUA_HookShouldSquish(player_t *player, mobj_t *inflictor, mobj_t *source); /
boolean LUA_HookPlayerSpin(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_SpinPlayer. Allows Lua to execute code and/or overwrite its behavior.
boolean LUA_HookPlayerExplode(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_ExplodePlayer. Allows Lua to execute code and/or overwrite its behavior.
boolean LUA_HookPlayerSquish(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_SquishPlayer. Allows Lua to execute code and/or overwrite its behavior.
// SRB2KART - Saturn: Allows changing vote level picks
// (note: function format in lua doesn't include maxresults, so its function(result, gametype, secondgametype, prevmap)
// to get maxresults use #result)
void LUA_HookSetupVote(INT16 result[], INT16 maxresults, UINT8 gt, UINT8 secondgt);
+52 -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;
@@ -1132,3 +1138,43 @@ boolean LUA_HookPlayerExplode(player_t *player, mobj_t *inflictor, mobj_t *sourc
{
return kartdamage_hook(player, inflictor, source, HOOK(PlayerExplode), res_true);
}
void LUA_HookSetupVote(INT16 result[], INT16 maxresults, UINT8 gt, UINT8 secondgt)
{
Hook_State hook;
if (prepare_hook(&hook, 0, HOOK(SetupVote)))
{
// { 0, 0, 0, 0, }
lua_newtable(gL);
for (int i = 1; i <= maxresults; ++i)
{
lua_pushinteger(gL, 0);
lua_rawseti(gL, -2, i);
}
// call_hooks does lua_settop(gL, 0) so we need to store our table somewhere
lua_pushvalue(gL, -1);
lua_setfield(gL, LUA_REGISTRYINDEX, "SetupVoteResults");
lua_pushinteger(gL, gt);
lua_pushinteger(gL, secondgt);
lua_pushinteger(gL, prevmap+1); // prevmap is gamemap-1 so we offset it back
call_hooks(&hook, 0, res_none);
lua_getfield(gL, LUA_REGISTRYINDEX, "SetupVoteResults");
for (int i = 1; i <= maxresults; ++i)
{
lua_rawgeti(gL, -1, i);
result[i-1] = lua_tointeger(gL, -1);
lua_pop(gL, 1);
if (result[i-1] && (result[i-1] < 0 || !mapheaderinfo[result[i-1]-1]))
{
CONS_Alert(CONS_WARNING, "Unknown map #%d for vote\n", result[i-1]);
result[i-1] = 0;
}
}
lua_pop(gL, 1);
}
}
+15 -10
View File
@@ -24,6 +24,7 @@
#include "p_slopes.h" // for P_SlopeById
#include "s_sound.h"
#include "m_menu.h"
#include "m_argv.h"
#ifdef LUA_ALLOW_BYTECODE
#include "d_netfil.h" // for LUA_DumpFile
#endif
@@ -252,7 +253,11 @@ static inline void LUA_LoadFile(MYFILE *f, char *name)
lua_pushcfunction(gL, LUA_GetErrorMessage);
if (luaL_loadbuffer(gL, f->data, f->size, va("@%s",name)) || lua_pcall(gL, 0, 0, lua_gettop(gL) - 1)) {
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
if (M_CheckParm("-strict") || M_CheckParm("-strict-lua"))
I_Error("Lua error: %s", lua_tostring(gL, -1));
else
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
lua_pop(gL,1);
}
lua_gc(gL, LUA_GCCOLLECT, 0);
@@ -1023,8 +1028,8 @@ static UINT8 UnArchiveValue(UINT8 **p, int TABLESINDEX, boolean network)
case ARCH_MOBJ:
if (network == false) // for replays :chaosleep:
{
*p += sizeof(UINT32); // Skip this data, we can't read a mobj here, it'd point to garbage and crash the game.
return 3; // Don't set the field
*p += sizeof(UINT32); // Skip this data, we can't read a mobj here, it'd point to garbage and crash the game.
return 3; // Don't set the field
}
LUA_PushUserdata(gL, P_FindNewPosition(READUINT32(*p)), META_MOBJ);
@@ -1099,9 +1104,9 @@ static void UnArchiveExtVars(UINT8 **p, void *pointer, boolean network)
CONS_Alert(CONS_ERROR, "Unexpected end marker when reading ExtVars (field '%s')\n", field);
break;
}
else if (ret == 3) // This will return 3 if we shouldn't set this field.
else if (ret == 3) // This will return 3 if we shouldn't set this field.
{
CONS_Alert(CONS_WARNING,"Cannot read mobj_t stored in player variable \'%s\'. Desyncs may occur.\n", field);
//CONS_Alert(CONS_WARNING,"Cannot read mobj_t stored in player variable \'%s\'. Desyncs may occur.\n", field);
continue;
}
@@ -1155,7 +1160,7 @@ static void UnArchiveTables(UINT8 **p, boolean network)
ret = UnArchiveValue(p, TABLESINDEX, network);
if (ret == 3)
{
CONS_Alert(CONS_WARNING,"Couldn't read mobj_t\n");
//CONS_Alert(CONS_WARNING,"Couldn't read mobj_t\n");
lua_pushnil(gL);
}
else if (ret == 1) // read key
@@ -1170,7 +1175,7 @@ static void UnArchiveTables(UINT8 **p, boolean network)
}
else if (ret == 3)
{
CONS_Alert(CONS_WARNING,"Couldn't read mobj_t\n");
//CONS_Alert(CONS_WARNING,"Couldn't read mobj_t\n");
lua_pushnil(gL);
}
else if (ret == 2) // read value
@@ -1189,7 +1194,7 @@ static void UnArchiveTables(UINT8 **p, boolean network)
}
}
void LUA_Step(void)
/*void LUA_Step(void)
{
if (!gL)
return;
@@ -1200,7 +1205,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 +1217,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__
+294 -3613
View File
File diff suppressed because it is too large. Load diff
+2947
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];
+1 -1
View File
@@ -96,7 +96,7 @@ ATTRINLINE static fixed_t FUNCINLINE __internal_prng__(void)
randomseed ^= randomseed >> 13;
randomseed ^= randomseed >> 11;
randomseed ^= randomseed << 21;
return ( (randomseed*36548569) >> 4) & (FRACUNIT-1);
return ((randomseed*36548569) >> 4) & (FRACUNIT-1);
}
/** Provides a random fixed point number. Distribution is uniform.
+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));
}
+7 -3
View File
@@ -128,6 +128,9 @@ typedef struct camera_s
// SRB2Kart: camera pans while drifting
fixed_t pan;
// SRB2Kart: camera pitches on slopes
angle_t pitch;
// postproccess effects
UINT8 postimg;
} camera_t;
@@ -144,9 +147,11 @@ enum
extern camera_t camera[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_dist[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_still[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_height[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_pitch[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_speed[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_lookbackmom[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_still[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_rotate[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_timeover[MAXSPLITSCREENPLAYERS];
@@ -160,8 +165,6 @@ extern consvar_t cv_actionmovie;
extern consvar_t cv_screenquake;
extern consvar_t cv_lookbackmom[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_verticallook[MAXSPLITSCREENPLAYERS];
extern fixed_t t_cam_rotate[MAXSPLITSCREENPLAYERS];
@@ -180,6 +183,7 @@ void P_CalcChasePostImg(player_t *player, camera_t *thiscam);
boolean P_PlayerInPain(player_t *player);
void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor);
void P_ResetPlayer(player_t *player);
player_t *P_GetLocalPlayerForNum(UINT8 pnum);
boolean P_IsLocalPlayer(const player_t *player);
boolean P_IsDisplayPlayer(const player_t *player);
+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);
+60 -46
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;
@@ -6955,7 +6964,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj)
if (mobj->flags2 & MF2_AMBUSH)
{
mobj->colorized = true;
mobj->color = (1 + (leveltime % (MAXSKINCOLORS-1)));
mobj->color = K_RainbowColor();
mobj->frame |= FF_FULLBRIGHT;
}
else
@@ -7797,7 +7806,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
P_SetScale(mobj, (mobj->destscale = mobj->target->scale));
if (mobj->target->player->kartstuff[k_driftcharge] >= K_GetKartDriftSparkValue(mobj->target->player)*4)
mobj->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
mobj->color = K_RainbowColor();
else if (mobj->target->player->kartstuff[k_driftcharge] >= K_GetKartDriftSparkValue(mobj->target->player)*2)
mobj->color = SKINCOLOR_KETCHUP;
else if (mobj->target->player->kartstuff[k_driftcharge] >= K_GetKartDriftSparkValue(mobj->target->player))
@@ -8496,7 +8505,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (mobj->flags2 & MF2_AMBUSH)
{
mobj->colorized = true;
mobj->color = (1 + (leveltime % (MAXSKINCOLORS-1)));
mobj->color = K_RainbowColor();
mobj->frame |= FF_FULLBRIGHT;
}
else
@@ -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;
@@ -9844,7 +9854,6 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster)
mobj->radius = info->radius;
mobj->height = info->height;
mobj->flags = info->flags;
mobj->blendmode = AST_TRANSLUCENT;
mobj->health = info->spawnhealth;
@@ -9880,7 +9889,10 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster)
}
// Sprite rendering
mobj->spritexscale = mobj->spriteyscale = mobj->scale;
mobj->blendmode = AST_TRANSLUCENT;
mobj->realxscale = mobj->realyscale = mobj->scale;
mobj->spritexscale = mobj->realxscale;
mobj->spriteyscale = mobj->realyscale;
// set subsector and/or block links
P_SetThingPosition(mobj);
@@ -9982,6 +9994,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 +10326,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 +10339,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 +10350,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 +10358,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 +10374,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 +10394,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 +10402,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);
}
}
+1 -1
View File
@@ -1511,7 +1511,7 @@ static polyobj_t *Polyobj_GetParent(polyobj_t *po)
// Iteratively retrieves the children POs of a parent,
// sorta like P_FindSectorSpecialFromTag.
//
static polyobj_t *Polyobj_GetChild(polyobj_t *po, INT32 *start)
polyobj_t *Polyobj_GetChild(polyobj_t *po, INT32 *start)
{
for (; *start < numPolyObjects; (*start)++)
{
+1
View File
@@ -269,6 +269,7 @@ typedef struct polydisplacedata_s
//
polyobj_t *Polyobj_GetForNum(INT32 id);
polyobj_t *Polyobj_GetChild(polyobj_t *po, INT32 *start);
void Polyobj_InitLevel(void);
void Polyobj_MoveOnLoad(polyobj_t *po, angle_t angle, fixed_t x, fixed_t y);
boolean P_PointInsidePolyobj(polyobj_t *po, fixed_t x, fixed_t y);
+119
View File
@@ -2234,6 +2234,12 @@ static void LoadSpecialLevelThinker(savebuffer_t *save, actionf_p1 thinker, UINT
}
P_AddThinker(&ht->thinker);
// interpolation
if (floorOrCeiling & 2)
R_CreateInterpolator_SectorPlane(&ht->thinker, ht->sector, true);
if (floorOrCeiling & 1)
R_CreateInterpolator_SectorPlane(&ht->thinker, ht->sector, false);
}
//
@@ -2263,6 +2269,9 @@ static void LoadCeilingThinker(savebuffer_t *save, actionf_p1 thinker)
if (ht->sector)
ht->sector->ceilingdata = ht;
P_AddThinker(&ht->thinker);
// interpolation
R_CreateInterpolator_SectorPlane(&ht->thinker, ht->sector, true);
}
//
@@ -2287,6 +2296,9 @@ static void LoadFloormoveThinker(savebuffer_t *save, actionf_p1 thinker)
if (ht->sector)
ht->sector->floordata = ht;
P_AddThinker(&ht->thinker);
// interpolation
R_CreateInterpolator_SectorPlane(&ht->thinker, ht->sector, false);
}
//
@@ -2400,6 +2412,12 @@ static void LoadElevatorThinker(savebuffer_t *save, actionf_p1 thinker, UINT8 fl
}
P_AddThinker(&ht->thinker);
// interpolation
if (floorOrCeiling & 2)
R_CreateInterpolator_SectorPlane(&ht->thinker, ht->sector, true);
if (floorOrCeiling & 1)
R_CreateInterpolator_SectorPlane(&ht->thinker, ht->sector, false);
}
//
@@ -2422,6 +2440,22 @@ static void LoadScrollThinker(savebuffer_t *save, actionf_p1 thinker)
ht->exclusive = READINT32(save->p);
ht->type = READUINT8(save->p);
P_AddThinker(&ht->thinker);
// interpolation
switch (ht->type)
{
case sc_side:
R_CreateInterpolator_SideScroll(&ht->thinker, &sides[ht->affectee]);
break;
case sc_floor:
R_CreateInterpolator_SectorScroll(&ht->thinker, &sectors[ht->affectee], false);
break;
case sc_ceiling:
R_CreateInterpolator_SectorScroll(&ht->thinker, &sectors[ht->affectee], true);
break;
default:
break;
}
}
//
@@ -2553,6 +2587,17 @@ static inline void LoadPolyrotatetThinker(savebuffer_t *save, actionf_p1 thinker
ht->distance = READINT32(save->p);
ht->turnobjs = READUINT8(save->p);
P_AddThinker(&ht->thinker);
// interpolation
polyobj_t *po;
if (!(po = Polyobj_GetForNum(ht->polyObjNum)))
{
CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", ht->polyObjNum);
return;
}
R_CreateInterpolator_Polyobj(&ht->thinker, po);
}
//
@@ -2571,6 +2616,17 @@ static void LoadPolymoveThinker(savebuffer_t *save, actionf_p1 thinker)
ht->distance = READINT32(save->p);
ht->angle = READANGLE(save->p);
P_AddThinker(&ht->thinker);
// interpolation
polyobj_t *po;
if (!(po = Polyobj_GetForNum(ht->polyObjNum)))
{
CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", ht->polyObjNum);
return;
}
R_CreateInterpolator_Polyobj(&ht->thinker, po);
}
//
@@ -2595,6 +2651,36 @@ static inline void LoadPolywaypointThinker(savebuffer_t *save, actionf_p1 thinke
ht->diffy = READFIXED(save->p);
ht->diffz = READFIXED(save->p);
P_AddThinker(&ht->thinker);
// interpolation
polyobj_t *po;
polyobj_t *oldpo;
INT32 start;
if (!(po = Polyobj_GetForNum(ht->polyObjNum)))
{
CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", ht->polyObjNum);
return;
}
R_CreateInterpolator_Polyobj(&ht->thinker, po);
// T_PolyObjWaypoint is the only polyobject movement
// that can adjust z, so we add these ones too.
R_CreateInterpolator_SectorPlane(&ht->thinker, po->lines[0]->backsector, false);
R_CreateInterpolator_SectorPlane(&ht->thinker, po->lines[0]->backsector, true);
// Most other polyobject functions handle children by recursively
// giving each child another thinker. T_PolyObjWaypoint handles
// it manually though, which means we need to manually give them
// interpolation here instead.
start = 0;
oldpo = po;
while ((po = Polyobj_GetChild(oldpo, &start)))
{
R_CreateInterpolator_Polyobj(&ht->thinker, po);
R_CreateInterpolator_SectorPlane(&ht->thinker, po->lines[0]->backsector, false);
R_CreateInterpolator_SectorPlane(&ht->thinker, po->lines[0]->backsector, true);
}
}
//
@@ -2620,6 +2706,17 @@ static inline void LoadPolyslidedoorThinker(savebuffer_t *save, actionf_p1 think
ht->momy = READFIXED(save->p);
ht->closing = READUINT8(save->p);
P_AddThinker(&ht->thinker);
// interpolation
polyobj_t *po;
if (!(po = Polyobj_GetForNum(ht->polyObjNum)))
{
CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", ht->polyObjNum);
return;
}
R_CreateInterpolator_Polyobj(&ht->thinker, po);
}
//
@@ -2640,6 +2737,17 @@ static inline void LoadPolyswingdoorThinker(savebuffer_t *save, actionf_p1 think
ht->distance = READINT32(save->p);
ht->closing = READUINT8(save->p);
P_AddThinker(&ht->thinker);
// interpolation
polyobj_t *po;
if (!(po = Polyobj_GetForNum(ht->polyObjNum)))
{
CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", ht->polyObjNum);
return;
}
R_CreateInterpolator_Polyobj(&ht->thinker, po);
}
//
@@ -2657,6 +2765,17 @@ static inline void LoadPolydisplaceThinker(savebuffer_t *save, actionf_p1 thinke
ht->dy = READFIXED(save->p);
ht->oldHeights = READFIXED(save->p);
P_AddThinker(&ht->thinker);
// interpolation
polyobj_t *po;
if (!(po = Polyobj_GetForNum(ht->polyObjNum)))
{
CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", ht->polyObjNum);
return;
}
R_CreateInterpolator_Polyobj(&ht->thinker, po);
}
//
+62 -61
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
@@ -441,7 +442,7 @@ void P_UpdateSegLightOffset(seg_t *li)
extralight = -contrastFixed + FixedMul(light, contrastFixed * 2);
// Between -2 and 2 for software, -8 and 8 for hardware
// Between -1 and 1 for software, -8 and 8 for hardware
li->lightOffset = FixedFloor((extralight / 8) + (FRACUNIT / 2)) / FRACUNIT;
#ifdef HWRENDER
li->hwLightOffset = FixedFloor(extralight + (FRACUNIT / 2)) / FRACUNIT;
@@ -536,7 +537,6 @@ static void P_SetupDirectionalLight(void)
oldmap = gamemap;
oldencore = encoremode;
return;
}
maplighting.contrast = lighting->light_contrast;
@@ -649,6 +649,27 @@ size_t P_PrecacheLevelFlats(void)
return flatmem;
}
// check if our flat contains cyan pixels
// not sure if this is the best way to do it but it works
static void P_CheckCyanFlat(levelflat_t *levelflat)
{
// only need this for software
if (rendermode != render_soft)
return;
const UINT8 *flat = R_GetFlat(levelflat->lumpnum);
const size_t size = W_LumpLength(levelflat->lumpnum);
for (size_t steppy = 0; steppy < size; steppy++)
{
if (flat[steppy] == TRANSPARENTPIXEL)
{
levelflat->cyan = true;
break;
}
}
}
// help function for P_LoadSectors, find a flat in the active wad files,
// allocate an id for it, and set the levelflat (to speedup search)
//
@@ -660,7 +681,7 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat)
// first scan through the already found flats
//
for (i = 0; i < numlevelflats; i++, levelflat++)
if (strnicmp(levelflat->name,flatname,8) == 0)
if (strnicmp(levelflat->name, flatname, 8) == 0)
break;
// that flat was already found in the level, return the id
@@ -674,20 +695,7 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat)
levelflat->lumpnum = R_GetFlatNumForName(flatname);
levelflat->baselumpnum = LUMPERROR;
// check if our flat contains cyan pixels
// not sure if this is the best way to do it but it works
{
const UINT8 *flat = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_LEVEL);
size_t size = W_LumpLength(levelflat->lumpnum);
for (size_t steppy = 0; steppy < size; steppy++)
{
if (flat[steppy] == TRANSPARENTPIXEL)
{
levelflat->cyan = true;
break;
}
}
}
P_CheckCyanFlat(levelflat);
#ifndef ZDEBUG
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
@@ -734,20 +742,7 @@ INT32 P_AddLevelFlatRuntime(const char *flatname)
levelflat->lumpnum = R_GetFlatNumForName(flatname);
levelflat->baselumpnum = LUMPERROR;
// check if our flat contains cyan pixels
// not sure if this is the best way to do it but it works
{
const UINT8 *flat = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_LEVEL);
size_t size = W_LumpLength(levelflat->lumpnum);
for (size_t steppy = 0; steppy < size; steppy++)
{
if (flat[steppy] == TRANSPARENTPIXEL)
{
levelflat->cyan = true;
break;
}
}
}
P_CheckCyanFlat(levelflat);
#ifndef ZDEBUG
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
@@ -1752,33 +1747,33 @@ static void P_CreateBlockMap(void)
// Now we simply iterate block-by-block until we reach the end block.
for (curblockx = bxstart; curblockx <= bxend; curblockx++)
for (curblocky = bystart; curblocky <= byend; curblocky++)
{
size_t b = curblocky * bmapwidth + curblockx;
if (b >= tot)
continue;
if (!straight && !(LineInBlock((fixed_t)x, (fixed_t)y, (fixed_t)v2x, (fixed_t)v2y, (fixed_t)(curblockx << MAPBTOFRAC), (fixed_t)(curblocky << MAPBTOFRAC))))
continue;
// Increase size of allocated list if necessary
if (bmap[b].n >= bmap[b].nalloc)
for (curblocky = bystart; curblocky <= byend; curblocky++)
{
// Graue 02-29-2004: make code more readable, don't realloc a null pointer
// (because it crashes for me, and because the comp.lang.c FAQ says so)
if (bmap[b].nalloc == 0)
bmap[b].nalloc = 8;
else
bmap[b].nalloc *= 2;
bmap[b].list = Z_Realloc(bmap[b].list, bmap[b].nalloc * sizeof (*bmap->list), PU_CACHE, &bmap[b].list);
if (!bmap[b].list)
I_Error("Out of Memory in P_CreateBlockMap");
}
size_t b = curblocky * bmapwidth + curblockx;
// Add linedef to end of list
bmap[b].list[bmap[b].n++] = (INT32)i;
}
if (b >= tot)
continue;
if (!straight && !(LineInBlock((fixed_t)x, (fixed_t)y, (fixed_t)v2x, (fixed_t)v2y, (fixed_t)(curblockx << MAPBTOFRAC), (fixed_t)(curblocky << MAPBTOFRAC))))
continue;
// Increase size of allocated list if necessary
if (bmap[b].n >= bmap[b].nalloc)
{
// Graue 02-29-2004: make code more readable, don't realloc a null pointer
// (because it crashes for me, and because the comp.lang.c FAQ says so)
if (bmap[b].nalloc == 0)
bmap[b].nalloc = 8;
else
bmap[b].nalloc *= 2;
bmap[b].list = Z_Realloc(bmap[b].list, bmap[b].nalloc * sizeof (*bmap->list), PU_CACHE, &bmap[b].list);
if (!bmap[b].list)
I_Error("Out of Memory in P_CreateBlockMap");
}
// Add linedef to end of list
bmap[b].list[bmap[b].n++] = (INT32)i;
}
}
// Compute the total size of the blockmap.
@@ -2572,6 +2567,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 +3004,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 +3066,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++)
{
@@ -3337,6 +3332,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 +3347,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;
}
+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)
+44 -56
View File
@@ -16,6 +16,7 @@
#endif
#include "doomstat.h"
#include "dehacked.h"
#include "g_game.h"
#include "g_input.h"
#include "p_local.h"
@@ -190,7 +191,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 +462,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 +476,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 = P_GetLocalPlayerForNum(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 +509,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 +534,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 +552,7 @@ static void P_DeviceRumbleTick(void)
continue;
}
G_PlayerDeviceRumble(i, low, high, 57);
G_PlayerDeviceRumble(i, low, high, lenght);
}
}
@@ -556,7 +567,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,32 +614,6 @@ static void P_RunQuakes(void)
--quake.time;
}
static inline void P_ResetSpriteStuff(void)
{
thinker_t *th;
if (rendermode == render_none)
return;
for (th = thinkercap.next; th != &thinkercap; th = th->next)
{
mobj_t *mo;
if (th->function != (actionf_p1)P_MobjThinker) // not a mobj
continue;
mo = (mobj_t *)th;
if (!mo || (mo->sprite == SPR_NULL) || (mo->flags2 & MF2_DONTDRAW) || (mo->type == MT_SHADOW))
continue;
mo->spritexscale = mo->realxscale;
mo->spriteyscale = mo->realyscale;
mo->spritexoffset = mo->realxoffset;
mo->spriteyoffset = mo->realyoffset;
}
}
//
// P_Ticker
//
@@ -692,9 +681,9 @@ void P_Ticker(boolean run)
if (playeringame[i])
G_WriteDemoTiccmd(&players[i].cmd, i);
}
if (demo.playback)
{
#ifdef DEMO_COMPAT_100
if (demo.version == 0x0001)
{
@@ -726,8 +715,6 @@ void P_Ticker(boolean run)
ps_lua_mobjhooks.value.i = 0;
ps_checkposition_calls.value.i = 0;
P_ResetSpriteStuff();
PS_START_TIMING(ps_lua_prethinkframe_time);
LUA_HookPreThinkFrame();
PS_STOP_TIMING(ps_lua_prethinkframe_time);
@@ -735,8 +722,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 +746,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 +828,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 +949,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]);
+140 -62
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);
@@ -972,6 +972,17 @@ fixed_t P_GetPlayerSpinHeight(player_t *player)
return FixedMul(FixedMul(player->mo->info->height, player->mo->scale),2*FRACUNIT/3);
}
//
// P_GetLocalPlayerForNum
//
// Returns the player
// on the local machine for given number.
//
player_t *P_GetLocalPlayerForNum(UINT8 pnum)
{
return (pnum == 0 ? &players[consoleplayer] : &players[displayplayers[pnum]]);
}
//
// P_IsLocalPlayer
//
@@ -1287,13 +1298,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))
@@ -1640,7 +1652,7 @@ static void P_CheckInvincibilityTimer(player_t *player)
if (!player->powers[pw_invulnerability] && !player->kartstuff[k_invincibilitytimer])
return;
player->mo->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
player->mo->color = K_RainbowColor();
// Resume normal music stuff.
if (player->powers[pw_invulnerability] == 1 || player->kartstuff[k_invincibilitytimer] == 1)
@@ -1682,6 +1694,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 +1702,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 +2172,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 +2232,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 +2271,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 +2332,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 +2360,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 +2721,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!
@@ -2990,21 +3003,28 @@ static void CV_PlayerCam4_OnChange(void)
}
consvar_t cv_cam_dist[MAXSPLITSCREENPLAYERS] = {
{"cam_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam1_OnChange, 0, NULL, NULL, 0, 0, NULL},
{"cam_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam1_OnChange, 0, NULL, NULL, 0, 0, NULL},
{"cam2_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam2_OnChange, 0, NULL, NULL, 0, 0, NULL},
{"cam3_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam3_OnChange, 0, NULL, NULL, 0, 0, NULL},
{"cam4_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam4_OnChange, 0, NULL, NULL, 0, 0, NULL}
};
consvar_t cv_cam_height[MAXSPLITSCREENPLAYERS] = {
{"cam_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam1_OnChange, 0, NULL, NULL, 0, 0, NULL},
{"cam_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam1_OnChange, 0, NULL, NULL, 0, 0, NULL},
{"cam2_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam2_OnChange, 0, NULL, NULL, 0, 0, NULL},
{"cam3_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam3_OnChange, 0, NULL, NULL, 0, 0, NULL},
{"cam4_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam4_OnChange, 0, NULL, NULL, 0, 0, NULL},
};
consvar_t cv_cam_pitch[MAXSPLITSCREENPLAYERS] = {
{"cam_pitch", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cam2_pitch", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cam3_pitch", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cam4_pitch", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}
};
consvar_t cv_cam_still[MAXSPLITSCREENPLAYERS] = {
{"cam_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cam_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cam2_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cam3_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cam4_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}
@@ -3012,7 +3032,7 @@ consvar_t cv_cam_still[MAXSPLITSCREENPLAYERS] = {
static CV_PossibleValue_t cam_speed_cons_t[] = {{0, "MIN"}, {1*FRACUNIT, "MAX"}, {0, NULL}};
consvar_t cv_cam_speed[MAXSPLITSCREENPLAYERS] = {
{"cam_speed", "0.4", CV_FLOAT|CV_SAVE, cam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cam_speed", "0.4", CV_FLOAT|CV_SAVE, cam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cam2_speed", "0.4", CV_FLOAT|CV_SAVE, cam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cam3_speed", "0.4", CV_FLOAT|CV_SAVE, cam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cam4_speed", "0.4", CV_FLOAT|CV_SAVE, cam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}
@@ -3021,14 +3041,14 @@ consvar_t cv_cam_speed[MAXSPLITSCREENPLAYERS] = {
static CV_PossibleValue_t cam_rotate_cons_t[] = {{-720, "MIN"}, {720, "MAX"}, {0, NULL}};
consvar_t cv_cam_rotate[MAXSPLITSCREENPLAYERS] = {
{"cam_rotate", "0", CV_CALL|CV_NOINIT, cam_rotate_cons_t, CV_CamRotate_OnChange, 0, NULL, NULL, 0, 0, NULL},
{"cam_rotate", "0", CV_CALL|CV_NOINIT, cam_rotate_cons_t, CV_CamRotate_OnChange, 0, NULL, NULL, 0, 0, NULL},
{"cam2_rotate", "0", CV_CALL|CV_NOINIT, cam_rotate_cons_t, CV_CamRotate2_OnChange, 0, NULL, NULL, 0, 0, NULL},
{"cam3_rotate", "0", CV_CALL|CV_NOINIT, cam_rotate_cons_t, CV_CamRotate3_OnChange, 0, NULL, NULL, 0, 0, NULL},
{"cam4_rotate", "0", CV_CALL|CV_NOINIT, cam_rotate_cons_t, CV_CamRotate4_OnChange, 0, NULL, NULL, 0, 0, NULL}
};
consvar_t cv_cam_timeover[MAXSPLITSCREENPLAYERS] = {
{"cam_timeover", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cam_timeover", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cam2_timeover", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cam3_timeover", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cam4_timeover", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}
@@ -3036,7 +3056,7 @@ consvar_t cv_cam_timeover[MAXSPLITSCREENPLAYERS] = {
static CV_PossibleValue_t freecam_speed_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
consvar_t cv_freecam_speed[MAXSPLITSCREENPLAYERS] = {
{"freecam_speed", "1", CV_SAVE, freecam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"freecam_speed", "1", CV_SAVE, freecam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"freecam2_speed", "1", CV_SAVE, freecam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"freecam3_speed", "1", CV_SAVE, freecam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"freecam4_speed", "1", CV_SAVE, freecam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}
@@ -3050,13 +3070,13 @@ consvar_t cv_actionmovie = {"actionmovie", "Off", CV_SAVE, CV_OnOff, NULL, 0, NU
consvar_t cv_screenquake = {"quakescreenshake", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t lookbackmom_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Double"}, {0, NULL}};
static CV_PossibleValue_t cam_lookbackmom_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Double"}, {0, NULL}};
consvar_t cv_lookbackmom[MAXSPLITSCREENPLAYERS] = {
{"cameralookbackmom", "Off", CV_SAVE, lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cameralookbackmom2", "Off", CV_SAVE, lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cameralookbackmom3", "Off", CV_SAVE, lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cameralookbackmom4", "Off", CV_SAVE, lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}
consvar_t cv_cam_lookbackmom[MAXSPLITSCREENPLAYERS] = {
{"cameralookbackmom", "Off", CV_SAVE, cam_lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cameralookbackmom2", "Off", CV_SAVE, cam_lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cameralookbackmom3", "Off", CV_SAVE, cam_lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"cameralookbackmom4", "Off", CV_SAVE, cam_lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}
};
fixed_t t_cam_rotate[MAXSPLITSCREENPLAYERS] = {-42, -42, -42, -42};
@@ -3514,7 +3534,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 +3599,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 +3655,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);
@@ -3671,7 +3691,7 @@ static boolean P_CheckNoclipCameraPosition(player_t *player, camera_t *thiscam,
static void P_MoveCameraToSpawn(UINT8 playernum)
{
camera_t *thiscam = &camera[playernum];
player_t *player = playernum == 0 ? &players[consoleplayer] : &players[displayplayers[playernum]];
player_t *player = P_GetLocalPlayerForNum(playernum);
if (!thiscam || !player->mo)
return;
@@ -3700,8 +3720,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
static boolean lookbackactive[MAXSPLITSCREENPLAYERS];
static UINT8 lookbackdelay[MAXSPLITSCREENPLAYERS];
UINT8 num = 0;
angle_t angle = 0, focusangle = 0, focusaiming = 0;
fixed_t x, y, z, dist, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight;
angle_t angle = 0, focusangle = 0, focusaiming = 0, pitch = 0;
fixed_t x, y, z, dist, distxy, distz, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight;
fixed_t pan, xpan, ypan;
INT32 camrotate;
boolean camstill, lookback, lookbackdown;
@@ -3745,8 +3765,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
mo = player->mo;
const boolean vflip = (mo->eflags & MFE_VERTICALFLIP);
if (cv_cam_timeover[num].value && (player->pflags & PF_TIMEOVER))
timeover = (player->kartstuff[k_timeovercam] > 2*TICRATE ? 2 : 1); // 1 for momentum keep, 2 for turnaround
else
@@ -3804,6 +3822,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
if (P_CameraThinker(player, thiscam, resetcalled))
return true;
const boolean vflip = (mo->eflags & MFE_VERTICALFLIP);
camspeed = cv_cam_speed[num].value;
camstill = cv_cam_still[num].value;
camrotate = cv_cam_rotate[num].value;
@@ -3900,8 +3920,41 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
if (player->kartstuff[k_boostcam])
dist -= FixedMul(11*dist/16, player->kartstuff[k_boostcam]);
x = mo->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
if (cv_cam_pitch[num].value)
{
if (mo->standingslope)
{
pitch = (angle_t)FixedMul(P_ReturnThrustX(mo, thiscam->angle - mo->standingslope->xydirection, FRACUNIT), (fixed_t)mo->standingslope->zangle);
if (vflip)
{
if (pitch >= ANGLE_180)
pitch = 0;
}
else
{
if (pitch < ANGLE_180)
pitch = 0;
}
}
pitch = thiscam->pitch + (angle_t)FixedMul(pitch - thiscam->pitch, camspeed/4);
#ifdef HWRENDER
if (rendermode == render_opengl)
distxy = FixedMul(dist, FINECOSINE((pitch>>ANGLETOFINESHIFT) & FINEMASK));
else
#endif
distxy = dist;
distz = -FixedMul(dist, FINESINE((pitch>>ANGLETOFINESHIFT) & FINEMASK));
}
else
{
distxy = dist;
distz = 0;
}
x = mo->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy);
y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy);
// SRB2Kart: set camera panning
if (camstill || resetcalled || player->playerstate == PST_DEAD)
@@ -3933,10 +3986,26 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
pviewheight = FixedMul(32<<FRACBITS, mo->scale);
if (vflip)
z = mo->z + mo->height - pviewheight - camheight;
if (cv_cam_pitch[num].value)
{
if (vflip)
{
distz = min(-camheight, distz);
z = mo->z + mo->height - pviewheight + distz;
}
else
{
distz = max(camheight, distz);
z = mo->z + pviewheight + distz;
}
}
else
z = mo->z + pviewheight + camheight;
{
if (vflip)
z = mo->z + mo->height - pviewheight - camheight;
else
z = mo->z + pviewheight + camheight;
}
#ifndef NOCLIPCAM // Disable all z-clipping for noclip cam
if (P_CheckNoclipCameraPosition(player, thiscam, x, y, z, resetcalled))
@@ -3978,16 +4047,17 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
// when looking back, camera's momentum
// should inherit the momentum of the player
// if value is 2, add extra
if (cv_lookbackmom[num].value && lookback && lookbackdelay[num])
if (cv_cam_lookbackmom[num].value && lookback && lookbackdelay[num])
{
thiscam->momx += cv_lookbackmom[num].value*mo->momx;
thiscam->momy += cv_lookbackmom[num].value*mo->momy;
thiscam->momx += cv_cam_lookbackmom[num].value*mo->momx;
thiscam->momy += cv_cam_lookbackmom[num].value*mo->momy;
}
thiscam->momz = FixedMul(z - thiscam->z, camspeed/2);
}
thiscam->pan = pan;
thiscam->pitch = pitch;
// compute aming to look the viewed point
f1 = viewpointx-thiscam->x;
@@ -3995,9 +4065,17 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
dist = FixedHypot(f1, f2);
if (vflip)
{
angle = R_PointToAngle2(0, thiscam->z + thiscam->height, dist, mo->z + mo->height - P_GetPlayerHeight(player));
if (thiscam->pitch < ANGLE_180 && thiscam->pitch > angle)
angle += (thiscam->pitch - angle)/2;
}
else
{
angle = R_PointToAngle2(0, thiscam->z, dist, mo->z + P_GetPlayerHeight(player));
if (thiscam->pitch >= ANGLE_180 && thiscam->pitch < angle)
angle -= (angle - thiscam->pitch)/2;
}
if (player->playerstate != PST_DEAD && !((player->pflags & PF_NIGHTSMODE) && player->exiting))
angle += (focusaiming < ANGLE_180 ? focusaiming/2 : InvAngle(InvAngle(focusaiming)/2)); // overcomplicated version of '((signed)focusaiming)/2;'
@@ -4081,7 +4159,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 +4401,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 +4557,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 +4847,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 +4913,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 +4950,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 +5122,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 +5136,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;
}
+1 -3
View File
@@ -484,9 +484,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)
+3
View File
@@ -25,6 +25,9 @@
#include "screen.h" // MAXVIDWIDTH, MAXVIDHEIGHT
#define MAP_ICON_WIDTH 160
#define MAP_ICON_HEIGHT 100
//
// ClipWallSegment
// Clips the given range of columns
+2 -2
View File
@@ -57,7 +57,7 @@ static constexpr UINT8 R_GetColumnTranslucent(drawcolumndata_t* dc, UINT8 * rest
}
template<DrawColumnType Type>
static constexpr UINT8 R_DrawColumnPixel(drawcolumndata_t* dc, UINT8 * restrict dest, UINT32 bit, const restrict UINT8 *source, const restrict UINT8 *colormap)
static constexpr UINT8 R_DrawColumnPixel(drawcolumndata_t* dc, UINT8 * restrict dest, UINT32 bit, const UINT8 * restrict source, const UINT8 * restrict colormap)
{
UINT8 col = source[bit];
@@ -217,7 +217,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
{
if (frac < 0)
// adjust in case we underread
frac += FRACUNIT;
frac += fracstep;
// texture has no height, so just go
while (--count >= 0)
+33
View File
@@ -492,6 +492,7 @@ void R_CreateInterpolator_Polyobj(thinker_t *thinker, polyobj_t *polyobj)
interp->polyobj.oldcx = interp->polyobj.bakcx = polyobj->centerPt.x;
interp->polyobj.oldcy = interp->polyobj.bakcy = polyobj->centerPt.y;
interp->polyobj.oldangle = interp->polyobj.bakangle = polyobj->angle;
}
/*void R_CreateInterpolator_DynSlope(thinker_t *thinker, pslope_t *slope)
@@ -515,6 +516,15 @@ void R_InitializeLevelInterpolators(void)
levelinterpolators = NULL;
}
static void RecalculatePolyobjectSegAngles(polyobj_t *polyobj)
{
for (size_t i = 0; i < polyobj->segCount; i++)
{
seg_t *seg = polyobj->segs[i];
seg->angle = R_PointToAngle2(seg->v1->x, seg->v1->y, seg->v2->x, seg->v2->y);
}
}
static void UpdateLevelInterpolatorState(levelinterpolator_t *interp)
{
size_t i;
@@ -545,10 +555,14 @@ static void UpdateLevelInterpolatorState(levelinterpolator_t *interp)
interp->polyobj.bakvertices[i * 2 ] = interp->polyobj.polyobj->vertices[i]->x;
interp->polyobj.bakvertices[i * 2 + 1] = interp->polyobj.polyobj->vertices[i]->y;
}
RecalculatePolyobjectSegAngles(interp->polyobj.polyobj);
interp->polyobj.oldcx = interp->polyobj.bakcx;
interp->polyobj.oldcy = interp->polyobj.bakcy;
interp->polyobj.oldangle = interp->polyobj.bakangle;
interp->polyobj.bakcx = interp->polyobj.polyobj->centerPt.x;
interp->polyobj.bakcy = interp->polyobj.polyobj->centerPt.y;
interp->polyobj.bakangle = interp->polyobj.polyobj->angle;
break;
/*case LVLINTERP_DynSlope:
FV3_Copy(&interp->dynslope.oldo, &interp->dynslope.bako);
@@ -630,8 +644,11 @@ void R_ApplyLevelInterpolators(fixed_t frac)
interp->polyobj.polyobj->vertices[ii]->x = R_LerpFixed(interp->polyobj.oldvertices[ii * 2 ], interp->polyobj.bakvertices[ii * 2 ], frac);
interp->polyobj.polyobj->vertices[ii]->y = R_LerpFixed(interp->polyobj.oldvertices[ii * 2 + 1], interp->polyobj.bakvertices[ii * 2 + 1], frac);
}
RecalculatePolyobjectSegAngles(interp->polyobj.polyobj);
interp->polyobj.polyobj->centerPt.x = R_LerpFixed(interp->polyobj.oldcx, interp->polyobj.bakcx, frac);
interp->polyobj.polyobj->centerPt.y = R_LerpFixed(interp->polyobj.oldcy, interp->polyobj.bakcy, frac);
interp->polyobj.polyobj->angle = R_LerpAngle(interp->polyobj.oldangle, interp->polyobj.bakangle, frac);
break;
/*case LVLINTERP_DynSlope:
R_LerpVector3(&interp->dynslope.oldo, &interp->dynslope.bako, frac, &interp->dynslope.slope->o);
@@ -685,8 +702,11 @@ void R_RestoreLevelInterpolators(void)
interp->polyobj.polyobj->vertices[ii]->x = interp->polyobj.bakvertices[ii * 2 ];
interp->polyobj.polyobj->vertices[ii]->y = interp->polyobj.bakvertices[ii * 2 + 1];
}
RecalculatePolyobjectSegAngles(interp->polyobj.polyobj);
interp->polyobj.polyobj->centerPt.x = interp->polyobj.bakcx;
interp->polyobj.polyobj->centerPt.y = interp->polyobj.bakcy;
interp->polyobj.polyobj->angle = interp->polyobj.bakangle;
break;
/*case LVLINTERP_DynSlope:
FV3_Copy(&interp->dynslope.slope->o, &interp->dynslope.bako);
@@ -840,6 +860,19 @@ void R_ResetMobjInterpolationState(mobj_t *mobj)
mobj->player->old_frameangle = mobj->player->frameangle;
}
// Reset our Sprite scales and offsets
// at the start of the 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
// technically not interpolation related
// but this saves us another thinkerloop and multiple checks lel
mobj->spritexscale = mobj->realxscale;
mobj->spriteyscale = mobj->realyscale;
mobj->spritexoffset = mobj->realxoffset;
mobj->spriteyoffset = mobj->realyoffset;
mobj->resetinterp = false;
}
+1
View File
@@ -119,6 +119,7 @@ typedef struct levelinterpolator_s {
fixed_t *bakvertices;
size_t vertices_size;
fixed_t oldcx, oldcy, bakcx, bakcy;
angle_t oldangle, bakangle;
} polyobj;
struct {
pslope_t *slope;
+9 -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++)
@@ -1565,14 +1569,15 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_chasecam[i]);
CV_RegisterVar(&cv_cam_dist[i]);
CV_RegisterVar(&cv_cam_still[i]);
CV_RegisterVar(&cv_cam_height[i]);
CV_RegisterVar(&cv_cam_pitch[i]);
CV_RegisterVar(&cv_cam_speed[i]);
CV_RegisterVar(&cv_cam_rotate[i]);
CV_RegisterVar(&cv_cam_timeover[i]);
CV_RegisterVar(&cv_freecam_speed[i]);
CV_RegisterVar(&cv_cam_lookbackmom[i]);
CV_RegisterVar(&cv_cam_still[i]);
CV_RegisterVar(&cv_cam_rotate[i]);
CV_RegisterVar(&cv_lookbackmom[i]);
CV_RegisterVar(&cv_freecam_speed[i]);
}
CV_RegisterVar(&cv_tilting);
+7 -1
View File
@@ -108,7 +108,7 @@ FUNCINLINE static ATTRINLINE PUREFUNC INT32 R_PointOnSide(fixed_t x, fixed_t y,
// This is not as accurate
// SHOULD NOT BE USED FOR ANYTHING GAMEPLAY RELATED!!
FUNCINLINE static ATTRINLINE PUREFUNC INT32 R_PointOnSideFast(fixed_t x, fixed_t y, const node_t *node)
FUNCINLINE static ATTRINLINE PUREFUNC INT32 R_PointOnSideFast(fixed_t x, fixed_t y, const node_t* restrict node)
{
// use cross product to determine side quickly
INT64 v = ((INT64)y - node->y) * node->dx - ((INT64)x - node->x) * node->dy;
@@ -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;
FUNCINLINE static ATTRINLINE INT32 R_GetSoftLightlevel(INT32 llevel)
{
return CLAMP(llevel, cv_secbright.value, 255) >> LIGHTSEGSHIFT;
}
// Called by startup code.
void R_Init(void);
+159
View File
@@ -451,6 +451,124 @@ void *Patch_CreateGL(patch_t *patch)
}
#endif // HWRENDER
//
// R_MaskedFlatToPatch
//
// Convert raw pixels to a patch.
//
void *R_PixelsToPatch(UINT8 *raw, INT16 width, INT16 height, INT16 leftoffset, INT16 topoffset, size_t *destsize)
{
INT16 x, y;
UINT8 *img;
UINT8 *imgptr = imgbuf;
UINT8 *colpointers, *startofspan;
size_t size = 0;
if (!raw)
return NULL;
// Write image size and offset
WRITEINT16(imgptr, width);
WRITEINT16(imgptr, height);
WRITEINT16(imgptr, leftoffset);
WRITEINT16(imgptr, topoffset);
// Leave placeholder to column pointers
colpointers = imgptr;
imgptr += width*4;
// Write columns
for (x = 0; x < width; x++)
{
int lastStartY = 0;
int spanSize = 0;
startofspan = NULL;
// Write column pointer
WRITEINT32(colpointers, imgptr - imgbuf);
// Write pixels
for (y = 0; y < height; y++)
{
UINT8 pixel = raw[((y * width) + x)];
UINT8 opaque = (pixel != 0xf7); // If not 247 (0xf7), we have a pixel
// End span if we have a transparent pixel
if (!opaque)
{
if (startofspan)
WRITEUINT8(imgptr, 0);
startofspan = NULL;
continue;
}
// Start new column if we need to
if (!startofspan || spanSize == 255)
{
int writeY = y;
// If we reached the span size limit, finish the previous span
if (startofspan)
WRITEUINT8(imgptr, 0);
if (y > 254)
{
// Make sure we're aligned to 254
if (lastStartY < 254)
{
WRITEUINT8(imgptr, 254);
WRITEUINT8(imgptr, 0);
imgptr += 2;
lastStartY = 254;
}
// Write stopgap empty spans if needed
writeY = y - lastStartY;
while (writeY > 254)
{
WRITEUINT8(imgptr, 254);
WRITEUINT8(imgptr, 0);
imgptr += 2;
writeY -= 254;
}
}
startofspan = imgptr;
WRITEUINT8(imgptr, writeY);
imgptr += 2;
spanSize = 0;
lastStartY = y;
}
// Write the pixel
WRITEUINT8(imgptr, pixel);
spanSize++;
startofspan[1] = spanSize;
}
if (startofspan)
WRITEUINT8(imgptr, 0);
WRITEUINT8(imgptr, 0xFF);
}
size = imgptr-imgbuf;
img = Z_Malloc(size, PU_STATIC, NULL);
memcpy(img, imgbuf, size);
if (destsize != NULL)
*destsize = size;
patch_t *converted = Patch_Create((softwarepatch_t *)img, size, NULL);
#ifdef HWRENDER
Patch_CreateGL(converted);
#endif
Z_Free(img);
return converted;
}
//
// R_MaskedFlatToPatch
@@ -615,3 +733,44 @@ UINT16 R_GetPatchPixel(patch_t *patch, INT32 x, INT32 y, boolean flip)
return 0xFF00;
}
void R_PatchToPixels(patch_t *patch, UINT8 *dst)
{
const INT16 width = patch->width;
// init out destination to cyan so we can easily check for it when we convert it back to a patch
memset(dst, 0xf7, (width * patch->height)); // should this be here or should this be taken care of before passing it?
for (INT32 x = 0; x < width; ++x)
{
INT32 y = 0;
INT32 prevdelta = -1;
column_t *column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[x]));
while (column->topdelta != 0xff)
{
INT32 topdelta = column->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
for (; y-topdelta < column->length; ++y)
{
UINT8 pixel = 0;
if (y >= topdelta)
{
UINT8 *source = (UINT8*)(column) + 3;
pixel = source[y-topdelta];
}
dst[(y*width) + x] = pixel;
}
column = (column_t *)((UINT8 *)column + column->length + 4);
}
}
}
+64 -62
View File
@@ -1,62 +1,64 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 2018-2019 by Jaime "Lactozilla" Passos.
// Copyright (C) 2019 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file r_patch.h
/// \brief Patch generation.
#ifndef __R_PATCH__
#define __R_PATCH__
#include "r_defs.h"
// Structs
typedef enum
{
ROTAXIS_X, // Roll (the default)
ROTAXIS_Y, // Pitch
ROTAXIS_Z // Yaw
} rotaxis_t;
typedef struct
{
INT32 x, y;
rotaxis_t rotaxis;
} spriteframepivot_t;
typedef struct
{
spriteframepivot_t pivot[64];
boolean available;
} spriteinfo_t;
// Patch functions
patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest);
void Patch_Free(patch_t *patch);
#define Patch_FreeTag(tagnum) Patch_FreeTags(tagnum, tagnum)
void Patch_FreeTags(INT32 lowtag, INT32 hightag);
#ifdef HWRENDER
void *Patch_AllocateHardwarePatch(patch_t *patch);
void *Patch_CreateGL(patch_t *patch);
#endif
// Conversions between patches / flats / textures...
boolean R_CheckIfPatch(lumpnum_t lump);
// SpriteInfo
extern spriteinfo_t spriteinfo[NUMSPRITES];
void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps);
void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum);
void *R_MaskedFlatToPatch(UINT16 *raw, INT16 width, INT16 height, INT16 leftoffset, INT16 topoffset, size_t *destsize);
UINT16 R_GetPatchPixel(patch_t *patch, INT32 x, INT32 y, boolean flip);
#endif // __R_PATCH__
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 2018-2019 by Jaime "Lactozilla" Passos.
// Copyright (C) 2019 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file r_patch.h
/// \brief Patch generation.
#ifndef __R_PATCH__
#define __R_PATCH__
#include "r_defs.h"
// Structs
typedef enum
{
ROTAXIS_X, // Roll (the default)
ROTAXIS_Y, // Pitch
ROTAXIS_Z // Yaw
} rotaxis_t;
typedef struct
{
INT32 x, y;
rotaxis_t rotaxis;
} spriteframepivot_t;
typedef struct
{
spriteframepivot_t pivot[64];
boolean available;
} spriteinfo_t;
// Patch functions
patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest);
void Patch_Free(patch_t *patch);
#define Patch_FreeTag(tagnum) Patch_FreeTags(tagnum, tagnum)
void Patch_FreeTags(INT32 lowtag, INT32 hightag);
#ifdef HWRENDER
void *Patch_AllocateHardwarePatch(patch_t *patch);
void *Patch_CreateGL(patch_t *patch);
#endif
// Conversions between patches / flats / textures...
boolean R_CheckIfPatch(lumpnum_t lump);
// SpriteInfo
extern spriteinfo_t spriteinfo[NUMSPRITES];
void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps);
void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum);
void *R_MaskedFlatToPatch(UINT16 *raw, INT16 width, INT16 height, INT16 leftoffset, INT16 topoffset, size_t *destsize);
void *R_PixelsToPatch(UINT8 *raw, INT16 width, INT16 height, INT16 leftoffset, INT16 topoffset, size_t *destsize);
UINT16 R_GetPatchPixel(patch_t *patch, INT32 x, INT32 y, boolean flip);
void R_PatchToPixels(patch_t *patch, UINT8 *dst); // Important: dst must have enough space for patch->width*patch->height pixels!
#endif // __R_PATCH__
+17 -17
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;
}
@@ -1072,15 +1072,15 @@ void R_DrawSinglePlane(drawspandata_t* ds, visplane_t *pl, boolean allow_paralle
{
if ((pl->ffloor->flags & FF_CUTEXTRA) && (rover->flags & FF_EXTRA))
{
if (!(rover->flags & FF_EXTRA))
continue;
// The plane is from an extra 3D floor... Check the flags so
// there are no undesired cuts.
if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE)))
&& pl->height < *rover->topheight
&& pl->height > *rover->bottomheight)
return;
if (pl->ffloor->flags & FF_EXTRA)
{
// The plane is from an extra 3D floor... Check the flags so
// there are no undesired cuts.
if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE)))
&& pl->height < *rover->topheight
&& pl->height > *rover->bottomheight)
return;
}
}
}
@@ -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;
@@ -1180,7 +1182,7 @@ void R_DrawSinglePlane(drawspandata_t* ds, visplane_t *pl, boolean allow_paralle
levelflat = &levelflats[pl->picnum];
// Get the texture
ds->source = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_STATIC); // Stay here until Z_ChangeTag
ds->source = R_GetFlat(levelflat->lumpnum);
if (ds->source == NULL)
return;
@@ -1385,8 +1387,6 @@ using the palette colors.
}
}
#endif
Z_ChangeTag(ds->source, PU_CACHE);
}
void R_PlaneBounds(visplane_t *plane)
+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];
+136 -239
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);
@@ -42,12 +42,10 @@ static void Command_RestartMusic_f(void); //mhhhm amiga type filters here i come
static void Command_ShowMusicCredit_f(void);
// Sound system toggles
#ifndef NO_MIDI
static void GameMIDIMusic_OnChange(void);
#endif
static void GameSounds_OnChange(void);
static void GameMusic_OnChange(void);
static void SoundPrecache_OnChange(void);
static void GameDigiMusic_OnChange(void);
static void BufferSize_OnChange(void);
#ifdef HAVE_OPENMPT
@@ -59,10 +57,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,16 +79,17 @@ 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};
// Sound system toggles, saved into the config
consvar_t cv_gamedigimusic = {"digimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameDigiMusic_OnChange, 0, NULL, NULL, 0, 0, NULL};
#ifndef NO_MIDI
consvar_t cv_gamemidimusic = {"midimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameMIDIMusic_OnChange, 0, NULL, NULL, 0, 0, NULL};
#endif
consvar_t cv_gamesounds = {"sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameSounds_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_gamedigimusic = {"digimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameMusic_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_gamesounds = {"sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameSounds_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_playmusicifunfocused = {"playmusicifunfocused", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_playsoundifunfocused = {"playsoundsifunfocused", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -274,13 +275,14 @@ 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);
#ifndef NO_MIDI
CV_RegisterVar(&cv_gamemidimusic);
#endif
CV_RegisterVar(&cv_samesoundlimit);
// bird music stuff
CV_RegisterVar(&cv_playmusicifunfocused);
@@ -324,9 +326,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);
@@ -360,10 +359,7 @@ lumpnum_t S_GetSfxLumpNum(sfxinfo_t *sfx)
boolean S_SoundDisabled(void)
{
return (
sound_disabled ||
( window_notinfocus && ! cv_playsoundifunfocused.value )
);
return (sound_disabled || (window_notinfocus && !cv_playsoundifunfocused.value));
}
boolean S_PrecacheSound(void)
@@ -427,6 +423,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 +449,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 +464,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 +489,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 +527,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 +567,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 +587,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 +605,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 +614,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 +637,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)
{
@@ -670,14 +678,11 @@ void S_StopSound(void *origin)
// Updates music & sounds
//
static INT32 actualsfxvolume; // check for change through console
static INT32 actualdigmusicvolume;
#ifndef NO_MIDI
static INT32 actualmidimusicvolume;
#endif
static INT32 actualmusicvolume;
void S_UpdateSounds(void)
{
INT32 cnum, volume, sep, pitch;
INT32 cnum, volume, sep;
boolean audible = false;
channel_t *c;
INT32 i;
@@ -685,15 +690,21 @@ void S_UpdateSounds(void)
listener_t listener[MAXSPLITSCREENPLAYERS];
mobj_t *listenmobj[MAXSPLITSCREENPLAYERS];
#ifndef NO_MIDI
const boolean currentmidi = (I_SongType() == MU_MID);
#endif
// Update sound/music volumes, if changed manually at console
if (actualsfxvolume != cv_soundvolume.value)
S_SetSfxVolume (cv_soundvolume.value);
if (actualdigmusicvolume != cv_digmusicvolume.value)
S_SetDigMusicVolume (cv_digmusicvolume.value);
S_SetSfxVolume(cv_soundvolume.value);
#ifndef NO_MIDI
if (actualmidimusicvolume != cv_midimusicvolume.value)
S_SetMIDIMusicVolume (cv_midimusicvolume.value);
if (actualmusicvolume != (currentmidi ? cv_midimusicvolume.value : cv_digmusicvolume.value))
#else
if (actualmusicvolume != cv_digmusicvolume.value)
#endif
S_SetMusicVolume(-1);
memset(listener, 0, sizeof(listener));
// We're done now, if we're not in a level.
if (gamestate != GS_LEVEL)
@@ -714,7 +725,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 +735,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 +752,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 +766,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 +821,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 +880,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 +920,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 +929,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 +961,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 +982,7 @@ boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32
}
}
}
#undef RADIUSSTEP
}
}
else
@@ -990,14 +993,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 +1033,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 +1149,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;
}
@@ -1500,7 +1502,8 @@ void S_ShowSpecifiedMusicCredit(const char *musname)
{
musicdef_t *def;
if (digital_disabled) return;
if (music_disabled)
return;
if (!cv_songcredits.value || demo.rewinding)
return;
@@ -1530,19 +1533,9 @@ void S_ShowMusicCredit(void)
/// Music Status
/// ------------------------
boolean S_DigMusicDisabled(void)
{
return digital_disabled;
}
boolean S_MIDIMusicDisabled(void)
{
return midi_disabled; // SRB2Kart: defined as "true" w/ NO_MIDI
}
boolean S_MusicDisabled(void)
{
return (midi_disabled && digital_disabled);
return (music_disabled);
}
boolean S_MusicPlaying(void)
@@ -1631,6 +1624,25 @@ UINT32 S_GetMusicPosition(void)
/// Music Playback
/// ------------------------
static lumpnum_t S_GetMusicLumpNum(const char *mname)
{
if (S_MusicExists(mname, false, true)) // check non midis first
return W_GetNumForName(va("o_%s", mname));
else if (S_MusicExists(mname, true, false))
{
#ifdef NO_MIDI
CONS_Alert(CONS_ERROR, "A MIDI music lump %.6s was found,\nbut SRB2Kart does not support MIDI output.\nWe apologise for the inconvenience.\n", mname);
return LUMPERROR;
#else
return W_GetNumForName(va("d_%s", mname));
#endif
}
CONS_Alert(CONS_ERROR, "Music %.6s could not be loaded: lump not found!\n", mname);
return LUMPERROR;
}
static boolean S_LoadMusic(const char *mname)
{
lumpnum_t mlumpnum;
@@ -1639,27 +1651,10 @@ static boolean S_LoadMusic(const char *mname)
if (S_MusicDisabled())
return false;
if (!S_DigMusicDisabled() && S_DigExists(mname))
mlumpnum = W_GetNumForName(va("o_%s", mname));
else if (!S_MIDIMusicDisabled() && S_MIDIExists(mname))
mlumpnum = W_GetNumForName(va("d_%s", mname));
else if (S_DigMusicDisabled() && S_DigExists(mname))
mlumpnum = S_GetMusicLumpNum(mname);
if (mlumpnum == LUMPERROR)
{
CONS_Alert(CONS_NOTICE, "Digital music is disabled!\n");
return false;
}
else if (S_MIDIMusicDisabled() && S_MIDIExists(mname))
{
#ifdef NO_MIDI
CONS_Alert(CONS_ERROR, "A MIDI music lump %.6s was found,\nbut SRB2Kart does not support MIDI output.\nWe apologise for the inconvenience.\n", mname);
#else
CONS_Alert(CONS_NOTICE, "MIDI music is disabled!\n");
#endif
return false;
}
else
{
CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), mname);
return false;
}
@@ -1707,7 +1702,7 @@ static boolean S_PlayMusic(boolean looping, UINT32 fadeinms)
return false;
}
S_InitMusicVolume(); // switch between digi and sequence volume
S_SetMusicVolume(-1); // initialize music volume
if (S_MusicNotInFocus())
I_SetMusicVolume(0);
@@ -1863,55 +1858,32 @@ void S_ResumeAudio(void)
I_ResumeSong();
}
void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume)
void S_SetMusicVolume(INT32 volume)
{
if (digvolume < 0)
digvolume = cv_digmusicvolume.value;
#ifdef NO_MIDI
(void)seqvolume;
consvar_t *musicvolume = &cv_digmusicvolume;
#else
if (seqvolume < 0)
seqvolume = cv_midimusicvolume.value;
consvar_t *musicvolume = (I_SongType() == MU_MID) ? &cv_midimusicvolume : &cv_digmusicvolume;
#endif
if (digvolume < 0 || digvolume > 31)
CONS_Alert(CONS_WARNING, "digmusicvolume should be between 0-31\n");
CV_SetValue(&cv_digmusicvolume, digvolume&31);
actualdigmusicvolume = cv_digmusicvolume.value; //check for change of var
if (volume < 0)
volume = musicvolume->value;
#ifndef NO_MIDI
if (seqvolume < 0 || seqvolume > 31)
CONS_Alert(CONS_WARNING, "midimusicvolume should be between 0-31\n");
CV_SetValue(&cv_midimusicvolume, seqvolume&31);
actualmidimusicvolume = cv_midimusicvolume.value; //check for change of var
#endif
if (volume < 0 || volume > 31)
CONS_Alert(CONS_WARNING, "Music volume should be between 0-31\n");
#ifndef NO_MIDI
seqvolume = 31;
#endif
CV_SetValue(musicvolume, volume&31);
actualmusicvolume = musicvolume->value; //check for change of var
switch(I_SongType())
{
#ifndef NO_MIDI
case MU_MID:
//case MU_MOD:
//case MU_GME:
I_SetMusicVolume(seqvolume&31);
break;
#endif
default:
I_SetMusicVolume(digvolume&31);
break;
}
I_SetMusicVolume(volume&31);
}
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 +1992,6 @@ void S_KeepMusic(void)
if (oldmap == gamemap && oldencore == encoremode)
{
const boolean musicchanged = S_CheckMusicException();
resumekeepmusic = (musicchanged && keepmusic.resume);
keepmapmusic = (!musicchanged || resumekeepmusic);
}
@@ -2145,11 +2116,7 @@ void S_RestartMusic(void)
I_ShutdownMusic();
I_InitMusic();
#ifdef NO_MIDI
S_SetMusicVolume(cv_digmusicvolume.value, -1);
#else
S_SetMusicVolume(cv_digmusicvolume.value, cv_midimusicvolume.value);
#endif
S_SetMusicVolume(-1);
S_ResetKeepAndSpecialMus();
@@ -2187,6 +2154,7 @@ static void Command_Tunes_f(void)
mapmusic.name, (mapmusic.flags & MUSIC_TRACKMASK));
return;
}
if (!strcasecmp(tunearg, "-none"))
{
S_StopMusic();
@@ -2205,6 +2173,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 +2183,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,14 +2214,10 @@ 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
S_SetMusicVolume(cv_digmusicvolume.value, -1);
#else
S_SetMusicVolume(cv_digmusicvolume.value, cv_midimusicvolume.value);
#endif
S_SetMusicVolume(-1);
S_StartSound(NULL, sfx_strpst);
@@ -2323,16 +2287,14 @@ static void SoundPrecache_OnChange(void)
}
}
static void GameDigiMusic_OnChange(void)
void GameMusic_OnChange(void)
{
if (M_CheckParm("-nomusic") || M_CheckParm("-noaudio"))
return;
else if (M_CheckParm("-nodigmusic"))
return;
if (digital_disabled && cv_gamedigimusic.value)
if (music_disabled && cv_gamedigimusic.value)
{
digital_disabled = false;
music_disabled = false;
I_StartupSound(); // will return early if initialised
I_InitMusic();
@@ -2343,32 +2305,13 @@ static void GameDigiMusic_OnChange(void)
else
S_ChangeMusicInternal("titles", looptitle);
}
else if (!digital_disabled && !cv_gamedigimusic.value)
else if (!music_disabled && !cv_gamedigimusic.value)
{
digital_disabled = true;
if (S_MusicType() != MU_MID)
{
if (midi_disabled)
S_StopMusic();
else
{
char mmusic[7];
UINT16 mflags;
boolean looping;
if (S_MusicInfo(mmusic, &mflags, &looping) && S_MIDIExists(mmusic))
{
S_StopMusic();
S_ChangeMusic(mmusic, mflags, looping);
}
else
S_StopMusic();
}
}
music_disabled = true;
S_StopMusic();
}
}
#ifdef HAVE_OPENMPT
static void ModFilter_OnChange(void)
{
@@ -2410,49 +2353,3 @@ static void BufferSize_OnChange(void)
if (sound_started)
COM_ImmedExecute("restartaudio");
}
#ifndef NO_MIDI
static void GameMIDIMusic_OnChange(void)
{
if (M_CheckParm("-nomusic") || M_CheckParm("-noaudio"))
return;
else if (M_CheckParm("-nomidimusic"))
return;
if (midi_disabled && cv_gamemidimusic.value)
{
midi_disabled = false;
I_InitMusic();
S_ResetKeepAndSpecialMus();
if (Playing())
P_RestoreMusic(&players[consoleplayer]);
else
S_ChangeMusicInternal("titles", looptitle);
}
else if (!midi_disabled && !cv_gamemidimusic.value)
{
midi_disabled = true;
if (S_MusicType() == MU_MID)
{
if (digital_disabled)
S_StopMusic();
else
{
char mmusic[7];
UINT16 mflags;
boolean looping;
if (S_MusicInfo(mmusic, &mflags, &looping) && S_DigExists(mmusic))
{
S_StopMusic();
S_ChangeMusic(mmusic, mflags, looping);
}
else
S_StopMusic();
}
}
}
}
#endif
+4 -9
View File
@@ -32,11 +32,13 @@ 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;
#ifndef NO_MIDI
extern consvar_t cv_gamemidimusic, cv_midimusicvolume;
extern consvar_t cv_midimusicvolume;
#endif
extern consvar_t cv_gamesounds;
extern consvar_t cv_playmusicifunfocused;
@@ -146,8 +148,6 @@ void S_StopSound(void *origin);
// Music Status
//
boolean S_DigMusicDisabled(void);
boolean S_MIDIMusicDisabled(void);
boolean S_MusicDisabled(void);
boolean S_MusicPlaying(void);
boolean S_MusicPaused(void);
@@ -157,8 +157,6 @@ musictype_t S_MusicType(void);
const char *S_MusicName(void);
boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping);
boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi);
#define S_DigExists(a) S_MusicExists(a, false, true)
#define S_MIDIExists(a) S_MusicExists(a, true, false)
//
// Music Effects
@@ -279,10 +277,7 @@ void S_UpdateSounds(void);
FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2);
void S_SetSfxVolume(INT32 volume);
void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume);
#define S_SetDigMusicVolume(a) S_SetMusicVolume(a,-1)
#define S_SetMIDIMusicVolume(a) S_SetMusicVolume(-1,a)
#define S_InitMusicVolume() S_SetMusicVolume(-1,-1)
void S_SetMusicVolume(INT32 volume);
INT32 S_OriginPlaying(void *origin);
INT32 S_IdPlaying(sfxenum_t id);
+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;
+27 -124
View File
@@ -163,20 +163,13 @@ static INT32 firstEntry = 0;
static INT32 mousemovex = 0, mousemovey = 0;
// SDL vars
static SDL_Surface *vidSurface = NULL;
static SDL_Surface *bufSurface = NULL;
static SDL_Surface *icoSurface = NULL;
static SDL_Color localPalette[256];
#if 0
static SDL_Rect **modeList = NULL;
static Uint8 BitsPerPixel = 16;
#endif
static UINT32 localPalette[256];
Uint16 realwidth = BASEVIDWIDTH;
Uint16 realheight = BASEVIDHEIGHT;
static SDL_bool mousegrabok = SDL_TRUE;
static SDL_bool wrapmouseok = SDL_FALSE;
#define HalfWarpMouse(x,y) if (wrapmouseok) SDL_WarpMouseInWindow(window, (Uint16)(x/2),(Uint16)(y/2))
static SDL_bool videoblitok = SDL_FALSE;
static SDL_bool exposevideo = SDL_FALSE;
static SDL_bool usesdl2soft = SDL_FALSE;
static SDL_bool borderlesswindow = SDL_FALSE;
@@ -219,7 +212,6 @@ static INT32 windowedModes[MAXWINMODES][2] =
static INT32 custom_width = 0;
static INT32 custom_height = 0;
static void Impl_VideoSetupSDLBuffer(void);
static void Impl_VideoSetupBuffer(void);
static SDL_bool Impl_CreateWindow(SDL_bool fullscreen);
static void Impl_SetWindowIcon(void);
@@ -485,39 +477,6 @@ static void VID_Command_NumModes_f (void)
CONS_Printf(M_GetText("%d video mode(s) available(s)\n"), VID_NumModes());
}
// SDL2 doesn't have SDL_GetVideoSurface or a lot of the SDL_Surface flags that SDL 1.2 had
static void SurfaceInfo(const SDL_Surface *infoSurface, const char *SurfaceText)
{
INT32 vfBPP;
if (!infoSurface)
return;
if (!SurfaceText)
SurfaceText = M_GetText("Unknown Surface");
vfBPP = infoSurface->format?infoSurface->format->BitsPerPixel:0;
CONS_Printf("\x82" "%s\n", SurfaceText);
CONS_Printf(M_GetText(" %ix%i at %i bit color\n"), infoSurface->w, infoSurface->h, vfBPP);
if (infoSurface->flags&SDL_PREALLOC)
CONS_Printf("%s", M_GetText(" Uses preallocated memory\n"));
else
CONS_Printf("%s", M_GetText(" Stored in system memory\n"));
if (infoSurface->flags&SDL_RLEACCEL)
CONS_Printf("%s", M_GetText(" Colorkey RLE acceleration blit\n"));
}
static void VID_Command_Info_f (void)
{
if (!M_CheckParm("-noblit"))
videoblitok = SDL_TRUE;
SurfaceInfo(bufSurface, M_GetText("Current Engine Mode"));
SurfaceInfo(vidSurface, M_GetText("Current Video Mode"));
}
static void VID_Command_ModeList_f(void)
{
// List windowed modes
@@ -718,10 +677,10 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
// Tell game we got focus back, resume music if necessary
window_notinfocus = false;
S_InitMusicVolume();
S_SetMusicVolume(-1);
if (cv_gamesounds.value)
S_ResumeAudio(); //resume it
S_ResumeAudio(); // resume it
if (!firsttimeonmouse)
{
@@ -1340,8 +1299,6 @@ void I_OsPolling(void)
static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
{
static SDL_bool wasfullscreen = SDL_FALSE;
Uint32 rmask, gmask, bmask, amask;
int bpp = 16;
int sw_texture_format = SDL_PIXELFORMAT_ABGR8888;
realwidth = vid.width;
@@ -1361,6 +1318,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 +1338,7 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
if (fullscreen)
{
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
I_SetBorderlessWindow();
}
}
@@ -1408,32 +1367,13 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
SDL_DestroyTexture(texture);
}
if (!usesdl2soft)
{
sw_texture_format = SDL_PIXELFORMAT_RGB565;
}
else
{
bpp = 32;
sw_texture_format = SDL_PIXELFORMAT_RGBA8888;
}
texture = SDL_CreateTexture(renderer, sw_texture_format, SDL_TEXTUREACCESS_STREAMING, width, height);
// Set up SW surface
if (vidSurface != NULL)
{
SDL_FreeSurface(vidSurface);
}
if (vid.buffer)
{
free(vid.buffer);
vid.buffer = NULL;
}
SDL_PixelFormatEnumToMasks(sw_texture_format, &bpp, &rmask, &gmask, &bmask, &amask);
vidSurface = SDL_CreateRGBSurface(0, width, height, bpp, rmask, gmask, bmask, amask);
}
}
@@ -1492,19 +1432,21 @@ void I_FinishUpdate(void)
if (rendermode == render_soft && vid.screens[0])
{
if (!bufSurface) //Double-Check
void *pixels;
int pitch;
SDL_LockTexture(texture, NULL, &pixels, &pitch);
int step = pitch / 4 - vid.width;
UINT32 *restrict dst = pixels;
UINT8 *restrict src = vid.screens[0];
UINT32 *restrict palette = localPalette;
for (INT32 y = 0; y < vid.height; y++)
{
Impl_VideoSetupSDLBuffer();
}
if (bufSurface)
{
SDL_BlitSurface(bufSurface, &src_rect, vidSurface, &src_rect);
// Fury -- there's no way around UpdateTexture, the GL backend uses it anyway
SDL_LockSurface(vidSurface);
SDL_UpdateTexture(texture, &src_rect, vidSurface->pixels, vidSurface->pitch);
SDL_UnlockSurface(vidSurface);
UINT8 *restrict end = src + vid.width;
do *dst++ = palette[*src++];
while (src < end);
dst += step;
}
SDL_UnlockTexture(texture);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, &src_rect, NULL);
@@ -1551,14 +1493,11 @@ void I_SetPalette(RGBA_t *palette)
for (i = 0; i < 256; i++)
{
localPalette[i].r = palette[i].s.red;
localPalette[i].g = palette[i].s.green;
localPalette[i].b = palette[i].s.blue;
localPalette[i] = 0xff000000;
localPalette[i] |= palette[i].s.red << 0;
localPalette[i] |= palette[i].s.green << 8;
localPalette[i] |= palette[i].s.blue << 16;
}
//if (vidSurface) SDL_SetPaletteColors(vidSurface->format->palette, localPalette, 0, 256);
// Fury -- SDL2 vidSurface is a 32-bit surface buffer copied to the texture. It's not palletized, like bufSurface.
if (bufSurface) SDL_SetPaletteColors(bufSurface->format->palette, localPalette, 0, 256);
}
// return number of fullscreen + X11 modes
@@ -1680,15 +1619,6 @@ INT32 VID_SetMode(INT32 modeNum)
SDLSetMode(vid.width, vid.height, USE_FULLSCREEN);
Impl_VideoSetupBuffer();
if (rendermode == render_soft)
{
if (bufSurface)
{
SDL_FreeSurface(bufSurface);
bufSurface = NULL;
}
}
src_rect.w = vid.width;
src_rect.h = vid.height;
@@ -1816,36 +1746,19 @@ static void Impl_SetWindowIcon(void)
SDL_SetWindowIcon(window, icoSurface);
}
static void Impl_VideoSetupSDLBuffer(void)
{
if (bufSurface != NULL)
{
SDL_FreeSurface(bufSurface);
bufSurface = NULL;
}
// Set up the SDL palletized buffer (copied to vidbuffer before being rendered to texture)
bufSurface = SDL_CreateRGBSurfaceFrom(vid.screens[0], vid.width, vid.height, 8,
(int)vid.rowbytes, 0x00000000, 0x00000000, 0x00000000, 0x00000000); // 256 mode
if (bufSurface)
{
SDL_SetPaletteColors(bufSurface->format->palette, localPalette, 0, 256);
}
else
{
I_Error("%s", M_GetText("No system memory for SDL buffer surface\n"));
}
}
static void Impl_VideoSetupBuffer(void)
{
// Set up game's software render buffer
size_t size;
vid.rowbytes = vid.width;
if (vid.buffer)
free(vid.buffer);
vid.buffer = calloc(vid.rowbytes*vid.height, NUMSCREENS);
size = vid.rowbytes*vid.height * NUMSCREENS;
vid.buffer = calloc(size, NUMSCREENS);
if (!vid.buffer)
{
@@ -1872,7 +1785,6 @@ void I_StartupGraphics(void)
return;
COM_AddCommand ("vid_nummodes", VID_Command_NumModes_f);
COM_AddCommand ("vid_info", VID_Command_Info_f);
COM_AddCommand ("vid_modelist", VID_Command_ModeList_f);
COM_AddCommand ("vid_mode", VID_Command_Mode_f);
CV_RegisterVar (&cv_vidwait);
@@ -2074,7 +1986,6 @@ void I_StartupGraphics(void)
realwidth = (Uint16)vid.width;
realheight = (Uint16)vid.height;
VID_Command_Info_f();
SDLdoUngrabMouse();
SDL_RaiseWindow(window);
@@ -2099,17 +2010,9 @@ void I_ShutdownGraphics(void)
if (oldrendermode == render_soft)
{
if (vidSurface)
SDL_FreeSurface(vidSurface);
vidSurface = NULL;
if (vid.buffer)
free(vid.buffer);
vid.buffer = NULL;
if (bufSurface)
SDL_FreeSurface(bufSurface);
bufSurface = NULL;
}
I_OutputMsg("I_ShutdownGraphics(): ");
+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)
+4 -8
View File
@@ -189,7 +189,7 @@ static void Snd_LockAudio(void) //Alam: Lock audio data and uninstall audio call
{
if (Snd_Mutex) SDL_LockMutex(Snd_Mutex);
else if (sound_disabled) return;
else if (midi_disabled && digital_disabled) SDL_LockAudio();
else if (music_disabled) SDL_LockAudio();
#ifdef HAVE_MIXER
else if (musicStarted) Mix_SetPostMix(NULL, NULL);
#endif
@@ -199,7 +199,7 @@ static void Snd_UnlockAudio(void) //Alam: Unlock audio data and reinstall audio
{
if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex);
else if (sound_disabled) return;
else if (midi_disabled && digital_disabled) SDL_UnlockAudio();
else if (music_disabled) SDL_UnlockAudio();
#ifdef HAVE_MIXER
else if (musicStarted) Mix_SetPostMix(audio.callback, audio.userdata);
#endif
@@ -1061,7 +1061,7 @@ void I_ShutdownSound(void)
CONS_Printf("I_ShutdownSound: ");
if (midi_disabled && digital_disabled)
if (music_disabled)
SDL_CloseAudio();
CONS_Printf("%s", M_GetText("shut down\n"));
sound_started = false;
@@ -1078,11 +1078,7 @@ void I_UpdateSound(void)
void I_StartupSound(void)
{
#ifndef HAVE_MIXER
#ifndef NO_MIDI
midi_disabled =
#endif
digital_disabled = true;
#endif
music_disabled = true;
memset(channels, 0, sizeof (channels)); //Alam: Clean it
+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;
};
+15 -2
View File
@@ -367,7 +367,7 @@ static void ST_drawDebugInfo(void)
{
INT32 height = 192;
if (!stplyr->mo)
if (!cv_debug || !stplyr->mo)
return;
if (cv_debug & DBG_BASIC)
@@ -438,9 +438,21 @@ static void ST_drawLevelTitle(void)
zonttl = mapheaderinfo[gamemap-1]->zonttl; // SRB2kart
actnum = mapheaderinfo[gamemap-1]->actnum;
dupcalc = (vid.width/vid.dupx);
gtc = G_GetGametypeColor(gametype);
bary = (splitscreen) ? BASEVIDHEIGHT/2 : 163;
if (K_UseColorHud())
{
if (gametype == GT_RACE)
gtc = colortranslations[K_GetHudColor()][7]; // idk if this should also apply to other gametypes?
else if (modeattacking || gamestate == GS_TIMEATTACK)
gtc = colortranslations[K_GetHudColor()][4];
else
gtc = G_GetGametypeColor(gametype);
}
else
gtc = G_GetGametypeColor(gametype);
lvlw = V_LevelNameWidth(lvlttl);
if (actnum[0])
@@ -791,5 +803,6 @@ void ST_Drawer(void)
else
V_DrawFadeScreen(120, 15-timeinmap); // Then gradually fade out from there
}
ST_drawDebugInfo();
}
+33 -5
View File
@@ -615,8 +615,21 @@ static void CV_constextsize_OnChange(void)
void VID_BlitLinearScreen(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT32 height, size_t srcrowbytes,
size_t destrowbytes)
{
if ((srcrowbytes == destrowbytes) && (srcrowbytes == (size_t)width))
M_Memcpy(destptr, srcptr, srcrowbytes * height);
if (srcrowbytes == destrowbytes)
{
size_t i = srcrowbytes * height;
#if defined(__SSE__)
while (i >= 16)
{
// TODO: find where the buffer is misaligned at times and align it
_mm_storeu_ps((float *)destptr, _mm_loadu_ps((const float *)srcptr));
srcptr += 16;
destptr += 16;
i -= 16;
}
#endif
M_Memcpy(destptr, srcptr, i);
}
else
{
while (height--)
@@ -3775,17 +3788,32 @@ UINT8 GetColorLUTDirect(colorlookup_t *lut, UINT8 r, UINT8 g, UINT8 b)
void V_Init(void)
{
INT32 i;
UINT8 *base = vid.buffer;
const INT32 screensize = vid.rowbytes * vid.height;
for (i = 0; i < NUMSCREENS; i++)
{
#if defined(__SSE__)
aligned_free(vid.screens[i]);
#else
free(vid.screens[i]);
#endif
vid.screens[i] = NULL;
}
// start address of NUMSCREENS * width*height vidbuffers
if (base)
if (screensize > 0)
{
for (i = 0; i < NUMSCREENS; i++)
vid.screens[i] = base + i*screensize;
{
// we need to allocate these relative to their cpu restrictions to not trigger segfaults
// TODO: add support for sve and neon
#if defined(__SSE__)
vid.screens[i] = aligned_alloc(128, screensize);
#else
vid.screens[i] = malloc(screensize);
#endif
memset(vid.screens[i], 0, screensize);
}
}
#ifdef DEBUG
+12
View File
@@ -23,6 +23,18 @@ extern "C" {
#include "r_defs.h"
#include "r_main.h"
#if defined(__SSE__)
#ifdef _WIN32
#include <malloc.h>
#define aligned_alloc(align, size) _aligned_malloc(size, align)
#define aligned_free(ptr) _aligned_free(ptr)
#else
#define aligned_free(ptr) free(ptr)
#endif
#include <immintrin.h>
#endif
//
// VIDEO
//
+76 -48
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
//
@@ -1791,7 +1819,7 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
#ifdef HWRENDER
// Software-only compile cache the data without conversion
if (rendermode == render_opengl)
if (patch != NULL && rendermode == render_opengl)
Patch_CreateGL(patch);
#endif
+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
+15 -61
View File
@@ -73,7 +73,6 @@ static huddrawlist_h luahuddrawlist_intermission = NULL;
static huddrawlist_h luahuddrawlist_vote = NULL;
static void Y_FollowIntermission(void);
static void Y_UnloadData(void);
// SRB2Kart: voting stuff
// Level images
@@ -112,8 +111,6 @@ static y_voteclient voteclient;
static INT32 votetic;
static INT32 voteendtic = -1;
static void Y_UnloadVoteData(void);
//
// SRB2Kart - Y_CalculateMatchData and ancillary functions
//
@@ -789,7 +786,7 @@ void Y_StartIntermission(void)
break;
}
bgtile = W_CachePatchName("SRB2BACK", PU_PATCH);
bgtile = W_CachePatchName("SRB2BACK", PU_PATCH_LOWPRIORITY);
LUA_HUD_DestroyDrawList(luahuddrawlist_intermission);
luahuddrawlist_intermission = LUA_HUD_CreateDrawList();
@@ -802,9 +799,6 @@ void Y_StartIntermission(void)
//
void Y_EndIntermission(void)
{
if (!dedicated)
Y_UnloadData();
endtic = -1;
sorttic = -1;
intertype = int_none;
@@ -821,20 +815,6 @@ static void Y_FollowIntermission(void)
G_AfterIntermission();
}
#define UNLOAD(x) {if ((x) != NULL) {Patch_Free(x);} x = NULL;}
//
// Y_UnloadData
//
static void Y_UnloadData(void)
{
// unload the background patches
UNLOAD(VoteScreen.bgpatch);
UNLOAD(VoteScreen.widebgpatch);
UNLOAD(bgtile);
//UNLOAD(interpic);
}
// SRB2Kart: Voting!
//
@@ -877,8 +857,8 @@ static void Y_VoteScreenCheck(void)
// non lua vote background handling
boolean prefbattletype = ((votelevels[0][1] & ~0x80) == GT_MATCH);
VoteScreen.widebgpatch = W_CachePatchName((prefbattletype ? "BATTLSCW" : "INTERSCW"), PU_PATCH);
VoteScreen.bgpatch = W_CachePatchName((prefbattletype ? "BATTLSCR" : "INTERSCR"), PU_PATCH);
VoteScreen.widebgpatch = W_CachePatchName((prefbattletype ? "BATTLSCW" : "INTERSCW"), PU_PATCH_LOWPRIORITY);
VoteScreen.bgpatch = W_CachePatchName((prefbattletype ? "BATTLSCR" : "INTERSCR"), PU_PATCH_LOWPRIORITY);
}
//
@@ -926,7 +906,7 @@ static void Y_DrawLuaVoteScreenPatch(boolean widePatch)
// Draw non animated patch
if (!tempfoundAnimLuaVoteFrames)
{
votebg = W_CachePatchName(va("%s1", tempPrefix), PU_PATCH);
votebg = W_CachePatchName(va("%s1", tempPrefix), PU_PATCH_LOWPRIORITY);
Y_VoteBackgroundDrawer(votebg);
return;
}
@@ -939,7 +919,7 @@ static void Y_DrawLuaVoteScreenPatch(boolean widePatch)
nextframe = (VoteScreen.currentAnimFrame + 1);
votebg = W_CachePatchName(va("%s%d", tempPrefix, nextframe), PU_PATCH);
votebg = W_CachePatchName(va("%s%d", tempPrefix, nextframe), PU_PATCH_LOWPRIORITY);
Y_VoteBackgroundDrawer(votebg);
@@ -1481,14 +1461,14 @@ static void Y_InitVoteDrawing(void)
// setup the background patches
Y_VoteScreenCheck();
VoteScreen.cursor[0] = W_CachePatchName("M_CURSOR", PU_PATCH);
VoteScreen.cursor[1] = W_CachePatchName("P1CURSOR", PU_PATCH);
VoteScreen.cursor[2] = W_CachePatchName("P2CURSOR", PU_PATCH);
VoteScreen.cursor[3] = W_CachePatchName("P3CURSOR", PU_PATCH);
VoteScreen.cursor[4] = W_CachePatchName("P4CURSOR", PU_PATCH);
VoteScreen.cursor[0] = W_CachePatchName("M_CURSOR", PU_PATCH_LOWPRIORITY);
VoteScreen.cursor[1] = W_CachePatchName("P1CURSOR", PU_PATCH_LOWPRIORITY);
VoteScreen.cursor[2] = W_CachePatchName("P2CURSOR", PU_PATCH_LOWPRIORITY);
VoteScreen.cursor[3] = W_CachePatchName("P3CURSOR", PU_PATCH_LOWPRIORITY);
VoteScreen.cursor[4] = W_CachePatchName("P4CURSOR", PU_PATCH_LOWPRIORITY);
VoteScreen.randomlvl = W_CachePatchName("RANDOMLV", PU_PATCH);
VoteScreen.rubyicon = W_CachePatchName("RUBYICON", PU_PATCH);
VoteScreen.randomlvl = W_CachePatchName("RANDOMLV", PU_PATCH_LOWPRIORITY);
VoteScreen.rubyicon = W_CachePatchName("RUBYICON", PU_PATCH_LOWPRIORITY);
}
void Y_StartVote(void)
@@ -1573,9 +1553,9 @@ void Y_StartVote(void)
{
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votelevels[i][0]+1)));
if (lumpnum != LUMPERROR)
levelinfo[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votelevels[i][0]+1)), PU_PATCH);
levelinfo[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votelevels[i][0]+1)), PU_PATCH_LOWPRIORITY);
else
levelinfo[i].pic = W_CachePatchName("BLANKLVL", PU_PATCH);
levelinfo[i].pic = W_CachePatchName("BLANKLVL", PU_PATCH_LOWPRIORITY);
}
}
@@ -1589,35 +1569,9 @@ void Y_StartVote(void)
// Y_EndVote
//
void Y_EndVote(void)
{
Y_UnloadVoteData();
voteendtic = -1;
}
//
// Y_UnloadVoteData
//
static void Y_UnloadVoteData(void)
{
voteclient.loaded = false;
if (dedicated)
return;
UNLOAD(VoteScreen.widebgpatch);
UNLOAD(VoteScreen.bgpatch);
UNLOAD(VoteScreen.cursor[0]);
UNLOAD(VoteScreen.cursor[1]);
UNLOAD(VoteScreen.cursor[2]);
UNLOAD(VoteScreen.cursor[3]);
UNLOAD(VoteScreen.cursor[4]);
UNLOAD(VoteScreen.randomlvl);
UNLOAD(VoteScreen.rubyicon);
UNLOAD(levelinfo[3].pic);
UNLOAD(levelinfo[2].pic);
UNLOAD(levelinfo[1].pic);
UNLOAD(levelinfo[0].pic);
voteendtic = -1;
}
//
+17 -17
View File
@@ -503,7 +503,7 @@ void Z_CheckHeap(INT32 tag)
{
I_Error("Z_CheckHeap %d: block %u"
#ifdef ZDEBUG
"(owned by %s:%d)"
" (owned by %s:%d)"
#endif
" should not exist", i, blocknumon
#ifdef ZDEBUG
@@ -514,13 +514,13 @@ void Z_CheckHeap(INT32 tag)
#endif
if (block->user != NULL && *(block->user) != given)
{
I_Error("Z_CheckHeap"
I_Error("Z_CheckHeap :"
#ifdef ZDEBUG
"at %s %d :"
" %s %d"
#endif
"block %u"
" block %u"
#ifdef ZDEBUG
"(owned by %s:%d)"
" (owned by %s:%d)"
#endif
" doesn't have a proper user"
#ifdef ZDEBUG
@@ -534,13 +534,13 @@ void Z_CheckHeap(INT32 tag)
}
if (block->next->prev != block)
{
I_Error("Z_CheckHeap"
I_Error("Z_CheckHeap :"
#ifdef ZDEBUG
"at %s %d :"
" %s %d"
#endif
"block %u"
" block %u"
#ifdef ZDEBUG
"(owned by %s:%d)"
" (owned by %s:%d)"
#endif
" lacks proper backlink"
#ifdef ZDEBUG
@@ -554,13 +554,13 @@ void Z_CheckHeap(INT32 tag)
}
if (block->prev->next != block)
{
I_Error("Z_CheckHeap"
I_Error("Z_CheckHeap :"
#ifdef ZDEBUG
"at %s %d :"
" %s %d"
#endif
"block %u"
" block %u"
#ifdef ZDEBUG
"(owned by %s:%d)"
" (owned by %s:%d)"
#endif
" lacks proper forward link"
#ifdef ZDEBUG
@@ -574,13 +574,13 @@ void Z_CheckHeap(INT32 tag)
}
if (block->id != ZONEID)
{
I_Error("Z_CheckHeap"
I_Error("Z_CheckHeap :"
#ifdef ZDEBUG
"at %s %d :"
" %s %d"
#endif
"block %u"
" block %u"
#ifdef ZDEBUG
"(owned by %s:%d)"
" (owned by %s:%d)"
#endif
" have the wrong ID"
#ifdef ZDEBUG