Compare commits

..
293 Commits
Author SHA1 Message Date
alufolie91 9936f9c740 have Z_IsMobjValid2 print an error in console
if mobj pointer is invalid
the callee should handle the behavior
2026-10-02 18:23:29 +02:00
alufolie91 bee5c8e5ed add code to check for mobj pointer validity
as we use the pool allocator we may check if a mobj points into the address range of the level pool specific to mobj allocations (g_level_large_pool)
this may help in debugging stuff without the need to run things like ASAN or valgrind
2026-10-02 18:23:26 +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 0c440d240c can pass char to this now
no need to reconvert this stuff from const char to std::string and back to const char really lol
2026-07-24 15:54:50 +02:00
alufolie91 5c7be85977 fix cmake
.ch..........
2026-07-24 15:50:35 +02:00
alufolie91 c401926c0b fix lua hook profiler drawing out of screen bounds in some cases
this omits alot of hooks in the profiler, tho not sure if anyone should even care about those back in the list
maybe just have it have multiple pages like perfstats, or better just integrate it into perfstats......
2026-07-24 15:48:57 +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 957d3f7229 delet fmt for lua hook profiler
i dont want another stinky library
this would just be an arsepain to include in windoze builds

TODO: make this drawer less of a mess, maybe integrate into perfstats instead?
2026-07-24 15:31:16 +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
alufolie91 38a248193e make lua hook profiler kinda work
very scuffed up since we dont have the srb2::Draw lib
so it may display stuff out of screen bounds
i also rather not use fmt here but va since i dont want another dependency
needs to be fixed up sometime
2026-07-01 18:15:38 +02:00
James R 934f2d347c Add basic profiling for Lua hooks (except HUD hooks)
- Add lua_profile cheat: calculate average time spent in
  hooks over a period
- Show hook times in a sorted table, along with lump name,
  script line number and hook type
- Show cumulative time spent in game logic hooks and
  percentage of overhead to game logic
2026-07-01 18:13:51 +02:00
alufolie91 551d7d4d89 add V_DrawRightAlignedSmallStringAtFixed
idk but might be useful
2026-07-01 18:08:56 +02:00
alufolie91 a2184d2bef move cv_audbuffersize register
this stuff kinda grouped some cvars together, makes more sense there
2026-07-01 18:08:53 +02:00
alufolie91 d638baeda6 change mobj hook detection again
so we can restore the actual correct behavior for the HurtMsg hook, which nothing even uses lol
2026-07-01 18:08:50 +02:00
alufolie91 4a06e8a6d1 fix map replacement checks for pwads added on startup
stuff added per -file or whatever
this incorrectly rechecked the iwads again instead of the pwads themselves, which let to the game flagging vanilla maps as replaced, setting the game to be modified
2026-06-30 18:37:04 +02:00
alufolie91 e2a3992787 make online hud / chat menu scrollable
yes i checked green res....
it barely fits like this........
2026-06-29 22:02:18 +02:00
indev ec06150432 This todo is done :3 2026-06-29 20:45:45 +03:00
indev 2413a3503c Add stairjank particle effect using drift dust 2026-06-29 20:44:30 +03:00
alufolie91 d9e339cb56 toggable sound effect for stair jank
not the biggest fan of it but idk how to make this better on stairs with lots of steps
so this will do for now
2026-06-29 18:13:30 +02:00
alufolie91 408db7a2eb use G_KeynumToString for local addon menu key info
just in case we change them dont have to change them everywhere
2026-06-29 15:46:11 +02:00
alufolie91 e12ecabcf0 revert some P_IsObjectOnGround
pretty sure none of those cause issues currently, but rather not risk stuff as that condition might change from smth else in those cases
its not an expensive call anyways really
2026-06-29 15:35:45 +02:00
alufolie91 65c2d2733d clear deathmatch and ctf spawnpoints aswell
prob wont matter much for us but still better to not leave those dangling after map change
2026-06-29 14:43:04 +02:00
alufolie91 00aa023e9e cleanup p_setup a bit again 2026-06-29 14:42:58 +02:00
alufolie91 f43a4a2eb6 have gametype i_error actually print the invalid gametype
bit more informative ig?
2026-06-29 02:14:53 +02:00
alufolie91 4eb108e0a6 add sound thing for reference
does nothing cause it sucks
maybe someone else has a better idea what to do here
2026-06-29 02:13:59 +02:00
alufolie91 ea76af5a81 seenames is stupid
keep that ashnal utils breaks without this crap
2026-06-29 01:46:39 +02:00
alufolie91 4b8f998c85 cast this crap 2026-06-28 22:58:20 +02:00
alufolie91 d687be4997 change K_GetSpeedometerStyle to unsinged
does not need be signed
most other things will cache this into an uint8 eitherway
2026-06-28 22:34:09 +02:00
alufolie91 1bcadf3c46 fix the lap emblem animation thingie 2026-06-28 22:23:32 +02:00
alufolie91 80e4d02c51 dont skip intro sounds if music is disabled 2026-06-28 21:13:28 +02:00
alufolie91 352d1faacf forgor cv_chat_showlimit :chaosleep: 2026-06-28 18:59:28 +02:00
alufolie91 7f9d70285d add new chat stuff to menus + show chat box when hovering over some things
very ugly but i dont care, the hud stuff is done similar
just hoping this doesent explode or whatever
2026-06-28 18:53:28 +02:00
alufolie91 496477fa9a chatbgtint does actually not apply to the chatbox
but only to the also confusingly named "mini chat"
2026-06-28 18:37:11 +02:00
alufolie91 530bb50709 ig "style" is the better word here
lulul
2026-06-28 17:53:57 +02:00
alufolie91 8bb04a68a8 ass well 2026-06-28 17:52:53 +02:00
alufolie91 820ab4b2bc block "addfilelocal" from adding files that contains maps
now we have a more accessible menu for addfile local
i really dont want to risk stuff
2026-06-28 16:25:31 +02:00
alufolie91 af6abb5458 better check for map data within autoloaded files
before this flagged every file with lumps that contained the MAP as string somewhere, like palettes and such

this is kinda messy but i really do not want to dupe this huge block of code, neither do i want to convert this to ceepeepee again to mess about with templates
oh well
2026-06-28 16:23:24 +02:00
alufolie91 5c373b6251 demote those to asserts
never seen srb2, saturn, RR or blan or anything else have this return null
there is a possibility but whatever
just continuing in such cases was wrong eitherways as it wouldve just corrupted the vres thing
2026-06-28 16:05:14 +02:00
alufolie91 24bac9c133 actually print a different message for localskins with lua
tell ppl that this may cause issues
2026-06-28 16:05:11 +02:00
alufolie91 73c7a5a0c4 add better description for skip intro music stuff 2026-06-28 00:40:54 +02:00
alufolie91 49d6374505 have local skin message account for "KCL" prefix
for skins with lua
2026-06-28 00:27:02 +02:00
GLide KS 2ba4757c6a Hopefully a cleaner implementation of Local Addon switch 2026-06-28 00:26:59 +02:00
romoney5 3606b0ae66 Don't disable console on resync 2026-06-28 00:26:56 +02:00
romoney5 ba75523d48 Print a warning when archiving an invalid Lua value 2026-06-28 00:26:54 +02:00
alufolie91 71640202ed better polyobj count error for savegame
from Banpyura
gonna look into their return to menu instead of i_error stuff sometime
2026-06-27 23:42:16 +02:00
alufolie91 5fb5af05be this is P_NetUnArchiveThinkers lululul 2026-06-27 23:39:32 +02:00
indev 4f036c9312 Fix setupm_ip going out of textbox when its not being edited 2026-06-28 00:14:56 +03:00
alufolie91 d99c272a79 have textboxes "reserve" space for cursor
so it wont draw outside the textbox but rather scrolls
2026-06-27 23:14:40 +02:00
alufolie91 c4ed75fbc6 port over some chat stuff from SRB2-Banpyura
per https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2784

chat offsets and character count
offsets are added to the base offset like we do for hud stuff, the og pr will directly use the cvar values for this, but wanna keep consistent with our rest
needs to be added in the menu somewhere but idk where
2026-06-27 22:43:57 +02:00
alufolie91 91927e324b ,
this menu been broken since 4 months lol
2026-06-27 20:40:33 +02:00
alufolie91 13dc0db9a9 add stairjank and skydome stuff to menu
pls someone gib a better description for skydome idk ingles
2026-06-27 20:29:19 +02:00
alufolie91 8aafde4c9d "less" 2026-06-27 20:05:51 +02:00
alufolie91 266a4effb7 fix fogblock not accounting for fake contrast
super old oopsie lulul
2026-06-27 14:18:13 +02:00
alufolie91 948c9399de fix HWR_SplitWall again..
theres guards just above this which should just skip shit but for some reason the clamps still do stuff, idk man
fixes the weird grass fof in green hill
2026-06-27 14:18:10 +02:00
alufolie91 db4aedf498 readd missing setblend for sky bg
oopsie forgor to copy this back
2026-06-27 14:18:04 +02:00
alufolie91 f12d5a246d just dont set shader for this ig
otherwise this breaks when you disable the hud for whatever reason
looks the same so whatever
2026-06-26 19:54:20 +02:00
alufolie91 6efe56808a make sky "dome/barreling" toggable
per "skydome" cvar
using karts old sky code for gl since it appears to differ a bit from srb2 and id want to keep this "authentic" to old kart
2026-06-26 17:44:40 +02:00
alufolie91 ec047151e3 toggable stair "jank" visuals
akin to RR, just toned down for smaller kart chars
also toggable ofc
theres not that many stairs in kart but this looks cute with smol bumps in the road
wish this would work on slopes but theyre kinda messed up lol
2026-06-26 17:44:37 +02:00
alufolie91 b1100d6215 add mobj "temprollangle" field
same as rollangle but resets at beginning on each tic
i dont feel like exposing this to lua atm, so if someone wants to or if even needed at all
2026-06-23 18:24:27 +02:00
alufolie91 cb8df4c3d0 change how banana rotation throw stuff works
noticed sloperoll does not properly work from certain angles
so just reset rollangle if needed in K_RollMobjBySlopes since couldnt find a better place tbh
2026-06-23 18:21:04 +02:00
alufolie91 fbae43f61a move spinoutroll to k_hud
hud thing for minimap so should be in there
2026-06-23 00:11:47 +02:00
mazmazz 7ea95b4495 Fix OSX null-pointer-arithmetic error 2026-06-22 23:14:51 +02:00
alufolie91 07c780dc9c add missing null terminator for player name on server info screen 2026-06-22 23:10:36 +02:00
alufolie91 f6d3ab1f3a more random style cleanup
had those lying around in lugstuff branch
2026-06-22 21:05:10 +02:00
alufolie91 2c8099e228 make builds with more than 16 players undefine COMPAT_VANILLA 2026-06-22 20:57:24 +02:00
alufolie91 7c84dd5661 raise NUMMOBJFREESLOTS to 4096 on non vanilla compat build 2026-06-22 20:57:21 +02:00
alufolie91 cabd8baae5 some P_MobjWasRemoved for non COMPAT_VANILLA builds 2026-06-22 20:57:10 +02:00
alufolie91 593540a3f9 add flag "COMPAT_VANILLA"
undefine to enable features that are not vanilla compatible
2026-06-22 20:56:53 +02:00
alufolie91 407af1d25c Merge branch 'maperrors2' into Saturn-Next 2026-06-22 20:54:53 +02:00
alufolie91 029c21eae8 correct map issues clientside
but be loud about it instead of I_Error´ing
most of those would be fatal anyways, so screw vanilla desyncing if they crash eitherways
2026-06-22 20:53:49 +02:00
entryway 568f29ed1c Check for blockmap overflow in P_BlockLinesIterator. Under RANGECHECK define. 2026-06-22 20:52:49 +02:00
alufolie91 2dacc333b5 just set backsector to NULL
if not in vanilla doom compat mode/overflow emulation GetSectorAtNullAddress will just return NULL, so we can do so aswell
2026-06-22 20:52:42 +02:00
alufolie91 363612c488 port more checks from dsda-doom for invalid map data
decided to have it i_error for now, not sure what exactly is the best approach here
should we just "correct" some of those instead?
vanilla probably just crashes anyways
2026-06-22 20:52:19 +02:00
alufolie91 d8ffffd86e replace non valid sidenum magic number
with what dsda-doom uses
2026-06-22 20:52:11 +02:00
alufolie91 4b2a13defb cleanup K_DropItems a bit
move "paperitem" spawn to its separate function like RR
2026-06-21 23:30:20 +02:00
alufolie91 9cc74d8b17 use P_MobjWasRemoved for P_MoveChaseCamera
dont need to care about synch safety here....
2026-06-21 23:07:20 +02:00
alufolie91 066adb972e add some more mobj null checks to P_MobjThinker
from srb2 ig
2026-06-21 23:07:17 +02:00
alufolie91 0f1ad8a086 few more smaller cleanups 2026-06-21 23:07:12 +02:00
alufolie91 40537eca81 cleanup P_KillMobj a little 2026-06-21 23:03:45 +02:00
AJ Martinez 0cff3c23f3 Don't attempt itemamount correction after orbitals self-destruct 2026-06-21 22:35:20 +02:00
alufolie91 9bdda66a0c rename this to D_CheckMapReplacements 2026-06-21 19:14:22 +02:00
alufolie91 3b6a09da9b oops 2026-06-21 19:04:48 +02:00
Zwip-Zwap Zapony c275555678 Draw the input prompt while the console is moving 2026-06-21 19:00:10 +02:00
Zwip-Zwap Zapony fc588f8046 Make con_height adjustable on the fly 2026-06-21 19:00:07 +02:00
alufolie91 17093e8022 add command to list unused map slots
less pain for server owners
hope this is sufficient
2026-06-21 18:03:50 +02:00
alufolie91 b575c288fa allow page up/down to scroll through chat
like in console
2026-06-18 17:31:36 +02:00
indev f9a6702219 Fix player node staying muted when player leaves 2026-06-18 17:28:27 +03:00
indev cfda853e6f Add console variant for mute command, also fix it applying mute for players that are not in game 2026-06-18 16:35:48 +03:00
alufolie91 14ac3ca9b0 ;;... 2026-06-16 20:05:12 +02:00
alufolie91 e94fecf56d cleanup even more style issues
also should fix R_InitSprites printing the wrong spritename in some cases
2026-06-16 19:08:04 +02:00
alufolie91 51d9aa6197 add credit to bayer dither shader sources
completely forgot about this (sry!)
the original implementation was mostly based on hughsk´s 8x8 bayer shader while the current is mostly adapted from the libretro 4x4 bayer shader
2026-06-16 12:32:02 +02:00
alufolie91 96a29abc62 move this back
might change behavior of this, which may desynch in rare cases
2026-06-15 14:53:59 +02:00
alufolie91 fa1b797a44 handle interrupt signals during CONS_Error
also move stuff into smol inline function
2026-06-15 14:51:35 +02:00
alufolie91 e1061ab4b4 add PARANOIA cases for reject and blockmap stuff
also see comment
2026-06-13 15:11:41 +02:00
alufolie91 ab0d071d35 use sizeu1 instead of %lu
windoze.......
2026-06-13 13:41:06 +02:00
alufolie91 8129b89034 port P_VerifyBlockMap from dsda-doom
to check for blockmap issues that might cause crashes
2026-06-13 13:37:21 +02:00
alufolie91 14aaba7a87 make reject matrix print an error instead of warning
better on 2nd thought as this may crash vanilla clients that use nametags
2026-06-13 13:20:54 +02:00
alufolie91 2c1bb6c268 smol optimize fof checks in P_CheckSight
check if fof is solid before height comparisons, also split initial height comparisons to save on some height checks in some cases
2026-06-13 13:20:51 +02:00
alufolie91 cc6437285f check for missized rejectmatrix´s on load, pad them if needed
this is what dsda-doom/prboom does
ensures we wont crash from oob reads and makes us print a warning
2026-06-13 13:00:00 +02:00
indev b24f6683b7 Use SKINCOLOR_NONE for ROULETTECOLOR_NONE instead of TC_DEFAULT 2026-06-13 02:25:43 +03:00
indev 5f559af29c Add more options to roulettecolor 2026-06-13 02:12:23 +03:00
indev eef1c55549 Add option for item roulette to use 'local' colors instead of player color 2026-06-13 01:40:14 +03:00
alufolie91 3c227ec532 P_CheckSight: fix rare overflow in rejectmatrix check
didnt think this could overflow here but well it does
wish there was a better way to bounds check heap arrays in C
2026-06-12 22:06:57 +02:00
indev 50f839e1ad Fix JoyAxis and InputDown inputs being off by one, this fixes lookback only working for p1 (ty lug <3) 2026-06-12 16:47:55 +03:00
indev 8db399be9b Allow lookback in replays (currently only works for player 1) 2026-06-12 16:38:32 +03:00
alufolie91 8cb321993e restore functionality to set zipper/speed pad sounds
set using the front side upper texture field like the play sound special per "DSXXXX"
the parsing part already was there but not the actual code to make it use the specified sound for some reason lul
shouldnt break anything and is vanilla compatible!
2026-06-08 10:04:14 +02:00
alufolie91 b4cad08ad3 cleanup p_spec/p_setup a bit 2026-06-08 09:44:36 +02:00
alufolie91 fa899d3970 fix a few more style issues 2026-06-07 07:07:56 +02:00
alufolie91 b955fdb47d cleanup s_sound a little 2026-06-05 23:07:29 +02:00
James R 4686e8e112 Do not play invalid sfx 2026-06-05 23:07:26 +02:00
alufolie91 667c67a61a also avoid strcpy for PutFileNeeded 2026-06-05 20:43:37 +02:00
alufolie91 df9a23a6c7 CL_CheckFiles: avoid using strcpy
wadfile->filename has not a fixed size, so it theoretically might be bigger than wadfilename buffer
this probably wont ever happen but better be safe than sorry honestly
2026-06-05 20:20:38 +02:00
alufolie91 a3f557f4df SV_SendFile: check if I_GetNodeAddress is set before use 2026-06-05 20:07:43 +02:00
alufolie91 1ac029edc6 optimize CL_CheckFiles a bit
the "already loaded" check will not first compare the md5sum, which is a very simple memcmp, and only then it will do string copies, nameonly mutation and name compare should the md5sum match
this should save quite a few unnecessary string operations since the md5 match case will rarely ever hit
2026-06-05 20:07:43 +02:00
alufolie91 761766d353 whitespace fix 2026-06-05 16:19:02 +02:00
alufolie91 72d3360711 delet this
this doesent exist anymore lol
2026-06-05 15:59:55 +02:00
alufolie91 ac52ec2c48 print netcmd name for SendNetXCmdForPlayer warnings
makes those prints a little more useful for debug
2026-06-05 14:50:46 +02:00
alufolie91 956bc3f7df hw renderer cleanups from lugstuff branch
mostly just code dedupe with ceepeepee lambdas
had checked in the past those didnt cause any real noticeable perf changes
2026-06-05 13:07:57 +02:00
alufolie91 746a8cec8b hw_main: make HWR_SkyWallList_Add realloc check a little safer
stuff like that should always be checked per equals/greater than just equals
in practice this shouldnt have caused any issues but its just better practice to check for greater
2026-06-05 12:21:27 +02:00
alufolie91 f7a32b5f85 init "savegamename"
global that was missed
2026-06-04 09:21:38 +02:00
alufolie91 bd30ab8fb7 delet JoyType_t
palyer[sic]......
2026-06-04 09:21:36 +02:00
alufolie91 4140f93e41 update pingdisplay only once per second
this will make sense later......
2026-06-04 09:21:33 +02:00
alufolie91 8ae6f71578 bunch of smaller optimizations and cleanups
mostly avoiding needless work as per usual
2026-06-02 11:31:56 +02:00
alufolie91 d5083ac66c cleanup and split K_MoveKartPlayer
item stuff split into K_PlayerItemThink
2026-06-02 11:24:49 +02:00
alufolie91 62be792a0d cleanup K_KartDrift a bit 2026-06-02 11:23:47 +02:00
alufolie91 c34346cb9a Saturn Icon for mac 2026-05-30 07:29:30 +02:00
alufolie91 d7803ecdcf fix cmake build 2026-05-30 06:05:52 +02:00
alufolie91 1a2a487a93 change cmake title to "Saturn" 2026-05-30 05:42:54 +02:00
alufolie91 bed6306cdf p_sight: let P_CrossSubsecPolyObj also use "fast" P_DivlineCrossed
for P_CheckSight on polyobjects
2026-05-30 05:42:51 +02:00
alufolie91 7521b3abd2 tiny optimize PIT_RadiusAttack in some cases
by checking simpler things before distance checks which may avoid two P_AproxDistance/FixedHypot calls
2026-05-30 05:42:48 +02:00
alufolie91 58d5bab181 tiny optimization K_SpawnKartMissile
by avoiding "min/max" reevaluation
2026-05-30 05:42:46 +02:00
alufolie91 2bffe443ed simplify analogue throwdir stuff in K_drawInput 2026-05-25 17:11:18 +02:00
alufolie91 261c02f4b6 few more hw_ file cleanups 2026-05-22 23:12:56 +02:00
Alug d59ac7d01b fix weird gap in opengl options menu 2026-05-20 19:03:41 +02:00
indev ac86f36186 Skip empty lines in renderer.txt 2026-05-18 20:32:59 +03:00
alufolie91 b5c7fd5a2b HWR_Subsector: check for sub->polyList instead of numpolys
numpolys sometimes might not get reset, checking for sub->polyList is what was actually intended
2026-05-18 18:21:00 +02:00
alufolie91 da103f54d6 hw_main: reorder plane stuff in HWR_Subsector
check for subsector validcount first, then if its a sky plane
so we can skip checking sector heights for sky planes, which may save a bit of maths on maps with many slopes
2026-05-18 18:20:58 +02:00
160 changed files with 10104 additions and 8925 deletions

No files matched your search

+4 -1
View File
@@ -1,5 +1,8 @@
cmake_minimum_required(VERSION 3.5)
# needed for lto to work for some reason
cmake_policy(SET CMP0069 NEW)
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
message(FATAL_ERROR "In-source builds will bring you a world of pain. Please make a separate directory to invoke CMake from.")
endif()
@@ -31,7 +34,7 @@ if("${SRB2_CPACK_GENERATOR}" STREQUAL "")
endif()
set(CPACK_GENERATOR ${SRB2_CPACK_GENERATOR})
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Sonic Robo Blast 2 Kart" CACHE STRING "Program name for display purposes")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Sonic Robo Blast 2 Kart Saturn" CACHE STRING "Program name for display purposes")
set(CPACK_PACKAGE_VENDOR "Kart Krew" CACHE STRING "Vendor name for display purposes")
#set(CPACK_PACKAGE_DESCRIPTION_FILE )
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
+14 -2
View File
@@ -54,7 +54,7 @@ set(SRB2_CORE_SOURCES
string.c
tables.c
v_video.c
w_wad.cpp
w_wad.c
y_inter.c
z_zone.cpp
)
@@ -247,6 +247,9 @@ set(SRB2_CONFIG_ASAN OFF CACHE BOOL
set(SRB2_CONFIG_UBSAN OFF CACHE BOOL
"Compile with UndefinedBehaviorSanitizer (libubsan).")
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")
set(SRB2_CONFIG_SATURNJOIN ON CACHE BOOL
@@ -254,6 +257,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)
@@ -275,6 +281,7 @@ if(${SRB2_CONFIG_HAVE_BLUA})
lua_hooklib.c
lua_hudlib.c
lua_hudlib_drawlist.c
lua_profile.cpp
lua_infolib.c
lua_maplib.c
lua_mathlib.c
@@ -290,6 +297,7 @@ if(${SRB2_CONFIG_HAVE_BLUA})
lua_hook.h
lua_hud.h
lua_hudlib_drawlist.h
lua_profile.h
lua_libs.h
lua_script.h
lua_udatalib.h
@@ -518,7 +526,7 @@ if(${SRB2_CONFIG_HWRENDER})
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_batching.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_shaders.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_bsp.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_cache.cpp
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_cache.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_draw.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.cpp
@@ -578,6 +586,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
+4 -4
View File
@@ -65,6 +65,10 @@
# 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.
@@ -246,10 +250,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
+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
+1
View File
@@ -99,3 +99,4 @@ lua_skinlib.c
lua_thinkerlib.c
lua_udatalib.c
lua_glib.c
lua_profile.cpp
+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;
}
+8 -17
View File
@@ -519,22 +519,6 @@ LUA_API int lua_pushthread (lua_State *L) {
** get functions (Lua -> stack)
*/
static void auxgetstr (lua_State *L, TValue *t, const char *k) {
TValue *slot;
TValue key;
TString *str = luaS_new(L, k);
api_checkvalidindex(L, t);
if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
setobj2s(L, L->top, slot);
}
else {
setsvalue(L, &key, str);
luaV_finishget(L, t, &key, L->top, slot);
}
api_incr_top(L);
lua_unlock(L);
}
LUA_API void lua_gettable (lua_State *L, int idx) {
StkId t;
@@ -547,8 +531,15 @@ LUA_API void lua_gettable (lua_State *L, int idx) {
LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
StkId t;
TValue key;
lua_lock(L);
auxgetstr(L, index2adr(L, idx), k);
t = index2adr(L, idx);
api_checkvalidindex(L, t);
setsvalue(L, &key, luaS_new(L, k));
luaV_gettable(L, t, &key, L->top);
api_incr_top(L);
lua_unlock(L);
}
-1
View File
@@ -544,7 +544,6 @@ static void atomic (lua_State *L) {
marktmu(g); /* mark `preserved' userdata */
udsize += propagateall(g); /* remark, to propagate `preserveness' */
cleartable(g->weak); /* remove collected objects from weak tables */
luaS_clearcache(g);
/* flip current white */
g->currentwhite = cast_byte(otherwhite(g));
g->sweepstrgc = 0;
-30
View File
@@ -41,25 +41,6 @@ typedef unsigned char lu_byte;
*/
#define IntPoint(p) ((unsigned int)(lu_mem)(p))
/*
** conversion of pointer to unsigned integer: this is for hashing only;
** there is no problem if the integer cannot hold the whole pointer
** value. (In strict ISO C this may cause undefined behavior, but no
** actual machine seems to bother.)
*/
#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \
__STDC_VERSION__ >= 199901L
#include <stdint.h>
#if defined(UINTPTR_MAX) /* even in C99 this type is optional */
#define L_P2I uintptr_t
#else /* no 'intptr'? */
#define L_P2I uintmax_t /* use the largest available integer */
#endif
#else /* C89 option */
#define L_P2I size_t
#endif
#define point2uint(p) ((unsigned int)((L_P2I)(p) & UINT_MAX))
/* type to ensure maximum alignment */
@@ -119,17 +100,6 @@ typedef lu_int32 Instruction;
#endif
/*
** Size of cache for strings in the API. 'N' is the number of
** sets (better be a prime) and "M" is the size of each set (M == 1
** makes a direct cache.)
*/
#ifndef STRCACHE_N
#define STRCACHE_N 53
#define STRCACHE_M 2
#endif
/* minimum size for string buffer */
#ifndef LUA_MINBUFFER
#define LUA_MINBUFFER 32
+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;
}
+7 -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
*/
@@ -73,9 +76,12 @@ static void f_luaopen (lua_State *L, void *ud) {
stack_init(L, L); /* init stack */
sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */
sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */
luaS_init(L);
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
luaT_init(L);
luaX_init(L);
/* 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
@@ -92,7 +92,6 @@ typedef struct global_State {
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 */
TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */
} global_State;
-60
View File
@@ -18,9 +18,6 @@
#include "lstring.h"
#define MEMERRMSG "not enough memory"
void luaS_resize (lua_State *L, int newsize) {
GCObject **newhash;
@@ -75,36 +72,6 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
}
/*
** Clear API string cache. (Entries cannot be empty, so fill them with
** a non-collectable string.)
*/
void luaS_clearcache (global_State *g) {
int i, j;
for (i = 0; i < STRCACHE_N; i++)
for (j = 0; j < STRCACHE_M; j++) {
if (luaS_iswhite(g->strcache[i][j])) /* will entry be collected? */
g->strcache[i][j] = g->memerrmsg; /* replace it with something fixed */
}
}
/*
** Initialize the string table and the string cache
*/
void luaS_init (lua_State *L) {
global_State *g = G(L);
int i, j;
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
/* pre-create memory-error message */
g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
luaS_fix(g->memerrmsg); /* it should never be collected */
for (i = 0; i < STRCACHE_N; i++) /* fill cache with valid strings */
for (j = 0; j < STRCACHE_M; j++)
g->strcache[i][j] = g->memerrmsg;
}
// string hash taken from luaJIT
/* Unaligned load of uint32_t. */
@@ -161,10 +128,6 @@ static inline __attribute__((always_inline)) unsigned luaS_hash (const char *str
#endif
}
/*
** new string (with explicit length)
*/
TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
GCObject *o;
unsigned int h = luaS_hash(str, l);
@@ -184,29 +147,6 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
}
/*
** Create or reuse a zero-terminated string, first checking in the
** cache (using the string address as a key). The cache can contain
** only zero-terminated strings, so it is safe to use 'strcmp' to
** check hits.
*/
TString *luaS_new (lua_State *L, const char *str) {
unsigned int i = point2uint(str) % STRCACHE_N; /* hash */
int j;
TString **p = G(L)->strcache[i];
for (j = 0; j < STRCACHE_M; j++) {
if (strcmp(str, getstr(p[j])) == 0) /* hit? */
return p[j]; /* that is it */
}
/* normal route */
for (j = STRCACHE_M - 1; j > 0; j--)
p[j] = p[j - 1]; /* move out last element */
/* new element is first in the list */
p[0] = luaS_newlstr(L, str, strlen(str));
return p[0];
}
Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
Udata *u;
if (l_unlikely(s > MAX_SIZET - sizeof(Udata)))
+2 -6
View File
@@ -17,19 +17,15 @@
#define sizeudata(u) (sizeof(union Udata)+(u)->len)
//#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
(sizeof(s)/sizeof(char))-1))
#define luaS_iswhite(x) test2bits((x)->tsv.marked, WHITE0BIT, WHITE1BIT)
#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
LUAI_FUNC void luaS_clearcache (global_State *g);
LUAI_FUNC void luaS_init (lua_State *L);
LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
LUAI_FUNC TString *luaS_new (lua_State *L, const char *str);
#endif
+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); \
+23 -51
View File
@@ -105,42 +105,27 @@ static void callTM (lua_State *L, const TValue *f, const TValue *p1,
}
/*
** Finish the table access 'val = t[key]'.
** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to
** t[k] entry (which must be nil).
*/
void luaV_finishget (lua_State *L, TValue *t, TValue *key, StkId val,
TValue *slot) {
int loop; /* counter to avoid infinite loops */
TValue *tm; /* metamethod */
void luaV_gettable (lua_State *L, TValue *t, TValue *key, StkId val) {
int loop;
for (loop = 0; loop < MAXTAGLOOP; loop++) {
if (slot == NULL) { /* 't' is not a table? */
lua_assert(!ttistable(t));
tm = luaT_gettmbyobj(L, t, TM_INDEX);
if (l_unlikely(ttisnil(tm)))
luaG_typeerror(L, t, "index"); /* no metamethod */
/* else will try the metamethod */
}
else { /* 't' is a table */
lua_assert(ttisnil(slot));
tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */
if (tm == NULL) { /* no metamethod? */
setnilvalue(val); /* result is nil */
TValue *tm;
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
const TValue *res = luaH_get(h, key); /* do a primitive get */
if (!ttisnil(res) || /* result is no nil? */
(tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
setobj2s(L, val, res);
return;
}
/* else will try the metamethod */
/* else will try the tag method */
}
if (ttisfunction(tm)) { /* is metamethod a function? */
callTMres(L, val, tm, t, key); /* call it */
else if (l_unlikely(ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))))
luaG_typeerror(L, t, "index");
if (ttisfunction(tm)) {
callTMres(L, val, tm, t, key);
return;
}
t = tm; /* else try to access 'tm[key]' */
if (luaV_fastget(L, t, key, slot, luaH_get)) { /* fast track? */
setobj2s(L, val, slot); /* done */
return;
}
/* else repeat (tail call 'luaV_finishget') */
t = tm; /* else repeat with `tm' */
}
luaG_runerror(L, "loop in gettable");
}
@@ -154,12 +139,8 @@ void luaV_settable (lua_State *L, TValue *t, TValue *key, StkId val) {
Table *h = hvalue(t);
TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
/* oldval is nil=> look for newindex, oldval is not nil => look for usedindex */
if (ttisnil(oldval)) {
tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
} else {
tm = fasttm(L, h->metatable, TM_USEDINDEX);
}
if (tm == NULL) { /* no metamethod? */
if (!((ttisnil(oldval) && ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) != NULL)) ||
((!ttisnil(oldval)) && ((tm = fasttm(L, h->metatable, TM_USEDINDEX)) != NULL)))) {
setobj2t(L, oldval, val);
luaC_barriert(L, h, val);
return;
@@ -397,14 +378,6 @@ static void Arith (lua_State *L, StkId ra, TValue *rb,
}
/*
** copy of 'luaV_gettable', but protecting call to potential metamethod
** (which can reallocate the stack)
*/
#define gettableProtected(L,t,k,v) { TValue *slot; \
if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
else Protect(luaV_finishget(L,t,k,v,slot)); }
void luaV_execute (lua_State *L, int nexeccalls) {
LClosure *cl;
@@ -414,9 +387,9 @@ void luaV_execute (lua_State *L, int nexeccalls) {
reentry: /* entry point */
lua_assert(isLua(L->ci));
pc = L->savedpc;
cl = &clvalue(L->ci->func)->l; /* local reference to function's closure */
k = cl->p->k; /* local reference to function's constant table */
base = L->base; /* local copy of function's base */
cl = &clvalue(L->ci->func)->l;
base = L->base;
k = cl->p->k;
/* main loop of interpreter */
for (;;) {
const Instruction i = *pc++;
@@ -476,7 +449,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
StkId ra = RA(i);
StkId rb = RB(i);
TValue *rc = RKC(i);
gettableProtected(L, rb, rc, ra);
Protect(luaV_gettable(L, rb, rc, ra));
continue;
}
case OP_SETGLOBAL: {
@@ -512,9 +485,8 @@ void luaV_execute (lua_State *L, int nexeccalls) {
case OP_SELF: {
StkId ra = RA(i);
StkId rb = RB(i);
TValue *rc = RKC(i);
setobjs2s(L, ra + 1, rb);
gettableProtected(L, rb, rc, ra);
setobjs2s(L, ra+1, rb);
Protect(luaV_gettable(L, rb, RKC(i), ra));
continue;
}
case OP_ADD: {
+2 -24
View File
@@ -22,34 +22,12 @@
(ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
/*
** fast track for 'gettable': if 't' is a table and 't[k]' is not nil,
** return 1 with 'slot' pointing to 't[k]' (final result). Otherwise,
** return 0 (meaning it will have to check metamethod) with 'slot'
** pointing to a nil 't[k]' (if 't' is a table) or NULL (otherwise).
** 'f' is the raw get function to use.
*/
#define luaV_fastget(L,t,k,slot,f) \
(!ttistable(t) \
? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \
: (slot = f(hvalue(t), k), /* else, do raw access */ \
!ttisnil(slot))) /* result not nil? */
/*
** standard implementation for 'gettable'
*/
#define luaV_gettable(L,t,k,v) { TValue *slot; \
if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
else luaV_finishget(L,t,k,v,slot); }
LUAI_FUNC int luaV_lessthan (lua_State *L, TValue *l, TValue *r);
LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
LUAI_FUNC void luaV_finishget (lua_State *L, TValue *t, TValue *key,
StkId val, TValue *tm);
LUAI_FUNC void luaV_gettable (lua_State *L, TValue *t, TValue *key,
StkId val);
LUAI_FUNC void luaV_settable (lua_State *L, TValue *t, TValue *key,
StkId val);
LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls);
+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
+42 -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);
}
@@ -1782,8 +1802,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 +1822,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 +2220,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 +2229,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);
+55 -39
View File
@@ -62,7 +62,7 @@ static boolean con_started = false; // console has been initialised
static boolean con_forcepic = true; // at startup toggle console translucency when first off
boolean con_recalc = false; // set true when screen size has changed
static tic_t con_tick; // console ticker for anim or blinking prompt cursor
static tic_t con_tick; // console ticker for blinking prompt cursor
// con_scrollup should use time (currenttime - lasttime)..
static boolean consoletoggle; // true when console key pushed, ticker will handle
@@ -103,6 +103,7 @@ static void CON_InputInit(void);
static void CON_RecalcSize(void);
static void CON_ChangeHeight(void);
static void CONS_height_Change(void);
static void CONS_hudlines_Change(void);
static void CONS_backcolor_Change(void);
@@ -131,7 +132,7 @@ static CV_PossibleValue_t speed_cons_t[] = {{0, "MIN"}, {64, "MAX"}, {0, NULL}};
static consvar_t cons_speed = {"con_speed", "8", CV_SAVE, speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// percentage of screen height to use for console
static consvar_t cons_height = {"con_height", "50", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
static consvar_t cons_height = {"con_height", "50", CV_CALL|CV_SAVE, CV_Unsigned, CONS_height_Change, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t backpic_cons_t[] = {{0, "translucent"}, {1, "picture"}, {0, NULL}};
// whether to use console background picture, or translucent mode
@@ -173,6 +174,18 @@ consvar_t cons_consoleprintinmenu = {"consoleprintinmenu", "Off", CV_SAVE, CV_On
static void CON_Print(char *msg);
// Change the console height on demand
//
static void CONS_height_Change(void)
{
Lock_state();
if (con_destlines > 0 && !con_startup) // If the console is open (as in, not using "bind")...
CON_ChangeHeight(); // ...update its height now, not only when it's closed and re-opened
Unlock_state();
}
//
//
static void CONS_hudlines_Change(void)
@@ -1437,6 +1450,8 @@ void CONS_Error(const char *msg)
// dirty quick hack, but for the good cause
while (I_GetKey() != KEY_ENTER)
{
I_HandleInterrupt();
// Sleep so we don't take too much of cpu usage
I_Sleep(1.f/TICRATE*1000);
@@ -1635,53 +1650,54 @@ static void CON_DrawConsole(void)
}
// draw console text lines from top to bottom
if (con_curlines < minheight)
return;
i = con_cy - con_scrollup;
// skip the last empty line due to the cursor being at the start of a new line
i--;
i -= (con_curlines - minheight) / charheight;
if (rendermode == render_none) return;
for (y = (con_curlines-minheight) % charheight; y <= con_curlines-minheight; y += charheight, i++)
if (con_curlines >= minheight)
{
INT32 x;
size_t c;
i = con_cy - con_scrollup;
p = (UINT8 *)&con_buffer[((i > 0 ? i : 0)%con_totallines)*con_width];
// skip the last empty line due to the cursor being at the start of a new line
i--;
for (c = 0, x = charwidth; c < con_width; c++, x += charwidth, p++)
i -= (con_curlines - minheight) / charheight;
if (rendermode == render_none)
return;
for (y = (con_curlines-minheight) % charheight; y <= con_curlines-minheight; y += charheight, i++)
{
while (*p & 0x80)
INT32 x;
size_t c;
p = (UINT8 *)&con_buffer[((i > 0 ? i : 0)%con_totallines)*con_width];
for (c = 0, x = charwidth; c < con_width; c++, x += charwidth, p++)
{
charflags = (*p & 0x7f) << V_CHARCOLORSHIFT;
p++;
c++;
while (*p & 0x80)
{
charflags = (*p & 0x7f) << V_CHARCOLORSHIFT;
p++;
c++;
}
if (c >= con_width)
break;
int emotelen;
emote_t *emote;
if ((emote = M_VerifyEmote((const char *)p, &emotelen)))
{
M_DrawScaledEmote(x<<FRACBITS, (y+2*con_scalefactor)<<FRACBITS, charwidth*FRACUNIT/EMOTEWIDTH, emote, V_NOSCALESTART|V_NOSCALEPATCH);
p += emotelen-1;
c += emotelen-1;
continue;
}
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
}
if (c >= con_width)
break;
int emotelen;
emote_t *emote;
if ((emote = M_VerifyEmote((const char *)p, &emotelen)))
{
M_DrawScaledEmote(x<<FRACBITS, (y+2*con_scalefactor)<<FRACBITS, charwidth*FRACUNIT/EMOTEWIDTH, emote, V_NOSCALESTART|V_NOSCALEPATCH);
p += emotelen-1;
c += emotelen-1;
continue;
}
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
}
}
// draw prompt if enough place (not while game startup)
if ((con_curlines == con_destlines) && (con_curlines >= minheight) && !con_startup)
if ((con_curlines >= (minheight-charheight)) && !con_startup)
CON_DrawInput();
}
+30 -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,8 +146,33 @@ void PoolAllocator::release()
first_chunk_ = nullptr;
head_ = nullptr;
allocated_blocks_ = 0;
}
bool PoolAllocator::ptrcheck(const void* p) const
{
const uintptr_t paddr = reinterpret_cast<uintptr_t>(p);
ChunkFooter* next = nullptr;
for (ChunkFooter* chunk = first_chunk_; chunk != nullptr; chunk = next)
{
const uintptr_t blockstart = reinterpret_cast<uintptr_t>(chunk->start);
const uintptr_t blockend = blockstart + blocks_ * block_size_;
//CONS_Printf("mobj ptr %lu, block start %lu end %lu\n", paddr, blockstart, blockend);
if (paddr >= blockstart && paddr < blockend)
{
return true;
}
next = chunk->next;
}
return false;
}
static LinearMemory g_frame_memory {4 * 1024 * 1024};
void* Z_Frame_Alloc(size_t size)
+8 -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,8 +61,11 @@ 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();
bool ptrcheck(const void* p) const;
};
} // namespace srb2
+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.
+173 -88
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
@@ -125,6 +125,7 @@ static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the
UINT16 pingmeasurecount = 1;
UINT32 realpingtable[MAXPLAYERS] = {}; //the base table of ping where an average will be sent to everyone.
UINT32 playerpingtable[MAXPLAYERS] = {}; //table of player latency values.
UINT32 localplayerping = 0;
#define GENTLEMANSMOOTHING (TICRATE)
static tic_t reference_lag = 0;
@@ -356,12 +357,13 @@ void SendNetXCmdForPlayer(UINT8 playerid, netxcmd_t id, const void *param, size_
if (2+nparam > MAXTEXTCMD)
{
CONS_Alert(CONS_ERROR, M_GetText("packet too large to fit NetXCmd, cannot add netcmd %d! (size: %s, max: %d)\n"), id, sizeu1(2+nparam), MAXTEXTCMD);
CONS_Alert(CONS_ERROR, M_GetText("packet too large to fit NetXCmd, cannot add netcmd %s with id %d! (size: %s, max: %d)\n"), netxcmdnames[id-1], id, sizeu1(2+nparam), MAXTEXTCMD);
return;
}
// for future reference: if (cv_debug) != debug disabled.
CONS_Alert(CONS_NOTICE, M_GetText("NetXCmd buffer full, delaying netcmd %d... (size: %d, needed: %s)\n"), id, localtextcmd[playerid][0], sizeu1(nparam));
CONS_Alert(CONS_NOTICE, M_GetText("NetXCmd buffer full, delaying netcmd %s with id %d... (size: %d, needed: %s)\n"), netxcmdnames[id-1], id, localtextcmd[playerid][0], sizeu1(nparam));
if (buf == NULL)
{
textcmdbuf[playerid] = (textcmdbuf_t*)Z_Malloc(sizeof(textcmdbuf_t), PU_STATIC, NULL);
@@ -839,11 +841,13 @@ static void resynch_write_ctf(resynchend_pak *rst)
rst->flagplayer[i] = (SINT8)j;
break;
}
if (j == MAXPLAYERS) // fine, no I_Error
{
CONS_Alert(CONS_ERROR, "One of the flags has gone completely missing...\n");
rst->flagplayer[i] = -2;
}
continue;
}
@@ -1121,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;
@@ -1133,6 +1137,7 @@ static void CV_SavePlayerNames(UINT8 **p)
WRITEUINT8(*p, 0);
continue;
}
WRITESTRING(*p, player_names[i]);
}
}
@@ -1146,13 +1151,17 @@ static void CV_LoadPlayerNames(UINT8 **p)
for (; i < MAXPLAYERS; ++i)
{
READSTRING(*p, tmp_name);
if (tmp_name[0] == 0)
continue;
if (tmp_name[MAXPLAYERNAME]) // overflow detected
I_Error("Received bad server config packet when trying to join");
memcpy(player_names[i], tmp_name, MAXPLAYERNAME+1);
}
}
#endif
static void CL_DrawAddonTypes(void)
{
@@ -1447,6 +1456,7 @@ static void CL_DrawConnectionStatus(void)
if (playerinfo[i].node < 255)
{
strncpy(player_name, playerinfo[i].name, MAXPLAYERNAME);
player_name[MAXPLAYERNAME] = '\0';
// if we get a skin color
// try to colourize the player name
@@ -1620,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
@@ -1646,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);
@@ -1760,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;
@@ -1805,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;
@@ -1915,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);
@@ -1934,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));
@@ -1949,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;
@@ -1956,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)
@@ -2026,6 +2047,7 @@ static void SV_SendSaveGame(INT32 node, boolean resending)
P_SaveNetGame(&save, resending);
length = save.p - save.buffer;
if (length > SAVEGAMESIZE)
{
Z_Free(save.buffer);
@@ -2084,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);
@@ -2122,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);
@@ -2178,7 +2200,8 @@ static void CL_LoadReceivedSavegame(boolean reloading)
if (unlink(tmpsave) == -1)
CONS_Alert(CONS_ERROR, M_GetText("Can't delete %s\n"), tmpsave);
consistancy[gametic%BACKUPTICS] = Consistancy();
CON_ToggleOff();
if (!reloading)
CON_ToggleOff();
#ifdef SATURNPAK
// Tell the server we have received and reloaded the gamestate
@@ -2200,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);
@@ -2856,10 +2879,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
{
INT32 key;
if (I_Interrupted())
{
I_Quit();
}
I_HandleInterrupt();
I_OsPolling();
@@ -2939,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;
@@ -3327,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)
@@ -3345,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
@@ -3361,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)
@@ -3438,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));
}
@@ -3498,8 +3538,11 @@ void CL_RemovePlayer(INT32 playernum, INT32 reason)
while ((doomcom->numslots > 1) && !playeringame[doomcom->numslots-1])
doomcom->numslots--;
// Unmute slot if player was muted
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;
@@ -3756,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)
@@ -3873,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
@@ -3922,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"));
@@ -3976,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);
@@ -4436,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));
@@ -4447,6 +4515,7 @@ void SV_ResetServer(void)
pingmeasurecount = 1;
memset(realpingtable, 0, sizeof(realpingtable));
memset(playerpingtable, 0, sizeof(playerpingtable));
localplayerping = 0;
ClearAdminPlayers();
@@ -4795,7 +4864,7 @@ void CL_RemoveSplitscreenPlayer(UINT8 p)
// is there a game running
boolean Playing(void)
{
return (server && serverrunning) || (client && cl_mode == CL_CONNECTED);
return ((server && serverrunning) || (client && cl_mode == CL_CONNECTED));
}
boolean SV_SpawnServer(void)
@@ -5125,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);
@@ -5374,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?
@@ -5396,10 +5467,12 @@ static void PT_ServerCFG(SINT8 node)
{
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);
if ((gametype = netbuffer->u.servercfg.gametype) >= NUMGAMETYPES)
I_Error("Bad gametype in cliserv!");
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);
}
@@ -5425,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++)
@@ -5441,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?
@@ -5494,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)
@@ -6836,7 +6911,10 @@ boolean TryRunTics(tic_t realtics)
DEBFILE(va("============ Running tic %d (local %d)\n", gametic, leveltime));
if (update_stats)
{
ps_prevtictime = ps_tictime;
PS_START_TIMING(ps_tictime);
}
G_Ticker((gametic % NEWTICRATERATIO) == 0);
ExtraDataTicker();
@@ -6983,10 +7061,12 @@ static void UpdatePingTable(void)
INT32 i;
const boolean playing = Playing();
if (server)
{
//if (Playing() && !(gametime % 8)) // Value chosen based on _my vibes man_ << dont do this for v8 atleast, this is placeboeing ppl to hell and back
if (Playing() && !(gametime % 35)) // update once per second.
//if (playing && !(gametime % 8)) // Value chosen based on _my vibes man_ << dont do this for v8 atleast, this is placeboeing ppl to hell and back
if (playing && !(gametime % 35)) // update once per second.
PingUpdate();
fastest = 0;
@@ -7045,6 +7125,10 @@ static void UpdatePingTable(void)
else
lowest_lag = simulated_lag = 0;
}
// this is really dumb but oh well
if (playing && !(gametime % 35))
localplayerping = playerpingtable[consoleplayer];
}
#ifdef HOLEPUNCH
@@ -7189,6 +7273,7 @@ static void DedicatedIdleUpdate(INT32 *realtics)
{
CONS_Printf("DEDICATED: Awakening from idle (Player detected...)\n");
}
dedicatedidle = 0;
}
}
+10 -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;
@@ -650,6 +656,8 @@ extern UINT8 playernode[MAXPLAYERS];
extern boolean player_muted[MAXPLAYERS];
extern UINT32 localplayerping;
INT32 D_NumPlayers(void);
void D_ResetTiccmds(void);
+26 -31
View File
@@ -79,6 +79,7 @@
#include "core/memory.h"
#include "lua_script.h"
#include "lua_profile.h"
/* Manually defined asset hashes for non-CMake builds
* Last updated 2015 / 05 / 03 - SRB2 v2.1.15 - srb2.srb
@@ -154,7 +155,7 @@ boolean music_disabled = false;
INT32 debugload = 0;
#endif
char savegamename[256];
char savegamename[256] = {};
char srb2home[256] = ".";
char srb2path[256] = ".";
@@ -275,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)
@@ -658,6 +645,11 @@ static boolean D_Display(void)
CON_Drawer(); // Ha, i LIED!
if (cv_lua_profile.value > 0)
{
LUA_RenderTimers();
}
PS_START_TIMING(ps_swaptime);
I_FinishUpdate(); // page flip or blit buffer
PS_STOP_TIMING(ps_swaptime);
@@ -726,10 +718,7 @@ void D_SRB2Loop(void)
enterprecise = I_GetPreciseTime();
if (I_Interrupted())
{
I_Quit();
}
I_HandleInterrupt();
memset(&g_dc, 0, sizeof(g_dc));
Z_Frame_Reset();
@@ -1162,7 +1151,7 @@ static void D_FindAddonsToAutoload(void)
// you can probably imagine how that goes in a netgame....
if (W_CheckAutoLoadContainsMap(wadsToAutoload))
{
CONS_Printf("Autoload: file %s contains map data! skipping...", wadsToAutoload);
CONS_Alert(CONS_WARNING, "Autoload: file %s contains map data, this WILL cause crashes and desynchs! skipping...\n", wadsToAutoload);
continue;
}
@@ -1256,7 +1245,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)
@@ -1356,20 +1345,24 @@ static void IdentifyVersion(void)
//
// search for maps
//
static void D_CheckMaps(boolean checkreplaced)
static void D_CheckMapReplacements(boolean pwad)
{
INT32 i;
char *name;
UINT16 wadnum;
lumpinfo_t *lumpinfo;
size_t numfiles;
for (wadnum = 0; wadnum < mainwads; wadnum++)
wadnum = pwad ? (mainwads+1) : 0;
numfiles = pwad ? numwadfiles : mainwads;
for (; wadnum < numfiles; wadnum++)
{
lumpinfo = wadfiles[wadnum]->lumpinfo;
for (i = 0; i < wadfiles[wadnum]->numlumps; i++, lumpinfo++)
{
name = lumpinfo->name;
P_CheckMapReplacements(name, checkreplaced);
P_CheckMapReplacements(name, pwad);
}
}
}
@@ -1832,17 +1825,19 @@ void D_SRB2Main(void)
// conversion sometimes needs the palette
V_ReloadPalette();
D_CheckMaps(false);
D_CheckMapReplacements(false);
W_InitMultipleFiles(startuppwads, startuppwadcount, true);
// Only search for pwad maps if we actually have a pwad added
if (startuppwadcount > 0)
{
D_CheckMaps(true);
CONS_Printf("W_InitMultipleFiles(): Adding extra PWADs.\n");
W_InitMultipleFiles(startuppwads, startuppwadcount, true);
// Only search for pwad maps if we actually have a pwad added
D_CheckMapReplacements(true);
D_CleanFile(startuppwads, startuppwadcount);
}
D_CleanFile(startuppwads, startuppwadcount);
startuppwadcount = 0;
cht_Init();
@@ -1929,7 +1924,7 @@ void D_SRB2Main(void)
CONS_Printf("R_Init(): Init SRB2 refresh daemon.\n");
R_Init();
#if SOUND==SOUND_DUMMY
#if SOUND == SOUND_DUMMY
sound_disabled = true;
music_disabled = true;
#else
+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");
}
+139 -28
View File
@@ -47,6 +47,7 @@
#include "z_zone.h"
#include "lua_script.h"
#include "lua_hook.h"
#include "lua_profile.h"
#include "m_cond.h"
#include "m_anigif.h"
#include "k_kart.h" // SRB2kart
@@ -146,10 +147,16 @@ 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);
static void Command_ListUnusedSprites_f(void);
static void Command_ListUnusedMapSlots_f(void);
static void Command_RunSOC(void);
static void Command_Pause(void);
static void Command_Respawn(void);
@@ -433,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};
@@ -505,6 +520,9 @@ static CV_PossibleValue_t ps_descriptor_cons_t[] = {
{1, "Average"}, {2, "SD"}, {3, "Minimum"}, {4, "Maximum"}, {0, NULL}};
consvar_t cv_ps_descriptor = {"ps_descriptor", "Average", 0, ps_descriptor_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
//consvar_t cv_lua_profile = {"lua_profile", "0").values(CV_Unsigned).onchange(lua_profile_OnChange).description("Show hook timings over an average of N tics");
consvar_t cv_lua_profile = {"lua_profile", "0", CV_CALL, CV_Unsigned, lua_profile_OnChange, 0, NULL, NULL, 0, 0, NULL};
// only there to better keep track of it globally
consvar_t cv_director = {"director", "Off", CV_HIDEN, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -565,6 +583,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
"MODIFYVOTE",
"PICKVOTE",
"REMOVEPLAYER",
"DISCORD",
"LUACMD",
"LUAVAR"
};
@@ -598,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);
@@ -645,6 +670,7 @@ void D_RegisterServerCommands(void)
COM_AddCommand("locatelump", Command_LocateLump_f);
COM_AddCommand("listmapthings", Command_ListDoomednums_f);
COM_AddCommand("listunusedsprites", Command_ListUnusedSprites_f);
COM_AddCommand("listunusedmapslots", Command_ListUnusedMapSlots_f);
COM_AddCommand("runsoc", Command_RunSOC);
COM_AddCommand("pause", Command_Pause);
@@ -845,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);
@@ -928,11 +959,11 @@ void D_RegisterClientCommands(void)
COM_AddCommand("displayplayer", Command_Displayplayer_f);
CV_RegisterVar(&cv_audbuffersize);
CV_RegisterVar(&cv_palette);
CV_RegisterVar(&cv_palettenum);
CV_RegisterVar(&cv_lua_profile);
// m_menu.c
CV_RegisterVar(&cv_chatheight);
CV_RegisterVar(&cv_chatwidth);
@@ -940,6 +971,9 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_chatspamprotection);
CV_RegisterVar(&cv_consolechat);
CV_RegisterVar(&cv_chatnotifications);
CV_RegisterVar(&cv_chat_xoffset);
CV_RegisterVar(&cv_chat_yoffset);
CV_RegisterVar(&cv_chat_showlimit);
CV_RegisterVar(&cv_chatbacktint);
CV_RegisterVar(&cv_chatcentertext);
CV_RegisterVar(&cv_songcredits);
@@ -1005,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);
@@ -1027,6 +1069,7 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_midimusicvolume);
#endif
CV_RegisterVar(&cv_numChannels);
CV_RegisterVar(&cv_audbuffersize);
#ifdef HAVE_OPENMPT
CV_RegisterVar(&cv_modfilter);
@@ -1263,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;
}
@@ -1548,8 +1592,8 @@ static void SendNameAndColor(UINT8 splitplayer)
// TODO: make those cvars arrays
consvar_t *playercolor, *playername, *playerskin;
consvar_t *colorvars[] = {&cv_playercolor, &cv_playercolor2, &cv_playercolor3, &cv_playercolor4};
consvar_t *namevars[] = {&cv_playername, &cv_playername2, &cv_playername3, &cv_playername4};
consvar_t *skinvars[] = {&cv_skin, &cv_skin2, &cv_skin3, &cv_skin4};
consvar_t *namevars[] = {&cv_playername, &cv_playername2, &cv_playername3, &cv_playername4};
consvar_t *skinvars[] = {&cv_skin, &cv_skin2, &cv_skin3, &cv_skin4};
playercolor = colorvars[splitplayer];
playername = namevars[splitplayer];
@@ -1655,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);
}
@@ -1663,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)
@@ -1685,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)
@@ -1793,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;
}
@@ -2317,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 */
@@ -2735,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");
}
@@ -4297,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];
@@ -4336,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])
@@ -4591,6 +4681,23 @@ void Command_ListUnusedSprites_f(void)
}
}
void Command_ListUnusedMapSlots_f(void)
{
INT32 i;
CONS_Printf("\x82Printing map slot non-usage...\n");
for (i = 0; i < NUMMAPS; i++)
{
// is checking this enough?
if (mapheaderinfo[i])
continue;
CONS_Printf("%s\n", G_BuildMapName(i+1));
}
}
// =========================================================================
// MISC. COMMANDS
// =========================================================================
@@ -5159,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
@@ -5471,7 +5580,6 @@ static void Name_OnChange(void)
}
SendNameAndColor(0);
}
static void Name2_OnChange(void)
@@ -5662,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.
+3 -4
View File
@@ -51,10 +51,6 @@ extern consvar_t cv_mousevisible;
//WTF
extern consvar_t cv_mouseturn;
extern consvar_t cv_usejoystick[4]; //MAXSPLITSCREENPLAYERS
#ifdef LJOYSTICK
extern consvar_t cv_joyport;
extern consvar_t cv_joyport2;
#endif
extern consvar_t cv_joyscale[4]; //MAXSPLITSCREENPLAYERS
// normally in p_mobj but the .h is not read
@@ -153,6 +149,7 @@ extern consvar_t cv_showminimapnames;
extern consvar_t cv_showminimapfinished;
extern consvar_t cv_minihead;
extern consvar_t cv_showminimapangle;
extern consvar_t cv_spinoutroll;
extern consvar_t cv_showlapemblem;
@@ -192,6 +189,8 @@ extern consvar_t cv_ps_thinkframe_page;
extern consvar_t cv_ps_samplesize;
extern consvar_t cv_ps_descriptor;
extern consvar_t cv_lua_profile;
extern consvar_t cv_director, cv_kartdebugdirector, cv_showdirectorhud;
extern consvar_t cv_showtrackaddon;
+39 -23
View File
@@ -167,7 +167,9 @@ UINT8 *PutFileNeeded(UINT16 firstfile)
continue;
}
nameonly(strcpy(wadfilename, wadfiles[i]->filename));
strncpy(wadfilename, wadfiles[i]->filename, MAX_WADPATH);
wadfilename[MAX_WADPATH-1] = '\0';
nameonly(wadfilename);
// Look below at the WRITE macros to understand what these numbers mean.
const size_t len = strlen(wadfilename) + 1;
@@ -257,9 +259,10 @@ void CL_PrepareDownloadSaveGame(const char *tmpsave)
*/
boolean CL_CheckDownloadable(void)
{
UINT8 i,dlstatus = 0;
UINT8 i, dlstatus = 0;
for (i = 0; i < fileneedednum; i++)
{
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN)
{
if (fileneeded[i].willsend == 1)
@@ -270,6 +273,7 @@ boolean CL_CheckDownloadable(void)
else //if (fileneeded[i].willsend == 2)
dlstatus = 2;
}
}
// Downloading locally disabled
if (!dlstatus && M_CheckParm("-nodownload"))
@@ -280,25 +284,31 @@ boolean CL_CheckDownloadable(void)
// not downloadable, put reason in console
CONS_Alert(CONS_NOTICE, M_GetText("You need additional files to connect to this server:\n"));
for (i = 0; i < fileneedednum; i++)
{
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN)
{
CONS_Printf(" * \"%s\" (%dK)", fileneeded[i].filename, fileneeded[i].totalsize >> 10);
if (fileneeded[i].status == FS_MD5SUMBAD)
CONS_Printf(M_GetText(" wrong version, md5: "));
else
CONS_Printf(M_GetText(" not found, md5: "));
if (fileneeded[i].status == FS_MD5SUMBAD)
CONS_Printf(M_GetText(" wrong version, md5: "));
else
CONS_Printf(M_GetText(" not found, md5: "));
{
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");
}
}
switch (dlstatus)
{
@@ -312,6 +322,7 @@ boolean CL_CheckDownloadable(void)
CONS_Printf(M_GetText("All files downloadable, but you have chosen to disable downloading locally.\n"));
break;
}
return false;
}
@@ -549,7 +560,7 @@ INT32 CL_CheckFiles(void)
if (fileneeded[i].status != FS_OPEN)
filestoload++;
if (fileneeded[i].status != FS_NOTCHECKED) //since we're running this over multiple tics now, its possible for us to come across files checked in previous tics
if (fileneeded[i].status != FS_NOTCHECKED) // since we're running this over multiple tics now, its possible for us to come across files checked in previous tics
continue;
CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename);
@@ -557,14 +568,18 @@ INT32 CL_CheckFiles(void)
// Check in already loaded files
for (j = mainwads+1; j < numwadfiles; j++)
{
nameonly(strcpy(wadfilename, wadfiles[j]->filename));
if (fasticmp(wadfilename, fileneeded[i].filename) &&
!memcmp(wadfiles[j]->md5sum, fileneeded[i].md5sum, 16))
if (!memcmp(wadfiles[j]->md5sum, fileneeded[i].md5sum, 16))
{
CONS_Debug(DBG_NETPLAY, "already loaded\n");
fileneeded[i].status = FS_OPEN;
return 4;
strncpy(wadfilename, wadfiles[j]->filename, MAX_WADPATH);
wadfilename[MAX_WADPATH-1] = '\0';
nameonly(wadfilename);
if (fasticmp(wadfilename, fileneeded[i].filename))
{
CONS_Debug(DBG_NETPLAY, "already loaded\n");
fileneeded[i].status = FS_OPEN;
return 4;
}
}
}
@@ -645,7 +660,7 @@ boolean CL_LoadServerFiles(void)
else
{
const char *s;
switch(fileneeded[i].status)
switch (fileneeded[i].status)
{
case FS_NOTFOUND:
s = "FS_NOTFOUND";
@@ -688,7 +703,7 @@ static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
char wadfilename[MAX_WADPATH];
if (cv_noticedownload.value)
if (cv_noticedownload.value && I_GetNodeAddress)
CONS_Printf("Sending file \"%s\" (id %d) to node %d (%s)\n", filename, fileid, node, I_GetNodeAddress(node));
// Find the last file in the list and set a pointer to its "next" field
@@ -713,7 +728,9 @@ static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
// Look for the requested file through all loaded files
for (wadnum = 0; wadfiles[wadnum]; wadnum++)
{
strlcpy(wadfilename, wadfiles[wadnum]->filename, MAX_WADPATH);
// im a certified strlcpy hater
strncpy(wadfilename, wadfiles[wadnum]->filename, MAX_WADPATH);
wadfilename[MAX_WADPATH-1] = '\0';
nameonly(wadfilename);
if (fasticmp(wadfilename, p->id.filename))
@@ -1066,7 +1083,7 @@ void Got_Filetxpak(void)
{
const char *s;
switch(file->status)
switch (file->status)
{
case FS_NOTFOUND:
s = "FS_NOTFOUND";
@@ -1194,7 +1211,7 @@ filestatus_t checkfilemd5(char *filename, const UINT8 *wantedmd5sum)
fhandle = fopen(filename, "rb");
if (fhandle)
{
md5_stream(fhandle,md5sum);
md5_stream(fhandle, md5sum);
fclose(fhandle);
if (!memcmp(wantedmd5sum, md5sum, 16))
return FS_FOUND;
@@ -1602,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;
@@ -1613,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;
+2
View File
@@ -566,6 +566,8 @@ typedef struct player_s
fixed_t fovadd; // adjust FOV for hw rendering
SINT8 driftlevel; // just for controller rumble for now
UINT8 stairjank;
} player_t;
#endif
+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);
+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
}
+88 -49
View File
@@ -337,12 +337,14 @@ static void readfreeslots(MYFILE *f)
{
if (used_spr[(i-SPR_FIRSTFREESLOT)/8] & (1<<(i%8)))
{
if (!sprnames[i][4] && memcmp(sprnames[i],word,4)==0)
if (!sprnames[i][4] && memcmp(sprnames[i], word, 4) == 0)
sprnames[i][4] = (char)f->wad;
continue; // Already allocated, next.
}
// Found a free slot!
strncpy(sprnames[i],word,4);
strncpy(sprnames[i], word, 4);
//sprnames[i][4] = 0;
CONS_Printf("Sprite SPR_%s allocated.\n",word);
@@ -351,22 +353,26 @@ static void readfreeslots(MYFILE *f)
used_spr[(i-SPR_FIRSTFREESLOT)/8] |= 1<<(i%8); // Okay, this sprite slot has been named now.
break;
}
if (i > SPR_LASTFREESLOT)
I_Error("Out of Sprite Freeslots while allocating \"%s\"\nLoad less addons to fix this.", word);
}
else if (fastcmp(type, "S"))
{
for (i = 0; i < NUMSTATEFREESLOTS; i++)
if (!FREE_STATES[i]) {
CONS_Printf("State S_%s allocated.\n",word);
{
if (!FREE_STATES[i])
{
CONS_Printf("State S_%s allocated.\n", word);
LUA_InvalidateMathlibCache(va("S_%s", word));
FREE_STATES[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_STATES[i],word);
strcpy(FREE_STATES[i], word);
freeslotusage[0][0]++;
break;
}
}
if (i == NUMSTATEFREESLOTS)
I_Error("Out of State Freeslots while allocating \"%s\"\nLoad less addons to fix this.", word);
@@ -374,16 +380,19 @@ static void readfreeslots(MYFILE *f)
else if (fastcmp(type, "MT"))
{
for (i = 0; i < NUMMOBJFREESLOTS; i++)
if (!FREE_MOBJS[i]) {
CONS_Printf("MobjType MT_%s allocated.\n",word);
{
if (!FREE_MOBJS[i])
{
CONS_Printf("MobjType MT_%s allocated.\n", word);
LUA_InvalidateMathlibCache(va("MT_%s", word));
FREE_MOBJS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_MOBJS[i],word);
strcpy(FREE_MOBJS[i], word);
freeslotusage[1][0]++;
break;
}
}
if (i == NUMMOBJFREESLOTS)
I_Error("Out of Mobj Freeslots while allocating \"%s\"\nLoad less addons to fix this.", word);
@@ -426,8 +435,11 @@ static void readthing(MYFILE *f, INT32 num)
strupr(word2);
else
break;
if (word2[strlen(word2)-1] == '\n')
word2[strlen(word2)-1] = '\0';
const size_t word2len = strlen(word2);
if (word2[word2len-1] == '\n')
word2[word2len-1] = '\0';
if (fastcmp(word, "MAPTHINGNUM") || fastcmp(word, "DOOMEDNUM"))
{
@@ -734,14 +746,20 @@ static void readlevelheader(MYFILE *f, INT32 num, INT32 wadnum)
{
UINT16 tol = 0;
tmp = strtok(word2,",");
do {
for (i = 0; TYPEOFLEVEL[i].name; i++)
{
if (fastcmp(tmp, TYPEOFLEVEL[i].name))
break;
}
if (!TYPEOFLEVEL[i].name)
deh_warning("Level header %d: unknown typeoflevel flag %s\n", num, tmp);
tol |= TYPEOFLEVEL[i].flag;
} while((tmp = strtok(NULL,",")) != NULL);
mapheaderinfo[num-1]->typeoflevel = tol;
}
}
@@ -1037,8 +1055,11 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
else
break;
if (word2[strlen(word2)-1] == '\n')
word2[strlen(word2)-1] = '\0';
const size_t word2len = strlen(word2);
if (word2[word2len-1] == '\n')
word2[word2len-1] = '\0';
i = atoi(word2);
usi = (UINT16)i;
@@ -1088,12 +1109,14 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
else if (fastcmp(word, "MUSICSLOT"))
{
i = get_mus(word2, true);
if (i && i <= 1035)
snprintf(cutscenes[num]->scene[scenenum].musswitch, 7, "%sM", G_BuildMapName(i));
else if (i && i <= 1050)
strncpy(cutscenes[num]->scene[scenenum].musswitch, compat_special_music_slots[i - 1036], 7);
else
cutscenes[num]->scene[scenenum].musswitch[0] = 0; // becomes empty string
cutscenes[num]->scene[scenenum].musswitch[6] = 0;
}
#endif
@@ -1498,8 +1521,11 @@ static void readframe(MYFILE *f, INT32 num)
strupr(word2);
else
break;
if (word2[strlen(word2)-1] == '\n')
word2[strlen(word2)-1] = '\0';
const size_t word2len = strlen(word2);
if (word2[word2len-1] == '\n')
word2[word2len-1] = '\0';
if (fastcmp(word1, "SPRITENUMBER") || fastcmp(word1, "SPRITENAME"))
{
@@ -1828,13 +1854,19 @@ static void readextraemblemdata(MYFILE *f, INT32 num)
value = atoi(word2); // used for numerical settings
if (fastcmp(word, "NAME"))
{
deh_strlcpy(extraemblems[num-1].name, word2,
sizeof (extraemblems[num-1].name), va("Extra emblem %d: name", num));
sizeof (extraemblems[num-1].name), va("Extra emblem %d: name", num));
}
else if (fastcmp(word, "OBJECTIVE"))
{
deh_strlcpy(extraemblems[num-1].description, word2,
sizeof (extraemblems[num-1].description), va("Extra emblem %d: objective", num));
sizeof (extraemblems[num-1].description), va("Extra emblem %d: objective", num));
}
else if (fastcmp(word, "CONDITIONSET"))
{
extraemblems[num-1].conditionset = (UINT8)value;
}
else if (fastcmp(word, "SPRITE"))
{
if (word2[0] >= 'A' && word2[0] <= 'Z')
@@ -1906,11 +1938,15 @@ static void readunlockable(MYFILE *f, INT32 num)
i = atoi(word2); // used for numerical settings
if (fastcmp(word, "NAME"))
{
deh_strlcpy(unlockables[num].name, word2,
sizeof (unlockables[num].name), va("Unlockable %d: name", num));
sizeof (unlockables[num].name), va("Unlockable %d: name", num));
}
else if (fastcmp(word, "OBJECTIVE"))
{
deh_strlcpy(unlockables[num].objective, word2,
sizeof (unlockables[num].objective), va("Unlockable %d: objective", num));
sizeof (unlockables[num].objective), va("Unlockable %d: objective", num));
}
else if (fastcmp(word, "SHOWCONDITIONSET"))
unlockables[num].showconditionset = (UINT8)i;
else if (fastcmp(word, "CONDITIONSET"))
@@ -8102,7 +8138,7 @@ static mobjtype_t get_mobjtype(const char *word)
if (*word >= '0' && *word <= '9')
return atoi(word);
if (fastncmp("MT_",word,3))
if (fastncmp("MT_", word, 3))
word += 3; // take off the MT_
for (i = 0; i < NUMMOBJFREESLOTS; i++)
@@ -8128,7 +8164,7 @@ static statenum_t get_state(const char *word)
if (*word >= '0' && *word <= '9')
return atoi(word);
if (fastncmp("S_",word,2))
if (fastncmp("S_", word, 2))
word += 2; // take off the S_
for (i = 0; i < NUMSTATEFREESLOTS; i++)
@@ -8155,11 +8191,11 @@ static spritenum_t get_sprite(const char *word)
if (*word >= '0' && *word <= '9')
return atoi(word);
if (fastncmp("SPR_",word,4))
if (fastncmp("SPR_", word, 4))
word += 4; // take off the SPR_
for (i = 0; i < NUMSPRITES; i++)
if (!sprnames[i][4] && memcmp(word,sprnames[i],4) == 0)
if (!sprnames[i][4] && memcmp(word, sprnames[i], 4) == 0)
return i;
deh_warning("Couldn't find sprite named 'SPR_%s'",word);
@@ -8200,14 +8236,15 @@ static UINT16 get_mus(const char *word, UINT8 dehacked_mode)
if (!word[2] && toupper(word[0]) >= 'A' && toupper(word[0]) <= 'Z')
return (UINT16)M_MapNumber(word[0], word[1]);
if (fastncmp("MUS_",word,4))
if (fastncmp("MUS_", word, 4))
word += 4; // take off the MUS_
else if (fastncmp("O_",word,2) || fastncmp("D_",word,2))
else if (fastncmp("O_", word, 2) || fastncmp("D_", word, 2))
word += 2; // take off the O_ or D_
strncpy(lumptmp, word, 4);
lumptmp[3] = 0;
if (fasticmp("MAP",lumptmp))
if (fasticmp("MAP", lumptmp))
{
word += 3;
if (toupper(word[0]) >= 'A' && toupper(word[0]) <= 'Z')
@@ -8320,7 +8357,7 @@ static inline int lib_freeslot(lua_State *L)
{
sfxenum_t sfx;
strlwr(word);
CONS_Printf("Sound sfx_%s allocated.\n",word);
CONS_Printf("Sound sfx_%s allocated.\n", word);
sfx = S_AddSoundFx(word, false, 0, false);
if (sfx != sfx_None)
@@ -8344,8 +8381,10 @@ static inline int lib_freeslot(lua_State *L)
{
if (!sprnames[j][4] && memcmp(sprnames[j], word, 4) == 0)
sprnames[j][4] = wad;
continue; // Already allocated, next.
}
// Found a free slot!
CONS_Printf("Sprite SPR_%s allocated.\n",word);
@@ -8353,7 +8392,7 @@ static inline int lib_freeslot(lua_State *L)
lua_pushfstring(L, "SPR_%s", word);
lua_call(L, 1, 0);
strncpy(sprnames[j],word,4);
strncpy(sprnames[j], word, 4);
//sprnames[j][4] = 0;
used_spr[(j-SPR_FIRSTFREESLOT)/8] |= 1<<(j%8); // Okay, this sprite slot has been named now.
lua_pushinteger(L, j);
@@ -8371,7 +8410,7 @@ static inline int lib_freeslot(lua_State *L)
{
if (!FREE_STATES[i])
{
CONS_Printf("State S_%s allocated.\n",word);
CONS_Printf("State S_%s allocated.\n", word);
lua_pushcfunction(L, lua_glib_invalidate_cache);
lua_pushfstring(L, "S_%s", word);
@@ -8396,14 +8435,14 @@ static inline int lib_freeslot(lua_State *L)
{
if (!FREE_MOBJS[i])
{
CONS_Printf("MobjType MT_%s allocated.\n",word);
CONS_Printf("MobjType MT_%s allocated.\n", word);
lua_pushcfunction(L, lua_glib_invalidate_cache);
lua_pushfstring(L, "MT_%s", word);
lua_call(L, 1, 0);
FREE_MOBJS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_MOBJS[i],word);
strcpy(FREE_MOBJS[i], word);
freeslotusage[1][0]++;
lua_pushinteger(L, i);
r++;
@@ -8590,6 +8629,7 @@ static int lua_enumlib_mobjtype_get(lua_State *L)
{
if (!FREE_MOBJS[i])
break;
if (fastcmp(s+3, FREE_MOBJS[i]))
{
lua_pushinteger(L, MT_FIRSTFREESLOT+i);
@@ -8678,30 +8718,29 @@ static int lua_enumlib_sfx_get_ds(lua_State *L)
}
#ifdef MUSICSLOT_COMPATIBILITY
static int lua_enumlib_mus_get(lua_State *L)
{
const char *name = strchr(lua_tostring(L, 1), '_') + 1;
int mus = get_mus(name, false);
static int lua_enumlib_mus_get(lua_State *L)
{
const char *name = strchr(lua_tostring(L, 1), '_') + 1;
int mus = get_mus(name, false);
if (mus == 0)
return 0;
if (mus == 0)
return 0;
lua_pushinteger(L, mus);
return 1;
}
lua_pushinteger(L, mus);
return 1;
}
static int lua_enumlib_mus_get_mathlib(lua_State *L)
{
const char *name = strchr(lua_tostring(L, 1), '_') + 1;
int mus = get_mus(name, false);
static int lua_enumlib_mus_get_mathlib(lua_State *L)
{
const char *name = strchr(lua_tostring(L, 1), '_') + 1;
int mus = get_mus(name, false);
if (mus == 0)
return luaL_error(L, "music '%s' could not be found.\n", lua_tostring(L, 1));
if (mus == 0)
return luaL_error(L, "music '%s' could not be found.\n", lua_tostring(L, 1));
lua_pushinteger(L, mus);
return 1;
}
lua_pushinteger(L, mus);
return 1;
}
#endif
static int lua_enumlib_power_get(lua_State *L)
+1 -1
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);
}
/*--------------------------------------------------
+3 -1
View File
@@ -81,10 +81,12 @@ typedef struct
INT16 flags;
INT16 special;
INT16 tag;
// sidenum[1] will be 0xffff if one sided
// sidenum[1] will be NO_INDEX if one sided
UINT16 sidenum[2];
} ATTRPACK maplinedef_t;
#define NO_INDEX 0xffff
//
// LineDef attributes.
//
+31 -2
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,6 +616,21 @@ 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!
#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 __
/// Detect if a client is on Saturn in the clientconfig.
/// To seperately allow them to join or block joining from vanilla clients.
+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
+3 -5
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);
@@ -361,10 +362,7 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
// on for fade-to-black
for (;;)
{
if (I_Interrupted())
{
I_Quit();
}
I_HandleInterrupt();
// get fademask first so we can tell if it exists or not
fmask = F_GetFadeMask(wipetype, wipeframe++);
+104 -97
View File
@@ -447,7 +447,8 @@ void G_WriteDemoExtraData(void)
{
static UINT8 timeout = 0;
if (timeout) timeout--;
if (timeout)
timeout--;
if (demo_writerng == 1 || (demo_writerng == 2 && timeout == 0))
{
@@ -467,6 +468,7 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
if (!demobuf.p || !demo.deferstart)
return;
ziptic = READUINT8(demobuf.p);
if (ziptic & ZT_FWD)
@@ -488,11 +490,12 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
// what in the actual fuck is this???
// SRB2kart: Copy-pasted from ticcmd building, removes that crappy demo cam
if (((players[displayplayers[0]].mo && players[displayplayers[0]].speed > 0) // Moving
const player_t *player = &players[displayplayers[0]];
if (((player->mo && player->speed > 0) // Moving
|| (leveltime > starttime && (cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE)) // Rubber-burn turn
|| (players[displayplayers[0]].kartstuff[k_respawn]) // Respawning
|| (players[displayplayers[0]].spectator || objectplacing)) // Not a physical player
&& !(players[displayplayers[0]].kartstuff[k_spinouttimer] && players[displayplayers[0]].kartstuff[k_sneakertimer])) // Spinning and boosting cancels out spinout
|| (player->kartstuff[k_respawn]) // Respawning
|| (player->spectator || objectplacing)) // Not a physical player
&& !(player->kartstuff[k_spinouttimer] && player->kartstuff[k_sneakertimer])) // Spinning and boosting cancels out spinout
localangle[0] += (cmd->angleturn<<16);
if (!(demoflags & DF_GHOST) && *demobuf.p == DEMOMARKER)
@@ -515,49 +518,49 @@ void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
if (cmd->forwardmove != oldcmd[playernum].forwardmove)
{
WRITEUINT8(demobuf.p,cmd->forwardmove);
WRITEUINT8(demobuf.p, cmd->forwardmove);
oldcmd[playernum].forwardmove = cmd->forwardmove;
ziptic |= ZT_FWD;
}
if (cmd->sidemove != oldcmd[playernum].sidemove)
{
WRITEUINT8(demobuf.p,cmd->sidemove);
WRITEUINT8(demobuf.p, cmd->sidemove);
oldcmd[playernum].sidemove = cmd->sidemove;
ziptic |= ZT_SIDE;
}
if (cmd->angleturn != oldcmd[playernum].angleturn)
{
WRITEINT16(demobuf.p,cmd->angleturn);
WRITEINT16(demobuf.p, cmd->angleturn);
oldcmd[playernum].angleturn = cmd->angleturn;
ziptic |= ZT_ANGLE;
}
if (cmd->buttons != oldcmd[playernum].buttons)
{
WRITEUINT16(demobuf.p,cmd->buttons);
WRITEUINT16(demobuf.p, cmd->buttons);
oldcmd[playernum].buttons = cmd->buttons;
ziptic |= ZT_BUTTONS;
}
if (cmd->aiming != oldcmd[playernum].aiming)
{
WRITEINT16(demobuf.p,cmd->aiming);
WRITEINT16(demobuf.p, cmd->aiming);
oldcmd[playernum].aiming = cmd->aiming;
ziptic |= ZT_AIMING;
}
if (cmd->driftturn != oldcmd[playernum].driftturn)
{
WRITEINT16(demobuf.p,cmd->driftturn);
WRITEINT16(demobuf.p, cmd->driftturn);
oldcmd[playernum].driftturn = cmd->driftturn;
ziptic |= ZT_DRIFT;
}
if (cmd->latency != oldcmd[playernum].latency)
{
WRITEUINT8(demobuf.p,cmd->latency);
WRITEUINT8(demobuf.p, cmd->latency);
oldcmd[playernum].latency = cmd->latency;
ziptic |= ZT_LATENCY;
}
@@ -713,7 +716,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;
@@ -726,8 +729,8 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
// GZT_XYZ is only useful if you've moved 256 FRACUNITS or more in a single tic.
if (abs(ghost->x-oldghost[playernum].x) > MAXMOM
|| abs(ghost->y-oldghost[playernum].y) > MAXMOM
|| abs(ghost->z-oldghost[playernum].z) > MAXMOM
|| abs(ghost->y-oldghost[playernum].y) > MAXMOM
|| abs(ghost->z-oldghost[playernum].z) > MAXMOM
|| ((UINT8)(leveltime & 255) > 0 && (UINT8)(leveltime & 255) <= (UINT8)cv_netdemosyncquality.value)) // Hack to enable slightly nicer resyncing
{
oldghost[playernum].x = ghost->x;
@@ -931,7 +934,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;
@@ -976,7 +979,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;
@@ -1344,7 +1347,7 @@ fadeghost:
}
else
{
mobj = P_SpawnMobj(g->mo->x, g->mo->y, g->mo->z - FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height,3*FRACUNIT), MT_THOK);
mobj = P_SpawnMobj(g->mo->x, g->mo->y, g->mo->z - FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height, 3*FRACUNIT), MT_THOK);
mobj->sprite = states[mobjinfo[type].spawnstate].sprite;
mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<<FF_TRANSSHIFT;
mobj->tics = -1; // nope.
@@ -1375,7 +1378,7 @@ fadeghost:
UINT16 i, health;
UINT16 count = READUINT16(g->p);
//UINT32 type;
fixed_t x,y,z;
fixed_t x, y, z;
angle_t angle;
mobj_t *poof;
@@ -1518,7 +1521,9 @@ void G_PreviewRewind(tic_t previewtime)
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
player_t *player = &players[i];
if (!playeringame[i] || player->spectator)
{
if (info->playerinfo[i].player.mo)
{
@@ -1530,35 +1535,35 @@ void G_PreviewRewind(tic_t previewtime)
if (!info->playerinfo[i].ingame || !info->playerinfo[i].player.mo)
{
if (players[i].mo)
players[i].mo->flags2 |= MF2_DONTDRAW;
if (player->mo)
player->mo->flags2 |= MF2_DONTDRAW;
continue;
}
if (!players[i].mo)
if (!player->mo)
continue; //@TODO spawn temp object to act as a player display
players[i].mo->flags2 &= ~MF2_DONTDRAW;
player->mo->flags2 &= ~MF2_DONTDRAW;
P_UnsetThingPosition(players[i].mo);
P_UnsetThingPosition(player->mo);
#define TWEEN(pr) info->playerinfo[i].mobj.pr + FixedMul((INT32) (next_info->playerinfo[i].mobj.pr - info->playerinfo[i].mobj.pr), tweenvalue)
players[i].mo->x = TWEEN(x);
players[i].mo->y = TWEEN(y);
players[i].mo->z = TWEEN(z);
players[i].mo->angle = TWEEN(angle);
player->mo->x = TWEEN(x);
player->mo->y = TWEEN(y);
player->mo->z = TWEEN(z);
player->mo->angle = TWEEN(angle);
#undef TWEEN
P_SetThingPosition(players[i].mo);
P_SetThingPosition(player->mo);
players[i].frameangle = info->playerinfo[i].player.frameangle + FixedMul((INT32) (next_info->playerinfo[i].player.frameangle - info->playerinfo[i].player.frameangle), tweenvalue);
player->frameangle = info->playerinfo[i].player.frameangle + FixedMul((INT32) (next_info->playerinfo[i].player.frameangle - info->playerinfo[i].player.frameangle), tweenvalue);
players[i].mo->sprite = info->playerinfo[i].mobj.sprite;
players[i].mo->frame = info->playerinfo[i].mobj.frame;
player->mo->sprite = info->playerinfo[i].mobj.sprite;
player->mo->frame = info->playerinfo[i].mobj.frame;
players[i].realtime = info->playerinfo[i].player.realtime;
player->realtime = info->playerinfo[i].player.realtime;
for (j = 0; j < NUMKARTSTUFF; j++)
players[i].kartstuff[j] = info->playerinfo[i].player.kartstuff[j];
player->kartstuff[j] = info->playerinfo[i].player.kartstuff[j];
}
for (i = splitscreen; i >= 0; i--)
@@ -1691,7 +1696,7 @@ void G_BeginRecording(void)
return;
}
memset(name,0,sizeof(name));
memset(name, 0, sizeof(name));
demobuf.p = demobuf.buffer;
demoflags = DF_GHOST|(multiplayer ? DF_MULTIPLAYER : (modeattacking<<DF_ATTACKSHIFT));
@@ -1705,9 +1710,9 @@ void G_BeginRecording(void)
// Setup header.
memcpy(demobuf.p, DEMOHEADER, 12); demobuf.p += 12;
WRITEUINT8(demobuf.p,VERSION);
WRITEUINT8(demobuf.p,SUBVERSION);
WRITEUINT16(demobuf.p,DEMOVERSION);
WRITEUINT8(demobuf.p, VERSION);
WRITEUINT8(demobuf.p, SUBVERSION);
WRITEUINT16(demobuf.p, DEMOVERSION);
// Full replay title
demobuf.p += 64;
@@ -1718,11 +1723,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));
@@ -1736,7 +1741,7 @@ void G_BeginRecording(void)
// game data
memcpy(demobuf.p, "PLAY", 4); demobuf.p += 4;
WRITEINT16(demobuf.p,gamemap);
WRITEINT16(demobuf.p, gamemap);
memcpy(demobuf.p, mapmd5, 16); demobuf.p += 16;
WRITEUINT8(demobuf.p, demoflags);
@@ -1768,8 +1773,8 @@ void G_BeginRecording(void)
break;
case ATTACKING_RECORD: // 1
demotime_p = demobuf.p;
WRITEUINT32(demobuf.p,UINT32_MAX); // time
WRITEUINT32(demobuf.p,UINT32_MAX); // lap
WRITEUINT32(demobuf.p, UINT32_MAX); // time
WRITEUINT32(demobuf.p, UINT32_MAX); // lap
break;
default: // 3
break;
@@ -1826,9 +1831,9 @@ void G_BeginRecording(void)
if (demoflags & DF_LUAVARS)
LUA_Archive(&demobuf, false);
memset(&oldcmd,0,sizeof(oldcmd));
memset(&oldghost,0,sizeof(oldghost));
memset(&ghostext,0,sizeof(ghostext));
memset(&oldcmd, 0, sizeof(oldcmd));
memset(&oldghost, 0, sizeof(oldghost));
memset(&ghostext, 0, sizeof(ghostext));
for (i = 0; i < MAXPLAYERS; i++)
{
@@ -1868,19 +1873,19 @@ void G_WriteStanding(UINT8 ranking, char *name, INT32 skinnum, UINT8 color, UINT
// Name
memset(temp, 0, 16);
strncpy(temp, name, 16);
memcpy(demobuf.p,temp,16);
memcpy(demobuf.p, temp, 16);
demobuf.p += 16;
// Skin
memset(temp, 0, 16);
strncpy(temp, skins[skinnum].name, 16);
memcpy(demobuf.p,temp,16);
memcpy(demobuf.p, temp, 16);
demobuf.p += 16;
// Color
memset(temp, 0, 16);
strncpy(temp, KartColor_Names[color], 16);
memcpy(demobuf.p,temp,16);
memcpy(demobuf.p, temp, 16);
demobuf.p += 16;
// Score/time/whatever
@@ -2207,7 +2212,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;
}
@@ -2217,7 +2222,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;
}
@@ -2242,14 +2247,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;
}
@@ -2262,7 +2267,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;
}
@@ -2283,7 +2288,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
@@ -2330,7 +2335,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);
@@ -2339,7 +2344,8 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
extrainfo_p += 16;
// Skin
memcpy(temp,extrainfo_p,16);
memcpy(temp, extrainfo_p, 16);
temp[16] = '\0';
extrainfo_p += 16;
pdemo->standings[count].skin = UINT8_MAX;
@@ -2353,12 +2359,13 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
}
// Color
memcpy(temp,extrainfo_p,16);
memcpy(temp, extrainfo_p, 16);
temp[16] = '\0';
extrainfo_p += 16;
for (i = 0; i < MAXSKINCOLORS; i++)
{
if (fasticmp(KartColor_Names[i],temp)) // SRB2kart
if (fasticmp(KartColor_Names[i], temp)) // SRB2kart
{
pdemo->standings[count].color = i;
break;
@@ -2517,7 +2524,7 @@ void G_LoadDemoTitle(menudemo_t *pdemo)
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;
}
@@ -2529,7 +2536,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;
}
@@ -2558,13 +2565,13 @@ void G_LoadDemoTitle(menudemo_t *pdemo)
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");
}
}
@@ -2628,7 +2635,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);
@@ -2640,7 +2647,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);
@@ -2661,7 +2668,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();
@@ -2687,7 +2694,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();
@@ -2698,7 +2705,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();
@@ -2715,7 +2722,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();
@@ -2742,31 +2749,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;
@@ -2816,7 +2823,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();
@@ -2827,15 +2834,15 @@ void G_DoPlayDemo(char *defdemoname)
if (demo.version == 0x0001)
{
// Player name
memcpy(player_names[0],demobuf.p,16);
memcpy(player_names[0], demobuf.p, 16);
demobuf.p += 16;
// Skin
memcpy(skin,demobuf.p,16);
memcpy(skin, demobuf.p, 16);
demobuf.p += 16;
// Color
memcpy(color,demobuf.p,16);
memcpy(color, demobuf.p, 16);
demobuf.p += 16;
demobuf.p += 5; // Backwards compat - some stats
@@ -2848,7 +2855,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();
@@ -2858,7 +2865,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();
@@ -2868,7 +2875,7 @@ void G_DoPlayDemo(char *defdemoname)
// Set color
for (i = 0; i < MAXSKINCOLORS; i++)
{
if (fasticmp(KartColor_Names[i],color)) // SRB2kart
if (fasticmp(KartColor_Names[i], color)) // SRB2kart
{
players[0].skincolor = i;
break;
@@ -2881,16 +2888,16 @@ 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();
return;
}
memset(&oldcmd,0,sizeof(oldcmd));
memset(&oldghost,0,sizeof(oldghost));
memset(&ghostext,0,sizeof(ghostext));
memset(&oldcmd, 0, sizeof(oldcmd));
memset(&oldghost, 0, sizeof(oldghost));
memset(&ghostext, 0, sizeof(ghostext));
CONS_Alert(CONS_WARNING, M_GetText("Demo version does not match game version. Desyncs may occur.\n"));
@@ -2919,7 +2926,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();
@@ -2968,7 +2975,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();
@@ -2980,7 +2987,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();
@@ -2994,16 +3001,16 @@ void G_DoPlayDemo(char *defdemoname)
players[p].spectator = spectator;
// Name
memcpy(player_names[p],demobuf.p,16);
memcpy(player_names[p], demobuf.p, 16);
demobuf.p += 16;
// Skin
memcpy(skin,demobuf.p,16);
memcpy(skin, demobuf.p, 16);
demobuf.p += 16;
SetPlayerSkin(p, skin);
// Color
memcpy(color,demobuf.p,16);
memcpy(color, demobuf.p, 16);
demobuf.p += 16;
for (i = 0; i < MAXSKINCOLORS; i++)
@@ -3221,15 +3228,15 @@ void G_AddGhost(char *defdemoname)
if (ghostversion == 0x0001)
{
// Player name (TODO: Display this somehow if it doesn't match cv_playername!)
memcpy(name, p,16);
memcpy(name, p, 16);
p += 16;
// Skin
memcpy(skin, p,16);
memcpy(skin, p, 16);
p += 16;
// Color
memcpy(color, p,16);
memcpy(color, p, 16);
p += 16;
// Ghosts do not have a player structure to put this in.
@@ -3381,7 +3388,7 @@ void G_AddGhost(char *defdemoname)
for (i = 0; i < MAXSKINCOLORS; i++)
{
if (fasticmp(KartColor_Names[i],color)) // SRB2kart
if (fasticmp(KartColor_Names[i], color)) // SRB2kart
{
gh->mo->color = (UINT8)i;
break;
@@ -3473,7 +3480,7 @@ void G_UpdateStaffGhostName(lumpnum_t l)
if (ghostversion == 0x0001)
{
// Player name
memcpy(dummystaffname, p,16);
memcpy(dummystaffname, p, 16);
dummystaffname[16] = '\0';
return; // Not really a failure but whatever
}
+2 -1
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;
+41 -46
View File
@@ -63,11 +63,9 @@ gameaction_t gameaction = 0;
gamestate_t gamestate = GS_NULL;
boolean botingame = false;
UINT8 botskin = 0;
skinnum_t botskin = 0;
UINT8 botcolor = 0;
JoyType_t Joystick[MAXSPLITSCREENPLAYERS] = {};
// SRB2kart
char gamedatafilename[64] = "kartdata.dat";
char timeattackfolder[64] = "kart";
@@ -455,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] =
@@ -627,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';
}
@@ -755,7 +736,7 @@ INT32 JoyAxis(axis_input_e axissel, UINT8 player)
if (retaxis > (+JOYAXISRANGE))
retaxis = +JOYAXISRANGE;
if (!Joystick[pnum].bGamepadStyle && axissel < AXISDEAD)
if (!DigitalGamepadStyle(pnum) && axissel < AXISDEAD)
{
const INT32 jdeadzone = ((JOYAXISRANGE-1) * deadzone) >> FRACBITS;
@@ -803,8 +784,8 @@ static void G_HandleLocalDriftturn(ticcmd_t *cmd, UINT8 ssplayer)
const UINT8 forplayer = (ssplayer-1);
const boolean analogjoystickmove = cv_usejoystick[forplayer].value && !Joystick[forplayer].bGamepadStyle;
const boolean gamepadjoystickmove = cv_usejoystick[forplayer].value && Joystick[forplayer].bGamepadStyle;
const boolean analogjoystickmove = cv_usejoystick[forplayer].value && !DigitalGamepadStyle(forplayer);
const boolean gamepadjoystickmove = cv_usejoystick[forplayer].value && DigitalGamepadStyle(forplayer);
turnright = InputDown(gc_turnright, ssplayer);
turnleft = InputDown(gc_turnleft, ssplayer);
@@ -859,7 +840,8 @@ static void G_HandleLocalDriftturn(ticcmd_t *cmd, UINT8 ssplayer)
static void G_BuildLocalTiccmd(ticcmd_t *cmd, UINT8 ssplayer, boolean freecam)
{
INT32 axis = 0;
const boolean usejoystick = cv_usejoystick[(ssplayer-1)].value;
const UINT8 forplayer = (ssplayer-1);
const boolean usejoystick = cv_usejoystick[forplayer].value;
// check for inputs and return button commands
// for stuff like joining with item button, saltyhop, honking, etc.
@@ -895,7 +877,7 @@ static void G_BuildLocalTiccmd(ticcmd_t *cmd, UINT8 ssplayer, boolean freecam)
#undef CHECKINPUT
axis = JoyAxis(AXISLOOKBACK, ssplayer);
camspin[ssplayer-1] = (InputDown(gc_lookback, ssplayer) || (usejoystick && axis > 0));
camspin[forplayer] = (InputDown(gc_lookback, ssplayer) || (usejoystick && axis > 0));
// Reset to our spec player if we watch someone else.
if ((cmd->driftturn || cmd->buttons)
@@ -992,10 +974,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
player_t *player = P_GetLocalPlayerForNum(forplayer);
camera_t *thiscam = &camera[forplayer];
const boolean freecam = camera[forplayer].freecam;
const boolean analogjoystickmove = cv_usejoystick[forplayer].value && !Joystick[forplayer].bGamepadStyle;
const boolean gamepadjoystickmove = cv_usejoystick[forplayer].value && Joystick[forplayer].bGamepadStyle;
const boolean freecam = thiscam->freecam;
lang = localangle[forplayer];
laim = localaiming[forplayer];
@@ -1027,6 +1006,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
return;
}
const boolean analogjoystickmove = cv_usejoystick[forplayer].value && !DigitalGamepadStyle(forplayer);
const boolean gamepadjoystickmove = cv_usejoystick[forplayer].value && DigitalGamepadStyle(forplayer);
usejoystick = (analogjoystickmove || gamepadjoystickmove);
turnright = InputDown(gc_turnright, ssplayer);
turnleft = InputDown(gc_turnleft, ssplayer);
@@ -1311,6 +1293,7 @@ static void G_DoLoadLevel(boolean resetplayer)
{
// fail so reset game stuff
Command_ExitGame_f();
P_FreeCorruptMapWarnings();
return;
}
@@ -1344,6 +1327,8 @@ static void G_DoLoadLevel(boolean resetplayer)
// clear hud messages remains (usually from game startup)
CON_ClearHUD();
// print any map errors now due to clearhud above :chaosleep:
P_PrintCorruptMapWarnings();
server_lagless = !cv_gentlemens.value;
@@ -2645,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))
@@ -3785,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)
@@ -3797,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))
{
@@ -3863,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)
@@ -3882,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);
@@ -4089,6 +4080,7 @@ char *G_BuildMapTitle(INT32 mapnum)
const char *actnum = NULL;
len += strlen(mapheaderinfo[mapnum-1]->lvlttl);
if (strlen(mapheaderinfo[mapnum-1]->zonttl) > 0)
{
zonetext = M_GetText(mapheaderinfo[mapnum-1]->zonttl);
@@ -4099,6 +4091,7 @@ char *G_BuildMapTitle(INT32 mapnum)
zonetext = M_GetText("Zone");
len += strlen(zonetext) + 1; // ' ' + zonetext
}
if (strlen(mapheaderinfo[mapnum-1]->actnum) > 0)
{
actnum = M_GetText(mapheaderinfo[mapnum-1]->actnum);
@@ -4110,10 +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);
if (actnum) sprintf(title + strlen(title), " %s", actnum);
if (zonetext)
snprintf(title + strlen(title), len - strlen(title), " %s", zonetext);
if (actnum)
snprintf(title + strlen(title), len - strlen(title), " %s", actnum);
}
return title;
+6 -4
View File
@@ -118,10 +118,11 @@ extern consvar_t cv_driftsparkpulse;
extern consvar_t cv_gravstretch;
extern consvar_t cv_sloperoll;
extern consvar_t cv_sliptideroll;
extern consvar_t cv_stairjank;
extern consvar_t cv_stairjanksfx;
extern consvar_t cv_slamsound;
extern consvar_t cv_sloperolldist;
extern consvar_t cv_sparkroll;
extern consvar_t cv_spinoutroll;
extern consvar_t cv_squishdance, cv_squishdancespeed;
@@ -227,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)
{
+50 -13
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,26 +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 (cv_rumble_stairjank[i].value
&& (player->stairjank > 8)
&& (player->speed != 0)
&& P_IsObjectOnGround(player->mo))
{
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)
@@ -1214,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)
+295 -245
View File
@@ -12,20 +12,21 @@
/// \brief convert SRB2 map
#include "../doomdef.h"
#include "../doomstat.h"
#ifdef HWRENDER
#include "hw_main.h"
#include "hw_glob.h"
#include "../r_local.h"
#include "../z_zone.h"
#ifdef HWR_LOADING_SCREEN
#include "../console.h"
#include "../v_video.h"
#include "../m_menu.h"
#include "../i_system.h"
#include "../m_argv.h"
#include "../i_video.h"
#include "../w_wad.h"
#include "../p_setup.h" // levelfadecol
#include "../i_video.h"
#endif
//#define DEBUG_HWBSP
// --------------------------------------------------------------------------
// This is global data for planes rendering
@@ -33,19 +34,20 @@
extrasubsector_t *extrasubsectors = NULL;
// newsubsectors are subsectors without segs, added for the plane polygons
#define NEWSUBSECTORS 50
static size_t totsubsectors;
// extra subsectors are subsectors without segs, added for the plane polygons
#define NUM_EXTRA_SUBSECTORS 50
static size_t num_alloc_extra_subsector;
#ifdef PARANOIA
size_t addsubsector;
size_t num_extra_subsector;
#else
static size_t addsubsector;
static size_t num_extra_subsector;
#endif
typedef struct
{
typedef struct {
float x, y;
float dx, dy;
polyvertex_t divpt;
float divfrac;
} fdivline_t;
// when loading the map, this is set to true if portals are found.
@@ -53,7 +55,7 @@ typedef struct
boolean gl_maphasportals = false;
// Determine on mapload if current map has any Horizonlines present
// so we can avoid rather hot checks in HWR_Subsector
// avoids doing a bunch of work during rendering
boolean gl_maphashorizonlines = false;
// ==========================================================================
@@ -80,26 +82,25 @@ static poly_t *HWR_AllocPoly(INT32 numpts)
return p;
}
/// \todo polygons should be freed in reverse order for efficiency,
/// TODO: polygons should be freed in reverse order for efficiency,
/// for now don't free because it doesn't free in reverse order
static void HWR_FreePoly(poly_t *poly)
{
Z_Free(poly);
}
// Return interception along bsp line,
// Return interception along bsp line (partline),
// with the polygon segment
//
static float bspfrac;
static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
polyvertex_t *v2)
// Return the division in partline div fields.
// divfrac = how far along partline vector is crossing pt
static boolean fracdivline(fdivline_t *partline, polyvertex_t *v1, polyvertex_t *v2)
{
static polyvertex_t pt;
double frac;
double num;
double den;
double v1x, v1y, v1dx, v1dy;
double v2x, v2y, v2dx, v2dy;
double frac1, frac2;
double num; // numerator
double den; // denominator
double v1x, v1y, v1dx, v1dy; // polygon side vector, v1->v2
double v3x, v3y, v3dx, v3dy; // partline vector
// a segment of a polygon
v1x = v1->x;
@@ -108,111 +109,118 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
v1dy = v2->y - v1->y;
// the bsp partition line
v2x = bsp->x;
v2y = bsp->y;
v2dx = bsp->dx;
v2dy = bsp->dy;
v3x = partline->x;
v3y = partline->y;
v3dx = partline->dx;
v3dy = partline->dy;
den = v2dy*v1dx - v2dx*v1dy;
den = v3dy*v1dx - v3dx*v1dy;
if (fabsf((float)den) < 1.0E-36f) // avoid checking exactly for 0.0
return NULL; // parallel
if (fabs(den) < 1.0E-36) // avoid check of float for exact 0
return false; // partline and polygon side are effectively parallel
// first check the frac along the polygon segment,
// (do not accept hit with the extensions)
num = (v2x - v1x)*v2dy + (v1y - v2y)*v2dx;
frac = num / den;
num = (v3x - v1x)*v3dy + (v1y - v3y)*v3dx;
frac1 = num / den;
if (frac < 0.0l || frac > 1.0l)
return NULL;
// 0= cross at v1, 1.0= cross at v2
if (frac1 < 0.0 || frac1 > 1.0) // double
return false; // not within the polygon side
// now get the frac along the BSP line
// which is useful to determine what is left, what is right
num = (v2x - v1x)*v1dy + (v1y - v2y)*v1dx;
frac = num / den;
bspfrac = (float)frac;
num = (v3x - v1x)*v1dy + (v1y - v3y)*v1dx;
frac2 = num / den;
// find the interception point along the partition line
pt.x = (float)(v2x + v2dx*frac);
pt.y = (float)(v2y + v2dy*frac);
partline->divfrac = frac2; // how far along partline vector
return &pt;
// [WDJ] find the interception point along the segment.
// It should be slightly more accurate because it is always closer to the
// crossing point than arbitrary positions on the partition line.
partline->divpt.x = v1x + v1dx*frac1;
partline->divpt.y = v1y + v1dy*frac1;
return true;
}
// BOOMEDIT.WAD has a vertex error of .21
#define DIVLINE_VERTEX_DIFF 0.45f
// if two vertice coords have a x and/or y difference
// of less or equal than 1 FRACUNIT, they are considered the same
// point. Note: hardcoded value, 1.0f could be anything else.
static boolean SameVertice (polyvertex_t *p1, polyvertex_t *p2)
static boolean SameVertex(polyvertex_t *p1, polyvertex_t *p2)
{
if (fabsf( p2->x - p1->x ) > DIVLINE_VERTEX_DIFF)
if (fabsf(p2->x - p1->x) > DIVLINE_VERTEX_DIFF)
return false;
if (fabsf( p2->y - p1->y ) > DIVLINE_VERTEX_DIFF)
if (fabsf(p2->y - p1->y) > DIVLINE_VERTEX_DIFF)
return false;
// p1 and p2 are considered the same vertex
return true;
}
// split a _CONVEX_ polygon in two convex polygons
// outputs:
// frontpoly : polygon on right side of bsp line
// backpoly : polygon on left side
//
static void SplitPoly (fdivline_t *bsp, //splitting parametric line
poly_t *poly, //the convex poly we split
poly_t **frontpoly, //return one poly here
poly_t **backpoly) //return the other here
// Called from: WalkBSPNode
static void SplitPoly (fdivline_t *dlnp, // splitting parametric line
poly_t *poly, // the convex poly we split
poly_t **frontpoly, // return one poly here
poly_t **backpoly) // return the other here
{
INT32 i, j;
polyvertex_t *pv;
INT32 ps = -1, pe = -1;
INT32 nptfront, nptback;
INT32 ps, pe; // poly start, end
INT32 ps_online, pe_online;
INT32 nptfront, nptback;
polyvertex_t vs = {};
polyvertex_t ve = {};
polyvertex_t lastpv = {};
float fracs = 0.0f, frace = 0.0f; //used to tell which poly is on
// the front side of the bsp partition line
INT32 psonline = 0, peonline = 0;
float ps_frac = 0.0f, pe_frac = 0.0f; // used to tell which poly is on
// the front side of the bsp partition line
ps = pe = -1;
ps_online = pe_online = 0;
for (i = 0; i < poly->numpts; i++)
{
j = i + 1;
// i, j are one side of the poly
j = i+1;
if (j == poly->numpts)
j = 0;
j = 0; // wrap poly
// start & end points
pv = fracdivline(bsp, &poly->pts[i], &poly->pts[j]);
if (pv == NULL)
if (!fracdivline(dlnp, &poly->pts[i], &poly->pts[j]))
continue;
// have dividing pt
if (ps < 0)
{
// first point
ps = i;
vs = *pv;
fracs = bspfrac;
vs = dlnp->divpt;
ps_frac = dlnp->divfrac;
}
else
{
//the partition line traverse a junction between two segments
// the partition line can traverse a junction between two segments
// or the two points are so close, they can be considered as one
// thus, don't accept, since split 2 must be another vertex
if (SameVertice(pv, &lastpv))
if (SameVertex(&dlnp->divpt, &lastpv))
{
if (pe < 0)
{
ps = i;
psonline = 1;
ps_online = 1;
}
else
{
pe = i;
peonline = 1;
pe_online = 1;
}
}
else
@@ -220,24 +228,25 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
if (pe < 0)
{
pe = i;
ve = *pv;
frace = bspfrac;
ve = dlnp->divpt;
pe_frac = dlnp->divfrac;
}
else
{
// a frac, not same vertice as last one
// we already got pt2 so pt 2 is not on the line,
// so we probably got back to the start point
// which is on the line
if (SameVertice(pv, &vs))
psonline = 1;
// a frac, not same vertice as last one
// we already got pt2 so pt 2 is not on the line,
// so we probably got back to the start point
// which is on the line
if (SameVertex(&dlnp->divpt, &vs))
ps_online = 1;
break;
}
}
}
// remember last point intercept to detect identical points
lastpv = *pv;
lastpv = dlnp->divpt;
}
// no split: the partition line is either parallel and
@@ -254,28 +263,34 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
// linedefs where each side point the same sector, that is:
// the deep water effect with the original Doom
/// \todo make sure front poly is to front of partition line?
//TODO: make sure front poly is to front of partition line?
*frontpoly = poly;
*backpoly = NULL;
*backpoly = NULL;
return;
}
//if (ps >= 0 && pe < 0)
if (pe < 0)
{
//I_Error("SplitPoly: only one point for split line (%d %d)", ps, pe);
*frontpoly = poly;
*backpoly = NULL;
*backpoly = NULL;
return;
}
if (UNLIKELY(pe <= ps))
I_Error("SplitPoly: invalid splitting line (%d %d)", ps, pe);
if (pe <= ps)
{
//I_Error("SplitPoly: invalid splitting line (%d %d)", ps, pe);
*frontpoly = poly;
*backpoly = NULL;
return;
}
// number of points on each side, _not_ counting those
// that may lie just one the line
nptback = pe - ps - peonline;
nptfront = poly->numpts - peonline - psonline - nptback;
// Number of points on each side, _not_ counting those
// that may lie just on the line.
nptback = pe - ps - pe_online;
nptfront = poly->numpts - pe_online - ps_online - nptback;
if (nptback > 0)
*backpoly = HWR_AllocPoly(2 + nptback);
@@ -295,11 +310,9 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
*pv++ = ve;
i = pe;
do
{
do {
if (++i == poly->numpts)
i = 0;
*pv++ = poly->pts[i];
} while (i != ps && --nptfront);
}
@@ -312,68 +325,81 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
*pv++ = vs;
i = ps;
do
{
do {
if (++i == poly->numpts)
i = 0;
*pv++ = poly->pts[i];
} while (i != pe && --nptback);
}
// make sure frontpoly is the one on the 'right' side
// of the partition line
if (fracs > frace)
if (ps_frac > pe_frac)
{
poly_t *swappoly;
swappoly = *backpoly;
*backpoly = *frontpoly;
poly_t* swappoly;
swappoly = *backpoly;
*backpoly = *frontpoly;
*frontpoly = swappoly;
}
HWR_FreePoly (poly);
HWR_FreePoly(poly);
}
// checks if any line is a portal or horizonline, for optimization
static inline void CheckForPortalsAndHorizonLines(boolean firstside, const line_t *line)
{
// portal check
if (!gl_maphasportals && firstside && line->special == PORTALSPECIAL)
{
// Find the other side!
INT32 line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->tag, -1);
// use each seg of the poly as a partition line, keep only the
if (line2 >= 0 && line == &lines[line2])
line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->tag, line2);
if (line2 >= 0) // found it!
gl_maphasportals = 1;
}
// horizonline check
if (!gl_maphashorizonlines && line->special == HORIZONSPECIAL)
gl_maphashorizonlines = true;
}
// Use each seg of the poly as a partition line, keep only the
// part of the convex poly to the front of the seg (that is,
// the part inside the sector), the part behind the seg, is
// the void space and is cut out
// the part inside the sector). The part behind the seg, is
// the void space and is cut out.
//
static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly)
// poly : surrounding convex polygon, non-destructive
// lseg : array of seg
// segcount : number of seg in the array
// Return frontpoly, which may be new or ptr to poly.
// Called from: HWR_SubsecPoly
static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 segcount, poly_t *poly)
{
INT32 i, j;
poly_t* frontpoly = poly; // default, return same poly
polyvertex_t *pv;
INT32 nump = 0, ps, pe;
INT32 poly_num_pts = 0, ps, pe;
polyvertex_t vs = {}, ve = {},
p1 = {}, p2 = {};
float fracs = 0.0f;
float ps_frac = 0.0f;
vertex_t *v1, *v2;
fdivline_t cutseg; // x, y, dx, dy as start of node_t struct
poly_t *temppoly;
// for each seg of the subsector
for (; count--; lseg++)
for (; segcount--; lseg++)
{
// x, y, dx, dy (like a divline)
const line_t *line = lseg->linedef;
// portal check
if (UNLIKELY(!gl_maphasportals && line->special == PORTALSPECIAL && lseg->side == 0))
{
// Find the other side!
INT32 line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->tag, -1);
if (!line)
continue;
if (line == &lines[line2])
line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->tag, line2);
CheckForPortalsAndHorizonLines(lseg->side == 0, line);
if (line2 >= 0) // found it!
gl_maphasportals = 1;
}
if (!gl_maphashorizonlines && line->special == HORIZONSPECIAL)
gl_maphashorizonlines = true;
if (line->sidenum[1] != 0xffff)
if (line->sidenum[1] != NO_INDEX)
{
if (sides[line->sidenum[0]].sector == sides[line->sidenum[1]].sector)
{
@@ -385,10 +411,21 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly)
}
}
p1.x = FIXED_TO_FLOAT(lseg->side ? line->v2->x : line->v1->x);
p1.y = FIXED_TO_FLOAT(lseg->side ? line->v2->y : line->v1->y);
p2.x = FIXED_TO_FLOAT(lseg->side ? line->v1->x : line->v2->x);
p2.y = FIXED_TO_FLOAT(lseg->side ? line->v1->y : line->v2->y);
if (lseg->side) // side 1
{
v1 = line->v2;
v2 = line->v1;
}
else // side 0
{
v1 = line->v1;
v2 = line->v2;
}
p1.x = FixedToFloat(v1->x);
p1.y = FixedToFloat(v1->y);
p2.x = FixedToFloat(v2->x);
p2.y = FixedToFloat(v2->y);
cutseg.x = p1.x;
cutseg.y = p1.y;
@@ -401,125 +438,130 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly)
for (i = 0; i < poly->numpts; i++)
{
j = i + 1;
// i, j are one side of the poly
j = i+1;
if (j == poly->numpts)
j = 0;
pv = fracdivline(&cutseg, &poly->pts[i], &poly->pts[j]);
if (pv == NULL)
if (!fracdivline(&cutseg, &poly->pts[i], &poly->pts[j]))
continue;
// have dividing pt
if (ps < 0)
{
ps = i;
vs = *pv;
fracs = bspfrac;
vs = cutseg.divpt;
ps_frac = cutseg.divfrac;
continue;
}
// frac 1 on previous segment,
// 0 on the next,
// the split line goes through one of the convex poly
// vertices, happens quite often since the convex
// poly is already adjacent to the subsector segs
// on most borders
if (SameVertex(&cutseg.divpt, &vs))
continue;
if (ps_frac <= cutseg.divfrac)
{
poly_num_pts = 2 + poly->numpts - (i-ps);
pe = ps;
ps = i;
ve = cutseg.divpt;
}
else
{
//frac 1 on previous segment,
// 0 on the next,
//the split line goes through one of the convex poly
// vertices, happens quite often since the convex
// poly is already adjacent to the subsector segs
// on most borders
if (SameVertice(pv, &vs))
continue;
if (fracs <= bspfrac)
{
nump = 2 + poly->numpts - (i-ps);
pe = ps;
ps = i;
ve = *pv;
}
else
{
nump = 2 + (i-ps);
pe = i;
ve = vs;
vs = *pv;
}
//found 2nd point
break;
poly_num_pts = 2 + (i-ps);
pe = i;
ve = vs;
vs = cutseg.divpt;
}
// found 2nd point
break;
}
// there was a split
if (ps >= 0)
{
//need 2 points
// need 2 points
if (pe >= 0)
{
// generate FRONT poly
temppoly = HWR_AllocPoly(nump);
frontpoly = HWR_AllocPoly(poly_num_pts);
pv = temppoly->pts;
pv = frontpoly->pts;
*pv++ = vs;
*pv++ = ve;
do
{
if (++ps == poly->numpts)
do {
if (++ps == poly->numpts) // poly wrap
ps = 0;
*pv++ = poly->pts[ps];
} while (ps != pe);
HWR_FreePoly(poly);
poly = temppoly;
poly = frontpoly;
}
#ifdef DEBUG_HWBSP
// hmmm... maybe we should NOT accept this, but this happens
// only when the cut is not needed it seems (when the cut
// line is aligned to one of the borders of the poly, and
// only some times..)
else
{
// hmmm... maybe we should NOT accept this, but this happens
// only when the cut is not needed it seems (when the cut
// line is aligned to one of the borders of the poly, and
// only some times..)
// [WDJ] This happens often (27 times in Doom2 map01).
skipcut++;
I_Error("CutOutPoly: only one point for split line (%d %d) %d", ps, pe, debugpos);
//I_Error("CutOutPoly: only one point for split line (%d %d) %d", ps, pe, debugpos);
}
#endif
}
}
return poly;
return frontpoly;
}
// At this point, the poly should be convex and the exact
// layout of the subsector, it is not always the case,
// layout of the subsector. It is not always the case,
// so continue to cut off the poly into smaller parts with
// each seg of the subsector.
//
static inline void HWR_SubsecPoly(INT32 num, poly_t *poly)
// ssindex : subsec index, 0..(numsubsectors-1)
// poly : surrounding convex polygon, non-destructive
// Called from WalkBSPNode
static inline void HWR_SubsecPoly(INT32 ssindex, poly_t *poly)
{
INT16 count;
INT16 segcount;
subsector_t *sub;
seg_t *lseg;
sub = &subsectors[num];
count = sub->numlines;
sub = &subsectors[ssindex];
segcount = sub->numlines;
lseg = &segs[sub->firstline];
if (poly)
{
poly = CutOutSubsecPoly(lseg,count,poly);
poly = CutOutSubsecPoly(lseg, segcount, poly);
#ifdef DEBUG_HWBSP
totalsubsecpolys++;
#endif
//extra data for this subsector
extrasubsectors[num].planepoly = poly;
extrasubsectors[ssindex].planepoly = poly;
}
}
// the bsp divline have not enouth presition
// search for the segs source of this divline
static inline void SearchDivline(node_t *bsp, fdivline_t *divline)
// The bsp divline does not have enough precision.
// Search for the segs source of this divline.
static inline void SetDivline(node_t *bsp, fdivline_t *divline)
{
divline->x = FIXED_TO_FLOAT(bsp->x);
divline->y = FIXED_TO_FLOAT(bsp->y);
divline->dx = FIXED_TO_FLOAT(bsp->dx);
divline->dy = FIXED_TO_FLOAT(bsp->dy);
// MAR - If you don't use the same partition line that the BSP uses,
// the front/back polys won't match the subsectors in the BSP!
divline->x = FixedToFloat(bsp->x);
divline->y = FixedToFloat(bsp->y);
divline->dx = FixedToFloat(bsp->dx);
divline->dy = FixedToFloat(bsp->dy);
}
//Hurdler: implement a loading status
@@ -532,20 +574,26 @@ static void loading_status(void)
char s[16];
int x, y;
/*if (g_reloadinggamestate)
{
return;
}*/
I_OsPolling();
CON_Drawer();
sprintf(s, "%d%%", (++ls_percent)<<1);
snprintf(s, sizeof(s), "%d%%", (++ls_percent)<<1);
x = BASEVIDWIDTH/2;
y = BASEVIDHEIGHT/2;
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // Black background to match fade in effect
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); // Black background to match fade in effect
//V_DrawPatchFill(srb2back); // SRB2 background, ehhh too bright.
M_DrawTextBox(x-58, y-8, 13, 1);
V_DrawString(x-50, y, V_YELLOWMAP, "Loading...");
V_DrawRightAlignedString(x+50, y, V_YELLOWMAP, s);
// Is this really necessary at this point..?
V_DrawCenteredString(BASEVIDWIDTH/2, 40, V_YELLOWMAP, "OPENGL MODE IS INCOMPLETE AND MAY");
V_DrawCenteredString(BASEVIDWIDTH/2, 50, V_YELLOWMAP, "NOT DISPLAY SOME SURFACES.");
V_DrawCenteredString(BASEVIDWIDTH/2, 40, V_YELLOWMAP, "OPENGL MODE IS INCOMPLETE AND SOME");
V_DrawCenteredString(BASEVIDWIDTH/2, 50, V_YELLOWMAP, "VISUAL FEATURES ARE MISSING/BROKEN.");
V_DrawCenteredString(BASEVIDWIDTH/2, 70, V_YELLOWMAP, "USE AT SONIC'S RISK.");
I_UpdateNoVsync();
@@ -576,14 +624,14 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
{
CONS_Debug(DBG_RENDER, "Adding a new subsector\n");
if (UNLIKELY(addsubsector == numsubsectors + NEWSUBSECTORS))
I_Error("WalkBSPNode: not enough addsubsectors\n");
else if (UNLIKELY(addsubsector > 0x7fff))
I_Error("WalkBSPNode: addsubsector > 0x7fff\n");
if (num_extra_subsector == numsubsectors + NUM_EXTRA_SUBSECTORS)
I_Error("WalkBSPNode: not enough num_extra_subsectors\n");
else if (num_extra_subsector > 0x7fff)
I_Error("WalkBSPNode: num_extra_subsector > 0x7fff\n");
*leafnode = (UINT16)((UINT16)addsubsector | NF_SUBSECTOR);
extrasubsectors[addsubsector].planepoly = poly;
addsubsector++;
*leafnode = (UINT16)((UINT16)num_extra_subsector | NF_SUBSECTOR);
extrasubsectors[num_extra_subsector].planepoly = poly;
num_extra_subsector++;
}
//add subsectors without segs here?
@@ -593,8 +641,8 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
{
HWR_SubsecPoly(bspnum & ~NF_SUBSECTOR, poly);
//Hurdler: implement a loading status
#ifdef HWR_LOADING_SCREEN
//Hurdler: implement a loading status
if (ls_count-- <= 0)
{
ls_count = numsubsectors/50;
@@ -613,7 +661,7 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
}
bsp = &nodes[bspnum];
SearchDivline(bsp, &fdivline);
SetDivline(bsp, &fdivline);
SplitPoly(&fdivline, poly, &frontpoly, &backpoly);
poly = NULL;
@@ -656,12 +704,12 @@ void HWR_FreeExtraSubsectors(void)
extrasubsectors = NULL;
}
#define MAXDIST 1.5f
#define MAXDIST (1.5f)
// BP: can't move vertex: DON'T change polygon geometry! (convex)
//#define MOVEVERTEX
// Is vertex va within the seg v1, v2
static boolean PointInSeg(polyvertex_t *va,polyvertex_t *v1,polyvertex_t *v2)
static boolean PointInSeg(polyvertex_t *va, polyvertex_t *v1, polyvertex_t *v2)
{
register float ax, ay, bx, by, cx, cy, d, norm;
@@ -736,8 +784,8 @@ static boolean PointInSeg(polyvertex_t *va,polyvertex_t *v1,polyvertex_t *v2)
if (cx*cx+cy*cy <= MAXDIST*MAXDIST)
{
// ajust a little the point position
a->x = ax*d+v1->x;
a->y = ay*d+v1->y;
va->x = ax*d+v1->x;
va->y = ay*d+v1->y;
// anyway the correction is not enouth
return true;
}
@@ -749,10 +797,10 @@ static boolean PointInSeg(polyvertex_t *va,polyvertex_t *v1,polyvertex_t *v2)
static INT32 numsplitpoly;
static void SearchSegInBSP(INT32 bspnum,polyvertex_t *p,poly_t *poly)
static void SearchSegInBSP(INT32 bspnum, polyvertex_t *p, poly_t *poly)
{
poly_t *q;
INT32 j,k;
INT32 j, k;
if (bspnum & NF_SUBSECTOR)
{
@@ -772,12 +820,12 @@ static void SearchSegInBSP(INT32 bspnum,polyvertex_t *p,poly_t *poly)
if (k == numpts)
k = 0;
if (!SameVertice(p, &q->pts[j])
&& !SameVertice(p, &q->pts[k])
&& PointInSeg(p, &q->pts[j], &q->pts[k]))
if (!SameVertex(p, &q->pts[j]) &&
!SameVertex(p, &q->pts[k]) &&
PointInSeg(p, &q->pts[j], &q->pts[k]))
{
poly_t *newpoly = HWR_AllocPoly(numpts+1);
INT32 n;
poly_t *newpoly = HWR_AllocPoly(numpts+1);
for (n = 0; n <= j; n++)
newpoly->pts[n] = q->pts[n];
@@ -798,16 +846,17 @@ static void SearchSegInBSP(INT32 bspnum,polyvertex_t *p,poly_t *poly)
return;
}
if ((FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXBOTTOM])-MAXDIST <= p->y) &&
(FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXTOP ])+MAXDIST >= p->y) &&
(FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXLEFT ])-MAXDIST <= p->x) &&
(FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXRIGHT ])+MAXDIST >= p->x))
// Not a subsector, visit left and right children.
if ((FixedToFloat(nodes[bspnum].bbox[0][BOXBOTTOM])-MAXDIST <= p->y) &&
(FixedToFloat(nodes[bspnum].bbox[0][BOXTOP ])+MAXDIST >= p->y) &&
(FixedToFloat(nodes[bspnum].bbox[0][BOXLEFT ])-MAXDIST <= p->x) &&
(FixedToFloat(nodes[bspnum].bbox[0][BOXRIGHT ])+MAXDIST >= p->x))
SearchSegInBSP(nodes[bspnum].children[0], p, poly);
if ((FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXBOTTOM])-MAXDIST <= p->y) &&
(FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXTOP ])+MAXDIST >= p->y) &&
(FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXLEFT ])-MAXDIST <= p->x) &&
(FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXRIGHT ])+MAXDIST >= p->x))
if ((FixedToFloat(nodes[bspnum].bbox[1][BOXBOTTOM])-MAXDIST <= p->y) &&
(FixedToFloat(nodes[bspnum].bbox[1][BOXTOP ])+MAXDIST >= p->y) &&
(FixedToFloat(nodes[bspnum].bbox[1][BOXLEFT ])-MAXDIST <= p->x) &&
(FixedToFloat(nodes[bspnum].bbox[1][BOXRIGHT ])+MAXDIST >= p->x))
SearchSegInBSP(nodes[bspnum].children[1], p, poly);
}
@@ -816,38 +865,43 @@ static void SearchSegInBSP(INT32 bspnum,polyvertex_t *p,poly_t *poly)
// but we must use a different structure : polygone pointing on segs
// segs pointing on polygone and on vertex (too mush complicated, well not
// realy but i am soo lasy), the methode discibed is also better for segs presition
static INT32 SolveTProblem(void)
static void SolveTProblem(void)
{
poly_t *p;
INT32 i;
size_t l;
INT32 i, numpts;
size_t ssnum;
if (cv_glsolvetjoin.value == 0)
return 0;
if (!cv_glsolvetjoin.value)
return;
CONS_Debug(DBG_RENDER, "Solving T-joins. This may take a while. Please wait...\n");
#ifdef HWR_LOADING_SCREEN
CON_Drawer(); //let the user know what we are doing
I_FinishUpdate(); // page flip or blit buffer
#endif
numsplitpoly = 0;
for (l = 0; l < addsubsector; l++)
for (ssnum = 0; ssnum < num_extra_subsector; ssnum++)
{
p = extrasubsectors[l].planepoly;
p = extrasubsectors[ssnum].planepoly;
if (!p)
if (!p || p->numpts == 0)
continue;
for (i = 0; i < p->numpts; i++)
numpts = p->numpts;
for (i = 0; i < numpts; i++)
SearchSegInBSP((INT32)numnodes-1, &p->pts[i], p);
}
#ifdef DEBUG_HWBSP
CONS_Debug(DBG_RENDER, "numsplitpoly %d\n", numsplitpoly);
CONS_Debug(DBG_RENDER, "%d point divides a polygon line\n", numsplitpoly);
#endif
return numsplitpoly;
}
// call this routine after the BSP of a Doom wad file is loaded,
// and it will generate all the convex polys for the hardware renderer
void HWR_CreatePlanePolygons(INT32 bspnum)
@@ -865,7 +919,7 @@ void HWR_CreatePlanePolygons(INT32 bspnum)
#endif
// reset the portal and horizonline flag
gl_maphasportals = gl_maphashorizonlines = 0;
gl_maphasportals = gl_maphashorizonlines = false;
// find min/max boundaries of map
#ifdef DEBUG_HWBSP
@@ -882,39 +936,35 @@ void HWR_CreatePlanePolygons(INT32 bspnum)
HWR_FreeExtraSubsectors();
// allocate extra data for each subsector present in map
totsubsectors = numsubsectors + NEWSUBSECTORS;
extrasubsectors = calloc(totsubsectors, sizeof(*extrasubsectors));
num_alloc_extra_subsector = numsubsectors + NUM_EXTRA_SUBSECTORS;
extrasubsectors = (extrasubsector_t*)calloc(num_alloc_extra_subsector, sizeof(*extrasubsectors));
if (UNLIKELY(!extrasubsectors))
I_Error("couldn't malloc extrasubsectors totsubsectors %s\n", sizeu1(totsubsectors));
I_Error("couldn't malloc extrasubsectors num_alloc_extra_subsector %s\n", sizeu1(num_alloc_extra_subsector));
// number of the first new subsector that might be added
addsubsector = numsubsectors;
num_extra_subsector = numsubsectors;
// construct the initial convex poly that encloses the full map
rootp = HWR_AllocPoly(4);
rootpv = rootp->pts;
rootpv->x = FIXED_TO_FLOAT(rootbbox[BOXLEFT ]);
rootpv->y = FIXED_TO_FLOAT(rootbbox[BOXBOTTOM]); //lr
// clockwise polygon
rootpv->x = FixedToFloat(rootbbox[BOXLEFT ]);
rootpv->y = FixedToFloat(rootbbox[BOXBOTTOM]); //lr
rootpv++;
rootpv->x = FIXED_TO_FLOAT(rootbbox[BOXLEFT ]);
rootpv->y = FIXED_TO_FLOAT(rootbbox[BOXTOP ]); //ur
rootpv->x = FixedToFloat(rootbbox[BOXLEFT ]);
rootpv->y = FixedToFloat(rootbbox[BOXTOP ]); //ur
rootpv++;
rootpv->x = FIXED_TO_FLOAT(rootbbox[BOXRIGHT ]);
rootpv->y = FIXED_TO_FLOAT(rootbbox[BOXTOP ]); //ul
rootpv->x = FixedToFloat(rootbbox[BOXRIGHT ]);
rootpv->y = FixedToFloat(rootbbox[BOXTOP ]); //ul
rootpv++;
rootpv->x = FIXED_TO_FLOAT(rootbbox[BOXRIGHT ]);
rootpv->y = FIXED_TO_FLOAT(rootbbox[BOXBOTTOM]); //ll
rootpv->x = FixedToFloat(rootbbox[BOXRIGHT ]);
rootpv->y = FixedToFloat(rootbbox[BOXBOTTOM]); //ll
rootpv++;
WalkBSPNode(bspnum, rootp, NULL, rootbbox);
#ifdef DEBUG_HWBSP
i = SolveTProblem();
CONS_Debug(DBG_RENDER, "%d point divides a polygon line\n",i);
#else
SolveTProblem();
#endif
#ifdef DEBUG_HWBSP
//debug debug..
+32 -8
View File
@@ -446,7 +446,7 @@ typedef struct
} GLMapTextureSet_t; // idk i suck at naming things
static size_t gl_numtextures = 0; // Texture count
static GLMapTextureSet_t *gl_textures; // For all textures
static GLMapTextureSet_t *gl_textures = NULL; // For all textures
static void HWR_FreeTextureData(patch_t *patch)
{
@@ -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);
}
@@ -570,7 +571,8 @@ void HWR_ClearAllTextures(void)
/*static void HWR_FreeColormapCache(void)
{
HWR_FreePatchCache(false);
}*/
}
*/
void HWR_InitMapTextures(void)
{
@@ -622,11 +624,26 @@ static void HWR_PrecacheLevelFlats(void)
{
// lookup for flats that may´ve been already loaded
flatcheck flatpresent;
flatcheck_init(&flatpresent);
size_t i, j;
size_t i;
#if 0
size_t j;
#endif
INT32 k;
// this kinda messes up encore remapping behavior at times
// so just disable it for now ig
#ifdef GLENCORE
if (encoremap)
{
return;
}
#endif
flatcheck_init(&flatpresent);
flatcheck_reserve(&flatpresent, numlevelflats);
// special case for encore
#if 0
#ifdef GLENCORE
if (encoremap)
{
@@ -666,6 +683,7 @@ static void HWR_PrecacheLevelFlats(void)
}
}
else
#endif
#endif
{
// on non encore we have it simple
@@ -726,7 +744,7 @@ static void HWR_PrecacheLevelTextures(void)
for (j = 0; j < 2; j++)
{
// check if single-sided linedef
if (line->sidenum[j] == 0xffff)
if (line->sidenum[j] == NO_INDEX)
continue;
const side_t *side = &sides[line->sidenum[j]];
@@ -989,18 +1007,18 @@ static void HWR_CacheFlat(GLMipmap_t *glMipmap, lumpnum_t flatlumpnum)
flat[steppy] = glMipmap->colormap->source[flat[steppy]];
}
#endif
if (haschromakey)
{
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;
}
}
#endif
}
// Download a Doom 'flat' to the hardware cache and make it ready for use
@@ -1127,7 +1145,9 @@ void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap)
HWR_UpdatePatchMipmap(patch, glMipmap);
}
else
{
HWR_LoadPatchMipmap(patch, glMipmap);
}
return;
}
@@ -1309,6 +1329,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
@@ -1386,6 +1407,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++)
{
@@ -1394,6 +1416,7 @@ void HWR_SetMapPalette(void)
RGBA_converted[i].s.blue = *(RGB_data++);
RGBA_converted[i].s.alpha = 255;
}
palette = RGBA_converted;
}
@@ -1401,6 +1424,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);
+435 -477
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -102,7 +102,7 @@ void HWR_SetViewSize(void);
void HWR_AddCommands(void);
void HWR_RenderPlayerView(void);
void HWR_RenderPortalViewpoint(gl_portal_t *rootportal, int stencil_level, boolean allow_portals);
void HWR_RenderPortalViewpoint(gl_portal_t *rootportal, int stencil_level);
void HWR_ClearSkyDome(void);
void HWR_BuildSkyDome(void);
+9 -7
View File
@@ -1153,8 +1153,11 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
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;
@@ -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)
@@ -1400,12 +1403,11 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
const angle_t sliptideroll = ((cv_sliptideroll.value && spr->mobj->player) ? spr->mobj->player->sliproll : 0);
const SINT8 flipfactor = flip ? -1 : 1;
const angle_t thingrollangle = (spr->mobj->rollangle - spr->mobj->temprollangle);
if (spr->mobj->rollangle || sliptideroll)
if (thingrollangle || sliptideroll)
{
angle_t rollang = sliptideroll
? (spr->mobj->rollangle) + (sliptideroll * spr->mobj->player->kartstuff[k_aizdriftstrat])
: (spr->mobj->rollangle);
angle_t rollang = sliptideroll ? (thingrollangle + (sliptideroll * spr->mobj->player->kartstuff[k_aizdriftstrat])) : thingrollangle;
rollang *= flipfactor;
@@ -1481,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);
+7 -7
View File
@@ -80,8 +80,8 @@ void HWR_Portal_Add2Lines(const INT32 line1, const INT32 line2, seg_t *seg)
gl_portal_t *portal = HWR_Portal_Add(seg);
// Offset the portal view by the linedef centers
line_t* start = &lines[line1];
line_t* dest = &lines[line2];
line_t* start = &lines[line1];
line_t* dest = &lines[line2];
angle_t dangle = R_PointToAngle2(0, 0, dest->dx, dest->dy) - R_PointToAngle2(start->dx, start->dy, 0, 0);
@@ -99,7 +99,7 @@ void HWR_Portal_Add2Lines(const INT32 line1, const INT32 line2, seg_t *seg)
dest_c.y = dest->v1->y/2 + dest->v2->y/2;
disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy);
angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy);
angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy);
angtopoint += dangle;
portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
@@ -170,7 +170,7 @@ void HWR_RenderPortal(gl_portal_t* portal, gl_portal_t* rootportal, const float
HWR_PortalFrame(portal);
// call HWR_RenderViewpoint
HWR_RenderPortalViewpoint(portal, stencil_level + 1, true);
HWR_RenderPortalViewpoint(portal, stencil_level + 1);
// return to current frame
if (rootportal)
@@ -220,9 +220,9 @@ boolean HWR_PortalCheckBBox(const fixed_t *bspcoord)
if (!portalclipline)
return true;
if (HWR_PortalCheckPointSide(bspcoord[BOXLEFT], bspcoord[BOXTOP]) ||
HWR_PortalCheckPointSide(bspcoord[BOXLEFT], bspcoord[BOXBOTTOM]) ||
HWR_PortalCheckPointSide(bspcoord[BOXRIGHT], bspcoord[BOXTOP]) ||
if (HWR_PortalCheckPointSide(bspcoord[BOXLEFT], bspcoord[BOXTOP]) ||
HWR_PortalCheckPointSide(bspcoord[BOXLEFT], bspcoord[BOXBOTTOM]) ||
HWR_PortalCheckPointSide(bspcoord[BOXRIGHT], bspcoord[BOXTOP]) ||
HWR_PortalCheckPointSide(bspcoord[BOXRIGHT], bspcoord[BOXBOTTOM]))
{
return true;
+5
View File
@@ -76,6 +76,11 @@
//
// Include GLSL_FLOOR_FUDGES or GLSL_WALL_FUDGES or define the fudges in shaders that use this macro.
// dither shader based on
// https://github.com/hughsk/glsl-dither/blob/master/8x8.glsl
// https://github.com/libretro/glsl-shaders/blob/master/dithering/shaders/bayer_4x4.glsl
// adapted and messed about to work with srb2 and scale per resolution
#define GLSL_DOOM_COLORMAP_DITHER \
"float baseValue = max(startmap * STARTMAP_FUDGE - scale * 0.5 * SCALE_FUDGE, cap);\n" \
"float patscale = min(scr_resolution.x / 1280.0, scr_resolution.y / 720.0);\n" \
-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
+37 -22
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; \
} \
@@ -1122,7 +1122,7 @@ static void GL_Perspective(GLfloat fovy, GLfloat aspect)
const GLfloat deltaZ = FAR_CLIPPING_PLANE - NEAR_CLIPPING_PLANE;
if ((fabsf((float)deltaZ) < 1.0E-36f) || fpclassify(aspect) == FP_ZERO)
if ((fabsf(deltaZ) < 1.0E-36f) || fpclassify(aspect) == FP_ZERO)
{
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);
@@ -1583,6 +1596,7 @@ void GL_Draw2DLine(F2DCoord * v1, F2DCoord * v2, RGBA_t Color)
angle = atanf((v2->y-v1->y)/(v2->x-v1->x));
else
angle = (float)N_PI_DEMI;
dx = sinf(angle) / (float)screen_width;
dy = cosf(angle) / (float)screen_height;
@@ -1697,7 +1711,7 @@ static void GL_SetBlendMode(FBITFIELD flags)
void GL_SetBlend(FBITFIELD PolyFlags)
{
const FBITFIELD Xor = CurrentPolyFlags^PolyFlags;;
const FBITFIELD Xor = CurrentPolyFlags^PolyFlags;
if (Xor & (PF_Blending|PF_RemoveYWrap|PF_ForceWrapX|PF_ForceWrapY|PF_Occlude|PF_NoTexture|PF_Modulated|PF_NoDepthTest|PF_Decal|PF_Skydecal|PF_Invisible))
{
@@ -1917,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;
@@ -2489,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)
@@ -2914,7 +2929,7 @@ void GL_CreateModelVBOs(model_t *model)
}
}
#define BUFFER_OFFSET(i) ((char*)(i))
#define BUFFER_OFFSET(i) ((void*)(i))
void GL_DrawModelEx(model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
{
@@ -3207,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);
@@ -3233,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
@@ -3253,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
@@ -3268,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
@@ -3318,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;
}
@@ -3331,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);
@@ -3340,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);
@@ -3355,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);
+177 -67
View File
@@ -117,6 +117,11 @@ static void HU_DrawRankings(void);
consvar_t cv_showspecstuff = {"showspecstuff", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
// stuff from SRB2-Banpyura thx alot! :3
consvar_t cv_chat_xoffset = {"chat_xoffset", "0", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chat_yoffset = {"chat_yoffset", "0", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chat_showlimit = {"chat_showlimit", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
static char cechotext[1024];
static tic_t cechotimer = 0;
static tic_t cechoduration = 5*TICRATE;
@@ -133,6 +138,7 @@ static void Command_Say_f(void);
static void Command_Sayto_f(void);
static void Command_Sayteam_f(void);
static void Command_CSay_f(void);
static void Command_Mute_f(void);
static void Got_Saycmd(const UINT8 **p, INT32 playernum);
void HU_LoadGraphics(void)
@@ -148,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
@@ -182,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
@@ -193,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)
@@ -206,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)
@@ -218,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);
}
@@ -234,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);
}
@@ -260,6 +266,8 @@ void HU_Init(void)
COM_AddCommand("csay", Command_CSay_f);
RegisterNetXCmd(XD_SAY, Got_Saycmd);
COM_AddCommand("muteplayer", Command_Mute_f);
if (dedicated || rendermode == render_none)
return;
@@ -464,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:
@@ -520,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.
@@ -771,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)
@@ -823,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;
@@ -963,7 +968,7 @@ void HU_Ticker(void)
size_t i = 0;
// handle spam while we're at it:
for(; (i < MAXPLAYERS); i++)
for (; (i < MAXPLAYERS); i++)
{
if (stop_spamming[i] > 0)
stop_spamming[i]--;
@@ -1022,21 +1027,42 @@ static boolean HU_clearChatSpaces(void)
return nothingbutspaces;
}
static void DoMute(const char *name)
static void DoMute(const char *name, boolean chat)
{
INT32 pnum = D_LookupPlayer(name);
if (pnum < 0)
// Shortcut to reuse this function for console and chat command
#define PRINT(msg, sound) do { \
if (chat) \
HU_AddChatText((msg), (sound)); \
else \
CONS_Printf("%s\n", msg); \
} while (0)
if (pnum < 0 || !playeringame[pnum])
{
HU_AddChatText("\x85""ERROR: \x80Player not found.", false);
PRINT("\x85""ERROR: \x80Player not found.", false);
return;
}
player_muted[pnum] = !player_muted[pnum];
HU_AddChatText(va("Player '%s' has been %smuted.", player_names[pnum], player_muted[pnum] ? "" : "un"), false);
PRINT(va("Player '%s' has been %smuted.", player_names[pnum], player_muted[pnum] ? "" : "un"), false);
if (player_muted[pnum])
HU_AddChatText("Use same command to unmute them.", false);
PRINT("Use same command to unmute them.", false);
#undef PRINT
}
static void Command_Mute_f(void)
{
if (COM_Argc() < 2)
{
CONS_Printf(M_GetText("mute <playername|playernum>: mute/unmute a player\n"));
return;
}
DoMute(COM_Argv(1), false);
}
static void HU_SendChatMessage(void)
@@ -1070,7 +1096,7 @@ static void HU_SendChatMessage(void)
if (msglength >= 5 && strnicmp(msg, "/mute", 5) == 0) // Used /mute
{
if (msglength > 6)
DoMute(msg+6);
DoMute(msg+6, true);
else
HU_AddChatText("\x82NOTICE: \x80Usage: /mute <name|node>", false);
@@ -1111,6 +1137,7 @@ static void HU_SendChatMessage(void)
return;
}
}
// I'm very bad at C, I swear I am, additional checks eww!
if (spc != 0)
{
@@ -1257,13 +1284,15 @@ boolean HU_Responder(event_t *ev)
chat_on = false;
I_SetTextInput(false);
}
else if ((c == KEY_UPARROW || c == KEY_MOUSEWHEELUP) && chat_scroll > 0 && !OLDCHAT) // CHAT SCROLLING YAYS!
else if ((c == KEY_UPARROW || c == KEY_PGUP || c == KEY_MOUSEWHEELUP) &&
((chat_scroll > 0) && !OLDCHAT)) // CHAT SCROLLING YAYS!
{
chat_scroll--;
justscrolledup = true;
chat_scrolltime = 4;
}
else if ((c == KEY_DOWNARROW || c == KEY_MOUSEWHEELDOWN) && chat_scroll < chat_maxscroll && chat_maxscroll > 0 && !OLDCHAT)
else if ((c == KEY_DOWNARROW || c == KEY_PGDN || c == KEY_MOUSEWHEELDOWN) &&
((chat_scroll < chat_maxscroll) && (chat_maxscroll > 0) && !OLDCHAT))
{
chat_scroll++;
justscrolleddown = true;
@@ -1343,7 +1372,12 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
// 30/7/18: chaty is now the distance at which the lowest point of the chat will be drawn if that makes any sense.
INT16 chatx = 13, chaty = 169; // let's use this as our coordinates, shh
// let's use this as our coordinates, shh
// :chao: guess this just works lol
#define chatx ((INT16)(13 + (cv_chat_xoffset.value)))
#define chaty ((INT16)(169 + (cv_chat_yoffset.value)))
#define CHATSNAP (V_SNAPTOBOTTOM|V_SNAPTOLEFT)
// chat stuff by VincyTM LOL XD!
@@ -1370,7 +1404,7 @@ static void HU_drawMiniChat(void)
for (; i > 0; i--)
{
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), CHATSNAP|V_ALLOWLOWERCASE, chat_mini[i-1]);
size_t j = 0;
INT32 linescount = 0;
emote_t *emote = NULL;
@@ -1430,6 +1464,7 @@ static void HU_drawMiniChat(void)
if (splitscreen)
{
y -= BASEVIDHEIGHT/2;
if (splitscreen > 1)
y += 16;
}
@@ -1447,7 +1482,7 @@ static void HU_drawMiniChat(void)
INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one.
size_t j = 0;
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), CHATSNAP|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
UINT8 *colormap = NULL;
emote_t *emote = NULL;
int emotelen = 0;
@@ -1480,9 +1515,9 @@ static void HU_drawMiniChat(void)
else if ((emote = M_VerifyEmote(msg+j, &emotelen)))
{
if (cv_chatbacktint.value) // on request of wolfy
V_DrawFillConsoleMap(x + dx + 2, y+dy, EMOTEWIDTH, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
V_DrawFillConsoleMap(x + dx + 2, y+dy, EMOTEWIDTH, charheight, 239|CHATSNAP);
M_DrawEmote(x+dx+2, y+dy, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag);
M_DrawEmote(x+dx+2, y+dy, emote, CHATSNAP|transflag);
dx += EMOTEWIDTH - charwidth;
j += emotelen;
@@ -1490,9 +1525,9 @@ static void HU_drawMiniChat(void)
else
{
if (cv_chatbacktint.value) // on request of wolfy
V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|CHATSNAP);
V_DrawChatCharacter(x + dx + 2, y+dy+cv_chatcentertext.value, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap);
V_DrawChatCharacter(x + dx + 2, y+dy+cv_chatcentertext.value, msg[j++] |CHATSNAP|transflag, !cv_allcaps.value, colormap);
}
dx += charwidth;
@@ -1553,13 +1588,13 @@ static void HU_drawChatLog(INT32 offset)
chat_topy = y + chat_scroll*charheight;
chat_bottomy = chat_topy + boxh*charheight;
V_DrawFillConsoleMap(chatx, chat_topy, boxw, boxh*charheight +2, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); // log box
V_DrawFillConsoleMap(chatx, chat_topy, boxw, boxh*charheight +2, 239|CHATSNAP); // log box
for (i = 0; i < chat_nummsg_log; i++) // iterate through our chatlog
{
INT32 clrflag = 0;
INT32 j = 0;
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), CHATSNAP|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
UINT8 *colormap = NULL;
emote_t *emote = NULL;
int emotelen = 0;
@@ -1589,7 +1624,7 @@ static void HU_drawChatLog(INT32 offset)
{
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
{
M_DrawEmote(x+dx+2, y+dy+1, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT);
M_DrawEmote(x+dx+2, y+dy+1, emote, CHATSNAP);
dx += EMOTEWIDTH - charwidth;
}
j += emotelen;
@@ -1597,7 +1632,7 @@ static void HU_drawChatLog(INT32 offset)
else
{
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, !cv_allcaps.value, colormap);
V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j++] |CHATSNAP, !cv_allcaps.value, colormap);
else
j++; // don't forget to increment this or we'll get stuck in the limbo.
}
@@ -1634,9 +1669,9 @@ static void HU_drawChatLog(INT32 offset)
// draw arrows to indicate that we can (or not) scroll.
if (chat_scroll > 0)
V_DrawCharacter(chatx-9, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight | '\x1A', false); // up arrow
V_DrawCharacter(chatx-9, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), CHATSNAP | highlight | '\x1A', false); // up arrow
if (chat_scroll < chat_maxscroll)
V_DrawCharacter(chatx-9, chat_bottomy-((justscrolleddown) ? 5 : 6), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight | '\x1B', false); // down arrow
V_DrawCharacter(chatx-9, chat_bottomy-((justscrolleddown) ? 5 : 6), CHATSNAP | highlight | '\x1B', false); // down arrow
justscrolleddown = false;
justscrolledup = false;
@@ -1654,6 +1689,7 @@ static void HU_DrawChat(void)
INT32 boxw = cv_chatwidth.value;
INT32 t = 0, c = 0, y = chaty - (typelines*charheight);
UINT32 i = 0, saylen = strlen(w_chat_buf); // You learn new things everyday!
UINT32 charcount = 0;
INT32 cflag = 0;
INT32 pm_offset = 0; // for cases when you type emote while also doing /pm
size_t select_start = 0, select_end = 0;
@@ -1685,7 +1721,7 @@ static void HU_DrawChat(void)
cflag = V_GRAYMAP; // set text in gray if chat is muted.
}
V_DrawFillConsoleMap(chatx, y-1, boxw, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT);
V_DrawFillConsoleMap(chatx, y-1, boxw, (typelines*charheight), 239 | CHATSNAP);
while (talk[i])
{
@@ -1693,7 +1729,7 @@ static void HU_DrawChat(void)
++i;
else
{
V_DrawChatCharacter(chatx + c + 2, y, talk[i] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|cflag, !cv_allcaps.value, V_GetStringColormap(talk[i]|cflag));
V_DrawChatCharacter(chatx + c + 2, y, talk[i] |CHATSNAP|cflag, !cv_allcaps.value, V_GetStringColormap(talk[i]|cflag));
i++;
}
@@ -1711,7 +1747,7 @@ static void HU_DrawChat(void)
typelines = 1;
if ((w_chat.cursor == 0 || w_chat.length == 0) && hu_tick < 4)
V_DrawChatCharacter(chatx+2+c, y+1, '_'|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
V_DrawChatCharacter(chatx+2+c, y+1, '_'|CHATSNAP|t, !cv_allcaps.value, NULL);
if (w_chat.select != w_chat.cursor)
{
@@ -1728,17 +1764,23 @@ static void HU_DrawChat(void)
if ((emote = M_VerifyEmote(w_chat_buf+i, &emotelen)))
{
M_DrawEmote(chatx + c + 2, y-1, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT|t);
M_DrawEmote(chatx + c + 2, y-1, emote, CHATSNAP|t);
c += EMOTEWIDTH - charwidth;
i += emotelen-1;
drawwidth = EMOTEWIDTH;
if (cv_chat_showlimit.value)
charcount += emotelen;
}
else if (w_chat_buf[i] >= HU_FONTSTART) //Hurdler: isn't it better like that?
V_DrawChatCharacter(chatx + c + 2, y, w_chat_buf[i] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL);
{
V_DrawChatCharacter(chatx + c + 2, y, w_chat_buf[i] | CHATSNAP | t, !cv_allcaps.value, NULL);
if (cv_chat_showlimit.value)
charcount++;
}
// Draw selection
if (i >= select_start && i < select_end)
V_DrawFill(chatx + c + 2 - (drawwidth-charwidth), y-1, drawwidth, charheight, 103|V_TRANSLUCENT|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t);
V_DrawFill(chatx + c + 2 - (drawwidth-charwidth), y-1, drawwidth, charheight, 103|V_TRANSLUCENT|CHATSNAP|t);
++i;
@@ -1747,7 +1789,7 @@ static void HU_DrawChat(void)
INT32 cursorx = (c+charwidth < boxw-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down.
INT32 cursory = (cursorx != chatx+1) ? (y) : (y+charheight);
if (hu_tick < 4)
V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
V_DrawChatCharacter(cursorx, cursory+1, '_' |CHATSNAP|t, !cv_allcaps.value, NULL);
if (cursorx == chatx+1 && saylen == i-1) // a weirdo hack
{
@@ -1765,6 +1807,13 @@ static void HU_DrawChat(void)
}
}
if (cv_chat_showlimit.value)
{
// Limit
const INT32 clr = ((HU_MAXMSGLEN - charcount) > 64 ? V_TRANSLUCENT : (charcount == HU_MAXMSGLEN ? V_REDMAP : V_YELLOWMAP));
V_DrawSmallString(chatx, y+7, CHATSNAP|clr, va("%d/%d", charcount, HU_MAXMSGLEN));
}
// handle /pm list. It's messy, horrible and I don't care.
if (strnicmp(w_chat_buf, "/pm", 3) == 0 && vid.width >= 400 && !teamtalk) // 320x200 unsupported kthxbai
{
@@ -1800,6 +1849,7 @@ static void HU_DrawChat(void)
{
char nodenum[3];
UINT32 n;
// right, that's half important: (w_chat_buf[4] may be a space since /pm0 msg is perfectly acceptable!)
if (!isdigit(w_chat_buf[3]) || !(isdigit(w_chat_buf[4]) || (w_chat_buf[4] == ' ') || (w_chat_buf[4] == 0)))
break;
@@ -1837,17 +1887,17 @@ static void HU_DrawChat(void)
}
// fill it like the chat so the text doesn't become hard to read because of the hud.
V_DrawFillConsoleMap(chatx + boxw + 2, p_dispy - (6*count), (longest_name_length+4)*4, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT);
V_DrawFillConsoleMap(chatx + boxw + 2, p_dispy - (6*count), (longest_name_length+4)*4, 6, 239 | CHATSNAP);
V_DrawSmallString(chatx + boxw + 4, p_dispy - (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, player_names[i]));
V_DrawSmallString(chatx + boxw + 4, p_dispy - (6*count), CHATSNAP|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, player_names[i]));
count++;
}
if (count == 0) // no results.
{
pm_offset = 48 + 2;
V_DrawFillConsoleMap(chatx + boxw + 2, p_dispy - (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); // fill it like the chat so the text doesn't become hard to read because of the hud.
V_DrawSmallString(chatx + boxw + 4, p_dispy - (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, "NO RESULT.");
V_DrawFillConsoleMap(chatx + boxw + 2, p_dispy - (6*count), 48, 6, 239 | CHATSNAP); // fill it like the chat so the text doesn't become hard to read because of the hud.
V_DrawSmallString(chatx + boxw + 4, p_dispy - (6*count), CHATSNAP|V_ALLOWLOWERCASE, "NO RESULT.");
}
else
{
@@ -1899,15 +1949,15 @@ static void HU_DrawChat(void)
while ((suggest = M_FindEmote(complete, complete_len, skip)) != NULL)
{
V_DrawFillConsoleMap(chatx + boxw + pm_offset + 2, suggesty - (7*skip), emote_suggest_boxw, 6, V_SNAPTOBOTTOM|V_SNAPTOLEFT);
V_DrawFillConsoleMap(chatx + boxw + pm_offset + 2, suggesty - (7*skip), emote_suggest_boxw, 6, CHATSNAP);
// Highlight currently suggested emote
int hlflag = 0;
if (skip == emote_autocomplete.skip && emote_autocomplete.complete[0])
hlflag = V_YELLOWMAP;
V_DrawSmallString(chatx + boxw + pm_offset + 4 + EMOTEWIDTH, suggesty - (7*skip), hlflag|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va(":%s:", suggest->name));
M_DrawEmote(chatx + boxw + pm_offset + 2, suggesty - skip*7, suggest, V_SNAPTOBOTTOM|V_SNAPTOLEFT);
V_DrawSmallString(chatx + boxw + pm_offset + 4 + EMOTEWIDTH, suggesty - (7*skip), hlflag|CHATSNAP|V_ALLOWLOWERCASE, va(":%s:", suggest->name));
M_DrawEmote(chatx + boxw + pm_offset + 2, suggesty - skip*7, suggest, CHATSNAP);
++skip;
}
@@ -1921,6 +1971,7 @@ static void HU_DrawChat(void)
static void HU_DrawChat_Old(void)
{
INT32 t = 0, c = 0, y = HU_INPUTY;
UINT32 charcount = 0;
size_t i = 0;
const char *ntalk = "Say: ", *ttalk = "Say-Team: ";
const char *talk = ntalk;
@@ -1966,11 +2017,17 @@ static void HU_DrawChat_Old(void)
{
M_DrawScaledEmote((HU_INPUTX + c)<<FRACBITS, (y+con_scalefactor*2)<<FRACBITS, charwidth*FRACUNIT/EMOTEWIDTH, emote, V_NOSCALESTART | V_NOSCALEPATCH | t);
i += emotelen-1;
if (cv_chat_showlimit.value)
charcount += emotelen;
}
else if (w_chat_buf[i] >= HU_FONTSTART) //Hurdler: isn't it better like that?
{
//charwidth = hu_font[w_chat[i]-HU_FONTSTART]->width * con_scalefactor;
V_DrawCharacter(HU_INPUTX + c, y, w_chat_buf[i] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value);
if (cv_chat_showlimit.value)
charcount++;
}
// Draw selection
@@ -1983,7 +2040,7 @@ static void HU_DrawChat_Old(void)
{
INT32 cursorx = (HU_INPUTX+c+charwidth < vid.width) ? (HU_INPUTX + c + charwidth) : (HU_INPUTX); // we may have to go down.
INT32 cursory = (cursorx != HU_INPUTX) ? (y) : (y+charheight);
V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value);
V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' | cv_constextsize.value | V_NOSCALESTART |t, !cv_allcaps.value);
}
c += charwidth;
@@ -1993,6 +2050,24 @@ static void HU_DrawChat_Old(void)
y += charheight;
}
}
// console chat users are FINALLY being fed!
if (cv_chat_showlimit.value)
{
const char *lim = va(" (%i/%i)", charcount, HU_MAXMSGLEN);
for (i = 0; lim[i]; i++)
{
V_DrawCharacter(HU_INPUTX + c, y, lim[i] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value);
c += charwidth;
if (c >= vid.width) // text wrapping
{
c = 0;
y += charheight;
}
}
}
}
static void HU_DrawCEcho(void)
@@ -2181,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)
@@ -2213,7 +2289,22 @@ void HU_DrawSongCredits(void)
}
}
static void HU_ForceShowChat(void)
{
// only matters for non console chat
// see m_menu for how forceshowchat is set
if (!chat_on && forceshowchat)
{
// only print this if theres nothing in chat already
if (chat_nummsg_log == 0)
{
HU_AddChatText("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", false);
}
HU_DrawChat();
}
}
// Heads up displays drawer, call each frame
//
void HU_Drawer(void)
@@ -2221,6 +2312,8 @@ void HU_Drawer(void)
if (cv_vhseffect.value && ((paused && !camera[R_GetViewNumber()].freecam) || (demo.playback && cv_playbackspeed.value > 1)))
V_DrawVhsEffect(demo.rewinding);
HU_ForceShowChat();
// draw chat string plus cursor
if (chat_on)
{
@@ -2300,8 +2393,7 @@ void HU_Drawer(void)
// IN-LEVEL MULTIPLAYER RANKINGS
//======================================================================
static int
Ping_gfx_num (int lag)
static int Ping_gfx_num(int lag)
{
if (lag < 2)
return 0;
@@ -2315,8 +2407,7 @@ Ping_gfx_num (int lag)
return 4;
}
static int
Ping_gfx_color (UINT32 lag)
static int Ping_gfx_color(UINT32 lag)
{
if (lag < 2)
return SKINCOLOR_JAWZ;
@@ -2339,8 +2430,7 @@ Ping_gfx_color (UINT32 lag)
return SKINCOLOR_WHITE; // to make the flashing work
}
static const UINT8 *
Ping_gfx_colormap (UINT32 lag, boolean gentleman)
static const UINT8 *Ping_gfx_colormap(UINT32 lag, boolean gentleman)
{
const UINT8 *colormap = NULL;
@@ -2360,8 +2450,7 @@ Ping_gfx_colormap (UINT32 lag, boolean gentleman)
return colormap;
}
static UINT32
Ping_conversion (UINT32 lag)
static UINT32 Ping_conversion(UINT32 lag)
{
if (cv_pingmeasurement.value)
{
@@ -2478,6 +2567,26 @@ void HU_drawPlayerPing(INT32 x, INT32 y, INT32 pnum, INT32 flags)
}
}
void HU_drawLocalPlayerPing(INT32 x, INT32 y, INT32 flags)
{
UINT32 lag = localplayerping;
const boolean gentleman = (cv_mindelay.value && (lag < (tic_t)simulated_lag));
if (gentleman)
{
lag = simulated_lag;
}
if (cv_pingstyle.value == 0) // kart
{
HU_drawKartPing(x, y, lag, flags, gentleman);
}
else if (cv_pingstyle.value == 1) // old style ping
{
HU_drawOldPing(x, y, lag, flags, gentleman);
}
}
//
// HU_DrawSpectatorTicker
//
@@ -2718,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
}
+5
View File
@@ -88,6 +88,10 @@ extern patch_t *tallminus;
// set true whenever the tab rankings are being shown for any reason
extern boolean hu_showscores;
extern consvar_t cv_chat_xoffset;
extern consvar_t cv_chat_yoffset;
extern consvar_t cv_chat_showlimit;
// init heads up data at game startup.
void HU_Init(void);
@@ -104,6 +108,7 @@ void HU_Drawer(void);
char HU_dequeueChatChar(void);
void HU_clearChatChars(void);
void HU_drawPlayerPing(INT32 x, INT32 y, INT32 pnum, INT32 flags); // Lat': Ping drawer for scoreboard.
void HU_drawLocalPlayerPing(INT32 x, INT32 y, INT32 flags);
void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 hilicol);
void HU_DrawEmeralds(INT32 x, INT32 y, INT32 pemeralds);
const char *HU_SkinColorToConsoleColor(skincolors_t color);
+1 -19
View File
@@ -36,25 +36,7 @@ extern "C" {
"JOYBUTTONS is greater than INT64 bits can hold"
#endif
/** \brief The struct JoyType_s
share some joystick information (maybe 2 for splitscreen), to the game input code,
actually, we need to know if it is a gamepad or analog controls
*/
struct JoyType_s
{
/*! this joystick is a gamepad, read: digital axes
if FALSE, interpret the joystick event data as JOYAXISRANGE (see above) */
INT32 bGamepadStyle;
};
typedef struct JoyType_s JoyType_t;
/** \brief Joystick info
for palyer[sic] 1-4's joystick/gamepad
*/
extern JoyType_t Joystick[MAXSPLITSCREENPLAYERS];
#define DigitalGamepadStyle(i) (cv_joyscale[i].value == 0)
#ifdef __cplusplus
} // extern "C"
+27
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
@@ -203,6 +206,15 @@ void I_ShutdownSystem(void);
/** \brief To check if a Interrupt or Terminate Signal was fired
*/
boolean I_Interrupted(void);
static inline void I_HandleInterrupt(void)
{
if (I_Interrupted())
I_Quit();
}
/** \brief Open A URL
*/
int I_OpenURL(const char *url);
/** \brief The I_GetDiskFreeSpace function
@@ -225,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));
+4
View File
@@ -452,7 +452,11 @@ void A_SpawnFreshCopy(void *actor);
extern boolean actionsoverridden[NUMACTIONS];
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
#ifdef PHOBOS_BUILD
#define NUMMOBJFREESLOTS 4096 // should be sufficient
#else
#define NUMMOBJFREESLOTS 1024
#endif
#define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS
#define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8)
+111 -75
View File
@@ -98,6 +98,8 @@ consvar_t cv_showminimapfinished = {"showminimapfinished", "On", CV_SAVE, CV_OnO
CV_PossibleValue_t minimapdot_cons_t[NUMMINIMAPDOTSTUFF];
consvar_t cv_showminimapangle = {"showminimapangle", "Off", CV_SAVE, minimapdot_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_spinoutroll = {"spinoutroll", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t posanim_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Smooth"}, {0, NULL}};
consvar_t cv_posanim = {"postitionanimation", "On", CV_SAVE, posanim_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_smallposnum = {"smallpositionnumber", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -110,6 +112,11 @@ consvar_t cv_fancyroulette = {"animatedroulette", "Off", CV_SAVE, CV_OnOff, NULL
consvar_t cv_darkitembox = {"darkitembox", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; // itembox gets a dark border with specific items
consvar_t cv_multiitemicon = {"multiitemicon", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
enum { ROULETTECOLOR_NONE = -1, ROULETTECOLOR_HUD, ROULETTECOLOR_PLAYER, ROULETTECOLOR_ITEM };
static CV_PossibleValue_t roulettecolor_cons_t[] = {
{ROULETTECOLOR_NONE, "None"}, {ROULETTECOLOR_HUD, "Hud"}, {ROULETTECOLOR_PLAYER, "Player"}, {ROULETTECOLOR_ITEM, "Item"}, {0, NULL}};
consvar_t cv_roulettecolor = {"roulettecolor", "Hud", CV_SAVE, roulettecolor_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_showlaptimes = {"showlaptimes", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_biglaps = {"biglaphud", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; // here for ppl who dont want to make 2 more patches for their custom hud
@@ -226,6 +233,7 @@ void K_RegisterKartHudStuff(void)
CV_RegisterVar(&cv_showminimapnames);
CV_RegisterVar(&cv_showminimapfinished);
CV_RegisterVar(&cv_showminimapangle);
CV_RegisterVar(&cv_spinoutroll);
CV_RegisterVar(&cv_showlapemblem);
@@ -243,6 +251,8 @@ void K_RegisterKartHudStuff(void)
CV_RegisterVar(&cv_multiitemicon);
CV_RegisterVar(&cv_huditemamount);
CV_RegisterVar(&cv_roulettecolor);
CV_RegisterVar(&cv_highresportrait);
CV_RegisterVar(&cv_nametag);
@@ -378,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);
@@ -497,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);
@@ -667,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;
@@ -678,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);
@@ -693,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);
@@ -762,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;
@@ -784,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;
@@ -792,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;
@@ -805,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;
@@ -813,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);
@@ -822,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);
@@ -837,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;
@@ -848,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);
@@ -1136,7 +1149,7 @@ enum
SPEEDO_PMETERSMOL,
};
static SINT8 K_GetSpeedometerStyle(void)
static UINT8 K_GetSpeedometerStyle(void)
{
if (cv_newspeedometer.value == 2 && xtra_speedo)
return SPEEDO_EXTRA;
@@ -1507,74 +1520,77 @@ static void K_drawKartItem(void)
if (stplyr->kartstuff[k_itemroulette])
{
localcolor = K_GetHudColor();
if (cv_roulettecolor.value == ROULETTECOLOR_PLAYER)
localcolor = stplyr->skincolor;
else if (cv_roulettecolor.value != ROULETTECOLOR_NONE)
localcolor = K_GetHudColor();
switch ((stplyr->kartstuff[k_itemroulette] % (14*3)) / 3)
{
// Each case is handled in threes, to give three frames of in-game time to see the item on the roulette
case 0: // Sneaker
localpatch = kp_sneaker[offset];
//localcolor = SKINCOLOR_RASPBERRY;
if (cv_roulettecolor.value == ROULETTECOLOR_ITEM) localcolor = SKINCOLOR_RASPBERRY;
break;
case 1: // Banana
localpatch = kp_banana[offset];
//localcolor = SKINCOLOR_YELLOW;
if (cv_roulettecolor.value == ROULETTECOLOR_ITEM) localcolor = SKINCOLOR_YELLOW;
break;
case 2: // Orbinaut
localpatch = kp_orbinaut[3+offset];
//localcolor = SKINCOLOR_STEEL;
if (cv_roulettecolor.value == ROULETTECOLOR_ITEM) localcolor = SKINCOLOR_STEEL;
break;
case 3: // Mine
localpatch = kp_mine[offset];
//localcolor = SKINCOLOR_JET;
if (cv_roulettecolor.value == ROULETTECOLOR_ITEM) localcolor = SKINCOLOR_JET;
break;
case 4: // Grow
localpatch = kp_grow[offset];
//localcolor = SKINCOLOR_TEAL;
if (cv_roulettecolor.value == ROULETTECOLOR_ITEM) localcolor = SKINCOLOR_TEAL;
break;
case 5: // Hyudoro
localpatch = kp_hyudoro[offset];
//localcolor = SKINCOLOR_STEEL;
if (cv_roulettecolor.value == ROULETTECOLOR_ITEM) localcolor = SKINCOLOR_STEEL;
break;
case 6: // Rocket Sneaker
localpatch = kp_rocketsneaker[offset];
//localcolor = SKINCOLOR_TANGERINE;
if (cv_roulettecolor.value == ROULETTECOLOR_ITEM) localcolor = SKINCOLOR_TANGERINE;
break;
case 7: // Jawz
localpatch = kp_jawz[offset];
//localcolor = SKINCOLOR_JAWZ;
if (cv_roulettecolor.value == ROULETTECOLOR_ITEM) localcolor = SKINCOLOR_JAWZ;
break;
case 8: // Self-Propelled Bomb
localpatch = kp_selfpropelledbomb[offset];
//localcolor = SKINCOLOR_JET;
if (cv_roulettecolor.value == ROULETTECOLOR_ITEM) localcolor = SKINCOLOR_JET;
break;
case 9: // Shrink
localpatch = kp_shrink[offset];
//localcolor = SKINCOLOR_ORANGE;
if (cv_roulettecolor.value == ROULETTECOLOR_ITEM) localcolor = SKINCOLOR_ORANGE;
break;
case 10: // Invincibility
localpatch = localinv;
//localcolor = SKINCOLOR_GREY;
if (cv_roulettecolor.value == ROULETTECOLOR_ITEM) localcolor = SKINCOLOR_GREY;
break;
case 11: // Eggman Monitor
localpatch = kp_eggman[offset];
//localcolor = SKINCOLOR_ROSE;
if (cv_roulettecolor.value == ROULETTECOLOR_ITEM) localcolor = SKINCOLOR_ROSE;
break;
case 12: // Ballhog
localpatch = kp_ballhog[offset];
//localcolor = SKINCOLOR_LILAC;
if (cv_roulettecolor.value == ROULETTECOLOR_ITEM) localcolor = SKINCOLOR_LILAC;
break;
case 13: // Thunder Shield
localpatch = kp_thundershield[offset];
//localcolor = SKINCOLOR_CYAN;
if (cv_roulettecolor.value == ROULETTECOLOR_ITEM) localcolor = SKINCOLOR_CYAN;
break;
/*case 14: // Pogo Spring
localpatch = kp_pogospring[offset];
localcolor = SKINCOLOR_TANGERINE;
if (cv_roulettecolor.value == ROULETTECOLOR_ITEM) localcolor = SKINCOLOR_TANGERINE;
break;
case 15: // Kitchen Sink
localpatch = kp_kitchensink[offset];
localcolor = SKINCOLOR_STEEL;
if (cv_roulettecolor.value == ROULETTECOLOR_ITEM) localcolor = SKINCOLOR_STEEL;
break;*/
default:
break;
@@ -1961,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));
@@ -2281,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]);
}
@@ -2372,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]);
}
@@ -3568,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)
@@ -3771,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);
@@ -3928,10 +3962,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;
@@ -4019,12 +4066,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));
}
}
@@ -4254,6 +4301,7 @@ static void K_drawInput(void)
y -= FRACUNIT;
// stick displays
if (cv_showinput.value == 2 || cv_showinput.value == 3)
{
INT32 axis;
@@ -4263,7 +4311,7 @@ static void K_drawInput(void)
const INT32 joyy = y>>FRACBITS;
static const INT32 joyxoffs = -8;
static const INT32 joyyoffs = -24;
const boolean usejoysprite = (cv_showinput.value == 3 && joystickicon);
const boolean usejoysprite = (cv_showinput.value == 3 && joystickicon);
// O backing
if (usejoysprite)
@@ -4281,40 +4329,20 @@ static void K_drawInput(void)
// kart does not have anything we can get analogue joystick y axis values from
// during normal gameplay, so replicate shit here
// this is horrid but we cant get actual input in replays so uhh
if (demo.playback || !P_IsLocalPlayer(stplyr)) // yeah...........
const boolean analogjoystickmove = (!demo.playback && P_IsLocalPlayer(stplyr) && cv_usejoystick[stplyrnum].value && !DigitalGamepadStyle(stplyrnum));
axis = analogjoystickmove ? JoyAxis(AXISAIM, stplyrnum+1) : 0;
if (axis != 0)
{
hudforward = stplyr->kartstuff[k_throwdir] * KART_FULLTURN;
hudforward -= ((axis * KART_FULLTURN) / JOYAXISRANGE);
}
else
{
const boolean analogjoystickmove = cv_usejoystick[stplyrnum].value && !Joystick[stplyrnum].bGamepadStyle;
const boolean gamepadjoystickmove = cv_usejoystick[stplyrnum].value && Joystick[stplyrnum].bGamepadStyle;
const UINT8 ssplayer = stplyrnum+1;
axis = JoyAxis(AXISAIM, ssplayer);
if (analogjoystickmove && axis != 0)
{
// JOYAXISRANGE is supposed to be 1023 (divide by 1024)
hudforward -= ((axis * KART_FULLTURN) / (JOYAXISRANGE-1));
}
else
{
if (InputDown(gc_aimforward, ssplayer) || (gamepadjoystickmove && axis < 0))
{
hudforward += KART_FULLTURN;
}
if (InputDown(gc_aimbackward, ssplayer) || (gamepadjoystickmove && axis > 0))
{
hudforward -= KART_FULLTURN;
}
}
hudforward = CLAMP(hudforward, -KART_FULLTURN, KART_FULLTURN);
hudforward = stplyr->kartstuff[k_throwdir] * KART_FULLTURN;
}
hudforward = CLAMP(hudforward, -KART_FULLTURN, KART_FULLTURN);
if (cmd->driftturn || hudforward)
{
INT16 turning = encoremode ? -cmd->driftturn : cmd->driftturn;
@@ -4347,7 +4375,7 @@ static void K_drawInput(void)
}
}
}
else
else // wheel
{
if (!cmd->driftturn) // no turn
target = 0;
@@ -4403,6 +4431,9 @@ static void K_drawChallengerScreen(void)
static void K_drawLapStartAnim(void)
{
if (!cv_showlapemblem.value)
return;
// This is an EVEN MORE insanely complicated animation.
const UINT8 progress = 80-stplyr->kartstuff[k_lapanimation];
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE);
@@ -4446,9 +4477,10 @@ static void K_drawLapStartAnim(void)
V_DrawFixedPatch(leftx, y, FRACUNIT, vflags, kp_lapanim_lap[min(progress/2, 6)], NULL);
char *lapnum = va("%02d", stplyr->laps + 1);
const size_t laplength = strlen(lapnum);
for (size_t i = 0; i < laplength; i++)
const int laplength = (int)strlen(lapnum);
for (int i = 0; i < laplength; i++)
{
int digit = lapnum[i] - '0';
int frame = min(2, progress/2 - 8 - (i*2));
@@ -4578,7 +4610,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
@@ -4830,7 +4866,7 @@ void K_drawKartHUD(void)
{
if (stplyr->exiting)
K_drawKartFinish();
else if (stplyr->kartstuff[k_lapanimation] && !splitscreen && cv_showlapemblem.value)
else if (stplyr->kartstuff[k_lapanimation] && !splitscreen)
K_drawLapStartAnim();
}
+1
View File
@@ -41,6 +41,7 @@ extern consvar_t cv_showlaptimes;
extern consvar_t cv_battlespeedo;
extern consvar_t cv_multiitemicon;
extern consvar_t cv_huditemamount;
extern consvar_t cv_roulettecolor;
// for use in timeattack menu
extern patch_t *kp_facenum[MAXPLAYERS+1];
+912 -720
View File
File diff suppressed because it is too large. Load diff
+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;
}
+98 -11
View File
@@ -25,6 +25,7 @@
#include "lua_libs.h"
#include "lua_hook.h"
#include "lua_hud.h" // hud_running errors
#include "lua_profile.h"
/* =========================================================================
ABSTRACTION
@@ -65,6 +66,8 @@ static stringhook_t stringHooks[STRING_HOOK(MAX)];
bool hook_important = true;
#define NONMOHOOK ((mobjtype_t)-1)
// This will be indexed by hook id, the value of which fetches the registry.
static int * hookRefs;
static int nextid;
@@ -296,7 +299,7 @@ struct Hook_State {
INT32 status; /* return status to calling function */
void * userdata;
int hook_type;
mobjtype_t mobj_type; /* < NUMMOBJTYPES if mobj hook */
mobjtype_t mobj_type; /* != NONMOHOOK if mobj hook */
const char * string; /* used to fetch table, ran first if set */
int top; /* index of last argument passed to hook */
int id; /* id to fetch ref */
@@ -364,7 +367,7 @@ FUNCINLINE static ATTRINLINE boolean prepare_hook
int hook_type
){
return init_hook_type(hook, default_status,
hook_type, NUMMOBJTYPES, NULL,
hook_type, NONMOHOOK, NULL,
hookIds[hook_type].numHooks);
}
@@ -391,7 +394,7 @@ FUNCINLINE static ATTRINLINE boolean prepare_string_hook
const char * string
){
if (init_hook_type(hook, default_status,
hook_type, NUMMOBJTYPES, string,
hook_type, NONMOHOOK, string,
stringHooks[hook_type].ref))
{
lua_pushstring(gL, string);
@@ -407,7 +410,7 @@ FUNCINLINE static ATTRINLINE boolean prepare_hud_hook
int hook_type
){
return init_hook_type(hook, 0,
hook_type, NUMMOBJTYPES, NULL,
hook_type, NONMOHOOK, NULL,
hudHookIds[hook_type].numHooks);
}
@@ -443,11 +446,54 @@ FUNCINLINE static ATTRINLINE void get_hook_from_table(Hook_State *hook, int n)
lua_getref(gL, hookRefs[hook->id]);
}
static int pcall(Hook_State *hook)
{
return lua_pcall(gL, hook->values, hook->results, EINDEX);
}
static const char *hook_name(Hook_State *hook)
{
if (hud_running)
{
return hudHookNames[hook->hook_type];
}
else if (hook->string)
{
return stringHookNames[hook->hook_type];
}
//else if (hook->mobj_type > 0)
else if (hook->mobj_type != NONMOHOOK)
{
return mobjHookNames[hook->hook_type];
}
else
{
return hookNames[hook->hook_type];
}
}
static int pcall_timed_or_untimed(Hook_State *hook)
{
if (!hud_running && cv_lua_profile.value > 0)
{
lua_timer_t *timer = LUA_BeginFunctionTimer(gL, -1 - hook->values, hook_name(hook));
int k = pcall(hook);
LUA_EndFunctionTimer(timer);
return k;
}
else
{
return pcall(hook);
}
}
static int call_single_hook_no_copy(Hook_State *hook)
{
hook_important = hook->important;
if (lua_pcall(gL, hook->values, hook->results, EINDEX) == 0)
//if (lua_pcall(gL, hook->values, hook->results, EINDEX) == 0)
if (pcall_timed_or_untimed(hook) == 0)
{
if (hook->results > 0)
{
@@ -530,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,
@@ -547,11 +629,13 @@ static int call_hooks
{
calls += call_string_hooks(hook);
}
else if (hook->mobj_type < NUMMOBJTYPES)
//else if (hook->mobj_type > 0)
else if (hook->mobj_type != NONMOHOOK)
{
/* call generic mobj hooks first */
calls += call_mobj_type_hooks(hook, MT_NULL);
calls += call_mobj_type_hooks(hook, hook->mobj_type);
if (hook->mobj_type < NUMMOBJTYPES)
calls += call_mobj_type_hooks(hook, hook->mobj_type);
ps_lua_mobjhooks.value.i += calls;
}
else
@@ -718,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))
{
@@ -814,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)
@@ -903,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);
@@ -976,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);
+13 -8
View File
@@ -644,20 +644,22 @@ static int libd_drawScaled(lua_State *L)
// KART: draw patch on minimap from x, y coordinates on the map
static int libd_drawOnMinimap(lua_State *L)
{
fixed_t x, y, scale; // coordinates of the object
patch_t *patch; // patch we want to draw
UINT8 *colormap = NULL; // do we want to colormap this patch?
boolean centered; // the patch is centered and doesn't need readjusting on x/y coordinates.
fixed_t x, y, scale; // coordinates of the object
patch_t *patch; // patch we want to draw
UINT8 *colormap = NULL; // do we want to colormap this patch?
boolean centered; // the patch is centered and doesn't need readjusting on x/y coordinates.
huddrawlist_h list;
patch_t *AutomapPic = NULL;
drawinfo_t info;
// variables used to replicate k_kart's mmap drawer:
patch_t *AutomapPic;
// variables used for actually drawing the icon:
INT32 splitflags, minimaptrans;
fixed_t amnumxpos, amnumypos;
fixed_t amxpos, amypos;
INT32 mm_x, mm_y;
fixed_t patchw = 0, patchh = 0;
fixed_t patchw, patchh;
HUDONLY // only run this function in hud hooks
@@ -722,8 +724,11 @@ static int libd_drawOnMinimap(lua_State *L)
mm_y -= AutomapPic->topoffset;
// patch is supposedly already centered, don't butt in.
if (!centered)
if (centered)
{
patchw = patchh = 0; // patch is supposedly already centered, don't butt in.
}
else
{
// scale patch coords
patchw = (patch->width * scale / 2);
+5 -1
View File
@@ -22,7 +22,8 @@
#include "lua_script.h"
#include "lua_libs.h"
#include "lua_hud.h" // hud_running errors
#include "lua_hook.h" // cmd errors
#include "lua_hook.h" // hook_cmd_running errors
#include "lua_profile.h"
boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor);
state_t *astate = NULL;
@@ -110,7 +111,10 @@ static void A_Lua(mobj_t *actor)
LUA_PushUserdata(gL, actor, META_MOBJ);
lua_pushinteger(gL, var1);
lua_pushinteger(gL, var2);
lua_timer_t *timer = LUA_BeginFunctionTimer(gL, -4, "A_Lua");
LUA_Call(gL, 3, 0, 1);
LUA_EndFunctionTimer(timer);
lua_pop(gL, 1); // pop error handler
+1 -1
View File
@@ -652,7 +652,7 @@ static int line_get(lua_State *L)
LUA_PushUserdata(L, &sides[line->sidenum[0]], META_SIDE);
return 1;
case line_backside: // backside
if (line->sidenum[1] == 0xffff)
if (line->sidenum[1] == NO_INDEX)
return 0;
LUA_PushUserdata(L, &sides[line->sidenum[1]], META_SIDE);
return 1;
+264
View File
@@ -0,0 +1,264 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by James Robert Roman
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
#include "screen.h"
#include <algorithm>
#include <cstddef>
#include <unordered_map>
#include <string>
#include <string_view>
#include <vector>
extern "C" {
#include "blua/lua.h"
};
#include "v_video.h"
#include "command.h"
#include "doomtype.h"
#include "i_system.h"
#include "lua_profile.h"
#include "m_perfstats.h"
extern "C" consvar_t cv_lua_profile;
namespace
{
precise_t g_time_reference;
int g_tics_counted;
double g_running_tic_time;
double g_avg_tic_time;
bool g_invalid;
}; // namespace
struct lua_timer_t
{
struct Stat
{
double calls = 0;
double time = 0.0;
};
Stat running, avg;
};
namespace
{
std::unordered_map<std::string, lua_timer_t> g_tic_timers;
}; // namespace
lua_timer_t* LUA_BeginFunctionTimer(lua_State* L, int fn_idx, const char* name)
{
lua_Debug ar;
lua_pushvalue(L, fn_idx);
lua_getinfo(L, ">S", &ar);
auto label = [&]
{
using sv = std::string_view;
sv view{ar.source};
switch (view.front())
{
case '@': // file
if (std::size_t p = view.rfind('/'); p != sv::npos) // lump or base
{
return view.substr(p + 1);
}
break;
case '=': // ??
view.remove_prefix(1);
break;
}
return view;
};
// i sure hope this std::string mess is fine...
auto [it, ins] = g_tic_timers.try_emplace(std::string(va("%s:%d (%s)", std::string(label()).c_str(), ar.linedefined, name)));
auto& [key, timer] = *it;
g_time_reference = I_GetPreciseTime();
return &timer;
}
void LUA_EndFunctionTimer(lua_timer_t* timer)
{
precise_t t = I_GetPreciseTime() - g_time_reference;
double precision = I_GetPrecisePrecision();
timer->running.time += t / precision;
timer->running.calls += 1.0;
}
void LUA_ResetTicTimers(void)
{
if (cv_lua_profile.value <= 0)
{
return;
}
if (g_tics_counted < cv_lua_profile.value)
{
g_tics_counted++;
double precision = I_GetPrecisePrecision();
g_running_tic_time += ps_prevtictime.value.p / precision;
}
else
{
double counted = g_tics_counted;
for (auto& [key, timer] : g_tic_timers)
{
timer.avg = {timer.running.calls / counted, timer.running.time / counted};
timer.running = {};
}
g_avg_tic_time = g_running_tic_time / counted;
g_running_tic_time = 0.0;
g_tics_counted = 1;
g_invalid = false;
}
}
void LUA_RenderTimers(void)
{
constexpr int kRowHeight = 4;
float row_y = kRowHeight;
// pretty much what the whole srb2::Draw does lol
auto draw_row = [](float x, float y, INT32 flags, const char *str)
{
V_DrawSmallStringAtFixed(
FloatToFixed(x),
FloatToFixed(y),
V_MONOSPACE|V_ALLOWLOWERCASE|flags,
str
);
};
draw_row(0.f, 0.f, 0, va("-- AVERAGES PER TIC (over %d tics) --", cv_lua_profile.value));
if (g_invalid)
{
draw_row(0.f, row_y, V_GRAYMAP, " <Data pending>");
return;
}
std::vector<decltype(g_tic_timers)::iterator> view;
view.reserve(g_tic_timers.size());
auto color_flag = [](double t)
{
if (t < 10.0)
{
return V_GRAYMAP;
}
else if (t >= 100.0)
{
return V_YELLOWMAP;
}
else
{
return 0;
}
};
{
double cum = 0.0;
for (auto it = g_tic_timers.begin(); it != g_tic_timers.end(); ++it)
{
auto& [key, timer] = *it;
cum += timer.avg.time;
if (timer.avg.time > 0.0)
{
view.push_back(it);
}
}
{
const INT32 tally_flags = color_flag(cum * 1'000'000.0);
draw_row(0.f, row_y, tally_flags, va("%8.2f us - TOTAL", cum * 1'000'000.0));
draw_row(0.f, row_y + kRowHeight, tally_flags, va("%8.2f ms", cum * 1000.0));
// dont need to show this if we didnt capture over time
// this would just show nan or inf anyways
if (std::fpclassify(g_avg_tic_time) != FP_ZERO)
{
draw_row(0.f, row_y + kRowHeight * 2, tally_flags, va(
"%8.2f%% overhead (%.2f / %.2f) <-- not counting rendering time",
(cum / g_avg_tic_time) * 100.0,
(cum * (double)TICRATE),
(g_avg_tic_time * (double)TICRATE)
));
}
}
row_y += kRowHeight * 4;
}
std::sort(
view.rbegin(),
view.rend(),
[](auto a, auto b)
{
auto& [k1, t1] = *a;
auto& [k2, t2] = *b;
return t1.avg.time < t2.avg.time;
}
);
for (auto it : view)
{
auto& [key, timer] = *it;
double t = timer.avg.time * 1'000'000.0;
draw_row(0.f, row_y, color_flag(t), va(
"%8.2f us %8.2f calls - %s",
t,
timer.avg.calls,
key.c_str()
));
row_y += kRowHeight;
// FIXME this is all ugly and sucks
if (row_y >= BASEVIDHEIGHT)
break;
}
}
extern "C" void lua_profile_OnChange(void)
{
g_invalid = true;
if (cv_lua_profile.value == 0)
{
g_tic_timers = {};
}
}
+38
View File
@@ -0,0 +1,38 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by James Robert Roman
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
#ifndef lua_profile_h
#define lua_profile_h
#include "blua/lua.h"
#include "doomtype.h"
//#include "typedef.h"
#ifdef __cplusplus
extern "C" {
#endif
struct lua_timer_t;
typedef struct lua_timer_t lua_timer_t;
void LUA_ResetTicTimers(void);
lua_timer_t *LUA_BeginFunctionTimer(lua_State *L, int fn_idx, const char *name);
void LUA_EndFunctionTimer(lua_timer_t *timer);
void LUA_RenderTimers(void);
void lua_profile_OnChange(void);
#ifdef __cplusplus
} // extern "C"
#endif
#endif/*lua_profile_h*/
+33 -16
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)
@@ -713,9 +710,12 @@ static UINT8 GetUserdataArchType(int index)
static UINT8 ArchiveValue(UINT8 **p, int TABLESINDEX, int myindex)
{
int type = lua_type(gL, myindex);
if (myindex < 0)
myindex = lua_gettop(gL)+1+myindex;
switch (lua_type(gL, myindex))
switch (type)
{
case LUA_TNONE:
case LUA_TNIL:
@@ -725,8 +725,12 @@ static UINT8 ArchiveValue(UINT8 **p, int TABLESINDEX, int myindex)
case LUA_TLIGHTUSERDATA:
case LUA_TTHREAD:
case LUA_TFUNCTION:
{
const char *typestr = (type == LUA_TLIGHTUSERDATA ? "light userdata" : (type == LUA_TTHREAD ? "thread" : (type == LUA_TFUNCTION ? "function" : "??")));
CONS_Alert(CONS_ERROR, M_GetText("Archived an invalid value! (%s)\n"), typestr);
WRITEUINT8(*p, ARCH_NULL);
return 2;
}
case LUA_TBOOLEAN:
WRITEUINT8(*p, ARCH_BOOLEAN);
WRITEUINT8(*p, lua_toboolean(gL, myindex));
@@ -1453,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);
+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;
+276 -178
View File
File diff suppressed because it is too large. Load diff
+3 -3
View File
@@ -26,7 +26,7 @@ extern "C" {
#include "mserv.h"
#include "r_things.h" // for SKINNAMESIZE
extern boolean forceshowhud;
extern boolean forceshowhud, forceshowchat;
//
// MENUS
@@ -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;
+214 -116
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;
@@ -208,7 +209,7 @@ typedef enum
static menuitem_t MPauseMenu[] =
{
{IT_STRING | IT_CALL, NULL, "Addons...", M_Addons, 8},
{IT_STRING | IT_CALL, NULL, "Add local skins...", M_LocalSkins, 16},
{IT_STRING | IT_CALL, NULL, "Local Add-ons...", M_LocalAddons, 8},
{IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 24},
{IT_STRING | IT_CALL, NULL, "Switch Map..." , M_MapChange, 32},
@@ -238,7 +239,7 @@ static menuitem_t MPauseMenu[] =
typedef enum
{
mpause_addons = 0,
mpause_addlocalskins,
mpause_localaddons,
mpause_scramble,
mpause_switchmap,
#ifdef HAVE_DISCORDRPC
@@ -446,25 +447,25 @@ enum
static menuitem_t SP_ReplayMenu[] =
{
{IT_WHITESTRING|IT_CALL, NULL, "Replay Best Time", M_ReplayTimeAttack, 90},
{IT_WHITESTRING|IT_CALL, NULL, "Replay Best Lap", M_ReplayTimeAttack, 98},
{IT_WHITESTRING|IT_CALL, NULL, "Replay Best Time", M_ReplayTimeAttack, 90},
{IT_WHITESTRING|IT_CALL, NULL, "Replay Best Lap", M_ReplayTimeAttack, 98},
{IT_WHITESTRING|IT_CALL, NULL, "Replay Last", M_ReplayTimeAttack, 106},
{IT_WHITESTRING|IT_CALL, NULL, "Replay Guest", M_ReplayTimeAttack, 114},
{IT_WHITESTRING|IT_KEYHANDLER, NULL, "Replay Staff",M_HandleStaffReplay,122},
{IT_WHITESTRING|IT_CALL, NULL, "Replay Last", M_ReplayTimeAttack, 106},
{IT_WHITESTRING|IT_CALL, NULL, "Replay Guest", M_ReplayTimeAttack, 114},
{IT_WHITESTRING|IT_KEYHANDLER, NULL, "Replay Staff",M_HandleStaffReplay, 122},
{IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 130}
{IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 130}
};
static menuitem_t SP_GuestReplayMenu[] =
{
{IT_WHITESTRING|IT_CALL, NULL, "Save Best Time as Guest", M_SetGuestReplay, 94},
{IT_WHITESTRING|IT_CALL, NULL, "Save Best Lap as Guest", M_SetGuestReplay,102},
{IT_WHITESTRING|IT_CALL, NULL, "Save Last as Guest", M_SetGuestReplay,110},
{IT_WHITESTRING|IT_CALL, NULL, "Save Best Time as Guest", M_SetGuestReplay, 94},
{IT_WHITESTRING|IT_CALL, NULL, "Save Best Lap as Guest", M_SetGuestReplay, 102},
{IT_WHITESTRING|IT_CALL, NULL, "Save Last as Guest", M_SetGuestReplay, 110},
{IT_WHITESTRING|IT_CALL, NULL, "Delete Guest Replay", M_SetGuestReplay,120},
{IT_WHITESTRING|IT_CALL, NULL, "Delete Guest Replay", M_SetGuestReplay, 120},
{IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 130}
{IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 130}
};
static menuitem_t SP_GhostMenu[] =
@@ -555,10 +556,10 @@ static menuitem_t MP_PlayerSetupMenu[] =
static menuitem_t MP_ConnectMenu[] =
{
{IT_STRING | IT_CVAR, NULL, "Sort By", &cv_serversort, 0},
{IT_STRING | IT_KEYHANDLER, NULL, "Page", M_HandleServerPage, 8},
{IT_STRING | IT_CALL, NULL, "Refresh", M_Refresh, 16},
{IT_STRING | IT_KEYHANDLER, NULL, "", M_HandleServerSearch,25},
{IT_STRING | IT_CVAR, NULL, "Sort By", &cv_serversort, 0},
{IT_STRING | IT_KEYHANDLER, NULL, "Page", M_HandleServerPage, 8},
{IT_STRING | IT_CALL, NULL, "Refresh", M_Refresh, 16},
{IT_STRING | IT_KEYHANDLER, NULL, "", M_HandleServerSearch, 25},
{IT_STRING | IT_SPACE, NULL, "", M_Connect, 48},
{IT_STRING | IT_SPACE, NULL, "", M_Connect, 60},
@@ -725,29 +726,36 @@ static const char* OP_AllControlsTooltips[sizeof(OP_AllControlsMenu)/sizeof(OP_A
// The rest is null, for now
};
#define OP_JOYMENU(pnum) \
{IT_HEADER, NULL, "Gameplay Controls", NULL, 7}, \
{IT_STRING | IT_CVAR, NULL, "Aim Forward/Back" , &cv_aimaxis[pnum] , 15}, \
{IT_STRING | IT_CVAR, NULL, "Turn Left/Right" , &cv_turnaxis[pnum] , 20}, \
{IT_STRING | IT_CVAR, NULL, "Accelerate" , &cv_moveaxis[pnum] , 25}, \
{IT_STRING | IT_CVAR, NULL, "Brake" , &cv_brakeaxis[pnum] , 30}, \
{IT_STRING | IT_CVAR, NULL, "Drift" , &cv_driftaxis[pnum] , 35}, \
{IT_STRING | IT_CVAR, NULL, "Use Item" , &cv_fireaxis[pnum] , 40}, \
{IT_STRING | IT_CVAR, NULL, "Look Backward" , &cv_lookbackaxis[pnum] , 45}, \
{IT_STRING | IT_CVAR, NULL, "Custom Button 1" , &cv_custom1axis[pnum] , 50}, \
{IT_STRING | IT_CVAR, NULL, "Custom Button 2" , &cv_custom2axis[pnum] , 55}, \
{IT_STRING | IT_CVAR, NULL, "Custom Button 3" , &cv_custom3axis[pnum] , 60}, \
{IT_HEADER, NULL, "Camera Controls", NULL, 67}, \
{IT_STRING | IT_CVAR, NULL, "Look Up/Down" , &cv_lookaxis[pnum] , 75}, \
{IT_STRING | IT_CVAR, NULL, "Turn Left/Right" , &cv_camturnaxis[pnum] , 80}, \
{IT_STRING | IT_CVAR, NULL, "Strafe Left/Right" , &cv_camstrafeaxis[pnum] , 85}, \
{IT_HEADER, NULL, "Deadzones", NULL, 92}, \
{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},
// 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}, \
{IT_STRING | IT_CVAR, NULL, "Turn Left/Right" , &cv_turnaxis[pnum] , 20}, \
{IT_STRING | IT_CVAR, NULL, "Accelerate" , &cv_moveaxis[pnum] , 25}, \
{IT_STRING | IT_CVAR, NULL, "Brake" , &cv_brakeaxis[pnum] , 30}, \
{IT_STRING | IT_CVAR, NULL, "Drift" , &cv_driftaxis[pnum] , 35}, \
{IT_STRING | IT_CVAR, NULL, "Use Item" , &cv_fireaxis[pnum] , 40}, \
{IT_STRING | IT_CVAR, NULL, "Look Backward" , &cv_lookbackaxis[pnum] , 45}, \
{IT_STRING | IT_CVAR, NULL, "Custom Button 1" , &cv_custom1axis[pnum] , 50}, \
{IT_STRING | IT_CVAR, NULL, "Custom Button 2" , &cv_custom2axis[pnum] , 55}, \
{IT_STRING | IT_CVAR, NULL, "Custom Button 3" , &cv_custom3axis[pnum] , 60}, \
{IT_HEADER, NULL, "Camera Controls", NULL, 67}, \
{IT_STRING | IT_CVAR, NULL, "Look Up/Down" , &cv_lookaxis[pnum] , 75}, \
{IT_STRING | IT_CVAR, NULL, "Turn Left/Right" , &cv_camturnaxis[pnum] , 80}, \
{IT_STRING | IT_CVAR, NULL, "Strafe Left/Right" , &cv_camstrafeaxis[pnum] , 85}, \
{IT_HEADER, NULL, "Deadzones", NULL, 92}, \
{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_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},
@@ -789,10 +837,9 @@ static menuitem_t OP_JoystickSetMenu[] =
static menuitem_t OP_MouseOptionsMenu[] =
{
{IT_STRING | IT_CVAR, NULL, "Use Mouse", &cv_usemouse, 10},
{IT_STRING | IT_CVAR, NULL, "Mouse Turning", &cv_mouseturn, 20},
{IT_STRING | IT_CVAR, NULL, "Invert Mouse", &cv_invertmouse, 30},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Mouse X Speed", &cv_mousexsens, 40},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Mouse X Speed", &cv_mousexsens, 40},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Mouse Y Speed", &cv_mouseysens, 50},
};
@@ -861,7 +908,6 @@ static const char* OP_VideoTooltips[] =
"Advanced graphical options.",
};
enum
{
op_video_res = 0,
@@ -945,24 +991,25 @@ static menuitem_t OP_ExpOptionsMenu[] =
//{IT_STRING | IT_CVAR, NULL, "Randomized Directional Light", &cv_randomdirlight, 45}, // should this ever come back
{IT_STRING | IT_CVAR, NULL, "Skyboxes", &cv_skybox, 40},
{IT_STRING | IT_CVAR, NULL, "Skydome", &cv_skydome, 45},
{IT_STRING | IT_CVAR, NULL, "Precache Level Textures", &cv_precachetextures, 50},
{IT_STRING | IT_CVAR, NULL, "Precache Level Textures", &cv_precachetextures, 55},
{IT_STRING | IT_CVAR, NULL, "FPS counter sampling", &cv_accuratefps, 60},
{IT_STRING | IT_CVAR, NULL, "FPS counter sampling", &cv_accuratefps, 65},
{IT_STRING | IT_CVAR, NULL, "Frameskip", &cv_frameskip, 70},
{IT_STRING | IT_CVAR, NULL, "Frameskip", &cv_frameskip, 75},
{IT_STRING | IT_CVAR, NULL, "Votescreen Scaling", &cv_votebgscaling, 80},
{IT_STRING | IT_CVAR, NULL, "Votescreen Scaling", &cv_votebgscaling, 85},
#ifdef HWRENDER
{IT_STRING | IT_CVAR, NULL, "Screen Textures", &cv_glscreentextures, 90},
{IT_STRING | IT_CVAR, NULL, "Screen Textures", &cv_glscreentextures, 95},
#ifdef USE_FBO_OGL
{IT_STRING | IT_CVAR, NULL, "FBO Downsampling support", &cv_glframebuffer, 95},
{IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_glpalettedepth, 105},
{IT_DISABLED, NULL, "", NULL, 115}, // dummy text
{IT_STRING | IT_CVAR, NULL, "FBO Downsampling support", &cv_glframebuffer, 100},
{IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_glpalettedepth, 110},
{IT_DISABLED, NULL, "", NULL, 120}, // dummy text
#else
{IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_glpalettedepth, 100},
{IT_DISABLED, NULL, "", NULL, 110}, // dummy text
{IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_glpalettedepth, 110},
{IT_DISABLED, NULL, "", NULL, 120}, // dummy text
#endif
#endif
};
@@ -975,12 +1022,13 @@ static const char* OP_ExpTooltips[] =
"Sets minimum sector brightness, useful for dark areas.",
//"Should the directional lightning be randomized each map?\nTakes effect on next map load.",
"Toggle being able to see the sky.",
"Toggle skydome.", // idk man someone give a better description of this
"Preload all level textures on level load.\nMassively reduces texture related stuttering during gameplay\nat the cost of longer level loading times.\nDisable this if you experience timeouts during level switches.",
"Change the FPS counter sampling method\nInaccurate updates slower\nand might miss sudden framerate changes and drops,\nproviding a more averaged result.\nAccurate updates faster, but might be less readable.", // how to ingles??
"Skips rendering frames if game logic takes too long\npreventing gameplay issues during performance drops.", // idk im shit as describing things
"Different methods of scaling the votescreen backgrounds.",
#ifdef HWRENDER
"Disabling Screen Textures may result in a performance boost\nbut will break certain effects.\nScreen textures are required at resolutions lower than your desktop resolution!"
"Disabling Screen Textures may result in a performance boost\nbut will break certain effects.\nScreen textures are required at resolutions lower than your desktop resolution!",
#ifdef USE_FBO_OGL
"Allows the game to downsample from a higher resolution\nthan your display in OpenGL renderer mode.\nRequires a GPU with atleast OpenGL 2.1 support.",
#endif
@@ -996,6 +1044,7 @@ enum
op_exp_secbright,
//op_exp_dirlight,
op_exp_skybox,
op_exp_skydome,
op_exp_texcache,
op_exp_accuratefps,
op_exp_frameskip,
@@ -1009,7 +1058,6 @@ enum
#endif
};
#ifdef HWRENDER
static menuitem_t OP_OpenGLOptionsMenu[] =
{
@@ -1018,17 +1066,17 @@ static menuitem_t OP_OpenGLOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Shaders", &cv_glshaders, 25},
{IT_STRING | IT_CVAR, NULL, "Palette Rendering", &cv_glpaletterendering, 30},
{IT_STRING | IT_CVAR, NULL, "Texture Quality", &cv_gltexturedepth, 45},
{IT_STRING | IT_CVAR, NULL, "Texture Filter", &cv_glfiltermode, 50},
{IT_STRING | IT_CVAR, NULL, "Anisotropic", &cv_glanisotropicmode, 55},
{IT_STRING | IT_CVAR, NULL, "Visual Portals", &cv_glportals, 60},
{IT_STRING | IT_CVAR, NULL, "Texture Quality", &cv_gltexturedepth, 40},
{IT_STRING | IT_CVAR, NULL, "Texture Filter", &cv_glfiltermode, 45},
{IT_STRING | IT_CVAR, NULL, "Anisotropic", &cv_glanisotropicmode, 50},
{IT_STRING | IT_CVAR, NULL, "Visual Portals", &cv_glportals, 55},
{IT_STRING | IT_CVAR, NULL, "Wall Contrast Style", &cv_glfakecontrast, 70},
{IT_STRING | IT_CVAR, NULL, "Slope Contrast", &cv_glslopecontrast, 75},
{IT_STRING | IT_CVAR, NULL, "Dithered Lightning", &cv_gllightdither, 80},
{IT_STRING | IT_CVAR, NULL, "Sprite Billboarding", &cv_glspritebillboarding, 85},
{IT_STRING | IT_CVAR, NULL, "Software Perspective", &cv_glshearing, 90},
{IT_STRING | IT_CVAR, NULL, "Rendering Distance", &cv_glrenderdistance, 95},
{IT_STRING | IT_CVAR, NULL, "Wall Contrast Style", &cv_glfakecontrast, 65},
{IT_STRING | IT_CVAR, NULL, "Slope Contrast", &cv_glslopecontrast, 70},
{IT_STRING | IT_CVAR, NULL, "Dithered Lightning", &cv_gllightdither, 75},
{IT_STRING | IT_CVAR, NULL, "Sprite Billboarding", &cv_glspritebillboarding, 80},
{IT_STRING | IT_CVAR, NULL, "Software Perspective", &cv_glshearing, 85},
{IT_STRING | IT_CVAR, NULL, "Rendering Distance", &cv_glrenderdistance, 90},
};
static const char* OP_OpenGLTooltips[] =
@@ -1066,7 +1114,6 @@ enum
op_gl_shearing,
op_gl_renderdist,
};
#endif
static menuitem_t OP_SoundOptionsMenu[] =
@@ -1077,8 +1124,7 @@ static menuitem_t OP_SoundOptionsMenu[] =
{IT_STRING|IT_CVAR|IT_CV_NOPRINT, NULL, "Music", &cv_gamedigimusic, 30},
{IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "Music Volume", &cv_digmusicvolume, 38},
//#ifndef NO_MIDI
#if 0
#if 0 //#ifndef NO_MIDI
{IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "MIDI Volume", &cv_midimusicvolume, 46},
{IT_STRING|IT_CVAR, NULL, "Reverse L/R Channels", &stereoreverse, 60},
@@ -1113,8 +1159,7 @@ static const char* OP_SoundTooltips[] =
"Volume of Sound effects.",
"Turn Music on or off.",
"Volume of Music.",
//#ifndef NO_MIDI
#if 0
#if 0 //#ifndef NO_MIDI
"Volume of Midi Music.",
#endif
"Reverse left and right channels of audio.",
@@ -1174,7 +1219,7 @@ static const char* OP_SoundAdvancedTooltips[] =
"Should the Grow music be on or off?",
"Should the Invulnerability music be on or off?",
"Should music be kept when restarting the map?",
"Should the Intro fanfare be skipped\nand map music be played on map start?",
"Should the Intro fanfare be skipped\nand map music be played on map start?\nNote that this WILL skip sounds played by the map before round start as well!",
"Controls Sound effects caching.\nKeep will retain previously played sound effects in cache." // man idk how to describe this in a non awful way lmao
"\nOn will preload all sound effects.\nEliminates sound-related lag and stutters but increases memory usage.",
"Size of the Audio Buffer\nreducing it will result in less sound latency\nbut may cause issues such as crackling or distorted Sound.",
@@ -1408,44 +1453,70 @@ static const char* OP_PlayerCamOptionsTooltips[] =
static menuitem_t OP_ChatOptionsMenu[] =
{
// will ANYONE who doesn't know how to use the console want to touch this one?
{IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 5}, // nonetheless...
{IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 5}, // nonetheless...
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
NULL, "Chat Box Width", &cv_chatwidth, 20},
NULL, "Chat Box Width", &cv_chatwidth, 10},
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
NULL, "Chat Box Height", &cv_chatheight, 30},
{IT_STRING | IT_CVAR, NULL, "Center Text in Chat", &cv_chatcentertext, 40},
NULL, "Chat Box Height", &cv_chatheight, 15},
{IT_STRING | IT_CVAR, NULL, "Chat Horizontal Offset", &cv_chat_xoffset, 20},
{IT_STRING | IT_CVAR, NULL, "Chat Vertical Offset", &cv_chat_yoffset, 25},
{IT_STRING | IT_CVAR, NULL, "Chat Background Tint", &cv_chatbacktint, 55},
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 65},
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 75},
{IT_STRING | IT_CVAR, NULL, "Max Chat Messages", &cv_chatlogsize, 85},
{IT_STRING | IT_CVAR, NULL, "Center Text in Chat", &cv_chatcentertext, 35},
{IT_STRING | IT_CVAR, NULL, "Chat Background Tint", &cv_chatbacktint, 40},
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 45},
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 50},
{IT_STRING | IT_CVAR, NULL, "Max Chat Messages", &cv_chatlogsize, 55},
{IT_STRING | IT_CVAR, NULL, "Display Character Limit", &cv_chat_showlimit, 60},
{IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 105}, // shows ping above the framerate if we want to.
{IT_STRING | IT_CVAR, NULL, "Ping display style", &cv_pingstyle, 115},
{IT_STRING | IT_CVAR, NULL, "Ping measurement", &cv_pingmeasurement, 125},
{IT_STRING | IT_CVAR, NULL, "Ping icon", &cv_pingicon, 135},
{IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 70}, // shows ping above the framerate if we want to.
{IT_STRING | IT_CVAR, NULL, "Ping display style", &cv_pingstyle, 75},
{IT_STRING | IT_CVAR, NULL, "Ping measurement", &cv_pingmeasurement, 80},
{IT_STRING | IT_CVAR, NULL, "Ping icon", &cv_pingicon, 85},
{IT_STRING | IT_CVAR, NULL, "Show IP address in playerlist", &cv_shownodeip, 145},
{IT_STRING | IT_CVAR, NULL, "Show IP address in playerlist", &cv_shownodeip, 90},
};
static const char* OP_ChatOptionsTooltips[] =
{
"Chat mode used for in-game chat.",
"Width of chat box.",
"Height of chat box.",
"Width of the chat box.",
"Height of the chat box.",
"Horizontal Offset of the chat box.",
"Vertical Offset of the chat box.",
"Center text in the chat message pop ups.",
"Chatbox background.",
"Background for the chat message pop ups.",
"Fadeout time for new chat message.",
"Spam protection for in-game chat.",
"Maxiumum amount of chat messages to look back at.",
"Show how many characters you have left to type in the chat.",
"Show player ping.",
"Choose the looks of the ping display.", // this is ass idk english lmao
"Choose the style of the ping display.",
"Measurement used for ping.",
"Visibility of ping icon.",
"Should Player IP addresses be printed when using\nthe nodes or listplayers command?",
};
enum
{
op_chat_mode,
op_chat_boxwidth,
op_chat_boxheight,
op_chat_yoffs,
op_chat_xoffs,
op_chat_centertxt,
op_chat_bgtint,
op_chat_fadetime,
op_chat_spamprotect,
op_chat_maxmsg,
op_chat_charlmt,
op_chat_showping,
op_chat_pingstyle,
op_chat_pingmeasr,
op_chat_pingico,
op_chat_nodeip,
};
static menuitem_t OP_GameOptionsMenu[] =
{
{IT_STRING | IT_SUBMENU, NULL, "Random Item Toggles...", &OP_MonitorToggleDef, 10},
@@ -1631,7 +1702,7 @@ static menuitem_t OP_AccessibilityMenu[] =
{IT_SUBMENU|IT_STRING, NULL, "Video Color Settings...", &OP_ColorOptionsDef, 30},
{IT_STRING|IT_CVAR, NULL, "Reduce Effects", &cv_reducevfx, 35},
{IT_STRING|IT_CVAR, NULL, "Midnight Channel Flicker", &cv_lessflicker, 40}, // obsolete now? or still better be a seperate toggle?
{IT_STRING|IT_CVAR, NULL, "Less Midnight Channel Flicker", &cv_lessflicker, 40}, // obsolete now? or still better be a seperate toggle?
{IT_STRING|IT_CVAR, NULL, "Minimum Sector Brightness", &cv_secbright, 45},
@@ -1713,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[] =
@@ -1736,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
@@ -1757,6 +1830,7 @@ enum
sm_hud,
sm_distortionmenu,
sm_credits,
sm_issue,
};
static menuitem_t OP_PlayerDistortMenu[] =
@@ -1767,20 +1841,23 @@ static menuitem_t OP_PlayerDistortMenu[] =
{IT_STRING | IT_CVAR, NULL, "Slope Rotation Distance", &cv_sloperolldist, 15},
{IT_STRING | IT_CVAR, NULL, "Rotate Players when Sliptiding", &cv_sliptideroll, 25},
{IT_STRING | IT_CVAR, NULL, "Rotate Sparks and Boost Trails", &cv_sparkroll, 30},
{IT_STRING | IT_CVAR, NULL, "Rotate Bananas on Throw", &cv_bananthrowroll, 35},
{IT_STRING | IT_CVAR, NULL, "Stair Janking Effect", &cv_stairjank, 30},
{IT_STRING | IT_CVAR, NULL, "Stair Janking Sound Effect", &cv_stairjanksfx, 35}, // idk if that should be here but i dont care atm
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Player Stretch Factor", &cv_gravstretch, 45},
{IT_STRING | IT_CVAR, NULL, "Squish Sound Effect", &cv_slamsound, 50},
{IT_STRING | IT_CVAR, NULL, "Rotate Sparks and Boost Trails", &cv_sparkroll, 40},
{IT_STRING | IT_CVAR, NULL, "Rotate Bananas on Throw", &cv_bananthrowroll, 45},
{IT_STRING | IT_CVAR, NULL, "Saltyhop", &cv_saltyhop, 60},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saltyhop Height", &cv_saltyheight, 65},
{IT_STRING | IT_CVAR, NULL, "Saltyhop Sound Effect", &cv_saltyhopsfx, 70},
{IT_STRING | IT_CVAR, NULL, "Saltyhop Squish", &cv_saltysquish, 75},
{IT_STRING | IT_CVAR, NULL, "Saltyhop Roll", &cv_saltyroll, 80},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Player Stretch Factor", &cv_gravstretch, 55},
{IT_STRING | IT_CVAR, NULL, "Squish Sound Effect", &cv_slamsound, 60},
{IT_STRING | IT_CVAR, NULL, "Squishdance", &cv_squishdance, 90},
{IT_STRING | IT_CVAR, NULL, "Squishdance Speed", &cv_squishdancespeed, 96},
{IT_STRING | IT_CVAR, NULL, "Saltyhop", &cv_saltyhop, 70},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saltyhop Height", &cv_saltyheight, 75},
{IT_STRING | IT_CVAR, NULL, "Saltyhop Sound Effect", &cv_saltyhopsfx, 80},
{IT_STRING | IT_CVAR, NULL, "Saltyhop Squish", &cv_saltysquish, 85},
{IT_STRING | IT_CVAR, NULL, "Saltyhop Roll", &cv_saltyroll, 90},
{IT_STRING | IT_CVAR, NULL, "Squishdance", &cv_squishdance, 100},
{IT_STRING | IT_CVAR, NULL, "Squishdance Speed", &cv_squishdancespeed, 106}, // why is this offset by 6? idk cant remember lulul
};
static const char* OP_PlayerDistortTooltips[] =
@@ -1789,6 +1866,8 @@ static const char* OP_PlayerDistortTooltips[] =
"Sprite rotation on slopes. Can either be just players or all objects.",
"Distance object rotation should be visable.",
"Player rotation when sliptiding.",
"Slightly tilt the player when driving over stairs or small bumps.",
"Sound effect when driving over stairs or small bumps.",
"Rotation of a player's boost trails and drift sparks.",
"Should banans rotate when thrown?\nAnd should they stay rotated when on the ground?",
"Player squash and stretch.",
@@ -1799,7 +1878,7 @@ static const char* OP_PlayerDistortTooltips[] =
"Player hop squash and stretch.",
"Should the player rotation be kept during player hop.",
"Do a funny squishy dance when holding CUSTOM 3.",
"Speed of the Squishy dance in BPM.",
"Speed of the Squishy dance in SPM (Squishes Per Minute).",
};
enum
@@ -1808,6 +1887,8 @@ enum
sloperotate,
slrotatedist,
sliptide,
stairjank,
stairjanksfx,
sparkrotate,
bananrotat,
stretchyplayer,
@@ -1848,26 +1929,28 @@ static menuitem_t OP_SaturnHudMenu[] =
{IT_STRING|IT_CVAR, NULL, "Item Amount Number", &cv_huditemamount, 110},
{IT_STRING|IT_CVAR, NULL, "Animated Roulette", &cv_fancyroulette, 115},
{IT_STRING|IT_CVAR, NULL, "Show Lap Emblem", &cv_showlapemblem, 125},
{IT_STRING|IT_CVAR, NULL, "Show Cecho Messages", &cv_cechotoggle, 130},
{IT_STRING|IT_CVAR, NULL, "Item Roulette Color", &cv_roulettecolor, 120},
{IT_STRING|IT_CVAR, NULL, "Show Names on Minimap", &cv_showminimapnames, 140},
{IT_STRING|IT_CVAR, NULL, "Show Finished on Minimap", &cv_showminimapfinished, 145},
{IT_STRING|IT_CVAR, NULL, "Small Minimap Players", &cv_minihead, 150},
{IT_STRING|IT_CVAR, NULL, "Spin Minimap Icons", &cv_spinoutroll, 155},
{IT_STRING|IT_CVAR, NULL, "Player Angle Visual", &cv_showminimapangle, 160},
{IT_STRING|IT_CVAR, NULL, "Show Lap Emblem", &cv_showlapemblem, 130},
{IT_STRING|IT_CVAR, NULL, "Show Cecho Messages", &cv_cechotoggle, 135},
{IT_STRING|IT_CVAR, NULL, "Music Credits", &cv_songcredits, 170},
{IT_STRING|IT_CVAR, NULL, "Music Credits on Pause", &cv_pausesongcredits, 175},
{IT_STRING|IT_CVAR, NULL, "Show Names on Minimap", &cv_showminimapnames, 145},
{IT_STRING|IT_CVAR, NULL, "Show Finished on Minimap", &cv_showminimapfinished, 150},
{IT_STRING|IT_CVAR, NULL, "Small Minimap Players", &cv_minihead, 155},
{IT_STRING|IT_CVAR, NULL, "Spin Minimap Icons", &cv_spinoutroll, 160},
{IT_STRING|IT_CVAR, NULL, "Player Angle Visual", &cv_showminimapangle, 165},
{IT_STRING|IT_CVAR, NULL, "Beta Intermissionscreen", &cv_betainterscreen, 185},
{IT_STRING|IT_CVAR, NULL, "Music Credits", &cv_songcredits, 175},
{IT_STRING|IT_CVAR, NULL, "Music Credits on Pause", &cv_pausesongcredits, 180},
{IT_STRING|IT_CVAR, NULL, "Show Director Prompt", &cv_showdirectorhud, 195},
{IT_STRING|IT_CVAR, NULL, "Beta Intermissionscreen", &cv_betainterscreen, 190},
{IT_STRING|IT_SUBMENU, NULL, "Nametags...", &OP_NametagDef, 205},
{IT_STRING|IT_SUBMENU, NULL, "Driftgauge...", &OP_DriftGaugeDef, 210},
{IT_STRING|IT_CVAR, NULL, "Show Director Prompt", &cv_showdirectorhud, 200},
{IT_SUBMENU|IT_STRING, NULL, "Hud Offsets...", &OP_HudOffsetDef, 220},
{IT_STRING|IT_SUBMENU, NULL, "Nametags...", &OP_NametagDef, 210},
{IT_STRING|IT_SUBMENU, NULL, "Driftgauge...", &OP_DriftGaugeDef, 215},
{IT_SUBMENU|IT_STRING, NULL, "Hud Offsets...", &OP_HudOffsetDef, 225},
};
static const char* OP_SaturnHudTooltips[] =
@@ -1888,6 +1971,7 @@ static const char* OP_SaturnHudTooltips[] =
"Use extra graphics for multiple sneakers, bananas and jawz.",
"Change when the item amount is to be displayed.\nMultiple will always display the number.\nWhen you have multiple of the same Item.\nAlways will always display the number regardless of Item amount.",
"Enables an animation while the roulette is active.",
"Changes the way items are colorized in roulette.",
"Show the big 'LAP' text on a lap change.",
"Show the big Cecho Messages.",
"Show player names on the minimap.",
@@ -2497,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",
@@ -2588,7 +2677,7 @@ menu_t OP_Player2CamOptionsDef = DEFAULTMENUSTYLE(NULL, OP_Player2CamOptionsMenu
menu_t OP_Player3CamOptionsDef = DEFAULTMENUSTYLE(NULL, OP_Player3CamOptionsMenu, &OP_CamOptionsDef, 30, 30, OP_PlayerCamOptionsTooltips);
menu_t OP_Player4CamOptionsDef = DEFAULTMENUSTYLE(NULL, OP_Player4CamOptionsMenu, &OP_CamOptionsDef, 30, 30, OP_PlayerCamOptionsTooltips);
menu_t OP_ChatOptionsDef = DEFAULTMENUSTYLE("M_HUD", OP_ChatOptionsMenu, &OP_HUDOptionsDef, 30, 30, OP_ChatOptionsTooltips);
menu_t OP_ChatOptionsDef = DEFAULTSCROLLSTYLE("M_HUD", OP_ChatOptionsMenu, &OP_HUDOptionsDef, 30, 25, OP_ChatOptionsTooltips);
menu_t OP_SoundAdvancedDef = DEFAULTSCROLLSTYLE("M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30, OP_SoundAdvancedTooltips);
@@ -2713,6 +2802,15 @@ void PDistort_menu_Onchange(void)
OP_PlayerDistortMenu[slrotatedist].status = IT_GRAYEDOUT;
OP_PlayerDistortMenu[saltroll].status = IT_GRAYEDOUT;
}
if (cv_stairjank.value)
{
OP_PlayerDistortMenu[stairjanksfx].status = IT_STRING | IT_CVAR;
}
else
{
OP_PlayerDistortMenu[stairjanksfx].status = IT_GRAYEDOUT;
}
}
void Bird_menu_Onchange(void)
+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;
}
+42 -56
View File
@@ -47,6 +47,7 @@ struct perfstatrow {
static ps_metric_t ps_frametime = {0};
ps_metric_t ps_tictime = {0};
ps_metric_t ps_prevtictime = {0};
ps_metric_t ps_playerthink_time = {0};
ps_metric_t ps_thinkertime = {0};
@@ -168,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},
{}
};
@@ -605,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)
@@ -624,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())
{
@@ -691,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);
@@ -719,6 +690,7 @@ void PS_UpdateTickStats(void)
break;
}
}
if (cv_perfstats.value)
{
ps_tick_index++;
@@ -749,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;
@@ -865,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));
@@ -887,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));
@@ -975,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);
@@ -1008,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;
@@ -1036,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:
+11
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;
@@ -36,6 +46,7 @@ typedef struct
#define PS_STOP_TIMING(metric) metric.value.p = I_GetPreciseTime() - metric.value.p
extern ps_metric_t ps_tictime;
extern ps_metric_t ps_prevtictime;
extern ps_metric_t ps_playerthink_time;
extern ps_metric_t ps_thinkertime;
+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);
}
+1 -1
View File
@@ -44,7 +44,7 @@ boolean M_TextInputHandle(textinput_t *input, INT32 key);
// If currently typing something that looks like an existing emote, return suggestions for it
boolean M_TextInputHandleEmotes(textinput_t *input, INT32 key, emote_autocomplete_t *autocomplete);
#define M_DrawTextInput(x, y, input, flags) M_DrawTextInputScroll((x), (y), (input), (flags), ((input)->buffer_size-1)*8)
#define M_DrawTextInput(x, y, input, flags) M_DrawTextInputScroll((x), (y), (input), (flags), ((input)->buffer_size-2)*8)
void M_DrawTextInputScroll(INT32 x, INT32 y, textinput_t *input, INT32 flags, INT32 MAXINPUTWIDTH);
#endif
+722 -346
View File
File diff suppressed because it is too large. Load diff
+14 -9
View File
@@ -845,7 +845,7 @@ void T_BounceCheese(levelspecthink_t *bouncer)
T_MovePlane(bouncer->sector, 0, bouncer->sector->ceilingheight, 0, 1, -1); // update things on ceiling
T_MovePlane(bouncer->sector, 0, bouncer->sector->floorheight, 0, 0, -1); // update things on floor
bouncer->sector->ceilingdata = NULL;
bouncer->sector->floordata = NULL;;
bouncer->sector->floordata = NULL;
bouncer->sector->moved = true;
P_RemoveThinker(&bouncer->thinker); // remove bouncer from actives
}
@@ -1107,14 +1107,13 @@ void T_SpikeSector(levelspecthink_t *spikes)
if (affectsec == spikes->sector) // Applied to an actual sector
{
fixed_t affectfloor = P_GetSpecialBottomZ(thing, affectsec, affectsec);
fixed_t affectceil = P_GetSpecialTopZ(thing, affectsec, affectsec);
if (affectsec->flags & SF_FLIPSPECIAL_FLOOR)
{
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0)
continue;
fixed_t affectfloor = P_GetSpecialBottomZ(thing, affectsec, affectsec);
if (thing->z == affectfloor)
dothepain = true;
}
@@ -1124,19 +1123,21 @@ void T_SpikeSector(levelspecthink_t *spikes)
if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0)
continue;
fixed_t affectceil = P_GetSpecialTopZ(thing, affectsec, affectsec);
if (thing->z + thing->height == affectceil)
dothepain = true;
}
}
else
{
fixed_t affectfloor = P_GetSpecialBottomZ(thing, affectsec, spikes->sector);
fixed_t affectceil = P_GetSpecialTopZ(thing, affectsec, spikes->sector);
if (affectsec->flags & SF_FLIPSPECIAL_FLOOR)
{
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0)
continue;
fixed_t affectceil = P_GetSpecialTopZ(thing, affectsec, spikes->sector);
if (thing->z == affectceil)
dothepain = true;
}
@@ -1146,6 +1147,8 @@ void T_SpikeSector(levelspecthink_t *spikes)
if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0)
continue;
fixed_t affectfloor = P_GetSpecialBottomZ(thing, affectsec, spikes->sector);
if (thing->z + thing->height == affectfloor)
dothepain = true;
}
@@ -1652,6 +1655,7 @@ wegotit:
static mobj_t *SearchMarioNode(msecnode_t *node)
{
mobj_t *thing = NULL;
for (; node; node = node->m_thinglist_next)
{
// Things which should NEVER be ejected from a MarioBlock, by type.
@@ -2079,11 +2083,12 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
continue;
topheight = P_GetSpecialTopZ(players[j].mo, sec, targetsec);
bottomheight = P_GetSpecialBottomZ(players[j].mo, sec, targetsec);
if (players[j].mo->z > topheight)
continue;
bottomheight = P_GetSpecialBottomZ(players[j].mo, sec, targetsec);
if (players[j].mo->z + players[j].mo->height < bottomheight)
continue;
@@ -2333,7 +2338,7 @@ void T_RaiseSector(levelspecthink_t *raise)
fixed_t origspeed = raise->vars[3];
// Slow down as you get closer to the bottom
raise->vars[3] = FixedMul(raise->vars[3],FixedDiv(raise->sector->ceilingheight - raise->vars[7], (raise->vars[5] - raise->vars[7])>>5));
raise->vars[3] = FixedMul(raise->vars[3], FixedDiv(raise->sector->ceilingheight - raise->vars[7], (raise->vars[5] - raise->vars[7])>>5));
if (raise->vars[3] <= origspeed/16)
raise->vars[3] = origspeed/16;
@@ -2344,7 +2349,7 @@ void T_RaiseSector(levelspecthink_t *raise)
{
fixed_t origspeed = raise->vars[3];
// Slow down as you get closer to the top
raise->vars[3] = FixedMul(raise->vars[3],FixedDiv(raise->vars[5] - raise->sector->ceilingheight, (raise->vars[5] - raise->vars[7])>>5));
raise->vars[3] = FixedMul(raise->vars[3], FixedDiv(raise->vars[5] - raise->sector->ceilingheight, (raise->vars[5] - raise->vars[7])>>5));
if (raise->vars[3] <= origspeed/16)
raise->vars[3] = origspeed/16;
Loaded 100 of 160 files, more files were not shown because too many files have changed in this diff. Show more