Compare commits

...
197 Commits
Author SHA1 Message Date
alufolie91 80da0fc538 fix G_GetDemoDate
forgor to change this back oopsie
2026-11-07 13:52:29 +01:00
alufolie91 014126b57d Merge branch 'origin/polyholes' into Saturn-Next 2026-11-06 17:21:19 +01:00
alufolie91 d7b150a04f (hopefully) make replay date stuff more thread safe
dont do locale stuff from thread, use localtime_r && localtime_r as localtime is not threadsafe either
G_GetDemoDate returns malloc´d buffer again, tho not strictly necessary
also, fix dates not always being initialized in all cases and type issue with G_GetCreationTime
2026-11-06 16:14:39 +01:00
alufolie91 5751f9b29b fix windoze compile
windoze does not have threads.h and thread_local is only a keyword per c23....
thanks michealslop....
2026-11-05 15:55:22 +01:00
alufolie91 1a29bd1e63 Merge branch 'Saturn-Next' into polyholes 2026-11-05 15:38:42 +01:00
alufolie91 e54b6a780d "fix" skywalls on hadal trench and candy lake
this whole sky handling is just incredibly stupid and wouldve been such an easy fix, but here we go
this is just more stupid hacks but i really dont feel bad here since the code already hacked around a bunch of shit
just hoping this wont cause any issues on some maps and needs testing
sigh
2026-11-05 15:38:11 +01:00
alufolie91 c1a0b97c54 add checks for missing bsp lumps
not sure why there werent any, the other map lumps have those, and a corrupted file may have those missing also which would just crash instead of telling you wtf is wrong
2026-11-05 15:38:07 +01:00
alufolie91 b8aaf63b20 use "rawlinedef" when checking for seg issues
smth smth byte order or whatever but is consistent with the rest of the code anyways
2026-11-05 15:38:04 +01:00
alufolie91 d43b60ad83 fix blendmodes and line translucency on polyobject sides in gl
this is also how vanilla kart handled this code eitherways
2026-11-05 15:38:00 +01:00
alufolie91 cb5d3ab4e1 add compile flag for building with thread sanitizer
indev noticed thats a thing that exists
wouldve been quite useful a bunch of times before lol
also some fixes for the other sanitizer flags
2026-11-04 01:42:11 +01:00
alufolie91 eba1cfb94d remove "flatcheck" from HWR_PrecacheLevelFlats
in practice this did nothing really
would be more useful for encore but that aint working for us so whatever
2026-11-04 01:38:30 +01:00
alufolie91 f5030e6a3c fix some holes and cracks in the gl renderer on some maps
hopefully...
this is adapted from the large refactor but that was slow as shit
needs testing to see if this messes with something
2026-11-04 00:27:22 +01:00
indev 3adcf608c3 (Hopefully) fix race condition in replay hut
It was probably caused by menupath being modified when replay load
thread is in the middle of checking it, now the check for "valid"
replay load thread is simpler. Also as comment says, there still are
few reported data races for replaynamesloaded but i THINK it should be
fine, since the only "data race" that could be harmful here is
replaynamesloaded switching from true to false, which would mean
demolist_all is suddenly invalidated, and that shouldn't be possible
because we only switch replaynamesloaded from true to false inside main
thread while also locking the "search mutex"
(this is so wordy lol)
2026-11-04 01:06:18 +03:00
indev 9682ab59c9 Make M_CheckParm thread-safe, it is called from different thread in http-mserv.c for example 2026-11-03 23:56:22 +03:00
alufolie91 51adf8869c HWR_PrecacheLevelTextures should also skip texture number 0
whoopsie
2026-11-02 14:58:55 +01:00
alufolie91 5183baed44 make HWR_ApplyDispoffset a little less ugly lol 2026-11-02 14:41:09 +01:00
alufolie91 e5c6cb635d make teleporter handling in P_ProcessLineSpecial a little less ugly lulul 2026-11-02 14:41:06 +01:00
alufolie91 1ba4fe99a7 fix fof noencore ceiling checks being flipped in opengl renderer
matches software now
even if most  custom maps were made with opengl in mind, stuff did not work anyways for years so this shouldnt hopefully cause any issues
2026-11-02 14:38:56 +01:00
alufolie91 c44d6f6aeb update HWR precache stuff
not much but matches stuff i did for blan
2026-11-02 14:32:12 +01:00
alufolie91 07427b391e dont run horizonline code on fofs in opengl
this currently does NOT work anyways and just wastes time for nothing on some maps
2026-11-02 00:15:38 +01:00
alufolie91 2210bd4e2d opengl: fix opaque fof planes checking the wrong sector for encore remap
it should check its own "master" sector for remap behavior NOT the sector it resides in
note: i did not change the ceiling/floor behavior here as i noticed there might be more issues than this with fofs
2026-10-31 12:51:01 +01:00
alufolie91 f4ac08d09f some smaller mobj related things
mostly cleanup and correctness fixes for phobos build
2026-10-31 12:50:18 +01:00
alufolie91 090580badf replace number with COM_SPLITSCREEN 2026-10-31 12:50:14 +01:00
SteelT 0eacda7494 discord.c: Fix joinSecret memory leak 2026-10-17 16:26:33 +02:00
alufolie91 14df9c01fa send over less mobj stuff in savegame on mobjscaled maps in some cases for phobos build
none of this ever accounted for mapobjectscale
sadly not vanilla compatible but oh well
from https://gitlab.com/kart-krew-dev/ring-racers/-/commit/c4cca8c8b703b4bb23e27be4c3bfd37b9d092215
2026-10-15 16:25:51 +02:00
alufolie91 a69fc07dcf fix smoldering smoke not accounting for mapobject scale (but vanilla compatible)
:chaosleep:
2026-10-15 16:17:33 +02:00
alufolie91 cea97226d5 fix driftdust and respawn lasers not accounting for mapobjectscale (but vanilla compatible)
super annoying, but at least it looks right like that
2026-10-15 14:52:49 +02:00
alufolie91 19a7a4c5c1 remove duped copyright 2026-10-15 10:15:51 +02:00
alufolie91 98d4ab3e9d do not attempt to netsync locally spawned mobjs
it is generally not really advised to locally load addons as a host as that might cause issues
2026-10-15 10:15:48 +02:00
alufolie91 1700db48b4 make player gravstretch and squish properly account for mapobjscale 2026-10-15 09:30:13 +02:00
alufolie91 ba3429f497 software: add helper for getting "wall lights"
slightly less ugly
2026-10-15 09:28:10 +02:00
Alug 3b98d6c44f addfilelocal/autoload: fix showing wrong error when file was not found
W_CheckFileContains returns -1 if file was not found which still triggered those conditions
so just handle if file was not found to skip doing other stuff in those cases
2026-10-14 13:56:31 +02:00
alufolie91 3183ec58ab simpler fix for localskin minimap angle display crash 2026-10-12 15:13:38 +02:00
alufolie91 46a72bda8e fix crash when applying localskin midgame 2026-10-08 09:24:30 +02:00
alufolie91 156400ffc2 fix arithmetic on NULL pointer when drawing 3d models
caused by localskin code.... sigh......
noticed this while messing with dynamic allocated (local)skins
2026-10-07 20:25:56 +02:00
alufolie91 116fbd93d0 cleanup squishdance stuff a bit
we dont need all those things saved per player really lol
2026-10-07 09:58:20 +02:00
alufolie91 30affaf451 cleanup saltyhop a little, move it to player struct 2026-10-07 09:58:20 +02:00
alufolie91 d66020e3a9 fix localskin menu not showing localskin 3d models
this should use the skins localnumber not the "actual" skinnumber
yeah localskin code still sucks....
fixes https://github.com/Indev450/SRB2Kart-Saturn/issues/230
2026-10-04 00:56:25 +02:00
alufolie91 4749d1a108 OpenGL: prefer GL_RGBA for fbo texture
as recommended per https://wikis.khronos.org/opengl/Common_Mistakes
2026-10-01 19:30:09 +02:00
alufolie91 36d13734f6 v10.1 2026-09-27 17:53:52 +02:00
alufolie91 3fc5f572bb fix CMake again............ 2026-09-27 17:35:05 +02:00
alufolie91 d65319a9fc fix "Modulative" blendmode in software
forgot to account it when the gamma correction stuff was ported
2026-09-27 17:15:42 +02:00
alufolie91 1d8b066a64 fix desynchs with vanilla on Sewer System
read the sectornode list stuff
this means we reuse old stale data in some cases, which also causes strange bugs with orbiting items in some cases, but thats what vanilla does and we HAVE to keep vanilla compat after all
i really hope this does not cause any fun impossible to debug crashes, but what can you do
2026-09-26 15:12:28 +02:00
alufolie91 e6033322c6 disable phobos in cmake
stupid copy paste error
2026-09-26 12:03:05 +02:00
alufolie91 d988876bca change version number for phobos
phobos is NOT vanilla compatible and is not meant to be
this should prevent the game be able to connect to vanilla servers hopefully
2026-09-26 11:57:33 +02:00
alufolie91 7e92482ced add orbit mobj check into K_MoveHeldObjects 2026-09-25 22:07:09 +02:00
alufolie91 fa753c3694 Revert "cleanup and make safer, orbit item handling in K_MoveHeldObjects"
This reverts commit 5e1ae2155f.
2026-09-25 22:03:03 +02:00
indev 58403cf4a5 Revert "Prevent orbit from being freed by using P_SetTarget in K_RepairOrbitChain"
This reverts commit 13241d1880.
2026-09-25 22:04:15 +03:00
indev 13241d1880 Prevent orbit from being freed by using P_SetTarget in K_RepairOrbitChain 2026-09-25 21:54:49 +03:00
alufolie91 91f016fd0c remove inline from P_TagDamage
not only this is basically unused its also quite huge
so no need to inline this at all
2026-09-25 20:34:49 +02:00
alufolie91 5e1ae2155f cleanup and make safer, orbit item handling in K_MoveHeldObjects
based on https://gitlab.com/kart-krew-dev/ring-racers/-/commit/4e9d2295c9da30888fea77825c276bac831aecb3
2026-09-25 20:32:31 +02:00
alufolie91 dd2a227529 mobj hnext/hprev list fixes for phobos build
too lazy to cherry pick so
https://gitlab.com/kart-krew-dev/ring-racers/-/commit/a392996a5437742d5b7a91d0fce9da49c3a8bd76
and
https://gitlab.com/kart-krew-dev/ring-racers/-/commit/8b5bd645ca5d8ef9269aa6ccf4375337bd0c1672

both of which might change behavior so phobos only
2026-09-25 19:03:46 +02:00
alufolie91 9521183eb3 cast this to boolean
no effective change just wanna be more explicit there
2026-09-23 19:17:13 +02:00
alufolie91 56bb20f4e1 cleanup controller menu stuff a little more 2026-09-23 18:31:49 +02:00
alufolie91 604fa7281b dont reset JoyInfo in I_InitJoystick
seems to fix wonky behavior when changing controllers per player
2026-09-23 18:24:44 +02:00
indev 2c9a82e2d3 20 2026-09-21 22:36:41 +03:00
alufolie91 4f7e296885 fun times with M_DoAssignJoystick
my tired ass forgor cv_usejoystick gets reassinged within this, so the cvar string also changes
2026-09-21 20:41:01 +02:00
indev c917708184 Actually change command name to useprefcolor, so its a bit more intuitive 2026-09-21 20:57:18 +03:00
indev 110e93f4ed Add command to change skin color to prefcolor 2026-09-21 20:53:44 +03:00
orbitalviolet a0d6d452a0 Fix regression #1507 2026-09-21 18:41:10 +02:00
alufolie91 7fb3f7a1aa YES THANKS MICHEALSOFT VERY COOL 2026-09-21 17:32:08 +02:00
Roberto Ierusalimschy 7e906074ec keep memory-error message in the global state, so that its use
does not depend on Lua internalizing strings to avoid a string
creation on memory errors
2026-09-21 17:14:21 +02:00
alufolie91 de35e086d3 use strnlen in W_CheckNumForNamePwad
we clamped this to a length of 8 eitherways
so might aswell just use strnlen which is safer in any case
2026-09-21 16:44:56 +02:00
alufolie91 295b35b23a cleanup p_mobj + more safety
big cleanups and more mobj checks
needs to be rechecked since its quite a lot
2026-09-21 16:38:54 +02:00
alufolie91 a5b6dad8f3 cleanup p_enemy + more safety
add a crapton of checks for removed mobjs
copy pasted from srb2 mainly
2026-09-21 16:37:40 +02:00
alufolie91 d024992144 clean up Command_connect 2026-09-21 16:34:33 +02:00
alufolie91 3df604e8b6 expand sector flags
include gravflip, heatwave, noclipcam and invertencore
is a bit cleaner
may also add the special flags at some point to clean things up a bit more
2026-09-21 16:33:21 +02:00
alufolie91 080f586c19 simplify W_CheckNumForNamePwad
pretty much what blankart does
avoids doing a bunch of string work
2026-09-21 16:31:18 +02:00
indev 0e62afd348 Count lua memory for total usage in memfree command 2026-09-21 17:24:43 +03:00
indev 648d3c439b Change lua to not use z_zone allocator 2026-09-21 17:24:43 +03:00
NepDisk 1dd3e90363 Make memdump show block tags 2026-09-21 16:22:22 +02:00
NepDisk c78c0d1657 Fix memory block not being moved to correct taglist with Z_ChangeTag
I didn't even notice this one at first, whoops! Also added proper checking to prevent this from happening again.
2026-09-21 16:22:01 +02:00
NepDisk 838d05eef7 Convert Z_Zone head into a list similar to thinkerlists
I was thinking to myself about how 2.1 and before did thinkers and how 2.2 made it into thinker lists and thought "wait isn't memory allocated similar to that?" and well here we are.
2026-09-21 16:21:40 +02:00
alufolie91 3c3e8dd986 use Z_TotalUsage for memory debug display 2026-09-19 21:09:20 +02:00
alufolie91 2d79ff9606 few more smoler style cleanups 2026-09-17 11:44:15 +02:00
alufolie91 70f4207e02 smol fix for pm´s in DoSayCommand
sending a pm might change the length of the string which we need to reconsider when sending the cmd
2026-09-17 11:40:52 +02:00
alufolie91 242754f811 disable flat precaching in opengl in encoremode
this appears to mess up remapping behavior in certain cases (ex. sneaker/spring panels)
since i cba looking into properly fixing this, ill just disable this for now
2026-09-12 16:53:26 +02:00
alufolie91 521544f6ba raise skinlimit to 1024 for phobos build
not thoroughly tested by me, so might still be incomplete
2026-09-03 19:34:56 +02:00
alufolie91 efc0681e01 make PHOBOS_BUILD a compile flag
pass PHOBOS_BUILD=1 to build
2026-09-03 19:30:55 +02:00
alufolie91 4c3fa7d826 raise numlap limit to 255 for phobos client
idk but this was wanted
2026-09-03 19:21:18 +02:00
alufolie91 ac87678708 rename COMPAT_VANILLA to PHOBOS_BUILD
have a distinct name for that build "Phobos", as a nod to Doom
also invert the flag, as it should make adding stuff less headachey
will make this a compiler flag later but too lazy atm
2026-09-03 18:47:45 +02:00
alufolie91 a6e5edabd2 fix M_TextInputSetString not null terminating in some cases
if input string is longer than the buffer this may never be null terminated properly
2026-09-02 15:05:43 +02:00
alufolie91 24e5b1d84b fix buffer overflow when opening "Advanced Color Options"
idk if this is the intended thing, but works fine
2026-09-02 14:40:49 +02:00
alufolie91 ade7db9004 fix replayhut exploding due to sega fishe
"sega_bass_fishin" is exactly 16 characters which caused stuff to not be terminated
2026-09-02 14:09:33 +02:00
indev 819b171d90 Do a full garbage collection after LUA_InvalidateLevel 2026-08-28 00:44:49 +03:00
GenericHeroGuy 882716e911 Make Valgrind builds usable when not running with Valgrind + cleanup 2026-08-24 11:34:55 +02:00
alufolie91 5644036d25 macrofy Z_CheckHeap errors
stuff was slightly ugly and unwieldy.
making it a macro also makes adding new errors less messy
2026-08-24 10:30:28 +02:00
alufolie91 de74c9251f make HWR_AddPolyObjectPlanes a little less ugly 2026-08-23 16:40:31 +02:00
alufolie91 1552b1808f "about" 2026-08-21 16:51:04 +02:00
alufolie91 fd349e2b37 netsync mobj pmomz in non vanilla compat builds
may help with some join desynchs
2026-08-18 17:39:19 +02:00
alufolie91 0cf1cabcc2 basic 32 player support
can just be enabled per MAXPLAYERS define in doomdef
this will also auto undefine COMPAT_VANILLA
no support for tab rankings or intermission rankings at all yet
will port those over eventually from saturn 32p or blankart and clean stuff up
please note this may have bugs since not everything is ported over yet
2026-08-18 17:39:19 +02:00
alufolie91 bcbe765b9d fix potential buffer underflow in portal handling
P_FindSpecialLineFromTag may return -1 in some cases
2026-08-17 19:19:51 +02:00
alufolie91 eca3effb3b raise version to v10
was originally be 9.3 but this update is too massive to be a minor version update
2026-08-17 18:47:42 +02:00
Gustaf Alhäll f1380a276e Fix buffer overflow when running map scripts 2026-08-17 18:43:08 +02:00
James R 8ffeab1646 Reset wait period for COM_BufInsertText 2026-08-17 16:39:27 +02:00
alufolie91 2eb175c356 few more smaller code cleanups 2026-08-17 16:39:23 +02:00
alufolie91 4e606fc7de fix indentation 2026-08-10 15:50:35 +02:00
Gustaf Alhäll c5116dea1a Add support for OpenBSD 2026-08-10 15:50:32 +02:00
alufolie91 924f9c2151 put directory changing and getting stuff into functions
from https://gitlab.com/kart-krew-dev/ring-racers/-/commit/7ef40f5d743bf6bf251e2edc89cda23e8fb36ee5

changed a bit so windows also can print the "warning" on failure
2026-08-10 15:38:31 +02:00
alufolie91 e0fa53e4df demonames apparently should write one less character
better keep it like this
2026-08-10 15:33:40 +02:00
alufolie91 eeb7d48a6f one more snprintf replacement for next branch 2026-08-09 17:51:39 +02:00
alufolie91 df291710d8 replace a few more length magic numbers with sizeof
just to be sure really
2026-08-09 17:49:34 +02:00
alufolie91 16577877d3 replace all sprintf with snprintf
some of this was taken from https://gitlab.com/kart-krew-dev/ring-racers/-/commit/59f23dfa181327ed5c00f55688840d39e3583569 so thx!
should fix apple clang warnings and is alot safer to have all this crap be bounded
theres prob alot more other stuff, and id love to eventually replace all the strcpy family functions with snprintf and equivalent
2026-08-09 17:49:31 +02:00
alufolie91 309d459a70 fix apple clang warning for music test
define this as constant otherwise compiler may treat the array as being variable in size for some reason
2026-08-09 15:00:52 +02:00
alufolie91 e1430f7bc7 replace magic number with sizeof 2026-08-08 19:07:56 +02:00
alufolie91 bf70beb88a cleanup SV_SendServerInfo a little
mostly just make it more readable by using ptr
2026-08-08 19:03:31 +02:00
alufolie91 a951622f6a ensure serverinfo "application" is null terminated
not strictly needed but better be safe than sorry
2026-08-08 19:00:13 +02:00
alufolie91 d7db0d68dc ensure serverinfo mapname is null terminated
forgor back then
2026-08-08 18:53:55 +02:00
alufolie91 2b9224cc3f forgor to update player names comment 2026-08-08 18:09:45 +02:00
alufolie91 0a750cd3bc cleanup gl shadow checks
just move em into the function to be less ugly
2026-08-08 17:38:20 +02:00
alufolie91 0e8a32612f move player_name init to D_RegisterServerCommands
runs before registering client commands and is for everything server + client needs
2026-08-08 17:31:27 +02:00
Monster Iestyn 3c6882203b Initialise player_names[] in D_RegisterClientCommands such that we don't need to have to manually update it if MAXPLAYERS ever changed 2026-08-08 17:31:23 +02:00
alufolie91 0464a8b0c7 attempt to mitigate "palette" cvar allowing random lumps to be used as palette
if theres a proper way to check for actual palettes pls tell me thx
2026-08-07 20:14:48 +02:00
alufolie91 599eda96aa fix M_ScrollString not null terminating its output
this caused music test to have non terminated strings
2026-08-07 19:36:51 +02:00
alufolie91 421d735052 fix compiler complains when compiling with valgrind support 2026-08-06 22:16:50 +02:00
alufolie91 73bc64f9da fix clamp assert in HWR_SplitWall
idk man it really hates if lo > hi apparently lol
2026-08-06 22:16:48 +02:00
alufolie91 5d807d65e5 smol style fix
less confusing
2026-08-06 17:43:15 +02:00
alufolie91 88d86a6e60 fix NOMUMBLE compile
idk how and why this breaks, but I_OutputMsg is in  doomdef anyways for god knows why
2026-08-06 17:05:09 +02:00
alufolie91 b2cdbaae60 fix protocol register thingie 2026-08-06 16:58:07 +02:00
alufolie91 9160431556 fix compile for android bionic c lib 2026-08-06 16:58:01 +02:00
alufolie91 2f9a400cf3 cmake flag for mumble
stimky
2026-08-06 16:51:51 +02:00
alufolie91 c39073dd9e fix arm compile
idk why i added this, if this is ever needed for whatever pls yell at me
2026-08-06 15:09:48 +02:00
alufolie91 f03692b840 delet duped MobjThinker check 2026-08-05 22:50:11 +02:00
MIDIMan 617e8fdd55 Manually set NetVars's hook_type
Also adds a 2.3 TODO comment for MF_AMBIENT
2026-08-05 22:49:53 +02:00
alufolie91 d5252bd3b3 fix an oopsie in p_mobj.c
prob did that while sleep deprived, P_WeaponOrPanel includes a few more things than intended to be there
doubt we even use any of those, but i dont want to cause any potential issues agaion
2026-07-28 20:49:23 +02:00
alufolie91 94f46c3ce6 also prevent "local" pushable mobjs from executing linedef actions
missed when i did the other, pushables have a seperate executor special
2026-07-25 09:24:59 +02:00
alufolie91 c3e709231d Merge branch 'luaprofile' into Saturn-Next 2026-07-24 16:18:59 +02:00
alufolie91 7878e01e3f update copyrights for "core" folder 2026-07-24 16:15:56 +02:00
alufolie91 4631844c9f revert removing the slopelanding dupe
dont think this would cause any issues at all, but i dont feel like maybe causing some dumbass edge cases anywhere really
can test this further after v10 release since its already taking ages
2026-07-24 16:07:28 +02:00
alufolie91 e0e8be8d46 perfstats thinkframe maxpage fix from blan
+ also yoink the ps types to get rid of magic numbers
just prevents the cvar being set to a page that does not exist
2026-07-24 15:47:44 +02:00
alufolie91 7e47b9b6ba fix crash in K_drawKartMinimapHead if player mobj was removed 2026-07-24 07:36:47 +02:00
romoney5 6e91e00289 Ignore scenery thinker for player objects
Prevents Lua from being able to remove player objects using MF_SCENERY
and causing potential crashes
2026-07-24 07:36:43 +02:00
alufolie91 a539f38e72 add more safety checks to some maploading stuff
+ rename things to make more sense
2026-07-21 20:33:46 +02:00
alufolie91 4f21d8f983 dont apply lua rumble during replay playback
same as non lua rumble
2026-07-21 16:05:11 +02:00
alufolie91 31517ebebe smol fbo stuff cleanup
was from the water branch
2026-07-21 15:54:18 +02:00
alufolie91 3a2e009d01 have the musiccredit "box" style be colourized 2026-07-21 15:52:02 +02:00
alufolie91 38e50a3cfb bit more p_mobj cleanup
more unnesting stuffs
2026-07-21 15:31:33 +02:00
alufolie91 97555bc263 remove trailing whitespaces from musicdef fields
mostly just to prevent the warning popping from those, but also why not lol
2026-07-21 15:03:38 +02:00
alufolie91 848115d105 print the unedited musicdef field for whitespace warning
otherwise this may just show whitespaces where they arent ones originally
2026-07-21 15:03:27 +02:00
alufolie91 3668c2c4f3 more code cleanups
+ remove duped slopelanding stuff
mostly just unnesting stuffs, some mobj checks, etc
2026-07-21 14:44:56 +02:00
alufolie91 d5f68bf2aa fix compiler warning for sound stuff.....
:chaosleep:
2026-07-20 16:33:51 +02:00
alufolie91 3ae968f060 smol random cleanups 2026-07-20 16:08:55 +02:00
alufolie91 d73f79509e actually reduce pointinsubsector in P_SpawnMapThings in some cases lol
bunch of vanilla maps have rings and stuff present lul
2026-07-20 16:05:04 +02:00
MIDIMan 19e9eedce3 Fix NiGHTS hoops crashing the game for mid-level netgame joiners 2026-07-20 15:50:16 +02:00
alufolie91 8880057ff2 fix and cleanup P_SpawnMapThings
-split emeraldhunt handling into its own function
-merge hoop spawn loop into the main mapthing spawnloop
-continue early for things like rings and coins
- reduce the amount of R_PointInSubsector on maps with nights hoops
hopefully reduces levelload time slightly
2026-07-20 15:50:13 +02:00
alufolie91 9692484d2e fix issues with sound freeslotting
this "works" with a skinlimit of 255
but would cause hard to debug crashes with raised skinlimits and was generally really unsafe and could cause soundnames to not be null terminated aswell as buffer overflows from blind strcpy
the sprintf fix is from Indev originally for neptune
NOTE: if the skinlimit is ever raised above 1024 then freeslotnames NEEDS to be atleast one byte bigger to not truncuate stuff
NOTE2: pretty sure localskins are fucked if any are loaded in servers with 255 skins loaded, but i dont care atm
2026-07-20 11:29:19 +02:00
alufolie91 df3a64339c fix skin search command overflow
when using localskins and going over the skinlimit
this should use numskins not numallskins there
no i dont feel like supporting localskins here the other skin commands also dont care
2026-07-20 01:01:09 +02:00
indev 5a966aa317 Re-add playernode check 2026-07-20 01:54:47 +03:00
indev a132db9e6e Attempt to fix server locking up when trying to kick player that has left already 2026-07-19 23:41:19 +03:00
alufolie91 0acfc96812 attempt to fix kick/ban commands causing dedicated servers to self destruct
if a player was specified which was not being in game
this is what caused dedis to sometimes go to the main menu
2026-07-19 06:16:50 +02:00
alufolie91 f09c61cee9 only play stairjank sound if we have its visuals enabled 2026-07-19 02:42:18 +02:00
alufolie91 735c4b67dc move stairjank particles into K_MoveKartPlayer
to where we also rotate the player
also means we now use K_AltFlip :p
also means the visual toggle now actually does prevent spawning them
2026-07-19 02:40:17 +02:00
alufolie91 267a758447 fix up dedi i_system 2026-07-19 02:36:16 +02:00
indev 6892c212d1 Comment out stairjank particles for now, since spawning mobjs during P_TryMove may mess up some global variables 2026-07-19 03:31:09 +03:00
alufolie91 a1127068df fix wireframe potentially not disabling on toggle
netupdate sucks ass
2026-07-17 22:43:23 +02:00
alufolie91 7ee93d889e remove this from polyvertex_t
was used for optimization but not used anymore
2026-07-16 20:16:42 +02:00
alufolie91 ee9c9e2839 hack: fix paletterender stuff not applying to screenshots/gifs when using downsampling fbo
this sucks
but the final screen texture with the palette render postprocess step will not be in the downsample fbo
so we have to redraw it there with the postprocess step......
this is still better than drawing another screen texture when using paletterender which costs perf
2026-07-14 11:28:49 +02:00
alufolie91 28c4061a26 remove viewsky which doesent exist lol 2026-07-14 09:40:37 +02:00
alufolie91 d0f02f1530 remove pointless skybox check here
if skybox then newview->sky will be false there which R_DrawSkyPlanes will check for
2026-07-14 09:40:35 +02:00
alufolie91 53fbbecbcd fix incrementing garbage in Portal_AddSkyboxPortals 2026-07-14 03:00:42 +02:00
indev 587f24ae85 Add empty I_OpenURL into dedicated server build 2026-07-13 23:56:53 +03:00
alufolie91 ba0b414062 fix paletterender toggle calling setpalette during startup 2026-07-13 20:31:30 +02:00
alufolie91 b27b4bfd7a software: fix cv_spriteclip
scaled sprites should be excluded from the simple viewwindow checks
also R_CheckSpriteVisible should be done AFTER portal adjustments
2026-07-13 07:47:51 +02:00
alufolie91 7971f76885 software: cleanup sky hacks
still horrid, but atleast this wont give me braindamage each time i have to look at it
this also read stale data from the previous frames and was just insanely messy
this still sucks ass but oh well
2026-07-13 07:47:48 +02:00
alufolie91 7048eeacc3 Portal_AddSkybox can be static
its unused anyways
also adds plane bounds check which was missing
2026-07-13 07:44:47 +02:00
alufolie91 8a62f4e978 software: move hom removal to R_RenderPlayerView
gl also has it there so why not
2026-07-13 07:44:38 +02:00
Eidolon f5fdf917bd Support >4GB sys mem in memfree for linux, win32, macOS sys mem counts
Also includes memory counts for the extended allocation functionality
2026-07-13 07:44:33 +02:00
alufolie91 b9ac91c74f fix eggbox crap
:chaosleep:
2026-07-09 23:49:16 +02:00
indev b408a098bd Fix netxcmdnames missing one name 2026-07-09 13:01:13 +03:00
alufolie91 90ab1f4994 cleanup opengl wipe stuff a little
split it like srb2.2
2026-07-09 06:47:26 +02:00
alufolie91 96484c94db fix & cleanup hw_bsp
this basically brings it to the latest state from Doom-Legacy before the big refactor (which i had previously ported and tested as well) + some extra stuff from it
sadly this does not seem to fix plane holes, but its a bit cleaner and more accurate in some places
while the big refactor did fix issues with plane holes, it also introduced a few new issues, like z-fighting sneaker panels and significantly longer loading times
may as well just wait at this point for what (or rather if) RR will be doing
2026-07-09 06:47:26 +02:00
alufolie91 c805fa9f33 remove a bunch of unused crap 2026-07-09 06:46:27 +02:00
alufolie91 29159ca5cd whoopsie
sleeby....
2026-07-08 20:37:16 +02:00
alufolie91 b6b70ae8f0 Add "Report an Issue" button in the Saturn Menu
yoinked from SRB2-Legacy
2026-07-08 20:33:24 +02:00
alufolie91 2b0e4b7468 have fallback if SDL_OpenURL fails or does not exist on the Error box 2026-07-08 20:33:20 +02:00
alufolie91 c374bd75fc menu for controller rumble stuff 2026-07-07 13:10:05 +02:00
alufolie91 ec70e8aa29 only apply LUA controller rumble and led color to local players
what my dumb ass was meaning to do with 2ae1e0f56e
displayplayer[0] does not necessarily map to a local player!
2026-07-06 04:59:33 +02:00
alufolie91 3ad6159e85 make controller rumble types toggable separately
needs a proper menu, but too lazy for that currently
2026-07-05 22:51:29 +02:00
alufolie91 2ae1e0f56e only rumble controllers for local players
also not in replays
2026-07-05 22:25:39 +02:00
alufolie91 2302d4efbd mark R_ThingIsFullBrightT as static 2026-07-05 21:36:51 +02:00
alufolie91 be08c9cd1f changes to some saturn specific visual effects
most of those were added cause they´re cool to look at, but without much thought about potentially giving players that enable such features an "unfair" advantage over others.
- eggboxes wont be rotated while stationary and on the ground anymore (they are meant to deceive players, being rotated makes them stand out alot!)
- players that are about to explode due to eggboxes wont spawn extra red speedlines anymore
- option to show driftlevel per speedlines has been removed
2026-07-05 21:36:48 +02:00
alufolie91 7b91666db9 clean up some frameflags stuff
mfw no FF_VERTICALFLIP
2026-07-04 20:17:03 +02:00
alufolie91 ba5c85ba8a :chaosleep: 2026-07-04 06:21:06 +02:00
alufolie91 05e8771fbc Revert "add warning if theres no music lump for musicdef"
This reverts commit 59b7b0529f.
very fun if the music lumps were split into some other file!
2026-07-03 19:08:54 +02:00
alufolie91 59b7b0529f add warning if theres no music lump for musicdef
if theyre left over or typo´d (which prevents them from showing up)
2026-07-03 19:01:10 +02:00
alufolie91 3fa8ab442a print warning if whitespaces are encountered in musicdef fields
technically that is a non issue for saturn but vanilla will completely explode from this
2026-07-03 18:27:49 +02:00
indev fdd8381258 Fix 'attack or protect' text being offcentered on certain resolutions 2026-07-03 15:10:08 +03:00
alufolie91 41cbce3ed3 hack for kartdebugcheckpoint display
see comment
2026-07-02 19:43:06 +02:00
alufolie91 63e4c5a63d use viewsin and viewcos for spherefrustum checks in gl
dont need all those yaw vars, since they effectively map to gl_viewsin and -gl_viewcos respectively
while those are less accurate due to being fixed point, there appears to be no visual issues from this and seems to even slightly improve performance in some cases
2026-07-02 18:34:32 +02:00
alufolie91 bba86fe4af fix DRAWONLYFORX sprite visability handling
this effectively didnt do anything and had a typo for the player 3 case anyways
2026-07-02 18:34:29 +02:00
alufolie91 1dee3060dd add some more mobj checks to p_map
cross-checked against srb2 next branch
2026-07-02 18:34:22 +02:00
alufolie91 56c2178bde cleanup COMPAT_VANILLA mobj checks
move stuff into a helper func, which just returns if mo != NULL in vanilla compat mode, otherwise returns P_MobjWasRemoved
reasoning for this crap is in the comment above said helper
2026-07-02 18:34:19 +02:00
alufolie91 e445669521 cleanup stuff a bit for unused gametypes
wish could just remove all of this but gotta keep it for compat reasons ig
2026-07-02 18:34:06 +02:00
alufolie91 7a309bc0b8 make this less messy 2026-07-01 22:45:37 +02:00
alufolie91 8b6ebfbad4 promote those null checks again.....
sigh......
atleast this should be right this time
2026-07-01 22:26:50 +02:00
indev 5775c12b16 Disable writing to replay query while replays are loading 2026-07-01 23:23:04 +03:00
alufolie91 78ebc14d88 print performance warning for lua scripts using mobj hooks without specific mobjtype
thx indev for help <3
these may trash performance quite hard at times
and are not visible from just perfstats most of the time
2026-07-01 19:21:41 +02:00
132 changed files with 6846 additions and 6961 deletions

No files matched your search

+12
View File
@@ -246,6 +246,11 @@ set(SRB2_CONFIG_ASAN OFF CACHE BOOL
"Compile with AddressSanitizer (libasan).")
set(SRB2_CONFIG_UBSAN OFF CACHE BOOL
"Compile with UndefinedBehaviorSanitizer (libubsan).")
set(SRB2_CONFIG_TSAN OFF CACHE BOOL
"Compile with ThreadSanitizer (libtsan).")
set(SRB2_CONFIG_MUMBLE ON CACHE BOOL
"Enable Mumble support")
set(SRB2_CONFIG_SATURNPAK ON CACHE BOOL
"Enable Saturn specific special packet. Required for using the newer resynch system")
@@ -254,6 +259,9 @@ set(SRB2_CONFIG_SATURNJOIN ON CACHE BOOL
set(SRB2_CONFIG_SCREENFBO ON CACHE BOOL
"Enable hardware renderer (OpenGL) FBO downsampling support")
set(SRB2_CONFIG_PHOBOS OFF CACHE BOOL
" Compile the Phobos client. Which contains things not compatible with vanilla, such as raised skinlimits, 32 player support, bugfixes, etc.")
if(${SRB2_CONFIG_DEDICATED})
set(SRB2_CONFIG_HAVE_GME NO)
set(SRB2_CONFIG_HAVE_OPENMPT NO)
@@ -580,6 +588,10 @@ if(${SRB2_CONFIG_SATURNJOIN})
add_definitions(-DDOSATURNJOIN)
endif()
if(${SRB2_CONFIG_PHOBOS})
add_definitions(-DPHOBOS_BUILD)
endif()
# Targets
# Compatibility flag with later versions of GCC
+22 -9
View File
@@ -65,12 +65,17 @@
# DEBUGMODE=1 - Enable various debugging capabilities.
# Also disables optimizations.
#
# PHOBOS_BUILD=1 - Compile the Phobos client.
# Contains things not compatible with vanilla.
# such as raised skinlimits, 32 player support, bugfixes, etc.
#
# Development flags:
#
# VALGRIND=1 - Enable Valgrind memory debugging support.
# PROFILEMODE=1 - Enable performance profiling (gprof).
# USEASAN=1 - Enable building with Address Sanitizer.
# USEUBSAN=1 - Enable building with Undefined Behavior Sanitizer.
# USETSAN=1 - Enable building with Thread Sanitizer.
# NOLIBBACKTRACE=1 - Disable using Libbacktrace for crashlog traces.
#
# General flags for building:
@@ -246,10 +251,6 @@ ifdef STATIC
libs+=-static
endif
ifneq (,$(filter $(CC) $(CXX),gcc g++))
opts+=-mno-ms-bitfields
endif
# build with profiling information
ifdef PROFILEMODE
opts+=-pg
@@ -261,23 +262,35 @@ debug_opts=-D_DEBUG
else # build a normal optimized version
debug_opts=-DNDEBUG
opts+=-O3
ifndef NOLTO
# compile with LTO
opts+=-flto=auto
libs+=-flto=auto
endif
endif
ifdef USEASAN
# compile with asan
opts+=-O1 -fsanitize=address -fno-omit-frame-pointer -fno-common
libs+=-fsanitize=address
NOLTO=1
endif
ifdef USEUBSAN
# compile with ubsan
opts+=-O1 -fsanitize=undefined -fno-omit-frame-pointer
libs+=-fsanitize=undefined
NOLTO=1
endif
ifdef USETSAN
# compile with tsan
opts+=-O1 -fsanitize=thread -fno-omit-frame-pointer
libs+=-fsanitize=thread
NOLTO=1
endif
ifndef DEBUGMODE
ifndef NOLTO
# compile with LTO
opts+=-flto=auto
libs+=-flto=auto
endif
endif
ifdef USEJEMALLOC
+2 -1
View File
@@ -9,6 +9,7 @@ passthru_opts+=\
HAVE_DISCORDRPC DEVELOP\
NOHOLEPUNCH\
HAVE_IPV6\
PHOBOS_BUILD\
# build with debugging information
ifdef DEBUGMODE
@@ -86,7 +87,7 @@ ifdef VALGRIND
VALGRIND_PKGCONFIG?=valgrind
VALGRIND_LDFLAGS=
$(eval $(call Use_pkg_config,VALGRIND))
ZDEBUG=1
#ZDEBUG=1 we enable this by default
opts+=-DHAVE_VALGRIND
endif
-2
View File
@@ -42,8 +42,6 @@ include Makefile.d/haiku.mk
else ifdef SOLARIS # FIXME: UNTESTED
UNIX=1
platform=solaris
else ifdef CYGWIN32 # FIXME: UNTESTED
platform=cygwin
else ifdef MINGW
ifdef MINGW64
NONX86=1
-10
View File
@@ -15,16 +15,6 @@ sources+=$(call List,sdl/Sourcefile)
NOUPNP=1
# FIXME: UNTESTED
#ifdef PANDORA
#include sdl/SRB2Pandora/Makefile.cfg
#endif #ifdef PANDORA
# FIXME: UNTESTED
#ifdef CYGWIN32
#include sdl/MakeCYG.cfg
#endif #ifdef CYGWIN32
ifndef NOHW
sources+=sdl/ogl_sdl.c
endif
+5 -5
View File
@@ -34,8 +34,8 @@ size_t I_GetFreeMem(size_t *total)
/* return si.freeram; */
char buf[1024];
char *memTag;
UINT32 freeKBytes;
UINT32 totalKBytes;
size_t freeKBytes;
size_t totalKBytes;
INT32 n;
INT32 meminfo_fd = -1;
@@ -46,7 +46,7 @@ size_t I_GetFreeMem(size_t *total)
if (n < 0)
{
// Error
*total = 0L;
*total = 0;
return 0;
}
@@ -54,7 +54,7 @@ size_t I_GetFreeMem(size_t *total)
if (NULL == (memTag = strstr(buf, MEMTOTAL)))
{
// Error
*total = 0L;
*total = 0;
return 0;
}
@@ -64,7 +64,7 @@ size_t I_GetFreeMem(size_t *total)
if (NULL == (memTag = strstr(buf, MEMFREE)))
{
// Error
*total = 0L;
*total = 0;
return 0;
}
+2 -2
View File
@@ -55,8 +55,8 @@ struct lua_longjmp {
void luaD_seterrorobj (lua_State *L, int lerrcode, StkId oldtop) {
switch (lerrcode) {
case LUA_ERRMEM: {
setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG));
case LUA_ERRMEM: { /* memory error? */
setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
break;
}
case LUA_ERRERR: {
-2
View File
@@ -13,8 +13,6 @@
#include "llimits.h"
#include "lua.h"
#define MEMERRMSG "not enough memory"
#define luaM_reallocv(L,b,on,n,e) \
((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \
+1 -1
View File
@@ -143,7 +143,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
}
case 'p': {
char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
sprintf(buff, "%p", va_arg(argp, void *));
snprintf(buff, sizeof(buff), "%p", va_arg(argp, void *));
pushstr(L, buff);
break;
}
+6 -1
View File
@@ -64,6 +64,9 @@ static void freestack (lua_State *L, lua_State *L1) {
}
#define MEMERRMSG "not enough memory"
/*
** open parts that may cause memory-allocation errors
*/
@@ -76,7 +79,9 @@ static void f_luaopen (lua_State *L, void *ud) {
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
luaT_init(L);
luaX_init(L);
luaS_fix(luaS_newliteral(L, MEMERRMSG));
/* pre-create memory-error message */
g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
luaS_fix(g->memerrmsg); /* it should never be collected */
g->GCthreshold = 4*g->totalbytes;
}
+1
View File
@@ -88,6 +88,7 @@ typedef struct global_State {
lua_CFunction panic; /* to be called in unprotected errors */
TValue l_registry;
struct lua_State *mainthread;
TString *memerrmsg; /* memory-error message */
UpVal uvhead; /* head of double-linked list of all open upvalues */
struct Table *mt[NUM_TAGS]; /* metatables for basic types */
TString *tmname[TM_N]; /* array with tag-method names */
+6 -6
View File
@@ -776,23 +776,23 @@ static int str_format (lua_State *L) {
strfrmt = scanformat(L, strfrmt, form);
switch (*strfrmt++) {
case 'c': {
sprintf(buff, form, (int)luaL_checknumber(L, arg));
snprintf(buff, sizeof(buff), form, (int)luaL_checknumber(L, arg));
break;
}
case 'd': case 'i': {
addintlen(form);
sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
snprintf(buff, sizeof(buff), form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
break;
}
case 'o': case 'u': case 'x': case 'X': {
addintlen(form);
sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
snprintf(buff, sizeof(buff), form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
break;
}
case 'e': case 'E': case 'f':
case 'g': case 'G': {
lua_Number n = luaL_checknumber(L, arg);
sprintf(buff, form, (double)n);
lua_Number n = luaL_checknumber(L, arg);
snprintf(buff, sizeof(buff), form, (double)n);
break;
}
case 'q': {
@@ -810,7 +810,7 @@ static int str_format (lua_State *L) {
continue; /* skip the `addsize' at the end */
}
else {
sprintf(buff, form, s);
snprintf(buff, sizeof(buff), form, s);
break;
}
}
+1 -1
View File
@@ -536,7 +536,7 @@
#define LUA_NUMBER_SCAN "%d"
#define LUA_NUMBER_FMT "%d"
#endif
#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
#define lua_number2str(s,n) snprintf((s), LUAI_MAXNUMBER2STR, LUA_NUMBER_FMT, (n))
#define LUAI_MAXNUMBER2STR 12 /* 10 digits, sign, and \0 */
#define lua_str2number(s,p) ({ \
long nmr = strtol((s), (p), 10); \
+9
View File
@@ -206,6 +206,15 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
p += n; \
} while (0)
#ifdef PHOBOS_BUILD
#define WRITESKIN(p,b) WRITEUINT16(p,b)
#define READSKIN(p) READUINT16(p)
#else
#define WRITESKIN(p,b) WRITEUINT8(p,b)
#define READSKIN(p) READUINT8(p)
#endif
#ifdef __cplusplus
} // extern "C"
#endif
+43 -15
View File
@@ -113,18 +113,29 @@ static vsbuf_t com_text; // variable sized buffer
* \param ptext The text to add.
* \sa COM_BufInsertText
*/
void COM_BufAddText(const char *ptext)
void COM_BufAddTextEx(const char *ptext, size_t plen)
{
size_t l;
char *text;
l = strlen(ptext);
if (plen == 0)
plen = strlen(ptext);
text = Z_Malloc(sizeof(char) * (plen+1), PU_STATIC, NULL);
memcpy(text, ptext, plen);
text[plen] = '\0';
l = strlen(text);
if (com_text.cursize + l >= com_text.maxsize)
{
CONS_Alert(CONS_WARNING, M_GetText("Command buffer full!\n"));
return;
}
VS_Write(&com_text, ptext, l);
VS_Write(&com_text, text, l);
Z_Free(text);
}
/** Adds command text and executes it immediately.
@@ -132,8 +143,10 @@ void COM_BufAddText(const char *ptext)
* \param ptext The text to execute. A newline is automatically added.
* \sa COM_BufAddText
*/
void COM_BufInsertText(const char *ptext)
void COM_BufInsertTextEx(const char *ptext, size_t plen)
{
const INT32 old_wait = com_wait;
char *temp = NULL;
size_t templen;
@@ -145,10 +158,14 @@ void COM_BufInsertText(const char *ptext)
VS_Clear(&com_text);
}
com_wait = 0;
// add the entire text of the file (or alias)
COM_BufAddText(ptext);
COM_BufAddTextEx(ptext, plen);
COM_BufExecute(); // do it right away
com_wait += old_wait;
// add the copied off data
if (templen)
{
@@ -159,8 +176,7 @@ void COM_BufInsertText(const char *ptext)
/** Progress the wait timer and flush waiting console commands when ready.
*/
void
COM_BufTicker(void)
void COM_BufTicker(void)
{
if (com_wait)
{
@@ -1596,7 +1612,9 @@ void CV_SaveNetVars(UINT8 **p, boolean isdemorecording)
// send only changed cvars ...
// the client will reset all netvars to default before loading
WRITEUINT16(*p, 0x0000);
for (cvar = consvar_vars; cvar; cvar = cvar->next)
{
if (((cvar->flags & CV_NETVAR) && !CV_IsSetToDefault(cvar)) || (isdemorecording && cvar->netid == cv_numlaps.netid))
{
WRITEUINT16(*p, cvar->netid);
@@ -1614,7 +1632,7 @@ void CV_SaveNetVars(UINT8 **p, boolean isdemorecording)
else
{
char buf[9];
sprintf(buf, "%d", mapheaderinfo[gamemap - 1]->numlaps);
snprintf(buf, sizeof(buf), "%d", mapheaderinfo[gamemap - 1]->numlaps);
WRITESTRING(*p, buf);
}
}
@@ -1626,6 +1644,8 @@ void CV_SaveNetVars(UINT8 **p, boolean isdemorecording)
WRITEUINT8(*p, false);
++count;
}
}
WRITEUINT16(count_p, count);
}
@@ -1719,6 +1739,7 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
// send the value of the variable
UINT8 buf[128];
UINT8 *p = buf;
if (!(server || (IsPlayerAdmin(consoleplayer))))
{
CONS_Alert(CONS_NOTICE, "Only the server or admin can change: %s %s\n", var->name, var->string);
@@ -1782,8 +1803,7 @@ void CV_StealthSet(consvar_t *var, const char *value)
void CV_StealthSetValue(consvar_t *var, INT32 value)
{
char val[32];
sprintf(val, "%d", value);
snprintf(val, sizeof(val), "%d", value);
CV_SetCVar(var, val, true);
}
@@ -1803,8 +1823,7 @@ void CV_Set(consvar_t *var, const char *value)
void CV_SetValue(consvar_t *var, INT32 value)
{
char val[32];
sprintf(val, "%d", value);
snprintf(val, sizeof(val), "%d", value);
CV_SetCVar(var, val, false);
}
@@ -2202,6 +2221,7 @@ void CV_SaveVariables(FILE *f)
consvar_t *cvar;
for (cvar = consvar_vars; cvar; cvar = cvar->next)
{
if (cvar->flags & CV_SAVE)
{
char stringtowrite[MAXTEXTCMD+1];
@@ -2210,15 +2230,23 @@ void CV_SaveVariables(FILE *f)
if (fastcmp(cvar->string, "MAX") || fastcmp(cvar->string, "MIN"))
{
if (cvar->flags & CV_FLOAT)
sprintf(stringtowrite, "%f", FixedToFloat(cvar->value));
{
snprintf(stringtowrite, sizeof(stringtowrite), "%f", FixedToFloat(cvar->value));
}
else
sprintf(stringtowrite, "%d", cvar->value);
{
snprintf(stringtowrite, sizeof(stringtowrite), "%d", cvar->value);
}
}
else
strcpy(stringtowrite, cvar->string);
{
strncpy(stringtowrite, cvar->string, sizeof(stringtowrite)-1);
stringtowrite[sizeof(stringtowrite)-1] = '\0';
}
fprintf(f, "%s \"%s\"\n", cvar->name, stringtowrite);
}
}
}
//============================================================================
+4 -2
View File
@@ -52,10 +52,12 @@ size_t COM_FirstOption(void);
const char *COM_CompleteCommand(const char *partial, INT32 skips);
// insert at queu (at end of other command)
void COM_BufAddText(const char *btext);
#define COM_BufAddText(s) COM_BufAddTextEx(s, 0)
void COM_BufAddTextEx(const char *ptext, size_t plen);
// insert in head (before other command)
void COM_BufInsertText(const char *btext);
#define COM_BufInsertText(s) COM_BufInsertTextEx(s, 0)
void COM_BufInsertTextEx(const char *ptext, size_t plen);
// don't bother inserting, just do immediately
void COM_ImmedExecute(const char *ptext);
+6 -3
View File
@@ -1,7 +1,7 @@
// BLANKART
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@@ -114,6 +114,7 @@ void* PoolAllocator::allocate()
FreeBlock* ret = head_;
head_ = head_->next;
allocated_blocks_++;
return ret;
}
@@ -125,6 +126,7 @@ void PoolAllocator::deallocate(void* p)
FreeBlock* block = reinterpret_cast<FreeBlock*>(p);
block->next = head_;
head_ = block;
allocated_blocks_--;
}
void PoolAllocator::release()
@@ -144,6 +146,7 @@ void PoolAllocator::release()
first_chunk_ = nullptr;
head_ = nullptr;
allocated_blocks_ = 0;
}
static LinearMemory g_frame_memory {4 * 1024 * 1024};
+7 -3
View File
@@ -1,7 +1,7 @@
// SONIC ROBO BLAST 2 KART
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@@ -37,6 +37,7 @@ class PoolAllocator final
FreeBlock* head_;
size_t block_size_;
size_t blocks_;
size_t allocated_blocks_;
int32_t tag_;
ChunkFooter* allocate_chunk();
@@ -47,6 +48,7 @@ public:
, head_(nullptr)
, block_size_(block_size)
, blocks_(blocks)
, allocated_blocks_(0)
, tag_(tag)
{}
PoolAllocator(const PoolAllocator&) = delete;
@@ -59,6 +61,8 @@ public:
void* allocate();
void deallocate(void* p);
constexpr size_t block_size() const noexcept { return block_size_; };
constexpr size_t allocated_blocks() const noexcept { return allocated_blocks_; };
constexpr size_t allocated_bytes() const noexcept { return allocated_blocks_ * block_size_; };
void release();
};
+3 -3
View File
@@ -1,7 +1,7 @@
// SONIC ROBO BLAST 2 KART
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
+3 -3
View File
@@ -1,7 +1,7 @@
// BLANKART
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
+3 -3
View File
@@ -1,7 +1,7 @@
// SONIC ROBO BLAST 2 KART
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
+141 -77
View File
@@ -110,7 +110,7 @@ SINT8 joinnode = 0; // used for CL_VIEWSERVER
boolean player_muted[MAXPLAYERS] = {};
// Server specific vars
UINT8 playernode[MAXPLAYERS] = {};
UINT8 playernode[MAXPLAYERS] = {UINT8_MAX};
// Minimum timeout for sending the savegame
// The actual timeout will be longer depending on the savegame length
@@ -1125,7 +1125,7 @@ static cl_mode_t cl_mode = CL_SEARCHING;
static UINT16 cl_lastcheckedfilecount = 0; // used for full file list
// Player name send/load
#ifndef PHOBOS_BUILD
static void CV_SavePlayerNames(UINT8 **p)
{
INT32 i = 0;
@@ -1161,6 +1161,7 @@ static void CV_LoadPlayerNames(UINT8 **p)
memcpy(player_names[i], tmp_name, MAXPLAYERNAME+1);
}
}
#endif
static void CL_DrawAddonTypes(void)
{
@@ -1629,8 +1630,8 @@ static boolean CL_SendJoin(void)
netbuffer->u.clientcfg.packetversion = PACKETVERSION;
netbuffer->u.clientcfg.version = VERSION;
netbuffer->u.clientcfg.subversion = SUBVERSION;
strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION,
sizeof(netbuffer->u.clientcfg.application));
strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION, sizeof(netbuffer->u.clientcfg.application)-1);
netbuffer->u.clientcfg.application[sizeof(netbuffer->u.clientcfg.application)-1] = '\0';
#ifdef SATURNJOIN
netbuffer->u.clientcfg.issaturn = ISSATURN;
#endif
@@ -1655,88 +1656,91 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
serverinfo_pak *serverinfo = &netbuffer->u.serverinfo;
netbuffer->packettype = PT_SERVERINFO;
netbuffer->u.serverinfo._255 = 255;
netbuffer->u.serverinfo.packetversion = PACKETVERSION;
netbuffer->u.serverinfo.version = VERSION;
netbuffer->u.serverinfo.subversion = SUBVERSION;
strncpy(netbuffer->u.serverinfo.application, SRB2APPLICATION,
sizeof netbuffer->u.serverinfo.application);
serverinfo->_255 = 255;
serverinfo->packetversion = PACKETVERSION;
serverinfo->version = VERSION;
serverinfo->subversion = SUBVERSION;
strncpy(serverinfo->application, SRB2APPLICATION, sizeof(serverinfo->application)-1);
serverinfo->application[sizeof(serverinfo->application)-1] = '\0';
// return back the time value so client can compute their ping
netbuffer->u.serverinfo.time = (tic_t)LONG(servertime);
netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime);
serverinfo->time = (tic_t)LONG(servertime);
serverinfo->leveltime = (tic_t)LONG(leveltime);
// force 1 player
if (UseFakeSeed())
netbuffer->u.serverinfo.numberofplayer = (UINT8)1;
serverinfo->numberofplayer = (UINT8)1;
else
netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers();
serverinfo->numberofplayer = (UINT8)D_NumPlayers();
netbuffer->u.serverinfo.maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value));
serverinfo->maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value));
// SRB2Kart: Vanilla's gametype constants for MS support
netbuffer->u.serverinfo.gametype = (UINT8)((gt == GT_MATCH) ? VANILLA_GT_MATCH : VANILLA_GT_RACE);
serverinfo->gametype = (UINT8)((gt == GT_MATCH) ? VANILLA_GT_MATCH : VANILLA_GT_RACE);
netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame;
netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled();
serverinfo->modifiedgame = (UINT8)modifiedgame;
serverinfo->cheatsenabled = CV_CheatsEnabled();
netbuffer->u.serverinfo.kartvars = (UINT8) (
serverinfo->kartvars = (UINT8) (
(cv_kartspeed.value & SV_SPEEDMASK) |
(dedicated ? SV_DEDICATED : 0)
);
CopyCaretColors(netbuffer->u.serverinfo.servername, cv_servername.string,
MAXSERVERNAME);
strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), sizeof(netbuffer->u.serverinfo.mapname)-1);
CopyCaretColors(serverinfo->servername, cv_servername.string, MAXSERVERNAME);
memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, sizeof(netbuffer->u.serverinfo.mapmd5));
strncpy(serverinfo->mapname, G_BuildMapName(gamemap), sizeof(serverinfo->mapname)-1);
serverinfo->mapname[sizeof(serverinfo->mapname)-1] = '\0';
netbuffer->u.serverinfo.iszone = 0;
memcpy(serverinfo->mapmd5, mapmd5, sizeof(serverinfo->mapmd5));
memset(netbuffer->u.serverinfo.maptitle, 0, sizeof(netbuffer->u.serverinfo.maptitle));
memset(netbuffer->u.serverinfo.httpsource, 0, MAX_MIRROR_LENGTH);
serverinfo->iszone = 0;
memset(serverinfo->maptitle, 0, sizeof(serverinfo->maptitle));
memset(serverinfo->httpsource, 0, MAX_MIRROR_LENGTH);
if (!(mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU) && mapheaderinfo[gamemap-1]->lvlttl[0])
{
strncpy(netbuffer->u.serverinfo.maptitle, mapheaderinfo[gamemap-1]->lvlttl, sizeof(netbuffer->u.serverinfo.maptitle)-1);
strncpy(serverinfo->maptitle, mapheaderinfo[gamemap-1]->lvlttl, sizeof(serverinfo->maptitle)-1);
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
{
if (mapheaderinfo[gamemap-1]->zonttl[0])
{
strncat(netbuffer->u.serverinfo.maptitle, " ", sizeof(netbuffer->u.serverinfo.maptitle)-1);
strncat(netbuffer->u.serverinfo.maptitle, mapheaderinfo[gamemap-1]->zonttl,
sizeof(netbuffer->u.serverinfo.maptitle)-1);
strncat(serverinfo->maptitle, " ", sizeof(serverinfo->maptitle)-1);
strncat(serverinfo->maptitle, mapheaderinfo[gamemap-1]->zonttl, sizeof(serverinfo->maptitle)-1);
}
else
{
netbuffer->u.serverinfo.iszone = 1; // ms and clients will append this themselves
serverinfo->iszone = 1; // ms and clients will append this themselves
}
}
if (mapheaderinfo[gamemap-1]->actnum[0])
{
strncat(netbuffer->u.serverinfo.maptitle, " ", sizeof(netbuffer->u.serverinfo.maptitle)-1);
strncat(netbuffer->u.serverinfo.maptitle, mapheaderinfo[gamemap-1]->actnum,
sizeof(netbuffer->u.serverinfo.maptitle)-1);
strncat(serverinfo->maptitle, " ", sizeof(serverinfo->maptitle)-1);
strncat(serverinfo->maptitle, mapheaderinfo[gamemap-1]->actnum, sizeof(serverinfo->maptitle)-1);
}
}
else
strncpy(netbuffer->u.serverinfo.maptitle, "Unknown", 33);
{
strncpy(serverinfo->maptitle, "Unknown", sizeof(serverinfo->maptitle)-1);
}
netbuffer->u.serverinfo.maptitle[32] = '\0';
serverinfo->maptitle[sizeof(serverinfo->maptitle)-1] = '\0';
netbuffer->u.serverinfo.actnum = 0; //mapheaderinfo[gamemap-1]->actnum
serverinfo->actnum = 0; //mapheaderinfo[gamemap-1]->actnum
mirror_length = strlen(httpurl);
if (mirror_length > MAX_MIRROR_LENGTH)
mirror_length = MAX_MIRROR_LENGTH;
if (snprintf(netbuffer->u.serverinfo.httpsource, mirror_length+1, "%s", httpurl) < 0)
if (snprintf(serverinfo->httpsource, mirror_length+1, "%s", httpurl) < 0)
// If there's an encoding error, send nothing, we accept that the above may be truncated
strncpy(netbuffer->u.serverinfo.httpsource, "", mirror_length);
strncpy(serverinfo->httpsource, "", mirror_length);
netbuffer->u.serverinfo.httpsource[MAX_MIRROR_LENGTH-1] = '\0';
serverinfo->httpsource[MAX_MIRROR_LENGTH-1] = '\0';
p = PutFileNeeded(0);
@@ -1769,7 +1773,7 @@ static void SV_SendPlayerInfo(INT32 node)
// doesent really matter what we put here lel
netbuffer->u.playerinfo[0].score = LONG(42069);
netbuffer->u.playerinfo[0].timeinserver = SHORT(42069);
netbuffer->u.playerinfo[0].skin = (UINT8)1; // no clue wtf skin 1 is, tails maybe?
netbuffer->u.playerinfo[0].skin = (skinnum_t)1; // no clue wtf skin 1 is, tails maybe?
netbuffer->u.playerinfo[0].data = 0;
@@ -1814,11 +1818,11 @@ static void SV_SendPlayerInfo(INT32 node)
netbuffer->u.playerinfo[i].score = LONG(players[i].score);
netbuffer->u.playerinfo[i].timeinserver = SHORT((UINT16)(players[i].jointime / TICRATE));
netbuffer->u.playerinfo[i].skin = (UINT8)players[i].skin;
netbuffer->u.playerinfo[i].skin = (skinnum_t)players[i].skin;
// Extra data
// Kart has extra skincolors, so we can't use this
//netbuffer->u.playerinfo[i].data = 0; //netbuffer->u.playerinfo[i].data = players[i].skincolor;
//netbuffer->u.playerinfo[i].data = 0;
// well why not, we only got like 100 of these?
netbuffer->u.playerinfo[i].data = players[i].skincolor;
@@ -1924,8 +1928,10 @@ static void SV_SendMapIcon(INT32 node)
*/
static boolean SV_SendServerConfig(INT32 node)
{
#ifndef PHOBOS_BUILD
INT32 i;
UINT8 *p, *op;
#endif
boolean waspacketsent;
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
@@ -1943,6 +1949,7 @@ static boolean SV_SendServerConfig(INT32 node)
netbuffer->u.servercfg.gametype = (UINT8)gametype;
netbuffer->u.servercfg.modifiedgame = (UINT8)modifiedgame;
#ifndef PHOBOS_BUILD
// we fill these structs with FFs so that any players not in game get sent as 0xFFFF
// which is nice and easy for us to detect
memset(netbuffer->u.servercfg.playerskins, 0xFF, sizeof(netbuffer->u.servercfg.playerskins));
@@ -1958,6 +1965,7 @@ static boolean SV_SendServerConfig(INT32 node)
netbuffer->u.servercfg.playerskins[i] = (UINT8)players[i].skin;
netbuffer->u.servercfg.playercolor[i] = (UINT8)players[i].skincolor;
}
#endif
netbuffer->u.servercfg.maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value));
netbuffer->u.servercfg.allownewplayer = cv_allownewplayer.value;
@@ -1965,12 +1973,16 @@ static boolean SV_SendServerConfig(INT32 node)
memcpy(netbuffer->u.servercfg.server_context, server_context, 8);
#ifdef PHOBOS_BUILD
const size_t len = sizeof(serverconfig_pak);
#else
op = p = netbuffer->u.servercfg.varlengthinputs;
CV_SavePlayerNames(&p);
CV_SaveNetVars(&p, false);
const size_t len = sizeof (serverconfig_pak) + (size_t)(p - op);
#endif
#ifdef DEBUGFILE
if (debugfile)
@@ -2094,7 +2106,7 @@ static void SV_SavedGame(void)
if (!cv_dumpconsistency.value)
return;
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
snprintf(tmpsave, sizeof(tmpsave), "%s" PATHSEP TMPSAVENAME, srb2home);
// first save it in a malloced buffer
save.p = save.buffer = (UINT8 *)Z_Malloc(SAVEGAMESIZE, PU_STATIC, NULL);
@@ -2132,7 +2144,7 @@ static void CL_LoadReceivedSavegame(boolean reloading)
size_t length, decompressedlen;
char tmpsave[264];
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
snprintf(tmpsave, sizeof(tmpsave), "%s" PATHSEP TMPSAVENAME, srb2home);
length = FIL_ReadFile(tmpsave, &save.buffer);
@@ -2211,7 +2223,7 @@ static void CL_ReloadReceivedSavegame(void)
for (i = 0; i < MAXPLAYERS; i++)
{
LUA_InvalidatePlayer(&players[i]);
sprintf(player_names[i], "Player %d", i + 1);
snprintf(player_names[i], MAXPLAYERNAME+1, "Player %d", i + 1);
}
CL_LoadReceivedSavegame(true);
@@ -2947,7 +2959,7 @@ static void CL_ConnectToServer(void)
tic_t asksent;
char tmpsave[264];
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
snprintf(tmpsave, sizeof(tmpsave), "%s" PATHSEP TMPSAVENAME, srb2home);
filedownload.current = -1;
cl_mode = CL_SEARCHING;
@@ -3335,6 +3347,7 @@ static void Command_connect(void)
return;
}
// StarManiaKG: allow us to join servers from anywhere at any time //
if (Playing() || demo.title || demo.playback)
{
if (demo.title || demo.playback)
@@ -3353,7 +3366,9 @@ static void Command_connect(void)
D_StartTitle();
}
else
{
M_ClearMenus(true); // close the menus
}
// modified game check: no longer handled
// we don't request a restart unless the filelist differs
@@ -3369,37 +3384,52 @@ static void Command_connect(void)
}
else
{
// used in menu to connect to a server in the list
if (netgame && fasticmp(COM_Argv(1), "node"))
// Get the server node.
if (netgame)
{
servernode = (SINT8)atoi(COM_Argv(2));
}
else if (netgame)
{
CONS_Printf(M_GetText("You cannot connect while in a game. End this game first.\n"));
return;
}
else if (I_NetOpenSocket)
{
I_NetOpenSocket();
netgame = true;
multiplayer = true;
if (fasticmp(COM_Argv(1), "any"))
servernode = BROADCASTADDR;
else if (I_NetMakeNodewPort && COM_Argc() >= 3)
servernode = I_NetMakeNodewPort(COM_Argv(1), COM_Argv(2));
else if (I_NetMakeNodewPort)
servernode = I_NetMakeNode(COM_Argv(1));
// used in menu to connect to a server in the list
if (fasticmp(COM_Argv(1), "node"))
{
servernode = (SINT8)atoi(COM_Argv(2));
}
else
{
CONS_Alert(CONS_ERROR, M_GetText("There is no server identification with this network driver\n"));
D_CloseConnection();
return;
D_QuitNetGame();
CL_Reset();
D_StartTitle();
}
}
else
CONS_Alert(CONS_ERROR, M_GetText("There is no network driver\n"));
{
// Standard behaviour
if (I_NetOpenSocket)
{
I_NetOpenSocket();
netgame = true;
multiplayer = true;
if (fasticmp(COM_Argv(1), "any"))
servernode = BROADCASTADDR;
else if (I_NetMakeNodewPort)
{
if (COM_Argc() >= 3) // address AND port
servernode = I_NetMakeNodewPort(COM_Argv(1), COM_Argv(2));
else // address only, or address:port
servernode = I_NetMakeNode(COM_Argv(1));
}
else
{
CONS_Alert(CONS_ERROR, M_GetText("There is no server identification with this network driver\n"));
D_CloseConnection();
return;
}
}
else
{
CONS_Alert(CONS_ERROR, M_GetText("There is no network driver\n"));
return;
}
}
// invalid address
if (servernode == -1)
@@ -3446,14 +3476,16 @@ static void ResetNode(INT32 node);
//
void CL_ClearPlayer(INT32 playernum)
{
// Handle mobj_t pointers.
if (players[playernum].mo)
{
// Don't leave a NiGHTS ghost!
if (UNLIKELY((players[playernum].pflags & PF_NIGHTSMODE) && players[playernum].mo->tracer))
if (nightsplayer(&players[playernum]) && players[playernum].mo->tracer)
P_RemoveMobj(players[playernum].mo->tracer);
P_RemoveMobj(players[playernum].mo);
}
// Wipe the struct.
memset(&players[playernum], 0, sizeof(player_t));
}
@@ -3510,7 +3542,7 @@ void CL_RemovePlayer(INT32 playernum, INT32 reason)
player_muted[playernum] = false;
// Reset the name
sprintf(player_names[playernum], "Player %d", playernum+1);
snprintf(player_names[playernum], MAXPLAYERNAME+1, "Player %d", playernum+1);
player_name_changes[playernum] = 0;
@@ -3767,6 +3799,10 @@ static void Command_Ban(void)
if (pn == -1 || pn == 0)
return;
// player does not exist
if (!playeringame[pn])
return;
WRITEUINT8(p, pn);
if (COM_Argc() == 2)
@@ -3884,6 +3920,10 @@ static void Command_Kick(void)
if (pn == -1 || pn == 0)
return;
// player does not exist
if (!playeringame[pn])
return;
// Special case if we are trying to kick a player who is downloading the game state:
// trigger a timeout instead of kicking them, because a kick would only
// take effect after they have finished downloading
@@ -3933,6 +3973,13 @@ static void Got_KickCmd(const UINT8 **p, INT32 playernum)
pnum = READUINT8(*p);
msg = READUINT8(*p);
if (pnum >= MAXPLAYERS)
{
CONS_Alert(CONS_WARNING, M_GetText("Illegal kick command received from %s for player %d\n"), player_names[playernum], pnum);
return;
}
// FIXME: this does not work at all on dedi, servernode == 0 which is prevented from kick/ban command
if (pnum == serverplayer && IsPlayerAdmin(playernum))
{
CONS_Printf(M_GetText("Server is being shut down remotely. Goodbye!\n"));
@@ -3987,6 +4034,16 @@ static void Got_KickCmd(const UINT8 **p, INT32 playernum)
msg = KICK_MSG_CON_FAIL;
}
// without this the server will remove itself and thus self destruct on dedicated
if (server && (playernode[pnum] == UINT8_MAX || !playeringame[pnum]))
{
CONS_Alert(CONS_WARNING, M_GetText("Attempting to kick player %d which is not in game received from %s\n"), pnum, player_names[playernum]);
return;
}
// make sure we dont read garbage anywhere
memset(reason, 0, sizeof(buf));
if (msg == KICK_MSG_CUSTOM_BAN || msg == KICK_MSG_CUSTOM_KICK)
{
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
@@ -4447,7 +4504,7 @@ void SV_ResetServer(void)
for (i = 0; i < MAXPLAYERS; i++)
{
LUA_InvalidatePlayer(&players[i]);
sprintf(player_names[i], "Player %d", i + 1);
snprintf(player_names[i], MAXPLAYERNAME+1, "Player %d", i + 1);
}
memset(player_name_changes, 0, sizeof(player_name_changes));
@@ -5137,7 +5194,7 @@ static void PT_ServerInfo(SINT8 node)
const tic_t ticthen = (tic_t)LONG(netbuffer->u.serverinfo.time);
const tic_t ticdiff = (ticnow - ticthen)*1000/NEWTICRATE;
netbuffer->u.serverinfo.time = (tic_t)LONG(ticdiff);
netbuffer->u.serverinfo.servername[MAXSERVERNAME-1] = 0;
netbuffer->u.serverinfo.servername[MAXSERVERNAME-1] = '\0';
netbuffer->u.serverinfo.application
[sizeof netbuffer->u.serverinfo.application - 1] = '\0';
memcpy(servername, netbuffer->u.serverinfo.servername, MAXSERVERNAME);
@@ -5386,8 +5443,10 @@ static void PT_ServerRefuse(SINT8 node)
// Positive response of client join request
static void PT_ServerCFG(SINT8 node)
{
#ifndef PHOBOS_BUILD
INT32 j;
UINT8 *scp;
#endif
if (server && serverrunning && node != servernode)
{ // but wait I thought I'm the server?
@@ -5410,8 +5469,10 @@ static void PT_ServerCFG(SINT8 node)
if ((gametype = netbuffer->u.servercfg.gametype) >= NUMGAMETYPES)
I_Error("Bad gametype %d in cliserv!", gametype);
modifiedgame = netbuffer->u.servercfg.modifiedgame;
#ifndef PHOBOS_BUILD
for (j = 0; j < MAXPLAYERS; j++)
adminplayers[j] = netbuffer->u.servercfg.adminplayers[j];
#endif
memcpy(server_context, netbuffer->u.servercfg.server_context, 8);
}
@@ -5437,6 +5498,7 @@ static void PT_ServerCFG(SINT8 node)
SendSaturnInfo(node);
#endif
#ifndef PHOBOS_BUILD
memset(playeringame, 0, sizeof(playeringame));
for (j = 0; j < MAXPLAYERS; j++)
@@ -5453,6 +5515,7 @@ static void PT_ServerCFG(SINT8 node)
scp = netbuffer->u.servercfg.varlengthinputs;
CV_LoadPlayerNames(&scp);
scp += CV_LoadNetVars(scp);
#endif
/// \note Wait. What if a Lua script uses some global custom variables synched with the NetVars hook?
/// Shouldn't them be downloaded even at intermission time?
@@ -5506,7 +5569,7 @@ static void PT_WillResendGamestate(void)
CONS_Printf(M_GetText("Reloading game state...\n"));
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
snprintf(tmpsave, sizeof(tmpsave), "%s" PATHSEP TMPSAVENAME, srb2home);
// Don't get a corrupt savegame error because tmpsave already exists
if (FIL_FileExists(tmpsave) && unlink(tmpsave) == -1)
@@ -7210,6 +7273,7 @@ static void DedicatedIdleUpdate(INT32 *realtics)
{
CONS_Printf("DEDICATED: Awakening from idle (Player detected...)\n");
}
dedicatedidle = 0;
}
}
+8 -2
View File
@@ -339,13 +339,17 @@ typedef struct
UINT8 clientnode;
UINT8 gamestate;
#ifndef PHOBOS_BUILD
// 0xFF == not in game; else player skin num
UINT8 playerskins[MAXPLAYERS];
UINT8 playercolor[MAXPLAYERS];
#endif
UINT8 gametype;
UINT8 modifiedgame;
#ifndef PHOBOS_BUILD
SINT8 adminplayers[MAXPLAYERS]; // Needs to be signed
#endif
char server_context[8]; // Unique context id, generated at server startup.
@@ -354,7 +358,9 @@ typedef struct
boolean allownewplayer;
boolean discordinvites;
#ifndef PHOBOS_BUILD
UINT8 varlengthinputs[0]; // Playernames and netvars
#endif
} ATTRPACK serverconfig_pak;
typedef struct {
@@ -444,7 +450,7 @@ typedef struct
char name[MAXPLAYERNAME+1];
UINT8 address[4]; // sending another string would run us up against MAXPACKETLENGTH
UINT8 team;
UINT8 skin;
skinnum_t skin;
UINT8 data; // Color is first four bits, hasflag, isit and issuper have one bit each, the last is unused.
UINT32 score;
UINT16 timeinserver; // In seconds.
@@ -454,7 +460,7 @@ typedef struct
typedef struct
{
char name[MAXPLAYERNAME+1];
UINT8 skin;
skinnum_t skin;
UINT8 color;
UINT32 pflags;
UINT32 score;
+9 -17
View File
@@ -276,20 +276,6 @@ static void D_Renderview(void)
R_ApplyLevelInterpolators(R_GetTimeFrac(RTF_LEVEL));
if (rendermode == render_soft && cv_homremoval.value)
{
if (cv_homremoval.value == 1)
{
// Clear the software screen buffer to remove HOM
memset(vid.screens[0], 31, vid.width * vid.height);
}
else if (cv_homremoval.value == 2)
{
//'development' HOM removal -- makes it blindingly obvious if HOM is spotted.
memset(vid.screens[0], 32+(timeinmap&15), vid.width * vid.height);
}
}
for (i = 0; i <= splitscreen; i++)
{
if (!P_MobjWasRemoved(players[displayplayers[i]].mo) || players[displayplayers[i]].playerstate == PST_DEAD)
@@ -1163,13 +1149,19 @@ static void D_FindAddonsToAutoload(void)
// ok so theres still issues with players adding stuff to autoload by accident
// sometimes this stuff contains maps
// you can probably imagine how that goes in a netgame....
if (W_CheckAutoLoadContainsMap(wadsToAutoload))
int retmap = W_CheckAutoLoadContainsMap(wadsToAutoload);
if (retmap == -1)
{
CONS_Alert(CONS_WARNING, "Autoload: file %s was not found or not valid.\n", wadsToAutoload);
continue;
}
if (retmap > 0)
{
CONS_Alert(CONS_WARNING, "Autoload: file %s contains map data, this WILL cause crashes and desynchs! skipping...\n", wadsToAutoload);
continue;
}
if (!postload && W_CheckPostLoadList(wadsToAutoload))
if (!postload && W_CheckPostLoadList(wadsToAutoload) > 0)
{
CONS_Printf("Autoload: forcing postload for file %s\n", wadsToAutoload);
postload = true;
@@ -1259,7 +1251,7 @@ static void IdentifyVersion(void)
#endif
char tempsrb2path[256] = ".";
if (getcwd(tempsrb2path, 256) == NULL)
if (I_GetCwd(tempsrb2path, 256) == NULL)
strcpy(tempsrb2path, ".");
// get the current directory (possible problem on NT with "." as current dir)
+3 -1
View File
@@ -1315,7 +1315,9 @@ boolean D_CheckNetGame(void)
while (!debugfile && k < MAXPLAYERS)
{
k++;
sprintf(filename, "debug%d.txt", k);
snprintf(filename, sizeof(filename), "debug%d.txt", k);
debugfile = fopen(va("%s" PATHSEP "%s", srb2home, filename), "w");
}
+108 -23
View File
@@ -147,6 +147,11 @@ static void Command_Addfilelocal(void);
static void Command_Addfile(void);
static void Command_Addskins(void);
static void Command_GLocalSkin(void);
static void SetPrefcolor(int splitplayer);
static void Command_UsePrefcolor(void);
static void Command_UsePrefcolor2(void);
static void Command_UsePrefcolor3(void);
static void Command_UsePrefcolor4(void);
static void Command_ListWADS_f(void);
static void Command_LocateLump_f(void);
static void Command_ListDoomednums_f(void);
@@ -435,10 +440,18 @@ consvar_t cv_pointlimit = {"pointlimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, point
static CV_PossibleValue_t timelimit_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}};
consvar_t cv_timelimit = {"timelimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t,
TimeLimit_OnChange, 0, NULL, NULL, 0, 0, NULL};
#ifdef PHOBOS_BUILD
static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}};
#else
static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, NULL}};
#endif
consvar_t cv_numlaps = {"numlaps", "3", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t,
NumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL};
#ifdef PHOBOS_BUILD
static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, "Map default"}, {0, NULL}};
#else
static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}};
#endif
consvar_t cv_basenumlaps = {"basenumlaps", "Map default", CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_forceskin = {"forceskin", "Off", CV_NETVAR|CV_CALL|CV_CHEAT, Forceskin_cons_t, ForceSkin_OnChange, 0, NULL, NULL, 0, 0, NULL};
@@ -570,6 +583,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
"MODIFYVOTE",
"PICKVOTE",
"REMOVEPLAYER",
"DISCORD",
"LUACMD",
"LUAVAR"
};
@@ -603,6 +617,12 @@ void D_RegisterServerCommands(void)
Forceskin_cons_t[i].value = 0;
Forceskin_cons_t[i].strvalue = NULL;
}
// Set default player names
// Monster Iestyn (12/08/19): not sure where else I could have actually put this, but oh well
for (i = 0; i < MAXPLAYERS; i++)
snprintf(player_names[i], sizeof(player_names[i]), "Player %d", 1 + i);
RegisterNetXCmd(XD_NAMEANDCOLOR, Got_NameAndColor);
RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref);
RegisterNetXCmd(XD_MAP, Got_Mapcmd);
@@ -851,6 +871,11 @@ void D_RegisterClientCommands(void)
COM_AddCommand("localskin", Command_GLocalSkin);
COM_AddCommand("useprefcolor", Command_UsePrefcolor);
COM_AddCommand("useprefcolor2", Command_UsePrefcolor2);
COM_AddCommand("useprefcolor3", Command_UsePrefcolor3);
COM_AddCommand("useprefcolor4", Command_UsePrefcolor4);
K_RegisterClientKartStuff(); // SRB2kart
CV_RegisterVar(&cv_screenshot_option);
@@ -1014,9 +1039,17 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_usejoystick[i]);
CV_RegisterVar(&cv_joyscale[i]);
CV_RegisterVar(&cv_rumble[i]);
CV_RegisterVar(&cv_rumblestrength[i]);
CV_RegisterVar(&cv_gamepadled[i]);
CV_RegisterVar(&cv_rumble[i]);
CV_RegisterVar(&cv_rumble_strength[i]);
CV_RegisterVar(&cv_rumble_spinout[i]);
CV_RegisterVar(&cv_rumble_sneakerboost[i]);
CV_RegisterVar(&cv_rumble_offroad[i]);
CV_RegisterVar(&cv_rumble_bananadrag[i]);
CV_RegisterVar(&cv_rumble_stairjank[i]);
CV_RegisterVar(&cv_rumble_brakedrift[i]);
CV_RegisterVar(&cv_rumble_driftcharge[i]);
}
CV_RegisterVar(&cv_gamepadifunfocused);
@@ -1273,7 +1306,8 @@ static boolean EnsurePlayerNameIsGood(char *name, INT32 playernum)
else if (len == 1) // Agh!
{
// Last ditch effort...
sprintf(name, "%d", M_RandomKey(10));
snprintf(name, MAXPLAYERNAME+1, "%d", M_RandomKey(10));
if (!EnsurePlayerNameIsGood(name, playernum))
return false;
}
@@ -1665,7 +1699,8 @@ static void SendNameAndColor(UINT8 splitplayer)
// Finally write out the complete packet and send it off.
WRITESTRINGN(p, playername->zstring, MAXPLAYERNAME);
WRITEUINT8(p, (UINT8)playercolor->value);
WRITEUINT8(p, (UINT8)playerskin->value);
WRITESKIN(p, (skinnum_t)playerskin->value);
SendNetXCmdForPlayer(splitplayer, XD_NAMEANDCOLOR, buf, p - buf);
}
@@ -1673,7 +1708,8 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
{
player_t *player;
char name[MAXPLAYERNAME+1] = {};
UINT8 color, skin;
UINT8 color;
skinnum_t skin;
#ifdef PARANOIA
if (playernum < 0 || playernum > MAXPLAYERS)
@@ -1695,7 +1731,7 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
READSTRINGN(*cp, name, MAXPLAYERNAME);
color = READUINT8(*cp);
skin = READUINT8(*cp);
skin = READSKIN(*cp);
// set name
if (player_name_changes[playernum] < MAXNAMECHANGES)
@@ -1803,7 +1839,7 @@ INT32 D_LookupPlayer(const char *s)
if ((playernum = atoi(s)))
{
playernum = max(min(playernum, MAXPLAYERS-1), 0);/* not out of range */
playernum = max(min(playernum, MAXPLAYERS-1), 0); /* not out of range */
return playernum;
}
@@ -2327,11 +2363,12 @@ static char *ConcatCommandArgv(int start, int end)
if (!p)
I_Error("ConcatCommandArgv: Out of memory!\n");
--end;/* handle the final argument separately */
--end; /* handle the final argument separately */
for (i = start; i < end; ++i)
{
p += sprintf(p, "%s ", COM_Argv(i));
if (size - (p - final) > 0)
p += snprintf(p, size - (p - final), "%s ", COM_Argv(i));
}
/* at this point "end" is actually the last argument's position */
@@ -2745,11 +2782,11 @@ static void Command_ReplayMarker(void)
if (title)
{
snprintf(demo.titlename, 64, "%s [%i:%02d/%.5s]", title, G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername);
snprintf(demo.titlename, sizeof(demo.titlename)-1, "%s [%i:%02d/%.5s]", title, G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername);
Z_Free(title);
}
else
snprintf(demo.titlename, 64, "[%i:%02d/%.5s]", G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername);
snprintf(demo.titlename, sizeof(demo.titlename)-1, "[%i:%02d/%.5s]", G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername);
CONS_Printf("Replay will be saved!\n");
}
@@ -4307,6 +4344,49 @@ static void Command_GLocalSkin(void)
}
}
static void SetPrefcolor(int splitplayer)
{
// splitscreen
if (splitscreen < splitplayer)
return;
const INT32 pnum = P_GetLocalPlayerNumForNum(splitplayer);
player_t *player = &players[pnum];
consvar_t *colorvars[] = {&cv_playercolor, &cv_playercolor2, &cv_playercolor3, &cv_playercolor4};
consvar_t *playercolor = colorvars[splitplayer];
if (skins[player->skin].prefcolor)
{
CV_SetValue(playercolor, skins[player->skin].prefcolor);
CONS_Printf("Set color to %s%s\n", HU_SkinColorToConsoleColor(skins[player->skin].prefcolor), KartColor_Names[skins[player->skin].prefcolor]);
}
else
{
CONS_Printf("\x86Your skin has no prefcolor set\n");
}
}
static void Command_UsePrefcolor(void)
{
SetPrefcolor(0);
}
static void Command_UsePrefcolor2(void)
{
SetPrefcolor(1);
}
static void Command_UsePrefcolor3(void)
{
SetPrefcolor(2);
}
static void Command_UsePrefcolor4(void)
{
SetPrefcolor(3);
}
static void Got_RequestAddfilecmd(const UINT8 **cp, INT32 playernum)
{
char filename[241];
@@ -4346,15 +4426,15 @@ static void Got_RequestAddfilecmd(const UINT8 **cp, INT32 playernum)
char message[275];
if (toomany)
sprintf(message, M_GetText("Too many files loaded to add %s\n"), filename);
snprintf(message, sizeof(message), M_GetText("Too many files loaded to add %s\n"), filename);
else if (ncs == FS_NOTFOUND)
sprintf(message, M_GetText("The server doesn't have %s\n"), filename);
snprintf(message, sizeof(message), M_GetText("The server doesn't have %s\n"), filename);
else if (ncs == FS_MD5SUMBAD)
sprintf(message, M_GetText("Checksum mismatch on %s\n"), filename);
snprintf(message, sizeof(message), M_GetText("Checksum mismatch on %s\n"), filename);
else
sprintf(message, M_GetText("Unknown error finding wad file (%s)\n"), filename);
snprintf(message, sizeof(message), M_GetText("Unknown error finding wad file (%s)\n"), filename);
CONS_Printf("%s",message);
CONS_Printf("%s", message);
for (j = 0; j < MAXPLAYERS; j++)
if (adminplayers[j])
@@ -5186,8 +5266,10 @@ static void Command_Mapmd5_f(void)
{
INT32 i;
char md5tmp[33];
for (i = 0; i < 16; ++i)
sprintf(&md5tmp[i*2], "%02x", mapmd5[i]);
snprintf(&md5tmp[i*2], 3, "%02x", mapmd5[i]);
CONS_Printf("%s: %s\n", G_BuildMapName(gamemap), md5tmp);
}
else
@@ -5688,19 +5770,22 @@ static void Command_SkinSearch(void)
size_t i;
UINT16 s;
UINT16 ic = 0;
//skin_t *skininput = &skins[s];
for (i = 1; i < COM_Argc(); i++){
for( s = 0 ; s < numallskins ; s++ )
for (i = 1; i < COM_Argc(); i++)
{
for (s = 0; s < numskins; s++)
{
skin_t *skininput = &skins[s];
if (strcasestr(skininput->realname,COM_Argv(i)))
if (strcasestr(skininput->realname, COM_Argv(i)))
{
ic++;
CONS_Printf("%d. %s%s:\x80 %s\n", ic,HU_SkinColorToConsoleColor(skininput->prefcolor),skininput->realname,skininput->name);
CONS_Printf("%d. %s%s:\x80 %s\n", ic, HU_SkinColorToConsoleColor(skininput->prefcolor), skininput->realname, skininput->name);
}
}
}
CONS_Printf("Total %d skins.\n", ic);
CONS_Printf("Total %d skins.\n", ic);
}
/** Sends a color change for the console player, unless that player is moving.
+6 -4
View File
@@ -299,10 +299,13 @@ boolean CL_CheckDownloadable(void)
{
INT32 j;
char md5tmp[33];
for (j = 0; j < 16; j++)
sprintf(&md5tmp[j*2], "%02x", fileneeded[i].md5sum[j]);
snprintf(&md5tmp[j*2], 3, "%02x", fileneeded[i].md5sum[j]);
CONS_Printf("%s", md5tmp);
}
CONS_Printf("\n");
}
}
@@ -1616,8 +1619,7 @@ static void CURLGetFile(void)
#endif
}
HTTP_login *
CURLGetLogin (const char *url, HTTP_login ***return_prev_next)
HTTP_login *CURLGetLogin(const char *url, HTTP_login ***return_prev_next)
{
HTTP_login * login;
HTTP_login ** prev_next;
@@ -1627,7 +1629,7 @@ CURLGetLogin (const char *url, HTTP_login ***return_prev_next)
( login = (*prev_next));
prev_next = &login->next
){
if (fastcmp(login->url, url) != 0)
if (fastcmp(login->url, url))
{
if (return_prev_next)
(*return_prev_next) = prev_next;
+12 -3
View File
@@ -361,11 +361,17 @@ typedef struct squishdance_s
{
tic_t countdown; // hold "custom 3" for 2 seconds to engange le dance
tic_t time;
fixed_t work;
fixed_t ang;
fixed_t bounce; // hehe squishy
} squishdance_t;
typedef struct salty_s
{
bool ready;
bool tapping;
fixed_t zoffset;
fixed_t momz;
bool jump;
} salty_t;
// ========================================================================
// PLAYER STRUCTURE
// ========================================================================
@@ -561,6 +567,9 @@ typedef struct player_s
fixed_t spinoutrot; // When a player spins out, this value increments modulus 360.
// saltyhop! hardcode edition
salty_t salty;
squishdance_t squishdance;
fixed_t fovadd; // adjust FOV for hw rendering
+2 -2
View File
@@ -211,12 +211,12 @@ void D_SetupProtocol(void)
if (result)
{
if (!fastcmp(buffer, "no"))
if (fastcmp(buffer, "no"))
{
fclose(fp);
return;
}
else if (fastcmp(buffer, exe_path))
else if (!fastcmp(buffer, exe_path))
{
// overwrite
fclose(fp);
+8 -3
View File
@@ -119,20 +119,25 @@ target_compile_definitions(SRB2SDL2 PRIVATE
-DHAVE_THREADS
)
if(SRB2_CONFIG_LTO AND NOT SRB2_CONFIG_DEBUGMODE)
if(SRB2_CONFIG_LTO AND NOT SRB2_CONFIG_DEBUGMODE AND NOT SRB2_CONFIG_ASAN AND NOT SRB2_CONFIG_UBSAN AND NOT SRB2_CONFIG_TSAN)
set_property(TARGET SRB2SDL2 PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
if(SRB2_CONFIG_ASAN)
target_compile_options(SRB2SDL2 PRIVATE -fsanitize=address)
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=address -fno-omit-frame-pointer -fno-common)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=address)
endif()
if(SRB2_CONFIG_UBSAN)
target_compile_options(SRB2SDL2 PRIVATE -fsanitize=undefined)
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=undefined -fno-omit-frame-pointer)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=undefined)
endif()
if(SRB2_CONFIG_TSAN)
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=thread -fno-omit-frame-pointer)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=thread)
endif()
## strip debug symbols into separate file when using gcc
# if(CMAKE_COMPILER_IS_GNUCC)
# if(${CMAKE_BUILD_TYPE} MATCHES Debug)
+128 -56
View File
@@ -68,6 +68,12 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#include <time.h>
#if defined (__linux__)
#include <sys/vfs.h>
#elif defined(__APPLE__)
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <mach/mach.h>
#else
#include <sys/param.h>
#include <sys/mount.h>
@@ -156,8 +162,7 @@ const char *wadSearchPaths[] = {
/** \brief WAD file to look for
*/
#define WADKEYWORD1 "srb2.srb"
#define WADKEYWORD2 "srb2.wad"
#define WADKEYWORD "srb2.srb"
/** \brief holds wad path
*/
static char returnWadPath[256];
@@ -520,17 +525,24 @@ void I_OutputMsg(const char *fmt, ...)
{
size_t len;
char *txt;
va_list argptr;
va_list argptr;
va_start(argptr,fmt);
if (!fmt)
return;
va_start(argptr, fmt);
len = vsnprintf(NULL, 0, fmt, argptr);
va_end(argptr);
if (len == 0)
return;
txt = malloc(len+1);
va_start(argptr,fmt);
vsprintf(txt, fmt, argptr);
txt = (char*)(malloc(len+1));
if (!txt)
I_Error("I_OutputMsg: Out of memory!\n");
va_start(argptr, fmt);
vsnprintf(txt, len+1, fmt, argptr);
va_end(argptr);
#ifdef HAVE_TTF
@@ -538,7 +550,7 @@ void I_OutputMsg(const char *fmt, ...)
DEFAULTFONTBGR, DEFAULTFONTBGG, DEFAULTFONTBGB, DEFAULTFONTBGA, txt);
#endif
len = strlen(txt);
len = strnlen(txt, len+1);
#ifdef LOGMESSAGES
if (logstream)
@@ -956,14 +968,18 @@ void I_Sleep(UINT32 ms)
void I_SleepDuration(precise_t duration)
{
#if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__)
#if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__) || defined(__OpenBSD__)
UINT64 precision = I_GetPrecisePrecision();
struct timespec ts = {
.tv_sec = duration / precision,
.tv_nsec = duration * 1000000000 / precision % 1000000000,
};
int status;
#ifdef __OpenBSD__
do status = nanosleep(&ts, &ts);
#else
do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
#endif
while (status == EINTR);
#elif defined (MIN_SLEEP_DURATION_MS)
UINT64 precision = I_GetPrecisePrecision();
@@ -1041,7 +1057,7 @@ static void I_PrintSignal(INT32 signal_num, boolean core_dumped, char *signal_ms
sigmsg = ("SIGABRT - SRB2Kart-Saturn was terminated by an abort signal.");
break;
default:
sprintf(signal_msg, "Signal number %d", signal_num);
snprintf(signal_msg, 512, "Signal number %d", signal_num);
sigmsg = (core_dumped ? "Unknown signal" : signal_msg);
break;
}
@@ -1049,13 +1065,17 @@ static void I_PrintSignal(INT32 signal_num, boolean core_dumped, char *signal_ms
if (core_dumped)
{
if (sigmsg)
sprintf(signal_msg, "%s (core dumped)", sigmsg);
{
snprintf(signal_msg, 512, "%s (core dumped)", sigmsg);
}
else
{
strcat(signal_msg, " (core dumped)");
}
}
else
{
sprintf(signal_msg, "%s", sigmsg);
snprintf(signal_msg, 512, "%s", sigmsg);
}
}
@@ -1332,7 +1352,7 @@ FUNCNORETURN static ATTRNORETURN void newsignalhandler_Warn(const char *pr)
{
char text[128];
snprintf(text, sizeof text,
snprintf(text, sizeof(text),
"Error while setting up signal reporting: %s: %s",
pr,
strerror(errno)
@@ -1413,6 +1433,12 @@ static void I_Fork(void)
}
#endif/*NEWSIGNALHANDLER*/
int I_OpenURL(const char *url)
{
(void)url;
return -1;
}
INT32 I_StartupSystem(void)
{
I_StartupConsole();
@@ -1512,7 +1538,7 @@ FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...)
if (errorcount > 20)
{
va_start(argptr, error);
vsnprintf(buffer, 8192, error, argptr);
vsnprintf(buffer, sizeof(buffer), error, argptr);
va_end(argptr);
I_OutputMsg("SRB2Kart %s Recursive Error", buffer);
@@ -1525,7 +1551,7 @@ FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...)
// Display error message in the console before we start shutting it down
va_start(argptr, error);
vsnprintf(buffer, 8192, error, argptr);
vsnprintf(buffer, sizeof(buffer), error, argptr);
va_end(argptr);
I_OutputMsg("\nI_Error(): %s\n", buffer);
@@ -1746,7 +1772,8 @@ char *I_GetUserName(void)
}
}
}
strncpy(username, p, MAXPLAYERNAME);
snprintf(username, sizeof(username), "%s", p);
}
if (!fastcmp(username, ""))
@@ -1770,6 +1797,24 @@ INT32 I_mkdir(const char *dirname, INT32 unixright)
#endif
}
INT32 I_ChDir(const char *path)
{
#ifdef _WIN32
return (SetCurrentDirectoryA(path) ? 0 : -1);
#else
return chdir(path);
#endif
}
char *I_GetCwd(char *buf, size_t size)
{
#ifdef _WIN32
return (GetCurrentDirectoryA((DWORD)size, buf) ? buf : NULL);
#else
return getcwd(buf, size);
#endif
}
char *I_GetEnv(const char *name)
{
return getenv(name);
@@ -1802,42 +1847,34 @@ const char *I_ClipboardPaste(void)
*/
static boolean isWadPathOk(const char *path)
{
char *wad3path = malloc(256);
char wad3path[256];
if (!wad3path)
return false;
sprintf(wad3path, pandf, path, WADKEYWORD1);
snprintf(wad3path, sizeof(wad3path), pandf, path, WADKEYWORD);
if (FIL_ReadFileOK(wad3path))
{
free(wad3path);
return true;
}
sprintf(wad3path, pandf, path, WADKEYWORD2);
if (FIL_ReadFileOK(wad3path))
{
free(wad3path);
return true;
}
free(wad3path);
return false;
}
static void pathonly(char *s)
static void pathonly(char *s, size_t size)
{
size_t j;
for (j = strlen(s); j != (size_t)-1; j--)
for (j = strnlen(s, size); j != (size_t)-1; j--)
{
if ((s[j] == '\\') || (s[j] == ':') || (s[j] == '/'))
{
if (s[j] == ':') s[j+1] = 0;
else s[j] = 0;
if (s[j] == ':')
s[j+1] = 0;
else
s[j] = 0;
return;
}
}
}
/** \brief search for srb2.srb in the given path
@@ -1853,11 +1890,12 @@ static const char *searchWad(const char *searchDir)
static char tempsw[256] = "";
filestatus_t fstemp;
strcpy(tempsw, WADKEYWORD1);
snprintf(tempsw, sizeof(tempsw), "%s", WADKEYWORD);
fstemp = filesearch(tempsw, searchDir, NULL, true, 20);
if (fstemp == FS_FOUND)
{
pathonly(tempsw);
pathonly(tempsw, sizeof(tempsw));
return tempsw;
}
@@ -1895,7 +1933,7 @@ static const char *locateWad(void)
#ifndef NOCWD
// examine current dir
strcpy(returnWadPath, ".");
snprintf(returnWadPath, sizeof(returnWadPath), "%s", ".");
I_OutputMsg(",%s", returnWadPath);
if (isWadPathOk(returnWadPath))
return NULL;
@@ -1907,7 +1945,7 @@ static const char *locateWad(void)
// examine user jart directory
if ((envstr = I_GetEnv("HOME")) != NULL)
{
sprintf(returnWadPath, "%s" PATHSEP DEFAULTDIR, envstr);
snprintf(returnWadPath, sizeof(returnWadPath), "%s" PATHSEP DEFAULTDIR, envstr);
CHECKWADPATH(returnWadPath);
}
#endif
@@ -1921,7 +1959,7 @@ static const char *locateWad(void)
// examine default dirs
for (i = 0; wadDefaultPaths[i]; i++)
{
strcpy(returnWadPath, wadDefaultPaths[i]);
snprintf(returnWadPath, sizeof(returnWadPath), "%s", wadDefaultPaths[i]);
CHECKWADPATH(returnWadPath);
}
@@ -1949,12 +1987,11 @@ const char *I_LocateWad(void)
// change to the directory where we found srb2.srb
#if defined (_WIN32)
waddir = _fullpath(NULL, waddir, MAX_PATH);
SetCurrentDirectoryA(waddir);
#else
waddir = realpath(waddir, NULL);
if (waddir == NULL || chdir(waddir) == -1)
I_OutputMsg("Couldn't change working directory\n");
#endif
if (waddir == NULL || I_ChDir(waddir) == -1)
I_OutputMsg("Couldn't change working directory\n");
}
return waddir;
@@ -1974,17 +2011,22 @@ const char *I_LocateWad(void)
static long get_entry(const char* name, const char* buf)
{
long val;
char* hit = strstr(buf, name);
if (hit == NULL) {
const char* hit = strstr(buf, name);
if (hit == NULL)
{
return -1;
}
errno = 0;
val = strtol(hit + strlen(name), NULL, 10);
if (errno != 0) {
if (errno != 0)
{
CONS_Alert(CONS_ERROR, M_GetText("get_entry: strtol() failed: %s\n"), strerror(errno));
return -1;
}
return val;
}
#endif
@@ -2009,13 +2051,13 @@ size_t I_GetFreeMem(size_t *total)
*total = 32 << 20;
return 32 << 20;
#elif defined (_WIN32)
MEMORYSTATUS info;
MEMORYSTATUSEX info;
info.dwLength = sizeof (MEMORYSTATUS);
GlobalMemoryStatus( &info );
info.dwLength = sizeof (MEMORYSTATUSEX);
GlobalMemoryStatusEx( &info );
if (total)
*total = (size_t)info.dwTotalPhys;
return (size_t)info.dwAvailPhys;
*total = (size_t)info.ullTotalPhys;
return (size_t)info.ullAvailPhys;
#elif defined (__OS2__)
UINT32 pr_arena;
@@ -2048,7 +2090,7 @@ size_t I_GetFreeMem(size_t *total)
{
// Error
if (total)
*total = 0L;
*total = 0;
return 0;
}
@@ -2057,12 +2099,12 @@ size_t I_GetFreeMem(size_t *total)
{
// Error
if (total)
*total = 0L;
*total = 0;
return 0;
}
memTag += sizeof (MEMTOTAL);
totalKBytes = (size_t)atoi(memTag);
totalKBytes = strtoul(memTag, NULL, 10);
if ((memTag = strstr(buf, MEMAVAILABLE)) == NULL)
{
@@ -2076,7 +2118,7 @@ size_t I_GetFreeMem(size_t *total)
{
// Error
if (total)
*total = 0L;
*total = 0;
return 0;
}
freeKBytes = MemAvailable;
@@ -2084,16 +2126,46 @@ size_t I_GetFreeMem(size_t *total)
else
{
memTag += sizeof (MEMAVAILABLE);
freeKBytes = atoi(memTag);
freeKBytes = strtoul(memTag, NULL, 10);
}
if (total)
*total = totalKBytes << 10;
return freeKBytes << 10;
#elif defined(__APPLE__)
/* macOS */
mach_port_t host = mach_host_self();
kern_return_t kr;
mach_msg_type_number_t count;
vm_size_t v_page_size;
struct vm_statistics64 vm_stats;
uint64_t total_mem, free_mem;
size_t size;
size = sizeof(total_mem);
if (sysctlbyname("hw.memsize", &total_mem, &size, NULL, 0) < 0)
total_mem = 0;
kr = host_page_size(host, &v_page_size);
if (kr != KERN_SUCCESS)
v_page_size = 4096;
count = HOST_VM_INFO64_COUNT;
kr = host_statistics64(host, HOST_VM_INFO64, (host_info64_t)&vm_stats, &count);
if (kr == KERN_SUCCESS)
free_mem = (uint64_t)(vm_stats.free_count + vm_stats.inactive_count) * v_page_size;
else
free_mem = 0;
if (total)
*total = (size_t)total_mem;
return (size_t)free_mem;
#else
// Guess 48 MB.
if (total)
{
*total = 48<<20;
}
return 48<<20;
#endif
}
+5 -2
View File
@@ -402,7 +402,7 @@ static void Discordrp_OnChange(void)
static void DRPC_GotServerIP(UINT32 address)
{
const unsigned char * p = (const unsigned char *)&address;
sprintf(self_ip, "%u.%u.%u.%u:%u", p[0], p[1], p[2], p[3], current_port);
snprintf(self_ip, IP_SIZE+1, "%u.%u.%u.%u:%u", p[0], p[1], p[2], p[3], current_port);
}
/*--------------------------------------------------
@@ -474,6 +474,7 @@ void DRPC_UpdatePresence(void)
char charname[11+SKINNAMESIZE+1];
boolean joinSecretSet = false;
char *clientJoinSecret = NULL;
DiscordRichPresence discordPresence;
memset(&discordPresence, 0, sizeof(discordPresence));
@@ -530,7 +531,8 @@ void DRPC_UpdatePresence(void)
// Grab the host's IP for joining.
if ((join = DRPC_GetServerIP()) != NULL)
{
discordPresence.joinSecret = DRPC_XORIPString(join);
clientJoinSecret = DRPC_XORIPString(join);
discordPresence.joinSecret = clientJoinSecret;
joinSecretSet = true;
}
}
@@ -712,6 +714,7 @@ void DRPC_UpdatePresence(void)
}
Discord_UpdatePresence(&discordPresence);
free(clientJoinSecret);
}
#endif // HAVE_DISCORDRPC
+29 -14
View File
@@ -128,10 +128,24 @@ extern char logfilename[1024];
// most interface strings are ignored in development mode.
// we use comprevision and compbranch instead.
#else
#ifdef PHOBOS_BUILD
#define VERSION 1 // Game version
#define SUBVERSION 69 // more precise version number
#else
#define VERSION 1 // Game version
#define SUBVERSION 6 // more precise version number
#define VERSIONSTRING "Saturn v9.3"
#define VERSIONSTRINGW L"Saturn v9.3"
#endif
#ifdef PHOBOS_BUILD
#define CLIENTNAME "Phobos"
#define CLIENTNAMEW L"Phobos"
#else
#define CLIENTNAME "Saturn"
#define CLIENTNAMEW L"Saturn"
#endif
#define VERSIONSTRING CLIENTNAME " v10.1"
#define VERSIONSTRINGW CLIENTNAMEW L" v10.1"
#define SATURN_TESTING // comment out for saturn release builds!
@@ -602,11 +616,19 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
// None of these that are disabled in the normal build are guaranteed to work perfectly
// Compile them at your own risk!
// undefine to enable fixes and features that are not vanilla compatible
#define COMPAT_VANILLA
// if we build with 32 player (or more!) support we dont need to care vanilla compat
#if MAXPLAYERS > 16
#undef COMPAT_VANILLA
#ifdef PHOBOS_BUILD
// we want 32 players yesss
#undef MAXPLAYERS
#define MAXPLAYERS 32
// raise skinlimit to 1024
#undef MAXSKINS
#define MAXSKINS 1024
// overwrite some of those
// when not compiling in vanilla compat mode
#define SATURNJOIN
#define SATURNPAK
#endif
//-- SATURN __
@@ -673,13 +695,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
#undef UPDATE_ALERT
#endif
// overwrite some of those
// when not compiling in vanilla compat mode
#ifndef COMPAT_VANILLA
#define SATURNJOIN
#define SATURNPAK
#endif
#ifdef __cplusplus
} // extern "C"
#endif
+6
View File
@@ -42,6 +42,12 @@ extern "C" {
#define INT64 int64_t
#define UINT64 uint64_t
#ifdef PHOBOS_BUILD
typedef uint16_t skinnum_t;
#else
typedef uint8_t skinnum_t;
#endif
#ifdef __APPLE_CC__
#define DEBUG_LOG
#define NOIPX
+2 -1
View File
@@ -111,7 +111,8 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum)
goto freemask;
// SRB2Kart: This suddenly triggers ERRORMODE now
//sprintf(&lumpname[4], "%.2hu%.2hu", (UINT16)masknum, (UINT16)scrnnum);
//snprintf(&lumpname[4], 3, "%.2hu%.2hu", (UINT16)masknum, (UINT16)scrnnum);
//lumpname[8] = 0;
lumpname[4] = '0'+(masknum/10);
lumpname[5] = '0'+(masknum%10);
+63 -92
View File
@@ -63,7 +63,6 @@
// for replay dates
#include <time.h>
#include <locale.h>
// menu demo things
UINT32 demoDelayTime = 15*TICRATE;
@@ -716,7 +715,7 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
if (!(demoflags & DF_GHOST))
return; // No ghost data to write.
if (ghost->player && ghost->player->pflags & PF_NIGHTSMODE && ghost->tracer)
if (ghost->player && nightsplayer(ghost->player) && ghost->tracer)
{
// We're talking about the NiGHTS thing, not the normal platforming thing!
ziptic |= GZT_NIGHTS;
@@ -934,7 +933,7 @@ void G_ConsAllGhostTics(void)
void G_ConsGhostTic(INT32 playernum)
{
UINT8 ziptic;
fixed_t px,py,pz,gx,gy,gz;
fixed_t px, py, pz, gx, gy, gz;
mobj_t *testmo;
fixed_t syncleeway;
boolean nightsfail = false;
@@ -979,7 +978,7 @@ void G_ConsGhostTic(INT32 playernum)
if (ziptic & GZT_NIGHTS)
{
if (!testmo || !testmo->player || !(testmo->player->pflags & PF_NIGHTSMODE) || !testmo->tracer)
if (!testmo || !testmo->player || !nightsplayer(testmo->player) || !testmo->tracer)
nightsfail = true;
else
testmo = testmo->tracer;
@@ -1723,11 +1722,11 @@ void G_BeginRecording(void)
// Print to a separate temp buffer instead of demo.titlename, so we can use it in M_TextInputSetString
if (title)
{
snprintf(demotitlename, 64, "%s - %s", title, modeattacking ? "Time Attack" : connectedservername);
snprintf(demotitlename, sizeof(demotitlename)-1, "%s - %s", title, modeattacking ? "Time Attack" : connectedservername);
Z_Free(title);
}
else
snprintf(demotitlename, 64, "%s", modeattacking ? "Time Attack" : connectedservername);
snprintf(demotitlename, sizeof(demotitlename)-1, "%s", modeattacking ? "Time Attack" : connectedservername);
// Init just in case it isn't initialized already
M_TextInputInit(&demo.titlenameinput, demo.titlename, sizeof(demo.titlename));
@@ -2212,7 +2211,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
{
CONS_Alert(CONS_ERROR, M_GetText("Failed to read file '%s'.\n"), pdemo->filepath);
pdemo->type = MD_INVALID;
sprintf(pdemo->title, "INVALID REPLAY");
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
return;
}
@@ -2222,7 +2221,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
{
CONS_Alert(CONS_ERROR, M_GetText("%s is not a SRB2Kart replay file.\n"), pdemo->filepath);
pdemo->type = MD_INVALID;
sprintf(pdemo->title, "INVALID REPLAY");
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
return;
}
@@ -2247,14 +2246,14 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
#ifdef DEMO_COMPAT_100
case 0x0001:
pdemo->type = MD_OUTDATED;
sprintf(pdemo->title, "Legacy Replay");
snprintf(pdemo->title, sizeof(pdemo->title), "Legacy Replay");
break;
#endif
// too old, cannot support.
default:
CONS_Alert(CONS_ERROR, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemo->filepath);
pdemo->type = MD_INVALID;
sprintf(pdemo->title, "INVALID REPLAY");
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
return;
}
@@ -2267,7 +2266,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
{
CONS_Alert(CONS_ERROR, M_GetText("%s is the wrong type of recording and cannot be played.\n"), pdemo->filepath);
pdemo->type = MD_INVALID;
sprintf(pdemo->title, "INVALID REPLAY");
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
return;
}
@@ -2288,7 +2287,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
{
CONS_Alert(CONS_ERROR, M_GetText("%s is a legacy multiplayer replay and cannot be played.\n"), pdemo->filepath);
pdemo->type = MD_INVALID;
sprintf(pdemo->title, "INVALID REPLAY");
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
return;
}
#endif
@@ -2335,7 +2334,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
while (READUINT8(extrainfo_p) == DW_STANDING) // Assume standings are always first in the extrainfo
{
INT32 i;
char temp[16];
char temp[17];
pdemo->standings[count].ranking = READUINT8(extrainfo_p);
@@ -2345,6 +2344,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
// Skin
memcpy(temp, extrainfo_p, 16);
temp[16] = '\0';
extrainfo_p += 16;
pdemo->standings[count].skin = UINT8_MAX;
@@ -2359,6 +2359,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
// Color
memcpy(temp, extrainfo_p, 16);
temp[16] = '\0';
extrainfo_p += 16;
for (i = 0; i < MAXSKINCOLORS; i++)
@@ -2385,7 +2386,9 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
#if defined (_WIN32)
// return the file creation time
// useful for demos that were renamed
static long G_GetCreationTime(char *filepath)
// windows only, as file creation times are
// very unreliable (or non existant depending on fs) on linux
static time_t G_GetCreationTime(char *filepath)
{
struct stat fileinfo;
@@ -2396,35 +2399,24 @@ static long G_GetCreationTime(char *filepath)
}
#endif
static char *G_GetDemoDate(menudemo_t *pdemo)
static char *G_GetDemoDate(menudemo_t *pdemo, const char *dateformat)
{
char *endPos = NULL;
static char datetime[11];
char *datetime;
time_t file_time = 0;
const char *format = NULL;
struct tm *tm_buf = NULL;
struct tm tm_buf;
CLEANUP(pfree) char *filename = NULL;
// get le filepath
filename = strdup(pdemo->filepath);
if (!filename)
{
#if defined (_WIN32)
// if we cant get a filename try just getting the file creation time
file_time = G_GetCreationTime(pdemo->filepath);
goto skipfilenametime;
#else
return NULL;
#endif
}
// get the actual filename Zzz...
nameonly(filename);
// the first 10 characters of a replay name usually is a unix timestamp
// not long enough to contain a valid timestamp
// the first 10 characters of a replay name is a unix timestamp
if (strlen(filename) < 10)
{
#if defined (_WIN32)
@@ -2456,73 +2448,55 @@ static char *G_GetDemoDate(menudemo_t *pdemo)
#endif
}
#if defined (_WIN32)
skipfilenametime:
#endif
// then throw it into localtime to get an actual human readable format lmao
tm_buf = localtime(&file_time);
// cant believe we ended up in 1970
if (tm_buf == NULL || tm_buf->tm_year <= 110)
#if defined(_WIN32)
skipfilenametime:
if ((localtime_s(&tm_buf, &file_time) != 0) ||
(tm_buf.tm_year <= 110)) // cant believe we ended up in 1970
{
#if defined (_WIN32)
// uh ohh, we got an invalid time
// try one more time getting the creation time
file_time = G_GetCreationTime(pdemo->filepath);
tm_buf = localtime(&file_time);
if (tm_buf == NULL || tm_buf->tm_year <= 110)
if ((localtime_s(&tm_buf, &file_time) != 0) ||
(tm_buf.tm_year <= 110))
return NULL;
goto gotcreationtime;
}
#else
if ((localtime_r(&file_time, &tm_buf) == NULL) ||
(tm_buf.tm_year <= 110)) // cant believe we ended up in 1970
return NULL;
#endif
}
#if defined (_WIN32)
gotcreationtime:
#endif
datetime = malloc(sizeof(pdemo->date)); // mallocma balls
// US ppl are special (:
if (cv_demodateformat.value == 2)
format = "%m.%d.%Y";
else if (cv_demodateformat.value == 1)
format = "%d.%m.%Y";
else
{
const char *locale = setlocale(LC_TIME, NULL);
// no mallocma balls... :c
if (!datetime)
return NULL;
if (locale == NULL)
format = "%d.%m.%Y"; // fallback to non US format
else if (strstr(locale, "en_US"))
format = "%m.%d.%Y";
else
format = "%d.%m.%Y";
}
if (strftime(datetime, sizeof(datetime), format, tm_buf) == 0)
if (strftime(datetime, sizeof(pdemo->date), dateformat, &tm_buf) == 0)
{
free(datetime);
return NULL;
}
return datetime;
}
void G_LoadDemoTitle(menudemo_t *pdemo)
void G_LoadDemoTitle(menudemo_t *pdemo, const char *dateformat)
{
UINT8 infobuffer[96], *info_p;
UINT16 pdemoversion;
char *demodate = NULL;
size_t count;
memset(pdemo->date, 0, sizeof(pdemo->date));
FILE *handle = fopen(pdemo->filepath, "rb");
if (!handle)
{
CONS_Alert(CONS_ERROR, M_GetText("Failed to read file '%s'.\n"), pdemo->filepath);
sprintf(pdemo->title, "INVALID REPLAY");
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
return;
}
@@ -2534,7 +2508,7 @@ void G_LoadDemoTitle(menudemo_t *pdemo)
if (count < 96 || memcmp(info_p, DEMOHEADER, 12))
{
CONS_Alert(CONS_ERROR, M_GetText("%s is not a SRB2Kart replay file.\n"), pdemo->filepath);
sprintf(pdemo->title, "INVALID REPLAY");
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
return;
}
@@ -2544,8 +2518,6 @@ void G_LoadDemoTitle(menudemo_t *pdemo)
pdemoversion = READUINT16(info_p);
memset(pdemo->date, 0, sizeof(pdemo->date));
switch (pdemoversion)
{
case DEMOVERSION: // latest always supported
@@ -2553,23 +2525,22 @@ void G_LoadDemoTitle(menudemo_t *pdemo)
memcpy(pdemo->title, info_p, 64);
// demo date
demodate = G_GetDemoDate(pdemo);
char *demodate = G_GetDemoDate(pdemo, dateformat);
if (demodate)
{
strlcpy(pdemo->date, demodate, sizeof(pdemo->date));
free(demodate);
}
break;
#ifdef DEMO_COMPAT_100
case 0x0001:
sprintf(pdemo->title, "Legacy Replay");
snprintf(pdemo->title, sizeof(pdemo->title), "Legacy Replay");
break;
#endif
// too old, cannot support.
default:
CONS_Alert(CONS_ERROR, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemo->filepath);
sprintf(pdemo->title, "INVALID REPLAY");
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
}
}
@@ -2633,7 +2604,7 @@ void G_DoPlayDemo(char *defdemoname)
//FIL_DefaultExtension(defdemoname, ".lmp");
if (!FIL_ReadFile(defdemoname, &demobuf.buffer))
{
snprintf(msg, 1024, M_GetText("Failed to read file '%s'.\n"), defdemoname);
snprintf(msg, sizeof(msg), M_GetText("Failed to read file '%s'.\n"), defdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
gameaction = ga_nothing;
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
@@ -2645,7 +2616,7 @@ void G_DoPlayDemo(char *defdemoname)
// load demo resource from WAD
else if ((l = W_CheckNumForName(defdemoname)) == LUMPERROR)
{
snprintf(msg, 1024, M_GetText("Failed to read lump '%s'.\n"), defdemoname);
snprintf(msg, sizeof(msg), M_GetText("Failed to read lump '%s'.\n"), defdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
gameaction = ga_nothing;
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
@@ -2666,7 +2637,7 @@ void G_DoPlayDemo(char *defdemoname)
if (memcmp(demobuf.p, DEMOHEADER, 12))
{
snprintf(msg, 1024, M_GetText("%s is not a SRB2Kart replay file.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s is not a SRB2Kart replay file.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2692,7 +2663,7 @@ void G_DoPlayDemo(char *defdemoname)
#endif
// too old, cannot support.
default:
snprintf(msg, 1024, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2703,7 +2674,7 @@ void G_DoPlayDemo(char *defdemoname)
if (memcmp(demobuf.p, "PLAY", 4))
{
snprintf(msg, 1024, M_GetText("%s is the wrong type of recording and cannot be played.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s is the wrong type of recording and cannot be played.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2720,7 +2691,7 @@ void G_DoPlayDemo(char *defdemoname)
{
if (demoflags & DF_MULTIPLAYER)
{
snprintf(msg, 1024, M_GetText("%s is an alpha multiplayer replay and cannot be played.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s is an alpha multiplayer replay and cannot be played.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2747,31 +2718,31 @@ void G_DoPlayDemo(char *defdemoname)
switch (error)
{
case DFILE_ERROR_NOTLOADED:
snprintf(msg, 1024,
snprintf(msg, sizeof(msg),
"Required files for this demo are not loaded.\n\nUse\n\"playdemo %s -addfiles\"\nto load them and play the demo.\n",
pdemoname);
break;
case DFILE_ERROR_OUTOFORDER:
snprintf(msg, 1024,
snprintf(msg, sizeof(msg),
"Required files for this demo are loaded out of order.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n",
pdemoname);
break;
case DFILE_ERROR_INCOMPLETEOUTOFORDER:
snprintf(msg, 1024,
snprintf(msg, sizeof(msg),
"Required files for this demo are not loaded, and some are out of order.\n\nUse\n\"playdemo %s -addfiles\"\nto load needed files and play the demo.\n",
pdemoname);
break;
case DFILE_ERROR_CANNOTLOAD:
snprintf(msg, 1024,
snprintf(msg, sizeof(msg),
"Required files for this demo cannot be loaded.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n",
pdemoname);
break;
case DFILE_ERROR_EXTRAFILES:
snprintf(msg, 1024,
snprintf(msg, sizeof(msg),
"You have additional files loaded beyond the demo's file list.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n",
pdemoname);
break;
@@ -2821,7 +2792,7 @@ void G_DoPlayDemo(char *defdemoname)
// ...*map* not loaded?
if (!gamemap || (gamemap > NUMMAPS) || (W_CheckNumForName(G_BuildMapName(gamemap)) == LUMPERROR))
{
snprintf(msg, 1024, M_GetText("%s features a course that is not currently loaded.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s features a course that is not currently loaded.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2853,7 +2824,7 @@ void G_DoPlayDemo(char *defdemoname)
// Skin not loaded?
if (!SetPlayerSkin(0, skin))
{
snprintf(msg, 1024, M_GetText("%s features a character that is not currently loaded.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s features a character that is not currently loaded.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2863,7 +2834,7 @@ void G_DoPlayDemo(char *defdemoname)
// ...*map* not loaded?
if (!gamemap || (gamemap > NUMMAPS) || !mapheaderinfo[gamemap-1] || !(mapheaderinfo[gamemap-1]->menuflags & LF2_EXISTSHACK))
{
snprintf(msg, 1024, M_GetText("%s features a course that is not currently loaded.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s features a course that is not currently loaded.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2886,7 +2857,7 @@ void G_DoPlayDemo(char *defdemoname)
// Sigh ... it's an empty demo.
if (*demobuf.p == DEMOMARKER)
{
snprintf(msg, 1024, M_GetText("%s contains no data to be played.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s contains no data to be played.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2924,7 +2895,7 @@ void G_DoPlayDemo(char *defdemoname)
// Sigh ... it's an empty demo.
if (*demobuf.p == DEMOMARKER)
{
snprintf(msg, 1024, M_GetText("%s contains no data to be played.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s contains no data to be played.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2973,7 +2944,7 @@ void G_DoPlayDemo(char *defdemoname)
if (modeattacking)
{
snprintf(msg, 1024, M_GetText("%s is a Record Attack replay with spectators, and is thus invalid.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s is a Record Attack replay with spectators, and is thus invalid.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2985,7 +2956,7 @@ void G_DoPlayDemo(char *defdemoname)
if (modeattacking && numslots > 1)
{
snprintf(msg, 1024, M_GetText("%s is a Record Attack replay with multiple players, and is thus invalid.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s is a Record Attack replay with multiple players, and is thus invalid.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
+3 -2
View File
@@ -82,7 +82,8 @@ typedef struct menudemo_s {
struct {
UINT8 ranking;
char name[17];
UINT8 skin, color;
skinnum_t skin;
UINT8 color;
UINT32 timeorscore;
} standings[MAXPLAYERS];
} menudemo_t;
@@ -97,7 +98,7 @@ void G_SetDemoTime(UINT32 ptime, UINT32 plap);
UINT8 G_CmpDemoTime(char *oldname, char *newname);
void G_LoadDemoInfo(menudemo_t *pdemo);
void G_LoadDemoTitle(menudemo_t *pdemo); // For use in replay search feature
void G_LoadDemoTitle(menudemo_t *pdemo, const char *dateformat); // For use in replay search feature
void G_DeferedPlayDemo(const char *demo);
typedef enum
+24 -35
View File
@@ -63,7 +63,7 @@ gameaction_t gameaction = 0;
gamestate_t gamestate = GS_NULL;
boolean botingame = false;
UINT8 botskin = 0;
skinnum_t botskin = 0;
UINT8 botcolor = 0;
// SRB2kart
@@ -453,34 +453,13 @@ consvar_t cv_driftsparkpulse = {"driftsparkpulse", "1.4", CV_FLOAT | CV_SAVE, dr
static CV_PossibleValue_t cechotoggle_t[] = {{0, "Off"}, {1, "On"}, {2, "Console"}, {0, NULL}};
consvar_t cv_cechotoggle = {"show_cecho", "On", CV_SAVE, cechotoggle_t, NULL, 0, NULL, NULL, 0, 0, NULL};
#if MAXPLAYERS > 16
#error "please update player_name table using the new value for MAXPLAYERS"
#endif
#ifdef SEENAMES
player_t *seenplayer = NULL; // player we're aiming at right now
#endif
char player_names[MAXPLAYERS][MAXPLAYERNAME+1] =
{
"Player 1",
"Player 2",
"Player 3",
"Player 4",
"Player 5",
"Player 6",
"Player 7",
"Player 8",
"Player 9",
"Player 10",
"Player 11",
"Player 12",
"Player 13",
"Player 14",
"Player 15",
"Player 16"
}; // SRB2kart - removed Players 17 through 32
// now automatically allocated in D_RegisterServerCommands
// so that it doesn't have to be updated depending on the value of MAXPLAYERS
char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
INT32 player_name_changes[MAXPLAYERS] = {};
INT16 rw_maximums[NUM_WEAPONS] =
@@ -625,14 +604,18 @@ const char *G_BuildMapName(INT32 map)
}
if (map < 100 && map >= 0) // ...but why use signed integer in first place? idk but this prevents warning (and potential buffer overflow lol)
sprintf(&mapname[3], "%.2d", map);
{
snprintf(&mapname[3], sizeof(mapname)-3, "%.2d", map);
}
else
{
mapname[3] = (char)('A' + (char)((map - 100) / 36));
if ((map - 100) % 36 < 10)
mapname[4] = (char)('0' + (char)((map - 100) % 36));
else
mapname[4] = (char)('A' + (char)((map - 100) % 36) - 10);
mapname[5] = '\0';
}
@@ -2647,12 +2630,18 @@ mapthing_t *G_FindRaceStart(INT32 playernum)
// Just spawn there.
//return playerstarts[0];
#if MAXPLAYERS > 16
//this section courtesy of fickle - v1.1 battle royale
// screw collision chex
return playerstarts[pos % numcoopstarts];
#else
if (P_IsLocalPlayerNum(playernum))
{
CONS_Alert(CONS_WARNING, "Could not spawn at any Race starts!\n");
}
return NULL;
#endif
}
if (P_IsLocalPlayerNum(playernum))
@@ -3787,7 +3776,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
startonmapnum = mapoverride;
#endif
sprintf(savename, savegamename, slot);
snprintf(savename, sizeof(savename), savegamename, slot);
length = FIL_ReadFile(savename, &save.buffer);
if (!length)
@@ -3799,7 +3788,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
save.p = save.buffer;
memset(vcheck, 0, sizeof (vcheck));
sprintf(vcheck, "version %d", VERSION);
snprintf(vcheck, sizeof(vcheck), "version %d", VERSION);
if (!fastcmp((const char *)save.p, (const char *)vcheck))
{
@@ -3865,8 +3854,8 @@ void G_SaveGame(UINT32 savegameslot)
const char *backup;
savebuffer_t save = {};
sprintf(savename, savegamename, savegameslot);
backup = va("%s",savename);
snprintf(savename, sizeof(savename), savegamename, savegameslot);
backup = va("%s", savename);
// save during evaluation or credits? game's over, folks!
if (gamestate == GS_CREDITS || gamestate == GS_EVALUATION)
@@ -3884,8 +3873,8 @@ void G_SaveGame(UINT32 savegameslot)
return;
}
memset(name, 0, sizeof (name));
sprintf(name, "version %d", VERSION);
memset(name, 0, sizeof(name));
snprintf(name, sizeof(name), "version %d", VERSION);
WRITEMEM(save.p, name, VERSIONSIZE);
P_SaveGame(&save);
@@ -4114,12 +4103,12 @@ char *G_BuildMapTitle(INT32 mapnum)
if (!title)
return NULL;
sprintf(title, "%s", mapheaderinfo[mapnum-1]->lvlttl);
snprintf(title, len, "%s", mapheaderinfo[mapnum-1]->lvlttl);
if (zonetext)
sprintf(title + strlen(title), " %s", zonetext);
snprintf(title + strlen(title), len - strlen(title), " %s", zonetext);
if (actnum)
sprintf(title + strlen(title), " %s", actnum);
snprintf(title + strlen(title), len - strlen(title), " %s", actnum);
}
return title;
+4 -3
View File
@@ -228,10 +228,11 @@ void G_SaveGameData(boolean force);
void G_SaveGame(UINT32 slot);
#define G_GametypeHasTeams() (G_IsGameType(GT_TEAMMATCH) || G_IsGameType(GT_CTF))
#define G_RaceGametype() (G_IsGameType(GT_RACE))
#define G_BattleGametype() (G_IsGameType(GT_MATCH))
#define G_RaceGametype() (G_IsGameType(GT_RACE))
#define G_TagGametype() (G_IsGameType(GT_TAG) || G_IsGameType(GT_HIDEANDSEEK))
#define G_GametypeHasTeams() (UNLIKELY(G_IsGameType(GT_TEAMMATCH) || G_IsGameType(GT_CTF)))
#define G_TagGametype() (UNLIKELY(G_IsGameType(GT_TAG) || G_IsGameType(GT_HIDEANDSEEK)))
FUNCINLINE static ATTRINLINE boolean G_IsGameType(int type)
{
+48 -17
View File
@@ -66,13 +66,30 @@ consvar_t cv_rumble[MAXSPLITSCREENPLAYERS] = {
static CV_PossibleValue_t rumblestrength_cons_t[] = {{FRACUNIT/4, "MIN"}, {FRACUNIT*4, "MAX"}, {0, NULL}};
consvar_t cv_rumblestrength[MAXSPLITSCREENPLAYERS] = {
consvar_t cv_rumble_strength[MAXSPLITSCREENPLAYERS] = {
{"rumblestrength", "1.0", CV_SAVE|CV_FLOAT, rumblestrength_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"rumblestrength2", "1.0", CV_SAVE|CV_FLOAT, rumblestrength_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"rumblestrength3", "1.0", CV_SAVE|CV_FLOAT, rumblestrength_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"rumblestrength4", "1.0", CV_SAVE|CV_FLOAT, rumblestrength_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}
};
#define IMPL_RUMBLE_TYPE(type)\
consvar_t cv_rumble_##type [MAXSPLITSCREENPLAYERS] = {\
{"rumble_" #type, "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},\
{"rumble2_" #type, "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},\
{"rumble3_" #type, "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},\
{"rumble4_" #type, "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}\
};
IMPL_RUMBLE_TYPE(spinout);
IMPL_RUMBLE_TYPE(sneakerboost);
IMPL_RUMBLE_TYPE(offroad);
IMPL_RUMBLE_TYPE(bananadrag);
IMPL_RUMBLE_TYPE(stairjank);
IMPL_RUMBLE_TYPE(brakedrift);
IMPL_RUMBLE_TYPE(driftcharge);
static CV_PossibleValue_t gamepadled_cons_t[] = {{0, "Off"}, {1, "Skincolor"}, {2, "Mobjcolor"}, {0, NULL}};
consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS] = {
{"gamepadled", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, gamepadled_cons_t, led_off_handle, 0, NULL, NULL, 0, 0, NULL},
@@ -1036,8 +1053,8 @@ void G_PlayerDeviceRumble(INT32 playernum, UINT16 low_strength, UINT16 high_stre
// doesent need to be super precise
// but ensure this is within range (0-65535)
// placed here so it applies to lua aswell
low_strength = (UINT16)min(FixedMul(low_strength, cv_rumblestrength[playernum].value), UINT16_MAX);
high_strength = (UINT16)min(FixedMul(high_strength, cv_rumblestrength[playernum].value), UINT16_MAX);
low_strength = (UINT16)min(FixedMul(low_strength, cv_rumble_strength[playernum].value), UINT16_MAX);
high_strength = (UINT16)min(FixedMul(high_strength, cv_rumble_strength[playernum].value), UINT16_MAX);
I_GamepadRumble(playernum, low_strength, high_strength, duration);
}
@@ -1059,7 +1076,7 @@ void G_DeviceRumbleTick(void)
{
UINT8 i;
if (dedicated || numcontrollers == 0 || gamestate != GS_LEVEL)
if (dedicated || numcontrollers == 0 || gamestate != GS_LEVEL || demo.playback)
{
return;
}
@@ -1090,6 +1107,11 @@ void G_DeviceRumbleTick(void)
const player_t *player = P_GetLocalPlayerForNum(i);
if (!player)
{
continue;
}
// allow lua to do some crap for spectators
if (player->spectator || !player->mo)
{
@@ -1105,17 +1127,20 @@ void G_DeviceRumbleTick(void)
continue;
}
if (player->kartstuff[k_spinouttimer])
if (cv_rumble_spinout[i].value
&& player->kartstuff[k_spinouttimer])
{
//low = high = FRACUNIT / 6;
low = high = FixedMul((RUMBLE_VERYSTRONG), (FixedDiv(player->kartstuff[k_spinouttimer], (3*TICRATE / 2)))); // try do some some kinda fadeout, 3*TICRATE / 2 is the "default" spinout time
}
else if (player->kartstuff[k_sneakertimer] > (sneakertime-(TICRATE/2)))
else if (cv_rumble_sneakerboost[i].value
&& (player->kartstuff[k_sneakertimer] > (sneakertime-(TICRATE/2))))
{
low = high = RUMBLE_STRONG;
}
else if ((player->kartstuff[k_offroad])
&& player->speed != 0
else if (cv_rumble_offroad[i].value
&& (player->kartstuff[k_offroad])
&& (player->speed != 0)
&& P_IsObjectOnGround(player->mo))
{
// weaken this depending on if you got hyu or invinc
@@ -1132,32 +1157,37 @@ void G_DeviceRumbleTick(void)
low = high = RUMBLE_MODERATE;
}
}
else if ((player->kartstuff[k_bananadrag] > TICRATE)
&& player->speed != 0
else if (cv_rumble_bananadrag[i].value
&& (player->kartstuff[k_bananadrag] > TICRATE)
&& (player->speed != 0)
&& P_IsObjectOnGround(player->mo))
{
if (leveltime & 1) // this is actually funny lel
high = RUMBLE_MODERATE;
}
/*else if ((player->stairjank > 8) // this is kinda cool but prob gets annoying after a while
&& player->speed != 0
else if (cv_rumble_stairjank[i].value
&& (player->stairjank > 8)
&& (player->speed != 0)
&& P_IsObjectOnGround(player->mo))
{
low = high = RUMBLE_WEAK;
}*/
low = high = RUMBLE_VERYWEAK;
}
if (player->kartstuff[k_brakedrift])
if (cv_rumble_brakedrift[i].value
&& player->kartstuff[k_brakedrift])
{
high = CLAMP((high + RUMBLE_VERYWEAK), 0, UINT16_MAX);
}
// pulse when gettin new driftlevel
// let this come last
if (player->kartstuff[k_driftcharge]
if (cv_rumble_driftcharge[i].value
&& player->kartstuff[k_driftcharge]
&& player->driftlevel)
{
high = CLAMP((high + RUMBLE_VERYWEAK), 0, UINT16_MAX);
// make it rumble slightly longer the higher your driftlevel!
if (player->driftlevel == 2)
lenght = 114;
else if (player->driftlevel == 3)
@@ -1220,7 +1250,8 @@ const char *G_KeynumToString(INT32 keynum)
return keynames[j].name;
// create a name for unknown keys
sprintf(keynamestr, "KEY%d", keynum);
snprintf(keynamestr, sizeof(keynamestr), "KEY%d", keynum);
return keynamestr;
}
+15 -5
View File
@@ -100,9 +100,10 @@ typedef enum
gc_custom2, // Lua scriptable
gc_custom3, // Lua scriptable
gc_director,
gc_freecam, // Toggle for freecam while ingame
gc_camfloat, // alternative button for raising cam
gc_camsink, // alternative button for sinking
// freecam specific controls
gc_freecam, // Toggle for freecam while ingame
gc_camfloat, // alternative button for raising camera
gc_camsink, // alternative button for sinking camera
gc_strafeleft,
gc_straferight,
num_gamecontrols
@@ -112,10 +113,19 @@ typedef enum
extern consvar_t cv_mousexsens, cv_mouseysens;
extern consvar_t cv_controlperkey;
extern consvar_t cv_turnsmooth[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumble[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumblestrength[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumble[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumble_strength[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumble_spinout[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumble_sneakerboost[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumble_offroad[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumble_bananadrag[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumble_stairjank[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumble_brakedrift[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumble_driftcharge[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_gamepadifunfocused;
extern consvar_t cv_gamepadledifunfocused;
extern consvar_t cv_rumbleifunfocused;
+2 -1
View File
@@ -55,6 +55,7 @@ extern gamestate_t gamestate;
extern gameaction_t gameaction;
extern boolean botingame;
extern UINT8 botskin, botcolor;
extern skinnum_t botskin;
extern UINT8 botcolor;
#endif //__G_STATE__
+6 -5
View File
@@ -35,7 +35,7 @@ static int finalVertexArrayAllocSize = 65536;
// not gonna use this for now, just sort by color and change state when it changes
// later maybe when using vertex attributes if it's needed
static PolygonArrayEntry* polygonArray = NULL ;// contains the polygon data from DrawPolygon, waiting to be processed
static PolygonArrayEntry* polygonArray = NULL; // contains the polygon data from DrawPolygon, waiting to be processed
static PolygonArrayEntry **polygonArraySorted = NULL; // contains sorted pointers to polygonArray
static int polygonArraySize = 0;
static int polygonArrayAllocSize = 65536;
@@ -171,8 +171,8 @@ static int comparePolygons(const void *p1, const void *p2)
// special case with signedness to prevent overflowing
// FIXME: check for prediction slowdowns!
const int shader1 = poly1->hash & 0x80000000 ? -1 : poly1->shader;
const int shader2 = poly2->hash & 0x80000000 ? -1 : poly2->shader;
const int shader1 = (poly1->hash & 0x80000000) ? -1 : poly1->shader;
const int shader2 = (poly2->hash & 0x80000000) ? -1 : poly2->shader;
// skywalls and horizon lines must retain their order for horizon lines to work
if (shader1 == -1 && shader2 == -1)
@@ -183,6 +183,7 @@ static int comparePolygons(const void *p1, const void *p2)
UINT32 downloaded1 = poly1->texture ? poly1->texture->downloaded : 0; // there should be a opengl texture name here, usable for comparisons
UINT32 downloaded2 = poly2->texture ? poly2->texture->downloaded : 0;
diff64 = downloaded1 - downloaded2;
if (diff64 != 0) return diff64;
@@ -213,8 +214,8 @@ static int comparePolygonsNoShaders(const void *p1, const void *p2)
const PolygonArrayEntry *poly1 = *(PolygonArrayEntry *const *)p1;
const PolygonArrayEntry *poly2 = *(PolygonArrayEntry *const *)p2;
const GLMipmap_t *texture1 = poly1->hash & 0x80000000 ? NULL : poly1->texture;
const GLMipmap_t *texture2 = poly2->hash & 0x80000000 ? NULL : poly2->texture;
const GLMipmap_t *texture1 = (poly1->hash & 0x80000000) ? NULL : poly1->texture;
const GLMipmap_t *texture2 = (poly2->hash & 0x80000000) ? NULL : poly2->texture;
// skywalls and horizon lines must retain their order for horizon lines to work
if (!texture1 && !texture2)
+380 -246
View File
File diff suppressed because it is too large. Load diff
+35 -37
View File
@@ -555,7 +555,8 @@ static void HWR_FreePatchCache(boolean freeall)
callback = FreeColormapsCallback;
//Z_IterateTags(PU_PATCH, PU_PATCH_ROTATED, callback);
Z_IterateTags(PU_PATCH, PU_PATCH, callback);
//Z_IterateTags(PU_PATCH, PU_PATCH_LOWPRIORITY, callback); // we dont really need to free low priority patches here as P_FreeLevelState takes care of them
Z_IterateTag(PU_PATCH, callback);
Z_IterateTags(PU_SPRITE, PU_HUDGFX, callback);
}
@@ -613,29 +614,28 @@ void HWR_FreeMapTextures(void)
gl_numtextures = 0;
}
#define NAME flatcheck
#define KEY_TY UINT32
#define HASH_FN vt_hash_integer
#define CMPR_FN vt_cmpr_integer
#include "../verstable.h"
static void HWR_PrecacheLevelFlats(void)
{
// lookup for flats that may´ve been already loaded
flatcheck flatpresent;
size_t i, j;
size_t i;
INT32 k;
flatcheck_init(&flatpresent);
flatcheck_reserve(&flatpresent, numlevelflats);
// FIXME: this needs to account for FOFs to properly work
#ifdef GLENCORE
if (encoremap)
{
return;
}
#endif
// special case for encore
#if 0
#ifdef GLENCORE
if (encoremap)
{
// go through all sectors to determine if it should be remapped for encore
for (i = 0; i < numsectors; i++)
{
size_t j;
sector_t *sec = &sectors[i];
// gotta check sector floor and ceiling
@@ -669,6 +669,7 @@ static void HWR_PrecacheLevelFlats(void)
}
}
else
#endif
#endif
{
// on non encore we have it simple
@@ -677,11 +678,7 @@ static void HWR_PrecacheLevelFlats(void)
{
const levelflat_t *levelflat = &levelflats[i];
if (flatcheck_is_end(flatcheck_get(&flatpresent, levelflat->lumpnum)))
{
HWR_GetFlat(levelflat->lumpnum, false);
flatcheck_insert(&flatpresent, levelflat->lumpnum);
}
HWR_GetFlat(levelflat->lumpnum, false);
if (levelflat->speed) // is it an animated flat ?
{
@@ -689,17 +686,11 @@ static void HWR_PrecacheLevelFlats(void)
for (k = 0; k < levelflat->numpics; k++)
{
lumpnum_t lump = levelflat->baselumpnum + k;
if (flatcheck_is_end(flatcheck_get(&flatpresent, lump)))
{
HWR_GetFlat(lump, false);
flatcheck_insert(&flatpresent, lump);
}
HWR_GetFlat(lump, false);
}
}
}
}
flatcheck_cleanup(&flatpresent);
}
static void HWR_PrecacheLevelTextures(void)
@@ -723,7 +714,7 @@ static void HWR_PrecacheLevelTextures(void)
{
const line_t *line = &lines[i];
#ifdef GLENCORE
const int noencoremap = ((encoremap && (line->flags & ML_TFERLINE)) ? 2 : 1);
const boolean noencoremap = (encoremap && (line->flags & ML_TFERLINE));
#endif
// two sides
for (j = 0; j < 2; j++)
@@ -740,25 +731,27 @@ static void HWR_PrecacheLevelTextures(void)
{
const INT32 texnum = sidetex[f];
if (texnum < 0 || texnum >= (signed)gl_numtextures)
if (texnum <= 0 || (unsigned)texnum >= gl_numtextures)
continue;
if (texturepresent[texnum])
continue;
if (!(texturepresent[texnum] & 1))
{
texturepresent[texnum] |= 1;
HWR_GetTexture(texnum, false);
}
#ifdef GLENCORE
texturepresent[texnum] = 1|noencoremap;
#else
texturepresent[texnum] = 1;
#endif
HWR_GetTexture(texnum, false);
#ifdef GLENCORE
if (noencoremap & 2)
if (noencoremap
&& !(texturepresent[texnum] & 2))
{
texturepresent[texnum] |= 2;
HWR_GetTexture(texnum, true);
}
#endif
}
}
}
// check for animated textures
for (anim = anims; anim < lastanim; anim++)
{
if (!anim->istexture)
@@ -777,6 +770,7 @@ static void HWR_PrecacheLevelTextures(void)
{
HWR_GetTexture(animtexnum, false);
}
#ifdef GLENCORE
if (texpresent & 2)
{
@@ -898,7 +892,7 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean noencore)
GLMapTexture_t *gltex;
GLMipmap_t *glMipmap;
if (tex < 0 || tex >= (signed)gl_numtextures)
if (tex < 0 || (unsigned)tex >= gl_numtextures)
{
#ifdef PARANOIA
I_Error("HWR_GetTexture: Invalid texture ID %d", tex);
@@ -998,7 +992,7 @@ static void HWR_CacheFlat(GLMipmap_t *glMipmap, lumpnum_t flatlumpnum)
const char *flatname = W_CheckNameForNum(flatlumpnum);
// hack for gba rainbow roads cyan floors
if (UNLIKELY(memcmp(flatname, "GBA_RRF5", 8) == 0 && flatname[8] == 0))
if (UNLIKELY(flatname && memcmp(flatname, "GBA_RRF5", 8) == 0 && flatname[8] == 0))
{
glMipmap->flags &= ~TF_CHROMAKEYED;
}
@@ -1314,6 +1308,7 @@ void HWR_SetPalette(RGBA_t *palette)
crushed_palette[i].s.blue = (UINT8)(fblue / 31.0f * 255.0f);
crushed_palette[i].s.alpha = 255;
}
GL_SetScreenPalette(crushed_palette);
}
else
@@ -1391,6 +1386,7 @@ void HWR_SetMapPalette(void)
I_Error("HWR_SetMapPalette: A programmer assumed palette lumps are at least 768 bytes long, but apparently this was a wrong assumption!\n");
RGB_data = (UINT8 *)(W_CacheLumpNum(lumpnum, PU_CACHE));
// we got the RGB palette now, but we need it in RGBA format.
for (i = 0; i < 256; i++)
{
@@ -1399,6 +1395,7 @@ void HWR_SetMapPalette(void)
RGBA_converted[i].s.blue = *(RGB_data++);
RGBA_converted[i].s.alpha = 255;
}
palette = RGBA_converted;
}
@@ -1406,6 +1403,7 @@ void HWR_SetMapPalette(void)
if (memcmp(mapPalette, palette, sizeof(mapPalette)))
{
memcpy(mapPalette, palette, sizeof(mapPalette));
// in palette rendering mode, this means that all rgba textures now have wrong colors
// and the lookup table is outdated
HWR_SetPaletteLookup(mapPalette);
-1
View File
@@ -96,7 +96,6 @@ typedef struct
typedef struct
{
float x, y, z;
fixed_t x2, y2, z2;
} polyvertex_t;
// a convex 'plane' polygon, clockwise order
+1 -1
View File
@@ -54,7 +54,7 @@ void HWR_ObjectLightLevelPost(gl_vissprite_t *spr, const sector_t *sector, INT32
// --------
extern extrasubsector_t *extrasubsectors;
#ifdef PARANOIA
extern size_t addsubsector;
extern size_t num_extra_subsector;
#endif
void HWR_FreeExtraSubsectors(void);
+185 -134
View File
@@ -84,11 +84,6 @@ float gl_viewsin = 0.0f, gl_viewcos = 0.0f;
static float gl_viewludsin, gl_viewludcos;
static angle_t gl_aimingangle;
static float yaw = 0.0f;
static float inv_yaw = 0.0f;
static float cos_inv_yaw = 0.0f;
static float sin_inv_yaw = 0.0f;
static constexpr float deg2radians = (M_PIf / 180.0f);
seg_t *gl_curline = NULL;
@@ -519,7 +514,7 @@ static FUINT HWR_CalcWallLight(FUINT lightnum, seg_t *seg, extracolormap_t *colo
const INT16 offset = (cv_glfakecontrast.value == 2) ? seg->hwLightOffset : ((INT16)seg->lightOffset * 8);
finallight += offset;
finallight = CLAMP(finallight, 0 , 255);
finallight = CLAMP(finallight, 0, 255);
}
return (FUINT)finallight;
@@ -537,7 +532,7 @@ static FUINT HWR_CalcSlopeLight(FUINT lightnum, pslope_t *slope, const sector_t
const INT16 offset = (cv_glfakecontrast.value == 2) ? slope->hwLightOffset : ((INT16)slope->lightOffset * 8);
finallight += (fof ? -offset : offset);
finallight = CLAMP(finallight, 0 , 255);
finallight = CLAMP(finallight, 0, 255);
}
return (FUINT)finallight;
@@ -615,7 +610,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
fflatsize = 1024.0f;
flatflag = 1023;
break;
case 262144:// 512x512 lump
case 262144: // 512x512 lump
fflatsize = 512.0f;
flatflag = 511;
break;
@@ -726,7 +721,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags, shader, false);
if (gl_maphashorizonlines && subsector && cv_glhorizonlines.value)
if (gl_maphashorizonlines && subsector && !FOFsector && cv_glhorizonlines.value)
{
// Horizon lines
FOutVector horizonpts[6];
@@ -747,7 +742,6 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
line_t* ld = line->linedef;
// this check sucks and is a hotspot lel
if (LIKELY(ld->special != HORIZONSPECIAL))
continue;
@@ -1106,8 +1100,8 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
// Found a break
// The heights are clamped to ensure the polygon doesn't cross itself.
bot = std::clamp(bheight, realbot, top);
endbot = std::clamp(endbheight, endrealbot, endtop);
bot = std::min(std::max(bheight, realbot), top);
endbot = std::min(std::max(endbheight, endrealbot), endtop);
Surf->PolyColor.s.alpha = alpha;
@@ -1241,50 +1235,48 @@ static void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf)
// Returns true if the midtexture is visible, and false if... it isn't...
static inline boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf)
{
FUINT blendmode = PF_Masked | PF_Translucent;
FUINT blendmode = PF_Masked;
pSurf->PolyColor.s.alpha = 0xFF;
if (LIKELY(!gl_curline->polyseg))
{
// check if linedef alpha is within range
const boolean linealpha = (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT);
// check if linedef alpha is within range
const boolean linealpha = (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT);
// set alpha for transparent walls
switch (gl_linedef->special)
{
// Translucent linedef types
case 102:
case 121 ... 125:
case 141 ... 145:
case 174:
case 175:
case 192:
case 195:
case 221:
case 253:
case 256:
if (gl_linedef->blendmode && linealpha)
// set alpha for transparent walls
switch (gl_linedef->special)
{
// Translucent linedef types
case 102:
case 121 ... 125:
case 141 ... 145:
case 174:
case 175:
case 192:
case 195:
case 221:
case 253:
case 256:
if (gl_linedef->blendmode && linealpha)
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = PF_Translucent;
break;
default:
if (gl_linedef->blendmode)
{
if (linealpha)
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = PF_Translucent;
break;
default:
if (gl_linedef->blendmode)
{
if (linealpha)
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode);
}
else if (linealpha)
blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = PF_Masked;
break;
}
blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode);
}
else if (linealpha)
blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = PF_Masked;
break;
}
else if (gl_curline->polyseg->translucency > 0)
if (gl_curline->polyseg && gl_curline->polyseg->translucency > 0)
{
// Polyobject translucency is shared between all of its lines
if (gl_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn
@@ -1391,7 +1383,8 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// two sided line
if (gl_backsector)
{
INT32 gl_toptexture = 0, gl_bottomtexture = 0;
const INT32 gl_toptexture = R_GetTextureNum(gl_sidedef->toptexture);
const INT32 gl_bottomtexture = R_GetTextureNum(gl_sidedef->bottomtexture);
fixed_t texturevpeg;
@@ -1402,7 +1395,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if (!gl_curline->polyseg) // Don't do it for polyobjects
{
// Sky Ceilings
wallVerts[3].y = wallVerts[2].y = FLOATMAX;
wallVerts[2].y = wallVerts[3].y = FLOATMAX; // draw to top of map space
auto draw_sky_walls = []
(int vert1, int vert2, fixed_t world, fixed_t worldslope, auto& wwallVerts, auto& sSurf) FUNCINLINE
@@ -1412,6 +1405,9 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
HWR_DrawSkyWall(wwallVerts, &sSurf);
};
// worldtop = front ceiling
// worldhigh = back ceiling
if (gl_frontsector->ceilingpic == skyflatnum)
{
if (gl_backsector->ceilingpic == skyflatnum)
@@ -1430,6 +1426,17 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
worldtop = worldhigh;
worldtopslope = worldhighslope;
}
else if (!gl_toptexture &&
(worldhigh <= worldtop && worldhighslope <= worldtopslope) && // Assuming ESLOPE is always on with my changes
(worldhigh != worldtop || worldhighslope != worldtopslope))
{
// Only the frontsector is sky.
// If there's no upper texture, extend the sky wall
// down to the lower of the two ceilings.
fixed_t top = std::min(worldtop, worldhigh);
fixed_t topslope = std::min(worldtopslope, worldhighslope);
draw_sky_walls(0, 1, top, topslope, wallVerts, Surf);
}
else
{
// Only the frontsector is sky, just draw a skywall from the front ceiling
@@ -1442,8 +1449,11 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
draw_sky_walls(0, 1, worldtop, worldtopslope, wallVerts, Surf);
}
// worldbottom = front floor
// worldlow = back floor
// Sky Floors
wallVerts[0].y = wallVerts[1].y = FLOATMIN;
wallVerts[0].y = wallVerts[1].y = FLOATMIN; // draw to bottom of map space
if (gl_frontsector->floorpic == skyflatnum)
{
@@ -1455,7 +1465,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if ((worldlow >= worldbottom && worldlowslope >= worldbottomslope)
&& (worldlow != worldbottom || worldlowslope != worldbottomslope)
// Removing the second line above will render more rarely visible skywalls. Example: Cave garden ceiling in Dark race
&& !(gl_sidedef->bottomtexture))
&& !(gl_bottomtexture))
{
draw_sky_walls(3, 2, worldlow, worldlowslope, wallVerts, Surf);
}
@@ -1466,15 +1476,25 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
draw_sky_walls(3, 2, worldbottom, worldbottomslope, wallVerts, Surf);
}
}
else if ((gl_backsector->floorpic == skyflatnum) && !(gl_sidedef->bottomtexture))
else if ((gl_backsector->floorpic == skyflatnum) && !(gl_bottomtexture))
{
// Only the backsector has sky, just draw a skywall from the back floor if there's no bottomtexture
draw_sky_walls(3, 2, worldlow, worldlowslope, wallVerts, Surf);
}
else if (gl_frontsector->ceilingpic == skyflatnum &&
gl_backsector->ceilingpic == skyflatnum &&
(worldlow >= worldbottom && worldlowslope >= worldbottomslope)
&& (worldlow != worldbottom || worldlowslope != worldbottomslope)
// Removing the second line above will render more rarely visible skywalls. Example: Cave garden ceiling in Dark race
&& !(gl_bottomtexture))
{
// Both ceilings are sky, but neither floor is sky.
// If there's a lower wall gap without a bottom texture,
// draw a skywall from the backsector's higher floor.
draw_sky_walls(3, 2, worldlow, worldlowslope, wallVerts, Surf);
}
}
gl_toptexture = R_GetTextureNum(gl_sidedef->toptexture);
// check TOP TEXTURE
if (gl_toptexture && (worldhighslope < worldtopslope || worldhigh < worldtop))
{
@@ -1538,8 +1558,6 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
}
gl_bottomtexture = R_GetTextureNum(gl_sidedef->bottomtexture);
// check BOTTOM TEXTURE
if (gl_bottomtexture && (worldlowslope > worldbottomslope || worldlow > worldbottom))
{
@@ -2311,7 +2329,7 @@ static inline void DoAddLine(seg_t* line, angle_t angle1, angle_t angle2)
// Find the other side!
INT32 line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->linedef->tag, -1);
if (line->linedef == &lines[line2])
if (line2 >= 0 && line->linedef == &lines[line2])
line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->linedef->tag, line2);
if (line2 >= 0) // found it!
@@ -2667,11 +2685,13 @@ static void HWR_AddPolyObjectPlanes(void)
polyobjsector = po_ptrs[i]->lines[0]->backsector; // the in-level polyobject sector
if (polyobjsector->floorheight <= gl_frontsector->ceilingheight
&& polyobjsector->floorheight >= gl_frontsector->floorheight
&& (viewz < polyobjsector->floorheight))
if (polyobjsector->floorheight <= gl_frontsector->ceilingheight &&
polyobjsector->floorheight >= gl_frontsector->floorheight &&
(viewz < polyobjsector->floorheight))
{
light = R_GetPlaneLight(gl_frontsector, polyobjsector->floorheight, true);
const INT16 llevel = (light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel);
extracolormap_t *colmap = (light == -1 ? gl_frontsector->extra_colormap : gl_frontsector->lightlist[light].extra_colormap);
if (po_ptrs[i]->translucency > 0)
{
@@ -2679,22 +2699,24 @@ static void HWR_AddPolyObjectPlanes(void)
FBITFIELD blendmode;
blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf);
HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->floorpic].lumpnum, po_ptrs[i], false, polyobjsector->floorheight,
(light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), Surf.PolyColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gl_frontsector->extra_colormap : gl_frontsector->lightlist[light].extra_colormap));
llevel, Surf.PolyColor.s.alpha, polyobjsector, blendmode, colmap);
}
else
{
HWR_GetFlat(levelflats[polyobjsector->floorpic].lumpnum, R_NoEncore(polyobjsector, false));
HWR_RenderPolyObjectPlane(po_ptrs[i], false, polyobjsector->floorheight, PF_Occlude,
(light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum,
polyobjsector, 255, (light == -1 ? gl_frontsector->extra_colormap : gl_frontsector->lightlist[light].extra_colormap));
llevel, levelflats[polyobjsector->floorpic].lumpnum,
polyobjsector, 255, colmap);
}
}
if (polyobjsector->ceilingheight >= gl_frontsector->floorheight
&& polyobjsector->ceilingheight <= gl_frontsector->ceilingheight
&& (viewz > polyobjsector->ceilingheight))
if (polyobjsector->ceilingheight >= gl_frontsector->floorheight &&
polyobjsector->ceilingheight <= gl_frontsector->ceilingheight &&
(viewz > polyobjsector->ceilingheight))
{
light = R_GetPlaneLight(gl_frontsector, polyobjsector->ceilingheight, true);
const INT16 llevel = (light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel);
extracolormap_t *colmap = (light == -1 ? gl_frontsector->extra_colormap : gl_frontsector->lightlist[light].extra_colormap);
if (po_ptrs[i]->translucency > 0)
{
@@ -2702,14 +2724,14 @@ static void HWR_AddPolyObjectPlanes(void)
FBITFIELD blendmode;
blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf);
HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->ceilingpic].lumpnum, po_ptrs[i], true, polyobjsector->ceilingheight,
(light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), Surf.PolyColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gl_frontsector->extra_colormap : gl_frontsector->lightlist[light].extra_colormap));
llevel, Surf.PolyColor.s.alpha, polyobjsector, blendmode, colmap);
}
else
{
HWR_GetFlat(levelflats[polyobjsector->ceilingpic].lumpnum, R_NoEncore(polyobjsector, true));
HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude,
(light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->ceilingpic].lumpnum,
polyobjsector, 255, (light == -1 ? gl_frontsector->extra_colormap : gl_frontsector->lightlist[light].extra_colormap));
llevel, levelflats[polyobjsector->ceilingpic].lumpnum,
polyobjsector, 255, colmap);
}
}
}
@@ -2784,9 +2806,9 @@ static void HWR_Subsector(size_t num)
ffloor_t *rover;
#ifdef PARANOIA // no risk while developing, enough debugging nights!
if (num >= addsubsector)
if (num >= num_extra_subsector)
I_Error("HWR_Subsector: ss %s with numss = %s, addss = %s\n",
sizeu1(num), sizeu2(numsubsectors), sizeu3(addsubsector));
sizeu1(num), sizeu2(numsubsectors), sizeu3(num_extra_subsector));
#endif
if (num < numsubsectors)
@@ -2963,7 +2985,7 @@ static void HWR_Subsector(size_t num)
}
else
{
HWR_GetFlat(flatlump, R_NoEncore(gl_frontsector, !bottom));
HWR_GetFlat(flatlump, R_NoEncore(rover->master->frontsector, bottom));
light = R_GetPlaneLight(gl_frontsector, centerHeight, underside);
HWR_RenderPlane(sub, &extrasubsectors[num], !bottom, roverheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, flatlump,
@@ -3240,6 +3262,18 @@ static void HWR_DrawSpriteShadow(gl_vissprite_t *spr, patch_t *gpatch, GLPatch_t
if (!spr->mobj)
return;
// Ceiling scenery have no shadow.
if ((spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) == (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY))
return;
// Debris have no corona or shadow.
if (spr->mobj->flags2 & MF2_DEBRIS)
return;
// Without this, your shadow shows on the floor, even after you die and fall through the ground.
if (spr->mobj->z < spr->mobj->floorz)
return;
R_GetShadowZ(spr->mobj, &floorslope);
mobjfloor = HWR_OpaqueFloorAtPos(
@@ -3449,8 +3483,12 @@ static inline void HWR_ApplyDispoffset(gl_vissprite_t *spr, FOutVector *wallVert
{
HWR_RotateSpritePolyToAim(spr, wallVerts, false, papersprite);
const float sprdist = sqrtf((spr->x1 - gl_viewx)*(spr->x1 - gl_viewx) + (spr->z1 - gl_viewy)*(spr->z1 - gl_viewy) + (spr->gzt - gl_viewz)*(spr->gzt - gl_viewz));
const float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist;
const float f_xdiff = (spr->x1 - gl_viewx);
const float f_ydiff = (spr->z1 - gl_viewy);
const float f_zdiff = (spr->gzt - gl_viewz);
const float sprdist = sqrtf((f_xdiff*f_xdiff) + (f_ydiff*f_ydiff) + (f_zdiff*f_zdiff));
const float distfact = ((2.0f * spr->dispoffset) + 20.0f) / sprdist;
for (size_t i = 0; i < 4; i++)
{
@@ -3488,6 +3526,8 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
fixed_t v1x, v1y, v2x, v2y;
INT32 shader = SHADER_NONE;
const boolean billboarding = (cv_glspritebillboarding.value && !cv_glshearing.value && !papersprite);
gpatch = spr->gpatch;
// cache the patch in the graphics card memory
@@ -3498,10 +3538,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
hwrpatch = static_cast<GLPatch_t *>(gpatch->hardware);
// Draw shadow BEFORE sprite
if (UNLIKELY(cv_shadow.value // Shadows enabled
&& (sprmo->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow.
&& !(sprmo->flags2 & MF2_DEBRIS) // Debris have no corona or shadow.
&& (sprmo->z >= sprmo->floorz))) // Without this, your shadow shows on the floor, even after you die and fall through the ground.
if (UNLIKELY(cv_shadow.value))
{
////////////////////
// SHADOW SPRITE! //
@@ -3685,7 +3722,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
wallVerts[1].y = endbot;
// The x and y only need to be adjusted in the case that it's not a papersprite
if (cv_glspritebillboarding.value && !cv_glshearing.value && !papersprite)
if (billboarding)
{
// Get the x and z of the vertices so billboarding draws correctly
realheight = realbot - realtop;
@@ -3707,11 +3744,11 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
wallVerts[1].z = baseWallVerts[2].z + (baseWallVerts[2].z - baseWallVerts[1].z) * heightmult;
}
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector) && !(sprmo->frame & FF_FULLBRIGHT));
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector) && !R_ThingIsFullBright(sprmo));
Surf.PolyColor.s.alpha = alpha;
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false); // sprite shader
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false);
top = bot;
endtop = endbot;
@@ -3738,7 +3775,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
Surf.PolyColor.s.alpha = alpha;
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false); // sprite shader
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false);
}
// -----------------+
@@ -3761,7 +3798,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
if (!sprmo->subsector)
return;
const boolean papersprite = (sprmo->frame & FF_PAPERSPRITE);
const boolean papersprite = R_ThingIsPaperSprite(sprmo);
const sector_t *sector = sprmo->subsector->sector;
if (sector->numlights)
@@ -3827,10 +3864,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
}
// Draw shadow BEFORE sprite
if (UNLIKELY(cv_shadow.value // Shadows enabled
&& (sprmo->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow.
&& !(sprmo->flags2 & MF2_DEBRIS) // Debris have no corona or shadow.
&& (sprmo->z >= sprmo->floorz))) // Without this, your shadow shows on the floor, even after you die and fall through the ground.
if (UNLIKELY(cv_shadow.value))
{
////////////////////
// SHADOW SPRITE! //
@@ -3920,7 +3954,7 @@ static void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
INT32 shader = SHADER_NONE;
const precipmobj_t *sprmo = spr->precip;
precipmobj_t *sprmo = spr->precip;
if (!sprmo->subsector)
return;
@@ -3966,11 +4000,10 @@ static void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
if (sector->numlights)
{
INT32 light;
// Always use the light at the top instead of whatever I was doing before
INT32 light = R_GetPlaneLight(sector, sprmo->z, false); // sprmo->z + sprmo->height
light = R_GetPlaneLight(sector, sprmo->z, false); // Always use the light at the top instead of whatever I was doing before
if (!(sprmo->frame & FF_FULLBRIGHT))
if (!R_PrecipThingIsFullBright(sprmo))
lightlevel = static_cast<INT32>(*sector->lightlist[light].lightlevel);
if (sector->lightlist[light].extra_colormap)
@@ -3978,7 +4011,7 @@ static void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
}
else
{
if (!(sprmo->frame & FF_FULLBRIGHT))
if (!R_PrecipThingIsFullBright(sprmo))
lightlevel = static_cast<INT32>(sector->lightlevel);
if (sector->extra_colormap)
@@ -4281,7 +4314,10 @@ static void HWR_RenderDrawNodes(void)
gl_frontsector = NULL;
if (!(plane->blend & PF_NoTexture))
HWR_GetFlat(plane->lumpnum, R_NoEncore(plane->FOFSector, plane->isceiling));
{
const boolean ceiling = plane->FOFSector ? !plane->isceiling : plane->isceiling; // match software!
HWR_GetFlat(plane->lumpnum, R_NoEncore(plane->FOFSector, ceiling));
}
HWR_RenderPlane(NULL, plane->xsub, plane->isceiling, plane->fixedheight, plane->blend, plane->lightlevel,
plane->lumpnum, plane->FOFSector, plane->alpha, plane->planecolormap);
@@ -4562,7 +4598,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
return;
}
const boolean papersprite = (thing->frame & FF_PAPERSPRITE);
const boolean papersprite = R_ThingIsPaperSprite(thing);
// transform the origin point
tr_x = FixedToFloat(interp.x);
@@ -4576,8 +4612,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
return;
const boolean mirrored = thing->mirrored;
const boolean vflip = (thing->eflags & MFE_VERTICALFLIP);
const boolean hflip = (!(thing->frame & FF_HORIZONTALFLIP) != !mirrored);
const boolean vflip = R_ThingVerticallyFlipped(thing);
const boolean hflip = (!R_ThingHorizontallyFlipped(thing) != !mirrored);
// decide which patch to use for sprite relative to player
#ifdef RANGECHECK
@@ -4764,9 +4800,9 @@ static void HWR_ProjectSprite(mobj_t *thing)
// if the sprite is out of our view, dont need to draw it X)
if (!gld_SphereInFrustum(
(FixedToFloat(interp.x)) + cos_inv_yaw * (x1 + x2) / 2.0f,
(FixedToFloat(interp.x)) + gl_viewsin * (x1 + x2) / 2.0f,
FixedToFloat(interp.z) + (y1 + y2) / 2.0f,
FixedToFloat(interp.y) - sin_inv_yaw * (x1 + x2) / 2.0f,
FixedToFloat(interp.y) - (-gl_viewcos) * (x1 + x2) / 2.0f,
//1.5 == sqrt(2) + small delta for MF_FOREGROUND
std::max<float>(FixedToFloat(spr_width) * spritexscale,
FixedToFloat(spr_height) * spriteyscale) / 2.0f * 1.5f))
@@ -4984,9 +5020,9 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
y2 *= thing_scale;
if (!gld_SphereInFrustum(
(FixedToFloat(interp.x)) + cos_inv_yaw * (x1 + x2) / 2.0f,
(FixedToFloat(interp.x)) + gl_viewsin * (x1 + x2) / 2.0f,
FixedToFloat(interp.z) + (y1 + y2) / 2.0f,
FixedToFloat(interp.y) - sin_inv_yaw * (x1 + x2) / 2.0f,
FixedToFloat(interp.y) - (-gl_viewcos) * (x1 + x2) / 2.0f,
//1.5 == sqrt(2) + small delta for MF_FOREGROUND
std::max<float>(FixedToFloat(spr_width) * thing_scale,
FixedToFloat(spr_height) * thing_scale) / 2.0f * 1.5f))
@@ -5116,24 +5152,22 @@ void HWR_BuildSkyDome(void)
int c, r;
signed char yflip;
static constexpr int row_count = 4;
int col_count = 4;
static constexpr int col_count = (4 * 16);
float delta;
gl_sky_t *sky = &gl_sky;
gl_skyvertex_t *vertex_p;
const texture_t *texture = textures[texturetranslation[skytexture]];
col_count *= 16;
if ((sky->columns != col_count) || (sky->rows != row_count))
HWR_ClearSkyDome();
sky->columns = col_count;
sky->rows = row_count;
sky->vertex_count = 2 * sky->rows * (sky->columns * 2 + 2) + sky->columns * 2;
sky->vertex_count = 2 * row_count * (col_count * 2 + 2) + col_count * 2;
if (!sky->loops)
sky->loops = static_cast<gl_skyloopdef_t*>(malloc((sky->rows * 2 + 2) * sizeof(sky->loops[0])));
sky->loops = static_cast<gl_skyloopdef_t*>(malloc((row_count * 2 + 2) * sizeof(sky->loops[0])));
// create vertex array
if (!sky->data)
@@ -5397,12 +5431,6 @@ void HWR_SetTransform(float fpov)
HWR_SetTransformAiming(&atransform);
atransform.angley = static_cast<float>(viewangle >> ANGLETOFINESHIFT)*(FINEDEGREE);
yaw = 270.0f - atransform.angley;
inv_yaw = 180.0f - yaw;
const float inv_yaw_radians = inv_yaw * deg2radians;
cos_inv_yaw = cosf(inv_yaw_radians);
sin_inv_yaw = sinf(inv_yaw_radians);
// only needed for sprite billboarding
if (cv_glspritebillboarding.value && !cv_glshearing.value)
{
@@ -5465,6 +5493,8 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, int stencil_level, bool
{
gl_portallist_t portallist;
const boolean wireframe = HWR_IsWireframeMode();
player_t *viewplayer = &players[displayplayers[viewssnum]];
const float fpov = FixedToFloat(R_GetPlayerFov(viewplayer));
@@ -5525,7 +5555,7 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, int stencil_level, bool
}
}
if (HWR_IsWireframeMode())
if (wireframe)
GL_SetSpecialState(HWD_SET_WIREFRAME, 1);
// FIXME: perfstats does not account for portal rendering!
@@ -5540,7 +5570,8 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, int stencil_level, bool
if constexpr (Type == RenderViewpointType::kPortal)
{
gl_collect_skywalls = (allow_portals && !rootportal && portallist.base && (!skyboxmo[0] || !cv_skybox.value)); // if portals have been drawn in the main view, then render skywalls differently
// if portals have been drawn in the main view, then render skywalls differently
gl_collect_skywalls = (allow_portals && !rootportal && portallist.base && (!skyboxmo[0] || !cv_skybox.value));
// HAYA: Save the old portal state, and turn portals off while normally rendering the BSP tree.
// This fixes specific effects not working, such as horizon lines.
@@ -5610,7 +5641,7 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, int stencil_level, bool
HWR_RenderDrawNodes();
if (HWR_IsWireframeMode())
if (wireframe)
GL_SetSpecialState(HWD_SET_WIREFRAME, 0);
HWR_FreePortalList(portallist); // always call this just in case
@@ -5999,6 +6030,10 @@ static void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD
static void HWR_DoPostProcessor(void)
{
// no flashes or screen waving if we want less vfx!
if (cv_reducevfx.value)
return;
// Armageddon Blast Flash!
// Could this even be considered postprocessor?
if (!HWR_ShouldUsePaletteRendering())
@@ -6038,7 +6073,7 @@ static void HWR_DoPostProcessor(void)
return;
// Not supported in splitscreen - someone want to add support?
if (splitscreen || cv_reducevfx.value)
if (splitscreen)
return;
//UINT8 viewnum = R_GetViewNumber();
@@ -6096,44 +6131,60 @@ static void HWR_DoPostProcessor(void)
// Flipping of the screen isn't done here anymore
}
void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum)
//
// wipes
//
static lumpnum_t wipelumpnum;
// puts wipe lumpname in wipename[9]
static boolean HWR_WipeCheck(UINT8 wipenum, UINT8 scrnnum)
{
static char lumpname[9] = "FADEmmss";
lumpnum_t lumpnum;
size_t lsize;
// screen textures disabled completely
if (cv_glscreentextures.value == 0)
{
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // just draw a black screen instead of flashing and crap
return;
return false;
}
if (wipenum > 99 || scrnnum > 99) // not a valid wipe number
// not a valid wipe number
if (wipenum > 99 || scrnnum > 99)
{
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // just draw a black screen instead of flashing and crap
return; // shouldn't end up here really, the loop should've stopped running beforehand
return false; // shouldn't end up here really, the loop should've stopped running beforehand
}
// puts the numbers into the lumpname
sprintf(&lumpname[4], "%.2hu%.2hu", (UINT16)wipenum, (UINT16)scrnnum);
lumpnum = W_CheckNumForName(lumpname);
snprintf(&lumpname[4], sizeof(lumpname) - 4, "%.2hu%.2hu", (UINT16)wipenum, (UINT16)scrnnum);
wipelumpnum = W_CheckNumForName(lumpname);
if (lumpnum == LUMPERROR) // again, shouldn't be here really
// again, shouldn't be here really
if (wipelumpnum == LUMPERROR)
{
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // just draw a black screen instead of flashing and crap
return;
return false;
}
lsize = W_LumpLength(lumpnum);
lsize = W_LumpLength(wipelumpnum);
if (!(lsize == 256000 || lsize == 64000 || lsize == 16000 || lsize == 4000))
{
CONS_Alert(CONS_WARNING, "Fade mask lump %s of incorrect size, ignored\n", lumpname);
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // just draw a black screen instead of flashing and crap
return; // again, shouldn't get here if it is a bad size
return false; // again, shouldn't get here if it is a bad size
}
HWR_GetFadeMask(lumpnum);
return true;
}
void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum)
{
if (!HWR_WipeCheck(wipenum, scrnnum))
{
// just draw a black screen instead of rapidly flashing a white screen
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
return;
}
HWR_GetFadeMask(wipelumpnum);
GL_DoScreenWipe(HWD_SCREENTEXTURE_WIPE_START, HWD_SCREENTEXTURE_WIPE_END);
}
+9 -6
View File
@@ -1146,15 +1146,18 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
// Look at HWR_ProjectSprite for more
{
md2_t *md2s;
int skinnum;
md2_t *md2s = NULL;
int skinnum = 0;
patch_t *gpatch, *blendgpatch;
GLPatch_t *hwrPatch = NULL, *hwrBlendPatch = NULL;
INT32 durs = spr->mobj->state->tics;
INT32 tics = spr->mobj->tics;
//mdlframe_t *next = NULL;
//const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(spr->mobj)); // :chaosleep:
const UINT8 flip = (UINT8)((spr->mobj->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP);
const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !(spr->mobj->frame & FF_HORIZONTALFLIP));
const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !R_ThingHorizontallyFlipped(spr->mobj));
spritedef_t *sprdef;
spriteframe_t *sprframe;
spriteinfo_t *sprinfo;
@@ -1218,7 +1221,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
skinnum = (skin_t *)spr->mobj->localskin - skins;
}
}
else
else if (spr->mobj->skin)
{
md2s = md2_playermodels;
skinnum = (skin_t *)spr->mobj->skin - skins;
@@ -1244,7 +1247,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
if (!md2->model)
{
CONS_Debug(DBG_RENDER, "Loading model... (%s, %s)", sprnames[spr->mobj->sprite], md2->filename);
sprintf(filename, "mdls/%s", md2->filename);
snprintf(filename, sizeof(filename), "mdls/%s", md2->filename);
md2->model = md2_readModel(filename);
if (md2->model)
@@ -1480,7 +1483,7 @@ void HWR_Draw2DModel(md2_t *md2, INT32 x, INT32 y, INT32 skinnum, skincolors_t c
{
char filename[64];
CONS_Debug(DBG_RENDER, "Loading model... (%s)\n", md2->filename);
sprintf(filename, "mdls/%s", md2->filename);
snprintf(filename, sizeof(filename), "mdls/%s", md2->filename);
md2->model = md2_readModel(filename);
if (md2->model)
+1 -57
View File
@@ -275,13 +275,6 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
return NULL;
retModel = (model_t*)Z_Calloc(sizeof(model_t), ztag, NULL);
//size_t fileLen;
//int i, j;
//size_t namelen;
//char *texturefilename;
texPos = strchr(fileName, '/');
if (texPos)
@@ -318,8 +311,6 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
retModel->numMeshes = 1; // MD2 only has one mesh
retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t) * retModel->numMeshes, ztag, NULL);
retModel->meshes[0].numFrames = header->numFrames;
// const float WUNITS = 1.0f;
// float dataScale = WUNITS;
// Tris and ST are simple structures that can be straight-copied
tris = (md2triangle_t*)&buffer[header->offsetTris];
@@ -355,47 +346,6 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
retModel->materials[t].specular[3] = 1.0f;
retModel->materials[t].shininess = 0.0f;
retModel->materials[t].spheremap = false;
/* retModel->materials[t].texture = Texture::ReadTexture((char*)texturefilename, ZT_TEXTURE);
if (!systemSucks)
{
// Check for a normal map...??
char openfilename[1024];
char normalMapName[1024];
strcpy(normalMapName, texturefilename);
size_t len = strlen(normalMapName);
char *ptr = &normalMapName[len];
ptr--; // z
ptr--; // u
ptr--; // b
ptr--; // .
*ptr++ = '_';
*ptr++ = 'n';
*ptr++ = '.';
*ptr++ = 'b';
*ptr++ = 'u';
*ptr++ = 'z';
*ptr++ = '\0';
sprintf(openfilename, "%s/%s", "textures", normalMapName);
// Convert backslashes to forward slashes
for (int k = 0; k < 1024; k++)
{
if (openfilename[k] == '\0')
break;
if (openfilename[k] == '\\')
openfilename[k] = '/';
}
Resource::resource_t *res = Resource::Open(openfilename);
if (res)
{
Resource::Close(res);
retModel->materials[t].lightmap = Texture::ReadTexture(normalMapName, ZT_TEXTURE);
}
}*/
}
retModel->meshes[0].numTriangles = header->numTris;
@@ -425,15 +375,11 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
md2frame_t *framePtr = (md2frame_t*)ptr;
retModel->meshes[0].tinyframes[i].vertices = (short*)Z_Malloc(sizeof(short) * 3 * header->numXYZ, ztag, NULL);
retModel->meshes[0].tinyframes[i].normals = (char*)Z_Malloc(sizeof(char) * 3 * header->numXYZ, ztag, NULL);
// if (retModel->materials[0].lightmap)
// retModel->meshes[0].tinyframes[i].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*header->numVerts, ztag);
retModel->meshes[0].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * header->numTris, ztag, NULL);
vertptr = retModel->meshes[0].tinyframes[i].vertices;
normptr = retModel->meshes[0].tinyframes[i].normals;
// tanptr = retModel->meshes[0].tinyframes[i].tangents;
retModel->meshes[0].tinyframes[i].material = &retModel->materials[0];
framePtr++; // Advance to vertex list
@@ -509,9 +455,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
md2frame_t *framePtr = (md2frame_t*)ptr;
retModel->meshes[0].frames[i].normals = (float*)Z_Malloc(sizeof(float) * 3 * header->numTris * 3, ztag, NULL);
retModel->meshes[0].frames[i].vertices = (float*)Z_Malloc(sizeof(float) * 3 * header->numTris * 3, ztag, NULL);
// if (retModel->materials[0].lightmap)
// retModel->meshes[0].frames[i].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag);
//float *vertptr, *normptr;
normptr = (float*)retModel->meshes[0].frames[i].normals;
vertptr = (float*)retModel->meshes[0].frames[i].vertices;
trisPtr = tris;
+1 -79
View File
@@ -243,48 +243,6 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat)
mdShader[j].name[len-1] = 'z';
mdShader[j].name[len-2] = 'u';
mdShader[j].name[len-3] = 'b';
// Load material
/* retModel->materials[matCount].texture = Texture::ReadTexture(mdShader[j].name, ZT_TEXTURE);
if (!systemSucks)
{
// Check for a normal map...??
char openfilename[1024];
char normalMapName[1024];
strcpy(normalMapName, mdShader[j].name);
len = strlen(normalMapName);
char *ptr = &normalMapName[len];
ptr--; // z
ptr--; // u
ptr--; // b
ptr--; // .
*ptr++ = '_';
*ptr++ = 'n';
*ptr++ = '.';
*ptr++ = 'b';
*ptr++ = 'u';
*ptr++ = 'z';
*ptr++ = '\0';
sprintf(openfilename, "%s/%s", "textures", normalMapName);
// Convert backslashes to forward slashes
for (int k = 0; k < 1024; k++)
{
if (openfilename[k] == '\0')
break;
if (openfilename[k] == '\\')
openfilename[k] = '/';
}
Resource::resource_t *res = Resource::Open(openfilename);
if (res)
{
Resource::Close(res);
retModel->materials[matCount].lightmap = Texture::ReadTexture(normalMapName, ZT_TEXTURE);
}
}*/
}
retModel->meshes[i].numFrames = mdS->numFrames;
@@ -305,19 +263,15 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat)
{
short *vertptr;
char *normptr;
// char *tanptr;
int k;
md3Vertex *mdV = (md3Vertex*)((char*)mdS + mdS->offsetXYZNormal + (mdS->numVerts*j*sizeof(md3Vertex)));
retModel->meshes[i].tinyframes[j].vertices = (short*)Z_Malloc(sizeof(short)*3*mdS->numVerts, ztag, NULL);
retModel->meshes[i].tinyframes[j].normals = (char*)Z_Malloc(sizeof(char)*3*mdS->numVerts, ztag, NULL);
// if (retModel->materials[0].lightmap)
// retModel->meshes[i].tinyframes[j].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*mdS->numVerts, ztag);
retModel->meshes[i].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * mdS->numTriangles, ztag, NULL);
vertptr = retModel->meshes[i].tinyframes[j].vertices;
normptr = retModel->meshes[i].tinyframes[j].normals;
// tanptr = retModel->meshes[i].tinyframes[j].tangents;
retModel->meshes[i].tinyframes[j].material = &retModel->materials[i];
for (k = 0; k < mdS->numVerts; k++)
@@ -384,8 +338,7 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat)
md3Vertex *mdV = (md3Vertex*)((char*)mdS + mdS->offsetXYZNormal + (mdS->numVerts*j*sizeof(md3Vertex)));
retModel->meshes[i].frames[j].vertices = (float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag, NULL);
retModel->meshes[i].frames[j].normals = (float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag, NULL);
// if (retModel->materials[i].lightmap)
// retModel->meshes[i].frames[j].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag);
vertptr = retModel->meshes[i].frames[j].vertices;
normptr = retModel->meshes[i].frames[j].normals;
retModel->meshes[i].frames[j].material = &retModel->materials[i];
@@ -471,37 +424,6 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat)
}
}
}
/*
// Tags?
retModel->numTags = mdh->numTags;
retModel->maxNumFrames = mdh->numFrames;
retModel->tags = (tag_t*)Z_Calloc(sizeof(tag_t) * retModel->numTags * mdh->numFrames, ztag);
md3Tag *mdTag = (md3Tag*)&buffer[mdh->offsetTags];
tag_t *curTag = retModel->tags;
for (i = 0; i < mdh->numFrames; i++)
{
int j;
for (j = 0; j < retModel->numTags; j++, mdTag++)
{
strcpys(curTag->name, mdTag->name, sizeof(curTag->name) / sizeof(char));
curTag->transform.m[0][0] = mdTag->axis[0];
curTag->transform.m[0][1] = mdTag->axis[1];
curTag->transform.m[0][2] = mdTag->axis[2];
curTag->transform.m[1][0] = mdTag->axis[3];
curTag->transform.m[1][1] = mdTag->axis[4];
curTag->transform.m[1][2] = mdTag->axis[5];
curTag->transform.m[2][0] = mdTag->axis[6];
curTag->transform.m[2][1] = mdTag->axis[7];
curTag->transform.m[2][2] = mdTag->axis[8];
curTag->transform.m[3][0] = mdTag->origin[0] * WUNITS;
curTag->transform.m[3][1] = mdTag->origin[1] * WUNITS;
curTag->transform.m[3][2] = mdTag->origin[2] * WUNITS;
curTag->transform.m[3][3] = 1.0f;
Matrix::Rotate(&curTag->transform, 90.0f, &Vector::Xaxis);
curTag++;
}
}*/
free(buffer);
-549
View File
@@ -1,549 +0,0 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//-----------------------------------------------------------------------------
/// \file
/// \brief Windows specific part of the OpenGL API for Doom Legacy
///
/// TODO:
/// - check if windowed mode works
/// - support different pixel formats
#if defined (_WIN32)
//#define WIN32_LEAN_AND_MEAN
#define RPC_NO_WINDOWS_H
#include <windows.h>
#include <time.h>
#include "r_opengl.h"
// **************************************************************************
// GLOBALS
// **************************************************************************
#ifdef DEBUG_TO_FILE
static unsigned long nb_frames = 0;
static clock_t my_clock;
FILE *gllogstream;
#endif
static HDC hDC = NULL; // the window's device context
static HGLRC hGLRC = NULL; // the OpenGL rendering context
static HWND hWnd = NULL;
static BOOL WasFullScreen = FALSE;
static void UnSetRes(void);
#ifdef USE_WGL_SWAP
PFNWGLEXTSWAPCONTROLPROC wglSwapIntervalEXT = NULL;
#endif
PFNglClear pglClear;
PFNglGetIntegerv pglGetIntegerv;
PFNglGetString pglGetString;
#define MAX_VIDEO_MODES 32
static vmode_t video_modes[MAX_VIDEO_MODES];
INT32 oglflags = 0;
// **************************************************************************
// FUNCTIONS
// **************************************************************************
// -----------------+
// APIENTRY DllMain : DLL Entry Point,
// : open/close debug log
// Returns :
// -----------------+
BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved) // reserved
{
// Perform actions based on the reason for calling.
UNREFERENCED_PARAMETER(lpvReserved);
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
#ifdef DEBUG_TO_FILE
gllogstream = fopen("ogllog.txt", "wt");
if (gllogstream == NULL)
return FALSE;
#endif
DisableThreadLibraryCalls(hinstDLL);
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
#ifdef DEBUG_TO_FILE
if (gllogstream)
{
fclose(gllogstream);
gllogstream = NULL;
}
#endif
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
#ifdef STATIC_OPENGL
#define pwglGetProcAddress wglGetProcAddress;
#define pwglCreateContext wglCreateContext;
#define pwglDeleteContext wglDeleteContext;
#define pwglMakeCurrent wglMakeCurrent;
#else
static HMODULE OGL32;
typedef void *(WINAPI *PFNwglGetProcAddress) (const char *);
static PFNwglGetProcAddress pwglGetProcAddress;
typedef HGLRC (WINAPI *PFNwglCreateContext) (HDC hdc);
static PFNwglCreateContext pwglCreateContext;
typedef BOOL (WINAPI *PFNwglDeleteContext) (HGLRC hglrc);
static PFNwglDeleteContext pwglDeleteContext;
typedef BOOL (WINAPI *PFNwglMakeCurrent) (HDC hdc, HGLRC hglrc);
static PFNwglMakeCurrent pwglMakeCurrent;
#endif
#ifndef STATIC_OPENGL
void *GetGLFunc(const char *proc)
{
void *func = NULL;
if (pwglGetProcAddress)
func = pwglGetProcAddress(proc);
if (!func)
func = GetProcAddress(OGL32, proc);
return func;
}
#endif
boolean LoadGL(void)
{
#ifndef STATIC_OPENGL
OGL32 = LoadLibrary("OPENGL32.DLL");
if (!OGL32)
return 0;
pwglGetProcAddress = GetGLFunc("wglGetProcAddress");
pwglCreateContext = GetGLFunc("wglCreateContext");
pwglDeleteContext = GetGLFunc("wglDeleteContext");
pwglMakeCurrent = GetGLFunc("wglMakeCurrent");
#endif
return SetupGLfunc();
}
// -----------------+
// SetupPixelFormat : Set the device context's pixel format
// Note : Because we currently use only the desktop's BPP format, all the
// : video modes in Doom Legacy OpenGL are of the same BPP, thus the
// : PixelFormat is set only once.
// : Setting the pixel format more than once on the same window
// : doesn't work. (ultimately for different pixel formats, we
// : should close the window, and re-create it)
// -----------------+
int SetupPixelFormat(INT32 WantColorBits, INT32 WantStencilBits, INT32 WantDepthBits)
{
static DWORD iLastPFD = 0;
INT32 nPixelFormat;
PIXELFORMATDESCRIPTOR pfd =
{
sizeof (PIXELFORMATDESCRIPTOR), // size
1, // version
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA, // color type
32 /*WantColorBits*/, // cColorBits : prefered color depth
0, 0, // cRedBits, cRedShift
0, 0, // cGreenBits, cGreenShift
0, 0, // cBlueBits, cBlueShift
0, 0, // cAlphaBits, cAlphaShift
0, // cAccumBits
0, 0, 0, 0, // cAccum Red/Green/Blue/Alpha Bits
0, // cDepthBits (0,16,24,32)
0, // cStencilBits
0, // cAuxBuffers
PFD_MAIN_PLANE, // iLayerType
0, // reserved, must be zero
0, 0, 0, // dwLayerMask, dwVisibleMask, dwDamageMask
};
DWORD iPFD = (WantColorBits<<16) | (WantStencilBits<<8) | WantDepthBits;
pfd.cDepthBits = (BYTE)WantDepthBits;
pfd.cStencilBits = (BYTE)WantStencilBits;
if (iLastPFD)
{
DBG_Printf("WARNING : SetPixelFormat() called twise not supported by all drivers !\n");
}
// set the pixel format only if different than the current
if (iPFD == iLastPFD)
return 2;
else
iLastPFD = iPFD;
DBG_Printf("SetupPixelFormat() - %d ColorBits - %d StencilBits - %d DepthBits\n",
WantColorBits, WantStencilBits, WantDepthBits);
nPixelFormat = ChoosePixelFormat(hDC, &pfd);
if (nPixelFormat == 0)
DBG_Printf("ChoosePixelFormat() FAILED\n");
if (SetPixelFormat(hDC, nPixelFormat, &pfd) == 0)
{
DBG_Printf("SetPixelFormat() FAILED\n");
return 0;
}
return 1;
}
// -----------------+
// SetRes : Set a display mode
// Notes : pcurrentmode is actually not used
// -----------------+
static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode)
{
LPCSTR renderer;
BOOL WantFullScreen = !(lvid->u.windowed); //(lvid->u.windowed ? 0 : CDS_FULLSCREEN);
UNREFERENCED_PARAMETER(pcurrentmode);
DBG_Printf ("SetMode(): %dx%d %d bits (%s)\n",
lvid->width, lvid->height, lvid->bpp*8,
WantFullScreen ? "fullscreen" : "windowed");
hWnd = lvid->WndParent;
// BP : why flush texture ?
// if important flush also the first one (white texture) and restore it !
Flush(); // Flush textures.
// TODO: if not fullscreen, skip display stuff and just resize viewport stuff ...
// Exit previous mode
//if (hGLRC) //Hurdler: TODO: check if this is valid
// UnSetRes();
if (WasFullScreen)
ChangeDisplaySettings(NULL, CDS_FULLSCREEN); //switch in and out of fullscreen
// Change display settings.
if (WantFullScreen)
{
DEVMODE dm;
ZeroMemory(&dm, sizeof (dm));
dm.dmSize = sizeof (dm);
dm.dmPelsWidth = lvid->width;
dm.dmPelsHeight = lvid->height;
dm.dmBitsPerPel = lvid->bpp*8;
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
if (ChangeDisplaySettings(&dm, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
return -2;
if (ChangeDisplaySettings(&dm, CDS_FULLSCREEN) !=DISP_CHANGE_SUCCESSFUL)
return -3;
SetWindowLong(hWnd, GWL_STYLE, WS_POPUP|WS_VISIBLE);
// faB : book says to put these, surely for windowed mode
//WS_CLIPCHILDREN|WS_CLIPSIBLINGS);
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, lvid->width, lvid->height, SWP_NOACTIVATE|SWP_NOZORDER);
}
else
{
RECT bounds;
INT32 x, y;
INT32 w = lvid->width, h = lvid->height;
GetWindowRect(hWnd, &bounds);
bounds.right = bounds.left+w;
bounds.bottom = bounds.top+h;
AdjustWindowRectEx(&bounds, GetWindowLong(hWnd, GWL_STYLE), (GetMenu(hWnd) != NULL), 0);
w = bounds.right-bounds.left;
h = bounds.bottom-bounds.top;
x = (GetSystemMetrics(SM_CXSCREEN)-w)/2;
y = (GetSystemMetrics(SM_CYSCREEN)-h)/2;
SetWindowPos(hWnd, NULL, x, y, w, h, SWP_NOACTIVATE|SWP_NOZORDER);
}
if (!hDC)
hDC = GetDC(hWnd);
if (!hDC)
{
DBG_Printf("GetDC() FAILED\n");
return 0;
}
{
INT32 res;
// Set res.
res = SetupPixelFormat(lvid->bpp*8, 0, 16);
if (res == 0)
return 0;
else if (res == 1)
{
// Exit previous mode
if (hGLRC)
UnSetRes();
hGLRC = pwglCreateContext(hDC);
if (!hGLRC)
{
DBG_Printf("pwglCreateContext() FAILED\n");
return 0;
}
if (!pwglMakeCurrent(hDC, hGLRC))
{
DBG_Printf("wglMakeCurrent() FAILED\n");
return 0;
}
}
}
gl_extensions = pglGetString(GL_EXTENSIONS);
// Get info and extensions.
//BP: why don't we make it earlier ?
//Hurdler: we cannot do that before intialising gl context
renderer = (LPCSTR)pglGetString(GL_RENDERER);
DBG_Printf("Vendor : %s\n", pglGetString(GL_VENDOR));
DBG_Printf("Renderer : %s\n", renderer);
DBG_Printf("Version : %s\n", pglGetString(GL_VERSION));
DBG_Printf("Extensions : %s\n", gl_extensions);
// BP: disable advenced feature that don't work on somes hardware
// Hurdler: Now works on G400 with bios 1.6 and certified drivers 6.04
if (strstr(renderer, "810")) oglflags |= GLF_NOZBUFREAD;
DBG_Printf("oglflags : 0x%X\n", oglflags);
#ifdef USE_WGL_SWAP
if (isExtAvailable("WGL_EXT_swap_control",gl_extensions))
wglSwapIntervalEXT = GetGLFunc("wglSwapIntervalEXT");
else
wglSwapIntervalEXT = NULL;
#endif
if (isExtAvailable("GL_EXT_texture_filter_anisotropic",gl_extensions))
pglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnisotropy);
else
maximumAnisotropy = 0;
SetupGLFunc13();
screen_depth = (GLbyte)(lvid->bpp*8);
if (screen_depth > 16)
textureformatGL = GL_RGBA;
else
textureformatGL = GL_RGB5_A1;
GL_SetModelView(lvid->width, lvid->height);
GL_SetStates();
// we need to clear the depth buffer. Very important!!!
pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
lvid->buffer = NULL; // unless we use the software view
lvid->direct = NULL; // direct access to video memory, old DOS crap
WasFullScreen = WantFullScreen;
return 1; // on renvoie une valeur pour dire que cela s'est bien pass�
}
// -----------------+
// UnSetRes : Restore the original display mode
// -----------------+
static void UnSetRes(void)
{
DBG_Printf("UnSetRes()\n");
pwglMakeCurrent(hDC, NULL);
pwglDeleteContext(hGLRC);
hGLRC = NULL;
if (WasFullScreen)
ChangeDisplaySettings(NULL, CDS_FULLSCREEN);
}
// -----------------+
// GetModeList : Return the list of available display modes.
// Returns : pvidmodes - points to list of detected OpenGL video modes
// : numvidmodes - number of detected OpenGL video modes
// -----------------+
EXPORT void HWRAPI(GetModeList) (vmode_t** pvidmodes, INT32 *numvidmodes)
{
INT32 i;
#if 1
INT32 iMode;
/*
faB test code
Commented out because there might be a problem with combo (Voodoo2 + other card),
we need to get the 3D card's display modes only.
*/
(*pvidmodes) = &video_modes[0];
// Get list of device modes
for (i = 0,iMode = 0; iMode < MAX_VIDEO_MODES; i++)
{
DEVMODE Tmp;
ZeroMemory(&Tmp, sizeof (Tmp));
Tmp.dmSize = sizeof (Tmp);
if (!EnumDisplaySettings(NULL, i, &Tmp))
break;
// add video mode
if (Tmp.dmBitsPerPel == 16 &&
(iMode == 0 || !
(Tmp.dmPelsWidth == video_modes[iMode-1].width &&
Tmp.dmPelsHeight == video_modes[iMode-1].height)
)
)
{
video_modes[iMode].pnext = &video_modes[iMode+1];
video_modes[iMode].windowed = 0; // fullscreen is the default
video_modes[iMode].misc = 0;
video_modes[iMode].name = malloc(12 * sizeof (CHAR));
sprintf(video_modes[iMode].name, "%dx%d", (INT32)Tmp.dmPelsWidth, (INT32)Tmp.dmPelsHeight);
DBG_Printf ("Mode: %s\n", video_modes[iMode].name);
video_modes[iMode].width = Tmp.dmPelsWidth;
video_modes[iMode].height = Tmp.dmPelsHeight;
video_modes[iMode].bytesperpixel = Tmp.dmBitsPerPel/8;
video_modes[iMode].rowbytes = Tmp.dmPelsWidth * video_modes[iMode].bytesperpixel;
video_modes[iMode].pextradata = NULL;
video_modes[iMode].setmode = SetRes;
iMode++;
}
}
(*numvidmodes) = iMode;
#else
// classic video modes (fullscreen/windowed)
// Added some. Tails
INT32 res[][2] = {
{ 320, 200},
{ 320, 240},
{ 400, 300},
{ 512, 384},
{ 640, 400},
{ 640, 480},
{ 800, 600},
{ 960, 600},
{1024, 768},
{1152, 864},
{1280, 800},
{1280, 960},
{1280,1024},
{1600,1000},
{1680,1050},
{1920,1200},
};
HDC bpphdc;
INT32 iBitsPerPel;
DBG_Printf ("HWRAPI GetModeList()\n");
bpphdc = GetDC(NULL); // on obtient le bpp actuel
iBitsPerPel = GetDeviceCaps(bpphdc, BITSPIXEL);
ReleaseDC(NULL, bpphdc);
(*pvidmodes) = &video_modes[0];
(*numvidmodes) = sizeof (res) / sizeof (res[0]);
for (i = 0; i < (*numvidmodes); i++)
{
video_modes[i].pnext = &video_modes[i+1];
video_modes[i].windowed = 0; // fullscreen is the default
video_modes[i].misc = 0;
video_modes[i].name = malloc(12 * sizeof (CHAR));
sprintf(video_modes[i].name, "%dx%d", res[i][0], res[i][1]);
DBG_Printf ("Mode: %s\n", video_modes[i].name);
video_modes[i].width = res[i][0];
video_modes[i].height = res[i][1];
video_modes[i].bytesperpixel = iBitsPerPel/8;
video_modes[i].rowbytes = res[i][0] * video_modes[i].bytesperpixel;
video_modes[i].pextradata = NULL;
video_modes[i].setmode = SetRes;
}
#endif
video_modes[(*numvidmodes)-1].pnext = NULL;
}
// -----------------+
// Shutdown : Shutdown OpenGL, restore the display mode
// -----------------+
EXPORT void HWRAPI(Shutdown) (void)
{
#ifdef DEBUG_TO_FILE
long nb_centiemes;
DBG_Printf ("HWRAPI Shutdown()\n");
nb_centiemes = ((clock()-my_clock)*100)/CLOCKS_PER_SEC;
DBG_Printf("Nb frames: %li; Nb sec: %2.2f -> %2.1f fps\n",
nb_frames, nb_centiemes/100.0f, (100*nb_frames)/(double)nb_centiemes);
#endif
Flush();
// Exit previous mode
if (hGLRC)
UnSetRes();
if (hDC)
{
ReleaseDC(hWnd, hDC);
hDC = NULL;
}
FreeLibrary(OGL32);
DBG_Printf ("HWRAPI Shutdown(DONE)\n");
}
// -----------------+
// FinishUpdate : Swap front and back buffers
// -----------------+
void GL_FinishUpdate (INT32 waitvbl)
{
#ifdef USE_WGL_SWAP
static INT32 oldwaitvbl = 0;
#else
UNREFERENCED_PARAMETER(waitvbl);
#endif
// DBG_Printf ("FinishUpdate()\n");
#ifdef DEBUG_TO_FILE
if ((++nb_frames)==2) // on ne commence pas � la premi�re frame
my_clock = clock();
#endif
#ifdef USE_WGL_SWAP
if (oldwaitvbl != waitvbl && wglSwapIntervalEXT)
wglSwapIntervalEXT(waitvbl);
oldwaitvbl = waitvbl;
#endif
SwapBuffers(hDC);
}
#endif
+33 -19
View File
@@ -776,15 +776,15 @@ static int GLFramebuffer_CheckExt(void)
// gl versions from 2.1 may still support framebuffer objects
// maybe, just maybe, we support the standart extensions
if (GL_isExtAvailable("GL_ARB_framebuffer_no_attachments", gl_extensions)
&& GL_isExtAvailable("GL_ARB_framebuffer_object", gl_extensions)
&& GL_isExtAvailable("GL_ARB_framebuffer_sRGB", gl_extensions))
if (GL_isExtAvailable("GL_ARB_framebuffer_no_attachments", gl_extensions) &&
GL_isExtAvailable("GL_ARB_framebuffer_object", gl_extensions) &&
GL_isExtAvailable("GL_ARB_framebuffer_sRGB", gl_extensions))
return FBO_ARB;
// nope, try the older 2.1 extensions
if (GL_isExtAvailable("GL_EXT_framebuffer_no_attachments", gl_extensions)
&& GL_isExtAvailable("GL_EXT_framebuffer_object", gl_extensions)
&& GL_isExtAvailable("GL_EXT_framebuffer_sRGB", gl_extensions))
if (GL_isExtAvailable("GL_EXT_framebuffer_no_attachments", gl_extensions) &&
GL_isExtAvailable("GL_EXT_framebuffer_object", gl_extensions) &&
GL_isExtAvailable("GL_EXT_framebuffer_sRGB", gl_extensions))
{
// perhaps we may even support a stencil attachment
if (GL_isExtAvailable("GL_EXT_packed_depth_stencil", gl_extensions))
@@ -885,7 +885,7 @@ void SetupGLFunc4(void)
{ \
GL_MSG_Warning("failed to get OpenGL FBO function: %s\n", #func); \
GL_DBG_Printf("\nFBO: No framebuffer object support\n"); \
supportFBO = false; \
supportFBO = FBO_NONE; \
return; \
} \
@@ -1465,6 +1465,19 @@ void GL_ReadScreenTexture(int tex, UINT8 *restrict dest, INT32 scale)
if (tex != HWD_SCREENTEXTURE_GENERIC2)
GL_DrawScreenTexture(tex, NULL, 0);
#ifdef USE_FBO_OGL
// FIXME: this is incredibly stupid
// but the final screen texture will NOT be drawn in the downsample fbo
if (tex == HWD_SCREENTEXTURE_GENERIC2 &&
UseScreenFBO() && HWR_ShouldUsePaletteRendering())
{
GL_SetShader(HWR_GetShaderFromTarget(SHADER_PALETTE_POSTPROCESS));
GL_EnableShader();
GL_DrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2, NULL, 0);
GL_UnSetShader();
}
#endif
image = malloc(screen_width*screen_height*3);
pglPixelStorei(GL_PACK_ALIGNMENT, 1);
pglReadPixels(0, 0, screen_width, screen_height, GL_RGB, GL_UNSIGNED_BYTE, image);
@@ -1918,6 +1931,7 @@ static void GenerateMipmaps(INT32 w, INT32 h, RGBA_t *tex, INT32 maxLOD, UINT32
{
if (samplePoint[p].s.alpha == 0)
continue;
sumR += samplePoint[p].s.red;
sumG += samplePoint[p].s.green;
sumB += samplePoint[p].s.blue;
@@ -2490,7 +2504,7 @@ void GL_RenderSkyDome(gl_sky_t *sky)
GL_Shader_SetUniforms(NULL, NULL, NULL, NULL);
// Build the sky dome! Yes!
if (sky->rebuild)
if (sky->rebuild || !sky->vbo)
{
// delete VBO when already exists
if (sky->vbo)
@@ -3208,8 +3222,8 @@ void GL_SetTransform(FTransform *stransform)
{
float dy = stransform->viewaiming * 2;
if (stransform->fliptype == TRANSFORM_FLIP
|| stransform->fliptype == TRANSFORM_MIRRORFLIP)
if (stransform->fliptype == TRANSFORM_FLIP ||
stransform->fliptype == TRANSFORM_MIRRORFLIP)
dy *= -1.0f;
pglTranslatef(0.0f, -dy/BASEVIDHEIGHT, 0.0f);
@@ -3234,7 +3248,7 @@ void GL_SetTransform(FTransform *stransform)
#ifdef USE_FBO_OGL
static void GL_Framebuffer_DeleteAttachments(void)
{
if (!supportFBO || !framebufferobject.init)
if (supportFBO == FBO_NONE || !framebufferobject.init)
return;
// Unbind the framebuffer
@@ -3254,7 +3268,7 @@ static void GL_Framebuffer_DeleteAttachments(void)
static void GL_Framebuffer_Generate(void)
{
if (!supportFBO || framebufferobject.init || !UseScreenFBO())
if (supportFBO == FBO_NONE || framebufferobject.init || !UseScreenFBO())
return;
// Generate the framebuffer
@@ -3269,15 +3283,15 @@ static void GL_Framebuffer_Generate(void)
{
pglGenTextures(1, &framebufferobject.tex);
pglBindTexture(GL_TEXTURE_2D, framebufferobject.tex);
pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screen_width, screen_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screen_width, screen_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
pglBindTexture(GL_TEXTURE_2D, 0);
// Attach the framebuffer texture to the framebuffer
pglFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, framebufferobject.tex, 0);
pglBindTexture(GL_TEXTURE_2D, 0);
}
// Generate the renderbuffer
@@ -3319,7 +3333,7 @@ static void GL_Framebuffer_Generate(void)
// if this fails, dont retry it a gazillion times
// this wouldnt recover
supportFBO = false;
supportFBO = FBO_NONE;
pglBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
return;
}
@@ -3332,7 +3346,7 @@ static void GL_Framebuffer_Generate(void)
void GL_Framebuffer_Unbind(void)
{
if (!supportFBO || !framebufferobject.init)
if (supportFBO == FBO_NONE || !framebufferobject.init)
return;
pglBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
@@ -3341,13 +3355,13 @@ void GL_Framebuffer_Unbind(void)
void GL_Framebuffer_Enable(void)
{
if (!supportFBO || !UseScreenFBO())
if (supportFBO == FBO_NONE || !UseScreenFBO())
return;
GL_Framebuffer_Generate();
// failed
if (!supportFBO || !framebufferobject.init)
if (supportFBO == FBO_NONE || !framebufferobject.init)
return;
pglBindFramebuffer(GL_FRAMEBUFFER_EXT, framebufferobject.fboobj);
@@ -3356,7 +3370,7 @@ void GL_Framebuffer_Enable(void)
void GL_Framebuffer_Disable(void)
{
if (!supportFBO || !framebufferobject.init)
if (supportFBO == FBO_NONE || !framebufferobject.init)
return;
pglBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
-79
View File
@@ -1,79 +0,0 @@
[Project]
FileName=r_opengl.dev
Name=r_opengl
Ver=1
IsCpp=1
Type=3
Compiler=-D_M_IX86=500_@@_-Wall_@@_-D_WINDOWS_@@_-DUSE_WGL_SWAP_@@_-Os_@@_-fomit-frame-pointer_@@_
CppCompiler=
Includes=
Linker=--def ../r_mingw.def_@@_-lgdi32_@@_
Libs=
UnitCount=3
Folders=
ObjFiles=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Icon=
ExeOutput=C:\srb2demo2
ObjectOutput=..\..\..\objs\Mingw\r_opengl
OverrideOutput=1
OverrideOutputName=r_opengl.dll
HostApplication=
CommandLine=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=00000000000000000111d0
UseCustomMakefile=0
CustomMakefile=
[Unit1]
FileName=ogl_win.c
Folder=
Compile=1
CompileCpp=0
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit2]
FileName=r_opengl.c
Folder=
Compile=1
CompileCpp=0
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit3]
FileName=r_opengl.h
Folder=
Compile=1
CompileCpp=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=0.1
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=r_opengl.exe
ProductName=r_opengl
ProductVersion=0.1
AutoIncBuildNr=0
-105
View File
@@ -1,105 +0,0 @@
# Microsoft Developer Studio Project File - Name="r_opengl" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=r_opengl - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "r_opengl.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "r_opengl.mak" CFG="r_opengl - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "r_opengl - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "r_opengl - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "r_opengl - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "r_opengl___Win32_Release"
# PROP BASE Intermediate_Dir "r_opengl___Win32_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\..\..\bin\VC\Release\r_opengl"
# PROP Intermediate_Dir "..\..\..\objs\VC\Release\r_opengl"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "R_OPENGL_EXPORTS" /YX /FD /c
# ADD CPP /nologo /G5 /W3 /GX /Zi /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /D "USE_WGL_SWAP" /FR /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x80c /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 user32.lib gdi32.lib /nologo /dll /pdb:"..\..\..\bin\VC\Release\r_opengl.pdb" /machine:I386 /out:"C:\srb2demo2\r_opengl.dll"
# SUBTRACT LINK32 /pdb:none /debug
!ELSEIF "$(CFG)" == "r_opengl - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "..\..\..\objs\Debug"
# PROP BASE Intermediate_Dir "..\..\..\objs\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\..\..\bin\VC\Debug\r_opengl"
# PROP Intermediate_Dir "..\..\..\objs\VC\Debug\r_opengl"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "R_OPENGL_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /G6 /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /D "USE_WGL_SWAP" /FR /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x80c /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 user32.lib gdi32.lib /nologo /dll /pdb:"..\..\..\bin\VC\Debug\r_opengl.pdb" /debug /machine:I386 /out:"C:\srb2demo2\r_opengld.dll" /pdbtype:sept
# SUBTRACT LINK32 /pdb:none
!ENDIF
# Begin Target
# Name "r_opengl - Win32 Release"
# Name "r_opengl - Win32 Debug"
# Begin Source File
SOURCE=.\ogl_win.c
# End Source File
# Begin Source File
SOURCE=.\r_opengl.c
# End Source File
# Begin Source File
SOURCE=.\r_opengl.h
# End Source File
# End Target
# End Project
+10 -8
View File
@@ -135,8 +135,7 @@ HMS_on_read (char *s, size_t _1, size_t n, void *userdata)
return n;
}
static struct HMS_buffer *
HMS_connect (const char *format, ...)
static struct HMS_buffer *HMS_connect(const char *format, ...)
{
va_list ap;
CURL *curl;
@@ -174,7 +173,7 @@ HMS_connect (const char *format, ...)
if (cv_masterserver_token.string && cv_masterserver_token.string[0])
{
quack_token = curl_easy_escape(curl, cv_masterserver_token.string, 0);
token_length = ( sizeof "&token="-1 )+ strlen(quack_token);
token_length = ( sizeof "&token="-1 ) + strlen(quack_token);
}
else
{
@@ -186,27 +185,30 @@ HMS_connect (const char *format, ...)
I_lock_mutex(&hms_api_mutex);
#endif
seek = strlen(hms_api) + 1;/* + '/' */
seek = strlen(hms_api) + 1; /* + '/' */
va_start (ap, format);
url = malloc(seek + vsnprintf(NULL, 0, format, ap) + sizeof HMS_QUERY_VERSION - 1 + token_length + 1);
size_t url_size = (seek + vsnprintf(NULL, 0, format, ap) +
sizeof HMS_QUERY_VERSION - 1 +
token_length + 1);
url = malloc(url_size);
va_end (ap);
sprintf(url, "%s/", hms_api);
snprintf(url, seek + 1, "%s/", hms_api);
#ifdef HAVE_THREADS
I_unlock_mutex(hms_api_mutex);
#endif
va_start (ap, format);
seek += vsprintf(&url[seek], format, ap);
seek += vsnprintf(&url[seek], url_size - seek, format, ap);
va_end (ap);
strcpy(&url[seek], HMS_QUERY_VERSION);
seek += sizeof HMS_QUERY_VERSION - 1;
if (quack_token)
sprintf(&url[seek], "&token=%s", quack_token);
snprintf(&url[seek], url_size - seek, "&token=%s", quack_token);
Printf_url(url);
+21 -22
View File
@@ -154,14 +154,14 @@ void HU_LoadGraphics(void)
for (i = 0; i < HU_FONTSIZE; i++, j++)
{
// cache the heads-up font for entire game execution
sprintf(buffer, "STCFN%.3d", j);
snprintf(buffer, sizeof(buffer), "STCFN%.3d", j);
if (W_CheckNumForName(buffer) == LUMPERROR)
hu_font[i] = NULL;
else
hu_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
// tiny version of the heads-up font
sprintf(buffer, "TNYFN%.3d", j);
snprintf(buffer, sizeof(buffer), "TNYFN%.3d", j);
if (W_CheckNumForName(buffer) == LUMPERROR)
tny_font[i] = NULL;
else
@@ -188,7 +188,7 @@ void HU_LoadGraphics(void)
for (i = 0; i < KART_FONTSIZE; i++, j++)
{
// cache the heads-up font for entire game execution
sprintf(buffer, "MKFNT%.3d", j);
snprintf(buffer, sizeof(buffer), "MKFNT%.3d", j);
if (W_CheckNumForName(buffer) == LUMPERROR)
kart_font[i] = NULL;
else
@@ -199,7 +199,7 @@ void HU_LoadGraphics(void)
j = LT_FONTSTART;
for (i = 0; i < LT_FONTSIZE; i++)
{
sprintf(buffer, "LTFNT%.3d", j);
snprintf(buffer, sizeof(buffer), "LTFNT%.3d", j);
j++;
if (W_CheckNumForName(buffer) == LUMPERROR)
@@ -212,7 +212,7 @@ void HU_LoadGraphics(void)
j = CRED_FONTSTART;
for (i = 0; i < CRED_FONTSIZE; i++)
{
sprintf(buffer, "CRFNT%.3d", j);
snprintf(buffer, sizeof(buffer), "CRFNT%.3d", j);
j++;
if (W_CheckNumForName(buffer) == LUMPERROR)
@@ -224,11 +224,11 @@ void HU_LoadGraphics(void)
// cache numbers too!
for (i = 0; i < 10; i++)
{
sprintf(buffer, "STTNUM%d", i);
snprintf(buffer, sizeof(buffer), "STTNUM%d", i);
tallnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "PINGN%d", i);
snprintf(buffer, sizeof(buffer), "PINGN%d", i);
pingnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "OPPRNK0%d", i);
snprintf(buffer, sizeof(buffer), "OPPRNK0%d", i);
ranknum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
@@ -240,7 +240,7 @@ void HU_LoadGraphics(void)
// cache ping gfx:
for (i = 0; i < 5; i++)
{
sprintf(buffer, "PINGGFX%d", i+1);
snprintf(buffer, sizeof(buffer), "PINGGFX%d", i+1);
pinggfx[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
@@ -472,9 +472,7 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
strlcat(msg, COM_Argv(ix + usedargs), msgspace);
}
const size_t msglength = strlen(msg);
if (msglength > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
{
// what we're gonna do now is check if the node exists
// with that logic, characters 4 and 5 are our numbers:
@@ -528,7 +526,7 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
strlcpy(msg, newmsg, HU_MAXMSGLEN + 1);
}
SendNetXCmd(XD_SAY, buf, msglength + 1 + msg-buf);
SendNetXCmd(XD_SAY, buf, strlen(msg) + 1 + msg-buf);
}
/** Send a message to everyone.
@@ -779,12 +777,11 @@ static void Got_Saycmd(const UINT8 **p, INT32 playernum)
return;
}
const size_t msglength = strlen(msg);
//check for invalid characters (0x80 or above)
{
size_t i;
const size_t j = msglength;
const size_t j = strlen(msg);
for (i = 0; i < j; i++)
{
if (msg[i] & 0x80)
@@ -831,7 +828,7 @@ static void Got_Saycmd(const UINT8 **p, INT32 playernum)
}
// Handle "/me" actions, but only in messages to everyone.
if (target == 0 && msglength > 4 && strnicmp(msg, "/me ", 4) == 0)
if (target == 0 && strlen(msg) > 4 && strnicmp(msg, "/me ", 4) == 0)
{
msg += 4;
action = true;
@@ -2259,12 +2256,13 @@ static void HU_DrawSongCreditsBox(void)
y = -BOXCREDITHEIGHT*dup + (FixedMul(BOXCREDITHEIGHT*FRACUNIT, FixedDiv(t*FRACUNIT, TICRATE*FRACUNIT/2))*dup - interpoffset)/FRACUNIT;
}
bgt = (NUMTRANSMAPS/2) + (cursongcredit.trans/2);
bgt = (NUMTRANSMAPS/2) + (cursongcredit.trans/2) - 2; // arbitrary value, looks a bit better
if (bgt < NUMTRANSMAPS)
{
V_DrawFill(x, y, strwidth*dup, BOXCREDITHEIGHT*dup, 28|flags|(bgt<<V_ALPHASHIFT));
V_DrawFill(x+dup, y+dup, (strwidth-2)*dup, (BOXCREDITHEIGHT-2)*dup, 30|flags|(bgt<<V_ALPHASHIFT));
const UINT8 accent = colortranslations[K_GetHudColor()][7];
V_DrawFill(x, y, strwidth*dup, BOXCREDITHEIGHT*dup, accent|flags|(bgt<<V_ALPHASHIFT));
V_DrawFill(x+dup, y+dup, (strwidth-2)*dup, (BOXCREDITHEIGHT-2)*dup, accent|flags|(bgt<<V_ALPHASHIFT));
}
if (cursongcredit.trans < NUMTRANSMAPS)
@@ -2829,8 +2827,9 @@ static void HU_DrawRankings(void)
scorelines++;
#if MAXPLAYERS > 16
if (scorelines > 16)
break; //dont draw past bottom of screen, show the best only
// 32 Player TODO: port over and cleanup scoreboard from sat-32p/blankart
if (scorelines >= 16)
break; // dont draw past bottom of screen, show the best only
#endif
}
+22
View File
@@ -14,6 +14,9 @@
#ifndef __I_SYSTEM__
#define __I_SYSTEM__
// page for Saturn issue reports
#define SATURNISSUEPAGE "https://github.com/Indev450/SRB2Kart-Saturn/issues"
#ifdef __cplusplus
extern "C" {
#endif
@@ -209,6 +212,10 @@ static inline void I_HandleInterrupt(void)
I_Quit();
}
/** \brief Open A URL
*/
int I_OpenURL(const char *url);
/** \brief The I_GetDiskFreeSpace function
\param freespace a INT64 pointer to hold the free space amount
@@ -230,6 +237,21 @@ char *I_GetUserName(void);
*/
INT32 I_mkdir(const char *dirname, INT32 unixright);
/** \brief Change current working directory
\param path directory path
\return 0 on success, -1 on error
*/
INT32 I_ChDir(const char *path);
/** \brief Get current working directory
\param buf buffer to store path
\param size size of buffer
\return buf on success, NULL on error
*/
char *I_GetCwd(char *buf, size_t size);
/** \brief Find main WAD
\return path to main WAD
*/
+5 -5
View File
@@ -213,7 +213,7 @@ static char *get_WSAErrorStr(int e)
NULL);
if (!buf[0]) // provide a fallback error message if no message is available for some reason
sprintf(buf, "Unknown error");
snprintf(buf, sizeof(buf), "Unknown error");
return buf;
}
@@ -364,12 +364,12 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
if (addr == NULL)
{
sprintf(s, "No address");
snprintf(s, sizeof(s), "No address");
}
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));
snprintf(s, sizeof(s), "Unknown family type, error #%u: %s", e, strerror(e));
}
#ifdef HAVE_IPV6
else if(sk->any.sa_family == AF_INET6)
@@ -416,7 +416,7 @@ static const char *SOCK_GetBanMask(size_t ban)
if (ban >= numbans)
return NULL;
if (sprintf(s,"%d",banned[ban].mask) > 0)
if (snprintf(s, sizeof(s), "%d",banned[ban].mask) > 0)
return s;
return NULL;
@@ -622,7 +622,6 @@ static boolean hole_punch(ssize_t c)
{
return false;
}
}
#endif //ifdef HOLEPUNCH
@@ -1694,6 +1693,7 @@ boolean I_InitTcpNetwork(void)
hardware_MAXPACKETLENGTH = MAXPACKETLENGTH;
}
}
if (M_CheckProtoParam("ip"))
{
COM_ImmedExecute(va("exec \"%s"PATHSEP"kartexec.cfg\" -noerror\n", srb2home));
+3 -3
View File
@@ -452,10 +452,10 @@ void A_SpawnFreshCopy(void *actor);
extern boolean actionsoverridden[NUMACTIONS];
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
#ifdef COMPAT_VANILLA
#define NUMMOBJFREESLOTS 1024
#else
#ifdef PHOBOS_BUILD
#define NUMMOBJFREESLOTS 4096 // should be sufficient
#else
#define NUMMOBJFREESLOTS 1024
#endif
#define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS
#define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8)
+63 -27
View File
@@ -388,7 +388,7 @@ static void K_LoadSaturnHUDGraphics(void)
skp_speedpatchesdial[3] = (patch_t *)W_CachePatchName("SP_DFRAC", PU_HUDGFX);
skp_speedpatchesdial[4] = (patch_t *)W_CachePatchName("SP_DPERC", PU_HUDGFX);
sprintf(buffer, "K_DSPNMx");
snprintf(buffer, sizeof(buffer), "K_DSPNMx");
for (i = 0; i < 10; i++)
{
buffer[7] = '0'+(i%10);
@@ -507,7 +507,7 @@ static void K_LoadSaturnHUDGraphics(void)
skp_speedpatchesdialclr[3] = (patch_t *)W_CachePatchName("SC_DFRAC", PU_HUDGFX);
skp_speedpatchesdialclr[4] = (patch_t *)W_CachePatchName("SC_DPERC", PU_HUDGFX);
sprintf(buffer, "K_DSPNCx");
snprintf(buffer, sizeof(buffer), "K_DSPNCx");
for (i = 0; i < 10; i++)
{
buffer[7] = '0'+(i%10);
@@ -677,7 +677,7 @@ void K_LoadKartHUDGraphics(void)
kp_racefinish[5] = (patch_t *)W_CachePatchName("K_2PFINB", PU_HUDGFX);
// Position numbers
sprintf(buffer, "K_POSNxx");
snprintf(buffer, sizeof(buffer), "K_POSNxx");
for (i = 0; i < NUMPOSNUMS; i++)
{
buffer[6] = '0'+i;
@@ -688,14 +688,17 @@ void K_LoadKartHUDGraphics(void)
}
}
sprintf(buffer, "K_POSNWx");
snprintf(buffer, sizeof(buffer), "K_POSNWx");
for (i = 0; i < NUMWINFRAMES; i++)
{
buffer[7] = '0'+i;
kp_winnernum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
sprintf(buffer, "OPPRNKxx");
// 32 player note: there are only 16 of those!
// so slots after this will just be missing patches!
// but keeping like this incase of missed adjustments which might cause crashes otherwise
snprintf(buffer, sizeof(buffer), "OPPRNKxx");
for (i = 0; i <= MAXPLAYERS; i++)
{
buffer[6] = '0'+(i/10);
@@ -703,7 +706,7 @@ void K_LoadKartHUDGraphics(void)
kp_facenum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
sprintf(buffer, "K_CHILIx");
snprintf(buffer, sizeof(buffer), "K_CHILIx");
for (i = 0; i < 8; i++)
{
buffer[7] = '0'+(i+1);
@@ -772,21 +775,21 @@ void K_LoadKartHUDGraphics(void)
kp_kitchensink[1] = (patch_t *)W_CachePatchName("K_ISSINK", PU_HUDGFX);
kp_sadface[1] = (patch_t *)W_CachePatchName("K_ISSAD", PU_HUDGFX);
sprintf(buffer, "K_ITINVx");
snprintf(buffer, sizeof(buffer), "K_ITINVx");
for (i = 0; i < 7; i++)
{
buffer[7] = '1'+i;
kp_invincibility[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
sprintf(buffer, "K_ITORBx");
snprintf(buffer, sizeof(buffer), "K_ITORBx");
for (i = 0; i < 4; i++)
{
buffer[7] = '1'+i;
kp_orbinaut[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
sprintf(buffer, "K_ISINVx");
snprintf(buffer, sizeof(buffer), "K_ISINVx");
for (i = 0; i < 6; i++)
{
buffer[7] = '1'+i;
@@ -794,7 +797,7 @@ void K_LoadKartHUDGraphics(void)
}
// CHECK indicators
sprintf(buffer, "K_CHECKx");
snprintf(buffer, sizeof(buffer), "K_CHECKx");
for (i = 0; i < 6; i++)
{
buffer[7] = '1'+i;
@@ -802,7 +805,7 @@ void K_LoadKartHUDGraphics(void)
}
// Eggman warning numbers
sprintf(buffer, "K_EGGNx");
snprintf(buffer, sizeof(buffer), "K_EGGNx");
for (i = 0; i < 4; i++)
{
buffer[6] = '0'+i;
@@ -815,7 +818,7 @@ void K_LoadKartHUDGraphics(void)
kp_fpview[2] = (patch_t *)W_CachePatchName("VIEWC0E0", PU_HUDGFX);
// Input UI Wheel
sprintf(buffer, "K_WHEELx");
snprintf(buffer, sizeof(buffer), "K_WHEELx");
for (i = 0; i < 5; i++)
{
buffer[7] = '0'+i;
@@ -823,7 +826,7 @@ void K_LoadKartHUDGraphics(void)
}
// HERE COMES A NEW CHALLENGER
sprintf(buffer, "K_CHALxx");
snprintf(buffer, sizeof(buffer), "K_CHALxx");
for (i = 0; i < 25; i++)
{
buffer[6] = '0'+((i+1)/10);
@@ -832,14 +835,14 @@ void K_LoadKartHUDGraphics(void)
}
// Lap start animation
sprintf(buffer, "K_LAP0x");
snprintf(buffer, sizeof(buffer), "K_LAP0x");
for (i = 0; i < 7; i++)
{
buffer[6] = '0'+(i+1);
kp_lapanim_lap[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
sprintf(buffer, "K_LAPFxx");
snprintf(buffer, sizeof(buffer), "K_LAPFxx");
for (i = 0; i < 11; i++)
{
buffer[6] = '0'+((i+1)/10);
@@ -847,7 +850,7 @@ void K_LoadKartHUDGraphics(void)
kp_lapanim_final[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
sprintf(buffer, "K_LAPNxx");
snprintf(buffer, sizeof(buffer), "K_LAPNxx");
for (i = 0; i < 10; i++)
{
buffer[6] = '0'+i;
@@ -858,14 +861,14 @@ void K_LoadKartHUDGraphics(void)
}
}
sprintf(buffer, "K_LAPE0x");
snprintf(buffer, sizeof(buffer), "K_LAPE0x");
for (i = 0; i < 2; i++)
{
buffer[7] = '0'+(i+1);
kp_lapanim_emblem[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
sprintf(buffer, "K_LAPH0x");
snprintf(buffer, sizeof(buffer), "K_LAPH0x");
for (i = 0; i < 3; i++)
{
buffer[7] = '0'+(i+1);
@@ -1974,7 +1977,7 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
goto bademblem;
}
snprintf(targettext, 9, "%i'%02i\"%02i",
snprintf(targettext, sizeof(targettext), "%i'%02i\"%02i",
G_TicsToMinutes(timetoreach, false),
G_TicsToSeconds(timetoreach),
G_TicsToCentiseconds(timetoreach));
@@ -2294,6 +2297,11 @@ static boolean K_drawKartPositionFaces(void)
if (pos < 0 || pos > MAXPLAYERS)
pos = 0;
#if MAXPLAYERS > 16
if (pos > 16)
V_DrawPingNum(FACE_X+2, Y+10, V_HUDTRANS|V_SNAPTOLEFT, pos, NULL);
else
#endif
// Draws the little number over the face
V_DrawScaledPatch(FACE_X-5, Y+10, V_HUDTRANS|V_SNAPTOLEFT, kp_facenum[pos]);
}
@@ -2385,6 +2393,12 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
INT32 pos = player->kartstuff[k_position];
if (pos < 0 || pos > MAXPLAYERS)
pos = 0;
#if MAXPLAYERS > 16
if (pos > 16)
V_DrawPingNum(x+2, y+10, 0, pos, NULL);
else
#endif
// Draws the little number over the face
V_DrawScaledPatch(x-5, y+6, 0, kp_facenum[pos]);
}
@@ -3581,6 +3595,10 @@ static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags)
#endif
skin = K_GetMobjSkin(mo);
if (!skin)
return;
minimaphead = (skinlocal ? localfacemmapprefix : facemmapprefix)[K_GetMobjSkinNum(skin, skinlocal)];
if (minimaphead == NULL)
@@ -3784,6 +3802,9 @@ static void K_drawKartMinimap(void)
mobj_t *mobj = players[localplayers[i]].mo;
if (!mobj)
continue;
// dont draw for no contestants
boolean playertimedout = (mobj->health <= 0 && players[localplayers[i]].pflags & PF_TIMEOVER);
@@ -3808,10 +3829,8 @@ static void K_drawKartMinimap(void)
}
else
{
const INT32 skinnum = K_GetMobjLocalSkinNum(mobj->skin, mobj->localskin, mobj->skinlocal);
// special case if startcolor is not the default (160 / Green)
if (skinnum && skins[skinnum].starttranscolor != skins[0].starttranscolor)
if (K_GetMobjSkin(mobj)->starttranscolor != skins[0].starttranscolor)
{
colormap = R_GetTranslationColormap(TC_DEFAULT, mobj->color, GTC_CACHE);
}
@@ -3941,10 +3960,23 @@ static void K_drawBattleFullscreen(void)
INT32 x = BASEVIDWIDTH/2;
INT32 y = (-64*FRACUNIT) + cardanim; // card animation goes from 0 to 164, 164 is the middle of the screen
INT32 splitflags = V_SNAPTOTOP; // I don't feel like properly supporting non-green resolutions, so you can have a misuse of SNAPTO instead
INT32 splitflags = splitscreen ? V_SNAPTOTOP : 0; // I don't feel like properly supporting non-green resolutions, so you can have a misuse of SNAPTO instead
fixed_t scale = FRACUNIT;
boolean drawcomebacktimer = true; // lazy hack because it's cleaner in the long run.
// Small hack, if we're not in splitscreen we will not use V_SNAPTOTOP, instead we will just slightly offset
// y position so "attack or protect" doesn't slightly show before popping in
// We will also reduce this when is closer to finishing so when its at the bottom, the "hack offset" is 0
if (!splitscreen)
{
fixed_t offset = ((vid.height - vid.dup*BASEVIDHEIGHT)/vid.dup) * FRACUNIT/2;
// cardanim goes from 0 to 164, so when it is 164 offset will be multiplied by (1 - 164/164) = 0 :3
offset = FixedMul(offset, FRACUNIT - FixedDiv(cardanim, 164*FRACUNIT));
y -= offset;
}
if (!LUA_HudEnabled(hud_battlecomebacktimer))
drawcomebacktimer = false;
@@ -4032,12 +4064,12 @@ static void K_drawBattleFullscreen(void)
if (K_UseColorHud()) // Colourized hud
{
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE);
V_DrawFixedPatch(x<<FRACBITS, ty<<FRACBITS, scale, 0, kp_timeoutstickerclr, colormap);
V_DrawFixedPatch(x<<FRACBITS, ty<<FRACBITS, scale, splitflags, kp_timeoutstickerclr, colormap);
}
else
V_DrawFixedPatch(x<<FRACBITS, ty<<FRACBITS, scale, 0, kp_timeoutsticker, NULL);
V_DrawFixedPatch(x<<FRACBITS, ty<<FRACBITS, scale, splitflags, kp_timeoutsticker, NULL);
V_DrawKartString(x-txoff, ty, 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE));
V_DrawKartString(x-txoff, ty, splitflags, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE));
}
}
@@ -4576,7 +4608,11 @@ static void K_drawCheckpointDebugger(void)
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]));
// really gnarly hack
const INT32 prevcheck = (stprevnextchecks[0] != INT32_MAX) ? stprevnextchecks[0]: stplyr->kartstuff[k_prevcheck];
const INT32 nextcheck = (stprevnextchecks[1] != INT32_MAX) ? stprevnextchecks[1]: stplyr->kartstuff[k_nextcheck];
V_DrawString(8, 192, 0, va("Waypoint dist: Prev %d, Next %d", prevcheck, nextcheck));
}
// determines if gametype info (laps/bumpers) should be hidden
+310 -202
View File
@@ -34,7 +34,7 @@
// extra colourisation stuff
static CV_PossibleValue_t colorspeedlines_cons_t[] = {{0, "Off"}, {1, "Normal"}, {2, "+Driftcharge"}, {3, "Drift only"}, {0, NULL}};
static CV_PossibleValue_t colorspeedlines_cons_t[] = {{0, "Off"}, {1, "On"}, {0, NULL}};
consvar_t cv_coloredspeedlines = {"colorizedspeedlines", "Off", CV_SAVE, colorspeedlines_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_coloredsneakertrail = {"sneakertrailcolor", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -71,12 +71,11 @@ consvar_t cv_stairjank = {"stairjank", "Off", CV_SAVE|CV_CALL, CV_OnOff, PDistor
consvar_t cv_stairjanksfx = {"stairjanksfx", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
//hardcode saltyhop mhhm
static void saltyhop_onchange(void);
consvar_t cv_saltyhop = {"hardcodehop", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, saltyhop_onchange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_saltyhop = {"hardcodehop", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_saltyhopsfx = {"hardcodehopsfx", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_saltysquish = {"hardcodehopsquish", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t saltyheight_t[] = {{FRACUNIT/4, "MIN"}, {2*FRACUNIT, "MAX"}, {0, NULL}};
consvar_t cv_saltyheight = {"hardcodehopheight", "1", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, saltyheight_t, saltyhop_onchange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_saltyheight = {"hardcodehopheight", "1", CV_FLOAT|CV_SAVE, saltyheight_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_saltyroll = {"hardcodehoproll", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_squishdance = {"squishdance", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -84,23 +83,6 @@ consvar_t cv_squishdance = {"squishdance", "On", CV_SAVE, CV_OnOff, NULL, 0, NUL
static CV_PossibleValue_t squishdancespeed_cons_t[] = {{20, "MIN"}, {280, "MAX"}, {0, NULL}};
consvar_t cv_squishdancespeed = {"squishdance_speed", "140", CV_SAVE, squishdancespeed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static void saltyhop_onchange(void)
{
// reset everything when toggling saltyhop
if (gamestate != GS_LEVEL)
return;
for (INT32 i = 0; i < MAXPLAYERS; i++)
{
player_t *player = &players[i];
if (!player || P_MobjWasRemoved(player->mo))
continue;
memset(&player->mo->salty, 0, sizeof(player->mo->salty));
}
}
// SOME IMPORTANT VARIABLES DEFINED IN DOOMDEF.H:
// gamespeed is cc (0 for easy, 1 for normal, 2 for hard)
// franticitems is Frantic Mode items, bool
@@ -1033,6 +1015,12 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush)
}
}
#if MAXPLAYERS > 16
// courtesy of fickle from 1.1 battleroyale
// battleroyale: limit how much items will scale to try to prevent shit-tier items in shit-huge netames
pingame = min(pingame, 12);
#endif
if (first != -1 && second != -1) // calculate 2nd's distance from 1st, for SPB
{
secondist = P_AproxDistance(P_AproxDistance(players[first].mo->x - players[second].mo->x,
@@ -1821,25 +1809,56 @@ void K_RespawnChecker(player_t *player)
mobj_t *mo;
angle_t newangle;
fixed_t newx, newy, newz;
#ifdef PHOBOS_BUILD
const fixed_t fscale = player->mo->scale;
#else
static const fixed_t fscale = FRACUNIT; // does NOT use scale, since this effect doesn't scale properly
#endif
newangle = FixedAngle(((360/8)*i)*FRACUNIT);
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31<<FRACBITS); // does NOT use scale, since this effect doesn't scale properly
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31<<FRACBITS);
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31 * fscale);
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31 * fscale);
if (player->mo->eflags & MFE_VERTICALFLIP)
newz = player->mo->z + player->mo->height;
else
newz = player->mo->z;
mo = P_SpawnMobj(newx, newy, newz, MT_DEZLASER);
if (mo)
if (!P_MobjWasRemovedCompat(mo))
{
if (player->mo->eflags & MFE_VERTICALFLIP)
mo->eflags |= MFE_VERTICALFLIP;
P_SetTarget(&mo->target, player->mo);
mo->angle = newangle+ANGLE_90;
mo->momz = (8<<FRACBITS) * P_MobjFlip(player->mo);
P_SetScale(mo, (mo->destscale = FRACUNIT));
mo->momz = (8 * fscale) * P_MobjFlip(player->mo);
P_SetScale(mo, (mo->destscale = fscale));
}
#ifndef PHOBOS_BUILD
// vanilla compat really is annoying.......
// but this stuff is messed up on mobjscaled maps
// and we gotta respawn it locally to avoid desynchs...
if (mapobjectscale != FRACUNIT)
{
// hide the normal lazers!
mo->flags2 |= MF2_DONTDRAW;
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31 * player->mo->scale);
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31 * player->mo->scale);
// now spawn our local lazers
mo = P_SpawnMobj(newx, newy, newz, MT_DEZLASER);
if (!P_MobjWasRemovedCompat(mo))
{
if (player->mo->eflags & MFE_VERTICALFLIP)
mo->eflags |= MFE_VERTICALFLIP;
P_SetTarget(&mo->target, player->mo);
mo->angle = newangle+ANGLE_90;
mo->momz = (8 * player->mo->scale) * P_MobjFlip(player->mo);
P_SetScale(mo, (mo->destscale = player->mo->scale));
mo->islocal = true; // Keep this local!
}
}
#endif
}
}
}
@@ -2188,7 +2207,7 @@ static void K_GetKartBoostPower(player_t *player)
// Technically, all mobjs that think can cause desynchs if they are spawned conditionally, so best we can do
// is to hide them if you are in saltyhop jump
if (dust && player->mo->salty.jump)
if (dust && player->salty.jump)
dust->flags2 |= MF2_DONTDRAW;
if (leveltime % 6 == 0)
@@ -3217,10 +3236,8 @@ static void K_SpawnDriftSparks(player_t *player)
for (i = 0; i < 2; i++)
{
fixed_t driftExtraScale = 0;
angle_t thrustangle = (travelangle + ((i&1) ? -1 : 1)*ANGLE_135);
fixed_t smolscale = FixedMul(32*FRACUNIT, player->mo->scale);
const angle_t thrustangle = (travelangle + ((i&1) ? -1 : 1)*ANGLE_135);
const fixed_t smolscale = FixedMul(32*FRACUNIT, player->mo->scale);
newx = player->mo->x + P_ReturnThrustX(player->mo, thrustangle, smolscale);
newy = player->mo->y + P_ReturnThrustY(player->mo, thrustangle, smolscale);
@@ -3232,9 +3249,9 @@ static void K_SpawnDriftSparks(player_t *player)
spark->angle = travelangle-(ANGLE_45/5)*player->kartstuff[k_drift];
// scale increase while driftspark level gained timer is running
driftExtraScale = FixedDiv(player->driftsparkGrowTimer, DRIFTSPARKGROWTICS);
const fixed_t driftExtraScale = FixedDiv(player->driftsparkGrowTimer, DRIFTSPARKGROWTICS);
spark->destscale = FixedMul(player->mo->scale, FRACUNIT + FixedMul(driftExtraScale, cv_driftsparkpulse.value));
P_SetScale(spark, spark->destscale); // why not use what we calculated above?
P_SetScale(spark, spark->destscale);
spark->momx = player->mo->momx/2;
spark->momy = player->mo->momy/2;
@@ -3326,10 +3343,10 @@ static void K_StretchPlayerGravity(player_t *player)
mobj_t *pmo = player->mo;
fixed_t tempxscale = pmo->realxscale;
fixed_t tempyscale = pmo->realyscale;
const fixed_t tempxscale = pmo->realxscale;
const fixed_t tempyscale = pmo->realyscale;
stretchScaleFactor = FixedDiv(FRACUNIT*60, cv_gravstretch.value);
stretchScaleFactor = FixedDiv(mapobjectscale*60, cv_gravstretch.value);
stretchScaleFactor = min(stretchScaleFactor, MAXSTRETCHDIV);
if (pmo->slamsoundtimer)
@@ -3337,26 +3354,26 @@ static void K_StretchPlayerGravity(player_t *player)
if (!P_IsObjectOnGround(pmo))
{
fixed_t pzmom = abs(pmo->momz);
const fixed_t pzmom = abs(pmo->momz);
const fixed_t stretchDiv = FixedDiv(pzmom, stretchScaleFactor);
if (abs(pzmom/FRACUNIT) != 0)
if (abs(pzmom/mapobjectscale) != 0)
{
if (((tempxscale-(stretchDiv))) > (tempxscale/5))
if ((tempxscale - stretchDiv) > (tempxscale / 5))
{
pmo->spritexscale = (tempxscale - stretchDiv);
pmo->stretchslam = pzmom;
}
else
pmo->spritexscale = (tempxscale/5);
pmo->spritexscale = (tempxscale / 5);
pmo->spriteyscale = (tempyscale + ((stretchDiv*2)/3));
pmo->spriteyscale = (tempyscale + ((stretchDiv * 2) / 3));
}
}
else if (pmo->stretchslam > 0)
{
// Funni slam sound when landing
if (cv_slamsound.value && (pmo->eflags & MFE_JUSTHITFLOOR) && !pmo->slamsoundtimer && (pmo->stretchslam > 4*FRACUNIT))
if (cv_slamsound.value && (pmo->eflags & MFE_JUSTHITFLOOR) && !pmo->slamsoundtimer && (pmo->stretchslam > 4*mapobjectscale))
{
S_StartSound(pmo, sfx_s3k4c);
pmo->slamsoundtimer = TICRATE;
@@ -3364,9 +3381,9 @@ static void K_StretchPlayerGravity(player_t *player)
const fixed_t slamDiv = FixedDiv(pmo->stretchslam, stretchScaleFactor);
pmo->spritexscale = (tempxscale + (((slamDiv*2)/3)*2));
pmo->spritexscale = (tempxscale + (((slamDiv * 2) / 3 ) * 2));
pmo->spriteyscale = (tempyscale - slamDiv);
pmo->stretchslam -= (4*FRACUNIT);
pmo->stretchslam -= (4*mapobjectscale);
}
else
pmo->stretchslam = 0;
@@ -3381,16 +3398,16 @@ static void K_SaltySquish(player_t *player)
mobj_t *pmo = player->mo;
fixed_t tempxscale = pmo->realxscale;
fixed_t tempyscale = pmo->realyscale;
const fixed_t tempxscale = pmo->realxscale;
const fixed_t tempyscale = pmo->realyscale;
if (pmo->stretchslam > 0)
{
const fixed_t slamDiv = FixedDiv(pmo->stretchslam, FRACUNIT*60); // stretchScaleFactor = FixedDiv(FRACUNIT*60, FRACUNIT)
const fixed_t slamDiv = FixedDiv(pmo->stretchslam, mapobjectscale*60); // stretchScaleFactor = FixedDiv(mapobjectscale*60, FRACUNIT)
pmo->spritexscale = (tempxscale + (((slamDiv*2)/3)*2));
pmo->spritexscale = (tempxscale + (((slamDiv * 2) / 3) * 2));
pmo->spriteyscale = (tempyscale - slamDiv);
pmo->stretchslam -= (4*FRACUNIT);
pmo->stretchslam -= (4*mapobjectscale);
}
else
pmo->stretchslam = 0;
@@ -3398,88 +3415,92 @@ static void K_SaltySquish(player_t *player)
static void K_QuiteSaltyHop(player_t *player)
{
if (!cv_saltyhop.value)
return;
I_Assert(player != NULL);
I_Assert(!P_MobjWasRemoved(player->mo));
// what the fuck is this haya
mobj_t *pmo = player->mo;
salty_t *psalt = &pmo->salty;
salty_t *psalty = &player->salty;
if (!cv_saltyhop.value)
{
// reset before we leave
psalty->jump = psalty->ready = psalty->tapping = false;
psalty->momz = psalty->zoffset = 0;
return;
}
const boolean onground = P_IsObjectOnGround(pmo);
// ready?
if (!player->kartstuff[k_jmp])
{
psalt->ready = true;
psalt->tapping = false;
psalty->ready = true;
psalty->tapping = false;
}
else if (psalt->ready)
else if (psalty->ready)
{
psalt->ready = false;
psalt->tapping = true;
psalty->ready = false;
psalty->tapping = true;
}
else
{
psalt->tapping = false;
psalty->tapping = false;
}
// GO!
if (!psalt->init)
{
psalt->jump = false;
psalt->zoffset = 0;
psalt->momz = 0;
psalt->init = true;
}
else if (psalt->jump)
if (psalty->jump)
{
if (pmo->eflags & MFE_JUSTHITFLOOR)
{
psalt->zoffset = 0;
psalty->zoffset = 0;
}
else if (onground)
{
psalt->zoffset += psalt->momz;
psalt->momz -= (FRACUNIT*3/2);
psalty->zoffset += psalty->momz;
psalty->momz -= (FRACUNIT*3/2);
}
else
{
psalt->zoffset *= (49/50)*FRACUNIT;
psalt->momz = 0;
//psalty->zoffset *= (49/50)*FRACUNIT; // this just rounds down to 0 lol
psalty->zoffset = 0;
psalty->momz = 0;
}
if (psalt->zoffset <= 0)
if (psalty->zoffset <= 0)
{
if (cv_saltyhopsfx.value && !(pmo->eflags & MFE_JUSTHITFLOOR) && onground)
S_StartSound(pmo, sfx_s268);
psalt->jump = false;
psalt->zoffset = 0;
psalt->momz = 0;
psalty->jump = false;
psalty->zoffset = 0;
psalty->momz = 0;
// shlamma damma
if (cv_saltysquish.value)
pmo->stretchslam += 8*FRACUNIT;
pmo->stretchslam += 8*mapobjectscale;
}
else if (cv_saltysquish.value && psalt->zoffset >= 0)
else if (psalty->zoffset > 0)
{
// goofy ahh hack
pmo->spriteyscale += (FRACUNIT/8);
pmo->spritexscale -= (FRACUNIT/8);
if (cv_saltysquish.value)
{
// goofy ahh hack
pmo->spriteyscale += (FRACUNIT/8);
pmo->spritexscale -= (FRACUNIT/8);
}
}
pmo->spriteyoffset += FixedMul(psalt->zoffset, cv_saltyheight.value);
pmo->spriteyoffset += FixedMul(psalty->zoffset, cv_saltyheight.value);
if (cv_saltyhopsfx.value)
{
if (S_SoundPlaying(pmo, sfx_screec))
S_StopSoundByID(pmo, sfx_screec);
if (S_SoundPlaying(pmo, sfx_drift))
S_StopSoundByID(pmo, sfx_drift);
}
// Stop any and all drift sounds when hopping.
if (S_SoundPlaying(pmo, sfx_screec))
S_StopSoundByID(pmo, sfx_screec);
if (S_SoundPlaying(pmo, sfx_drift))
S_StopSoundByID(pmo, sfx_drift);
}
else if (psalt->tapping && onground && !player->kartstuff[k_spinouttimer] && !player->kartstuff[k_squishedtimer])
else if (psalty->tapping && onground && !player->kartstuff[k_spinouttimer] && !player->kartstuff[k_squishedtimer])
{
psalt->jump = true;
psalt->zoffset = 0;
psalt->momz = 6*FRACUNIT;
psalty->jump = true;
psalty->zoffset = 0;
psalty->momz = 6*FRACUNIT;
if (cv_saltyhopsfx.value)
S_StartSound(pmo, sfx_s25a);
}
@@ -3506,7 +3527,7 @@ boolean K_ShouldSlopeRoll(mobj_t *mobj)
return false;
// seeing a character rotate mid-hop looks really janky
if (!cv_saltyroll.value && mobj->player && mobj->player->mo->salty.jump)
if (!cv_saltyroll.value && mobj->player && mobj->player->salty.jump)
return false;
return K_CheckSlopeRollDist(mobj);
@@ -3522,26 +3543,6 @@ static INT32 K_StairJankFlip(INT32 value)
return K_AltFlip(value, 2);
}
// reset banan and eggbox rollangle when they´re on the ground
// if not cv_bananthrowroll option "+Onground"
static void K_ResetBananaRollangle(mobj_t* mo)
{
if (cv_bananthrowroll.value != 1)
return;
if (!mo->rollangle)
return;
if (mo->type != MT_BANANA && mo->type != MT_EGGMANITEM)
return;
// only reset if on ground
if (!P_IsObjectOnGround(mo))
return;
mo->rollangle = 0;
}
#define SLOPEROLL_DIV 3
void K_RollMobjBySlopes(mobj_t* mo, pslope_t *slope)
{
@@ -3555,9 +3556,6 @@ void K_RollMobjBySlopes(mobj_t* mo, pslope_t *slope)
I_Assert(mo->subsector != NULL);
I_Assert(mo->subsector->sector != NULL);
// kinda stupid but idk where else to put this
K_ResetBananaRollangle(mo);
if (!K_ShouldSlopeRoll(mo))
{
mo->pitch_sprite = mo->roll_sprite = 0;
@@ -3741,7 +3739,7 @@ mobj_t *K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent)
dust = P_SpawnMobj(rand_x, rand_y, mo->z, MT_WIPEOUTTRAIL);
P_SetTarget(&dust->target, mo);
dust->angle = R_PointToAngle2(0,0,mo->momx,mo->momy);
dust->angle = R_PointToAngle2(0, 0, mo->momx, mo->momy);
dust->destscale = mo->scale;
P_SetScale(dust, mo->scale);
K_FlipFromObject(dust, mo);
@@ -3767,6 +3765,11 @@ mobj_t *K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent)
void K_DriftDustHandling(mobj_t *spawner)
{
angle_t anglediff;
#ifdef PHOBOS_BUILD
const fixed_t fscale = spawner->scale;
#else
static const fixed_t fscale = FRACUNIT; // should be spawner->scale but the below calls P_Random!
#endif
if (leveltime % 2 != 0 || !P_IsObjectOnGround(spawner))
return;
@@ -3783,7 +3786,7 @@ void K_DriftDustHandling(mobj_t *spawner)
{
angle_t playerangle = spawner->angle;
if (spawner->player->speed < 5<<FRACBITS)
if (spawner->player->speed < (5 * fscale))
return;
if (spawner->player->cmd.forwardmove < 0)
@@ -3794,7 +3797,7 @@ void K_DriftDustHandling(mobj_t *spawner)
}
else
{
if (P_AproxDistance(spawner->momx, spawner->momy) < 5<<FRACBITS)
if (P_AproxDistance(spawner->momx, spawner->momy) < (5 * fscale))
return;
anglediff = abs((signed)(spawner->angle - R_PointToAngle2(0, 0, spawner->momx, spawner->momy)));
@@ -3807,13 +3810,29 @@ void K_DriftDustHandling(mobj_t *spawner)
if (anglediff > ANG10*4) // Trying to turn further than 40 degrees
{
mobj_t *dust = NULL;
fixed_t spawnx = P_RandomRange(-spawnrange, spawnrange)<<FRACBITS;
fixed_t spawny = P_RandomRange(-spawnrange, spawnrange)<<FRACBITS;
INT32 speedrange = 2;
mobj_t *dust = P_SpawnMobj(spawner->x + spawnx, spawner->y + spawny, spawner->z, MT_DRIFTDUST);
dust->momx = FixedMul(spawner->momx + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*(spawner->scale)/4);
dust->momy = FixedMul(spawner->momy + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*(spawner->scale)/4);
dust->momz = P_MobjFlip(spawner) * (P_RandomRange(1, 4) * (spawner->scale));
dust = P_SpawnMobj(spawner->x + spawnx, spawner->y + spawny, spawner->z, MT_DRIFTDUST);
const INT32 momxrand = P_RandomRange(-speedrange, speedrange);
const INT32 momyrand = P_RandomRange(-speedrange, speedrange);
const INT32 momzrand = P_RandomRange(1, 4);
if (P_MobjWasRemovedCompat(dust))
return;
#ifdef PHOBOS_BUILD
dust->momx = FixedMul(spawner->momx + (momxrand * spawner->scale), 3*FRACUNIT/4);
dust->momy = FixedMul(spawner->momy + (momyrand * spawner->scale), 3*FRACUNIT/4);
#else
dust->momx = FixedMul(spawner->momx + (momxrand<<FRACBITS), 3*(spawner->scale)/4);
dust->momy = FixedMul(spawner->momy + (momyrand<<FRACBITS), 3*(spawner->scale)/4);
#endif
dust->momz = P_MobjFlip(spawner) * (momzrand * (spawner->scale));
P_SetScale(dust, spawner->scale/2);
dust->destscale = spawner->scale * 3;
dust->scalespeed = spawner->scale/12;
@@ -3822,6 +3841,33 @@ void K_DriftDustHandling(mobj_t *spawner)
S_StartSound(spawner, sfx_screec);
K_MatchGenericExtraFlags(dust, spawner);
#ifndef PHOBOS_BUILD
// vanilla compat really is annoying.......
// but this stuff is messed up on mobjscaled maps
// and we gotta respawn it locally to avoid desynchs...
if (mapobjectscale != FRACUNIT)
{
// hide the normal dust!
dust->flags2 |= MF2_DONTDRAW;
// now spawn our dust locally
dust = P_SpawnMobj(spawner->x + spawnx, spawner->y + spawny, spawner->z, MT_DRIFTDUST);
if (P_MobjWasRemovedCompat(dust))
return;
dust->momx = FixedMul(spawner->momx + (momxrand * spawner->scale), 3*FRACUNIT/4);
dust->momy = FixedMul(spawner->momy + (momyrand * spawner->scale), 3*FRACUNIT/4);
dust->momz = P_MobjFlip(spawner) * (momzrand * (spawner->scale));
P_SetScale(dust, spawner->scale/2);
dust->destscale = spawner->scale * 3;
dust->scalespeed = spawner->scale/12;
dust->islocal = true; // Keep this local!
K_MatchGenericExtraFlags(dust, spawner);
}
#endif
}
}
@@ -4354,7 +4400,6 @@ static void K_DoShrink(player_t *user)
}
}
void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound)
{
if (mo->player && mo->player->spectator)
@@ -4417,8 +4462,7 @@ void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source)
mobj_t *cachenext;
killnext:
if (!banana)
if (P_MobjWasRemovedCompat(banana))
return;
cachenext = banana->hnext;
@@ -4457,10 +4501,21 @@ void K_UpdateHnextList(player_t *player, boolean clean)
nextwork = work->hnext;
if (!clean && (!work->movedir || work->movedir <= (UINT16)player->kartstuff[k_itemamount]))
{
continue;
}
P_RemoveMobj(work);
}
#ifdef PHOBOS_BUILD
if (P_MobjWasRemoved(player->mo->hnext))
{
// Like below, try to clean up the pointer if it's NULL.
// Maybe this was a cause of the shrink/eggbox fails?
P_SetTarget(&player->mo->hnext, NULL);
}
#endif
}
// For getting hit!
@@ -4525,7 +4580,9 @@ void K_DropHnextList(player_t *player)
}
dropwork = P_SpawnMobj(work->x, work->y, work->z, type);
P_SetTarget(&dropwork->target, player->mo);
dropwork->angle = work->angle;
dropwork->flags2 = work->flags2;
dropwork->flags |= MF_NOCLIPTHING;
@@ -4593,10 +4650,13 @@ void K_DropHnextList(player_t *player)
// we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic...
P_SetTarget(&player->mo->hnext, NULL);
player->kartstuff[k_bananadrag] = 0;
if (player->kartstuff[k_eggmanheld])
{
player->kartstuff[k_eggmanheld] = 0;
}
else if (player->kartstuff[k_itemheld]
&& (dropall || (--player->kartstuff[k_itemamount] <= 0)))
{
@@ -4725,11 +4785,7 @@ void K_RepairOrbitChain(mobj_t *orbit)
}
// Then recount to make sure item amount is correct
#ifndef COMPAT_VANILLA
if (!P_MobjWasRemoved(orbit->target) && orbit->target->player)
#else
if (orbit->target && orbit->target->player)
#endif
if (!P_MobjWasRemovedCompat(orbit->target) && orbit->target->player)
{
INT32 num = 0;
@@ -4746,11 +4802,7 @@ void K_RepairOrbitChain(mobj_t *orbit)
prev->movedir = num;
}
#ifndef COMPAT_VANILLA
if (!P_MobjWasRemoved(orbit->target))
#else
if (orbit->target)
#endif
if (!P_MobjWasRemovedCompat(orbit->target))
orbit->target->player->kartstuff[k_itemamount] = num;
}
}
@@ -4897,7 +4949,7 @@ static void K_CalculateBananaSlope(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z
// Move the hnext chain!
static void K_MoveHeldObjects(player_t *player)
{
if (!player->mo)
if (P_MobjWasRemovedCompat(player->mo))
return;
if (!player->mo->hnext)
@@ -4905,7 +4957,9 @@ static void K_MoveHeldObjects(player_t *player)
player->kartstuff[k_bananadrag] = 0;
if (player->kartstuff[k_eggmanheld])
{
player->kartstuff[k_eggmanheld] = 0;
}
else if (player->kartstuff[k_itemheld])
{
player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0;
@@ -4922,7 +4976,9 @@ static void K_MoveHeldObjects(player_t *player)
player->kartstuff[k_bananadrag] = 0;
if (player->kartstuff[k_eggmanheld])
{
player->kartstuff[k_eggmanheld] = 0;
}
else if (player->kartstuff[k_itemheld])
{
player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0;
@@ -4938,7 +4994,12 @@ static void K_MoveHeldObjects(player_t *player)
case MT_JAWZ_SHIELD:
{
mobj_t *cur = player->mo->hnext;
fixed_t speed = ((8 - min(4, player->kartstuff[k_itemamount])) * cur->info->speed) / 7;
fixed_t speed = 0;
if (cur == NULL)
return;
speed = ((8 - min(4, player->kartstuff[k_itemamount])) * cur->info->speed) / 7;
player->kartstuff[k_bananadrag] = 0; // Just to make sure
@@ -4985,8 +5046,13 @@ static void K_MoveHeldObjects(player_t *player)
cur->flags &= ~MF_NOCLIPTHING;
if (!P_TryMove(cur, player->mo->x + cur->momx, player->mo->y + cur->momy, true))
{
P_SlideMove(cur, true);
if (P_MobjWasRemovedCompat(cur))
continue;
}
if (P_IsObjectOnGround(player->mo))
{
if (P_MobjFlip(cur) > 0)
@@ -5493,59 +5559,15 @@ boolean K_PlayerEffectsShouldBlend(player_t *player)
return false;
}
static UINT8 K_GetSpeedLineColor(player_t *player, boolean colorSpeed)
FUNCINLINE static ATTRINLINE void K_SpawnNormalSpeedLines(player_t *player)
{
UINT8 speedcolor = SKINCOLOR_NONE;
const UINT8 playercolor = player->mo->color;
if (colorSpeed)
{
if (cv_coloredspeedlines.value != 3)
speedcolor = playercolor;
if (cv_coloredspeedlines.value >= 2 && player->kartstuff[k_driftboost])
{
if (player->kartstuff[k_driftboost] <= 20)
speedcolor = SKINCOLOR_SAPPHIRE;
else if (player->kartstuff[k_driftboost] <= 50)
speedcolor = SKINCOLOR_RASPBERRY;
else if (player->kartstuff[k_driftboost] <= 125)
speedcolor = K_RainbowColor();
if (cv_coloredspeedlines.value == 2)
speedcolor = (leveltime & 1) ? playercolor : speedcolor;
}
}
if (cv_coloredspeedlines.value != 3)
{
if (player->kartstuff[k_eggmanexplode])
{
// Make it red when you have the eggman speed boost
speedcolor = SKINCOLOR_RED;
}
else if (player->kartstuff[k_invincibilitytimer])
{
speedcolor = playercolor;
}
}
return speedcolor;
}
typedef INT32 (*randomFunc)(INT32 min, INT32 max);
FUNCINLINE static ATTRINLINE void K_SpawnNormalSpeedLines(player_t *player, boolean synched)
{
const randomFunc randomfunc = synched ? P_RandomRange : M_RandomRange;
fixed_t rand_x;
fixed_t rand_y;
fixed_t rand_z;
rand_z = player->mo->z + (player->mo->height/2) + (randomfunc(-20,20) * player->mo->scale);
rand_y = player->mo->y + (randomfunc(-36,36) * player->mo->scale);
rand_x = player->mo->x + (randomfunc(-36,36) * player->mo->scale);
rand_z = player->mo->z + (player->mo->height/2) + (P_RandomRange(-20, 20) * player->mo->scale);
rand_y = player->mo->y + (P_RandomRange(-36, 36) * player->mo->scale);
rand_x = player->mo->x + (P_RandomRange(-36, 36) * player->mo->scale);
mobj_t *fast = P_SpawnMobj(rand_x, rand_y, rand_z, MT_FASTLINE);
@@ -5553,7 +5575,7 @@ FUNCINLINE static ATTRINLINE void K_SpawnNormalSpeedLines(player_t *player, bool
fast->momx = 3*player->mo->momx/4;
fast->momy = 3*player->mo->momy/4;
fast->momz = 3*player->mo->momz/4;
fast->islocal = !synched;
//fast->islocal = false;
P_SetTarget(&fast->target, player->mo); // easier lua access
K_MatchGenericExtraFlags(fast, player->mo);
@@ -5564,8 +5586,11 @@ FUNCINLINE static ATTRINLINE void K_SpawnNormalSpeedLines(player_t *player, bool
if (cv_coloredspeedlines.value)
{
fast->color = K_GetSpeedLineColor(player, colorSpeed);
fast->colorized = true;
if (colorSpeed || player->kartstuff[k_invincibilitytimer]) // let invul color them even when players go rather slow
{
fast->color = player->mo->color;
fast->colorized = true;
}
}
if (colorSpeed && K_PlayerEffectsShouldBlend(player))
@@ -5594,11 +5619,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
// Speed lines
if ((player->kartstuff[k_sneakertimer] || player->kartstuff[k_driftboost] || player->kartstuff[k_startboost]) && player->speed > 0)
{
K_SpawnNormalSpeedLines(player, true);
}
else if ((cv_coloredspeedlines.value == 1 || cv_coloredspeedlines.value == 2) && player->kartstuff[k_eggmanexplode]) // gotta love the speedlines calling synched rng :chaosleep:
{
K_SpawnNormalSpeedLines(player, false);
K_SpawnNormalSpeedLines(player);
}
if (player->playerstate == PST_DEAD || player->kartstuff[k_respawn] > 1) // Ensure these are set correctly here
@@ -6220,6 +6241,64 @@ static void K_KartDrift(player_t *player, boolean onground)
player->kartstuff[k_brakedrift] = 0;
}
INT32 stprevnextchecks[2] = {INT32_MAX, INT32_MAX}; // there wont be any map this big, wont there?.....
// K_KartUpdatePosition has a bug where whatever player comes last in the players array
// gets its distance calculations applied twice
// since we cannot fix this due to compat concerns (kartstuff is exposed after all)
// we gotta do this shit hack to atleast fix the debugcheckpoint display
static void K_KartUpdatePositionDebugHack(player_t *player, player_t *otherplayer)
{
mobj_t *mo;
fixed_t pmo;
fixed_t ppcd, pncd;
// dont need this crap
if (!cv_kartdebugcheckpoint.value)
return;
// not checking against ourselves
if (player != otherplayer)
return;
// dont care if its not first displayplayer
// since this is only used for the debug display
if (player != &players[displayplayers[0]])
return;
ppcd = pncd = 0;
stprevnextchecks[0] = stprevnextchecks[1] = 0;
// This checks every thing on the map, and looks for MT_BOSS3WAYPOINT (the thing we're using for checkpoint wp's, for now)
for (mo = waypointcap; mo != NULL; mo = mo->tracer)
{
const boolean isprevcheckpointp = mo->health == player->starpostnum;
const boolean isnextcheckpointp = mo->health == (player->starpostnum + 1);
if ((isprevcheckpointp || isnextcheckpointp) && (!mo->movecount || mo->movecount == player->laps+1))
{
pmo = P_AproxDistance(P_AproxDistance( mo->x - player->mo->x,
mo->y - player->mo->y),
mo->z - player->mo->z) / FRACUNIT;
if (isprevcheckpointp)
{
stprevnextchecks[0] += pmo;
ppcd++;
}
if (isnextcheckpointp)
{
stprevnextchecks[1] += pmo;
pncd++;
}
}
}
if (ppcd > 1) stprevnextchecks[0] /= ppcd;
if (pncd > 1) stprevnextchecks[1] /= pncd;
}
//
// K_KartUpdatePosition
//
@@ -6231,6 +6310,9 @@ void K_KartUpdatePosition(player_t *player)
fixed_t pmo, imo;
mobj_t *mo;
// always reset this
stprevnextchecks[0] = stprevnextchecks[1] = INT32_MAX;
if (player->spectator || !player->mo)
return;
@@ -6243,11 +6325,12 @@ void K_KartUpdatePosition(player_t *player)
if (G_RaceGametype())
{
if ((((players[i].starpostnum) + (numstarposts + 1) * players[i].laps) >
((player->starpostnum) + (numstarposts + 1) * player->laps)))
const INT32 iplayerlaps = (players[i].starpostnum + (numstarposts + 1) * players[i].laps);
const INT32 pplayerlaps = (player->starpostnum + (numstarposts + 1) * player->laps);
if (iplayerlaps > pplayerlaps)
position++;
else if (((players[i].starpostnum) + (numstarposts+1)*players[i].laps) ==
((player->starpostnum) + (numstarposts+1)*player->laps))
else if (iplayerlaps == pplayerlaps)
{
ppcd = pncd = ipcd = incd = 0;
@@ -6330,6 +6413,9 @@ void K_KartUpdatePosition(player_t *player)
if (players[i].starposttime < player->starposttime)
position++;
}
// stupid hack
K_KartUpdatePositionDebugHack(player, &players[i]);
}
}
else if (G_BattleGametype())
@@ -6599,7 +6685,7 @@ static void K_PlayerItemThink(player_t *player, boolean onground, boolean oldatt
{
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BANANA_SHIELD);
if (!mo)
if (P_MobjWasRemovedCompat(mo))
{
player->kartstuff[k_itemamount] = moloop;
break;
@@ -6660,7 +6746,7 @@ static void K_PlayerItemThink(player_t *player, boolean onground, boolean oldatt
newangle = (player->mo->angle + ANGLE_157h) + FixedAngle(((360 / player->kartstuff[k_itemamount]) * moloop) << FRACBITS) + ANGLE_90;
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_ORBINAUT_SHIELD);
if (!mo)
if (P_MobjWasRemovedCompat(mo))
{
player->kartstuff[k_itemamount] = moloop;
break;
@@ -6703,7 +6789,7 @@ static void K_PlayerItemThink(player_t *player, boolean onground, boolean oldatt
newangle = (player->mo->angle + ANGLE_157h) + FixedAngle(((360 / player->kartstuff[k_itemamount]) * moloop) << FRACBITS) + ANGLE_90;
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_JAWZ_SHIELD);
if (!mo)
if (P_MobjWasRemovedCompat(mo))
{
player->kartstuff[k_itemamount] = moloop;
break;
@@ -7066,6 +7152,28 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
// "Stair jank" visuals akin to RR
if (cv_stairjank.value && player->stairjank > 0)
{
// only spawn em once
if (player->stairjank > 8)
{
// 90 degrees to direction you're facing
fixed_t dirx = -FINESINE(player->mo->angle>>ANGLETOFINESHIFT);
fixed_t diry = FINECOSINE(player->mo->angle>>ANGLETOFINESHIFT);
fixed_t offset = player->mo->radius;
dirx = K_AltFlip(-dirx, 4);
diry = K_AltFlip(-diry, 4);
mobj_t * spark = P_SpawnMobj(player->mo->x + FixedMul(dirx, offset), player->mo->y + FixedMul(diry, offset), player->mo->z, MT_DRIFTDUST);
spark->momx = FixedMul(dirx, FRACUNIT) + (6 + ((int)leveltime % 5))*(player->mo->momx)/10;
spark->momy = FixedMul(diry, FRACUNIT) + (6 + ((int)leveltime % 5))*(player->mo->momy)/10;
spark->momz = 5*FRACUNIT;
spark->scale = mapobjectscale/5;
spark->destscale = mapobjectscale/2;
spark->islocal = true;
spark->color = SKINCOLOR_WHITE;
P_SetTarget(&spark->target, player->mo);
}
player->mo->temprollangle += K_StairJankFlip(ANGLE_11hh / 2 / (17 / player->stairjank)); // TODO: make strength adjustable?
}
+2
View File
@@ -32,6 +32,8 @@ extern consvar_t cv_bananajitter;
extern consvar_t cv_bananthrowroll;
extern consvar_t cv_airsparks;
extern INT32 stprevnextchecks[2];
boolean K_IsPlayerLosing(player_t *player);
boolean K_IsPlayerWanted(player_t *player);
INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush);
+14 -26
View File
@@ -3055,58 +3055,46 @@ static int lib_kSetHyuCountdown(lua_State *L)
static int lib_gSetPlayerGamepadIndicatorColor(lua_State *L)
{
INT32 player = -1;
player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); // retrieve player
INT32 pnum = -1;
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); // retrieve player
UINT8 color = (UINT8)luaL_checkinteger(L, 2); // skincolor
if (!plr)
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (color >= MAXTRANSLATIONS)
return luaL_error(L, "color %d out of range (0 - %d).", color, MAXTRANSLATIONS-1);
for (int i = 0; i < MAXSPLITSCREENPLAYERS; ++i)
{
if (plr - players == displayplayers[i])
{
player = i;
break;
}
}
pnum = P_GetLocalPlayerNumForPlayer(player);
// Not a local player
if (player == -1) return 0;
if (pnum == -1) return 0;
// pls update with color 0 when youre done with changing led stuff so it can get player color again
G_SetPlayerGamepadIndicatorColor(player, color);
G_SetPlayerGamepadIndicatorColor(pnum, color);
return 0;
}
static int lib_gPlayerDeviceRumble(lua_State *L)
{
INT32 player = -1;
player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); // retrieve player
INT32 pnum = -1;
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); // retrieve player
UINT16 low_strength = (UINT16)luaL_checkinteger(L, 2); // low frequency rumble motor strenght
UINT16 high_strength = (UINT16)luaL_checkinteger(L, 3); // high frequency rumble motor strenght
UINT32 duration = (UINT32)luaL_optinteger(L, 4, 84); // duration of rumble in ms
if (!plr)
if (!player)
return LUA_ErrInvalid(L, "player_t");
for (int i = 0; i < MAXSPLITSCREENPLAYERS; ++i)
{
if (plr - players == displayplayers[i])
{
player = i;
break;
}
}
if (demo.playback) return 0;
pnum = P_GetLocalPlayerNumForPlayer(player);
// Not a local player
if (player == -1) return 0;
if (pnum == -1) return 0;
G_PlayerDeviceRumble(player, low_strength, high_strength, duration);
G_PlayerDeviceRumble(pnum, low_strength, high_strength, duration);
return 0;
}
+6 -1
View File
@@ -182,14 +182,19 @@ void COM_Lua_f(void)
len = (argc+1)*256;
buf = malloc(len);
if (buf == NULL)
I_Error("Failed to allocate buffer for COM_Lua_f");
p = buf;
WRITEUINT8(p, argc);
for (i = 0; i < argc; i++)
WRITESTRINGN(p, COM_Argv(i), 255);
if (flags & 2)
if (flags & COM_SPLITSCREEN)
SendNetXCmdForPlayer(1, XD_LUACMD, buf, p-buf);
else
SendNetXCmd(XD_LUACMD, buf, p-buf);
free(buf);
return;
}
+43 -4
View File
@@ -576,9 +576,45 @@ static int call_string_hooks(Hook_State *hook)
FUNCINLINE static ATTRINLINE int call_mobj_type_hooks(Hook_State *hook, mobjtype_t mobj_type)
{
return call_mapped(hook, &mobjHookIds[mobj_type][hook->hook_type]);
static UINT8 seen = 0; // so we dont have to check all this shit constantly
int numCalls = call_mapped(hook, &mobjHookIds[mobj_type][hook->hook_type]);
if (!seen && numCalls > 0 && mobj_type == MT_NULL &&
( hook->hook_type == MOBJ_HOOK(MobjThinker )
|| hook->hook_type == MOBJ_HOOK(MobjCollide )
|| hook->hook_type == MOBJ_HOOK(MobjMoveCollide)
|| hook->hook_type == MOBJ_HOOK(MobjFuse )
|| hook->hook_type == MOBJ_HOOK(BossThinker )
))
{
seen = 1;
CONS_Alert(
CONS_WARNING, "%s\n", va(
"%s hooks not attached to a specific mobj type may cause performance issues!",
mobjHookNames[hook->hook_type])
);
// print which script triggered it, ty indev <3
for (int k = 0; k < mobjHookIds[mobj_type][hook->hook_type].numHooks; ++k)
{
lua_getref(gL, hookRefs[mobjHookIds[mobj_type][hook->hook_type].ids[k].id]);
lua_Debug ar;
lua_getinfo(gL, ">S", &ar);
CONS_Printf("%s:%d\n", ar.short_src, ar.linedefined);
}
}
return numCalls;
}
/*FUNCINLINE static ATTRINLINE int call_mobj_type_hooks(Hook_State *hook, mobjtype_t mobj_type)
{
return call_mapped(hook, &mobjHookIds[mobj_type][hook->hook_type]);
}*/
static int call_hooks
(
Hook_State * hook,
@@ -766,7 +802,7 @@ static void hook_think_frame(int type)
const hook_t * map = &hookIds[type];
int k;
const boolean perfstats = (cv_perfstats.value >= 3);
const boolean perfstats = (cv_perfstats.value >= PS_THINKFRAME);
if (prepare_hook(&hook, 0, type))
{
@@ -862,7 +898,7 @@ int LUA_HookShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT3
int LUA_HookMobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
{
return damage_hook(target, inflictor, source, damage,
MOBJ_HOOK(MobjDamage), res_true);
MOBJ_HOOK(MobjDamage), res_true);
}
int LUA_HookMobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source)
@@ -951,7 +987,7 @@ void LUA_HookLinedefExecute(line_t *line, mobj_t *mo, sector_t *sector)
{
Hook_State hook = {};
if (prepare_string_hook
(&hook, 0, STRING_HOOK(LinedefExecute), line->text))
(&hook, 0, STRING_HOOK(LinedefExecute), line->text))
{
LUA_PushUserdata(gL, line, META_LINE);
LUA_PushUserdata(gL, mo, META_MOBJ);
@@ -1024,6 +1060,9 @@ void LUA_HookNetArchive(lua_CFunction archFunc, savebuffer_t *save)
lua_pushcclosure(gL, archFunc, 2);
// stack: tables, savebuffer_t, archFunc
// Manually set the hook's variables here since we don't call prepare_hook
hook.hook_type = HOOK(NetVars);
hook.mobj_type = NONMOHOOK; // Force mobj_type to be NONMOHOOK so the mobj_type check get skipped
init_hook_call(&hook, 0, res_none);
call_mapped(&hook, map);
+25 -15
View File
@@ -62,14 +62,6 @@ static lua_CFunction liblist[] = {
NULL
};
// Lua asks for memory using this.
static void *LUA_Alloc(void *ud, void *ptr, size_t osize, size_t nsize)
{
(void)ud;
(void)osize;
return Z_Realloc(ptr, nsize, PU_LUA, NULL);
}
// Panic function Lua calls when there's an unprotected error.
// This function cannot return. Lua would kill the application anyway if it did.
FUNCNORETURN static int LUA_Panic(lua_State *L)
@@ -197,7 +189,7 @@ void LUA_ClearState(void)
CONS_Printf(M_GetText("Pardon me while I initialize the Lua scripting interface...\n"));
// allocate state
L = lua_newstate(LUA_Alloc, NULL);
L = luaL_newstate();
lua_atpanic(L, LUA_Panic);
// open base libraries
@@ -277,20 +269,19 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
if (wadfiles[wad]->type == RET_LUA)
{
name = malloc(len+1);
strcpy(name, wadfiles[wad]->filename);
name = malloc(len + 1);
snprintf(name, len + 1, "%s", wadfiles[wad]->filename);
}
else // If it's not a .lua file, copy the lump name in too.
{
lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump];
len += 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name
name = malloc(len+1);
name = malloc(len + 1);
if (!name)
I_Error("LUA_LoadLump: Out of memory!\n");
sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->fullname);
name[len] = '\0';
snprintf(name, len + 1, "%s|%s", wadfiles[wad]->filename, lump_p->fullname);
}
LUA_LoadFile(&f, name); // actually load file!
@@ -374,7 +365,7 @@ void LUA_DumpFile(const char *filename)
static void createMathLibState(void)
{
mL = lua_newstate(LUA_Alloc, NULL);
mL = luaL_newstate();
lua_atpanic(mL, LUA_Panic);
// open only enum lib
@@ -592,6 +583,7 @@ void LUA_InvalidateLevel(void)
for (i = 0; i < numsubsectors; i++)
LUA_InvalidateUserdata(&subsectors[i]);
for (i = 0; i < numsectors; i++)
{
LUA_InvalidateUserdata(&sectors[i]);
@@ -612,6 +604,7 @@ void LUA_InvalidateLevel(void)
for (i = 0; i < numsides; i++)
LUA_InvalidateUserdata(&sides[i]);
for (i = 0; i < numvertexes; i++)
LUA_InvalidateUserdata(&vertexes[i]);
@@ -622,6 +615,10 @@ void LUA_InvalidateLevel(void)
LUA_InvalidateUserdata(&slope->o);
LUA_InvalidateUserdata(&slope->d);
}
// We invalidated a lot of userdata objects, a lot of them probably ended up unreachable so they can be
// GC'd right away
lua_gc(gL, LUA_GCCOLLECT, 0);
}
void LUA_InvalidateMapthings(void)
@@ -1460,3 +1457,16 @@ int Lua_CreateFieldTable(lua_State *L, const char *const lst[])
return luaL_ref(L, LUA_REGISTRYINDEX);
}
size_t LUA_MemoryUsage(void)
{
size_t usage = 0;
if (gL)
usage += lua_gc(gL, LUA_GCCOUNT, 0);
if (mL)
usage += lua_gc(mL, LUA_GCCOUNT, 0);
return usage;
}
+3
View File
@@ -82,6 +82,9 @@ int Lua_optoption(lua_State *L, int narg, int def, int list_ref);
int Lua_CreateFieldTable(lua_State *L, const char *const lst[]);
void LUA_HookNetArchive(lua_CFunction archFunc, savebuffer_t *save);
// Returns lua memory usage in kbytes
size_t LUA_MemoryUsage(void);
// Console wrapper
void COM_Lua_f(void);
+11 -2
View File
@@ -13,6 +13,12 @@
#include <string.h>
#ifdef HAVE_THREADS
#define local_for_thread _Thread_local
#else
#define local_for_thread
#endif
#include "doomdef.h"
#include "command.h"
#include "m_argv.h"
@@ -31,8 +37,11 @@ char **myargv = NULL;
boolean myargmalloc = false;
/** \brief founded the parm
*
* thread_local because it can potentially be used from multiple threads (global variables aaaaaa)
* (myargc and myargv don't have to be thread_local because they are never modified after being set up)
*/
static INT32 found;
static local_for_thread INT32 found;
/** \brief The M_CheckParm function
@@ -91,7 +100,7 @@ INT32 M_CheckProtoParam(const char *check)
const char *M_GetProtoParam(void)
{
INT32 i;
static char *string;
char *string;
for (i = 1; i < myargc; i++)
{
+3 -3
View File
@@ -766,7 +766,7 @@ boolean OP_FreezeObjectplace(void)
if (!objectplacing)
return false;
if ((maptol & TOL_NIGHTS) && (players[consoleplayer].pflags & PF_NIGHTSMODE))
if (nightsmode && nightsplayer(&players[consoleplayer]))
return false;
return true;
@@ -1049,7 +1049,7 @@ void Command_ObjectPlace_f(void)
{
objectplacing = true;
if ((players[0].pflags & PF_NIGHTSMODE))
if (nightsplayer(&players[0]))
return;
if (!COM_CheckParm("-silent"))
@@ -1120,7 +1120,7 @@ void Command_ObjectPlace_f(void)
// Don't touch the NiGHTS Objectplace stuff.
// ... or if the mo mysteriously vanished.
if (!players[0].mo || (players[0].pflags & PF_NIGHTSMODE))
if (!players[0].mo || nightsplayer(&players[0]))
return;
// If still in dummy state, get out of it.
+1 -1
View File
@@ -11,7 +11,7 @@
#include "m_curl.h"
#include "doomtype.h"
#include "i_system.h" // I_OutputMsg
#include "doomdef.h" // I_OutputMsg
#include "m_argv.h" // M_CheckParm, M_GetNextParm
static boolean curl_args_init = false;
+212 -142
View File
@@ -25,6 +25,7 @@
#include "d_netcmd.h"
#include "d_clisrv.h"
#include "i_net.h"
#include "i_system.h"
#include "console.h"
#include "r_fps.h"
#include "r_local.h"
@@ -276,6 +277,8 @@ static void M_ConfirmTeamChange(INT32 choice);
static void M_ConfirmSpectateChange(INT32 choice);
static void M_QuitSRB2(INT32 choice);
static void M_SaturnReportIssue(INT32 choice);
// Single Player
static void M_TimeAttack(INT32 choice);
static boolean M_QuitTimeAttackMenu(void);
@@ -613,7 +616,7 @@ void Nextmap_OnChange(void)
if (!gpath)
return;
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value));
snprintf(gpath, glen, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value));
CV_StealthSetValue(&cv_dummystaff, 0);
@@ -732,7 +735,7 @@ static void Dummystaff_OnChange(void)
while (*temp)
temp++;
sprintf(temp, " - %d", cv_dummystaff.value);
snprintf(temp, sizeof(dummystaffname) - (size_t)(temp - dummystaffname), " - %d", cv_dummystaff.value);
}
}
@@ -822,7 +825,8 @@ static void M_ChangeCvar(INT32 choice)
float increment;
increment = FIXED_TO_FLOAT(cv->value)+(choice)*((currentMenu->menuitems[itemOn].status & IT_CV_BIGFLOAT) ? 0.5f : (1.0f/16.0f));
sprintf(s,"%ld%s",(long)increment,M_Ftrim(increment));
snprintf(s, sizeof(s), "%ld%s", (long)increment, M_Ftrim(increment));
CV_Set(cv, s);
}
else
@@ -3980,6 +3984,14 @@ menudemo_t *demolist = NULL; // Replays that that have been checked to match wit
menudemo_t *demolist_all = NULL; // All replays
size_t demolist_all_size = 0;
boolean replaynamesloaded = false;
// Whenever we start a replay load thread, we increment this number and then thread will remember current value,
// and by the end it will compare it with current value, and if it is equal it means thread can store data it has loaded.
// If it's not equal, that means we started more than one thread (left and re-entered menu for example)
size_t replaythreadnum = 0;
// for replay dates
#include <locale.h>
const char *demodateformat = "%d.%m.%Y";
#ifdef HAVE_THREADS
I_mutex replayquerymutex;
@@ -4009,12 +4021,15 @@ static SINT8 replayScrollDelay = TICRATE, replayScrollDir = 1;
static void ReplayNamesLoadThread(void* userdata)
{
(void)userdata;
Lock_search_state();
size_t demolist_all_size_local = demolist_all_size;
menudemo_t *demolist_all_local = (menudemo_t*)malloc(sizeof(menudemo_t)*demolist_all_size_local);
memcpy(demolist_all_local, demolist_all, sizeof(menudemo_t)*demolist_all_size_local);
char *replaydirpath = (char*)userdata;
size_t localreplaythreadnum = replaythreadnum;
const char *localdemodateformat = demodateformat;
Unlock_search_state();
@@ -4022,19 +4037,13 @@ static void ReplayNamesLoadThread(void* userdata)
{
if (demolist_all_local[i].type != MD_SUBDIR)
{
G_LoadDemoTitle(&demolist_all_local[i]);
// this is fucking horrid, but i wanna be able to search for dates
/*if (demolist_all_local[i].date[0] != '\0')
{
snprintf(demolist_all_local[i].title, sizeof(demolist_all_local[i].title), "%s %s", demolist_all_local[i].title, demolist_all_local[i].date);
}*/
G_LoadDemoTitle(&demolist_all_local[i], localdemodateformat);
}
}
Lock_search_state();
if (fastcmp(menupath, replaydirpath) && demolist_all)
if (replaythreadnum == localreplaythreadnum && demolist_all)
{
memcpy(demolist_all, demolist_all_local, sizeof(menudemo_t)*demolist_all_size);
replaynamesloaded = true;
@@ -4043,22 +4052,32 @@ static void ReplayNamesLoadThread(void* userdata)
Unlock_search_state();
// Was allocated before thread start, we need to free it
free(replaydirpath);
free(demolist_all_local);
}
static void LoadReplayNames(void)
{
char *replaydirpath = strdup(menupath);
Lock_search_state();
replaythreadnum++;
replaynamesloaded = false;
if (cv_demodateformat.value == 2)
demodateformat = "%m.%d.%Y";
else if (cv_demodateformat.value == 1)
demodateformat = "%d.%m.%Y";
else
{
// get the date format here
// setlocale reads/writes global state
const char *locale = setlocale(LC_TIME, NULL);
// US ppl are special (:
demodateformat = (locale && strstr(locale, "en_US")) ? "%m.%d.%Y" : "%d.%m.%Y";
}
Unlock_search_state();
#ifdef HAVE_THREADS
I_spawn_thread("replay-names-load", ReplayNamesLoadThread, replaydirpath);
I_spawn_thread("replay-names-load", ReplayNamesLoadThread, NULL);
#else
ReplayNamesLoadThread(replaydirpath);
ReplayNamesLoadThread(NULL);
#endif
}
@@ -4097,8 +4116,12 @@ static void M_HutCheckReplays(size_t maxnum)
// Mark as done
replayqueryfound = replayquerycheck = sizedirmenu;
Lock_search_state();
memcpy(demolist, demolist_all, sizeof(menudemo_t) * sizedirmenu);
Unlock_search_state();
return;
}
@@ -4182,12 +4205,12 @@ static void PrepReplayList(boolean reset)
if (dirmenu[i][DIR_TYPE] == EXT_UP)
{
demolist_all[i].type = MD_SUBDIR;
sprintf(demolist_all[i].title, "UP");
snprintf(demolist_all[i].title, sizeof(demolist_all[i].title), "UP");
}
else if (dirmenu[i][DIR_TYPE] == EXT_FOLDER)
{
demolist_all[i].type = MD_SUBDIR;
strncpy(demolist_all[i].title, dirmenu[i] + DIR_STRING, 64);
snprintf(demolist_all[i].title, sizeof(demolist_all[i].title), "%s", dirmenu[i] + DIR_STRING);
}
else
{
@@ -4195,7 +4218,7 @@ static void PrepReplayList(boolean reset)
snprintf(demolist_all[i].filepath, sizeof(demolist_all[i].filepath),
// 255 = UINT8 limit. dirmenu entries are restricted to this length (see DIR_LEN).
"%s%.255s", menupath, dirmenu[i] + DIR_STRING);
sprintf(demolist_all[i].title, ".....");
snprintf(demolist_all[i].title, sizeof(demolist_all[i].title), ".....");
}
}
@@ -4247,6 +4270,16 @@ static boolean M_HandleReplayHutQuery(INT32 choice)
char tmp[MAXREPLAYQUERY+1];
memcpy(tmp, replayqueryinput_buffer, MAXREPLAYQUERY+1);
// Honestly not sure if locks for replaynamesloaded are necessary...
// Thread sanitizer does report race condition whenever replaynamesloaded is accessed without lock
// but really it is only ever set to false in main thread and only set to true in replay load thread,
// and both are done via locks. If replaynamesloaded is true, it is never gonna suddenly switch from true to false
// while we're in main thread, and if it would switch from false to true it is not really a big deal, we will just skip
// 1 frame where replay names were loaded
if (!replaynamesloaded)
return false;
if (M_TextInputHandle(&replayqueryinput, choice))
{
S_StartSound(NULL, sfx_menu1);
@@ -5755,7 +5788,8 @@ static void M_DrawMusicTest(void)
x = 24;
y = 64;
if (renderisnewtic) st_musictime++;
if (renderisnewtic)
st_musictime++;
while (t <= b)
{
@@ -5764,11 +5798,11 @@ static void M_DrawMusicTest(void)
{
const musicdef_t *def = S_GetMusicCredit(t);
const size_t MAXLENGTH = 34;
const char *songname = def->title[0] ? def->title : def->source;
size_t namelength = strlen(songname);
#define MAXLENGTH 34
char buf[MAXLENGTH+1];
if (t == st_sel && namelength > MAXLENGTH)
@@ -5777,11 +5811,14 @@ static void M_DrawMusicTest(void)
strlcpy(buf, songname, MAXLENGTH);
V_DrawString(x, y, (t == st_sel ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE|V_MONOSPACE, buf);
if (curplaying == def)
{
V_DrawFill(20+280-9, y-4, 8, 16, 230);
}
#undef MAXLENGTH
}
t++;
y += 16;
}
@@ -5968,7 +6005,8 @@ static void M_DrawStatsMaps(void)
V_DrawString(20, 42, highlightflags|MENUCAPS, "Combined time records:");
sprintf(beststr, "%i:%02i:%02i.%02i", G_TicsToHours(besttime), G_TicsToMinutes(besttime, false), G_TicsToSeconds(besttime), G_TicsToCentiseconds(besttime));
snprintf(beststr, sizeof(beststr), "%i:%02i:%02i.%02i", G_TicsToHours(besttime), G_TicsToMinutes(besttime, false), G_TicsToSeconds(besttime), G_TicsToCentiseconds(besttime));
V_DrawRightAlignedString(BASEVIDWIDTH-16, 42, (mapsunfinished ? warningflags : 0), beststr);
if (mapsunfinished)
@@ -6434,7 +6472,7 @@ static void M_ChooseTimeAttack(INT32 choice)
else
G_RecordDemo(nameofdemo);
G_DeferedInitNew(false, mapname, (UINT8)(cv_chooseskin.value-1), 0, false);
G_DeferedInitNew(false, mapname, (skinnum_t)(cv_chooseskin.value-1), 0, false);
}
static void M_HandleStaffReplay(INT32 choice)
@@ -7135,7 +7173,7 @@ static void M_CheckMODVersion(int id)
if (updatecheck)
{
sprintf(updatestring, UPDATE_ALERT_STRING, VERSIONSTRING, updatecheck);
snprintf(updatestring, sizeof(updatestring), UPDATE_ALERT_STRING, VERSIONSTRING, updatecheck);
#ifdef HAVE_THREADS
I_lock_mutex(&m_menu_mutex);
#endif
@@ -7633,11 +7671,8 @@ static void M_DrawMPMainMenu(void)
// use generic drawer for cursor, items and title
M_DrawGenericMenu();
#if MAXPLAYERS != 16
Update the maxplayers label...
#endif
V_DrawRightAlignedString(BASEVIDWIDTH-x, y+MP_MainMenu[4].alphaKey,
((itemOn == 4) ? highlightflags : 0)|MENUCAPS, "(2-16 Players)");
((itemOn == 4) ? highlightflags : 0)|MENUCAPS, va("(2-%d Players)", MAXPLAYERS));
V_DrawRightAlignedString(BASEVIDWIDTH-x, y+MP_MainMenu[5].alphaKey,
((itemOn == 5) ? highlightflags : 0)|MENUCAPS,
@@ -7653,7 +7688,7 @@ Update the maxplayers label...
{
char buf[28];
strlcpy(buf, setupm_ip, sizeof(buf));
V_DrawString(x+8,y+12, V_ALLOWLOWERCASE, buf);
V_DrawString(x+8, y+12, V_ALLOWLOWERCASE, buf);
}
else
M_DrawTextInputScroll(x+8, y+12, &setupm_input_ip, 0, SETUPM_IP_MAXSIZE);
@@ -7663,7 +7698,7 @@ Update the maxplayers label...
#define iconwidth 32
#define spacingwidth 32
#define incrwidth (iconwidth + spacingwidth)
UINT8 i = 0, pskin, pcol;
UINT16 i = 0, pskin, pcol;
// player arrangement width, but there's also a chance i'm a furry, shhhhhh
const INT32 paw = iconwidth + 3*incrwidth;
INT32 trans = 0;
@@ -7916,16 +7951,16 @@ static void M_DrawSetupMultiPlayerMenu(void)
spritedef_t *sprdef;
spriteframe_t *sprframe;
patch_t *patch;
UINT8 frame;
UINT8 speed;
UINT8 weight;
UINT8 i;
UINT8 s, w;
UINT16 frame;
UINT16 speed;
UINT16 weight;
UINT16 i;
UINT16 s, w;
INT32 skinnum = 0;
INT32 statx, staty;
UINT32 speenframe;
INT32 sltw, actw, hetw;
UINT8 skintodisplay;
skinnum_t skintodisplay;
INT32 nameboxaddy = 0;
const UINT8 *flashcol = V_GetStringColormap(highlightflags);
@@ -7982,7 +8017,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
break;
case SKINMENUTYPE_2D:
skintodisplay = setupm_fakeskin;
skintodisplay = (skinnum_t)setupm_fakeskin;
if (setupm_skinlockedselect) //show the skin we are trying to select
skintodisplay = skinstats[setupm_skinxpos][setupm_skinypos][setupm_skinselect];
else if (skinstatscount[setupm_skinxpos][setupm_skinypos] && itemOn == 1)
@@ -8191,12 +8226,12 @@ static void M_DrawSetupMultiPlayerMenu(void)
case SKINMENUTYPE_EXTENDED:
for (s = 0; s < SKINGRIDNEWWIDTH*SKINGRIDNEWHEIGHT; s++)
{
INT32 x = ((s % SKINGRIDNEWWIDTH) * 18) + ((BASEVIDWIDTH / 2) - (18 * SKINGRIDNEWWIDTH) - 8) + 100 + SKINXSHIFT; //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
INT32 y = ((s / SKINGRIDNEWWIDTH) * 18) + ((BASEVIDHEIGHT / 2) - (18 * (SKINGRIDNEWWIDTH/2)) + 10); //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
INT32 calcs = s + (setupm_skinypos * SKINGRIDNEWWIDTH);
INT32 skinn;
patch_t *face;
UINT8 *cmap;
const INT32 x = ((s % SKINGRIDNEWWIDTH) * 18) + ((BASEVIDWIDTH / 2) - (18 * SKINGRIDNEWWIDTH) - 8) + 100 + SKINXSHIFT; //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
const INT32 y = ((s / SKINGRIDNEWWIDTH) * 18) + ((BASEVIDHEIGHT / 2) - (18 * (SKINGRIDNEWWIDTH/2)) + 10); //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
const INT32 calcs = s + (setupm_skinypos * SKINGRIDNEWWIDTH);
if (calcs < numskins)
skinn = skinsorted[calcs];
@@ -8217,10 +8252,10 @@ static void M_DrawSetupMultiPlayerMenu(void)
if (itemOn == 1) //has to be on skin select part
{
patch_t *cursor;
INT32 curx = (((setupm_skinselect % SKINGRIDNEWWIDTH) * 18) + ((BASEVIDWIDTH / 2) - (18 * SKINGRIDNEWWIDTH/2)) + SKINXSHIFT) + 20;
INT32 cury = (((setupm_skinselect / SKINGRIDNEWWIDTH) - setupm_skinypos) * 18) + ((BASEVIDHEIGHT / 2) - (18 * (SKINGRIDNEWWIDTH/2))+ 10);
const INT32 curx = (((setupm_skinselect % SKINGRIDNEWWIDTH) * 18) + ((BASEVIDWIDTH / 2) - (18 * SKINGRIDNEWWIDTH/2)) + SKINXSHIFT) + 20;
const INT32 cury = (((setupm_skinselect / SKINGRIDNEWWIDTH) - setupm_skinypos) * 18) + ((BASEVIDHEIGHT / 2) - (18 * (SKINGRIDNEWWIDTH/2))+ 10);
UINT8 cursorframe = (I_GetTime() / 4) % 7;
const UINT8 cursorframe = (I_GetTime() / 4) % 7;
cursor = (patch_t *)W_CachePatchName(va("K_CHILI%d", cursorframe + 1), PU_PATCH);
V_DrawFixedPatch((curx << FRACBITS) - (FRACUNIT), (cury << FRACBITS) - (FRACUNIT), FRACUNIT+(FRACUNIT>>3), 0, cursor, NULL);
}
@@ -8229,9 +8264,9 @@ static void M_DrawSetupMultiPlayerMenu(void)
case SKINMENUTYPE_GRID:
for (s = 0; s < SKINGRIDWIDTH*SKINGRIDHEIGHT; s++)
{
INT32 x = ((s % SKINGRIDWIDTH) * 18) + ((BASEVIDWIDTH / 2) - (18 * SKINGRIDWIDTH) - 8) + 100 + SKINXSHIFT; //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
INT32 y = ((s / SKINGRIDWIDTH) * 18) + ((BASEVIDHEIGHT / 2) - (18 * (SKINGRIDWIDTH/2))); //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
INT32 calcs = s + (setupm_skinypos * SKINGRIDWIDTH);
const INT32 x = ((s % SKINGRIDWIDTH) * 18) + ((BASEVIDWIDTH / 2) - (18 * SKINGRIDWIDTH) - 8) + 100 + SKINXSHIFT; //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
const INT32 y = ((s / SKINGRIDWIDTH) * 18) + ((BASEVIDHEIGHT / 2) - (18 * (SKINGRIDWIDTH/2))); //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
const INT32 calcs = s + (setupm_skinypos * SKINGRIDWIDTH);
INT16 skinn;
patch_t *face;
UINT8 *cmap;
@@ -8255,36 +8290,44 @@ static void M_DrawSetupMultiPlayerMenu(void)
if (itemOn == 1) //has to be on skin select part
{
patch_t *cursor;
INT32 curx = (((setupm_skinselect % SKINGRIDWIDTH) * 18) + ((BASEVIDWIDTH / 2) - (18 * SKINGRIDWIDTH/2)) + SKINXSHIFT) + 20;
INT32 cury = (((setupm_skinselect / SKINGRIDWIDTH) - setupm_skinypos) * 18) + ((BASEVIDHEIGHT / 2) - (18 * (SKINGRIDWIDTH/2)));
const INT32 curx = (((setupm_skinselect % SKINGRIDWIDTH) * 18) + ((BASEVIDWIDTH / 2) - (18 * SKINGRIDWIDTH/2)) + SKINXSHIFT) + 20;
const INT32 cury = (((setupm_skinselect / SKINGRIDWIDTH) - setupm_skinypos) * 18) + ((BASEVIDHEIGHT / 2) - (18 * (SKINGRIDWIDTH/2)));
if (setupm_skinselect < numskins)
{
UINT8 *cmap = R_GetTranslationColormap(setupm_skinselect, setupm_fakecolor, GTC_MENUCACHE);
const UINT8 *cmap = R_GetTranslationColormap(setupm_skinselect, setupm_fakecolor, GTC_MENUCACHE);
cursor = facewantprefix[skinsorted[setupm_skinselect]];
V_DrawFixedPatch(((curx-8) << FRACBITS), ((cury-8) << FRACBITS), FRACUNIT, 0, cursor, cmap);
}
else
{
UINT8 cursorframe = (I_GetTime() / 4) % 7;
const UINT8 cursorframe = (I_GetTime() / 4) % 7;
cursor = (patch_t *)W_CachePatchName(va("K_CHILI%d", cursorframe + 1), PU_PATCH);
V_DrawFixedPatch((curx << FRACBITS) - (FRACUNIT), (cury << FRACBITS) - (FRACUNIT), FRACUNIT+(FRACUNIT>>3), 0, cursor, NULL);
}
}
{ // stat dot
INT32 selectedskin = (itemOn == 1 && setupm_skinselect < numskins ? skinsorted[setupm_skinselect] : setupm_fakeskin);
const INT32 selectedskin = (itemOn == 1 && setupm_skinselect < numskins ? skinsorted[setupm_skinselect] : setupm_fakeskin);
speed = skins[selectedskin].kartspeed;
weight = skins[selectedskin].kartweight;
statdot = (patch_t *)W_CachePatchName("K_SDOT1", PU_PATCH);
if (skullAnimCounter < 4) // SRB2Kart: we draw this dot later so that it's not covered if there's multiple skins with the same stats
V_DrawFixedPatch((((statx+46) + (speed*4))<<FRACBITS) + (FRACUNIT>>1), (((staty+71) + (weight*4))<<FRACBITS), FRACUNIT>>1, 0, statdot, flashcol);
else
V_DrawFixedPatch((((statx+46) + (speed*4))<<FRACBITS) + (FRACUNIT>>1), (((staty+71) + (weight*4))<<FRACBITS), FRACUNIT>>1, 0, statdot, NULL);
statdot = (patch_t *)W_CachePatchName("K_SDOT2", PU_PATCH); // coloured center
const INT32 x = (((statx+46) + (speed*4))<<FRACBITS) + (FRACUNIT>>1);
const INT32 y = (((staty+71) + (weight*4))<<FRACBITS);
statdot = (patch_t *)W_CachePatchName("K_SDOT1", PU_PATCH);
if (skullAnimCounter < 4) // SRB2Kart: we draw this dot later so that it's not covered if there's multiple skins with the same stats
V_DrawFixedPatch(x, y, FRACUNIT>>1, 0, statdot, flashcol);
else
V_DrawFixedPatch(x, y, FRACUNIT>>1, 0, statdot, NULL);
if (setupm_fakecolor)
V_DrawFixedPatch((((statx+46) + (speed*4))<<FRACBITS) + (FRACUNIT>>1), (((staty+71) + (weight*4))<<FRACBITS), FRACUNIT>>1, 0, statdot, R_GetTranslationColormap(0, setupm_fakecolor, GTC_MENUCACHE));
{
statdot = (patch_t *)W_CachePatchName("K_SDOT2", PU_PATCH); // coloured center
V_DrawFixedPatch(x, y, FRACUNIT>>1, 0, statdot, R_GetTranslationColormap(0, setupm_fakecolor, GTC_MENUCACHE));
}
}
break;
case SKINMENUTYPE_2D:
@@ -8293,12 +8336,13 @@ static void M_DrawSetupMultiPlayerMenu(void)
{
for (w = 0; w < MAXSTAT; w++)
{
INT32 x = ((s * 18) + ((BASEVIDWIDTH / 2) - (18 * 4)) - 8 + SKINXSHIFT); //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
INT32 y = ((w * 18) + ((BASEVIDHEIGHT / 2) - (18 * 4)) - 8); //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
INT32 skinn;
patch_t *face;
UINT8 *cmap;
const INT32 x = ((s * 18) + ((BASEVIDWIDTH / 2) - (18 * 4)) - 8 + SKINXSHIFT); //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
const INT32 y = ((w * 18) + ((BASEVIDHEIGHT / 2) - (18 * 4)) - 8); //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
if (!skinstatscount[s][w])
{
V_DrawFill(x, y, 16, 16, 239);
@@ -8316,20 +8360,20 @@ static void M_DrawSetupMultiPlayerMenu(void)
if (itemOn == 1) //has to be on skin select part
{
patch_t *cursor;
INT32 curx = ((setupm_skinxpos * 18) + ((BASEVIDWIDTH / 2) - (18 * 4)) - 8 + SKINXSHIFT);
INT32 cury = ((setupm_skinypos * 18) + ((BASEVIDHEIGHT / 2) - (18 * 4)) - 8);
const INT32 curx = ((setupm_skinxpos * 18) + ((BASEVIDWIDTH / 2) - (18 * 4)) - 8 + SKINXSHIFT);
const INT32 cury = ((setupm_skinypos * 18) + ((BASEVIDHEIGHT / 2) - (18 * 4)) - 8);
if (skinstatscount[setupm_skinxpos][setupm_skinypos])
{
UINT8 *cmap = R_GetTranslationColormap(setupm_skinselect, setupm_fakecolor, GTC_MENUCACHE);
INT32 skinn = skinstats[setupm_skinxpos][setupm_skinypos][(I_GetTime() / TICRATE) % skinstatscount[setupm_skinxpos][setupm_skinypos]];
const UINT8 *cmap = R_GetTranslationColormap(setupm_skinselect, setupm_fakecolor, GTC_MENUCACHE);
const INT32 skinn = skinstats[setupm_skinxpos][setupm_skinypos][(I_GetTime() / TICRATE) % skinstatscount[setupm_skinxpos][setupm_skinypos]];
cursor = facewantprefix[skinn];
V_DrawFixedPatch(((curx-8) << FRACBITS), ((cury-8) << FRACBITS), FRACUNIT, 0, cursor, cmap);
}
else
{
UINT8 cursorframe = (I_GetTime() / 4) % 7;
const UINT8 cursorframe = (I_GetTime() / 4) % 7;
cursor = (patch_t *)W_CachePatchName(va("K_CHILI%d", cursorframe + 1), PU_PATCH);
V_DrawFixedPatch((curx << FRACBITS) - (FRACUNIT), (cury << FRACBITS) - (FRACUNIT), FRACUNIT+(FRACUNIT>>3), 0, cursor, NULL);
}
@@ -8337,18 +8381,26 @@ static void M_DrawSetupMultiPlayerMenu(void)
break;
#undef SKINXSHIFT
default:
speed = skins[setupm_fakeskin].kartspeed;
weight = skins[setupm_fakeskin].kartweight;
{
speed = skins[setupm_fakeskin].kartspeed;
weight = skins[setupm_fakeskin].kartweight;
statdot = (patch_t *)W_CachePatchName("K_SDOT1", PU_PATCH);
if (skullAnimCounter < 4) // SRB2Kart: we draw this dot later so that it's not covered if there's multiple skins with the same stats
V_DrawFixedPatch(((BASEVIDWIDTH - mx - 80) + ((speed-1)*8))<<FRACBITS, ((my+76) + ((weight-1)*8))<<FRACBITS, FRACUNIT, 0, statdot, flashcol);
else
V_DrawFixedPatch(((BASEVIDWIDTH - mx - 80) + ((speed-1)*8))<<FRACBITS, ((my+76) + ((weight-1)*8))<<FRACBITS, FRACUNIT, 0, statdot, NULL);
const INT32 x = ((BASEVIDWIDTH - mx - 80) + ((speed-1)*8))<<FRACBITS;
const INT32 y = ((my+76) + ((weight-1)*8))<<FRACBITS;
statdot = (patch_t *)W_CachePatchName("K_SDOT2", PU_PATCH); // coloured center
if (setupm_fakecolor)
V_DrawFixedPatch(((BASEVIDWIDTH - mx - 80) + ((speed-1)*8))<<FRACBITS, ((my+76) + ((weight-1)*8))<<FRACBITS, FRACUNIT, 0, statdot, R_GetTranslationColormap(0, setupm_fakecolor, GTC_MENUCACHE));
statdot = (patch_t *)W_CachePatchName("K_SDOT1", PU_PATCH);
if (skullAnimCounter < 4) // SRB2Kart: we draw this dot later so that it's not covered if there's multiple skins with the same stats
V_DrawFixedPatch(x, y, FRACUNIT, 0, statdot, flashcol);
else
V_DrawFixedPatch(x, y, FRACUNIT, 0, statdot, NULL);
if (setupm_fakecolor)
{
statdot = (patch_t *)W_CachePatchName("K_SDOT2", PU_PATCH); // coloured center
V_DrawFixedPatch(x, y, FRACUNIT, 0, statdot, R_GetTranslationColormap(0, setupm_fakecolor, GTC_MENUCACHE));
}
}
break;
}
@@ -8362,7 +8414,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
colwidth = colwidth - 10;
INT32 j = -colwidth;
INT16 col = setupm_fakecolor - colwidth;
INT32 col = setupm_fakecolor - colwidth;
INT32 x = mx;
INT32 cw = indexwidth;
UINT8 ch;
@@ -8375,10 +8427,13 @@ static void M_DrawSetupMultiPlayerMenu(void)
cw = charw;
else
cw = indexwidth;
for (ch = 0; ch < 16; ch++)
V_DrawFill(x, my+(cv_skinselectmenu.value?176:162)+ch, cw, 1, colortranslations[col][ch]);
if (++col >= MAXSKINCOLORS)
col -= MAXSKINCOLORS-1;
x += cw;
}
}
@@ -8390,7 +8445,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
{
const INT32 icons = 4;
INT32 k = -icons;
INT16 col = setupm_fakeskin - icons;
INT32 col = setupm_fakeskin - icons;
INT32 x = BASEVIDWIDTH/2 - ((icons+1)*24) - 4;
fixed_t scale = FRACUNIT/2;
INT32 offx = 8, offy = 8;
@@ -8406,6 +8461,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
if (col < 0)
col += numskins;
while (k <= icons)
{
if (!(k++))
@@ -8422,12 +8478,16 @@ static void M_DrawSetupMultiPlayerMenu(void)
offx = 8;
offy = 8;
}
colmap = R_GetTranslationColormap(col, setupm_fakecolor, GTC_MENUCACHE);
V_DrawFixedPatch((x+offx)<<FRACBITS, (my+28+offy)<<FRACBITS, FRACUNIT, 0, face, colmap);
if (scale == FRACUNIT) // bit of a hack
V_DrawFixedPatch((x+offx)<<FRACBITS, (my+28+offy)<<FRACBITS, FRACUNIT, 0, cursor, colmap);
if (++col >= numskins)
col -= numskins;
x += FixedMul(iconwidth<<FRACBITS, 3*scale/2)/FRACUNIT;
}
}
@@ -8453,7 +8513,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
switch (cv_skinselectmenu.value)
{
case SKINMENUTYPE_2D:
skintodisplay = (UINT8)setupm_fakeskin;
skintodisplay = (skinnum_t)setupm_fakeskin;
if (setupm_skinlockedselect) // show the skin we are trying to select
skintodisplay = skinstats[setupm_skinxpos][setupm_skinypos][setupm_skinselect];
else if (skinstatscount[setupm_skinxpos][setupm_skinypos] && itemOn == 1)
@@ -8461,10 +8521,10 @@ static void M_DrawSetupMultiPlayerMenu(void)
break;
case SKINMENUTYPE_EXTENDED:
case SKINMENUTYPE_GRID:
skintodisplay = ((itemOn == 1 && (setupm_skinselect < numskins)) ? skinsorted[setupm_skinselect] : (UINT8)setupm_fakeskin);
skintodisplay = ((itemOn == 1 && (setupm_skinselect < numskins)) ? skinsorted[setupm_skinselect] : (skinnum_t)setupm_fakeskin);
break;
default:
skintodisplay = (UINT8)setupm_fakeskin;
skintodisplay = (skinnum_t)setupm_fakeskin;
break;
}
@@ -8568,6 +8628,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
}
else
M_NextOpt();
S_StartSound(NULL, sfx_menu1); // Tails
break;
}
@@ -8594,6 +8655,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
{
M_NextOpt();
}
S_StartSound(NULL, sfx_menu1);
}
else if (itemOn == 0)
@@ -8604,9 +8666,11 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
}
else
M_NextOpt();
S_StartSound(NULL, sfx_menu1); // Tails
break;
}
M_NextOpt();
S_StartSound(NULL, sfx_menu1); // Tails
break;
@@ -8624,6 +8688,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
}
else
M_PrevOpt();
S_StartSound(NULL, sfx_menu1); // Tails
break;
}
@@ -8642,6 +8707,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
{
M_PrevOpt();
}
S_StartSound(NULL, sfx_menu1);
}
else if (itemOn == 2)
@@ -8661,9 +8727,11 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
}
else
M_PrevOpt();
S_StartSound(NULL, sfx_menu1); // Tails
break;
}
M_PrevOpt();
S_StartSound(NULL, sfx_menu1); // Tails
break;
@@ -8682,6 +8750,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
setupm_skinselect--;
else
setupm_skinselect = SELECTEDSTATSCOUNT - 1;
S_StartSound(NULL, sfx_menu1);
}
else //player skin
@@ -8714,6 +8783,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
else if (cv_skinselectmenu.value == SKINMENUTYPE_EXTENDED)
setupm_skinypos = (((roundedskins/8) - SKINGRIDHEIGHT-2) > 0 ? (roundedskins/8) - SKINGRIDHEIGHT-2 : 0);
}
S_StartSound(NULL, sfx_menu1);
break;
}
@@ -8744,6 +8814,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
setupm_skinselect++;
else
setupm_skinselect = 0;
S_StartSound(NULL, sfx_menu1);
}
else //player skin
@@ -8778,6 +8849,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
setupm_skinselect = 0;
setupm_skinypos = 0;
}
S_StartSound(NULL, sfx_menu1);
break;
}
@@ -8800,12 +8872,14 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
setupm_skinlockedselect = false;
break;
}
exitmenu = true;
break;
case KEY_BACKSPACE:
if (cv_skinselectmenu.value)
BREAKWHENLOCKED
if (itemOn == 0)
{
M_TextInputHandle(&setupm_input, choice);
@@ -8835,6 +8909,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
case KEY_DEL:
if (cv_skinselectmenu.value)
BREAKWHENLOCKED
if (itemOn == 0)
{
M_TextInputHandle(&setupm_input, choice);
@@ -9037,15 +9112,15 @@ static boolean M_QuitMultiPlayerMenu(void)
if (!fastcmp(setupm_name, setupm_cvname->string))
{
// remove trailing whitespaces
for (l = strlen(setupm_name)-1;
(signed)l >= 0 && setupm_name[l] ==' '; l--)
setupm_name[l] =0;
COM_BufAddText(va("%s \"%s\"\n",setupm_cvname->name,setupm_name));
l = strlen(setupm_name)-1;
for (;(signed)l >= 0 && setupm_name[l] ==' '; l--)
setupm_name[l] = 0;
COM_BufAddText(va("%s \"%s\"\n", setupm_cvname->name, setupm_name));
}
// you know what? always putting these in the buffer won't hurt anything.
COM_BufAddText(va("%s \"%s\"\n",setupm_cvskin->name,skins[setupm_fakeskin].name));
COM_BufAddText(va("%s %d\n",setupm_cvcolor->name,setupm_fakecolor));
COM_BufAddText(va("%s \"%s\"\n", setupm_cvskin->name, skins[setupm_fakeskin].name));
COM_BufAddText(va("%s %d\n", setupm_cvcolor->name, setupm_fakecolor));
return true;
}
@@ -9151,7 +9226,7 @@ static void M_DrawJoystick(void)
compareval4 = cv_usejoystick[3].value;
compareval3 = cv_usejoystick[2].value;
compareval2 = cv_usejoystick[1].value;
compareval = cv_usejoystick[0].value;
compareval = cv_usejoystick[0].value;
#endif
if ((setupcontrolplayer == 4 && (i == compareval4))
@@ -9190,14 +9265,13 @@ void M_SetupJoystickMenu(INT32 choice)
//
// Update cv_usejoystick.string here so that the user can
// properly change this value.
if (i == cv_usejoystick[0].value)
CV_SetValue(&cv_usejoystick[0], i);
if (i == cv_usejoystick[1].value)
CV_SetValue(&cv_usejoystick[1], i);
if (i == cv_usejoystick[2].value)
CV_SetValue(&cv_usejoystick[2], i);
if (i == cv_usejoystick[3].value)
CV_SetValue(&cv_usejoystick[3], i);
for (INT32 f = 0; f < MAXSPLITSCREENPLAYERS; f++)
{
if (i == cv_usejoystick[f].value)
{
CV_SetValue(&cv_usejoystick[f], i);
}
}
#endif
}
@@ -9236,9 +9310,11 @@ static void M_Setup4PJoystickMenu(INT32 choice)
static void M_DoAssignJoystick(UINT8 pnum, INT32 choice)
{
INT32 oldchoice, oldstringchoice;
const int joynum = atoi(cv_usejoystick[pnum].string);
oldchoice = oldstringchoice = joynum > numcontrollers ? joynum : cv_usejoystick[pnum].value;
#define joystrnum (atoi(cv_usejoystick[pnum].string))
#define joyoldchoice ((joystrnum > numcontrollers) ? joystrnum : cv_usejoystick[pnum].value)
oldchoice = oldstringchoice = joyoldchoice;
CV_SetValue(&cv_usejoystick[pnum], choice);
// Just in case last-minute changes were made to cv_usejoystick.value,
@@ -9248,59 +9324,37 @@ static void M_DoAssignJoystick(UINT8 pnum, INT32 choice)
{
CV_SetValue(&cv_usejoystick[pnum], cv_usejoystick[pnum].value);
if (oldchoice > numcontrollers) /* reset this so the comparison is valid*/
// reset this so the comparison is valid
if (oldchoice > numcontrollers)
oldchoice = cv_usejoystick[pnum].value;
if (oldchoice != choice)
{
if (choice && oldstringchoice > numcontrollers) // if we did not select "None", we likely selected a used device
CV_SetValue(&cv_usejoystick[pnum], (oldstringchoice > numcontrollers ? oldstringchoice : oldchoice));
{
CV_SetValue(&cv_usejoystick[pnum], ((oldstringchoice > numcontrollers) ? oldstringchoice : oldchoice));
}
if (oldstringchoice ==
(joynum > numcontrollers ? joynum : cv_usejoystick[pnum].value))
if (oldstringchoice == joyoldchoice)
{
M_StartMessage("This joystick is used by another\n"
"player. Reset the joystick\n"
"for that player first.\n\n"
"(Press a key)\n", NULL, MM_NOTHING);
}
}
}
#undef joystrnum
#undef joyoldchoice
}
#endif
static void M_AssignJoystick(INT32 choice)
{
#ifdef JOYSTICK_HOTPLUG
switch (setupcontrolplayer)
{
case 4:
M_DoAssignJoystick(3, choice);
break;
case 3:
M_DoAssignJoystick(2, choice);
break;
case 2:
M_DoAssignJoystick(1, choice);
break;
case 1:
M_DoAssignJoystick(0, choice);
break;
}
M_DoAssignJoystick((setupcontrolplayer-1), choice);
#else
switch (setupcontrolplayer)
{
case 4:
CV_SetValue(&cv_usejoystick[3], choice);
break;
case 3:
CV_SetValue(&cv_usejoystick[2], choice);
break;
case 2:
CV_SetValue(&cv_usejoystick[1], choice);
break;
case 1:
CV_SetValue(&cv_usejoystick[0], choice);
break;
}
CV_SetValue(&cv_usejoystick[(setupcontrolplayer-1)], choice);
#endif
}
@@ -9338,7 +9392,7 @@ static void M_SetupControlsMenu(UINT8 pnum)
{
// Hide P1-only controls
OP_AllControlsMenu[19].status = IT_GRAYEDOUT2; // Chat
OP_AllControlsMenu[10].status = IT_GRAYEDOUT2; // Rankings
OP_AllControlsMenu[20].status = IT_GRAYEDOUT2; // Rankings
OP_AllControlsMenu[21].status = IT_GRAYEDOUT2; // Pause
OP_AllControlsMenu[22].status = IT_GRAYEDOUT2; // Screenshot
OP_AllControlsMenu[23].status = IT_GRAYEDOUT2; // GIF
@@ -9350,7 +9404,7 @@ static void M_SetupControlsMenu(UINT8 pnum)
{
// Unhide P1-only controls
OP_AllControlsMenu[19].status = IT_CONTROL; // Chat
OP_AllControlsMenu[10].status = IT_CONTROL; // Rankings
OP_AllControlsMenu[20].status = IT_CONTROL; // Rankings
OP_AllControlsMenu[21].status = IT_CONTROL; // Pause
OP_AllControlsMenu[22].status = IT_CONTROL; // Screenshot
OP_AllControlsMenu[23].status = IT_CONTROL; // GIF
@@ -9587,11 +9641,13 @@ static void M_ChangecontrolResponse(event_t *ev)
menu_t *prev = currentMenu->prevMenu;
if (controltochange == gc_pause)
sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nyou may select another key. \n\nHit another key for\n%s\nESC for Cancel"),
controltochangetext);
{
snprintf(tmp, sizeof(tmp), M_GetText("The \x82Pause Key \x80is enabled, but \nyou may select another key. \n\nHit another key for\n%s\nESC for Cancel"), controltochangetext);
}
else
sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nit is not configurable. \n\nHit another key for\n%s\nESC for Cancel"),
controltochangetext);
{
snprintf(tmp, sizeof(tmp), M_GetText("The \x82Pause Key \x80is enabled, but \nit is not configurable. \n\nHit another key for\n%s\nESC for Cancel"), controltochangetext);
}
M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER);
currentMenu->prevMenu = prev;
@@ -9612,8 +9668,7 @@ static void M_ChangeControl(INT32 choice)
static char tmp[68];
controltochange = currentMenu->menuitems[choice].alphaKey;
sprintf(tmp, M_GetText("Hit the new key for\n%s\nESC for Cancel"),
currentMenu->menuitems[choice].text);
snprintf(tmp, sizeof(tmp), M_GetText("Hit the new key for\n%s\nESC for Cancel"), currentMenu->menuitems[choice].text);
strlcpy(controltochangetext, currentMenu->menuitems[choice].text, 33);
M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER);
@@ -9895,6 +9950,7 @@ static void M_DrawLocalSkinMenu(void)
V_DrawFill(mx + 220 - (charw/2), my+54, charw, 84, 239);
#undef charw
// FIXME: is skins[displayskin.localnum] even correct?
UINT8 *colormap = R_GetLocalTranslationColormap(&skins[displayskin.localnum], (displayskin.localskin ? &localskins[displayskin.localnum] : NULL), cv_playercolor.value, GTC_MENUCACHE, displayskin.localskin);
V_DrawMappedPatch(mx, my+50, 0, (patch_t *)W_CachePatchName(displayskin.facewant, PU_PATCH), colormap);
@@ -9912,7 +9968,7 @@ static void M_DrawLocalSkinMenu(void)
my += 120;
#ifdef HWRENDER
md2_t *md2 = (displayskin.localskin ? &md2_localplayermodels[skintodisplay] : &md2_playermodels[skintodisplay]);
md2_t *md2 = (displayskin.localskin ? &md2_localplayermodels[displayskin.localnum] : &md2_playermodels[skintodisplay]);
// if we have 3d models enabled and a model exists
// try to show it instead of the sprite
@@ -10045,7 +10101,7 @@ static void M_DrawColorMenu(void)
for (max = currentMenu->numitems; max > 0; max--)
{
if (currentMenu->menuitems[max].status != IT_DISABLED && currentMenu->menuitems[max-1].alphaKey*2 + tempcentery <= (currentMenu->y + 2*scrollareaheight))
if (currentMenu->menuitems[max-1].status != IT_DISABLED && currentMenu->menuitems[max-1].alphaKey*2 + tempcentery <= (currentMenu->y + 2*scrollareaheight))
break;
}
@@ -10581,6 +10637,20 @@ static void M_QuitSRB2(INT32 choice)
M_StartMessage(quitmsg[M_RandomKey(NUM_QUITMESSAGES)], M_QuitResponse, MM_YESNO);
}
// ===========
// SATURN MENU
// ===========
static void M_SaturnReportIssue(INT32 choice)
{
(void)choice;
int url = I_OpenURL(SATURNISSUEPAGE);
// SDL_OpenURL unsupported or failed
if (url == -1)
M_StartMessage(M_GetText("Failed to Open Web Page.\nPlease open the following page in your web browser:\n\n" SATURNISSUEPAGE "\n\n(Press a key)\n"), NULL, MM_NOTHING);
}
#ifdef HAVE_DISCORDRPC
// =====================================================================
+2 -2
View File
@@ -230,8 +230,8 @@ typedef struct
char levelname[32];
UINT8 actnum;
UINT8 skincolor;
UINT8 skinnum;
UINT8 botskin;
skinnum_t skinnum;
skinnum_t botskin;
UINT8 botcolor;
UINT8 numemeralds;
INT32 lives;
+59 -3
View File
@@ -36,6 +36,7 @@ static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef;
menu_t OP_ControlsDef, OP_AllControlsDef;
menu_t OP_MouseOptionsDef;
menu_t OP_Joystick1Def, OP_Joystick2Def, OP_Joystick3Def, OP_Joystick4Def;
menu_t OP_Joystick1RumbleDef, OP_Joystick2RumbleDef, OP_Joystick3RumbleDef, OP_Joystick4RumbleDef;
// Custom cvar menu
menu_t OP_CustomCvarMenuDef;
@@ -725,6 +726,14 @@ static const char* OP_AllControlsTooltips[sizeof(OP_AllControlsMenu)/sizeof(OP_A
// The rest is null, for now
};
// i really do not feel like messing with setup routines
// and macro preprocessor cannot eval maths for string shit like this :chaosleep:
#define RUMBDEF_0 OP_Joystick1RumbleDef
#define RUMBDEF_1 OP_Joystick2RumbleDef
#define RUMBDEF_2 OP_Joystick3RumbleDef
#define RUMBDEF_3 OP_Joystick4RumbleDef
#define RUMBDEF(x) RUMBDEF_##x
#define OP_JOYMENU(pnum) \
{IT_HEADER, NULL, "Gameplay Controls", NULL, 7}, \
{IT_STRING | IT_CVAR, NULL, "Aim Forward/Back" , &cv_aimaxis[pnum] , 15}, \
@@ -745,9 +754,8 @@ static const char* OP_AllControlsTooltips[sizeof(OP_AllControlsMenu)/sizeof(OP_A
{IT_STRING | IT_CVAR, NULL, "X deadzone" , &cv_xdeadzone[pnum] , 100}, \
{IT_STRING | IT_CVAR, NULL, "Y deadzone" , &cv_ydeadzone[pnum] , 105}, \
{IT_HEADER, NULL, "Miscellaneous", NULL, 112}, \
{IT_STRING | IT_CVAR, NULL, "Controller Rumble" , &cv_rumble[pnum] , 120}, \
{IT_STRING | IT_CVAR, NULL, "Controller Rumble Strength" , &cv_rumblestrength[pnum] , 125}, \
{IT_STRING | IT_CVAR, NULL, "Set LED to Player color" , &cv_gamepadled[pnum] , 130},
{IT_SUBMENU|IT_STRING, NULL, "Rumble Options..." , &RUMBDEF(pnum) , 120}, \
{IT_STRING | IT_CVAR, NULL, "Set LED to Player color" , &cv_gamepadled[pnum] , 125},
static menuitem_t OP_Joystick1Menu[] =
{
@@ -773,6 +781,46 @@ static menuitem_t OP_Joystick4Menu[] =
OP_JOYMENU(3)
};
#undef RUMBDEF
#undef RUMBDEF_0
#undef RUMBDEF_1
#undef RUMBDEF_2
#undef RUMBDEF_3
// FIXME: stair jank rumble should be greyed out if its disabled, but menus suck butt!
#define OP_JOYRUMBLEMENU(pnum) \
{IT_HEADER, NULL, "Global", NULL, 7}, \
{IT_STRING | IT_CVAR, NULL, "Controller Rumble" , &cv_rumble[pnum] , 15}, \
{IT_STRING | IT_CVAR, NULL, "Controller Rumble Strength" , &cv_rumble_strength[pnum] , 20}, \
{IT_HEADER, NULL, "Rumble Types", NULL, 27}, \
{IT_STRING | IT_CVAR, NULL, "Spinout" , &cv_rumble_spinout[pnum] , 35}, \
{IT_STRING | IT_CVAR, NULL, "Sneaker Boost" , &cv_rumble_sneakerboost[pnum] , 40}, \
{IT_STRING | IT_CVAR, NULL, "Offroad" , &cv_rumble_offroad[pnum] , 45}, \
{IT_STRING | IT_CVAR, NULL, "Banana Dragging" , &cv_rumble_bananadrag[pnum] , 50}, \
{IT_STRING | IT_CVAR, NULL, "Stair Jank" , &cv_rumble_stairjank[pnum] , 55}, \
{IT_STRING | IT_CVAR, NULL, "Brake Drift" , &cv_rumble_brakedrift[pnum] , 60}, \
{IT_STRING | IT_CVAR, NULL, "Drift Charge" , &cv_rumble_driftcharge[pnum] , 65}, \
static menuitem_t OP_Joystick1RumbleMenu[] =
{
OP_JOYRUMBLEMENU(0)
};
static menuitem_t OP_Joystick2RumbleMenu[] =
{
OP_JOYRUMBLEMENU(1)
};
static menuitem_t OP_Joystick3RumbleMenu[] =
{
OP_JOYRUMBLEMENU(2)
};
static menuitem_t OP_Joystick4RumbleMenu[] =
{
OP_JOYRUMBLEMENU(3)
};
static menuitem_t OP_JoystickSetMenu[] =
{
{IT_CALL | IT_NOTHING, "None", NULL, M_AssignJoystick, LINEHEIGHT+5},
@@ -1736,6 +1784,7 @@ static menuitem_t OP_SaturnMenu[] =
{IT_SUBMENU|IT_STRING, NULL, "Saturn Hud...", &OP_SaturnHudDef, 140},
{IT_SUBMENU|IT_STRING, NULL, "Sprite Distortion...", &OP_PlayerDistortDef, 145},
{IT_SUBMENU|IT_STRING, NULL, "Saturn Credits", &OP_SaturnCreditsDef, 150}, // uwu
{IT_STRING|IT_CALL, NULL, "Report an Issue", M_SaturnReportIssue, 155}
};
static const char* OP_SaturnTooltips[] =
@@ -1759,6 +1808,7 @@ static const char* OP_SaturnTooltips[] =
"Options for Saturn specific HUD things.",
"Options for sprite distortion effects.",
"See the people who helped make this project possible!",
"Noticed a bug, have a Suggestion or other Feedback?\nFeel free to tell us!",
};
enum
@@ -1780,6 +1830,7 @@ enum
sm_hud,
sm_distortionmenu,
sm_credits,
sm_issue,
};
static menuitem_t OP_PlayerDistortMenu[] =
@@ -2530,6 +2581,11 @@ menu_t OP_Joystick2Def = DEFAULTSCROLLSTYLE("M_CONTRO", OP_Joystick2Menu, &OP
menu_t OP_Joystick3Def = DEFAULTSCROLLSTYLE("M_CONTRO", OP_Joystick3Menu, &OP_AllControlsDef, 30, 36, NULL);
menu_t OP_Joystick4Def = DEFAULTSCROLLSTYLE("M_CONTRO", OP_Joystick4Menu, &OP_AllControlsDef, 30, 36, NULL);
menu_t OP_Joystick1RumbleDef = DEFAULTSCROLLSTYLE("M_CONTRO", OP_Joystick1RumbleMenu, &OP_Joystick1Def, 30, 36, NULL);
menu_t OP_Joystick2RumbleDef = DEFAULTSCROLLSTYLE("M_CONTRO", OP_Joystick2RumbleMenu, &OP_Joystick2Def, 30, 36, NULL);
menu_t OP_Joystick3RumbleDef = DEFAULTSCROLLSTYLE("M_CONTRO", OP_Joystick3RumbleMenu, &OP_Joystick3Def, 30, 36, NULL);
menu_t OP_Joystick4RumbleDef = DEFAULTSCROLLSTYLE("M_CONTRO", OP_Joystick4RumbleMenu, &OP_Joystick4Def, 30, 36, NULL);
menu_t OP_JoystickSetDef =
{
"M_CONTRO",
+19 -18
View File
@@ -515,8 +515,8 @@ static boolean M_BackupConfig(const char *filename)
{
char backupfile[MAX_WADPATH+4];
snprintf(backupfile, sizeof backupfile, "%s.bak", filename);
backupfile[sizeof backupfile - 1] = '\0';
snprintf(backupfile, sizeof(backupfile), "%s.bak", filename);
backupfile[sizeof(backupfile) - 1] = '\0';
FILE *config = fopen(filename, "r");
@@ -766,27 +766,27 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png
}
if (gamestate == GS_LEVEL)
snprintf(maptext, 8, "%s", G_BuildMapName(gamemap));
snprintf(maptext, sizeof(maptext), "%s", G_BuildMapName(gamemap));
else
snprintf(maptext, 8, "Unknown");
snprintf(maptext, sizeof(maptext), "Unknown");
if (gamestate == GS_LEVEL && mapheaderinfo[gamemap-1]->lvlttl[0] != '\0')
snprintf(lvlttltext, 48, "%s%s%s",
snprintf(lvlttltext, sizeof(lvlttltext), "%s%s%s",
mapheaderinfo[gamemap-1]->lvlttl,
(strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) ? va(" %s",mapheaderinfo[gamemap-1]->zonttl) : // SRB2kart
((mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE"),
(strlen(mapheaderinfo[gamemap-1]->actnum) > 0) ? va(" %s",mapheaderinfo[gamemap-1]->actnum) : "");
else
snprintf(lvlttltext, 48, "Unknown");
snprintf(lvlttltext, sizeof(lvlttltext), "Unknown");
if (gamestate == GS_LEVEL && players[displayplayers[0]].mo)
snprintf(locationtxt, 40, "X:%d Y:%d Z:%d A:%d",
snprintf(locationtxt, sizeof(locationtxt), "X:%d Y:%d Z:%d A:%d",
players[displayplayers[0]].mo->x>>FRACBITS,
players[displayplayers[0]].mo->y>>FRACBITS,
players[displayplayers[0]].mo->z>>FRACBITS,
FixedInt(AngleFixed(players[displayplayers[0]].mo->angle)));
else
snprintf(locationtxt, 40, "Unknown");
snprintf(locationtxt, sizeof(locationtxt), "Unknown");
memset(png_infotext, 0x00, sizeof(png_infotext));
@@ -1253,7 +1253,6 @@ boolean M_ScreenshotResponder(event_t *ev)
return true;
}
void M_ScrollString(const char name[], size_t len, char result[], size_t maxlen, tic_t timer)
{
// How much should we scroll. Not sure why +1 is needed, but without it this function skips 2
@@ -1261,7 +1260,7 @@ void M_ScrollString(const char name[], size_t len, char result[], size_t maxlen,
const size_t amount = len - maxlen + 1;
// Note: anything above 17 will cause zero division
const size_t MAXSPEED = 6;
static const size_t MAXSPEED = 6;
const tic_t t = timer / (35/min(amount, MAXSPEED));
const size_t state = (t / amount) % 4;
@@ -1296,7 +1295,7 @@ void M_ScrollString(const char name[], size_t len, char result[], size_t maxlen,
}
// Technically not necessary, since it gets set again after function call, but just in case
result[maxlen] = 0;
result[maxlen-1] = '\0';
}
void M_MinimapGenerate(void)
@@ -1394,7 +1393,7 @@ char *va(const char *format, ...)
static char string[1024];
va_start(argptr, format);
vsnprintf(string, 1024, format, argptr);
vsnprintf(string, sizeof(string), format, argptr);
va_end(argptr);
return string;
@@ -1708,7 +1707,7 @@ const char * M_Ftrim(double f)
int i;
/* I know I said it's the default, but just in case... */
sprintf(dig, "%.6f", fabs(modf(f, &f)));
snprintf(dig, sizeof(dig), "%.6f", fabs(modf(f, &f)));
/* trim trailing zeroes */
for (i = strlen(dig)-1; dig[i] == '0'; --i)
@@ -1736,6 +1735,7 @@ UINT8 M_CountBits(UINT32 num, UINT8 size)
const char *GetRevisionString(void)
{
static char rev[9] = {0};
if (rev[0])
return rev;
@@ -1743,6 +1743,7 @@ const char *GetRevisionString(void)
strncpy(rev, comprevision, 7);
else
snprintf(rev, 7, "r%s", comprevision);
rev[7] = '\0';
return rev;
@@ -1814,35 +1815,35 @@ TMatrix *RotateZMatrix(angle_t rad)
char *sizeu1(size_t num)
{
static char sizeu1_buf[28];
sprintf(sizeu1_buf, "%"PRIdS, num);
snprintf(sizeu1_buf, sizeof(sizeu1_buf), "%" PRIdS, num);
return sizeu1_buf;
}
char *sizeu2(size_t num)
{
static char sizeu2_buf[28];
sprintf(sizeu2_buf, "%"PRIdS, num);
snprintf(sizeu2_buf, sizeof(sizeu2_buf), "%" PRIdS, num);
return sizeu2_buf;
}
char *sizeu3(size_t num)
{
static char sizeu3_buf[28];
sprintf(sizeu3_buf, "%"PRIdS, num);
snprintf(sizeu3_buf, sizeof(sizeu3_buf), "%" PRIdS, num);
return sizeu3_buf;
}
char *sizeu4(size_t num)
{
static char sizeu4_buf[28];
sprintf(sizeu4_buf, "%"PRIdS, num);
snprintf(sizeu4_buf, sizeof(sizeu4_buf), "%" PRIdS, num);
return sizeu4_buf;
}
char *sizeu5(size_t num)
{
static char sizeu5_buf[28];
sprintf(sizeu5_buf, "%"PRIdS, num);
snprintf(sizeu5_buf, sizeof(sizeu5_buf), "%" PRIdS, num);
return sizeu5_buf;
}
+41 -56
View File
@@ -169,14 +169,14 @@ perfstatrow_t gamelogic_rows[] = {
};
perfstatrow_t thinkercount_rows[] = {
{"thnkers", "Thinkers: ", &ps_thinkercount, PS_LEVEL},
{" mobjs ", " Mobjs: ", &ps_mobjcount, PS_LEVEL},
{"thnkers" , "Thinkers: ", &ps_thinkercount, PS_LEVEL},
{" mobjs " , " Mobjs: ", &ps_mobjcount, PS_LEVEL},
{" regular", " Regular: ", &ps_regularcount, PS_LEVEL},
{" scenery", " Scenery: ", &ps_scenerycount, PS_LEVEL},
{" nothink", " Nothink: ", &ps_nothinkcount, PS_HIDE_ZERO|PS_LEVEL},
{" precip ", " Precipitation: ", &ps_precipcount, PS_LEVEL},
{" other ", " Other: ", &ps_otherthcount, PS_LEVEL},
{" remove ", " Pending removal:", &ps_removecount, PS_LEVEL},
{" precip " , " Precipitation: ", &ps_precipcount, PS_LEVEL},
{" other " , " Other: ", &ps_otherthcount, PS_LEVEL},
{" remove " , " Pending removal:", &ps_removecount, PS_LEVEL},
{}
};
@@ -606,7 +606,9 @@ static void PS_CountThinkers(void)
else if (thinker->function == (actionf_p1)P_MobjThinker)
{
mobj_t *mobj = (mobj_t*)thinker;
ps_mobjcount.value.i++;
if (mobj->flags & MF_NOTHINK)
ps_nothinkcount.value.i++;
else if (mobj->flags & MF_SCENERY)
@@ -625,49 +627,17 @@ static void PS_CountThinkers(void)
ps_precipcount.value.i++;
}
/*for (i = 0; i < NUM_THINKERLISTS; i++)
{
for (thinker = thlist[i].next; thinker != &thlist[i]; thinker = thinker->next)
{
ps_thinkercount.value.i++;
if (thinker->function == (actionf_p1)P_RemoveThinkerDelayed)
ps_removecount.value.i++;
else if (i == THINK_POLYOBJ)
ps_polythcount.value.i++;
else if (i == THINK_MAIN)
ps_mainthcount.value.i++;
else if (i == THINK_MOBJ)
{
if (thinker->function == (actionf_p1)P_MobjThinker)
{
mobj_t *mobj = (mobj_t*)thinker;
ps_mobjcount.value.i++;
if (mobj->flags & MF_NOTHINK)
ps_nothinkcount.value.i++;
else if (mobj->flags & MF_SCENERY)
ps_scenerycount.value.i++;
else
ps_regularcount.value.i++;
}
}
else if (i == THINK_DYNSLOPE)
ps_dynslopethcount.value.i++;
else if (i == THINK_PRECIP)
ps_precipcount.value.i++;
}
}*/
}
// Update all metrics that are calculated on every tick.
void PS_UpdateTickStats(void)
{
if (cv_perfstats.value == 1 && cv_ps_samplesize.value > 1)
if (cv_perfstats.value == PS_RENDER && cv_ps_samplesize.value > 1)
{
PS_UpdateRowHistories(gamelogicbrief_row, false);
}
if (cv_perfstats.value == 2)
if (cv_perfstats.value == PS_LOGIC)
{
if (PS_IsLevelActive())
{
@@ -692,25 +662,25 @@ void PS_UpdateTickStats(void)
if (cv_ps_samplesize.value > 1)
{
if (cv_perfstats.value >= 3 && PS_IsLevelActive())
if (cv_perfstats.value >= PS_THINKFRAME && PS_IsLevelActive())
{
int i;
switch (cv_perfstats.value)
{
case 3:
case PS_THINKFRAME:
for (i = 0; i < thinkframe_hooks_length; i++)
{
PS_UpdateMetricHistory(&thinkframe_hooks[i].time_taken, true, false);
}
break;
case 4:
case PS_PRETHINKFRAME:
for (i = 0; i < prethinkframe_hooks_length; i++)
{
PS_UpdateMetricHistory(&prethinkframe_hooks[i].time_taken, true, false);
}
break;
case 5:
case PS_POSTTHINKFRAME:
for (i = 0; i < postthinkframe_hooks_length; i++)
{
PS_UpdateMetricHistory(&postthinkframe_hooks[i].time_taken, true, false);
@@ -720,6 +690,7 @@ void PS_UpdateTickStats(void)
break;
}
}
if (cv_perfstats.value)
{
ps_tick_index++;
@@ -750,7 +721,7 @@ static void PS_DrawDescriptorHeader(void)
int samples_left = max(ps_frame_samples_left, ps_tick_samples_left);
int x, y;
if (cv_perfstats.value >= 3)
if (cv_perfstats.value >= PS_THINKFRAME)
{
x = 2;
y = 0;
@@ -866,20 +837,19 @@ static void draw_think_frame_stats(int hook_length, ps_hookinfo_t *hook)
last_mod_name[0] = '\0';
INT32 total = 0;
//Decide page length based and drawn text on choosen thinker type
// Decide page length based and drawn text on choosen thinker type
switch (cv_perfstats.value)
{
case 3:
case PS_THINKFRAME:
{
maxpage = thinkframe_hooks_length/PAGE_ENTRIES + 1;
page = max(1, min(cv_ps_thinkframe_page.value, maxpage));
pagestart = min((page - 1)*PAGE_ENTRIES, thinkframe_hooks_length);
pageend = min(pagestart + PAGE_ENTRIES, thinkframe_hooks_length);
V_DrawSmallString(MAX_X-50, MAX_Y+2*HEIGHT, V_MONOSPACE | V_GREENMAP, "ThinkFrame");
}
break;
case 4:
case PS_PRETHINKFRAME:
{
maxpage = prethinkframe_hooks_length/PAGE_ENTRIES + 1;
page = max(1, min(cv_ps_thinkframe_page.value, maxpage));
@@ -888,7 +858,7 @@ static void draw_think_frame_stats(int hook_length, ps_hookinfo_t *hook)
V_DrawSmallString(MAX_X-60, MAX_Y+2*HEIGHT, V_MONOSPACE | V_GREENMAP, "PreThinkFrame");
}
break;
case 5:
case PS_POSTTHINKFRAME:
{
maxpage = postthinkframe_hooks_length/PAGE_ENTRIES + 1;
page = max(1, min(cv_ps_thinkframe_page.value, maxpage));
@@ -976,7 +946,22 @@ static void draw_think_frame_stats(int hook_length, ps_hookinfo_t *hook)
void PS_ThinkFrame_Page_OnChange(void)
{
int maxpage = thinkframe_hooks_length/PAGE_ENTRIES + 1;
int maxpage = 0;
switch (cv_perfstats.value)
{
case PS_THINKFRAME:
maxpage = thinkframe_hooks_length/PAGE_ENTRIES + 1;
break;
case PS_PRETHINKFRAME:
maxpage = prethinkframe_hooks_length/PAGE_ENTRIES + 1;
break;
case PS_POSTTHINKFRAME:
maxpage = postthinkframe_hooks_length/PAGE_ENTRIES + 1;
break;
default:
break;
}
if (cv_ps_thinkframe_page.value > maxpage)
CV_StealthSetValue(&cv_ps_thinkframe_page, maxpage);
@@ -1009,18 +994,18 @@ static void PS_DrawPostThinkFrameStats(void)
void M_DrawPerfStats(void)
{
if (cv_perfstats.value == 1) // rendering
if (cv_perfstats.value == PS_RENDER) // rendering
{
PS_UpdateFrameStats();
PS_DrawRenderStats();
}
else if (cv_perfstats.value == 2) // logic
else if (cv_perfstats.value == PS_LOGIC) // logic
{
// PS_UpdateTickStats is called in TryRunTics, since otherwise it would miss
// tics when frame skips happen
PS_DrawGameLogicStats();
}
else if (cv_perfstats.value >= 3) // lua thinkframe
else if (cv_perfstats.value >= PS_THINKFRAME) // lua thinkframe
{
if (!PS_IsLevelActive())
return;
@@ -1037,13 +1022,13 @@ void M_DrawPerfStats(void)
switch (cv_perfstats.value)
{
case 3:
case PS_THINKFRAME:
PS_DrawThinkFrameStats();
break;
case 4:
case PS_PRETHINKFRAME:
PS_DrawPreThinkFrameStats();
break;
case 5:
case PS_POSTTHINKFRAME:
PS_DrawPostThinkFrameStats();
break;
default:
+10
View File
@@ -26,6 +26,16 @@ typedef struct
void *history;
} ps_metric_t;
typedef enum
{
PS_OFF = 0,
PS_RENDER,
PS_LOGIC,
PS_THINKFRAME,
PS_PRETHINKFRAME,
PS_POSTTHINKFRAME
} ps_types_t;
typedef struct
{
ps_metric_t time_taken;
+2 -2
View File
@@ -238,8 +238,8 @@ void M_TextInputClear(textinput_t *input)
void M_TextInputSetString(textinput_t *input, const char *c)
{
memset(input->buffer, 0, input->buffer_size);
strncpy(input->buffer, c, input->buffer_size);
strncpy(input->buffer, c, input->buffer_size-1);
input->buffer[input->buffer_size-1] = '\0';
input->cursor = input->select = input->length = strlen(input->buffer);
}
+718 -346
View File
File diff suppressed because it is too large. Load diff
+31 -37
View File
@@ -107,6 +107,9 @@ void P_DoNightsScore(player_t *player)
dummymo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z+player->mo->height/2, MT_NIGHTSCORE);
if (P_MobjWasRemovedCompat(dummymo))
return;
if (player->bot)
player = &players[consoleplayer];
@@ -589,7 +592,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
special->momx = special->momy = special->momz = 0;
P_GivePlayerRings(player, 1);
if (UNLIKELY((maptol & TOL_NIGHTS) && special->type != MT_FLINGRING))
if (nightsmode && special->type != MT_FLINGRING)
P_DoNightsScore(player);
break;
@@ -601,7 +604,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
special->momx = special->momy = 0;
P_GivePlayerRings(player, 1);
if (UNLIKELY((maptol & TOL_NIGHTS) && special->type != MT_FLINGCOIN))
if (nightsmode && special->type != MT_FLINGCOIN)
P_DoNightsScore(player);
break;
case MT_BLUEBALL:
@@ -617,7 +620,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
else
special->scalespeed = 4*FRACUNIT/5;
if (UNLIKELY(maptol & TOL_NIGHTS))
if (nightsmode)
P_DoNightsScore(player);
break;
case MT_AUTOPICKUP:
@@ -831,7 +834,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{
S_StartSound(toucher, special->info->seesound);
if (UNLIKELY(player->pflags & PF_NIGHTSMODE))
if (nightsplayer(player))
{
player->bumpertime = TICRATE/2;
if (special->threshold > 0)
@@ -883,18 +886,20 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
break;
case MT_HOOPCOLLIDE:
// This produces a kind of 'domino effect' with the hoop's pieces.
for (; special->hprev != NULL; special = special->hprev); // Move to the first sprite in the hoop
for (; special != NULL && special->hprev != NULL; special = special->hprev); // Move to the first sprite in the hoop
i = 0;
for (; special->hnext != NULL && special->type == MT_HOOP; special = special->hnext)
for (; special != NULL && special->type == MT_HOOP; special = special->hnext)
{
if (!P_MobjWasRemoved(special->target))
if (!P_MobjWasRemoved(special))
{
special->fuse = 11;
special->movedir = i;
special->extravalue1 = special->target->extravalue1;
special->extravalue2 = special->target->extravalue2;
special->target->threshold = 4242;
if (!P_MobjWasRemoved(special->target))
{
special->extravalue1 = special->target->extravalue1;
special->extravalue2 = special->target->extravalue2;
special->target->threshold = 4242;
}
}
i++;
}
@@ -1131,7 +1136,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
S_StartSound(toucher, special->info->painsound);
return;
}
else if (UNLIKELY((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING))
else if ((nightsplayer(player) && (player->pflags & PF_DRILLING)) || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING))
|| player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object?
{
// Shatter the shield!
@@ -1466,11 +1471,7 @@ static void P_UpdateRemovedOrbital(mobj_t *target, mobj_t *inflictor, mobj_t *so
{
// SRB2kart
// I wish I knew a better way to do this
#ifndef COMPAT_VANILLA
if (!P_MobjWasRemoved(target->target) && target->target->player && !P_MobjWasRemoved(target->target->player->mo))
#else
if (target->target && target->target->player && target->target->player->mo)
#endif
if (!P_MobjWasRemovedCompat(target->target) && target->target->player && !P_MobjWasRemovedCompat(target->target->player->mo))
{
if (target->target->player->kartstuff[k_eggmanheld] && target->type == MT_EGGMANITEM_SHIELD)
target->target->player->kartstuff[k_eggmanheld] = 0;
@@ -1483,11 +1484,7 @@ static void P_UpdateRemovedOrbital(mobj_t *target, mobj_t *inflictor, mobj_t *so
{
if (target->movedir != 0 && target->movedir < (UINT16)target->target->player->kartstuff[k_itemamount])
{
#ifndef COMPAT_VANILLA
if (!P_MobjWasRemoved(target->target->hnext))
#else
if (target->target->hnext)
#endif
if (!P_MobjWasRemovedCompat(target->target->hnext))
K_KillBananaChain(target->target->hnext, inflictor, source);
target->target->player->kartstuff[k_itemamount] = 0;
@@ -2019,7 +2016,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
}
}
static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
static boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
{
player_t *player = target->player;
(void)damage; //unused parm
@@ -2245,11 +2242,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return false;
// well no clue but this may happen ig
#ifndef COMPAT_VANILLA
if (P_MobjWasRemoved(target))
#else
if (!target)
#endif
if (P_MobjWasRemovedCompat(target))
return false;
if (target->health <= 0)
@@ -2266,7 +2259,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return false;
}
if (source && source->player && source->player->spectator)
if (!P_MobjWasRemovedCompat(source) && source->player && source->player->spectator)
return false;
}
@@ -2360,11 +2353,11 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (player->exiting)
return false;
if (UNLIKELY(!(target->player->pflags & (PF_NIGHTSMODE|PF_NIGHTSFALL)) && (maptol & TOL_NIGHTS)))
if (UNLIKELY(!(target->player->pflags & (PF_NIGHTSMODE|PF_NIGHTSFALL)) && nightsmode))
return false;
}
if (UNLIKELY(player->pflags & PF_NIGHTSMODE)) // NiGHTS damage handling
if (nightsplayer(player)) // NiGHTS damage handling
{
if (!force)
{
@@ -2609,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 (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
if (!twodmo(player->mo))
mo->momy = FixedMul(FINESINE(fa),ns);
P_SetObjectMomZ(mo, 8*FRACUNIT, false);
@@ -2633,7 +2626,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
ns = FixedMul(momxy, mo->scale);
mo->momx = FixedMul(FINECOSINE(fa),ns);
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
if (!twodmo(player->mo))
mo->momy = FixedMul(FINESINE(fa),ns);
ns = momz;
@@ -2642,6 +2635,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
if (i & 1)
P_SetObjectMomZ(mo, ns, true);
}
if (player->mo->eflags & MFE_VERTICALFLIP)
mo->momz *= -1;
}
@@ -2740,7 +2734,7 @@ void P_PlayerWeaponPanelBurst(player_t *player)
ns = FixedMul(3*FRACUNIT, mo->scale);
mo->momx = FixedMul(FINECOSINE(fa),ns);
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
if (!twodmo(player->mo))
mo->momy = FixedMul(FINESINE(fa),ns);
P_SetObjectMomZ(mo, 4*FRACUNIT, false);
@@ -2824,7 +2818,7 @@ void P_PlayerWeaponAmmoBurst(player_t *player)
ns = FixedMul(2*FRACUNIT, mo->scale);
mo->momx = FixedMul(FINECOSINE(fa), ns);
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
if (!twodmo(player->mo))
mo->momy = FixedMul(FINESINE(fa),ns);
P_SetObjectMomZ(mo, 3*FRACUNIT, false);
@@ -2940,7 +2934,7 @@ void P_PlayerEmeraldBurst(player_t *player, boolean toss)
momx = FixedMul(FINECOSINE(fa), ns);
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
if (!twodmo(player->mo))
momy = FixedMul(FINESINE(fa),ns);
else
momy = 0;
@@ -2997,7 +2991,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 (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
if (!twodmo(player->mo))
flag->momy = FixedMul(FINESINE(fa), FixedMul(6*FRACUNIT, player->mo->scale));
}
+18 -2
View File
@@ -59,8 +59,12 @@ extern "C" {
#define AIMINGTOSLOPE(aiming) FINESINE((aiming>>ANGLETOFINESHIFT) & FINEMASK)
#define mariomode (maptol & TOL_MARIO)
#define twodlevel (maptol & TOL_2D)
// unused modes, kept for compat
#define nightsmode (UNLIKELY(maptol & TOL_NIGHTS))
#define nightsplayer(player) (UNLIKELY((player)->pflags & PF_NIGHTSMODE))
#define mariomode (UNLIKELY(maptol & TOL_MARIO))
#define twodlevel (UNLIKELY(maptol & TOL_2D))
#define twodmo(mobj) (UNLIKELY(twodlevel || ((mobj)->flags2 & MF2_TWOD)))
//
// P_TICK
@@ -287,6 +291,17 @@ FUNCINLINE static ATTRINLINE boolean P_MobjWasRemoved(const mobj_t *mobj)
return (!mobj || mobj->thinker.function != (actionf_p1)P_MobjThinker);
}
// stupid, but kart allows mobjs that are marked to be removed to be accessed and modified in many cases
// so can only check if its not NULL in vanilla compat mode
FUNCINLINE static ATTRINLINE boolean P_MobjWasRemovedCompat(const mobj_t *mobj)
{
#ifdef PHOBOS_BUILD
return P_MobjWasRemoved(mobj);
#else
return !mobj;
#endif
}
fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
#define P_GetFloorZ(mobj, sector, x, y, line) P_MobjFloorZ(mobj, sector, NULL, x, y, line, false, false)
@@ -403,6 +418,7 @@ boolean P_CheckSector(sector_t *sector, boolean crunch);
void P_DelSeclist(msecnode_t *node);
void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y);
void P_Initsecnode(void);
void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist);
+119 -63
View File
@@ -136,14 +136,17 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic
return false;
// Spectators don't trigger springs.
if (object->player && object->player->spectator)
return false;
if (UNLIKELY(object->player && (object->player->pflags & PF_NIGHTSMODE)))
if (object->player)
{
/*Someone want to make these work like bumpers?*/
return false;
// Spectators don't trigger springs.
if (object->player->spectator)
return false;
if (nightsplayer(object->player))
{
/*Someone want to make these work like bumpers?*/
return false;
}
}
object->standingslope = NULL; // Okay, now we can't return - no launching off at silly angles for you.
@@ -160,10 +163,15 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
if (spring->eflags & MFE_VERTICALFLIP)
vertispeed *= -1;
// Vertical springs teleport you on TOP of them.
if (vertispeed > 0)
{
object->z = spring->z + spring->height + 1;
}
else if (vertispeed < 0)
{
object->z = spring->z - object->height - 1;
}
else
{
// Horizontal springs teleport you in FRONT of them.
@@ -215,7 +223,9 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
if (object->player)
{
if (spring->flags & MF_ENEMY) // Spring shells
{
P_SetTarget(&spring->target, object);
}
if (horizspeed && object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0)
{
@@ -235,12 +245,12 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
{
player_t *p = object->player; // will be NULL if not a player
player_t *player = object->player; // will be NULL if not a player
fixed_t zdist; // distance between bottoms
fixed_t speed = spring->info->mass; // conveniently, both fans and gas jets use this for the vertical thrust
SINT8 flipval = P_MobjFlip(spring); // virtually everything here centers around the thruster's gravity, not the object's!
if (p && object->state == &states[object->info->painstate]) // can't use fans and gas jets when player is in pain!
if (player && object->state == &states[object->info->painstate]) // can't use fans and gas jets when player is in pain!
return;
// is object's top below thruster's position? if not, calculate distance between their bottoms
@@ -266,7 +276,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
break;
if (flipval*object->momz >= FixedMul(speed, spring->scale)) // if object's already moving faster than your best, don't bother
break;
if (p && (p->climbing || p->pflags & PF_GLIDING)) // doesn't affect Knux when he's using his abilities!
if (player && (player->climbing || player->pflags & PF_GLIDING)) // doesn't affect Knux when he's using his abilities!
break;
object->momz += flipval*FixedMul(speed/4, spring->scale);
@@ -312,13 +322,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing == tmthing)
return true;
// Ignore... things.
if (!tmthing || P_MobjWasRemoved(thing))
return true;
I_Assert(!P_MobjWasRemoved(tmthing));
I_Assert(!P_MobjWasRemoved(thing));
// Ignore... things.
if (P_MobjWasRemovedCompat(tmthing) || P_MobjWasRemoved(thing))
return true;
// Ignore spectators
if ((tmthing->player && tmthing->player->spectator)
|| (thing->player && thing->player->spectator))
@@ -350,12 +360,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
}
#endif
if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE)) || (thing->flags & MF_NOCLIPTHING))
if ((thing->flags & MF_NOCLIPTHING) || !(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE)))
return true;
// Don't collide with your buddies while NiGHTS-flying.
if (UNLIKELY(tmthing->player && thing->player && (maptol & TOL_NIGHTS)
&& ((tmthing->player->pflags & PF_NIGHTSMODE) || (thing->player->pflags & PF_NIGHTSMODE))))
if (nightsmode &&
tmthing->player && thing->player &&
(nightsplayer(tmthing->player) || nightsplayer(thing->player)))
return true;
blockdist = thing->radius + tmthing->radius;
@@ -1817,14 +1828,14 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
delta1 = abs(thing->z - midheight);
delta2 = abs(thingtop - midheight);
if (topheight > tmfloorz && delta1 < delta2
if ((topheight > tmfloorz) && (delta1 < delta2)
&& !(rover->flags & FF_REVERSEPLATFORM))
{
tmfloorz = tmdropoffz = topheight;
tmfloorslope = *rover->t_slope;
}
if (bottomheight < tmceilingz && delta1 >= delta2
if ((bottomheight < tmceilingz) && (delta1 >= delta2)
&& !(rover->flags & FF_PLATFORM)
&& !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE)))
{
@@ -1879,8 +1890,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
po->validcount = validcount;
if (!P_BBoxInsidePolyobj(po, tmbbox)
|| !(po->flags & POF_SOLID))
if (!(po->flags & POF_SOLID) || !P_BBoxInsidePolyobj(po, tmbbox))
{
plink = (polymaplink_t *)(plink->link.next);
continue;
@@ -2016,7 +2026,7 @@ static boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
mapcampointer = thiscam;
if (UNLIKELY(GETSECSPECIAL(newsec->special, 4) == 12))
if (newsec->flags & SF_NOCLIPCAMERA)
{ // Camera noclip on entire sector.
tmfloorz = tmdropoffz = thiscam->z;
tmceilingz = tmdrpoffceilz = thiscam->z + thiscam->height;
@@ -2058,7 +2068,7 @@ static boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
fixed_t topheight, bottomheight, midheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL)
|| UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
|| rover->master->frontsector->flags & SF_NOCLIPCAMERA)
continue;
topheight = P_CameraGetFOFTopZ(thiscam, newsec, rover, x, y, NULL);
@@ -2125,7 +2135,7 @@ static boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
po->validcount = validcount;
if (!P_PointInsidePolyobj(po, x, y) || !(po->flags & POF_SOLID))
if (!(po->flags & POF_SOLID) || !P_PointInsidePolyobj(po, x, y))
{
plink = (polymaplink_t *)(plink->link.next);
continue;
@@ -2134,7 +2144,7 @@ static boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
// We're inside it! Yess...
polysec = po->lines[0]->backsector;
if (UNLIKELY(GETSECSPECIAL(polysec->special, 4) == 12))
if (polysec->flags & SF_NOCLIPCAMERA)
{ // Camera noclip polyobj.
plink = (polymaplink_t *)(plink->link.next);
continue;
@@ -2599,36 +2609,10 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
// sound does not work out all that well for kart maps
// best i can do...
if (cv_stairjanksfx.value)
if (cv_stairjank.value && cv_stairjanksfx.value)
S_StartSoundAtVolume(thing, (thing->player->stairjank >= 8 ? sfx_s23b : sfx_s268), 192); // dont blast this at full volume lul
//if (!thing->player->stairjank)
{
// 90 degrees to direction you're facing
fixed_t dirx = -FINESINE(thing->angle>>ANGLETOFINESHIFT);
fixed_t diry = FINECOSINE(thing->angle>>ANGLETOFINESHIFT);
fixed_t offset = thing->radius;
if (leveltime % 8 < 4)
{
dirx = -dirx;
diry = -diry;
}
mobj_t * spark = P_SpawnMobj(thing->x + FixedMul(dirx, offset), thing->y + FixedMul(diry, offset), thing->z, MT_DRIFTDUST);
spark->momx = FixedMul(dirx, FRACUNIT) + (6 + ((int)leveltime % 5))*(thing->momx)/10;
spark->momy = FixedMul(diry, FRACUNIT) + (6 + ((int)leveltime % 5))*(thing->momy)/10;
spark->momz = 5*FRACUNIT;
spark->scale = mapobjectscale/5;
spark->destscale = mapobjectscale/2;
spark->islocal = true;
//spark->fuse = 9;
spark->color = SKINCOLOR_WHITE;
//spark->cusval = K_StairJankFlip(ANGLE_90);
P_SetTarget(&spark->target, thing);
//P_SetTarget(&spark->owner, thing);
//spark->renderflags |= RF_REDUCEVFX;
}
// Can't spawn things during P_TryMove, because global variables :)
thing->player->stairjank = 9;
//thing->player->stairjank = 17;
@@ -2684,7 +2668,7 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
if (tmfloorz - thing->z > maxstep)
return false; // too big a step up
}
} while(tryx != x || tryy != y);
} while (tryx != x || tryy != y);
// the move is ok,
// so link the thing into its new position
@@ -3179,6 +3163,9 @@ void P_SlideMove(mobj_t *mo, boolean forceslide)
INT16 hitcount = 0;
boolean success = false;
if (P_MobjWasRemovedCompat(mo))
return;
if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height)
{
// Don't mess with your momentum if it's a pushable object. Pushables do their own crazy things already.
@@ -3215,6 +3202,9 @@ void P_SlideMove(mobj_t *mo, boolean forceslide)
bestslideline = NULL;
retry:
if (P_MobjWasRemovedCompat(mo))
return;
if (++hitcount == 3)
goto stairstep; // don't loop forever
@@ -3263,7 +3253,13 @@ retry:
// the move must have hit the middle, so stairstep
stairstep:
if (!P_TryMove(mo, mo->x, mo->y + mo->momy, true)) //Allow things to drop off.
{
if (P_MobjWasRemovedCompat(mo))
return;
P_TryMove(mo, mo->x + mo->momx, mo->y, true);
}
return;
}
@@ -3275,7 +3271,12 @@ stairstep:
newy = FixedMul(mo->momy, bestslidefrac);
if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true))
{
goto stairstep;
}
if (P_MobjWasRemovedCompat(mo))
return;
}
// Now continue along the wall.
@@ -3294,7 +3295,7 @@ stairstep:
if (bestslideline != NULL)
P_HitSlideLine(bestslideline); // clip the moves
if (UNLIKELY((twodlevel || (mo->flags2 & MF2_TWOD)) && mo->player))
if (twodmo(mo) && mo->player)
{
mo->momx = tmxmove;
tmymove = 0;
@@ -3346,8 +3347,11 @@ stairstep:
goto retry;
}
if (P_MobjWasRemovedCompat(mo))
return;
success = true;
} while(tmxmove || tmymove);
} while (tmxmove || tmymove);
}
//
@@ -3360,12 +3364,18 @@ void P_BouncePlayerMove(mobj_t *mo)
{
fixed_t leadx, leady;
fixed_t trailx, traily;
fixed_t mmomx = 0, mmomy = 0;
fixed_t oldmomx = mo->momx, oldmomy = mo->momy;
fixed_t mmomx, mmomy;
fixed_t oldmomx, oldmomy;
if (!mo->player)
if (P_MobjWasRemovedCompat(mo))
return;
if (mo->player == NULL)
return;
oldmomx = mo->momx;
oldmomy = mo->momy;
if (mo->player->spectator)
{
P_SlideMove(mo, true);
@@ -3454,6 +3464,9 @@ void P_BouncePlayerMove(mobj_t *mo)
if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true))
{
if (P_MobjWasRemovedCompat(mo))
return;
P_TryMove(mo, mo->x - oldmomx, mo->y - oldmomy, true);
}
}
@@ -3471,6 +3484,9 @@ void P_BounceMove(mobj_t *mo)
INT32 hitcount;
fixed_t mmomx = 0, mmomy = 0;
if (P_MobjWasRemovedCompat(mo))
return;
if (mo->player)
{
P_BouncePlayerMove(mo);
@@ -3487,6 +3503,9 @@ void P_BounceMove(mobj_t *mo)
hitcount = 0;
retry:
if (P_MobjWasRemovedCompat(mo))
return;
if (++hitcount == 3)
goto bounceback; // don't loop forever
@@ -3545,7 +3564,12 @@ bounceback:
newy = FixedMul(mmomy, bestslidefrac);
if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true))
{
if (P_MobjWasRemovedCompat(mo))
return;
goto bounceback;
}
}
// Now continue along the wall.
@@ -3742,7 +3766,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
delta1 = abs(thing->z - midheight);
delta2 = abs(thingtop - midheight);
if (bottomheight <= thing->ceilingz && delta1 >= delta2)
if ((bottomheight <= thing->ceilingz) && (delta1 >= delta2))
{
if (thing->flags & MF_PUSHABLE)
{
@@ -3959,19 +3983,51 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
Lots of new Boom functions that work faster and add functionality.
*/
#ifndef PHOBOS_BUILD
static msecnode_t *headsecnode = NULL;
#endif
void P_Initsecnode(void)
{
#ifndef PHOBOS_BUILD
headsecnode = NULL;
#endif
}
// P_GetSecnode() retrieves a node from the freelist. The calling routine
// should make sure it sets all fields properly.
static msecnode_t *P_GetSecnode(void)
{
#ifdef PHOBOS_BUILD
return Z_LevelPoolCalloc(sizeof(msecnode_t));
#else
msecnode_t *node;
if (headsecnode)
{
// vanilla does not clear this
// so for compat reasons we also dont
// means we just reuse stale data which causes weird interactions with orbiting items in some cases
node = headsecnode;
headsecnode = headsecnode->m_thinglist_next;
}
else
node = Z_LevelPoolCalloc(sizeof(msecnode_t));
return node;
#endif
}
// P_PutSecnode() returns a node to the freelist.
static inline void P_PutSecnode(msecnode_t *node)
{
#ifdef PHOBOS_BUILD
Z_LevelPoolFree(node, sizeof(msecnode_t));
#else
node->m_thinglist_next = headsecnode;
headsecnode = node;
#endif
}
// P_AddSecnode() searches the current list to see if this sector is
@@ -4200,7 +4256,7 @@ void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y)
* Must clear tmthing at tic end, as it might contain a pointer to a removed thinker, or the level might have ended/been ended and we clear the objects it was pointing too. Hopefully we don't need to carry this between tics for sync. */
void P_MapStart(void)
{
if (UNLIKELY(tmthing))
if (tmthing)
I_Error("P_MapStart: tmthing set!");
}
@@ -4252,7 +4308,7 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
delta1 = abs(z - midheight);
delta2 = abs(thingtop - midheight);
if (topheight > floorz && delta1 < delta2)
if ((topheight > floorz) && (delta1 < delta2))
floorz = topheight;
}
}
+32 -18
View File
@@ -326,16 +326,18 @@ void P_CameraLineOpening(line_t *linedef)
{
for (rover = front->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
fixed_t topheight, bottomheight, midheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || (rover->master->frontsector->flags & SF_NOCLIPCAMERA))
continue;
topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef);
bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tmx, tmy, linedef);
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
midheight = (bottomheight + ((topheight - bottomheight) / 2));
delta1 = abs(mapcampointer->z - midheight);
delta2 = abs(thingtop - midheight);
if (bottomheight < lowestceiling && delta1 >= delta2)
lowestceiling = bottomheight;
@@ -354,16 +356,18 @@ void P_CameraLineOpening(line_t *linedef)
{
for (rover = back->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
fixed_t topheight, bottomheight, midheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || (rover->master->frontsector->flags & SF_NOCLIPCAMERA))
continue;
topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef);
bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tmx, tmy, linedef);
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
midheight = (bottomheight + ((topheight - bottomheight) / 2));
delta1 = abs(mapcampointer->z - midheight);
delta2 = abs(thingtop - midheight);
if (bottomheight < lowestceiling && delta1 >= delta2)
lowestceiling = bottomheight;
@@ -462,7 +466,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
// Check for collision with front side's midtexture if Effect 4 is set
if (linedef->flags & ML_EFFECT4
&& !linedef->polyobj) // don't do anything for polyobjects! ...for now
{
{
side_t *side = &sides[linedef->sidenum[0]];
fixed_t textop, texbottom, texheight;
fixed_t texmid, delta1, delta2;
@@ -524,7 +528,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
// Check for frontsector's fake floors
for (rover = front->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
fixed_t topheight, bottomheight, midheight;
if (!(rover->flags & FF_EXISTS))
continue;
@@ -538,8 +542,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef);
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
midheight = (bottomheight + ((topheight - bottomheight) / 2));
delta1 = abs(mobj->z - midheight);
delta2 = abs(thingtop - midheight);
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
{
@@ -567,7 +573,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
// Check for backsectors fake floors
for (rover = back->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
fixed_t topheight, bottomheight, midheight;
if (!(rover->flags & FF_EXISTS))
continue;
@@ -580,8 +586,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef);
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
midheight = (bottomheight + ((topheight - bottomheight) / 2));
delta1 = abs(mobj->z - midheight);
delta2 = abs(thingtop - midheight);
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
{
@@ -611,8 +619,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
{
const sector_t *polysec = linedef->backsector;
delta1 = abs(mobj->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
delta2 = abs(thingtop - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
const fixed_t polymid = (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight) / 2));
delta1 = abs(mobj->z - polymid);
delta2 = abs(thingtop - polymid);
if (polysec->floorheight < lowestceiling && delta1 >= delta2)
{
@@ -620,7 +630,9 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
ceilingslope = NULL;
}
else if (polysec->floorheight < highestceiling && delta1 >= delta2)
{
highestceiling = polysec->floorheight;
}
if (polysec->ceilingheight > highestfloor && delta1 < delta2)
{
@@ -628,7 +640,9 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
floorslope = NULL;
}
else if (polysec->ceilingheight > lowestfloor && delta1 < delta2)
{
lowestfloor = polysec->ceilingheight;
}
}
if (highestceiling < highceiling)
@@ -842,7 +856,7 @@ void P_SetThingPosition(mobj_t *thing)
// at sector_t->touching_thinglist) are broken. When a node is
// added, new sector links are created.
P_CreateSecNodeList(thing,thing->x,thing->y);
P_CreateSecNodeList(thing, thing->x, thing->y);
thing->touching_sectorlist = sector_list; // Attach to Thing's mobj_t
sector_list = NULL; // clear for next time
}
+1614 -1309
View File
File diff suppressed because it is too large. Load diff
+4 -18
View File
@@ -113,7 +113,7 @@ typedef enum
// Don't use the blocklinks (inert but displayable)
MF_NOBLOCKMAP = 1<<4,
// Thin, paper-like collision bound (for visual equivalent, see FF_PAPERSPRITE)
MF_PAPERCOLLISION = 1<<5,
MF_PAPERCOLLISION = 1<<5,
// You can push this object. It can activate switches and things by pushing it on top.
MF_PUSHABLE = 1<<6,
// Object is a boss.
@@ -258,23 +258,12 @@ typedef enum
// PRECIPITATION flags ?! ?! ?!
//
typedef enum {
PCF_INVISIBLE = 1, // Don't draw.
PCF_INVISIBLE = 1, // Don't draw.
PCF_PIT = 1<<1, // Above pit.
PCF_FOF = 1<<2, // Above FOF.
PCF_MOVINGFOF = 1<<3, // Above MOVING FOF (this means we need to keep floorz up to date...)
PCF_SPLASH = 1<<4, // Splashed on the ground, return to the ceiling after the animation's over
PCF_THUNK = 1<<5, // Ran the thinker this tic.
PCF_SPLASH = 1<<2, // Splashed on the ground, return to the ceiling after the animation's over
PCF_THUNK = 1<<3, // Ran the thinker this tic.
} precipflag_t;
typedef struct salty_s
{
bool init;
bool ready;
bool tapping;
fixed_t zoffset;
fixed_t momz;
bool jump;
} salty_t;
// Map Object definition.
typedef struct mobj_s
@@ -412,9 +401,6 @@ typedef struct mobj_s
tic_t slamsoundtimer; // Funni slam sound when landing
// saltyhop! hardcode edition
salty_t salty;
// WARNING: New fields must be added separately to savegame and Lua.
boolean islocal; // BEWARE: islocal does not exist in vanilla, strictly to be used for locally loaded addons to not cause desynchs with the mobj linedef trigger check. DO NOT USE THIS IN ACTUAL ADDONS YOU INTEND TO USE ON YOUR SERVER
} mobj_t;
+72 -6
View File
@@ -69,7 +69,7 @@ FUNCINLINE static ATTRINLINE void P_ArchivePlayer(savebuffer_t *save)
pllives = 3; // has less than that.
WRITEUINT8(save->p, player->skincolor);
WRITEUINT8(save->p, player->skin);
WRITESKIN(save->p, player->skin);
WRITEUINT32(save->p, player->score);
WRITEINT32(save->p, pllives);
@@ -77,7 +77,7 @@ FUNCINLINE static ATTRINLINE void P_ArchivePlayer(savebuffer_t *save)
if (botskin)
{
WRITEUINT8(save->p, botskin);
WRITESKIN(save->p, botskin);
WRITEUINT8(save->p, botcolor);
}
}
@@ -88,7 +88,7 @@ FUNCINLINE static ATTRINLINE void P_ArchivePlayer(savebuffer_t *save)
FUNCINLINE static ATTRINLINE void P_UnArchivePlayer(savebuffer_t *save)
{
savedata.skincolor = READUINT8(save->p);
savedata.skin = READUINT8(save->p);
savedata.skin = READSKIN(save->p);
savedata.score = READINT32(save->p);
savedata.lives = READINT32(save->p);
@@ -96,9 +96,11 @@ FUNCINLINE static ATTRINLINE void P_UnArchivePlayer(savebuffer_t *save)
if (savedata.botcolor)
{
savedata.botskin = READUINT8(save->p);
savedata.botskin = READSKIN(save->p);
if (savedata.botskin-1 >= numskins)
savedata.botskin = 0;
savedata.botcolor = READUINT8(save->p);
}
else
@@ -117,7 +119,9 @@ static void P_NetArchivePlayers(savebuffer_t *save, boolean resending)
for (i = 0; i < MAXPLAYERS; i++)
{
#ifndef PHOBOS_BUILD
if (resending)
#endif
WRITESINT8(save->p, (SINT8)adminplayers[i]);
if (!playeringame[i])
@@ -127,7 +131,9 @@ static void P_NetArchivePlayers(savebuffer_t *save, boolean resending)
// no longer send ticcmds
#ifndef PHOBOS_BUILD
if (resending)
#endif
WRITESTRINGN(save->p, player_names[i], MAXPLAYERNAME);
const player_t *player = &players[i];
@@ -156,11 +162,16 @@ static void P_NetArchivePlayers(savebuffer_t *save, boolean resending)
WRITEUINT16(save->p, player->flashpal);
WRITEUINT16(save->p, player->flashcount);
#ifdef PHOBOS_BUILD
WRITEUINT8(save->p, player->skincolor);
WRITEINT32(save->p, player->skin);
#else
if (resending)
{
WRITEUINT8(save->p, player->skincolor);
WRITEINT32(save->p, player->skin);
}
#endif
WRITEUINT32(save->p, player->score);
WRITEFIXED(save->p, player->dashspeed);
@@ -309,7 +320,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save, boolean reloading)
for (i = 0; i < MAXPLAYERS; i++)
{
#ifndef PHOBOS_BUILD
if (reloading)
#endif
adminplayers[i] = (INT32)READSINT8(save->p);
// Do NOT memset player struct to 0
@@ -320,7 +333,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save, boolean reloading)
// NOTE: sending tics should (hopefully) no longer be necessary
#ifndef PHOBOS_BUILD
if (reloading)
#endif
READSTRINGN(save->p, player_names[i], MAXPLAYERNAME);
player_t *player = &players[i];
@@ -349,11 +364,16 @@ static void P_NetUnArchivePlayers(savebuffer_t *save, boolean reloading)
player->flashpal = READUINT16(save->p);
player->flashcount = READUINT16(save->p);
#ifdef PHOBOS_BUILD
player->skincolor = READUINT8(save->p);
player->skin = READINT32(save->p);
#else
if (reloading)
{
player->skincolor = READUINT8(save->p);
player->skin = READINT32(save->p);
}
#endif
player->score = READUINT32(save->p);
player->dashspeed = READFIXED(save->p); // dashing speed
@@ -1089,6 +1109,10 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
if (mobj->type == MT_HOOPCENTER && mobj->threshold == 4242)
return;
// do not send over locally spawned mobjs
if (mobj->islocal)
return;
if (mobj->spawnpoint && mobj->info->doomednum != -1)
{
// spawnpoint is not modified but we must save it since it is an identifier
@@ -1108,11 +1132,23 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
diff2 = 0;
// not the default but the most probable
#ifdef PHOBOS_BUILD
if (mobj->momx != 0 || mobj->momy != 0 || mobj->momz != 0 || mobj->pmomz !=0)
#else
if (mobj->momx != 0 || mobj->momy != 0 || mobj->momz != 0)
#endif
diff |= MD_MOM;
#ifdef PHOBOS_BUILD
if (mobj->radius != FixedMul(mapobjectscale, mobj->info->radius))
#else
if (mobj->radius != mobj->info->radius)
#endif
diff |= MD_RADIUS;
#ifdef PHOBOS_BUILD
if (mobj->height != FixedMul(mapobjectscale, mobj->info->height))
#else
if (mobj->height != mobj->info->height)
#endif
diff |= MD_HEIGHT;
if (mobj->flags != mobj->info->flags)
diff |= MD_FLAGS;
@@ -1155,11 +1191,19 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
diff |= MD_MOVEFACTOR;
if (mobj->fuse)
diff |= MD_FUSE;
#ifdef PHOBOS_BUILD
if (mobj->watertop != INT32_MAX)
#else
if (mobj->watertop)
#endif
diff |= MD_WATERTOP;
if (mobj->waterbottom)
diff |= MD_WATERBOTTOM;
#ifdef PHOBOS_BUILD
if (mobj->scale != mapobjectscale)
#else
if (mobj->scale != FRACUNIT)
#endif
diff |= MD_SCALE;
if (mobj->destscale != mobj->scale)
diff |= MD_DSCALE;
@@ -1236,6 +1280,9 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
WRITEFIXED(save->p, mobj->momx);
WRITEFIXED(save->p, mobj->momy);
WRITEFIXED(save->p, mobj->momz);
#ifdef PHOBOS_BUILD
WRITEFIXED(save->p, mobj->pmomz);
#endif
}
if (diff & MD_RADIUS)
WRITEFIXED(save->p, mobj->radius);
@@ -1297,7 +1344,7 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
if (diff2 & MD2_CVMEM)
WRITEINT32(save->p, mobj->cvmem);
if (diff2 & MD2_SKIN)
WRITEUINT8(save->p, (UINT8)((skin_t *)mobj->skin - skins));
WRITESKIN(save->p, (skinnum_t)((skin_t *)mobj->skin - skins));
if (diff2 & MD2_COLOR)
WRITEUINT8(save->p, mobj->color);
if (diff2 & MD2_EXTVAL1)
@@ -2055,16 +2102,27 @@ static void LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
mobj->momx = READFIXED(save->p);
mobj->momy = READFIXED(save->p);
mobj->momz = READFIXED(save->p);
#ifdef PHOBOS_BUILD
mobj->pmomz = READFIXED(save->p);
#endif
} // otherwise they're zero, and the memset took care of it
if (diff & MD_RADIUS)
mobj->radius = READFIXED(save->p);
else
#ifdef PHOBOS_BUILD
mobj->radius = FixedMul(mobj->info->radius, mapobjectscale);
#else
mobj->radius = mobj->info->radius;
#endif
if (diff & MD_HEIGHT)
mobj->height = READFIXED(save->p);
else
#ifdef PHOBOS_BUILD
mobj->height = FixedMul(mobj->info->height, mapobjectscale);
#else
mobj->height = mobj->info->height;
#endif
if (diff & MD_FLAGS)
mobj->flags = READUINT32(save->p);
else
@@ -2136,12 +2194,20 @@ static void LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
mobj->fuse = READINT32(save->p);
if (diff & MD_WATERTOP)
mobj->watertop = READFIXED(save->p);
#ifdef PHOBOS_BUILD
else
mobj->watertop = INT32_MAX;
#endif
if (diff & MD_WATERBOTTOM)
mobj->waterbottom = READFIXED(save->p);
if (diff & MD_SCALE)
mobj->scale = READFIXED(save->p);
else
#ifdef PHOBOS_BUILD
mobj->scale = mapobjectscale;
#else
mobj->scale = FRACUNIT;
#endif
if (diff & MD_DSCALE)
mobj->destscale = READFIXED(save->p);
else
@@ -2155,7 +2221,7 @@ static void LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
if (diff2 & MD2_CVMEM)
mobj->cvmem = READINT32(save->p);
if (diff2 & MD2_SKIN)
mobj->skin = &skins[READUINT8(save->p)];
mobj->skin = &skins[READSKIN(save->p)];
if (diff2 & MD2_COLOR)
mobj->color = READUINT8(save->p);
if (diff2 & MD2_EXTVAL1)
+2 -2
View File
@@ -24,8 +24,8 @@
typedef struct
{
UINT8 skincolor;
UINT8 skin;
UINT8 botskin;
skinnum_t skin;
skinnum_t botskin;
UINT8 botcolor;
INT32 score;
INT32 lives;
+210 -166
View File
@@ -117,6 +117,7 @@ line_t *spawnlines = NULL;
side_t *spawnsides = NULL;
INT32 numstarposts = 0;
boolean levelloading = false;
UINT8 levelfadecol = 120;
virtres_t *curmapvirt = NULL;
@@ -179,7 +180,7 @@ FUNCNORETURN static ATTRNORETURN void CorruptMapError(const char *msg)
// don't use va() because the calling function probably uses it
char mapnum[10];
sprintf(mapnum, "%hd", gamemap);
snprintf(mapnum, sizeof(mapnum), "%hd", gamemap);
CON_LogMessage("Map ");
CON_LogMessage(mapnum);
CON_LogMessage(" is corrupt: ");
@@ -265,8 +266,8 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->actnum[0] = '\0';
mapheaderinfo[num]->typeoflevel = 0;
mapheaderinfo[num]->nextlevel = (INT16)(i + 1);
snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i));
mapheaderinfo[num]->musname[6] = 0;
snprintf(mapheaderinfo[num]->musname, sizeof(mapheaderinfo[num]->musname), "%sM", G_BuildMapName(i));
mapheaderinfo[num]->musname[sizeof(mapheaderinfo[num]->musname)-1] = 0;
mapheaderinfo[num]->mustrack = 0;
mapheaderinfo[num]->muspos = 0;
mapheaderinfo[num]->forcecharacter[0] = '\0';
@@ -317,15 +318,15 @@ void P_AllocMapHeader(INT16 i)
// Loads the vertexes for a level.
FUNCINLINE static ATTRINLINE void P_LoadVertices(UINT8 *data)
{
mapvertex_t *ml = (mapvertex_t *)data;
vertex_t *li = vertexes;
mapvertex_t *mv = (mapvertex_t *)data;
vertex_t *v = vertexes;
size_t i;
// Copy and convert vertex coordinates, internal representation as fixed.
for (i = 0; i < numvertexes; i++, li++, ml++)
for (i = 0; i < numvertexes; i++, v++, mv++)
{
li->x = SHORT(ml->x)<<FRACBITS;
li->y = SHORT(ml->y)<<FRACBITS;
v->x = SHORT(mv->x)<<FRACBITS;
v->y = SHORT(mv->y)<<FRACBITS;
}
}
@@ -478,65 +479,30 @@ static void P_SetupDirectionalLight(void)
static void P_LoadSegs(UINT8 *data)
{
INT32 rawlinedef, rawside;
mapseg_t *ml = (mapseg_t*)data;
seg_t *li = segs;
mapseg_t *ms = (mapseg_t*)data;
seg_t *seg = segs;
line_t *ldef;
size_t i;
// Set map lighting settings.
P_SetupDirectionalLight();
for (i = 0; i < numsegs; i++, li++, ml++)
for (i = 0; i < numsegs; i++, seg++, ms++)
{
INT16 v1, v2;
v1 = SHORT(ml->v1);
v2 = SHORT(ml->v2);
v1 = SHORT(ms->v1);
v2 = SHORT(ms->v2);
// e6y
// check and fix wrong references to non-existent vertexes
// see e1m9 @ NIVELES.WAD
// http://www.doomworld.com/idgames/index.php?id=12647
if ((unsigned)v1 >= numvertexes || (unsigned)v2 >= numvertexes)
{
if ((unsigned)v1 >= numvertexes)
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v1));
if ((unsigned)v2 >= numvertexes)
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v2));
// moved down for additional checks to avoid overflow
// if wrong vertexe's indexes are in SEGS lump
// see below for more detailed information
if (li->sidedef == &sides[li->linedef->sidenum[0]])
{
li->v1 = lines[ml->linedef].v1;
li->v2 = lines[ml->linedef].v2;
}
else
{
li->v1 = lines[ml->linedef].v2;
li->v2 = lines[ml->linedef].v1;
}
}
else
{
li->v1 = &vertexes[v1];
li->v2 = &vertexes[v2];
}
seg->angle = (SHORT(ms->angle)) << FRACBITS;
seg->offset = (SHORT(ms->offset)) << FRACBITS;
#ifdef HWRENDER
if (rendermode == render_opengl)
{
li->fv1.x = FixedToFloat(li->v1->x);
li->fv1.y = FixedToFloat(li->v1->y);
//li->fv1.z = FixedToFloat(li->v1->z); // z is unused in gl
li->fv2.x = FixedToFloat(li->v2->x);
li->fv2.y = FixedToFloat(li->v2->y);
//li->fv2.z = FixedToFloat(li->v2->z);
}
#endif
li->length = P_SegLength(li);
li->angle = (SHORT(ml->angle))<<FRACBITS;
li->offset = (SHORT(ml->offset))<<FRACBITS;
rawlinedef = SHORT(ml->linedef);
rawlinedef = SHORT(ms->linedef);
//e6y: check for wrong indexes
if ((unsigned)rawlinedef >= numlines)
@@ -545,8 +511,8 @@ static void P_LoadSegs(UINT8 *data)
}
ldef = &lines[rawlinedef];
li->linedef = ldef;
rawside = SHORT(ml->side);
seg->linedef = ldef;
rawside = SHORT(ms->side);
//e6y: fix wrong side index
if (rawside != 0 && rawside != 1)
@@ -561,9 +527,9 @@ static void P_LoadSegs(UINT8 *data)
I_Error("P_LoadSegs: linedef %d for seg %s references a non-existent sidedef %d", rawlinedef, sizeu1(i), ldef->sidenum[rawside]);
}
li->side = rawside;
seg->side = rawside;
li->sidedef = &sides[ldef->sidenum[rawside]];
seg->sidedef = &sides[ldef->sidenum[rawside]];
/* cph 2006/09/30 - our frontsector can be the second side of the
* linedef, so must check for NO_INDEX in case we are incorrectly
@@ -571,11 +537,11 @@ static void P_LoadSegs(UINT8 *data)
if (ldef->sidenum[rawside] == NO_INDEX)
{
CorruptMapWarning(va("P_LoadSegs: front of seg %s has no sidedef\n", sizeu1(i)));
li->frontsector = NULL;
seg->frontsector = NULL;
}
else
{
li->frontsector = sides[ldef->sidenum[rawside]].sector;
seg->frontsector = sides[ldef->sidenum[rawside]].sector;
}
if (ldef->flags & ML_TWOSIDED)
@@ -583,15 +549,56 @@ static void P_LoadSegs(UINT8 *data)
if (ldef->sidenum[rawside^1] == NO_INDEX)
{
CorruptMapWarning(va("P_LoadSegs: back of seg %s has no sidedef while being marked as double sided\n", sizeu1(i)));
li->backsector = NULL;
seg->backsector = NULL;
}
else
{
li->backsector = sides[ldef->sidenum[rawside^1]].sector;
seg->backsector = sides[ldef->sidenum[rawside^1]].sector;
}
}
P_UpdateSegLightOffset(li);
// e6y
// check and fix wrong references to non-existent vertexes
// see e1m9 @ NIVELES.WAD
// http://www.doomworld.com/idgames/index.php?id=12647
if ((unsigned)v1 >= numvertexes || (unsigned)v2 >= numvertexes)
{
if ((unsigned)v1 >= numvertexes)
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v1));
if ((unsigned)v2 >= numvertexes)
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v2));
if (seg->sidedef == &sides[seg->linedef->sidenum[0]])
{
seg->v1 = lines[rawlinedef].v1;
seg->v2 = lines[rawlinedef].v2;
}
else
{
seg->v1 = lines[rawlinedef].v2;
seg->v2 = lines[rawlinedef].v1;
}
}
else
{
seg->v1 = &vertexes[v1];
seg->v2 = &vertexes[v2];
}
#ifdef HWRENDER
if (rendermode == render_opengl)
{
seg->fv1.x = FixedToFloat(seg->v1->x);
seg->fv1.y = FixedToFloat(seg->v1->y);
//seg->fv1.z = FixedToFloat(seg->v1->z); // z is unused in gl
seg->fv2.x = FixedToFloat(seg->v2->x);
seg->fv2.y = FixedToFloat(seg->v2->y);
//seg->fv2.z = FixedToFloat(seg->v2->z);
}
#endif
seg->length = P_SegLength(seg);
P_UpdateSegLightOffset(seg);
}
}
@@ -609,10 +616,6 @@ FUNCINLINE static ATTRINLINE void P_LoadSubsectors(void *data)
}
}
//
// P_LoadSectors
//
//
// levelflats
//
@@ -664,13 +667,17 @@ static void P_CheckCyanFlat(levelflat_t *levelflat)
const char *flatname = W_CheckNameForNum(levelflat->lumpnum);
// hack for gba rainbow roads cyan floors
if (UNLIKELY(memcmp(flatname, "GBA_RRF5", 8) == 0 && flatname[8] == 0))
if (UNLIKELY(flatname && memcmp(flatname, "GBA_RRF5", 8) == 0 && flatname[8] == 0))
{
levelflat->cyan = false;
return;
}
const UINT8 *flat = R_GetFlat(levelflat->lumpnum);
if (!flat)
return;
const size_t size = W_LumpLength(levelflat->lumpnum);
for (size_t steppy = 0; steppy < size; steppy++)
@@ -790,6 +797,10 @@ INT32 P_CheckLevelFlat(const char *flatname)
return (INT32)i;
}
//
// P_LoadSectors
//
static const sector_t sector_default = {
.nexttag = -1,
.firsttag = -1,
@@ -920,7 +931,48 @@ static void P_LoadThings(UINT8 *data)
}
}
static void P_SpawnMapThings(void)
static void P_SpawnEmeraldHunt(void)
{
INT32 i;
INT32 emer[3] = {0, 0, 0};
INT32 timeout = 0; // keeps from getting stuck
fixed_t x, y, z;
// increment spawn numbers because zero is valid.
emer[0] = (P_RandomKey(numhuntemeralds)) + 1;
while (timeout++ < 100)
{
emer[1] = (P_RandomKey(numhuntemeralds)) + 1;
if (emer[1] != emer[0])
break;
}
timeout = 0;
while (timeout++ < 100)
{
emer[2] = (P_RandomKey(numhuntemeralds)) + 1;
if (emer[2] != emer[1] && emer[2] != emer[0])
break;
}
for (i = 0; i < 3; i++)
{
if (!emer[i])
continue;
// decrement spawn values to the actual number because zero is valid.
x = huntemeralds[emer[i] - 1]->x<<FRACBITS;
y = huntemeralds[emer[i] - 1]->y<<FRACBITS;
z = huntemeralds[emer[i] - 1]->z<<FRACBITS;
// spawn emerald
P_SpawnMobj(x, y, z, MT_EMERHUNT);
}
}
static void P_SpawnMapThings(boolean spawnhoops)
{
size_t i;
mapthing_t *mt;
@@ -930,97 +982,68 @@ static void P_SpawnMapThings(void)
// Spawn axis points first so they are at the front of the list for fast searching.
for (i = 0, mt = mapthings; i < nummapthings; i++, mt++)
{
switch (mt->type)
if (mt->type == 1700 || // MT_AXIS
mt->type == 1701 || // MT_AXISTRANSFER
mt->type == 1702) // MT_AXISTRANSFERLINE
{
case 1700: // MT_AXIS
case 1701: // MT_AXISTRANSFER
case 1702: // MT_AXISTRANSFERLINE
mt->mobj = NULL;
P_SpawnMapThing(mt);
break;
default:
break;
mt->mobj = NULL;
P_SpawnMapThing(mt);
}
}
for (i = 0, mt = mapthings; i < nummapthings; i++, mt++)
{
sector_t *mtsector = R_PointInSubsector((mt->x << FRACBITS), (mt->y << FRACBITS))->sector;
sector_t *mtsector;
// srb2kart - ignore rings, coins and item patterns!
if (mt->type == 300 || mt->type == 308 || mt->type == 309 ||
(mt->type >= 600 && mt->type <= 609) ||
mt->type == 1706 || mt->type == 1800)
{
mt->mobj = NULL;
continue;
}
mtsector = R_PointInSubsector((mt->x << FRACBITS), (mt->y << FRACBITS))->sector;
// Z for objects
mt->z = (INT16)(P_GetSectorFloorZAt(mtsector, (mt->x << FRACBITS), (mt->y << FRACBITS))) >> FRACBITS;
if (mt->type == 1700 // MT_AXIS
|| mt->type == 1701 // MT_AXISTRANSFER
|| mt->type == 1702) // MT_AXISTRANSFERLINE
if (mt->type == 1700 || // MT_AXIS
mt->type == 1701 || // MT_AXISTRANSFER
mt->type == 1702) // MT_AXISTRANSFERLINE
{
continue; // These were already spawned
}
mt->mobj = NULL;
// spawn hoops
if (mt->type == 1705 || mt->type == 1713)
{
// Check for spawnhoops here so the hoops don't spawn ghost variants for players joining a netgame mid-level
// ...It's a long story.
if (spawnhoops)
{
// Z for objects Tails 05-26-2002
mt->z = (INT16)(mtsector->floorheight >> FRACBITS);
P_SpawnHoops(mt);
}
continue;
}
if (mt->type == mobjinfo[MT_RANDOMITEM].doomednum)
nummapboxes++;
mt->mobj = NULL;
// Everything else
P_SpawnMapThing(mt);
}
// random emeralds for hunt
if (numhuntemeralds)
{
INT32 emer1, emer2, emer3;
INT32 timeout = 0; // keeps from getting stuck
emer1 = emer2 = emer3 = 0;
//increment spawn numbers because zero is valid.
emer1 = (P_RandomKey(numhuntemeralds)) + 1;
while (timeout++ < 100)
{
emer2 = (P_RandomKey(numhuntemeralds)) + 1;
if (emer2 != emer1)
break;
}
timeout = 0;
while (timeout++ < 100)
{
emer3 = (P_RandomKey(numhuntemeralds)) + 1;
if (emer3 != emer2 && emer3 != emer1)
break;
}
//decrement spawn values to the actual number because zero is valid.
if (emer1)
P_SpawnMobj(huntemeralds[emer1 - 1]->x<<FRACBITS,
huntemeralds[emer1 - 1]->y<<FRACBITS,
huntemeralds[emer1 - 1]->z<<FRACBITS, MT_EMERHUNT);
if (emer2)
P_SpawnMobj(huntemeralds[emer2 - 1]->x<<FRACBITS,
huntemeralds[emer2 - 1]->y<<FRACBITS,
huntemeralds[emer2 - 1]->z<<FRACBITS, MT_EMERHUNT);
if (emer3)
P_SpawnMobj(huntemeralds[emer3 - 1]->x<<FRACBITS,
huntemeralds[emer3 - 1]->y<<FRACBITS,
huntemeralds[emer3 - 1]->z<<FRACBITS, MT_EMERHUNT);
}
// Run through the list of mapthings again to spawn hoops and rings
for (i = 0, mt = mapthings; i < nummapthings; i++, mt++)
{
if (mt->type == 300 || mt->type == 308 || mt->type == 309
|| mt->type == 1706 || (mt->type >= 600 && mt->type <= 609)
|| mt->type == 1705 || mt->type == 1713 || mt->type == 1800)
{
mt->mobj = NULL;
// Z for objects Tails 05-26-2002
mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector->floorheight>>FRACBITS);
P_SpawnHoops(mt);
}
}
P_SpawnEmeraldHunt();
}
static void P_SpawnEmblems(boolean loademblems)
@@ -1034,22 +1057,22 @@ static void P_SpawnEmblems(boolean loademblems)
for (i = 0; i < numemblems; i++)
{
if (emblemlocations[i].level != gamemap || emblemlocations[i].type > ET_SKIN)
const emblem_t *emblemlocation = &emblemlocations[i];
if (emblemlocation->level != gamemap || emblemlocation->type > ET_SKIN)
continue;
emblemmobj = P_SpawnMobj(emblemlocations[i].x<<FRACBITS, emblemlocations[i].y<<FRACBITS,
emblemlocations[i].z<<FRACBITS, MT_EMBLEM);
emblemmobj = P_SpawnMobj(emblemlocation->x<<FRACBITS, emblemlocation->y<<FRACBITS, emblemlocation->z<<FRACBITS, MT_EMBLEM);
I_Assert(emblemlocations[i].sprite >= 'A' && emblemlocations[i].sprite <= 'Z');
P_SetMobjStateNF(emblemmobj, emblemmobj->info->spawnstate + (emblemlocations[i].sprite - 'A'));
I_Assert(emblemlocation->sprite >= 'A' && emblemlocation->sprite <= 'Z');
P_SetMobjStateNF(emblemmobj, emblemmobj->info->spawnstate + (emblemlocation->sprite - 'A'));
emblemmobj->health = i+1;
color = M_GetEmblemColor(&emblemlocations[i]);
emblemmobj->color = (UINT8)color;
if (emblemlocations[i].collected
|| (emblemlocations[i].type == ET_SKIN && emblemlocations[i].var != players[0].skin))
if (emblemlocation->collected || (emblemlocation->type == ET_SKIN && emblemlocation->var != players[0].skin))
{
P_UnsetThingPosition(emblemmobj);
emblemmobj->flags |= MF_NOCLIP;
@@ -1881,7 +1904,7 @@ static void P_ReadBlockMapLump(INT16 *wadblockmaplump, size_t count)
// because making both the WAD and PK3 loading code use
// the same functions is trickier than it looks for blockmap
// -- Monster Iestyn 09/01/18
static boolean P_LoadRawBlockMap(UINT8 *data, size_t count)
static boolean P_LoadBlockMap(UINT8 *data, size_t count)
{
if (!count || count >= 0x20000)
return false;
@@ -2049,14 +2072,14 @@ static void P_LoadReject(UINT8 *data, size_t rejectsize)
if (rejectsize < neededsize)
{
CorruptMapWarning(va("P_LoadReject: REJECT is %s byte%s too small. REJECT might be invalid!\n", sizeu1(neededsize - rejectsize), (neededsize - rejectsize) == 1 ? "" : "s"));
#ifdef COMPAT_VANILLA
#ifdef PHOBOS_BUILD
rejectmatrix = NULL;
return;
#else
// we can pad this and somewhat prevent desyncs
// probs not cool if the reject is from a completely different map
// but whatever
allocsize = neededsize;
#else
rejectmatrix = NULL;
return;
#endif
}
@@ -2071,6 +2094,13 @@ static void P_LoadMapBSP(const virtres_t* virt)
virtlump_t* virtsegs = vres_Find(virt, "SEGS");
virtlump_t* virtnodes = vres_Find(virt, "NODES");
if (!virtssectors)
I_Error("SSECTORS lump not found");
if (!virtsegs)
I_Error("SEGS lump not found");
if (!virtnodes)
I_Error("NODES lump not found");
numsubsectors = virtssectors->size / sizeof(mapsubsector_t);
numnodes = virtnodes->size / sizeof(mapnode_t);
numsegs = virtsegs->size / sizeof(mapseg_t);
@@ -2107,7 +2137,7 @@ static void P_LoadMapLUT(const virtres_t* virt)
rejectmatrix = NULL;
}
if (!(virtblockmap && P_LoadRawBlockMap(virtblockmap->data, virtblockmap->size)))
if (!(virtblockmap && P_LoadBlockMap(virtblockmap->data, virtblockmap->size)))
P_CreateBlockMap();
}
@@ -2180,7 +2210,7 @@ void P_SetupLevelSky(INT32 skynum, boolean global)
{
char skytexname[12];
sprintf(skytexname, "SKY%d", skynum);
snprintf(skytexname, sizeof(skytexname), "SKY%d", skynum);
skytexture = R_TextureNumForName(skytexname);
levelskynum = skynum;
@@ -2400,7 +2430,8 @@ static void P_RunLevelScript(const char *scriptname)
lumpnum_t lumpnum;
char newname[9];
strlcpy(newname, scriptname, sizeof(newname));
strncpy(newname, scriptname, sizeof(newname)-1);
newname[sizeof(newname)-1] = '\0';
lumpnum = W_CheckNumForName(newname);
@@ -2410,7 +2441,7 @@ static void P_RunLevelScript(const char *scriptname)
return;
}
COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE));
COM_BufInsertTextEx(W_CacheLumpNum(lumpnum, PU_CACHE), W_LumpLength(lumpnum));
}
else
{
@@ -2425,23 +2456,26 @@ static void P_ForceCharacter(const char *forcecharskin)
if (netgame)
{
char skincmd[33];
if (splitscreen)
{
sprintf(skincmd, "skin2 %s\n", forcecharskin);
snprintf(skincmd, sizeof(skincmd), "skin2 %s\n", forcecharskin);
CV_Set(&cv_skin2, forcecharskin);
if (splitscreen > 1)
{
sprintf(skincmd, "skin3 %s\n", forcecharskin);
snprintf(skincmd, sizeof(skincmd), "skin3 %s\n", forcecharskin);
CV_Set(&cv_skin3, forcecharskin);
if (splitscreen > 2)
{
sprintf(skincmd, "skin4 %s\n", forcecharskin);
snprintf(skincmd, sizeof(skincmd), "skin4 %s\n", forcecharskin);
CV_Set(&cv_skin4, forcecharskin);
}
}
}
sprintf(skincmd, "skin %s\n", forcecharskin);
snprintf(skincmd, sizeof(skincmd), "skin %s\n", forcecharskin);
COM_BufAddText(skincmd);
}
else
@@ -2498,7 +2532,7 @@ static void P_LoadRecordGhosts(void)
const char *mapname = G_BuildMapName(gamemap);
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, mapname);
snprintf(gpath, glen, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, mapname);
// Best Time ghost
if (cv_ghost_besttime.value)
@@ -2854,7 +2888,8 @@ static void P_SetupPlayer(void)
if (!demo.playback && multiplayer && D_NumPlayers())
{
static char buf[256];
sprintf(buf, "replay"PATHSEP"online"PATHSEP"%d-%s", (int)(time(NULL)), G_BuildMapName(gamemap));
snprintf(buf, sizeof(buf), "replay"PATHSEP"online"PATHSEP"%d-%s", (int)(time(NULL)), G_BuildMapName(gamemap));
I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755);
I_mkdir(va("%s"PATHSEP"replay"PATHSEP"online", srb2home), 0755);
@@ -2956,7 +2991,6 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
// 99% of the things already did, so.
// Map header should always be in place at this point
INT32 i;
UINT8 levelfadecol;
boolean ranspecialwipe = false;
lumpnum_t encoreLump = LUMPERROR;
const mapheader_t *mapheader = mapheaderinfo[gamemap - 1];
@@ -2972,6 +3006,9 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
CON_Drawer(); // let the user know what we are going to do
I_FinishUpdate(); // page flip or blit buffer
// Initialize sector node list.
P_Initsecnode();
if (netgame || multiplayer)
cv_debug = botskin = 0;
@@ -3037,7 +3074,7 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
// Don't include these in the fade!
char tx[64];
V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to..."));
snprintf(tx, 63, "%s%s%s",
snprintf(tx, sizeof(tx)-1, "%s%s%s",
mapheader->lvlttl,
(strlen(mapheader->zonttl) > 0) ? va(" %s",mapheader->zonttl) : // SRB2kart
((mapheader->levelflags & LF_NOZONE) ? "" : " Zone"),
@@ -3079,7 +3116,7 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
// a shit ton of time loading mobj thinkers.
CalculateDoomednumToMobjtype();
P_SpawnMapThings();
P_SpawnMapThings(!fromnetsave);
P_SpawnEmblems(!fromnetsave);
@@ -3299,6 +3336,7 @@ static boolean P_CheckSoundReplacements(UINT16 wadnum, char *name, size_t i)
return false;
}
//
// P_CheckReplacMapReplacements
//
@@ -3391,7 +3429,13 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
{
// check if someone tries to load maps locally lol
// do this here so we can skip loading the file anyways
if (W_CheckAutoLoadContainsMap(wadfilename))
int retmap = W_CheckAutoLoadContainsMap(wadfilename);
if (retmap == -1)
{
CONS_Alert(CONS_WARNING, "addilelocal: file %s was not found or not valid.\n", wadfilename);
return UINT16_MAX;
}
if (retmap > 0)
{
CONS_Alert(CONS_WARNING, "addilelocal: locally added file %s contains map data, this WILL cause crashes and desynchs! not added.\n", wadfilename);
return UINT16_MAX;
+1
View File
@@ -35,6 +35,7 @@ extern mapthing_t *deathmatchstarts[MAX_DM_STARTS];
extern INT32 numdmstarts, numcoopstarts, numredctfstarts, numbluectfstarts;
extern boolean levelloading;
extern UINT8 levelfadecol;
extern lumpnum_t lastloadedmaplumpnum; // for comparative savegame
extern virtres_t *curmapvirt;
+48 -23
View File
@@ -1962,13 +1962,19 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
if (!dest)
return;
const angle_t ang = (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle;
const boolean dontstopmove = (line->flags & ML_EFFECT4) == ML_EFFECT4;
if (bot)
P_Teleport(bot, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, (line->flags & ML_BLOCKMONSTERS) == 0, (line->flags & ML_EFFECT4) == ML_EFFECT4);
P_Teleport(bot, dest->x, dest->y, dest->z, ang, (line->flags & ML_BLOCKMONSTERS) == 0, dontstopmove);
if (line->flags & ML_BLOCKMONSTERS)
P_Teleport(mo, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, false, (line->flags & ML_EFFECT4) == ML_EFFECT4);
{
P_Teleport(mo, dest->x, dest->y, dest->z, ang, false, dontstopmove);
}
else
{
P_Teleport(mo, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, true, (line->flags & ML_EFFECT4) == ML_EFFECT4);
P_Teleport(mo, dest->x, dest->y, dest->z, ang, true, dontstopmove);
// Play the 'bowrwoosh!' sound
S_StartSound(dest, sfx_mixup);
}
@@ -2161,7 +2167,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
newname[1] = 'C';
newname[2] = 'R';
scrnum = sides[line->sidenum[0]].textureoffset>>FRACBITS;
scrnum = sides[line->sidenum[0]].textureoffset >> FRACBITS;
if (scrnum < 0 || scrnum > 999)
{
scrnum = 0;
@@ -2169,9 +2175,9 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
}
else
{
newname[5] = (char)('0' + (char)((scrnum/100)));
newname[6] = (char)('0' + (char)((scrnum%100)/10));
newname[7] = (char)('0' + (char)(scrnum%10));
newname[5] = (char)('0' + (char)((scrnum / 100)));
newname[6] = (char)('0' + (char)((scrnum % 100) / 10));
newname[7] = (char)('0' + (char)(scrnum % 10));
}
newname[8] = '\0';
@@ -2184,14 +2190,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
else
{
// W_CacheLumpNum may not have null terminator, so we need to do this :blobcatgooglyholditsheadinitshands:
size_t len = W_LumpLength(lumpnum);
char *script = Z_Malloc(len+1, PU_STATIC, NULL);
memcpy(script, W_CacheLumpNum(lumpnum, PU_CACHE), len);
script[len] = 0;
COM_BufInsertText(script);
Z_Free(script);
COM_BufInsertTextEx(W_CacheLumpNum(lumpnum, PU_CACHE), W_LumpLength(lumpnum));
}
}
break;
@@ -3401,7 +3400,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
break;
case 12: // SRB2kart: Invert Encore Remap
break;
case 15: // no idea but keep it dont want anything to break
case 15: // also Invert Encore Remap....
break;
}
DoneSection2:
@@ -3880,7 +3879,7 @@ DoneSection2:
player->kartstuff[k_lapanimation] = 80;
if (UNLIKELY(player->pflags & PF_NIGHTSMODE))
if (nightsplayer(player))
player->drillmeter += 48*20;
if (netgame && player->laps >= (UINT8)cv_numlaps.value)
@@ -4611,7 +4610,7 @@ void P_UpdateSpecials(void)
// POINT LIMIT
P_CheckPointLimit();
#ifdef COMPAT_VANILLA
#ifndef PHOBOS_BUILD
// Dynamic slopeness
// we run this here only when not joined midrace
// for vanilla compat reasons :chaosleep:
@@ -5302,6 +5301,18 @@ static void P_RunLevelLoadExecutors(void)
}
}
static fixed_t P_GetSectorGravityFactor(sector_t *sec)
{
return FixedDiv(*sec->gravity >> FRACBITS, 1000);
}
fixed_t P_GetSectorGravity(sector_t *sec)
{
if (sec && sec->gravity)
return FixedMul(gravity, P_GetSectorGravityFactor(sec));
return gravity;
}
/** After the map has loaded, scans for specials that spawn 3Dfloors and
* thinkers.
*
@@ -5363,6 +5374,11 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
case 11: // Custom global gravity!
gravity = sector->floorheight/1000;
break;
case 12: // SRB2kart: Invert Encore Remap
case 15: // NOTE: vanilla kart checks only for this for some reason!
sector->flags |= SF_INVERTENCORE;
break;
}
// Process Section 4
@@ -5372,6 +5388,10 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
if (G_RaceGametype())
circuitmap = true;
break;
case 12: // Camera noclip
sector->flags |= SF_NOCLIPCAMERA;
break;
}
}
@@ -5456,11 +5476,11 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
sectors[s].gravity = &sectors[sec].floorheight; // This allows it to change in realtime!
if (lines[i].flags & ML_NOCLIMB)
sectors[s].verticalflip = true;
sectors[s].flags |= SF_GRAVITYFLIP;
else
sectors[s].verticalflip = false;
sectors[s].flags &= ~SF_GRAVITYFLIP;
CheckForReverseGravity = sectors[s].verticalflip;
CheckForReverseGravity = (boolean)(sectors[s].flags & SF_GRAVITYFLIP);
}
break;
@@ -5553,6 +5573,11 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
sectors[s].cullheight = &lines[i]; // This allows it to change in realtime!
break;
case 13: // Heat wave effect
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
sectors[s].flags |= SF_HEATWAVE;
break;
case 50: // Insta-Lower Sector
EV_DoFloor(&lines[i], instantLower);
break;
@@ -7126,7 +7151,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)) || UNLIKELY(thing->player->pflags & PF_NIGHTSMODE)))
if (thing->player && (!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) || nightsplayer(thing->player)))
{
INT32 dist;
INT32 speed;
@@ -7156,7 +7181,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 (LIKELY(!(thing->player->pflags & PF_NIGHTSMODE)))
if (!nightsplayer(thing->player))
{
// only push wrt Z if health & 1 (mapthing has ambush flag)
if (tmpusher->source->health & 1)
+2
View File
@@ -56,6 +56,8 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
void P_PlayerInSpecialSector(player_t *player);
void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector);
fixed_t P_GetSectorGravity(sector_t *sec);
fixed_t P_FindLowestFloorSurrounding(sector_t *sec);
fixed_t P_FindHighestFloorSurrounding(sector_t *sec);
+1 -1
View File
@@ -651,7 +651,7 @@ void P_Ticker(boolean run)
if (run)
{
// Dynamic slopeness
#ifdef COMPAT_VANILLA
#ifndef PHOBOS_BUILD
if (midgamejoin) // only run here if we joined midgame to fix some desynchs
#endif
P_RunDynamicSlopes();
+50 -35
View File
@@ -74,7 +74,7 @@ void P_Thrust(mobj_t *mo, angle_t angle, fixed_t move)
mo->momx += FixedMul(move, FINECOSINE(angle));
if (LIKELY(!(twodlevel || (mo->flags2 & MF2_TWOD))))
if (!twodmo(mo))
mo->momy += FixedMul(move, FINESINE(angle));
}
@@ -90,8 +90,8 @@ void P_InstaThrust(mobj_t *mo, angle_t angle, fixed_t move)
mo->momx = FixedMul(move, FINECOSINE(angle));
if (LIKELY(!(twodlevel || (mo->flags2 & MF2_TWOD))))
mo->momy = FixedMul(move,FINESINE(angle));
if (!twodmo(mo))
mo->momy = FixedMul(move, FINESINE(angle));
}
void P_InstaThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move)
@@ -475,7 +475,7 @@ void P_PlayLivesJingle(player_t *player)
if (UNLIKELY(use1upSound))
S_StartSound(NULL, sfx_oneup);
else if (UNLIKELY(mariomode))
else if (mariomode)
S_StartSound(NULL, sfx_marioa);
else
{
@@ -503,7 +503,7 @@ void P_PlayRinglossSound(mobj_t *source, mobj_t *damager)
S_StartSound(NULL, sfx);
}
else
S_StartSound(source, UNLIKELY(mariomode) ? sfx_mario8 : sfx_khurt1 + key);
S_StartSound(source, mariomode ? sfx_mario8 : sfx_khurt1 + key);
}
else
S_StartSound(source, sfx_slip);
@@ -625,15 +625,23 @@ boolean P_EndingMusic(player_t *player)
}
if (G_RaceGametype() && bestlocalpos == MAXPLAYERS+1)
sprintf(buffer, "k*fail"); // F-Zero death results theme
{
snprintf(buffer, sizeof(buffer), "k*fail"); // F-Zero death results theme
}
else
{
if (bestlocalpos == 1)
sprintf(buffer, "k*win");
{
snprintf(buffer, sizeof(buffer), "k*win");
}
else if (isPlayerLosing(bestlocalplayer))
sprintf(buffer, "k*lose");
{
snprintf(buffer, sizeof(buffer), "k*lose");
}
else
sprintf(buffer, "k*ok");
{
snprintf(buffer, sizeof(buffer), "k*ok");
}
}
S_SpeedMusic(1.0f);
@@ -1009,7 +1017,7 @@ boolean P_IsLocalPlayer(const player_t *player)
}
//
// P_IsLocalPlayer
// P_IsLocalPlayerNum
//
// Returns true if playernum is
// on the local machine.
@@ -1725,7 +1733,7 @@ static void P_DoBubbleBreath(player_t *player)
else
zh = player->mo->z + FixedDiv(player->mo->height,5*(FRACUNIT/4));
if (!(player->mo->eflags & MFE_UNDERWATER) || player->spectator || ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && !(player->pflags & PF_NIGHTSMODE)))
if (!(player->mo->eflags & MFE_UNDERWATER) || player->spectator || ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && !nightsplayer(player)))
return;
if (P_RandomChance(FRACUNIT/16))
@@ -2298,7 +2306,7 @@ static void P_MovePlayer(player_t *player)
P_3dMovement(player);
}
if (UNLIKELY(maptol & TOL_2D)) // psure this doesent even work at all
if (twodlevel) // psure this doesent even work at all
runspd = FixedMul(runspd, 2*FRACUNIT/3);
/////////////////////////
@@ -2748,8 +2756,8 @@ boolean P_LookForEnemies(player_t *player)
if (modist > FixedMul(RING_DIST, player->mo->scale))
continue; // out of range
if (UNLIKELY((twodlevel || player->mo->flags2 & MF2_TWOD)
&& abs(player->mo->y-mo->y) > player->mo->radius))
if (twodmo(player->mo) && abs(player->mo->y-mo->y) > player->mo->radius)
continue; // not in your 2d plane
if (closestmo && modist > P_AproxDistance(P_AproxDistance(player->mo->x-closestmo->x,
@@ -3508,7 +3516,7 @@ static boolean P_CheckNoclipCameraPosition(player_t *player, camera_t *thiscam,
boolean cameranoclip;
mobj_t *mo = player->mo;
cameranoclip = ((player->pflags & (PF_NOCLIP|PF_NIGHTSMODE))
cameranoclip = (nightsplayer(player)
|| (mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)) // Noclipping player camera noclips too!!
|| (leveltime < introtime)); // Kart intro cam
@@ -3553,7 +3561,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) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || (rover->master->frontsector->flags & SF_NOCLIPCAMERA))
continue;
topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
@@ -3618,7 +3626,7 @@ static boolean P_CheckNoclipCameraPosition(player_t *player, camera_t *thiscam,
// We're inside it! Yess...
polysec = po->lines[0]->backsector;
if (UNLIKELY(GETSECSPECIAL(polysec->special, 4) == 12))
if (polysec->flags & SF_NOCLIPCAMERA)
{ // Camera noclip polyobj.
plink = (polymaplink_t *)(plink->link.next);
continue;
@@ -3674,7 +3682,8 @@ static boolean P_CheckNoclipCameraPosition(player_t *player, camera_t *thiscam,
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (UNLIKELY((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) && (rover->master->frontsector->flags & SF_NOCLIPCAMERA))
{
topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
@@ -4097,7 +4106,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
angle -= (angle - thiscam->pitch)/2;
}
if (player->playerstate != PST_DEAD && LIKELY(!((player->pflags & PF_NIGHTSMODE) && player->exiting)))
if (player->playerstate != PST_DEAD && !(nightsplayer(player) && player->exiting))
angle += (focusaiming < ANGLE_180 ? focusaiming/2 : InvAngle(InvAngle(focusaiming)/2)); // overcomplicated version of '((signed)focusaiming)/2;'
if (!camstill && !timeover) // Keep the view still...
@@ -4174,7 +4183,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 (UNLIKELY(G_GametypeHasTeams()))
else if (G_GametypeHasTeams())
{
INT32 changeto = 0;
INT32 z, numplayersred = 0, numplayersblue = 0;
@@ -4254,7 +4263,7 @@ boolean P_SpectatorJoinGame(player_t *player)
static boolean P_CameraCheckHeatFirstperson(player_t *player, sector_t *sector, fixed_t pviewheight)
{
if (P_FindSpecialLineFromTag(13, sector->tag, -1) != -1)
if (sector->flags & SF_HEATWAVE)
return true;
if (sector->ffloors)
@@ -4272,7 +4281,7 @@ static boolean P_CameraCheckHeatFirstperson(player_t *player, sector_t *sector,
if (pviewheight <= P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y))
continue;
if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1)
if (rover->master->frontsector->flags & SF_HEATWAVE)
return true;
}
}
@@ -4508,27 +4517,33 @@ static void DoABarrelRoll(player_t *player)
static void P_DoFunnyDance(player_t *player)
{
fixed_t bpm; // 140bpm ish
fixed_t work, ang, bounce; // hehe squishy
if (player->spectator || !player->mo || player->kartstuff[k_respawn] || player->mo->salty.jump) // this looks jank as hell during hop
I_Assert(player != NULL);
I_Assert(!P_MobjWasRemoved(player->mo));
if (player->spectator)
return;
player->squishdance.bounce = 0;
// this looks jank as hell during hop or respawn
if (player->kartstuff[k_respawn] || player->salty.jump)
return;
// bpm = FixedDiv((60*TICRATE)<<FRACBITS, FLOAT_TO_FIXED(mapmusic.bpm)); << maybe can get the tempo and beat detection lib to work for bpm autodetection
bpm = FixedDiv((60*TICRATE)<<FRACBITS, FLOAT_TO_FIXED((float)cv_squishdancespeed.value));
bpm = ((60*TICRATE) / (cv_squishdancespeed.value)) << FRACBITS;
player->squishdance.work = (player->squishdance.time << FRACBITS) % bpm;
work = (player->squishdance.time << FRACBITS) % bpm;
if (player->squishdance.time >= (FRACUNIT >> 1)) // prevent overflow jump - takes about 15 minutes
player->squishdance.time = (player->squishdance.work >> FRACBITS);
player->squishdance.time = (work >> FRACBITS);
player->squishdance.work = FixedDiv(player->squishdance.work*180, bpm);
work = FixedDiv(work*180, bpm);
player->squishdance.ang = ((FixedAngle(player->squishdance.work) >> ANGLETOFINESHIFT) & FINEMASK);
player->squishdance.bounce = ((FINESINE(player->squishdance.ang) - FRACUNIT/2) / 2);
ang = ((FixedAngle(work) >> ANGLETOFINESHIFT) & FINEMASK);
bounce = ((FINESINE(ang) - FRACUNIT/2) / 2);
player->mo->spritexscale -= player->squishdance.bounce;
player->mo->spriteyscale += player->squishdance.bounce;
player->mo->spritexscale -= bounce;
player->mo->spriteyscale += bounce;
player->squishdance.time++;
}
@@ -4871,7 +4886,7 @@ void P_PlayerThink(player_t *player)
// Even if not NiGHTS, pull in nearby objects when walking around as John Q. Elliot.
if (UNLIKELY(!objectplacing && !((netgame || multiplayer) && player->spectator)
&& maptol & TOL_NIGHTS && (!(player->pflags & PF_NIGHTSMODE) || player->powers[pw_nights_helper])))
&& nightsmode && (!nightsplayer(player) || player->powers[pw_nights_helper])))
{
thinker_t *th;
mobj_t *mo2;
@@ -4973,7 +4988,7 @@ void P_PlayerThink(player_t *player)
#endif
// check for use
if (LIKELY(!(player->pflags & PF_NIGHTSMODE)))
if (!nightsplayer(player))
{
if (cmd->buttons & BT_BRAKE)
player->pflags |= PF_USEDOWN;
@@ -5164,7 +5179,7 @@ void P_PlayerAfterThink(player_t *player)
}
}
if (UNLIKELY(player->pflags & PF_NIGHTSMODE))
if (nightsplayer(player))
{
player->powers[pw_gravityboots] = 0;
}
+4 -5
View File
@@ -48,8 +48,7 @@ boolean g_walloffscreen = false;
boolean R_NoEncore(sector_t *sector, boolean ceiling)
{
const INT32 invspecial = GETSECSPECIAL(sector->special, 2);
boolean invertencore = (invspecial == 12 || invspecial == 15); // keeping this incase its used
const boolean invertEncore = (sector->flags & SF_INVERTENCORE);
#if 0 // perfect implementation
const INT32 sprnspecial = GETSECSPECIAL(sector->special, 3);
@@ -59,10 +58,10 @@ boolean R_NoEncore(sector_t *sector, boolean ceiling)
#endif
&& GETSECSPECIAL(sector->special, 4) != 6) // sneaker panel
{
return invertencore;
return invertEncore;
}
if (invertencore)
if (invertEncore)
{
return false;
}
@@ -395,7 +394,7 @@ static void R_AddLine(seg_t *line)
// Find the other side!
INT32 line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->linedef->tag, -1);
if (line->linedef == &lines[line2])
if (line2 >= 0 && line->linedef == &lines[line2])
line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->linedef->tag, line2);
if (line2 >= 0) // found it!
+13 -5
View File
@@ -307,10 +307,19 @@ typedef struct pslope_s
typedef enum
{
SF_FLIPSPECIAL_FLOOR = 1,
SF_FLIPSPECIAL_CEILING = 2,
SF_FLIPSPECIAL_BOTH = 3,
SF_TRIGGERSPECIAL_TOUCH = 4,
// flipspecial - planes with effect
SF_FLIPSPECIAL_FLOOR = 1,
SF_FLIPSPECIAL_CEILING = 1<<1,
SF_FLIPSPECIAL_BOTH = (SF_FLIPSPECIAL_FLOOR|SF_FLIPSPECIAL_CEILING),
// triggerspecial - conditions under which plane touch causes effect
SF_TRIGGERSPECIAL_TOUCH = 1<<2,
SF_GRAVITYFLIP = 1<<3,
SF_HEATWAVE = 1<<4,
SF_NOCLIPCAMERA = 1<<5,
// invert encore color remap status
SF_INVERTENCORE = 1<<6,
} sectorflags_t;
//
@@ -391,7 +400,6 @@ typedef struct sector_s
// This points to the master's floorheight, so it can be changed in realtime!
fixed_t *gravity; // per-sector gravity
boolean verticalflip; // If gravity < 0, then allow flipped physics
sectorflags_t flags;
// Sprite culling feature
+10 -12
View File
@@ -174,15 +174,10 @@ static void BlendTab_Translucent(UINT8 *table, int style, UINT8 blendamt)
{
frontrgba = pGammaCorrectedPalette[fg];
#if 0 // perfect implementation
result.rgba = ASTBlendPixel(backrgba, frontrgba, style, 0xFF);
result.rgba = ASTBlendPixel(result, frontrgba, AST_TRANSLUCENT, blendamt);
table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut, result.s.red, result.s.green, result.s.blue);
#else // performance scrabbler
result.rgba = ASTBlendPixel(backrgba, frontrgba, style, 0xFF);
result.rgba = ASTBlendPixel(result, frontrgba, AST_TRANSLUCENT, blendamt);
table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut_corrected, result.s.red, result.s.green, result.s.blue); // pGammaCorrectedPalette
#endif
}
}
}
@@ -190,6 +185,7 @@ static void BlendTab_Translucent(UINT8 *table, int style, UINT8 blendamt)
static void BlendTab_Subtractive(UINT8 *table, int style, UINT8 blendamt)
{
INT16 bg, fg;
RGBA_t backrgba, frontrgba, result;
if (table == NULL)
I_Error("BlendTab_Subtractive: input table was NULL!");
@@ -202,11 +198,11 @@ static void BlendTab_Subtractive(UINT8 *table, int style, UINT8 blendamt)
for (bg = 0; bg < 0x100; bg++)
{
backrgba = pLocalPalette[bg]; // intentionally uses pLocalPalette
for (fg = 0; fg < 0x100; fg++)
{
RGBA_t backrgba = V_GetColor(bg);
RGBA_t frontrgba = V_GetColor(fg);
RGBA_t result;
frontrgba = pLocalPalette[fg];
result.rgba = ASTBlendPixel(backrgba, frontrgba, style, 0xFF);
result.s.red = std::max(0, result.s.red - blendamt);
@@ -221,17 +217,19 @@ static void BlendTab_Subtractive(UINT8 *table, int style, UINT8 blendamt)
static void BlendTab_Modulative(UINT8 *table)
{
INT16 bg, fg;
RGBA_t backrgba, frontrgba, result;
if (table == NULL)
I_Error("BlendTab_Modulative: input table was NULL!");
for (bg = 0; bg < 0x100; bg++)
{
backrgba = pGammaCorrectedPalette[bg];
for (fg = 0; fg < 0x100; fg++)
{
RGBA_t backrgba = V_GetColor(bg);
RGBA_t frontrgba = V_GetColor(fg);
RGBA_t result;
frontrgba = pGammaCorrectedPalette[fg];
result.rgba = ASTBlendPixel(backrgba, frontrgba, AST_MODULATE, 0);
table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut_corrected, result.s.red, result.s.green, result.s.blue);
}
+1 -1
View File
@@ -6,7 +6,7 @@
// Copyright (C) 1996 by id Software, Inc.
// Copyright (C) 1999 by Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
// Copyright (C) 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
// Copyright (C) Copyright 2005, 2006 by Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
// Copyright (C) 2005, 2006 by Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
// Copyright (C) 2013 by James Haley, Stephen McGranahan, et al.
//
// This program is free software distributed under the
+40 -11
View File
@@ -757,6 +757,45 @@ void R_UpdateMobjInterpolators(void)
}
}
// reset banan and eggbox rollangle when they´re on the ground
// if not cv_bananthrowroll option "+Onground"
static void R_ResetBananaRollangle(mobj_t* mobj)
{
if (!mobj->rollangle)
return;
if (mobj->type != MT_BANANA && mobj->type != MT_EGGMANITEM) // always reset eggboxes
return;
// keep banans "rotated" if we want them to
if (mobj->type == MT_BANANA && cv_bananthrowroll.value == 2)
return;
// only reset if on ground
if (!P_IsObjectOnGround(mobj))
return;
mobj->rollangle = 0;
}
// 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
static void R_ResetMobjSpriteStuff(mobj_t *mobj)
{
mobj->spritexscale = mobj->realxscale;
mobj->spriteyscale = mobj->realyscale;
mobj->spritexoffset = mobj->realxoffset;
mobj->spriteyoffset = mobj->realyoffset;
mobj->temprollangle = 0;
// kinda stupid but idk where else to put this
R_ResetBananaRollangle(mobj);
}
//
// P_ResetMobjInterpolationState
//
@@ -795,19 +834,9 @@ 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->temprollangle = 0;
R_ResetMobjSpriteStuff(mobj);
mobj->resetinterp = false;
}
+21 -4
View File
@@ -411,7 +411,7 @@ angle_t R_PlayerSliptideAngle(player_t *player)
if (!sprframe)
return 0;
if (sprframe->rotate != SRF_SINGLE || (mo->frame & FF_PAPERSPRITE))
if (sprframe->rotate != SRF_SINGLE || R_ThingIsPaperSprite(mo))
ang = R_PointToAngle(mo->x, mo->y) - mo->angle;
return FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), mo->player->sliproll * mo->player->kartstuff[k_aizdriftstrat]);
@@ -1389,6 +1389,21 @@ void R_RenderPlayerView(player_t *player)
maskcount_t* masks = static_cast<maskcount_t*>(malloc(sizeof(maskcount_t)));
const boolean skybox = (skyboxmo[0] && cv_skybox.value);
// Only do it if it's the first screen being rendered
if (cv_homremoval.value && viewssnum == 0)
{
if (cv_homremoval.value == 1)
{
// Clear the software screen buffer to remove HOM
memset(vid.screens[0], 31, vid.width * vid.height);
}
else if (cv_homremoval.value == 2)
{
//'development' HOM removal -- makes it blindingly obvious if HOM is spotted.
memset(vid.screens[0], 32+(timeinmap&15), vid.width * vid.height);
}
}
// load previous saved value of skyVisible for the player
skyVisible = skyVisiblePerPlayer[viewssnum];
@@ -1455,10 +1470,12 @@ void R_RenderPlayerView(player_t *player)
NetUpdate();
R_SetColumnContext(COLUMNCONTEXT_FLUSH);
ps_numbspcalls.value.i = ps_numpolyobjects.value.i = ps_numdrawnodes.value.i = 0;
PS_START_TIMING(ps_bsptime);
R_RenderViewpoint(&masks[nummasks - 1], true);
PS_STOP_TIMING(ps_bsptime);
PS_START_TIMING(ps_sw_spritecliptime);
R_ClipSprites(drawsegs, NULL);
PS_STOP_TIMING(ps_sw_spritecliptime);
@@ -1466,8 +1483,8 @@ void R_RenderPlayerView(player_t *player)
ps_numsprites.value.i = numvisiblesprites;
PS_START_TIMING(ps_sw_portaltime);
// Portal rendering. Hijacks the BSP traversal.
PS_START_TIMING(ps_sw_portaltime);
if (portal_base)
{
portal_t *portal;
@@ -1508,8 +1525,7 @@ void R_RenderPlayerView(player_t *player)
R_SetColumnContext(COLUMNCONTEXT_DIRECT);
PS_START_TIMING(ps_sw_planetime);
if (!skybox)
R_DrawSkyPlanes();
R_DrawSkyPlanes();
R_DrawPlanes();
PS_STOP_TIMING(ps_sw_planetime);
// draw mid texture and sprite
@@ -1517,6 +1533,7 @@ void R_RenderPlayerView(player_t *player)
PS_START_TIMING(ps_sw_maskedtime);
R_DrawMasked(masks, nummasks);
PS_STOP_TIMING(ps_sw_maskedtime);
free(masks);
// Check for new console commands.
+5 -2
View File
@@ -272,7 +272,7 @@ static boolean TrimVisplaneBounds(const visplane_t* plane, INT16* start, INT16*
* Applies the necessary offsets and rotation to give
* a depth illusion to the skybox.
*/
void Portal_AddSkybox(const visplane_t* plane)
static void Portal_AddSkybox(const visplane_t* plane)
{
INT16 start, end;
mapheader_t *mh;
@@ -333,10 +333,13 @@ void Portal_AddSkyboxPortals(void)
INT32 i;
UINT16 count = 0;
for (i = 0; i < MAXVISPLANES; i++, pl++)
for (i = 0; i < MAXVISPLANES; i++)
{
for (pl = visplanes[i]; pl; pl = pl->next)
{
if (pl->minx >= pl->maxx)
continue;
if (pl->picnum == skyflatnum)
{
Portal_AddSkybox(pl);
Loaded 100 of 132 files, more files were not shown because too many files have changed in this diff. Show more