Compare commits

..
132 Commits
Author SHA1 Message Date
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 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 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
97 changed files with 4084 additions and 2590 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")
+4 -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
)
@@ -275,6 +275,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 +291,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 +520,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
+1
View File
@@ -99,3 +99,4 @@ lua_skinlib.c
lua_thinkerlib.c
lua_udatalib.c
lua_glib.c
lua_profile.cpp
+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);
}
+2 -2
View File
@@ -55,8 +55,8 @@ struct lua_longjmp {
void luaD_seterrorobj (lua_State *L, int lerrcode, StkId oldtop) {
switch (lerrcode) {
case LUA_ERRMEM: { /* memory error? */
setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
case LUA_ERRMEM: {
setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG));
break;
}
case LUA_ERRERR: {
-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
+2
View File
@@ -13,6 +13,8 @@
#include "llimits.h"
#include "lua.h"
#define MEMERRMSG "not enough memory"
#define luaM_reallocv(L,b,on,n,e) \
((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \
+2 -1
View File
@@ -73,9 +73,10 @@ 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);
luaS_fix(luaS_newliteral(L, MEMERRMSG));
g->GCthreshold = 4*g->totalbytes;
}
-2
View File
@@ -88,11 +88,9 @@ typedef struct global_State {
lua_CFunction panic; /* to be called in unprotected errors */
TValue l_registry;
struct lua_State *mainthread;
TString *memerrmsg; /* memory-error message */
UpVal uvhead; /* head of double-linked list of all open upvalues */
struct Table *mt[NUM_TAGS]; /* metatables for basic types */
TString *tmname[TM_N]; /* array with tag-method names */
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
+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);
+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();
}
+32 -11
View File
@@ -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;
}
@@ -1133,6 +1137,7 @@ static void CV_SavePlayerNames(UINT8 **p)
WRITEUINT8(*p, 0);
continue;
}
WRITESTRING(*p, player_names[i]);
}
}
@@ -1146,10 +1151,13 @@ 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);
}
}
@@ -1447,6 +1455,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
@@ -2026,6 +2035,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);
@@ -2178,7 +2188,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
@@ -2856,10 +2867,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
{
INT32 key;
if (I_Interrupted())
{
I_Quit();
}
I_HandleInterrupt();
I_OsPolling();
@@ -3498,6 +3506,9 @@ 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);
@@ -4447,6 +4458,7 @@ void SV_ResetServer(void)
pingmeasurecount = 1;
memset(realpingtable, 0, sizeof(realpingtable));
memset(playerpingtable, 0, sizeof(playerpingtable));
localplayerping = 0;
ClearAdminPlayers();
@@ -4795,7 +4807,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)
@@ -5396,7 +5408,7 @@ 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;
for (j = 0; j < MAXPLAYERS; j++)
adminplayers[j] = netbuffer->u.servercfg.adminplayers[j];
@@ -6836,7 +6848,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 +6998,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 +7062,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
+2
View File
@@ -650,6 +650,8 @@ extern UINT8 playernode[MAXPLAYERS];
extern boolean player_muted[MAXPLAYERS];
extern UINT32 localplayerping;
INT32 D_NumPlayers(void);
void D_ResetTiccmds(void);
+25 -16
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] = ".";
@@ -658,6 +659,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 +732,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 +1165,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;
}
@@ -1356,20 +1359,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 +1839,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 +1938,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
+31 -5
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
@@ -150,6 +151,7 @@ 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);
@@ -505,6 +507,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};
@@ -645,6 +650,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);
@@ -928,11 +934,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 +946,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);
@@ -1027,6 +1036,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);
@@ -1548,8 +1558,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];
@@ -4591,6 +4601,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
// =========================================================================
@@ -5471,7 +5498,6 @@ static void Name_OnChange(void)
}
SendNameAndColor(0);
}
static void Name2_OnChange(void)
+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;
+33 -19
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,15 +284,17 @@ 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;
@@ -299,6 +305,7 @@ boolean CL_CheckDownloadable(void)
}
CONS_Printf("\n");
}
}
switch (dlstatus)
{
@@ -312,6 +319,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 +557,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 +565,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 +657,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 +700,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 +725,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 +1080,7 @@ void Got_Filetxpak(void)
{
const char *s;
switch(file->status)
switch (file->status)
{
case FS_NOTFOUND:
s = "FS_NOTFOUND";
@@ -1194,7 +1208,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;
+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
+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)
+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.
//
+14
View File
@@ -602,6 +602,13 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
// None of these that are disabled in the normal build are guaranteed to work perfectly
// Compile them at your own risk!
// undefine to enable fixes and features that are not vanilla compatible
#define COMPAT_VANILLA
// if we build with 32 player (or more!) support we dont need to care vanilla compat
#if MAXPLAYERS > 16
#undef COMPAT_VANILLA
#endif
//-- SATURN __
/// Detect if a client is on Saturn in the clientconfig.
/// To seperately allow them to join or block joining from vanilla clients.
@@ -666,6 +673,13 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
#undef UPDATE_ALERT
#endif
// overwrite some of those
// when not compiling in vanilla compat mode
#ifndef COMPAT_VANILLA
#define SATURNJOIN
#define SATURNPAK
#endif
#ifdef __cplusplus
} // extern "C"
#endif
+1 -4
View File
@@ -361,10 +361,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++);
+68 -63
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;
}
@@ -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;
@@ -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;
@@ -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
@@ -2339,7 +2344,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
extrainfo_p += 16;
// Skin
memcpy(temp,extrainfo_p,16);
memcpy(temp, extrainfo_p, 16);
extrainfo_p += 16;
pdemo->standings[count].skin = UINT8_MAX;
@@ -2353,12 +2358,12 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
}
// Color
memcpy(temp,extrainfo_p,16);
memcpy(temp, extrainfo_p, 16);
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;
@@ -2827,15 +2832,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
@@ -2868,7 +2873,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;
@@ -2888,9 +2893,9 @@ void G_DoPlayDemo(char *defdemoname)
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"));
@@ -2994,16 +2999,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 +3226,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 +3386,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 +3478,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
}
+19 -13
View File
@@ -66,8 +66,6 @@ boolean botingame = false;
UINT8 botskin = 0;
UINT8 botcolor = 0;
JoyType_t Joystick[MAXSPLITSCREENPLAYERS] = {};
// SRB2kart
char gamedatafilename[64] = "kartdata.dat";
char timeattackfolder[64] = "kart";
@@ -755,7 +753,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 +801,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 +857,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 +894,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 +991,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 +1023,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 +1310,7 @@ static void G_DoLoadLevel(boolean resetplayer)
{
// fail so reset game stuff
Command_ExitGame_f();
P_FreeCorruptMapWarnings();
return;
}
@@ -1344,6 +1344,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;
@@ -4089,6 +4091,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 +4102,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);
@@ -4112,8 +4116,10 @@ char *G_BuildMapTitle(INT32 mapnum)
sprintf(title, "%s", mapheaderinfo[mapnum-1]->lvlttl);
if (zonetext) sprintf(title + strlen(title), " %s", zonetext);
if (actnum) sprintf(title + strlen(title), " %s", actnum);
if (zonetext)
sprintf(title + strlen(title), " %s", zonetext);
if (actnum)
sprintf(title + strlen(title), " %s", actnum);
}
return title;
+2 -1
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;
+6
View File
@@ -1139,6 +1139,12 @@ void G_DeviceRumbleTick(void)
if (leveltime & 1) // this is actually funny lel
high = RUMBLE_MODERATE;
}
/*else if ((player->stairjank > 8) // this is kinda cool but prob gets annoying after a while
&& player->speed != 0
&& P_IsObjectOnGround(player->mo))
{
low = high = RUMBLE_WEAK;
}*/
if (player->kartstuff[k_brakedrift])
{
+1 -1
View File
@@ -373,7 +373,7 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly)
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)
{
+10 -5
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)
{
@@ -570,7 +570,8 @@ void HWR_ClearAllTextures(void)
/*static void HWR_FreeColormapCache(void)
{
HWR_FreePatchCache(false);
}*/
}
*/
void HWR_InitMapTextures(void)
{
@@ -622,10 +623,12 @@ static void HWR_PrecacheLevelFlats(void)
{
// lookup for flats that may´ve been already loaded
flatcheck flatpresent;
flatcheck_init(&flatpresent);
size_t i, j;
INT32 k;
flatcheck_init(&flatpresent);
flatcheck_reserve(&flatpresent, numlevelflats);
// special case for encore
#ifdef GLENCORE
if (encoremap)
@@ -726,7 +729,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,7 +992,6 @@ static void HWR_CacheFlat(GLMipmap_t *glMipmap, lumpnum_t flatlumpnum)
flat[steppy] = glMipmap->colormap->source[flat[steppy]];
}
#endif
if (haschromakey)
{
@@ -1001,6 +1003,7 @@ static void HWR_CacheFlat(GLMipmap_t *glMipmap, lumpnum_t flatlumpnum)
glMipmap->flags &= ~TF_CHROMAKEYED;
}
}
#endif
}
// Download a Doom 'flat' to the hardware cache and make it ready for use
@@ -1127,7 +1130,9 @@ void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap)
HWR_UpdatePatchMipmap(patch, glMipmap);
}
else
{
HWR_LoadPatchMipmap(patch, glMipmap);
}
return;
}
+334 -397
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);
+3 -4
View File
@@ -1400,12 +1400,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;
+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" \
+4 -3
View File
@@ -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;
}
@@ -1583,6 +1583,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 +1698,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))
{
@@ -2914,7 +2915,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)
{
+156 -45
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)
@@ -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;
@@ -963,7 +971,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 +1030,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 +1099,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 +1140,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 +1287,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 +1375,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 +1407,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 +1467,7 @@ static void HU_drawMiniChat(void)
if (splitscreen)
{
y -= BASEVIDHEIGHT/2;
if (splitscreen > 1)
y += 16;
}
@@ -1447,7 +1485,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 +1518,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 +1528,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 +1591,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 +1627,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 +1635,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 +1672,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 +1692,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 +1724,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 +1732,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 +1750,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 +1767,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 +1792,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 +1810,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 +1852,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 +1890,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 +1952,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 +1974,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 +2020,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 +2043,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 +2053,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)
@@ -2213,7 +2291,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 +2314,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 +2395,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 +2409,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 +2432,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 +2452,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 +2569,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
//
+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"
+5
View File
@@ -203,6 +203,11 @@ 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 The I_GetDiskFreeSpace function
+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 COMPAT_VANILLA
#define NUMMOBJFREESLOTS 1024
#else
#define NUMMOBJFREESLOTS 4096 // should be sufficient
#endif
#define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS
#define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8)
+49 -51
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);
@@ -1136,7 +1146,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 +1517,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;
@@ -4254,6 +4267,7 @@ static void K_drawInput(void)
y -= FRACUNIT;
// stick displays
if (cv_showinput.value == 2 || cv_showinput.value == 3)
{
INT32 axis;
@@ -4263,7 +4277,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 +4295,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 +4341,7 @@ static void K_drawInput(void)
}
}
}
else
else // wheel
{
if (!cmd->driftturn) // no turn
target = 0;
@@ -4403,6 +4397,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 +4443,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));
@@ -4830,7 +4828,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];
+801 -654
View File
File diff suppressed because it is too large. Load diff
+55 -7
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)
{
@@ -547,11 +593,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
+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*/
+8 -1
View File
@@ -713,9 +713,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 +728,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));
+102 -52
View File
@@ -151,8 +151,6 @@ const char *quitmsg[NUM_QUITMESSAGES] = {};
INT32 mapwads[NUMMAPS] = {};
boolean browselocalskins = false;
boolean menuactive = false;
boolean fromlevelselect = false;
@@ -214,12 +212,19 @@ static INT32 setupm_fakeskin;
static INT32 setupm_fakecolor;
static UINT8 setupm_pselect = 1;
//variables used for other skin select menus
// variables used for other skin select menus
static UINT8 setupm_skinypos;
static INT32 setupm_skinselect;
static boolean setupm_skinlockedselect;
static UINT8 setupm_playernum; //brap
static UINT8 setupm_playernum; // brap
// Addons Menu: Local mode
static void M_LocalAddons(INT32 choice);
static boolean addons_localmode = false;
#define LOCALMODE_KEY (KEY_RALT)
#define AUTOLOAD_KEY (KEY_END)
//
// PROTOTYPES
@@ -325,7 +330,6 @@ static void M_EraseData(INT32 choice);
static void M_AddonsInternal();
static void M_Addons(INT32 choice);
static void M_LocalSkins(INT32 choice);
static void M_AddonsOptions(INT32 choice);
#define addonmenusize 9 // number of items actually displayed in the addons menu view, formerly (2*numaddonsshown + 1)
#define numaddonsshown 4 // number of items to each side of the currently selected item, unless at top/bottom ends of directory
@@ -409,6 +413,7 @@ static INT32 M_GetFirstLevelInList(void);
// crap to force hud to show when in saturns hud options
boolean forceshowhud = false;
boolean forceshowchat = false;
// smol text indicating if game is modified
// so ppl dont wonder where their ra times went and stuff
@@ -447,13 +452,13 @@ consvar_t cv_showallmaps = {"showallmaps", "No", CV_SAVE, CV_YesNo, NULL, 0, NUL
consvar_t cv_showmusicfilename = {"showmusicfilename", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t serversort_cons_t[] = {
{0,"Ping"},
{1,"Modified State"},
{2,"Most Players"},
{3,"Least Players"},
{4,"Max Player Slots"},
{5,"Gametype"},
{0,NULL}
{0, "Ping"},
{1, "Modified State"},
{2, "Most Players"},
{3, "Least Players"},
{4, "Max Player Slots"},
{5, "Gametype"},
{0, NULL}
};
consvar_t cv_serversort = {"serversort", "Ping", CV_CALL, serversort_cons_t, M_SortServerList, 0, NULL, NULL, 0, 0, NULL};
@@ -702,7 +707,7 @@ static void Dummystaff_OnChange(void)
dummystaffname[0] = '\0';
if ((l = W_CheckNumForName(va("%sS01",G_BuildMapName(cv_nextmap.value)))) == LUMPERROR)
if ((l = W_CheckNumForName(va("%sS01", G_BuildMapName(cv_nextmap.value)))) == LUMPERROR)
{
CV_StealthSetValue(&cv_dummystaff, 0);
return;
@@ -711,7 +716,7 @@ static void Dummystaff_OnChange(void)
{
char *temp = dummystaffname;
UINT8 numstaff = 1;
while (numstaff < 99 && (l = W_CheckNumForName(va("%sS%02u",G_BuildMapName(cv_nextmap.value),numstaff+1))) != LUMPERROR)
while (numstaff < 99 && (l = W_CheckNumForName(va("%sS%02u", G_BuildMapName(cv_nextmap.value), numstaff+1))) != LUMPERROR)
numstaff++;
if (cv_dummystaff.value < 1)
@@ -719,7 +724,7 @@ static void Dummystaff_OnChange(void)
else if (cv_dummystaff.value > numstaff)
CV_StealthSetValue(&cv_dummystaff, 1);
if ((l = W_CheckNumForName(va("%sS%02u",G_BuildMapName(cv_nextmap.value), cv_dummystaff.value))) == LUMPERROR)
if ((l = W_CheckNumForName(va("%sS%02u", G_BuildMapName(cv_nextmap.value), cv_dummystaff.value))) == LUMPERROR)
return; // shouldn't happen but might as well check...
G_UpdateStaffGhostName(l);
@@ -804,7 +809,8 @@ static void M_ChangeCvar(INT32 choice)
CV_SetValue(cv,skins[skinno].prefcolor);
return;
}
CV_Set(cv,cv->defaultvalue);
CV_Set(cv, cv->defaultvalue);
return;
}
@@ -953,6 +959,7 @@ static void Command_Manual_f(void)
{
if (modeattacking)
return;
M_StartControlPanel();
M_Manual(INT32_MAX);
itemOn = 0;
@@ -1014,6 +1021,24 @@ boolean M_Responder(event_t *ev)
case KEY_HAT1 + 3:
ch = KEY_RIGHTARROW;
break;
//Local Addon Mode
case LOCALMODE_KEY:
{
if (!(server || IsPlayerAdmin(consoleplayer)))
break;
if (!addons_localmode)
{
S_StartSound(NULL, sfx_ding);
addons_localmode = true;
}
else
{
S_StartSound(NULL, sfx_jshard);
addons_localmode = false;
}
}
break;
}
}
else if (menuactive)
@@ -1025,11 +1050,12 @@ boolean M_Responder(event_t *ev)
const INT32 jxdeadzone = ((JOYAXISRANGE-1) * max(cv_xdeadzone[0].value, FRACUNIT/2)) >> FRACBITS;
const INT32 jydeadzone = ((JOYAXISRANGE-1) * max(cv_ydeadzone[0].value, FRACUNIT/2)) >> FRACBITS;
INT32 accelaxis = abs(cv_moveaxis[0].value);
if (ev->data1 == 0)
{
if (ev->data3 != INT32_MAX)
{
if (Joystick[0].bGamepadStyle || abs(ev->data3) > jydeadzone)
if (DigitalGamepadStyle(0) || abs(ev->data3) > jydeadzone)
{
if (joywaity < thistime
&& (pjoyy == 0 || (ev->data3 < 0) != (pjoyy < 0))) // no previous direction OR change direction
@@ -1045,7 +1071,7 @@ boolean M_Responder(event_t *ev)
if (ev->data2 != INT32_MAX && joywaitx < thistime)
{
if (Joystick[0].bGamepadStyle || abs(ev->data2) > jxdeadzone)
if (DigitalGamepadStyle(0) || abs(ev->data2) > jxdeadzone)
{
if (joywaitx < thistime
&& (pjoyx == 0 || (ev->data2 < 0) != (pjoyx < 0))) // no previous direction OR change direction
@@ -1064,19 +1090,22 @@ boolean M_Responder(event_t *ev)
// The following borrows heavily from Joy1Axis.
const boolean xmode = (accelaxis%2);
INT32 retaxis = 0;
if (!xmode)
accelaxis--;
accelaxis /= 2;
if (ev->data1 == accelaxis)
{
const INT32 jacceldeadzone = xmode ? jxdeadzone : jydeadzone;
retaxis = xmode ? ev->data2 : ev->data3;
if (retaxis != INT32_MAX)
{
if (cv_moveaxis[0].value < 0)
retaxis = -retaxis;
if (Joystick[0].bGamepadStyle || retaxis > jacceldeadzone)
if (DigitalGamepadStyle(0) || retaxis > jacceldeadzone)
{
if (joywaitaccel < thistime && retaxis > pjoyaccel) // only on upwards event
{
@@ -1575,11 +1604,16 @@ static boolean ShouldDrawMenuBG(void)
if (forceshowhud)
return false;
if (forceshowchat)
return false;
// camera options stuff, only do when in level
if (gamestate == GS_LEVEL &&
(currentMenu == &OP_CamOptionsDef || currentMenu == &OP_Player1CamOptionsDef
|| currentMenu == &OP_Player2CamOptionsDef || currentMenu == &OP_Player3CamOptionsDef
|| currentMenu == &OP_Player4CamOptionsDef))
(currentMenu == &OP_CamOptionsDef ||
currentMenu == &OP_Player1CamOptionsDef ||
currentMenu == &OP_Player2CamOptionsDef ||
currentMenu == &OP_Player3CamOptionsDef ||
currentMenu == &OP_Player4CamOptionsDef))
return false;
return true;
@@ -1595,7 +1629,9 @@ void M_Drawer(void)
if (currentMenu == &MessageDef)
menuactive = true;
// pain and suffering
forceshowhud = (gamestate == GS_LEVEL && menuactive && (currentMenu == &OP_SaturnHudDef || currentMenu == &OP_HudOffsetDef || currentMenu == &OP_NametagDef || currentMenu == &OP_DriftGaugeDef)); // holy fuick
forceshowchat = (gamestate == GS_LEVEL && menuactive && currentMenu == &OP_ChatOptionsDef && (!OLDCHAT) && (itemOn == op_chat_boxwidth || itemOn == op_chat_boxheight || itemOn == op_chat_xoffs || itemOn == op_chat_yoffs || itemOn == op_chat_charlmt)); // man i dont gaf anymore lmao
if (menuactive)
{
@@ -1714,19 +1750,16 @@ void M_StartControlPanel(void)
MPauseMenu[mpause_switchteam].status = IT_DISABLED;
MPauseMenu[mpause_switchspectate].status = IT_DISABLED;
MPauseMenu[mpause_psetup].status = IT_DISABLED;
MPauseMenu[mpause_localaddons].status = IT_STRING | IT_CALL;
MISC_ChangeTeamMenu[0].status = IT_DISABLED;
MISC_ChangeSpectateMenu[0].status = IT_DISABLED;
MPauseMenu[mpause_addlocalskins].status = IT_STRING | IT_CALL;
MPauseMenu[mpause_localskin].status = IT_STRING | IT_CALL;
// Reset these in case splitscreen messes things up
MPauseMenu[mpause_addons].alphaKey = 8;
if (IsPlayerAdmin(consoleplayer))
MPauseMenu[mpause_addlocalskins].alphaKey = 16;
else
MPauseMenu[mpause_addlocalskins].alphaKey = 24;
MPauseMenu[mpause_localaddons].alphaKey = 24;
MPauseMenu[mpause_scramble].alphaKey = 8;
MPauseMenu[mpause_switchmap].alphaKey = 24;
@@ -1744,14 +1777,13 @@ void M_StartControlPanel(void)
{
MPauseMenu[mpause_switchmap].status = IT_STRING | IT_CALL;
MPauseMenu[mpause_addons].status = IT_STRING | IT_CALL;
MPauseMenu[mpause_localaddons].status = IT_DISABLED;
if (G_GametypeHasTeams())
MPauseMenu[mpause_scramble].status = IT_STRING | IT_SUBMENU;
}
if (server || (!cv_showlocalskinmenus.value))
{
MPauseMenu[mpause_addlocalskins].status = IT_DISABLED;
MPauseMenu[mpause_localskin].status = IT_DISABLED;
MPauseMenu[mpause_options].alphaKey = 64;
@@ -1759,7 +1791,6 @@ void M_StartControlPanel(void)
MPauseMenu[mpause_quit].alphaKey = 88;
}
if (splitscreen)
{
MPauseMenu[mpause_psetupsplit].status = MPauseMenu[mpause_psetupsplit2].status = IT_STRING | IT_CALL;
@@ -3304,14 +3335,14 @@ static void M_AddonsInternal(void)
static void M_Addons(INT32 choice)
{
(void)choice;
browselocalskins = false;
addons_localmode = false;
M_AddonsInternal();
}
static void M_LocalSkins(INT32 choice)
static void M_LocalAddons(INT32 choice)
{
(void)choice;
browselocalskins = true;
addons_localmode = true;
M_AddonsInternal();
}
@@ -3480,8 +3511,8 @@ static void M_DrawAddons(void)
if (Playing())
{
if (browselocalskins)
V_DrawCenteredString(BASEVIDWIDTH/2, 5, V_ALLOWLOWERCASE, "Load \x83local skins\x80 from addons!");
if (addons_localmode) // Draw notice that you're adding locally
V_DrawCenteredString(BASEVIDWIDTH/2, 5, V_ALLOWLOWERCASE, "Load addons or \x83local skins\x80 locally!");
else
V_DrawCenteredString(BASEVIDWIDTH/2, 5, warningflags, "Adding files mid-game may cause problems.");
}
@@ -3644,7 +3675,10 @@ static void M_DrawAddons(void)
//m = numwadfiles-(mainwads+2+1);
//V_DrawCenteredString(BASEVIDWIDTH/2, y+24, (majormods ? highlightflags : V_TRANSLUCENT), va("%d ADD-ON%s LOADED", (int)m, (m == 1) ? "" : "S")); //+2 for music, sounds, +1 for main.kart
V_DrawThinString(0, BASEVIDHEIGHT-10, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_TRANSLUCENT|V_ALLOWLOWERCASE, ("END Key - Add addon to autoload"));
V_DrawThinString(0, BASEVIDHEIGHT-10, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s Key - Add addon to autoload", G_KeynumToString(AUTOLOAD_KEY)));
if (Playing() && (server || IsPlayerAdmin(consoleplayer)))
V_DrawThinString(0, BASEVIDHEIGHT-20, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s Key - Switch to local addon mode", G_KeynumToString(LOCALMODE_KEY)));
}
static void M_AddonExec(INT32 ch)
@@ -3666,7 +3700,7 @@ static void M_AddonAutoLoad(INT32 ch)
FILE *autoloadconfigfile;
// check our controls //
if (ch != 'y' && ch != KEY_ENTER && ch != KEY_END)
if (ch != 'y' && ch != KEY_ENTER && ch != AUTOLOAD_KEY)
{
S_StartSound(NULL, sfx_s26d);
return;
@@ -3680,7 +3714,7 @@ static void M_AddonAutoLoad(INT32 ch)
switch (dirmenu[dir_on[menudepthleft]][DIR_TYPE])
{
case EXT_FOLDER:
M_StartMessage(va("%c%s\x80\nAutoloading folders is not supported as of yet. \n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING);
M_StartMessage(va("%c%s\x80\nAutoloading folders is not supported as of yet. \n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING), NULL, MM_NOTHING);
break;
case EXT_TXT:
case EXT_CFG:
@@ -3821,7 +3855,7 @@ static void M_HandleAddons(INT32 choice)
}
break;
case EXT_TXT:
M_StartMessage(va("%c%s\x80\nThis file may not be a console script.\nAttempt to run anyways? \n\n(Press 'Y' to confirm)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),M_AddonExec,MM_YESNO);
M_StartMessage(va("%c%s\x80\nThis file may not be a console script.\nAttempt to run anyways? \n\n(Press 'Y' to confirm)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING), M_AddonExec, MM_YESNO);
break;
case EXT_CFG:
M_AddonExec(KEY_ENTER);
@@ -3834,30 +3868,40 @@ static void M_HandleAddons(INT32 choice)
case EXT_KART:
#endif
case EXT_PK3:
if (browselocalskins)
{
if (DumbStartsWith("KC_", dirmenu[dir_on[menudepthleft]]+DIR_STRING) || DumbStartsWith("kc_", dirmenu[dir_on[menudepthleft]]+DIR_STRING)) {
M_StartMessage(va("%c%s\x80\nYou are loading a local skin.\nLocal skins will not be usable\nafter going back from\nthe title screen.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING);
COM_BufAddText(va("addfilelocal \"%s%s\"", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
const char *addonname = dirmenu[dir_on[menudepthleft]]+DIR_STRING;
if (addons_localmode)
{
if (DumbStartsWith("KC_", addonname) || DumbStartsWith("kc_", addonname))
{
M_StartMessage(va("%c%s\x80\nYou are loading a local skin.\nLocal skins will not be usable\nafter going back from\nthe title screen.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), addonname), NULL, MM_NOTHING);
}
else if (DumbStartsWith("KCL_", addonname) || DumbStartsWith("kcl_", addonname)) // skins with lua
{
M_StartMessage(va("%c%s\x80\nYou are loading a local skin with lua.\nBeware that this may cause issues like crashes or desyncs in some cases!\nLocal skins will not be usable\nafter going back from\nthe title screen.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), addonname), NULL, MM_NOTHING);
}
// no need to account for KRC cases
COM_BufAddText(va("addfilelocal \"%s%s\"", menupath, addonname));
}
else
S_StartSound(NULL, sfx_s26d);
}
else
{
COM_BufAddText(va("addfile \"%s%s\"", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
{
COM_BufAddText(va("addfile \"%s%s\"", menupath, addonname));
}
}
break;
default:
S_StartSound(NULL, sfx_s26d);
}
}
if (refresh)
refreshdirmenu |= REFRESHDIR_NORMAL;
}
break;
case KEY_END:
case AUTOLOAD_KEY:
{
boolean refresh = true;
if (!dirmenu[dir_on[menudepthleft]])
@@ -3924,6 +3968,8 @@ static void M_HandleAddons(INT32 choice)
M_SetupNextMenu(currentMenu->prevMenu);
else
M_ClearMenus(true);
addons_localmode = false; //Exiting this menu, disable addons_localmode already.
}
}
@@ -7604,7 +7650,11 @@ Update the maxplayers label...
// draw name string
if (itemOn != 9)
V_DrawString(x+8,y+12, V_ALLOWLOWERCASE, setupm_ip);
{
char buf[28];
strlcpy(buf, setupm_ip, sizeof(buf));
V_DrawString(x+8,y+12, V_ALLOWLOWERCASE, buf);
}
else
M_DrawTextInputScroll(x+8, y+12, &setupm_input_ip, 0, SETUPM_IP_MAXSIZE);
@@ -7736,7 +7786,7 @@ static void M_SetupMultiHandler(INT32 choice)
if (exitmenu)
{
if (currentMenu->prevMenu)
M_SetupNextMenu (currentMenu->prevMenu);
M_SetupNextMenu(currentMenu->prevMenu);
else
M_ClearMenus(true);
}
+1 -1
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
+158 -116
View File
@@ -208,7 +208,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 +238,7 @@ static menuitem_t MPauseMenu[] =
typedef enum
{
mpause_addons = 0,
mpause_addlocalskins,
mpause_localaddons,
mpause_scramble,
mpause_switchmap,
#ifdef HAVE_DISCORDRPC
@@ -446,25 +446,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 +555,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 +725,29 @@ 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},
#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},
static menuitem_t OP_Joystick1Menu[] =
{
@@ -789,10 +789,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 +860,6 @@ static const char* OP_VideoTooltips[] =
"Advanced graphical options.",
};
enum
{
op_video_res = 0,
@@ -945,24 +943,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 +974,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 +996,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 +1010,6 @@ enum
#endif
};
#ifdef HWRENDER
static menuitem_t OP_OpenGLOptionsMenu[] =
{
@@ -1018,17 +1018,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 +1066,6 @@ enum
op_gl_shearing,
op_gl_renderdist,
};
#endif
static menuitem_t OP_SoundOptionsMenu[] =
@@ -1077,8 +1076,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 +1111,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 +1171,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 +1405,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 +1654,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},
@@ -1767,20 +1790,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 +1815,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 +1827,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 +1836,8 @@ enum
sloperotate,
slrotatedist,
sliptide,
stairjank,
stairjanksfx,
sparkrotate,
bananrotat,
stretchyplayer,
@@ -1848,26 +1878,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 +1920,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.",
@@ -2588,7 +2621,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 +2746,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)
+1
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};
+1
View File
@@ -36,6 +36,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;
+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
+8 -4
View File
@@ -328,7 +328,7 @@ void P_NewChaseDir(mobj_t *actor)
else
d[1] = DI_NODIR;
if (twodlevel || actor->flags2 & MF2_TWOD)
if (UNLIKELY(twodlevel || actor->flags2 & MF2_TWOD))
d[2] = DI_NODIR;
if (deltay < -FixedMul(10*FRACUNIT, actor->scale))
d[2] = DI_SOUTH;
@@ -872,7 +872,7 @@ void A_PointyThink(void *thing)
TVector v;
TVector *res;
angle_t fa;
fixed_t radius = FixedMul(actor->info->radius*actor->info->reactiontime, actor->scale);
fixed_t radius;
boolean firsttime = true;
INT32 sign;
@@ -930,6 +930,8 @@ void A_PointyThink(void *thing)
if (!actor->tracer) // For some reason we do not have spike balls...
return;
radius = FixedMul(actor->info->radius*actor->info->reactiontime, actor->scale);
// Position spike balls relative to the value of 'lastlook'.
ball = actor->tracer;
@@ -2759,9 +2761,11 @@ void A_Invincibility(void *thing)
if (P_IsLocalPlayer(player) && !player->powers[pw_super])
{
S_StopMusic();
if (mariomode)
if (UNLIKELY(mariomode))
G_GhostAddColor((INT32) (player - players), GHC_INVINCIBLE);
S_ChangeMusicInternal((mariomode) ? "minvnc" : "invinc", false);
S_ChangeMusicInternal((UNLIKELY(mariomode)) ? "minvnc" : "invinc", false);
}
}
+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;
+107 -73
View File
@@ -1462,49 +1462,15 @@ boolean P_CheckRacers(void)
return false;
}
/** Kills an object.
*
* \param target The victim.
* \param inflictor The attack weapon. May be NULL (environmental damage).
* \param source The attacker. May be NULL.
* \todo Cleanup, refactor, split up.
* \sa P_DamageMobj
*/
void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
static void P_UpdateRemovedOrbital(mobj_t *target, mobj_t *inflictor, mobj_t *source)
{
mobjtype_t item;
mobj_t *mo;
int ms;
if (target->flags & (MF_ENEMY|MF_BOSS))
target->momx = target->momy = target->momz = 0;
// SRB2kart
if (target->type != MT_PLAYER && !(target->flags & MF_MONITOR)
&& !(target->type == MT_ORBINAUT || target->type == MT_ORBINAUT_SHIELD
|| target->type == MT_JAWZ || target->type == MT_JAWZ_DUD || target->type == MT_JAWZ_SHIELD
|| target->type == MT_BANANA || target->type == MT_BANANA_SHIELD
|| target->type == MT_EGGMANITEM || target->type == MT_EGGMANITEM_SHIELD
|| target->type == MT_BALLHOG || target->type == MT_SPB)) // kart dead items
target->flags |= MF_NOGRAVITY; // Don't drop Tails 03-08-2000
else
target->flags &= ~MF_NOGRAVITY; // lose it if you for whatever reason have it, I'm looking at you shields
//
if (target->flags2 & MF2_NIGHTSPULL)
P_SetTarget(&target->tracer, NULL);
// dead target is no more shootable
target->flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SPECIAL);
target->flags2 &= ~(MF2_SKULLFLY|MF2_NIGHTSPULL);
target->health = 0; // This makes it easy to check if something's dead elsewhere.
if (LUA_HookMobjDeath(target, inflictor, source) || P_MobjWasRemoved(target))
return;
// SRB2kart
// I wish I knew a better way to do this
#ifndef COMPAT_VANILLA
if (!P_MobjWasRemoved(target->target) && target->target->player && !P_MobjWasRemoved(target->target->player->mo))
#else
if (target->target && target->target->player && target->target->player->mo)
#endif
{
if (target->target->player->kartstuff[k_eggmanheld] && target->type == MT_EGGMANITEM_SHIELD)
target->target->player->kartstuff[k_eggmanheld] = 0;
@@ -1517,7 +1483,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
{
if (target->movedir != 0 && target->movedir < (UINT16)target->target->player->kartstuff[k_itemamount])
{
#ifndef COMPAT_VANILLA
if (!P_MobjWasRemoved(target->target->hnext))
#else
if (target->target->hnext)
#endif
K_KillBananaChain(target->target->hnext, inflictor, source);
target->target->player->kartstuff[k_itemamount] = 0;
@@ -1546,14 +1516,60 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
P_SetTarget(&target->target->hnext, NULL);
}
}
// Above block does not clean up rocket sneakers when a player dies, so we need to do it here target->target is null when using rocket sneakers
}
/** Kills an object.
*
* \param target The victim.
* \param inflictor The attack weapon. May be NULL (environmental damage).
* \param source The attacker. May be NULL.
* \todo Cleanup, refactor, split up.
* \sa P_DamageMobj
*/
void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
{
mobjtype_t item;
mobj_t *mo;
int ms;
if (target->flags & (MF_ENEMY|MF_BOSS))
target->momx = target->momy = target->momz = 0;
// SRB2kart
if (target->type != MT_PLAYER
&& !(target->flags & MF_MONITOR)
&& !(target->type == MT_ORBINAUT || target->type == MT_ORBINAUT_SHIELD
|| target->type == MT_JAWZ || target->type == MT_JAWZ_DUD || target->type == MT_JAWZ_SHIELD
|| target->type == MT_BANANA || target->type == MT_BANANA_SHIELD
|| target->type == MT_EGGMANITEM || target->type == MT_EGGMANITEM_SHIELD
|| target->type == MT_BALLHOG || target->type == MT_SPB)) // kart dead items
target->flags |= MF_NOGRAVITY; // Don't drop Tails 03-08-2000
else
target->flags &= ~MF_NOGRAVITY; // lose it if you for whatever reason have it, I'm looking at you shields
//
if (target->flags2 & MF2_NIGHTSPULL)
P_SetTarget(&target->tracer, NULL);
// dead target is no more shootable
target->flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SPECIAL);
target->flags2 &= ~(MF2_SKULLFLY|MF2_NIGHTSPULL);
target->health = 0; // This makes it easy to check if something's dead elsewhere.
if (LUA_HookMobjDeath(target, inflictor, source) || P_MobjWasRemoved(target))
return;
P_UpdateRemovedOrbital(target, inflictor, source);
if (target->player)
{
// Above block does not clean up rocket sneakers when a player dies, so we need to do it here target->target is null when using rocket sneakers
K_DropRocketSneaker(target->player);
// Let EVERYONE know what happened to a player! 01-29-2002 Tails
if (target->player && !target->player->spectator)
{
target->flags2 &= ~MF2_DONTDRAW;
// Let EVERYONE know what happened to a player! 01-29-2002 Tails
if (!target->player->spectator)
target->flags2 &= ~MF2_DONTDRAW;
}
// if killed by a player
@@ -1563,6 +1579,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
{
P_SetTarget(&target->target, source);
source->player->numboxes++;
if (cv_itemrespawn.value && (netgame || multiplayer))
{
target->fuse = cv_itemrespawntime.value*TICRATE + 2; // Random box generation
@@ -1580,35 +1597,41 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
target->player->playerstate = PST_DEAD;
if (cv_fading.value && P_IsLocalPlayer(target->player))
if (P_IsLocalPlayer(target->player))
{
if (netgame || multiplayer)
ms = cv_respawntime.value * 1000;
else
ms = 1000;
if (cv_fading.value)
{
if (netgame || multiplayer)
ms = cv_respawntime.value * 1000;
else
ms = 1000;
/*
If the time spent with the music paused is less than half
a second, continue playing the song (just mute it).
*/
if ((ms - cv_respawnfademusicout.value) < 500)
S_FadeMusic(0, cv_respawnfademusicout.value);
else
S_FadeOutStopMusic(cv_respawnfademusicout.value);
}
/*
* If the time spent with the music paused is less than half
* a second, continue playing the song (just mute it).
*/
if ((ms - cv_respawnfademusicout.value) < 500)
S_FadeMusic(0, cv_respawnfademusicout.value);
else
S_FadeOutStopMusic(cv_respawnfademusicout.value);
}
for (UINT8 i = 0; i <= splitscreen; i++)
{
if (target->player == P_GetLocalPlayerForNum(i))
if (target->player == &players[consoleplayer])
{
// don't die in auto map,
// switch view prior to dying
if (i == 0 && automapactive)
if (automapactive)
AM_Stop();
}
// added : 22-02-98: recenter view for next life...
localaiming[i] = 0;
break;
for (UINT8 i = 0; i <= splitscreen; i++)
{
if (target->player == P_GetLocalPlayerForNum(i))
{
// added : 22-02-98: recenter view for next life...
localaiming[i] = 0;
break;
}
}
}
@@ -1624,7 +1647,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
// Drop stuff.
// This determines the kind of object spawned
// during the death frame of a thing.
if (!mariomode // Don't show birds, etc. in Mario Mode Tails 12-23-2001
if (LIKELY(!mariomode) // Don't show birds, etc. in Mario Mode Tails 12-23-2001
&& target->flags & MF_ENEMY)
{
if (cv_soniccd.value)
@@ -1678,7 +1701,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
else
prandom = P_RandomKey(5); // No placable object, just use a random number.
switch(prandom)
switch (prandom)
{
default: item = MT_BUNNY; break;
case 1: item = MT_BIRD; break;
@@ -2222,16 +2245,26 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return false;
// well no clue but this may happen ig
if (!target || (target->health <= 0))
#ifndef COMPAT_VANILLA
if (P_MobjWasRemoved(target))
#else
if (!target)
#endif
return false;
if (target->health <= 0)
return false;
// Spectator handling
if (netgame)
{
if (damage == DMG_SPECTATOR && target->player && target->player->spectator)
damage = DMG_INSTAKILL;
else if (target->player && target->player->spectator)
return false;
if (target->player && target->player->spectator)
{
if (damage == DMG_SPECTATOR)
damage = DMG_INSTAKILL;
else
return false;
}
if (source && source->player && source->player->spectator)
return false;
@@ -2337,6 +2370,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
{
if (source == target)
return false; // Don't hit yourself with your own paraloop, baka
if (source && source->player && !cv_friendlyfire.value
&& (gametype == GT_COOP
|| (G_GametypeHasTeams() && target->player->ctfteam == source->player->ctfteam)))
@@ -2386,7 +2420,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
else if (player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->powers[pw_flashing])
{
if (!force) // shoulddamage bypasses all of that.
if (!force) // shoulddamage bypasses all of that.
{
K_DoInstashield(player);
return false;
-1
View File
@@ -99,7 +99,6 @@ typedef struct camera_s
// Hold up/down to pan the camera vertically
SINT8 dpad_y_held;
// Camera demobjerization
// Info for drawing: position.
fixed_t x, y, z;
+91 -15
View File
@@ -719,11 +719,11 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->type != MT_PLAYER)
return true;
if (thing->player && thing->player->powers[pw_flashing])
return true;
if (thing->type == MT_PLAYER && thing->player)
if (thing->player)
{
if (thing->player->powers[pw_flashing])
return true;
if (tmthing->state == &states[S_MINEEXPLOSION1])
K_ExplodePlayer(thing->player, tmthing->target, tmthing);
else
@@ -1077,6 +1077,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
thing->momy -= FixedMul(PUSHACCEL, thing->scale);
tmthing->momy += FixedMul(PUSHACCEL, thing->scale);
}
if (tmthing->momx > 0 && tmthing->momx > FixedMul(4*FRACUNIT, thing->scale)
&& tmthing->momx > thing->momx)
{
@@ -1094,6 +1095,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
thing->momx = FixedMul(thing->info->speed, thing->scale);
else if (thing->momx < -FixedMul(thing->info->speed, thing->scale))
thing->momx = -FixedMul(thing->info->speed, thing->scale);
if (thing->momy > FixedMul(thing->info->speed, thing->scale))
thing->momy = FixedMul(thing->info->speed, thing->scale);
else if (thing->momy < -FixedMul(thing->info->speed, thing->scale))
@@ -1105,6 +1107,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
tmthing->momx = FixedMul(4*FRACUNIT, thing->scale);
else if (tmthing->momx < FixedMul(-4*FRACUNIT, thing->scale))
tmthing->momx = FixedMul(-4*FRACUNIT, thing->scale);
if (tmthing->momy > FixedMul(4*FRACUNIT, thing->scale))
tmthing->momy = FixedMul(4*FRACUNIT, thing->scale);
else if (tmthing->momy < FixedMul(-4*FRACUNIT, thing->scale))
@@ -1126,6 +1129,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
P_TouchSpecialThing(thing, tmthing, true); // can remove thing
return true;
}
// check again for special pickup
if (tmthing->flags & MF_SPECIAL && thing->player)
{
@@ -1575,13 +1579,13 @@ static boolean PIT_CheckLine(line_t *ld)
tmbbox[BOXLEFT] >= ld->bbox[BOXRIGHT] ||
tmbbox[BOXTOP] <= ld->bbox[BOXBOTTOM] ||
tmbbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
return true;
return true; // didn't hit it
if (ld->polyobj && !(ld->polyobj->flags & POF_SOLID))
return true;
if (P_BoxOnLineSide(tmbbox, ld) != -1)
return true;
return true; // didn't hit it
if (tmthing->flags & MF_PAPERCOLLISION) // Caution! Turning whilst up against a wall will get you stuck. You probably shouldn't give the player this flag.
{
@@ -2371,8 +2375,10 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
fixed_t tryx = thing->x;
fixed_t tryy = thing->y;
fixed_t radius = thing->radius;
fixed_t thingtop ;//= thing->z + thing->height;
fixed_t thingtop;//= thing->z + thing->height;
fixed_t startingonground = P_IsObjectOnGround(thing);
fixed_t stairjank = 0;
pslope_t *oldslope = thing->standingslope;
INT32 special = -1;
floatok = false;
@@ -2422,7 +2428,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (thing->player)
{
if (special == -1)
if (special == -1) // this should use the target coords not the ones were started with, but cant fix that for compat reasons!
special = GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1);
// If using type Section1:13, double the maxstep.
@@ -2446,11 +2452,19 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
thingtop = thing->z + thing->height;
const boolean flipped =
(thing->eflags & MFE_VERTICALFLIP) != 0;
// Step up
if (thing->z < tmfloorz)
{
if (tmfloorz - thing->z <= maxstep)
{
if (maxstep > 0 && !flipped)
{
stairjank = (tmfloorz - thing->z);
}
thing->z = thing->floorz = tmfloorz;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
@@ -2463,6 +2477,11 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
{
if (thingtop - tmceilingz <= maxstep)
{
if (maxstep > 0 && flipped)
{
stairjank = (thingtop - tmceilingz);
}
thing->z = ( thing->ceilingz = tmceilingz ) - thing->height;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
@@ -2479,11 +2498,21 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (thingtop == thing->ceilingz && tmceilingz > thingtop && tmceilingz - thingtop <= maxstep)
{
if (flipped)
{
stairjank = (tmceilingz - thingtop);
}
thing->z = (thing->ceilingz = tmceilingz) - thing->height;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep)
{
if (!flipped)
{
stairjank = (thing->z - tmfloorz);
}
thing->z = thing->floorz = tmfloorz;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
@@ -2559,6 +2588,52 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
else // don't set standingslope if you're not going to clip against it
thing->standingslope = NULL;
/* FIXME: slope step down (even up) has some false
positives, so just ignore them entirely. */
if (stairjank && !oldslope && !thing->standingslope && thing->player && !thing->player->spectator)
{
/* use a shorter sound if not two tics have passed
* since the last step */
//S_ReducedVFXSound(thing, (thing->player->stairjank >= 16 ? sfx_s23b : sfx_s268), NULL);
//S_StartSound(thing, (thing->player->stairjank >= 16 ? sfx_s23b : sfx_s268));
// sound does not work out all that well for kart maps
// best i can do...
if (cv_stairjanksfx.value)
S_StartSoundAtVolume(thing, (thing->player->stairjank >= 8 ? sfx_s23b : sfx_s268), 192); // dont blast this at full volume lul
//if (!thing->player->stairjank)
{
// 90 degrees to direction you're facing
fixed_t dirx = -FINESINE(thing->angle>>ANGLETOFINESHIFT);
fixed_t diry = FINECOSINE(thing->angle>>ANGLETOFINESHIFT);
fixed_t offset = thing->radius;
if (leveltime % 8 < 4)
{
dirx = -dirx;
diry = -diry;
}
mobj_t * spark = P_SpawnMobj(thing->x + FixedMul(dirx, offset), thing->y + FixedMul(diry, offset), thing->z, MT_DRIFTDUST);
spark->momx = FixedMul(dirx, FRACUNIT) + (6 + ((int)leveltime % 5))*(thing->momx)/10;
spark->momy = FixedMul(diry, FRACUNIT) + (6 + ((int)leveltime % 5))*(thing->momy)/10;
spark->momz = 5*FRACUNIT;
spark->scale = mapobjectscale/5;
spark->destscale = mapobjectscale/2;
spark->islocal = true;
//spark->fuse = 9;
spark->color = SKINCOLOR_WHITE;
//spark->cusval = K_StairJankFlip(ANGLE_90);
P_SetTarget(&spark->target, thing);
//P_SetTarget(&spark->owner, thing);
//spark->renderflags |= RF_REDUCEVFX;
}
thing->player->stairjank = 9;
//thing->player->stairjank = 17;
}
thing->x = x;
thing->y = y;
@@ -3544,6 +3619,12 @@ static boolean PIT_RadiusAttack(mobj_t *thing)
if (thing->flags & MF_MONITOR)
return true;
if (thing->floorz > bombspot->z && bombspot->ceilingz < thing->z)
return true;
if (thing->ceilingz < bombspot->z && bombspot->floorz > thing->z)
return true;
dx = abs(thing->x - bombspot->x);
dy = abs(thing->y - bombspot->y);
dz = abs(thing->z + (thing->height>>1) - bombspot->z);
@@ -3557,14 +3638,9 @@ static boolean PIT_RadiusAttack(mobj_t *thing)
if (dist >= bombdamage)
return true; // out of range
if (thing->floorz > bombspot->z && bombspot->ceilingz < thing->z)
return true;
if (thing->ceilingz < bombspot->z && bombspot->floorz > thing->z)
return true;
// must be in direct path
if (P_CheckSight(thing, bombspot))
{ // must be in direct path
{
P_DamageMobj(thing, bombspot, bombsource, 1); // Tails 01-11-2001
}
+9 -2
View File
@@ -242,7 +242,7 @@ void P_CameraLineOpening(line_t *linedef)
sector_t *back;
fixed_t frontfloor, frontceiling, backfloor, backceiling;
if (linedef->sidenum[1] == 0xffff)
if (linedef->sidenum[1] == NO_INDEX)
{
// single sided line
openrange = 0;
@@ -398,7 +398,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
{
sector_t *front, *back;
if (linedef->sidenum[1] == 0xffff)
if (linedef->sidenum[1] == NO_INDEX)
{
// single sided line
openrange = 0;
@@ -972,6 +972,10 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *))
// First index is really empty, so +1 it.
for (list = blockmaplump + offset + 1; *list != -1; list++)
{
#ifdef RANGECHECK
if (*list < 0 || (UINT32)*list >= numlines)
I_Error("P_BlockLinesIterator: index >= numlines");
#endif
ld = &lines[*list];
if (ld->validcount == validcount)
@@ -1000,11 +1004,13 @@ boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean (*func)(mobj_t *))
for (mobj = blocklinks[y*bmapwidth + x]; mobj; mobj = bnext)
{
P_SetTarget(&bnext, mobj->bnext); // We want to note our reference to bnext here incase it is MF_NOTHINK and gets removed!
if (!func(mobj))
{
P_SetTarget(&bnext, NULL);
return false;
}
if (P_MobjWasRemoved(tmthing) // func just popped our tmthing, cannot continue.
|| (bnext && P_MobjWasRemoved(bnext))) // func just broke blockmap chain, cannot continue.
{
@@ -1012,6 +1018,7 @@ boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean (*func)(mobj_t *))
return true;
}
}
P_SetTarget(&bnext, NULL);
return true;
}
+188 -139
View File
@@ -1249,7 +1249,6 @@ static void P_PushableCheckBustables(mobj_t *mo)
if (rover->master->frontsector->crumblestate)
continue;
topheight = P_GetFOFTopZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);
bottomheight = P_GetFOFBottomZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);
// Height checks
@@ -1261,29 +1260,34 @@ static void P_PushableCheckBustables(mobj_t *mo)
if (mo->z+mo->height > bottomheight)
continue;
}
else if (rover->flags & FF_SPINBUST)
{
if (mo->z+mo->momz > topheight)
continue;
if (mo->z+mo->height < bottomheight)
continue;
}
else if (rover->flags & FF_SHATTER)
{
if (mo->z+mo->momz > topheight)
continue;
if (mo->z+mo->momz + mo->height < bottomheight)
continue;
}
else
{
if (mo->z >= topheight)
continue;
topheight = P_GetFOFTopZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);
if (mo->z+mo->height < bottomheight)
continue;
if (rover->flags & FF_SPINBUST)
{
if (mo->z+mo->momz > topheight)
continue;
if (mo->z+mo->height < bottomheight)
continue;
}
else if (rover->flags & FF_SHATTER)
{
if (mo->z+mo->momz > topheight)
continue;
if (mo->z+mo->momz + mo->height < bottomheight)
continue;
}
else
{
if (mo->z >= topheight)
continue;
if (mo->z+mo->height < bottomheight)
continue;
}
}
EV_CrumbleChain(node->m_sector, rover);
@@ -2950,7 +2954,8 @@ void P_MobjCheckWater(mobj_t *mobj)
if ((mobj->eflags & MFE_VERTICALFLIP) && mobj->ceilingz-mobj->waterbottom <= FixedMul(mobj->info->height, mobj->scale)>>1)
return;
if ((mobj->eflags & MFE_GOOWATER || wasingoo)) { // Decide what happens to your momentum when you enter/leave goopy water.
if ((mobj->eflags & MFE_GOOWATER || wasingoo)) // Decide what happens to your momentum when you enter/leave goopy water.
{
if (P_MobjFlip(mobj)*mobj->momz < 0) // You are entering the goo?
mobj->momz = FixedMul(mobj->momz, FixedDiv(2*FRACUNIT, 5*FRACUNIT)); // kill momentum significantly, to make the goo feel thick.
}
@@ -2964,6 +2969,7 @@ void P_MobjCheckWater(mobj_t *mobj)
{
// Spawn a splash
mobj_t *splish;
if (mobj->eflags & MFE_VERTICALFLIP)
{
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->waterbottom-FixedMul(mobjinfo[MT_SPLISH].height, mobj->scale), MT_SPLISH);
@@ -2972,6 +2978,7 @@ void P_MobjCheckWater(mobj_t *mobj)
}
else
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->watertop, MT_SPLISH);
splish->destscale = mobj->scale;
P_SetScale(splish, mobj->scale);
}
@@ -3372,7 +3379,11 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
I_Assert(mobj->player != NULL);
I_Assert(!P_MobjWasRemoved(mobj));
#ifndef COMPAT_VANILLA
if (P_MobjWasRemoved(mobj))
#else
if (!mobj)
#endif
return;
P_MobjCheckWater(mobj);
@@ -5161,9 +5172,9 @@ static void P_Boss9Thinker(mobj_t *mobj)
{
// Stunned after vector form
if (mobj->movedir > ANGLE_180)
mobj->angle -= FixedAngle(FixedMul(AngleFixed(InvAngle(mobj->movedir)),FixedDiv(mobj->reactiontime<<FRACBITS,24<<FRACBITS)));
mobj->angle -= FixedAngle(FixedMul(AngleFixed(InvAngle(mobj->movedir)), FixedDiv(mobj->reactiontime<<FRACBITS,24<<FRACBITS)));
else
mobj->angle += FixedAngle(FixedMul(AngleFixed(mobj->movedir),FixedDiv(mobj->reactiontime<<FRACBITS,24<<FRACBITS)));
mobj->angle += FixedAngle(FixedMul(AngleFixed(mobj->movedir), FixedDiv(mobj->reactiontime<<FRACBITS,24<<FRACBITS)));
mobj->reactiontime--;
@@ -5205,99 +5216,99 @@ static void P_Boss9Thinker(mobj_t *mobj)
// It's time to attack! What are we gonna do?!
switch(mobj->movecount)
{
case 0:
default:
// Fly up and prepare for an attack!
// We have to charge up first, so let's go up into the air
P_SetMobjState(mobj, mobj->info->raisestate);
if (mobj->floorz >= mobj->target->floorz)
mobj->watertop = mobj->floorz + 256*FRACUNIT;
else
mobj->watertop = mobj->target->floorz + 256*FRACUNIT;
break;
case 1:
{
// Okay, we're up? Good, time to gather energy...
if (mobj->health > mobj->info->damage)
{ // No more bubble if we're broken (pinch phase)
mobj_t *shield = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_MSSHIELD_FRONT);
P_SetTarget(&mobj->tracer, shield);
P_SetTarget(&shield->target, mobj);
}
else
P_LinedefExecute(LE_PINCHPHASE, mobj, NULL);
mobj->fuse = 4*TICRATE;
mobj->flags |= MF_PAIN;
if (mobj->info->attacksound)
S_StartSound(mobj, mobj->info->attacksound);
A_FaceTarget(mobj);
break;
}
case 2:
// We're all charged and ready now! Unleash the fury!!
if (mobj->health > mobj->info->damage)
{
mobj_t *removemobj = mobj->tracer;
P_SetTarget(&mobj->tracer, mobj->hnext);
P_RemoveMobj(removemobj);
}
if (mobj->health <= mobj->info->damage)
{
// Attack 1: Pinball dash!
if (mobj->health == 1)
mobj->movedir = 0;
case 0:
default:
// Fly up and prepare for an attack!
// We have to charge up first, so let's go up into the air
P_SetMobjState(mobj, mobj->info->raisestate);
if (mobj->floorz >= mobj->target->floorz)
mobj->watertop = mobj->floorz + 256*FRACUNIT;
else
mobj->movedir = 2;
if (mobj->info->seesound)
S_StartSound(mobj, mobj->info->seesound);
P_SetMobjState(mobj, mobj->info->seestate);
if (mobj->movedir == 2)
mobj->threshold = 16; // bounce 16 times
else
mobj->threshold = 32; // bounce 32 times
mobj->watertop = mobj->target->floorz + 16*FRACUNIT;
P_LinedefExecute(LE_PINCHPHASE, mobj, NULL);
}
else
mobj->watertop = mobj->target->floorz + 256*FRACUNIT;
break;
case 1:
{
// Attack 2: Energy shot!
mobj->movedir = 1;
if (mobj->health >= 8)
mobj->extravalue1 = 0;
else if (mobj->health >= 5)
mobj->extravalue1 = 2;
else if (mobj->health >= 4)
mobj->extravalue1 = 1;
else
mobj->extravalue1 = 3;
switch(mobj->extravalue1)
{
case 0: // shoot once
case 2: // spread-shot
default:
mobj->threshold = 2;
break;
case 1: // shoot 3 times
mobj->threshold = 3*2;
break;
case 3: // shoot like a goddamn machinegun
mobj->threshold = 8*2;
break;
// Okay, we're up? Good, time to gather energy...
if (mobj->health > mobj->info->damage)
{ // No more bubble if we're broken (pinch phase)
mobj_t *shield = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_MSSHIELD_FRONT);
P_SetTarget(&mobj->tracer, shield);
P_SetTarget(&shield->target, mobj);
}
else
P_LinedefExecute(LE_PINCHPHASE, mobj, NULL);
mobj->fuse = 4*TICRATE;
mobj->flags |= MF_PAIN;
if (mobj->info->attacksound)
S_StartSound(mobj, mobj->info->attacksound);
A_FaceTarget(mobj);
break;
}
break;
case 3:
// Return to idle.
mobj->watertop = mobj->target->floorz + 32*FRACUNIT;
P_SetMobjState(mobj, mobj->info->spawnstate);
mobj->flags &= ~MF_PAIN;
mobj->fuse = 10*TICRATE;
break;
case 2:
// We're all charged and ready now! Unleash the fury!!
if (mobj->health > mobj->info->damage)
{
mobj_t *removemobj = mobj->tracer;
P_SetTarget(&mobj->tracer, mobj->hnext);
P_RemoveMobj(removemobj);
}
if (mobj->health <= mobj->info->damage)
{
// Attack 1: Pinball dash!
if (mobj->health == 1)
mobj->movedir = 0;
else
mobj->movedir = 2;
if (mobj->info->seesound)
S_StartSound(mobj, mobj->info->seesound);
P_SetMobjState(mobj, mobj->info->seestate);
if (mobj->movedir == 2)
mobj->threshold = 16; // bounce 16 times
else
mobj->threshold = 32; // bounce 32 times
mobj->watertop = mobj->target->floorz + 16*FRACUNIT;
P_LinedefExecute(LE_PINCHPHASE, mobj, NULL);
}
else
{
// Attack 2: Energy shot!
mobj->movedir = 1;
if (mobj->health >= 8)
mobj->extravalue1 = 0;
else if (mobj->health >= 5)
mobj->extravalue1 = 2;
else if (mobj->health >= 4)
mobj->extravalue1 = 1;
else
mobj->extravalue1 = 3;
switch (mobj->extravalue1)
{
case 0: // shoot once
case 2: // spread-shot
default:
mobj->threshold = 2;
break;
case 1: // shoot 3 times
mobj->threshold = 3*2;
break;
case 3: // shoot like a goddamn machinegun
mobj->threshold = 8*2;
break;
}
}
break;
case 3:
// Return to idle.
mobj->watertop = mobj->target->floorz + 32*FRACUNIT;
P_SetMobjState(mobj, mobj->info->spawnstate);
mobj->flags &= ~MF_PAIN;
mobj->fuse = 10*TICRATE;
break;
}
mobj->movecount++;
mobj->movecount %= 4;
@@ -5315,6 +5326,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
// Face your target
angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); // absolute angle
angle = (angle-mobj->angle); // relative angle
if (angle < ANGLE_180)
mobj->angle += angle/8;
else
@@ -5326,18 +5338,19 @@ static void P_Boss9Thinker(mobj_t *mobj)
|| mobj->target->player->powers[pw_invulnerability]
|| mobj->target->player->powers[pw_super]))
danger = false;
if (mobj->target->x+mobj->target->radius+abs(mobj->target->momx*2) < mobj->x-mobj->radius)
else if (mobj->target->x+mobj->target->radius+abs(mobj->target->momx*2) < mobj->x-mobj->radius)
danger = false;
if (mobj->target->x-mobj->target->radius-abs(mobj->target->momx*2) > mobj->x+mobj->radius)
else if (mobj->target->x-mobj->target->radius-abs(mobj->target->momx*2) > mobj->x+mobj->radius)
danger = false;
if (mobj->target->y+mobj->target->radius+abs(mobj->target->momy*2) < mobj->y-mobj->radius)
else if (mobj->target->y+mobj->target->radius+abs(mobj->target->momy*2) < mobj->y-mobj->radius)
danger = false;
if (mobj->target->y-mobj->target->radius-abs(mobj->target->momy*2) > mobj->y+mobj->radius)
else if (mobj->target->y-mobj->target->radius-abs(mobj->target->momy*2) > mobj->y+mobj->radius)
danger = false;
if (mobj->target->z+mobj->target->height+mobj->target->momz*2 < mobj->z)
else if (mobj->target->z+mobj->target->height+mobj->target->momz*2 < mobj->z)
danger = false;
if (mobj->target->z+mobj->target->momz*2 > mobj->z+mobj->height)
else if (mobj->target->z+mobj->target->momz*2 > mobj->z+mobj->height)
danger = false;
if (danger)
{
// An incoming attack is detected! What should we do?!
@@ -5345,21 +5358,27 @@ static void P_Boss9Thinker(mobj_t *mobj)
mobj->movedir = ANGLE_11hh - FixedAngle(FixedMul(AngleFixed(ANGLE_11hh), FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS)));
if (P_RandomChance(FRACUNIT/2))
mobj->movedir = InvAngle(mobj->movedir);
mobj->threshold = 6 + (FixedMul(24<<FRACBITS, FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS))>>FRACBITS);
if (mobj->info->activesound)
S_StartSound(mobj, mobj->info->activesound);
if (mobj->info->painchance)
P_SetMobjState(mobj, mobj->info->painchance);
return;
}
// Move normally: Approach the player using normal thrust and simulated friction.
dist = P_AproxDistance(mobj->x-mobj->target->x, mobj->y-mobj->target->y);
P_Thrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), -3*FRACUNIT/8);
if (dist < 64*FRACUNIT)
P_Thrust(mobj, mobj->angle, -4*FRACUNIT);
else if (dist > 180*FRACUNIT)
P_Thrust(mobj, mobj->angle, FRACUNIT);
mobj->momz += P_AproxDistance(mobj->momx, mobj->momy)/12; // Move up higher the faster you're going.
}
}
@@ -5614,7 +5633,11 @@ void P_SetScale(mobj_t *mobj, fixed_t newscale)
player_t *player;
fixed_t oldscale;
#ifndef COMPAT_VANILLA
if (P_MobjWasRemoved(mobj))
#else
if (!mobj)
#endif
return;
oldscale = mobj->scale; //keep for adjusting stuff below
@@ -6853,11 +6876,9 @@ static boolean P_MobjDeadThink(mobj_t *mobj)
case MT_BANANA:
if (cv_bananthrowroll.value)
{
//mobj->angle -= spin;
if (cv_bananthrowroll.value == 1 && K_CheckSlopeRollDist(mobj))
mobj->sloperoll += (angle_t)FixedMul(FixedDiv(abs(mobj->momz), 8 * mobj->scale), ANGLE_67h); // im lazy but this makes sure the banan goes back to upright when it lands lmao
else if (cv_bananthrowroll.value == 2)
mobj->rollangle += (angle_t)FixedMul(FixedDiv(abs(mobj->momz), 8 * mobj->scale), ANGLE_67h);
const angle_t speen = (angle_t)FixedMul(FixedDiv(abs(mobj->momz), 8 * mobj->scale), ANGLE_67h);
//mobj->angle -= speen;
mobj->rollangle += speen;
}
/* FALLTHRU */
case MT_ORBINAUT:
@@ -7047,7 +7068,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
}
P_InstaThrust(mobj, mobj->angle, finalspeed);
if (grounded)
{
sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj);
@@ -7167,21 +7188,23 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
}
case MT_BANANA:
case MT_EGGMANITEM:
if (cv_bananthrowroll.value && !P_IsObjectOnGround(mobj))
{
boolean grounded = P_IsObjectOnGround(mobj);
if (cv_bananthrowroll.value && !grounded)
{
// tilt n tumble
//mobj->angle += spin;
if (cv_bananthrowroll.value == 1 && K_CheckSlopeRollDist(mobj))
mobj->sloperoll -= (angle_t)FixedMul(FixedDiv(mobj->momz, 8 * mobj->scale), ANGLE_67h); // im lazy but this makes sure the banan goes back to upright when it lands lmao
else if (cv_bananthrowroll.value == 2)
mobj->rollangle -= (angle_t)FixedMul(FixedDiv(mobj->momz, 8 * mobj->scale), ANGLE_67h);
const angle_t speen = (angle_t)FixedMul(FixedDiv(abs(mobj->momz), 8 * mobj->scale), ANGLE_67h);
//mobj->angle += speen;
mobj->rollangle -= speen;
}
mobj->friction = ORIG_FRICTION/4;
if (mobj->momx || mobj->momy)
P_SpawnGhostMobj(mobj);
if (P_IsObjectOnGround(mobj) && mobj->health > 1)
if (grounded && mobj->health > 1)
{
S_StartSound(mobj, mobj->info->activesound);
mobj->momx = mobj->momy = 0;
@@ -7192,7 +7215,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (mobj->threshold > 0)
mobj->threshold--;
break;
}
case MT_SPB:
indirectitemcooldown = 20*TICRATE;
/* FALLTHRU */
@@ -8663,14 +8688,15 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
{
const angle_t fa = (i*FINEANGLES/16) & FINEMASK;
ns = FixedMul(64 * FRACUNIT, mobj->scale);
x = mobj->x + FixedMul(FINESINE(fa),ns);
y = mobj->y + FixedMul(FINECOSINE(fa),ns);
x = mobj->x + FixedMul(FINESINE(fa), ns);
y = mobj->y + FixedMul(FINECOSINE(fa), ns);
mo2 = P_SpawnMobj(x, y, z, MT_EXPLODE);
ns = FixedMul(16 * FRACUNIT, mobj->scale);
mo2->momx = FixedMul(FINESINE(fa),ns);
mo2->momy = FixedMul(FINECOSINE(fa),ns);
mo2->momx = FixedMul(FINESINE(fa), ns);
mo2->momy = FixedMul(FINECOSINE(fa), ns);
}
z -= FixedMul(32*FRACUNIT, mobj->scale);
}
P_SetMobjState(mobj, mobj->info->deathstate);
@@ -8864,9 +8890,9 @@ static void P_IceBlockFuseThink(mobj_t *mobj)
for (i = 0; i < 5; i++)
{
mobj_t *debris = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMK_ICEBLOCK_DEBRIS);
debris->angle = FixedAngle(P_RandomRange(0,360)<<FRACBITS);
P_InstaThrust(debris, debris->angle, P_RandomRange(3,18)*(FRACUNIT/4));
debris->momz = P_RandomRange(4,8)<<FRACBITS;
debris->angle = FixedAngle(P_RandomRange(0, 360)<<FRACBITS);
P_InstaThrust(debris, debris->angle, P_RandomRange(3, 18)*(FRACUNIT/4));
debris->momz = P_RandomRange(4, 8)<<FRACBITS;
if (!i) // kinda hacky :V
S_StartSound(debris, sfx_s3k82);
}
@@ -8962,7 +8988,11 @@ static boolean P_FuseThink(mobj_t *mobj)
static boolean P_MobjPushableThink(mobj_t *mobj)
{
// would be cool if we could use P_MobjWasRemoved Zzz...
#ifndef COMPAT_VANILLA
if (P_MobjWasRemoved(mobj))
#else
if (!mobj)
#endif
return false;
P_MobjCheckWater(mobj);
@@ -9167,6 +9197,14 @@ void P_MobjThinker(mobj_t *mobj)
|| P_WeaponOrPanel(mobj->type))
{
P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly
#ifndef COMPAT_VANILLA
if (P_MobjWasRemoved(mobj)) // anything that calls checkposition can be lethal
#else
if (!mobj) // anything that calls checkposition can be lethal
#endif
return;
P_ButteredSlope(mobj);
}
@@ -9192,6 +9230,13 @@ void P_MobjThinker(mobj_t *mobj)
}
}
#ifndef COMPAT_VANILLA
if (P_MobjWasRemoved(mobj))
#else
if (!mobj)
#endif
return; // obligatory paranoia check
// Can end up here if a player dies.
P_CycleMobjState(mobj);
@@ -9249,7 +9294,11 @@ void P_PushableThinker(mobj_t *mobj)
I_Assert(!P_MobjWasRemoved(mobj));
#ifndef COMPAT_VANILLA
if (P_MobjWasRemoved(mobj))
#else
if (!mobj)
#endif
return;
sec = mobj->subsector->sector;
+1
View File
@@ -298,6 +298,7 @@ typedef struct mobj_s
angle_t angle, pitch, roll; // orientation
angle_t old_angle, old_pitch, old_roll; // orientation interpolation
angle_t rollangle;
angle_t temprollangle; // same as rollangle but resets each tic, idk either man. // cba exposing this to lua either
spritenum_t sprite; // used to find patch_t and flip value
UINT32 frame; // frame number, plus bits see p_pspr.h
UINT16 anim_duration; // for FF_ANIMATE states
+11 -6
View File
@@ -691,7 +691,7 @@ static void ArchiveLines(savebuffer_t *save)
if (spawnli->special == 321 || spawnli->special == 322) // only reason li->callcount would be non-zero is if either of these are involved
diff |= LD_CLLCOUNT;
if (li->sidenum[0] != 0xffff)
if (li->sidenum[0] != NO_INDEX)
{
si = &sides[li->sidenum[0]];
spawnsi = &spawnsides[li->sidenum[0]];
@@ -706,7 +706,8 @@ static void ArchiveLines(savebuffer_t *save)
if (si->midtexture != spawnsi->midtexture)
diff |= LD_S1MIDTEX;
}
if (li->sidenum[1] != 0xffff)
if (li->sidenum[1] != NO_INDEX)
{
si = &sides[li->sidenum[1]];
spawnsi = &spawnsides[li->sidenum[1]];
@@ -786,6 +787,7 @@ static void UnArchiveFFloors(savebuffer_t *save, const sector_t *ss)
I_Error("Sector does not have any ffloors!");
fflr_i = READUINT16(save->p); // get first modified ffloor's number ready
for (;;) // for some reason the usual for (rover = x; ...) thing doesn't work here?
{
if (fflr_i == 0xffff) // end of modified ffloors list, let's stop already
@@ -3057,7 +3059,7 @@ static void P_NetUnArchiveThinkers(savebuffer_t *save)
break;
default:
I_Error("P_UnarchiveSpecials: Unknown tclass %d in savegame", tclass);
I_Error("P_NetUnArchiveThinkers: Unknown tclass %d in savegame", tclass);
}
}
@@ -3168,7 +3170,7 @@ FUNCINLINE static ATTRINLINE void P_UnArchivePolyObjects(savebuffer_t *save)
numSavedPolys = READINT32(save->p);
if (numSavedPolys != numPolyObjects)
I_Error("P_UnArchivePolyObjects: polyobj count inconsistency\n");
I_Error("P_UnArchivePolyObjects: polyobj count inconsistency (expected %d, got %d)\n", numPolyObjects, numSavedPolys);
for (i = 0; i < numSavedPolys; ++i)
P_UnArchivePolyObj(save, &PolyObjects[i]);
@@ -3510,7 +3512,7 @@ static void P_ReloadSaveLevelData(void)
li->firsttag = spawnli->firsttag;
li->nexttag = spawnli->nexttag;
if (li->sidenum[0] != 0xffff)
if (li->sidenum[0] != NO_INDEX)
{
si = &sides[li->sidenum[0]];
spawnsi = &spawnsides[li->sidenum[0]];
@@ -3521,7 +3523,7 @@ static void P_ReloadSaveLevelData(void)
si->midtexture = spawnsi->midtexture;
}
if (li->sidenum[1] != 0xffff)
if (li->sidenum[1] != NO_INDEX)
{
si = &sides[li->sidenum[1]];
spawnsi = &spawnsides[li->sidenum[1]];
@@ -3588,8 +3590,11 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(savebuffer_t *save, bool
if (!P_SetupLevel(true, reloading))
{
CONS_Alert(CONS_ERROR, M_GetText("Can't load the level!\n"));
P_FreeCorruptMapWarnings();
return false;
}
P_PrintCorruptMapWarnings();
}
else
{
+478 -134
View File
@@ -188,6 +188,57 @@ FUNCNORETURN static ATTRNORETURN void CorruptMapError(const char *msg)
I_Error("Invalid or corrupt map.\nLook in log file or text console for technical details.");
}
static char **mapwarnings = NULL;
static size_t nummapwarnings = 0;
// collect map errors we can fix clientside
// we then can print em when the map finishes loading
// so they actually appear and raise awareness shits fucked
// see G_DoLoadLevel as to why :chaosleep:
static void CorruptMapWarning(const char *msg)
{
#ifdef PARANOIA
// just error out
I_Error("%sThis WILL crash Vanilla clients!\n", msg);
#endif
nummapwarnings++;
mapwarnings = Z_Realloc(mapwarnings, nummapwarnings * sizeof(*mapwarnings), PU_STATIC, NULL);
mapwarnings[nummapwarnings-1] = Z_StrDup(msg);
}
void P_PrintCorruptMapWarnings(void)
{
size_t i;
if (!nummapwarnings)
return;
for (i = 0; i < nummapwarnings; i++)
{
CONS_Alert(CONS_ERROR, "%sAttempting to fix... This WILL crash Vanilla clients!\n", mapwarnings[i]);
}
P_FreeCorruptMapWarnings();
}
void P_FreeCorruptMapWarnings(void)
{
size_t i;
if (!nummapwarnings)
return;
for (i = 0; i < nummapwarnings; i++)
{
Z_Free(mapwarnings[i]);
mapwarnings[i] = NULL;
}
Z_Free(mapwarnings);
mapwarnings = NULL;
nummapwarnings = 0;
}
#define NUMLAPS_DEFAULT 3
static void P_ClearMapHeaderLighting(mapheader_lighting_t *lighting)
@@ -405,10 +456,10 @@ static void P_SetupDirectionalLight(void)
if (gamemap != oldmap || encoremode != oldencore || reinitmaplight)
{
lighting->light_contrast = M_RandomRange(0, 58);
lighting->light_contrast = (UINT8)M_RandomRange(0, 58);
lighting->sprite_backlight = 0;
lighting->use_light_angle = M_RandomRange(0, 1); // either on or off
lighting->light_angle = M_RandomRange(-382, 382);
lighting->use_light_angle = (boolean)M_RandomRange(0, 1); // either on or off
lighting->light_angle = (angle_t)M_RandomRange(-382, 382);
reinitmaplight = false;
}
@@ -437,8 +488,39 @@ static void P_LoadSegs(UINT8 *data)
for (i = 0; i < numsegs; i++, li++, ml++)
{
li->v1 = &vertexes[SHORT(ml->v1)];
li->v2 = &vertexes[SHORT(ml->v2)];
INT16 v1, v2;
v1 = SHORT(ml->v1);
v2 = SHORT(ml->v2);
// e6y
// check and fix wrong references to non-existent vertexes
// see e1m9 @ NIVELES.WAD
// http://www.doomworld.com/idgames/index.php?id=12647
if ((unsigned)v1 >= numvertexes || (unsigned)v2 >= numvertexes)
{
if ((unsigned)v1 >= numvertexes)
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v1));
if ((unsigned)v2 >= numvertexes)
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v2));
if (li->sidedef == &sides[li->linedef->sidenum[0]])
{
li->v1 = lines[ml->linedef].v1;
li->v2 = lines[ml->linedef].v2;
}
else
{
li->v1 = lines[ml->linedef].v2;
li->v2 = lines[ml->linedef].v1;
}
}
else
{
li->v1 = &vertexes[v1];
li->v2 = &vertexes[v2];
}
#ifdef HWRENDER
if (rendermode == render_opengl)
{
@@ -455,14 +537,59 @@ static void P_LoadSegs(UINT8 *data)
li->angle = (SHORT(ml->angle))<<FRACBITS;
li->offset = (SHORT(ml->offset))<<FRACBITS;
rawlinedef = SHORT(ml->linedef);
//e6y: check for wrong indexes
if ((unsigned)rawlinedef >= numlines)
{
I_Error("P_LoadSegs: seg %s references a non-existent linedef %d", sizeu1(i), (unsigned)rawlinedef);
}
ldef = &lines[rawlinedef];
li->linedef = ldef;
li->side = rawside = SHORT(ml->side);
rawside = SHORT(ml->side);
//e6y: fix wrong side index
if (rawside != 0 && rawside != 1)
{
CorruptMapWarning(va("P_LoadSegs: seg %s contains wrong side index %d.\n", sizeu1(i), rawside));
rawside = 1;
}
//e6y: check for wrong indexes
if (ldef->sidenum[rawside] >= numsides)
{
I_Error("P_LoadSegs: linedef %d for seg %s references a non-existent sidedef %d", rawlinedef, sizeu1(i), ldef->sidenum[rawside]);
}
li->side = rawside;
li->sidedef = &sides[ldef->sidenum[rawside]];
li->frontsector = sides[ldef->sidenum[rawside]].sector;
/* cph 2006/09/30 - our frontsector can be the second side of the
* linedef, so must check for NO_INDEX in case we are incorrectly
* referencing the back of a 1S line */
if (ldef->sidenum[rawside] == NO_INDEX)
{
CorruptMapWarning(va("P_LoadSegs: front of seg %s has no sidedef\n", sizeu1(i)));
li->frontsector = NULL;
}
else
{
li->frontsector = sides[ldef->sidenum[rawside]].sector;
}
if (ldef->flags & ML_TWOSIDED)
li->backsector = sides[ldef->sidenum[rawside^1]].sector;
{
if (ldef->sidenum[rawside^1] == NO_INDEX)
{
CorruptMapWarning(va("P_LoadSegs: back of seg %s has no sidedef while being marked as double sided\n", sizeu1(i)));
li->backsector = NULL;
}
else
{
li->backsector = sides[ldef->sidenum[rawside^1]].sector;
}
}
P_UpdateSegLightOffset(li);
}
@@ -738,7 +865,33 @@ static void P_LoadNodes(UINT8 *data)
for (j = 0; j < 2; j++)
{
no->children[j] = SHORT(mn->children[j]);
UINT16 child;
child = SHORT(mn->children[j]);
if (child & NF_SUBSECTOR)
{
// Convert to extended type
child &= ~NF_SUBSECTOR;
// haleyjd 11/06/10: check for invalid subsector reference
if (child >= numsubsectors)
{
CorruptMapWarning(va("P_LoadNodes: BSP tree %s references invalid subsector %d\n", sizeu1(i), child));
child = 0;
}
child |= NF_SUBSECTOR;
}
else if (child >= numnodes)
{
CorruptMapWarning(va("P_LoadNodes: BSP node %s references invalid node.\n", sizeu1(i)));
//I_Error("P_LoadNodes: BSP node %d references invalid node %d.\n", sizeu1(i), Index(((node_t *)no->children[j])));
child = 0;
}
no->children[j] = child;
for (k = 0; k < 4; k++)
no->bbox[j][k] = SHORT(mn->bbox[j][k])<<FRACBITS;
}
@@ -1001,9 +1154,9 @@ static void P_InitializeLinedef(line_t *ld)
// cph 2002/07/20 - these errors are fatal if not fixed, so apply them
for (j = 0; j < 2; j++)
{
if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides)
if (ld->sidenum[j] != NO_INDEX && ld->sidenum[j] >= (UINT16)numsides)
{
ld->sidenum[j] = 0xffff;
ld->sidenum[j] = NO_INDEX;
CONS_Debug(DBG_SETUP, "P_InitializeLinedef: Linedef %s has out-of-range sidedef number\n", sizeu1((size_t)(ld - lines)));
}
}
@@ -1011,23 +1164,24 @@ static void P_InitializeLinedef(line_t *ld)
ld->firsttag = ld->nexttag = -1;
// killough 11/98: fix common wad errors (missing sidedefs):
if (ld->sidenum[0] == 0xffff)
if (ld->sidenum[0] == NO_INDEX)
{
ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side
// cph - print a warning about the bug
CONS_Debug(DBG_SETUP, "P_InitializeLinedef: Linedef %s missing first sidedef\n", sizeu1((size_t)(ld - lines)));
}
if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED))
if ((ld->sidenum[1] == NO_INDEX) && (ld->flags & ML_TWOSIDED))
{
ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side
// cph - print a warning about the bug
CONS_Debug(DBG_SETUP, "P_InitializeLinedef: Linedef %s has two-sided flag set, but no second sidedef\n", sizeu1((size_t)(ld - lines)));
}
if (ld->sidenum[0] != 0xffff && ld->special)
// killough 4/4/98: support special sidedef interpretation below
if (ld->sidenum[0] != NO_INDEX && ld->special)
sides[ld->sidenum[0]].special = ld->special;
if (ld->sidenum[1] != 0xffff && ld->special)
if (ld->sidenum[1] != NO_INDEX && ld->special)
sides[ld->sidenum[1]].special = ld->special;
}
@@ -1060,10 +1214,10 @@ static void P_LoadLineDefs2(void)
for (; i--; ld++)
{
ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here
ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : NULL;
ld->backsector = ld->sidenum[1] != NO_INDEX ? sides[ld->sidenum[1]].sector : NULL;
// Repeat count for midtexture
if ((ld->flags & ML_EFFECT5) && (ld->sidenum[1] != 0xffff))
if ((ld->flags & ML_EFFECT5) && (ld->sidenum[1] != NO_INDEX))
{
sides[ld->sidenum[0]].repeatcnt = (INT16)(((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) >> 12);
sides[ld->sidenum[0]].textureoffset = (((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) & 2047) << FRACBITS;
@@ -1079,13 +1233,13 @@ static void P_LoadLineDefs2(void)
{
size_t len = strlen(sides[ld->sidenum[0]].text)+1;
if (ld->sidenum[1] != 0xffff && sides[ld->sidenum[1]].text)
if (ld->sidenum[1] != NO_INDEX && sides[ld->sidenum[1]].text)
len += strlen(sides[ld->sidenum[1]].text);
ld->text = Z_Malloc(len, PU_LEVEL, NULL);
memcpy(ld->text, sides[ld->sidenum[0]].text, strlen(sides[ld->sidenum[0]].text)+1);
if (ld->sidenum[1] != 0xffff && sides[ld->sidenum[1]].text)
if (ld->sidenum[1] != NO_INDEX && sides[ld->sidenum[1]].text)
memcpy(ld->text+strlen(ld->text)+1, sides[ld->sidenum[1]].text, strlen(sides[ld->sidenum[1]].text)+1);
}
break;
@@ -1215,14 +1369,14 @@ static void P_LoadSideChangeMusic(boolean firstside, mapsidedef_t *msd, side_t *
if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0')
{
memcpy(process,msd->bottomtexture,8);
memcpy(process, msd->bottomtexture, 8);
process[8] = '\0';
sd->bottomtexture = get_number(process);
}
if (!(msd->midtexture[0] == '-' && msd->midtexture[1] == '\0') || msd->midtexture[1] != '\0')
{
memcpy(process,msd->midtexture,8);
memcpy(process, msd->midtexture, 8);
process[8] = '\0';
sd->midtexture = get_number(process);
}
@@ -1232,7 +1386,7 @@ static void P_LoadSideChangeMusic(boolean firstside, mapsidedef_t *msd, side_t *
if (firstside || msd->toptexture[0] != '-' || msd->toptexture[1] != '\0')
{
memcpy(process,msd->toptexture,8);
memcpy(process, msd->toptexture, 8);
process[8] = '\0';
// If they type in O_ or D_ and their music name, just shrug,
@@ -1272,7 +1426,7 @@ static void P_LoadSidedefs(void *data)
// Colormaps!
switch (sd->special)
{
case 63: // variable colormap via 242 linedef
case 63: // variable colormap via 242 linedef
case 606: //SoM: 4/4/2000: Just colormap transfer
// SoM: R_CreateColormap will only create a colormap in software mode...
// Perhaps we should just call it instead of doing the calculations here.
@@ -1288,26 +1442,26 @@ static void P_LoadSidedefs(void *data)
if (msd->toptexture[0] != '-' || msd->toptexture[1] != '\0')
{
char process[8+1];
memcpy(process,msd->toptexture,8);
memcpy(process, msd->toptexture, 8);
process[8] = '\0';
sd->toptexture = get_number(process);
}
break;
}
case 9: // Mace parameters
case 14: // Bustable block parameters
case 15: // Fan particle spawner parameters
case 9: // Mace parameters
case 14: // Bustable block parameters
case 15: // Fan particle spawner parameters
case 425: // Calls P_SetMobjState on calling mobj
case 434: // Custom Power
case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors
{
char process[8*3+1];
memset(process,0,8*3+1);
memset(process, 0, 8*3+1);
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
if (msd->toptexture[0] == '-' && msd->toptexture[1] == '\0')
break;
else
memcpy(process,msd->toptexture,8);
memcpy(process, msd->toptexture, 8);
if (msd->midtexture[0] != '-' || msd->midtexture[1] != '\0')
memcpy(process+strlen(process), msd->midtexture, 8);
if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0')
@@ -1319,12 +1473,12 @@ static void P_LoadSidedefs(void *data)
case 443: // Calls a named Lua function
{
char process[8*3+1];
memset(process,0,8*3+1);
memset(process, 0, 8*3+1);
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
if (msd->toptexture[0] == '-' && msd->toptexture[1] == '\0')
break;
else
memcpy(process,msd->toptexture,8);
memcpy(process,msd->toptexture, 8);
if (msd->midtexture[0] != '-' || msd->midtexture[1] != '\0')
memcpy(process+strlen(process), msd->midtexture, 8);
if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0')
@@ -1625,6 +1779,80 @@ static void P_CreateBlockMap(void)
}
}
//
// P_VerifyBlockMap
//
// haleyjd 03/04/10: do verification on validity of blockmap.
//
static boolean P_VerifyBlockMap(INT32 count)
{
// FIXME: should any of this shit be unsinged?
INT32 x, y;
INT32 *maxoffs = blockmaplump + count;
//skipblstart = true;
for (y = 0; y < bmapheight; y++)
{
for (x = 0; x < bmapwidth; x++)
{
INT32 offset;
INT32 *list, *tmplist;
INT32 *blockoffset;
offset = y * bmapwidth + x;
blockoffset = blockmaplump + offset + 4;
// check that block offset is in bounds
if (blockoffset >= maxoffs)
{
CONS_Alert(CONS_ERROR, "P_VerifyBlockMap: block offset overflow\n");
return false;
}
offset = *blockoffset;
// check that list offset is in bounds
if (offset < 4 || offset >= count)
{
CONS_Alert(CONS_ERROR, "P_VerifyBlockMap: list offset overflow\n");
return false;
}
list = blockmaplump + offset;
//if (*list != 0)
//skipblstart = false;
// scan forward for a -1 terminator before maxoffs
for (tmplist = list; ; tmplist++)
{
// we have overflowed the lump?
if (tmplist >= maxoffs)
{
CONS_Alert(CONS_ERROR, "P_VerifyBlockMap: open blocklist\n");
return false;
}
if (*tmplist == -1) // found -1
break;
}
// scan the list for out-of-range linedef indicies in list
for (tmplist = list; *tmplist != -1; tmplist++)
{
if (*tmplist < 0 || *tmplist >= (INT32)numlines)
{
CONS_Alert(CONS_ERROR, "P_VerifyBlockMap: index >= numlines\n");
return false;
}
}
}
}
return true;
}
// Split from P_LoadBlockMap for convenience
// -- Monster Iestyn 08/01/18
static void P_ReadBlockMapLump(INT16 *wadblockmaplump, size_t count)
@@ -1666,9 +1894,20 @@ static boolean P_LoadRawBlockMap(UINT8 *data, size_t count)
bmaporgx = blockmaplump[0]<<FRACBITS;
bmaporgy = blockmaplump[1]<<FRACBITS;
bmapwidth = blockmaplump[2];
bmapwidth = blockmaplump[2];
bmapheight = blockmaplump[3];
// haleyjd 03/04/10: check for blockmap problems
// http://www.doomworld.com/idgames/index.php?id=12935
if (!P_VerifyBlockMap(count))
{
CorruptMapWarning(va("P_LoadBlockMap: corrupted or invalid BLOCKMAP lump! Check the log for more information.\n"));
// vanilla WILL crash here anyways so just rebuild it ourselves
Z_Free(blockmaplump);
blockmaplump = NULL;
return false;
}
// clear out mobj chains
count = sizeof (*blocklinks)* bmapwidth*bmapheight;
blocklinks = Z_Calloc(count, PU_LEVEL, NULL);
@@ -1703,22 +1942,35 @@ static void P_GroupLines(void)
for (i = 0; i < numsubsectors; i++, ss++)
{
if (ss->firstline >= numsegs)
{
CorruptMapError(va("P_GroupLines: ss->firstline invalid "
"(subsector %s, firstline refers to %d of %s)", sizeu1(i), ss->firstline,
sizeu2(numsegs)));
}
seg = &segs[ss->firstline];
sidei = (size_t)(seg->sidedef - sides);
if (!seg->sidedef)
{
CorruptMapError(va("P_GroupLines: seg->sidedef is NULL "
"(subsector %s, firstline is %d)", sizeu1(i), ss->firstline));
}
if (seg->sidedef - sides < 0 || seg->sidedef - sides > (UINT16)numsides)
{
CorruptMapError(va("P_GroupLines: seg->sidedef refers to sidedef %s of %s "
"(subsector %s, firstline is %d)", sizeu1(sidei), sizeu2(numsides),
sizeu3(i), ss->firstline));
}
if (!seg->sidedef->sector)
{
CorruptMapError(va("P_GroupLines: seg->sidedef->sector is NULL "
"(subsector %s, firstline is %d, sidedef is %s)", sizeu1(i), ss->firstline,
sizeu1(sidei)));
}
ss->sector = seg->sidedef->sector;
}
@@ -1780,20 +2032,36 @@ static void P_GroupLines(void)
}
}
// PK3 version
// -- Monster Iestyn 09/01/18
static void P_LoadReject(UINT8 *data, size_t count)
static void P_LoadReject(UINT8 *data, size_t rejectsize)
{
if (!count) // zero length, someone probably used ZDBSP
const size_t neededsize = (numsectors * numsectors + 7) >> 3;
size_t allocsize = rejectsize;
if (!rejectsize) // zero length, someone probably used ZDBSP
{
rejectmatrix = NULL;
CONS_Debug(DBG_SETUP, "P_LoadReject: REJECT lump has size 0, will not be loaded\n");
}
else
{
rejectmatrix = Z_Malloc(count, PU_LEVEL, NULL); // allocate memory for the reject matrix
memcpy(rejectmatrix, data, count); // copy the data into it
if (rejectsize < neededsize)
{
CorruptMapWarning(va("P_LoadReject: REJECT is %s byte%s too small. REJECT might be invalid!\n", sizeu1(neededsize - rejectsize), (neededsize - rejectsize) == 1 ? "" : "s"));
#ifdef COMPAT_VANILLA
// we can pad this and somewhat prevent desyncs
// probs not cool if the reject is from a completely different map
// but whatever
allocsize = neededsize;
#else
rejectmatrix = NULL;
return;
#endif
}
rejectmatrix = Z_Calloc(allocsize, PU_LEVEL, NULL); // allocate memory for the reject matrix
memcpy(rejectmatrix, data, rejectsize); // copy the data into it
}
}
@@ -1831,9 +2099,13 @@ static void P_LoadMapLUT(const virtres_t* virt)
// Lookup tables
if (virtreject)
{
P_LoadReject(virtreject->data, virtreject->size);
}
else
{
rejectmatrix = NULL;
}
if (!(virtblockmap && P_LoadRawBlockMap(virtblockmap->data, virtblockmap->size)))
P_CreateBlockMap();
@@ -2224,7 +2496,9 @@ static void P_LoadRecordGhosts(void)
if (!gpath)
return;
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
const char *mapname = G_BuildMapName(gamemap);
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, mapname);
// Best Time ghost
if (cv_ghost_besttime.value)
@@ -2274,9 +2548,10 @@ static void P_LoadRecordGhosts(void)
{
lumpnum_t l;
UINT8 j = 1;
while (j <= 99 && (l = W_CheckNumForName(va("%sS%02u",G_BuildMapName(gamemap),j))) != LUMPERROR)
while (j <= 99 && (l = W_CheckNumForName(va("%sS%02u", mapname, j))) != LUMPERROR)
{
G_AddGhost(va("%sS%02u",G_BuildMapName(gamemap),j));
G_AddGhost(va("%sS%02u", mapname, j));
j++;
}
}
@@ -2284,6 +2559,31 @@ static void P_LoadRecordGhosts(void)
free(gpath);
}
static void P_ResetSpawnpoints(void)
{
UINT8 i;
numdmstarts = numredctfstarts = numbluectfstarts = 0;
// reset the player starts
for (i = 0; i < MAXPLAYERS; i++)
{
playerstarts[i] = NULL;
redctfstarts[i] = NULL;
bluectfstarts[i] = NULL;
}
for (i = 0; i < MAX_DM_STARTS; i++)
{
deathmatchstarts[i] = NULL;
}
for (i = 0; i < 2; i++)
{
skyboxmo[i] = NULL;
}
}
static void P_InitCamera(void)
{
INT32 i;
@@ -2293,6 +2593,7 @@ static void P_InitCamera(void)
for (i = 0; i <= splitscreen; i++)
{
camera[i].postimg = 0;
P_SetupCamera(&camera[i]);
}
@@ -2318,10 +2619,12 @@ static void P_InitMinimapInfo(void)
Patch_Free(minimapinfo.minimap_pic);
minimapinfo.minimap_pic = NULL;
lumpnum = W_CheckNumForName(va("%sR", G_BuildMapName(gamemap)));
const char *mapname = G_BuildMapName(gamemap);
lumpnum = W_CheckNumForName(va("%sR", mapname));
if (lumpnum != LUMPERROR)
minimapinfo.minimap_pic = W_CachePatchName(va("%sR", G_BuildMapName(gamemap)), PU_PATCH);
minimapinfo.minimap_pic = W_CachePatchName(va("%sR", mapname), PU_PATCH);
minimapinfo.min_x = bsp->bbox[0][BOXLEFT];
minimapinfo.max_x = bsp->bbox[0][BOXRIGHT];
@@ -2390,10 +2693,14 @@ static boolean P_RunSpecialWipe(boolean reloadinggamestate)
{
// Cancel all d_main.c fadeouts (keep fade in though).
if (reloadinggamestate)
{
wipegamestate = gamestate; // Don't fade if reloading the gamestate
return false;
}
// Encore mode fade to pink to white
// This is handled BEFORE sounds are stopped.
else if (encoremode && !prevencoremode && !demo.rewinding)
if (encoremode && !prevencoremode && !demo.rewinding)
{
tic_t locstarttime, endtime, nowtime;
@@ -2427,6 +2734,8 @@ static boolean P_RunSpecialWipe(boolean reloadinggamestate)
// Hold on white for extra effect.
while (nowtime < endtime)
{
I_HandleInterrupt();
// wait loop
while (!((nowtime = I_GetTime()) - lastwipetic))
{
@@ -2449,6 +2758,69 @@ static boolean P_RunSpecialWipe(boolean reloadinggamestate)
return false;
}
static void P_InitTagGametype(void)
{
UINT8 i;
INT32 realnumplayers = 0;
INT32 playersactive[MAXPLAYERS];
//I just realized how problematic this code can be.
//D_NumPlayers() will not always cover the scope of the netgame.
//What if one player is node 0 and the other node 31?
//The solution? Make a temp array of all players that are currently playing and pick from them.
//Future todo? When a player leaves, shift all nodes down so D_NumPlayers() can be used as intended?
//Also, you'd never have to loop through all 32 players slots to find anything ever again.
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && !players[i].spectator)
{
playersactive[realnumplayers] = i; //stores the player's node in the array.
realnumplayers++;
}
}
if (!realnumplayers) // this should also fix the dedicated crash bug. You only pick a player if one exists to be picked.
{
CONS_Printf(M_GetText("No player currently available to become IT. Awaiting available players.\n"));
return;
}
i = P_RandomKey(realnumplayers);
players[playersactive[i]].pflags |= PF_TAGIT; //choose our initial tagger before map starts.
// Taken and modified from G_DoReborn()
// Remove the player so he can respawn elsewhere.
// first dissasociate the corpse
if (players[playersactive[i]].mo)
P_RemoveMobj(players[playersactive[i]].mo);
G_SpawnPlayer(playersactive[i], false); //respawn the lucky player in his dedicated spawn location.
}
static void P_InitGametype(void)
{
if (modeattacking == ATTACKING_RECORD && !demo.playback)
P_LoadRecordGhosts();
if (G_RaceGametype() && server)
{
INT32 numLaps;
const mapheader_t *mapheader = mapheaderinfo[gamemap - 1];
if ((netgame || multiplayer) && cv_basenumlaps.value &&
(!(mapheader->levelflags & LF_SECTIONRACE) || (mapheader->numlaps > cv_basenumlaps.value)))
numLaps = cv_basenumlaps.value;
else
numLaps = mapheader->numlaps;
CV_StealthSetValue(&cv_numlaps, numLaps);
}
else if (G_TagGametype())
{
P_InitTagGametype();
}
}
static void P_SetupPlayer(void)
{
INT32 i;
@@ -2462,76 +2834,27 @@ static void P_SetupPlayer(void)
// Start players with pity shields if possible
players[i].pity = -1;
players[i].mo = NULL;
if (!G_RaceGametype())
{
players[i].mo = NULL;
G_DoReborn(i);
}
else // gametype is GT_COOP or GT_RACE
{
players[i].mo = NULL;
G_SpawnPlayer(i, (players[i].starposttime));
}
}
}
if (modeattacking == ATTACKING_RECORD && !demo.playback)
P_LoadRecordGhosts();
if (G_TagGametype())
{
INT32 realnumplayers = 0;
INT32 playersactive[MAXPLAYERS];
//I just realized how problematic this code can be.
//D_NumPlayers() will not always cover the scope of the netgame.
//What if one player is node 0 and the other node 31?
//The solution? Make a temp array of all players that are currently playing and pick from them.
//Future todo? When a player leaves, shift all nodes down so D_NumPlayers() can be used as intended?
//Also, you'd never have to loop through all 32 players slots to find anything ever again.
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && !players[i].spectator)
{
playersactive[realnumplayers] = i; //stores the player's node in the array.
realnumplayers++;
}
}
if (realnumplayers) // this should also fix the dedicated crash bug. You only pick a player if one exists to be picked.
{
i = P_RandomKey(realnumplayers);
players[playersactive[i]].pflags |= PF_TAGIT; //choose our initial tagger before map starts.
// Taken and modified from G_DoReborn()
// Remove the player so he can respawn elsewhere.
// first dissasociate the corpse
if (players[playersactive[i]].mo)
P_RemoveMobj(players[playersactive[i]].mo);
G_SpawnPlayer(playersactive[i], false); //respawn the lucky player in his dedicated spawn location.
}
else
CONS_Printf(M_GetText("No player currently available to become IT. Awaiting available players.\n"));
}
else if (G_RaceGametype() && server)
{
INT32 numLaps = ((netgame || multiplayer) && cv_basenumlaps.value
&& (!(mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE)
|| (mapheaderinfo[gamemap - 1]->numlaps > cv_basenumlaps.value)))
? cv_basenumlaps.value
: mapheaderinfo[gamemap - 1]->numlaps;
CV_StealthSetValue(&cv_numlaps, numLaps);
}
P_InitGametype();
// Start recording replay in multiplayer with a temp filename
// Ensure dedis only record a replay if there is a player at the start of the map, otherwise we get invalid replays!
if (!demo.playback && multiplayer && D_NumPlayers())
{
static char buf[256];
sprintf(buf, "replay"PATHSEP"online"PATHSEP"%d-%s", (int) (time(NULL)), G_BuildMapName(gamemap));
sprintf(buf, "replay"PATHSEP"online"PATHSEP"%d-%s", (int)(time(NULL)), G_BuildMapName(gamemap));
I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755);
I_mkdir(va("%s"PATHSEP"replay"PATHSEP"online", srb2home), 0755);
@@ -2633,9 +2956,10 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
// 99% of the things already did, so.
// Map header should always be in place at this point
INT32 i;
UINT8 levelfadecol;
boolean ranspecialwipe = false;
lumpnum_t encoreLump = LUMPERROR;
UINT8 levelfadecol;
const mapheader_t *mapheader = mapheaderinfo[gamemap - 1];
midgamejoin = fromnetsave; // makes dynslopes run in P_Ticker to avoid synch issues and other stuff
@@ -2643,7 +2967,7 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
levelloading = true;
// This is needed. Don't touch.
maptol = mapheaderinfo[gamemap-1]->typeoflevel;
maptol = mapheader->typeoflevel;
CON_Drawer(); // let the user know what we are going to do
I_FinishUpdate(); // page flip or blit buffer
@@ -2654,17 +2978,17 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
// Clear CECHO messages
HU_ClearCEcho();
if (mapheaderinfo[gamemap-1]->runsoc[0] != '#')
P_RunSOC(mapheaderinfo[gamemap-1]->runsoc);
if (mapheader->runsoc[0] != '#')
P_RunSOC(mapheader->runsoc);
if (cv_runscripts.value && mapheaderinfo[gamemap-1]->scriptname[0] != '#')
P_RunLevelScript(mapheaderinfo[gamemap-1]->scriptname);
if (cv_runscripts.value && mapheader->scriptname[0] != '#')
P_RunLevelScript(mapheader->scriptname);
P_LevelInitStuff(reloadinggamestate);
if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0'
&& atoi(mapheaderinfo[gamemap-1]->forcecharacter) != 255)
P_ForceCharacter(mapheaderinfo[gamemap-1]->forcecharacter);
if (mapheader->forcecharacter[0] != '\0'
&& atoi(mapheader->forcecharacter) != 255)
P_ForceCharacter(mapheader->forcecharacter);
// Initial height of PointOfView
// will be set by player think.
@@ -2714,10 +3038,10 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
char tx[64];
V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to..."));
snprintf(tx, 63, "%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(", Act %s",mapheaderinfo[gamemap-1]->actnum) : "");
mapheader->lvlttl,
(strlen(mapheader->zonttl) > 0) ? va(" %s",mapheader->zonttl) : // SRB2kart
((mapheader->levelflags & LF_NOZONE) ? "" : " Zone"),
(strlen(mapheader->actnum) > 0) ? va(", Act %s",mapheader->actnum) : "");
V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx);
I_UpdateNoVsync();
}*/
@@ -2736,20 +3060,16 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
curmapvirt = vres_GetMap(lastloadedmaplumpnum);
encoreLump = W_CheckNumForName(va("%s%c", maplumpname, (encoremode ? 'E' : 'T')));
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette, encoreLump);
R_ReInitColormaps(mapheader->palette, encoreLump);
CON_SetupBackColormap();
// SRB2 determines the sky texture to be used depending on the map header.
P_SetupLevelSky(mapheaderinfo[gamemap-1]->skynum, true);
P_SetupLevelSky(mapheader->skynum, true);
numdmstarts = numredctfstarts = numbluectfstarts = 0;
P_ResetSpawnpoints();
// reset the player starts
memset(playerstarts, 0, sizeof(playerstarts));
memset(skyboxmo, 0, sizeof(skyboxmo));
P_MapStart();
P_MapStart(); // tmthing can be used starting from this point
P_LoadMapFromFile();
@@ -2769,7 +3089,7 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
if (!playerstarts[numcoopstarts])
break;
globalweather = mapheaderinfo[gamemap-1]->weather;
globalweather = mapheader->weather;
// set up world state
P_SpawnSpecials(fromnetsave, reloadinggamestate);
@@ -2816,7 +3136,7 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
// clear special respawning que
iquehead = iquetail = 0;
P_MapEnd();
P_MapEnd(); // tmthing is no longer needed from this point onwards
// Remove the loading shit from the screen
if (rendermode != render_none && !reloadinggamestate)
@@ -2847,9 +3167,15 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
savedata.lives = 0;
}
// assume the skybox is visible on level load.
skyVisible = true;
memset(skyVisiblePerPlayer, true, sizeof(skyVisiblePerPlayer));
if (!reloadinggamestate)
{
// assume the skybox is visible on level load.
skyVisible = true;
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
skyVisiblePerPlayer[i] = true;
}
}
if (!fromnetsave) // uglier hack
{ // to make a newly loaded level start on the second frame.
@@ -2869,14 +3195,18 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
LUA_HookInt(gamemap, HOOK(MapLoad));
}
if (rendermode != render_none && !reloadinggamestate)
// reloading gamestate, stop here.
if (reloadinggamestate)
return true;
G_AddMapToBuffer(gamemap-1);
if (rendermode != render_none)
{
R_ResetViewInterpolation(0);
R_UpdateMobjInterpolators();
}
G_AddMapToBuffer(gamemap-1);
G_ResetDeviceLED();
return true;
@@ -2927,7 +3257,7 @@ static size_t sreplaces = 0, mreplaces = 0, digmreplaces = 0;
static boolean P_CheckSoundReplacements(UINT16 wadnum, char *name, size_t i)
{
size_t j;
lumpnum_t lumpnum = (i|(wadnum<<16));
lumpnum_t lumpnum = (i | (wadnum<<16));
if (name[0] == 'D')
{
@@ -2935,8 +3265,8 @@ static boolean P_CheckSoundReplacements(UINT16 wadnum, char *name, size_t i)
{
for (j = 1; j < NUMSFX; j++)
{
if (S_sfx[j].name && !strnicmp(S_sfx[j].name, name + 2, 6)
&& (S_sfx[j].lumpnum != lumpnum) && (S_sfx[j].lumpnum != LUMPERROR))
if ((S_sfx[j].lumpnum != lumpnum) && (S_sfx[j].lumpnum != LUMPERROR) &&
S_sfx[j].name && !strnicmp(S_sfx[j].name, name + 2, 6))
{
// the sound will be reloaded when needed,
// since sfx->data will be NULL
@@ -3057,6 +3387,17 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
sreplaces = mreplaces = digmreplaces = 0;
if (local)
{
// check if someone tries to load maps locally lol
// do this here so we can skip loading the file anyways
if (W_CheckAutoLoadContainsMap(wadfilename))
{
CONS_Alert(CONS_WARNING, "addilelocal: locally added file %s contains map data, this WILL cause crashes and desynchs! not added.\n", wadfilename);
return UINT16_MAX;
}
}
if ((numlumps = W_InitFile(wadfilename, local, false)) == INT16_MAX)
{
refreshdirmenu |= REFRESHDIR_NOTLOADED;
@@ -3087,12 +3428,15 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
allvotereplaced = true;
}
if (!devparm && sreplaces)
CONS_Printf(M_GetText("%s sounds replaced\n"), sizeu1(sreplaces));
if (!devparm && mreplaces)
CONS_Printf(M_GetText("%s midi musics ignored\n"), sizeu1(mreplaces));
if (!devparm && digmreplaces)
CONS_Printf(M_GetText("%s digital musics replaced\n"), sizeu1(digmreplaces));
if (!devparm)
{
if (sreplaces)
CONS_Printf(M_GetText("%s sounds replaced\n"), sizeu1(sreplaces));
if (mreplaces)
CONS_Printf(M_GetText("%s midi musics ignored\n"), sizeu1(mreplaces));
if (digmreplaces)
CONS_Printf(M_GetText("%s digital musics replaced\n"), sizeu1(digmreplaces));
}
if (!mapsadded)
CONS_Printf(M_GetText("No maps added\n"));
+3
View File
@@ -114,6 +114,9 @@ size_t P_PrecacheLevelFlats(void);
void P_AllocMapHeader(INT16 i);
void P_PrintCorruptMapWarnings(void);
void P_FreeCorruptMapWarnings(void);
#ifdef __cplusplus
} // extern "C"
#endif
+40 -22
View File
@@ -31,8 +31,6 @@ typedef struct {
fixed_t bbox[4];
} los_t;
static INT32 sightcounts[2];
typedef INT32 (*divlinefunc)(fixed_t x, fixed_t y, const divline_t *node);
typedef INT32 (*divlinecrossfunc)(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, const divline_t *node);
@@ -73,7 +71,7 @@ static inline INT32 P_DivlineCrossedFast(fixed_t x1, fixed_t y1, fixed_t x2, fix
return (P_DivlineSideFast(x1, y1, node) == P_DivlineSideFast(x2, y2, node));
}
static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los)
static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los, boolean fast)
{
size_t i;
sector_t *polysec;
@@ -81,6 +79,8 @@ static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los)
if (!(po->flags & POF_RENDERALL))
return true; // the polyobject isn't visible, so we can ignore it
const divlinecrossfunc divlinecrossFunc = fast ? P_DivlineCrossedFast : P_DivlineCrossed;
polysec = po->lines[0]->backsector;
for (i = 0; i < po->numLines; ++i)
@@ -108,21 +108,21 @@ static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los)
v2 = line->v2;
// line isn't crossed?
if (P_DivlineCrossed(v1->x, v1->y, v2->x, v2->y, &los->strace))
if (divlinecrossFunc(v1->x, v1->y, v2->x, v2->y, &los->strace))
continue;
divl.dx = v2->x - (divl.x = v1->x);
divl.dy = v2->y - (divl.y = v1->y);
// line isn't crossed?
if (P_DivlineCrossed(los->strace.x, los->strace.y, los->t2x, los->t2y, &divl))
if (divlinecrossFunc(los->strace.x, los->strace.y, los->t2x, los->t2y, &divl))
continue;
frac = P_InterceptVector(&los->strace, &divl);
// get slopes of top and bottom of this polyobject line
topslope = FixedDiv(polysec->ceilingheight - los->sightzstart , frac);
bottomslope = FixedDiv(polysec->floorheight - los->sightzstart , frac);
topslope = FixedDiv(polysec->ceilingheight - los->sightzstart, frac);
bottomslope = FixedDiv(polysec->floorheight - los->sightzstart, frac);
if (topslope >= los->topslope && bottomslope <= los->bottomslope)
return false; // view completely blocked
@@ -147,6 +147,8 @@ static boolean P_CrossSubsector(size_t num, register los_t *los, boolean fast)
I_Error("P_CrossSubsector: ss %s with numss = %s\n", sizeu1(num), sizeu2(numsubsectors));
#endif
const divlinecrossfunc divlinecrossFunc = fast ? P_DivlineCrossedFast : P_DivlineCrossed;
// haleyjd 02/23/06: this assignment should be after the above check
seg = segs + subsectors[num].firstline;
@@ -158,15 +160,13 @@ static boolean P_CrossSubsector(size_t num, register los_t *los, boolean fast)
if (po->validcount != validcount)
{
po->validcount = validcount;
if (!P_CrossSubsecPolyObj(po, los))
if (!P_CrossSubsecPolyObj(po, los, fast))
return false;
}
po = (polyobj_t *)(po->link.next);
}
}
const divlinecrossfunc divlinecrossFunc = fast ? P_DivlineCrossedFast : P_DivlineCrossed;
for (count = subsectors[num].numlines; --count >= 0; seg++) // check lines
{
line_t *line = seg->linedef;
@@ -214,14 +214,17 @@ static boolean P_CrossSubsector(size_t num, register los_t *los, boolean fast)
front = seg->frontsector;
back = seg->backsector;
// calculate position at intercept
fracx = los->strace.x + FixedMul(los->strace.dx, frac);
fracy = los->strace.y + FixedMul(los->strace.dy, frac);
// calculate sector heights
frontf = P_GetSectorFloorZAt (front, fracx, fracy);
frontc = P_GetSectorCeilingZAt(front, fracx, fracy);
backf = P_GetSectorFloorZAt (back , fracx, fracy);
backc = P_GetSectorCeilingZAt(back , fracx, fracy);
// crosses a two sided line
// no wall to block sight with?
if (frontf == backf && frontc == backc
@@ -262,6 +265,7 @@ static boolean P_CrossSubsector(size_t num, register los_t *los, boolean fast)
ffloor_t *rover;
fixed_t topslope, bottomslope;
fixed_t topz, bottomz;
// check front sector's FOFs first
for (rover = front->ffloors; rover; rover = rover->next)
{
@@ -275,9 +279,11 @@ static boolean P_CrossSubsector(size_t num, register los_t *los, boolean fast)
bottomz = P_GetFFloorBottomZAt(rover, fracx, fracy);
topslope = FixedDiv( topz - los->sightzstart, frac);
bottomslope = FixedDiv(bottomz - los->sightzstart, frac);
if (topslope >= los->topslope && bottomslope <= los->bottomslope)
return false; // view completely blocked
}
// check back sector's FOFs as well
for (rover = back->ffloors; rover; rover = rover->next)
{
@@ -291,6 +297,7 @@ static boolean P_CrossSubsector(size_t num, register los_t *los, boolean fast)
bottomz = P_GetFFloorBottomZAt(rover, fracx, fracy);
topslope = FixedDiv( topz - los->sightzstart, frac);
bottomslope = FixedDiv(bottomz - los->sightzstart, frac);
if (topslope >= los->topslope && bottomslope <= los->bottomslope)
return false; // view completely blocked
}
@@ -315,10 +322,10 @@ static boolean P_CrossBSPNode(INT32 bspnum, register los_t *los, boolean fast)
while (!(bspnum & NF_SUBSECTOR))
{
register node_t *bsp = nodes + bspnum;
register const node_t *bsp = nodes + bspnum;
INT32 side = divlineFunc(los->strace.x, los->strace.y, (divline_t *)bsp) & 1;
INT32 side2 = divlineFunc(los->t2x, los->t2y, (divline_t *) bsp);
INT32 side = divlineFunc(los->strace.x, los->strace.y, (const divline_t *)bsp) & 1;
INT32 side2 = divlineFunc(los->t2x, los->t2y, (const divline_t *)bsp);
if (side == side2)
{
@@ -357,8 +364,10 @@ boolean P_CheckSight2(mobj_t *t1, mobj_t *t2, boolean fast)
I_Assert(!P_MobjWasRemoved(t2));
if (!t1->subsector || !t2->subsector
|| !t1->subsector->sector || !t2->subsector->sector)
|| !t1->subsector->sector || !t2->subsector->sector)
{
return false;
}
s1 = t1->subsector->sector;
s2 = t2->subsector->sector;
@@ -368,7 +377,9 @@ boolean P_CheckSight2(mobj_t *t1, mobj_t *t2, boolean fast)
{
// Check in REJECT table.
if (rejectmatrix[pnum>>3] & (1 << (pnum&7))) // can't possibly be connected
{
return false;
}
}
// killough 11/98: shortcut for melee situations
@@ -376,11 +387,9 @@ boolean P_CheckSight2(mobj_t *t1, mobj_t *t2, boolean fast)
// haleyjd 02/23/06: can't do this if there are polyobjects in the subsec
if (!t1->subsector->polyList &&
t1->subsector == t2->subsector)
{
return true;
// An unobstructed LOS is possible.
// Now look from eyes of t1 to any part of t2.
sightcounts[1]++;
}
validcount++;
@@ -423,21 +432,30 @@ boolean P_CheckSight2(mobj_t *t1, mobj_t *t2, boolean fast)
continue;
}
topz1 = P_GetFFloorTopZAt (rover, t1->x, t1->y);
// Check for blocking floors here.
topz2 = P_GetFFloorTopZAt (rover, t2->x, t2->y);
bottomz1 = P_GetFFloorBottomZAt(rover, t1->x, t1->y);
if (los.sightzstart < bottomz1 && t2->z >= topz2)
{
// no way to see through that
return false;
}
topz1 = P_GetFFloorTopZAt (rover, t1->x, t1->y);
bottomz2 = P_GetFFloorBottomZAt(rover, t2->x, t2->y);
// Check for blocking floors here.
if ((los.sightzstart < bottomz1 && t2->z >= topz2)
|| (los.sightzstart >= topz1 && t2->z + t2->height < bottomz2))
if (los.sightzstart >= topz1 && t2->z + t2->height < bottomz2)
{
// no way to see through that
return false;
}
if (rover->flags & FF_SOLID)
{
continue; // shortcut since neither mobj can be inside the 3dfloor
}
if (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))
{
+7
View File
@@ -664,8 +664,10 @@ static pslope_t *P_NewVertexSlope(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flag
for (i = 0; i < 3; i++)
{
mt = ret->vertices[i];
if (!mt) // If a vertex wasn't found, it's game over. There's nothing you can do to recover (except maybe try and kill the slope instead - TODO?)
I_Error("P_NewVertexSlope: Slope vertex %s (for linedef tag %d) not found!", sizeu1(i), tag1);
if (mt->extrainfo)
mt->z = mt->options;
else
@@ -899,6 +901,11 @@ void P_SlopeLaunch(mobj_t *mo)
//CONS_Printf("Launched off of slope.\n");
mo->standingslope = NULL;
if (mo->player)
{
mo->player->stairjank = 0; // fuck you
}
}
// Function to help handle landing on slopes
+227 -129
View File
@@ -538,6 +538,7 @@ static sector_t *getNextSector(line_t *line, sector_t *sec)
else
return NULL;
}
return line->frontsector;
}
@@ -568,6 +569,7 @@ fixed_t P_FindLowestFloorSurrounding(sector_t *sec)
if (other->floorheight < floorh)
floorh = other->floorheight;
}
return floorh;
}
@@ -881,7 +883,7 @@ static boolean PolyDoor(line_t *line)
pdd.polyObjNum = line->tag; // polyobject id
switch(line->special)
switch (line->special)
{
case 480: // Polyobj_DoorSlide
pdd.doorType = POLY_DOOR_SLIDE;
@@ -889,7 +891,7 @@ static boolean PolyDoor(line_t *line)
pdd.angle = line->angle; // angle of motion
pdd.distance = sides[line->sidenum[0]].rowoffset;
if (line->sidenum[1] != 0xffff)
if (line->sidenum[1] != NO_INDEX)
pdd.delay = sides[line->sidenum[1]].textureoffset >> FRACBITS; // delay in tics
else
pdd.delay = 0;
@@ -899,7 +901,7 @@ static boolean PolyDoor(line_t *line)
pdd.speed = sides[line->sidenum[0]].textureoffset >> FRACBITS; // angular speed
pdd.distance = sides[line->sidenum[0]].rowoffset >> FRACBITS; // angular distance
if (line->sidenum[1] != 0xffff)
if (line->sidenum[1] != NO_INDEX)
pdd.delay = sides[line->sidenum[1]].textureoffset >> FRACBITS; // delay in tics
else
pdd.delay = 0;
@@ -1180,7 +1182,7 @@ INT32 P_FindMinSurroundingLight(sector_t *sector, INT32 max)
for (i = 0; i < sector->linecount; i++)
{
line = sector->lines[i];
check = getNextSector(line,sector);
check = getNextSector(line, sector);
if (!check)
continue;
@@ -1234,7 +1236,6 @@ static void P_AddExecutorDelay(line_t *line, mobj_t *mobj, sector_t *sector)
boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller)
{
sector_t *ctlsector;
fixed_t dist = P_AproxDistance(triggerline->dx, triggerline->dy)>>FRACBITS;
size_t i, linecnt, sectori;
INT16 specialtype = triggerline->special;
//fromlapexec = false;
@@ -1272,6 +1273,8 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
rings = actor->health-1;
}
const fixed_t dist = P_AproxDistance(triggerline->dx, triggerline->dy)>>FRACBITS;
if (triggerline->flags & ML_NOCLIMB)
{
if (rings > dist)
@@ -1293,7 +1296,6 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
msecnode_t *node;
mobj_t *mo;
INT32 numpush = 0;
INT32 numneeded = dist;
if (!caller)
return false; // we need a calling sector to find pushables in, silly!
@@ -1308,6 +1310,8 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
node = node->m_thinglist_next;
}
const fixed_t numneeded = P_AproxDistance(triggerline->dx, triggerline->dy)>>FRACBITS;
if (triggerline->flags & ML_NOCLIMB) // Need at least or more
{
if (numpush < numneeded)
@@ -1336,6 +1340,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
else if (secspecial == 7) // SRB2Kart: reusing for Race Lap executor
{
UINT8 lap;
INT32 targlap;
if (actor && actor->player && triggerline->flags & ML_EFFECT4)
{
@@ -1346,19 +1351,21 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
lap = P_FindLowestLap();
}
targlap = (INT32)(sides[triggerline->sidenum[0]].textureoffset >> FRACBITS);
if (triggerline->flags & ML_NOCLIMB) // Need higher than or equal to
{
if (lap < (sides[triggerline->sidenum[0]].textureoffset >> FRACBITS))
if (lap < targlap)
return false;
}
else if (triggerline->flags & ML_BLOCKMONSTERS) // Need lower than or equal to
{
if (lap > (sides[triggerline->sidenum[0]].textureoffset >> FRACBITS))
if (lap > targlap)
return false;
}
else // Need equal to
{
if (lap != (sides[triggerline->sidenum[0]].textureoffset >> FRACBITS))
if (lap != targlap)
return false;
}
@@ -1450,6 +1457,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
if (triggerline->flags & ML_EFFECT5) // disregard order for efficiency
{
for (i = 0; i < linecnt; i++)
{
if (ctlsector->lines[i]->special >= 400
&& ctlsector->lines[i]->special < 500)
{
@@ -1458,6 +1466,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
else
P_ProcessLineSpecial(ctlsector->lines[i], actor, caller);
}
}
}
else // walk around the sector in a defined order
{
@@ -1465,11 +1474,13 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
size_t j, masterlineindex = (size_t)-1;
for (i = 0; i < linecnt; i++)
{
if (ctlsector->lines[i] == triggerline)
{
masterlineindex = i;
break;
}
}
#ifdef PARANOIA
if (masterlineindex == (size_t)-1)
@@ -1488,11 +1499,13 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
{
if (i == j)
continue;
if (ctlsector->lines[i]->v1 == ctlsector->lines[j]->v2)
{
i = j;
break;
}
if (ctlsector->lines[i]->v1 == ctlsector->lines[j]->v1)
{
i = j;
@@ -1500,6 +1513,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
break;
}
}
if (j == linecnt)
{
const size_t vertexei = (size_t)(ctlsector->lines[i]->v1 - vertexes);
@@ -1514,11 +1528,13 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
{
if (i == j)
continue;
if (ctlsector->lines[i]->v2 == ctlsector->lines[j]->v1)
{
i = j;
break;
}
if (ctlsector->lines[i]->v2 == ctlsector->lines[j]->v2)
{
i = j;
@@ -1595,19 +1611,21 @@ void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller)
if (lines[masterline].tag != tag)
continue;
const INT16 specialtype = lines[masterline].special;
// "No More Enemies" and "Level Load" take care of themselves.
if (lines[masterline].special == 313
|| lines[masterline].special == 399
|| lines[masterline].special == 328
|| lines[masterline].special == 323
if (specialtype == 313
|| specialtype == 399
|| specialtype == 328
|| specialtype == 323
// Each-time executors handle themselves, too
|| lines[masterline].special == 301 // Each time
|| lines[masterline].special == 306 // Character ability - Each time
|| lines[masterline].special == 310 // CTF Red team - Each time
|| lines[masterline].special == 312 // CTF Blue team - Each time
|| lines[masterline].special == 322 // Trigger on X calls - Each Time
|| lines[masterline].special < 300
|| lines[masterline].special > 399)
|| specialtype == 301 // Each time
|| specialtype == 306 // Character ability - Each time
|| specialtype == 310 // CTF Red team - Each time
|| specialtype == 312 // CTF Blue team - Each time
|| specialtype == 322 // Trigger on X calls - Each Time
|| specialtype < 300
|| specialtype > 399)
continue;
if (!P_RunTriggerLinedef(&lines[masterline], actor, caller))
@@ -1973,8 +1991,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
INT32 position = (INT32)max(sides[line->sidenum[0]].midtexture, 0);
UINT32 prefadems = (UINT32)max(sides[line->sidenum[0]].textureoffset >> FRACBITS, 0);
UINT32 postfadems = (UINT32)max(sides[line->sidenum[0]].rowoffset >> FRACBITS, 0);
UINT8 fadetarget = (UINT8)max((line->sidenum[1] != 0xffff) ? sides[line->sidenum[1]].textureoffset >> FRACBITS : 0, 0);
INT16 fadesource = (INT16)max((line->sidenum[1] != 0xffff) ? sides[line->sidenum[1]].rowoffset >> FRACBITS : -1, -1);
UINT8 fadetarget = (UINT8)max((line->sidenum[1] != NO_INDEX) ? sides[line->sidenum[1]].textureoffset >> FRACBITS : 0, 0);
INT16 fadesource = (INT16)max((line->sidenum[1] != NO_INDEX) ? sides[line->sidenum[1]].rowoffset >> FRACBITS : -1, -1);
// Seek offset from current song position
if (line->flags & ML_EFFECT1)
@@ -2082,7 +2100,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
ffloor_t *rover;
boolean foundit = false;
for(rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
{
if (rover->master->frontsector->tag != line->tag)
continue;
@@ -2419,7 +2437,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
P_SetPlayerMobjState(mo, S_KART_STND1); // SRB2kart - was S_PLAY_STND
// Reset bot too.
if (bot) {
if (bot)
{
if (line->flags & ML_NOCLIMB)
P_SetOrigin(bot, mo->x, mo->y, mo->z);
bot->momx = bot->momy = bot->momz = 1;
@@ -2487,7 +2506,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
var1 = sides[line->sidenum[0]].toptexture; //(line->dx>>FRACBITS)-1;
if (line->sidenum[1] != 0xffff && line->flags & ML_BLOCKMONSTERS) // read power from back sidedef
if (line->sidenum[1] != NO_INDEX && line->flags & ML_BLOCKMONSTERS) // read power from back sidedef
var2 = sides[line->sidenum[1]].toptexture;
else if (line->flags & ML_NOCLIMB) // 'Infinite'
var2 = UINT16_MAX;
@@ -2502,6 +2521,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
P_SetTarget(&dummy->target, bot);
A_CustomPower(dummy);
}
P_RemoveMobj(dummy);
}
break;
@@ -2565,11 +2585,15 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
if (mo && mo->player)
{
UINT16 fractime = (UINT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS);
if (fractime < 1)
fractime = 1; //instantly wears off upon leaving
if (line->flags & ML_NOCLIMB)
fractime |= 1<<15; //more crazy &ing, as if music stuff wasn't enough
mo->player->powers[pw_nocontrol] = fractime;
if (bot)
bot->player->powers[pw_nocontrol] = fractime;
}
@@ -2579,8 +2603,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
if (mo)
{
mo->destscale = FixedDiv(P_AproxDistance(line->dx, line->dy), 100<<FRACBITS);
if (mo->destscale < FRACUNIT/100)
mo->destscale = FRACUNIT/100;
if (mo->player && bot)
bot->destscale = mo->destscale;
}
@@ -2609,7 +2635,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
if (always || this->bottomtexture)
this->bottomtexture = set->bottomtexture;
if (lines[linenum].sidenum[1] == 0xffff)
if (lines[linenum].sidenum[1] == NO_INDEX)
continue; // One-sided stops here.
// Back side
@@ -2658,16 +2684,18 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
sector_t *sec;
mobj_t *thing;
if (line->sidenum[1] != 0xffff)
if (line->sidenum[1] != NO_INDEX)
state = (statenum_t)sides[line->sidenum[1]].toptexture;
while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0)
{
boolean tryagain;
sec = sectors + secnum;
do {
tryagain = false;
for (thing = sec->thinglist; thing; thing = thing->snext)
{
if (thing->type == type)
{
if (state != NUMSTATES)
@@ -2684,6 +2712,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
break;
}
}
}
} while (tryagain);
}
break;
@@ -2961,10 +2990,10 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
{
fixed_t topheight, bottomheight;
if (GETSECSPECIAL(rover->master->frontsector->special, section) != number)
if (!(rover->flags & FF_EXISTS))
continue;
if (!(rover->flags & FF_EXISTS))
if (GETSECSPECIAL(rover->master->frontsector->special, section) != number)
continue;
topheight = P_GetSpecialTopZ(player->mo, sectors + rover->secnum, player->mo->subsector->sector);
@@ -3259,6 +3288,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
case 3: // Linedef executor requires all players present // Trigger Linedef Exec (Floor Touch, All Players)
/// \todo check continues for proper splitscreen support?
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && !players[i].bot && players[i].mo && (gametype != GT_COOP || players[i].lives > 0))
{
if (roversector)
@@ -3312,6 +3342,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
goto DoneSection2;
}
}
}
/* FALLTHRU */
case 4: // Linedef executor that doesn't require touching floor // Trigger Linedef Exec (Anywhere in Sector)
case 5: // Linedef executor // Trigger Linedef Exec (Floor Touch)
@@ -3385,14 +3416,16 @@ DoneSection2:
{
const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale);
const fixed_t minspeed = 24*hscale;
angle_t pushangle = FixedHypot(player->mo->momx, player->mo->momy) ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle;
// if we have no speed for SOME REASON, use the player's angle, otherwise we'd be forcefully thrusted to what I can only assume is angle 0
if (player->mo->eflags & MFE_SPRUNG)
break;
if (player->speed < minspeed) // Push forward to prevent getting stuck
{
// if we have no speed for SOME REASON, use the player's angle, otherwise we'd be forcefully thrusted to what I can only assume is angle 0
const angle_t pushangle = FixedHypot(player->mo->momx, player->mo->momy) ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle;
P_InstaThrust(player->mo, pushangle, minspeed);
}
player->kartstuff[k_pogospring] = 1;
K_DoPogoSpring(player->mo, 0, 1);
@@ -3408,16 +3441,22 @@ DoneSection2:
const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale);
const fixed_t minspeed = 24*hscale;
const fixed_t maxspeed = 28*hscale;
angle_t pushangle = FixedHypot(player->mo->momx, player->mo->momy) ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle;
// if we have no speed for SOME REASON, use the player's angle, otherwise we'd be forcefully thrusted to what I can only assume is angle 0
if (player->mo->eflags & MFE_SPRUNG)
break;
if (player->speed > maxspeed) // Prevent overshooting jumps
{
// if we have no speed for SOME REASON, use the player's angle, otherwise we'd be forcefully thrusted to what I can only assume is angle 0
const angle_t pushangle = FixedHypot(player->mo->momx, player->mo->momy) ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle;
P_InstaThrust(player->mo, pushangle, maxspeed);
}
else if (player->speed < minspeed) // Push forward to prevent getting stuck
{
// if we have no speed for SOME REASON, use the player's angle, otherwise we'd be forcefully thrusted to what I can only assume is angle 0
const angle_t pushangle = FixedHypot(player->mo->momx, player->mo->momy) ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle;
P_InstaThrust(player->mo, pushangle, minspeed);
}
player->kartstuff[k_pogospring] = 2;
K_DoPogoSpring(player->mo, 0, 1);
@@ -3436,11 +3475,14 @@ DoneSection2:
if (i != -1)
{
INT32 sfxnum;
angle_t lineangle;
fixed_t linespeed;
lineangle = lines[i].angle;
linespeed = P_AproxDistance(lines[i].v2->x-lines[i].v1->x, lines[i].v2->y-lines[i].v1->y);
const line_t *line = &lines[i];
lineangle = line->angle;
linespeed = P_AproxDistance(line->v2->x-line->v1->x, line->v2->y-line->v1->y);
player->mo->angle = lineangle;
@@ -3454,7 +3496,7 @@ DoneSection2:
P_ForceLocalAngle(player, player->mo->angle);
}
if (!(lines[i].flags & ML_EFFECT4))
if (!(line->flags & ML_EFFECT4))
{
P_UnsetThingPosition(player->mo);
if (roversector) // make FOF speed pads work
@@ -3476,7 +3518,14 @@ DoneSection2:
player->kartstuff[k_drift] = 0;
player->kartstuff[k_driftcharge] = 0;
player->kartstuff[k_pogospring] = 0;
S_StartSound(player->mo, sfx_spdpad);
sfxnum = sides[line->sidenum[0]].toptexture;
// none or invalid sound?
if (sfxnum <= sfx_None || sfxnum >= NUMSFX)
sfxnum = sfx_spdpad; // use the zippy sound then!
S_StartSound(player->mo, sfxnum);
{
sfxenum_t pick = P_RandomKey(2); // Gotta roll the RNG every time this is called for sync reasons
@@ -3525,21 +3574,25 @@ DoneSection2:
P_DoPlayerExit(player);
P_SetupSignExit(player);
// important: use sector->tag on next line instead of player->mo->subsector->tag
// this part is different from in P_PlayerThink, this is what was causing
// FOF custom exits not to work.
lineindex = P_FindSpecialLineFromTag(2, sector->tag, -1);
if (gametype == GT_COOP && lineindex != -1) // Custom exit!
if (gametype == GT_COOP)
{
// Special goodies with the block monsters flag depending on emeralds collected
if ((lines[lineindex].flags & ML_BLOCKMONSTERS) && ALL7EMERALDS(emeralds))
nextmapoverride = (INT16)(lines[lineindex].frontsector->ceilingheight>>FRACBITS);
else
nextmapoverride = (INT16)(lines[lineindex].frontsector->floorheight>>FRACBITS);
// important: use sector->tag on next line instead of player->mo->subsector->tag
// this part is different from in P_PlayerThink, this is what was causing
// FOF custom exits not to work.
lineindex = P_FindSpecialLineFromTag(2, sector->tag, -1);
if (lines[lineindex].flags & ML_NOCLIMB)
skipstats = true;
if (lineindex != -1) // Custom exit!)
{
// Special goodies with the block monsters flag depending on emeralds collected
if ((lines[lineindex].flags & ML_BLOCKMONSTERS) && ALL7EMERALDS(emeralds))
nextmapoverride = (INT16)(lines[lineindex].frontsector->ceilingheight>>FRACBITS);
else
nextmapoverride = (INT16)(lines[lineindex].frontsector->floorheight>>FRACBITS);
if (lines[lineindex].flags & ML_NOCLIMB)
skipstats = true;
}
}
}
break;
@@ -3645,7 +3698,6 @@ DoneSection2:
thinker_t *th;
mobj_t *waypoint = NULL;
mobj_t *mo2;
angle_t an;
if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT)
break;
@@ -3693,10 +3745,13 @@ DoneSection2:
CONS_Debug(DBG_GAMELOGIC, "Waypoint %d found in sequence %d - speed = %d\n", waypoint->health, sequence, speed);
}
an = R_PointToAngle2(player->mo->x, player->mo->y, waypoint->x, waypoint->y) - player->mo->angle;
if (!(lines[lineindex].flags & ML_EFFECT4))
{
const angle_t an = R_PointToAngle2(player->mo->x, player->mo->y, waypoint->x, waypoint->y) - player->mo->angle;
if (an > ANGLE_90 && an < ANGLE_270 && !(lines[lineindex].flags & ML_EFFECT4))
break; // behind back
if (an > ANGLE_90 && an < ANGLE_270)
break; // behind back
}
P_SetTarget(&player->mo->tracer, waypoint);
player->speed = speed;
@@ -3718,7 +3773,6 @@ DoneSection2:
thinker_t *th;
mobj_t *waypoint = NULL;
mobj_t *mo2;
angle_t an;
if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT)
break;
@@ -3766,10 +3820,13 @@ DoneSection2:
CONS_Debug(DBG_GAMELOGIC, "Waypoint %d found in sequence %d - speed = %d\n", waypoint->health, sequence, speed);
}
an = R_PointToAngle2(player->mo->x, player->mo->y, waypoint->x, waypoint->y) - player->mo->angle;
if (!(lines[lineindex].flags & ML_EFFECT4))
{
const angle_t an = R_PointToAngle2(player->mo->x, player->mo->y, waypoint->x, waypoint->y) - player->mo->angle;
if (an > ANGLE_90 && an < ANGLE_270 && !(lines[lineindex].flags & ML_EFFECT4))
break; // behind back
if (an > ANGLE_90 && an < ANGLE_270)
break; // behind back
}
P_SetTarget(&player->mo->tracer, waypoint);
player->speed = speed;
@@ -3783,10 +3840,13 @@ DoneSection2:
case 10: // Finish Line
// SRB2kart - 150117
if (G_RaceGametype() && (player->starpostnum >= (numstarposts - (numstarposts/2)) || player->exiting))
if (!G_RaceGametype())
break;
if (player->starpostnum >= (numstarposts - (numstarposts/2)) || player->exiting)
player->kartstuff[k_starpostwp] = player->kartstuff[k_waypoint] = 0;
//
if (G_RaceGametype() && !player->exiting)
if (!player->exiting)
{
if (player->starpostnum >= (numstarposts - (numstarposts/2))) // srb2kart: must have touched *enough* starposts (was originally "(player->starpostnum == numstarposts)")
{
@@ -4503,27 +4563,13 @@ void P_PlayerInSpecialSector(player_t *player)
#undef TELEPORTED
/** Animate planes, scroll walls, etc. and keeps track of level timelimit and exits if time is up.
*
* \sa P_CheckTimeLimit, P_CheckPointLimit
*/
void P_UpdateSpecials(void)
static void P_UpdateAnimFlats(void)
{
anim_t *anim;
INT32 i;
size_t j;
levelflat_t *foundflats; // for flat animation
// LEVEL TIMER
P_CheckTimeLimit();
// POINT LIMIT
P_CheckPointLimit();
// Dynamic slopeness
if (!midgamejoin) // run here when not joined midgame to prevent any potential issues that may arise
P_RunDynamicSlopes();
// ANIMATE TEXTURES
for (anim = anims; anim < lastanim; anim++)
{
@@ -4553,15 +4599,40 @@ void P_UpdateSpecials(void)
}
}
/** Animate planes, scroll walls, etc. and keeps track of level timelimit and exits if time is up.
*
* \sa P_CheckTimeLimit, P_CheckPointLimit
*/
void P_UpdateSpecials(void)
{
// LEVEL TIMER
P_CheckTimeLimit();
// POINT LIMIT
P_CheckPointLimit();
#ifdef COMPAT_VANILLA
// Dynamic slopeness
// we run this here only when not joined midrace
// for vanilla compat reasons :chaosleep:
if (!midgamejoin)
P_RunDynamicSlopes();
#endif
P_UpdateAnimFlats();
}
static inline ffloor_t *P_GetFFloorBySec(sector_t *sec, sector_t *sec2)
{
ffloor_t *rover;
if (!sec->ffloors)
return NULL;
for (rover = sec->ffloors; rover; rover = rover->next)
if (rover->secnum == (size_t)(sec2 - sectors))
return rover;
return NULL;
}
@@ -4612,6 +4683,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
if (sec == sec2)
return NULL; //Don't need a fake floor on a control sector.
if ((ffloor = (P_GetFFloorBySec(sec, sec2))))
return ffloor; // If this ffloor already exists, return it
@@ -4718,7 +4790,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
P_AddSpikeThinker(sec, (INT32)sec2num);
}
// Should this FOF have friction?
else if(th->function == (actionf_p1)T_Friction)
else if (th->function == (actionf_p1)T_Friction)
{
f = (friction_t *)th;
@@ -4726,7 +4798,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
Add_Friction(f->friction, f->movefactor, (INT32)(sec-sectors), f->affectee);
}
// Should this FOF have wind/current/pusher?
else if(th->function == (actionf_p1)T_Pusher)
else if (th->function == (actionf_p1)T_Pusher)
{
p = (pusher_t *)th;
@@ -5164,11 +5236,18 @@ void T_LaserFlash(laserthink_t *flash)
if (thing->health <= 0)
continue;
// thing is neither shootable nor an egg guard shield
if (!(thing->flags & MF_SHOOTABLE) && (thing->type != MT_EGGSHIELD))
continue;
top = P_GetSpecialTopZ(thing, sourcesec, sector);
if (thing->z >= top)
continue;
bottom = P_GetSpecialBottomZ(thing, sourcesec, sector);
if (thing->z >= top
|| thing->z + thing->height <= bottom)
if (thing->z + thing->height <= bottom)
continue;
if (thing->flags & MF_SHOOTABLE)
@@ -5262,7 +5341,7 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
continue;
// Process Section 1
switch(GETSECSPECIAL(sector->special, 1))
switch (GETSECSPECIAL(sector->special, 1))
{
case 5: // Spikes
P_AddSpikeThinker(sector, (INT32)(sector-sectors));
@@ -5274,7 +5353,7 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
}
// Process Section 2
switch(GETSECSPECIAL(sector->special, 2))
switch (GETSECSPECIAL(sector->special, 2))
{
case 10: // Time for special stage
sstimer = (sector->floorheight>>FRACBITS) * TICRATE + 6; // Time to finish
@@ -5287,7 +5366,7 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
}
// Process Section 4
switch(GETSECSPECIAL(sector->special, 4))
switch (GETSECSPECIAL(sector->special, 4))
{
case 10: // Circuit finish line
if (G_RaceGametype())
@@ -5323,11 +5402,13 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
// Allocate each list, and then zero the count so we can use it to track
// the end of the list as we add the thinkers
for (i = 0; i < numsectors; i++)
if(secthinkers[i].count > 0)
{
if (secthinkers[i].count > 0)
{
secthinkers[i].thinkers = Z_Malloc(secthinkers[i].count * sizeof(thinker_t *), PU_STATIC, NULL);
secthinkers[i].count = 0;
}
}
// Finally, populate the lists.
for (th = thinkercap.next; th != &thinkercap; th = th->next)
@@ -5407,6 +5488,7 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
if ((lines[i].flags & (ML_NOSONIC|ML_NOTAILS)) != (ML_NOSONIC|ML_NOTAILS)) // If you can do something...
{
angle_t flatangle = InvAngle(lines[i].angle);
fixed_t xoffs;
fixed_t yoffs;
@@ -5979,7 +6061,7 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
break;
case 259: // Make-Your-Own FOF!
if (lines[i].sidenum[1] != 0xffff)
if (lines[i].sidenum[1] != NO_INDEX)
{
UINT8 *data;
UINT16 b;
@@ -6426,15 +6508,19 @@ void T_Scroll(scroll_t *s)
if (thing->flags2 & MF2_PUSHED) // Already pushed this tic by an exclusive pusher.
continue;
height = P_GetSpecialBottomZ(thing, sec, psec);
if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped
if (!(thing->flags & MF_NOGRAVITY || thing->z+thing->height != height)) // Thing must a) be non-floating and have z+height == height
{
// Move objects only if on floor
// non-floating, and clipped.
P_DoScrollMove(thing, dx, dy, s->exclusive);
height = P_GetSpecialBottomZ(thing, sec, psec);
if (!(thing->flags & MF_NOGRAVITY || thing->z+thing->height != height)) // Thing must a) be non-floating and have z+height == height
{
// Move objects only if on floor
// non-floating, and clipped.
P_DoScrollMove(thing, dx, dy, s->exclusive);
}
}
} // end of for loop through touching_thinglist
} // end of loop through sectors
}
@@ -6448,14 +6534,16 @@ void T_Scroll(scroll_t *s)
if (thing->flags2 & MF2_PUSHED)
continue;
height = P_GetSpecialBottomZ(thing, sec, sec);
if (!(thing->flags & MF_NOCLIP) &&
(!(thing->flags & MF_NOGRAVITY || thing->z > height)))
if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped
{
// Move objects only if on floor or underwater,
// non-floating, and clipped.
P_DoScrollMove(thing, dx, dy, s->exclusive);
height = P_GetSpecialBottomZ(thing, sec, sec);
if (!(thing->flags & MF_NOGRAVITY || thing->z > height))
{
// Move objects only if on floor or underwater,
// non-floating, and clipped.
P_DoScrollMove(thing, dx, dy, s->exclusive);
}
}
}
}
@@ -6501,14 +6589,16 @@ void T_Scroll(scroll_t *s)
if (thing->flags2 & MF2_PUSHED)
continue;
height = P_GetSpecialTopZ(thing, sec, psec);
if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped
if (!(thing->flags & MF_NOGRAVITY || thing->z != height))// Thing must a) be non-floating and have z == height
{
// Move objects only if on floor or underwater,
// non-floating, and clipped.
P_DoScrollMove(thing, dx, dy, s->exclusive);
height = P_GetSpecialTopZ(thing, sec, psec);
if (!(thing->flags & MF_NOGRAVITY || thing->z != height))// Thing must a) be non-floating and have z == height
{
// Move objects only if on floor or underwater,
// non-floating, and clipped.
P_DoScrollMove(thing, dx, dy, s->exclusive);
}
}
} // end of for loop through touching_thinglist
} // end of loop through sectors
@@ -6523,14 +6613,16 @@ void T_Scroll(scroll_t *s)
if (thing->flags2 & MF2_PUSHED)
continue;
height = P_GetSpecialTopZ(thing, sec, sec);
if (!(thing->flags & MF_NOCLIP) &&
(!(thing->flags & MF_NOGRAVITY || thing->z+thing->height < height)))
if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped
{
// Move objects only if on floor or underwater,
// non-floating, and clipped.
P_DoScrollMove(thing, dx, dy, s->exclusive);
height = P_GetSpecialTopZ(thing, sec, sec);
if (!(thing->flags & MF_NOGRAVITY || thing->z+thing->height < height))
{
// Move objects only if on floor or underwater,
// non-floating, and clipped.
P_DoScrollMove(thing, dx, dy, s->exclusive);
}
}
}
}
@@ -6698,7 +6790,7 @@ static void P_SpawnScrollers(void)
case 506:
s = lines[i].sidenum[1];
if (s != 0xffff)
if (s != NO_INDEX)
Add_Scroller(sc_side, -sides[s].textureoffset, sides[s].rowoffset, -1, lines[i].sidenum[0], accel, 0);
else
CONS_Debug(DBG_GAMELOGIC, "Line special 506 (line #%s) missing 2nd side!\n", sizeu1(i));
@@ -6909,6 +7001,7 @@ static void P_SpawnFriction(void)
INT32 movefactor; // applied to each player move to simulate inertia
for (i = 0; i < numlines; i++, l++)
{
if (l->special == 540)
{
//length = P_AproxDistance(l->dx, l->dy)>>FRACBITS;
@@ -6942,6 +7035,7 @@ static void P_SpawnFriction(void)
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
Add_Friction(friction, movefactor, s, -1);
}
}
}
/*
@@ -6990,9 +7084,10 @@ static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, mobj_t *
// "The right triangle of the square of the length of the hypotenuse is equal to the sum of the squares of the lengths of the other two sides."
// "Bah! Stupid brains! Don't you know anything besides the Pythagorean Theorem?" - Earthworm Jim
if (type == p_downcurrent || type == p_upcurrent || type == p_upwind || type == p_downwind)
p->magnitude = P_AproxDistance(p->x_mag,p->y_mag)<<(FRACBITS-PUSH_FACTOR);
p->magnitude = P_AproxDistance(p->x_mag, p->y_mag)<<(FRACBITS-PUSH_FACTOR);
else
p->magnitude = P_AproxDistance(p->x_mag,p->y_mag);
p->magnitude = P_AproxDistance(p->x_mag, p->y_mag);
if (source) // point source exist?
{
// where force goes to zero
@@ -7043,15 +7138,14 @@ static inline boolean PIT_PushThing(mobj_t *thing)
// don't fade wrt Z if health & 2 (mapthing has multi flag)
if (tmpusher->source->health & 2)
dist = P_AproxDistance(thing->x - sx,thing->y - sy);
dist = P_AproxDistance(thing->x - sx, thing->y - sy);
else
{
// Make sure the Z is in range
if (thing->z < sz - tmpusher->radius || thing->z > sz + tmpusher->radius)
return false;
dist = P_AproxDistance(P_AproxDistance(thing->x - sx, thing->y - sy),
thing->z - sz);
dist = P_AproxDistance(P_AproxDistance(thing->x - sx, thing->y - sy), thing->z - sz);
}
speed = (tmpusher->magnitude - ((dist>>FRACBITS)>>1))<<(FRACBITS - PUSH_FACTOR - 1);
@@ -7214,7 +7308,6 @@ void T_Pusher(pusher_t *p)
if (p->type == p_push)
{
// Seek out all pushable things within the force radius of this
// point pusher. Crosses sectors, so use blockmap.
@@ -7257,13 +7350,16 @@ void T_Pusher(pusher_t *p)
if (thing->flags2 & MF2_PUSHED)
continue;
if (thing->player && thing->player->pflags & PF_ROPEHANG)
continue;
if (thing->player)
{
if (thing->player->pflags & PF_ROPEHANG)
continue;
if (thing->player && (thing->state == &states[thing->info->painstate])
&& (thing->player->powers[pw_flashing] > (K_GetKartFlashing(thing->player)/4)*3
&& thing->player->powers[pw_flashing] <= K_GetKartFlashing(thing->player)))
continue;
if ((thing->state == &states[thing->info->painstate])
&& (thing->player->powers[pw_flashing] > (K_GetKartFlashing(thing->player)/4)*3
&& thing->player->powers[pw_flashing] <= K_GetKartFlashing(thing->player)))
continue;
}
inFOF = touching = moved = false;
@@ -7393,7 +7489,7 @@ void T_Pusher(pusher_t *p)
if (p->slider && thing->player)
{
boolean jumped = (thing->player->pflags & PF_JUMPED);
P_ResetPlayer (thing->player);
P_ResetPlayer(thing->player);
if (jumped)
thing->player->pflags |= PF_JUMPED;
@@ -7461,16 +7557,17 @@ static void P_SpawnPushers(void)
mobj_t *thing;
for (i = 0; i < numlines; i++, l++)
{
switch (l->special)
{
case 541: // wind
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
Add_Pusher(p_wind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
break;
break;
case 544: // current
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
Add_Pusher(p_current, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
break;
break;
case 547: // push/pull
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
{
@@ -7482,20 +7579,21 @@ static void P_SpawnPushers(void)
case 545: // current up
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
Add_Pusher(p_upcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
break;
break;
case 546: // current down
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
Add_Pusher(p_downcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
break;
break;
case 542: // wind up
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
Add_Pusher(p_upwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
break;
break;
case 543: // wind down
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
Add_Pusher(p_downwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
break;
break;
}
}
}
void P_StartQuake(tic_t time, fixed_t intensity, fixed_t radius)
+18 -1
View File
@@ -38,6 +38,8 @@
#include "i_video.h" // rendermode
#include "m_perfstats.h"
#include "lua_profile.h"
// Object place
#include "m_cheat.h"
@@ -611,8 +613,19 @@ void P_Ticker(boolean run)
#ifdef DEMO_COMPAT_100
}
#endif
// Lookback is normally handled inside G_BuildTiccmd, which isn't called in replays so we're doing that manually
// idk if this is best place to handle this tho...
for (i = 0; i <= splitscreen; ++i)
{
const boolean usejoystick = cv_usejoystick[i].value;
INT32 axis = JoyAxis(AXISLOOKBACK, i+1);
camspin[i] = (InputDown(gc_lookback, i+1) || (usejoystick && axis > 0));
}
}
LUA_ResetTicTimers();
ps_lua_mobjhooks.value.i = 0;
ps_checkposition_calls.value.i = 0;
@@ -620,6 +633,7 @@ void P_Ticker(boolean run)
LUA_HookPreThinkFrame();
PS_STOP_TIMING(ps_lua_prethinkframe_time);
// OK! Now that we got all of that sorted, players can think!
PS_START_TIMING(ps_playerthink_time);
for (i = 0; i < MAXPLAYERS; i++)
{
@@ -637,7 +651,9 @@ void P_Ticker(boolean run)
if (run)
{
// Dynamic slopeness
#ifdef COMPAT_VANILLA
if (midgamejoin) // only run here if we joined midgame to fix some desynchs
#endif
P_RunDynamicSlopes();
PS_START_TIMING(ps_thinkertime);
@@ -664,6 +680,7 @@ void P_Ticker(boolean run)
PS_STOP_TIMING(ps_lua_thinkframe_time);
}
// Run shield positioning
P_RunOverlays();
P_RunShadows();
@@ -785,7 +802,7 @@ void P_Ticker(boolean run)
if (!player->mo)
continue;
const boolean skybox = (skyboxmo[0] && cv_skybox.value);
const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on
if (skyVisiblePerPlayer[i] && skybox)
{
+32 -19
View File
@@ -1122,22 +1122,26 @@ void P_SpawnShieldOrb(player_t *player)
P_SetTarget(&ov->target, shieldobj);
P_SetMobjState(ov, shieldobj->info->seestate);
}
if (shieldobj->info->meleestate)
{
ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY);
P_SetTarget(&ov->target, shieldobj);
P_SetMobjState(ov, shieldobj->info->meleestate);
}
if (shieldobj->info->missilestate)
{
ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY);
P_SetTarget(&ov->target, shieldobj);
P_SetMobjState(ov, shieldobj->info->missilestate);
}
if (player->powers[pw_shield] & SH_FORCE)
{
//Copy and pasted from P_ShieldLook in p_mobj.c
shieldobj->movecount = (player->powers[pw_shield] & 0xFF);
if (shieldobj->movecount < 1)
{
if (shieldobj->info->painstate)
@@ -1202,6 +1206,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
ghost->pitch = mobj->pitch;
ghost->roll = mobj->roll;
ghost->rollangle = mobj->rollangle;
ghost->temprollangle = mobj->temprollangle;
ghost->sloperoll = mobj->sloperoll;
ghost->slopepitch = mobj->slopepitch;
@@ -1569,10 +1574,12 @@ static void P_CheckBouncySectors(player_t *player)
newmom = -8*FRACUNIT;
}
if (newmom > P_GetPlayerHeight(player)/2)
newmom = P_GetPlayerHeight(player)/2;
else if (newmom < -P_GetPlayerHeight(player)/2)
newmom = -P_GetPlayerHeight(player)/2;
const fixed_t halfpheight = P_GetPlayerHeight(player)/2;
if (newmom > halfpheight)
newmom = halfpheight;
else if (newmom < -halfpheight)
newmom = -halfpheight;
momentum.z = newmom*2;
@@ -1835,6 +1842,9 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range)
if (!((mo2->flags & MF_SHOOTABLE && mo2->flags & MF_ENEMY) || mo2->type == MT_EGGGUARD || mo2->player))
continue;
if (mo2->health <= 0)
continue;
dist = P_AproxDistance(P_AproxDistance(player->mo->x-mo2->x, player->mo->y-mo2->y), player->mo->z-mo2->z);
if (range < dist)
@@ -1843,15 +1853,12 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range)
if (!P_CheckSight(player->mo, mo2))
continue; // if your psychic powers can't "see" it don't bother
if (mo2->health > 0)
{
an = R_PointToAngle2(player->mo->x, player->mo->y, mo2->x, mo2->y);
an = R_PointToAngle2(player->mo->x, player->mo->y, mo2->x, mo2->y);
P_Thrust(mo2, an, thrust);
P_Thrust(mo2, an, thrust);
if (mo2->type == MT_GOLDBUZZ || mo2->type == MT_REDBUZZ)
mo2->tics += 8;
}
if (mo2->type == MT_GOLDBUZZ || mo2->type == MT_REDBUZZ)
mo2->tics += 8;
}
//P_SpawnThokMobj(player);
@@ -2355,7 +2362,7 @@ static void P_MovePlayer(player_t *player)
if (onground && leveltime % 50 == 0 && player->kartstuff[k_drift] != 0)
S_StartSound(player->mo, sfx_drift);
// Leveltime being 50 might take a while at times. We'll start it up once, isntantly.
else if (onground && !S_SoundPlaying(player->mo, sfx_drift) && player->kartstuff[k_drift] != 0)
else if (onground && player->kartstuff[k_drift] != 0 && !S_SoundPlaying(player->mo, sfx_drift))
S_StartSound(player->mo, sfx_drift);
// Ok, we'll stop now.
else if (player->kartstuff[k_drift] == 0 || !onground)
@@ -2736,16 +2743,16 @@ boolean P_LookForEnemies(player_t *player)
|| ((mo->z+mo->height < player->mo->z+player->mo->height-FixedMul(MAXSTEPMOVE, mapobjectscale)) && (player->mo->eflags & MFE_VERTICALFLIP))) // Reverse gravity check - Flame.
continue; // Don't home upwards!
if (P_AproxDistance(P_AproxDistance(player->mo->x-mo->x, player->mo->y-mo->y),
player->mo->z-mo->z) > FixedMul(RING_DIST, player->mo->scale))
const fixed_t modist = P_AproxDistance(P_AproxDistance(player->mo->x-mo->x, player->mo->y-mo->y), player->mo->z-mo->z);
if (modist > FixedMul(RING_DIST, player->mo->scale))
continue; // out of range
if (UNLIKELY((twodlevel || player->mo->flags2 & MF2_TWOD)
&& abs(player->mo->y-mo->y) > player->mo->radius))
continue; // not in your 2d plane
if (closestmo && P_AproxDistance(P_AproxDistance(player->mo->x-mo->x, player->mo->y-mo->y),
player->mo->z-mo->z) > P_AproxDistance(P_AproxDistance(player->mo->x-closestmo->x,
if (closestmo && modist > P_AproxDistance(P_AproxDistance(player->mo->x-closestmo->x,
player->mo->y-closestmo->y), player->mo->z-closestmo->z))
continue;
@@ -3149,8 +3156,8 @@ static ticcmd_t *P_CameraCmd(camera_t *cam, UINT8 num)
cmd->angleturn = (INT16)(lang >> TICCMD_REDUCE);
cmd->aiming = G_ClipAimingPitch(&laim);
const boolean analogjoystickmove = cv_usejoystick[num].value && !Joystick[num].bGamepadStyle;
const boolean gamepadjoystickmove = cv_usejoystick[num].value && Joystick[num].bGamepadStyle;
const boolean analogjoystickmove = cv_usejoystick[num].value && !DigitalGamepadStyle(num);
const boolean gamepadjoystickmove = cv_usejoystick[num].value && DigitalGamepadStyle(num);
usejoystick = (analogjoystickmove || gamepadjoystickmove);
@@ -3733,7 +3740,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
fixed_t f1, f2;
// We probably shouldn't move the camera if there is no player or player mobj somehow
if (!player || !player->mo)
if (!player || P_MobjWasRemoved(player->mo))
return true;
// This can happen when joining
@@ -4580,6 +4587,7 @@ void P_PlayerThink(player_t *player)
{
short int i;
mo->flags |= MF_NOCLIPHEIGHT;
for (i = 0; i < 32; i++)
{
// Debug drawing
@@ -5082,6 +5090,11 @@ void P_PlayerThink(player_t *player)
player->squishdance.time = 0;
}
if (player->stairjank > 0)
{
player->stairjank--;
}
// Flash player after being hit.
if (!(player->kartstuff[k_hyudorotimer] // SRB2kart - fixes Hyudoro not flashing when it should.
|| player->kartstuff[k_growshrinktimer] > 0 // Grow doesn't flash either.
+18 -5
View File
@@ -320,13 +320,20 @@ static void R_AddLine(seg_t *line)
INT32 x1, x2;
angle_t angle1, angle2, span, tspan;
static sector_t tempsec;
boolean bothfloorssky = false;
boolean bothfloorssky = false;
fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t
g_portal = NULL;
v1x = line->v1->x;
v1y = line->v1->y;
v2x = line->v2->x;
v2y = line->v2->y;
// big room fix
angle1 = R_PointToAngle64(line->v1->x, line->v1->y);
angle2 = R_PointToAngle64(line->v2->x, line->v2->y);
angle1 = R_PointToAngle64(v1x, v1y);
angle2 = R_PointToAngle64(v2x, v2y);
curline = line;
@@ -519,6 +526,7 @@ static boolean R_CheckBBox(const fixed_t *bspcoord)
angle_t angle1, angle2;
INT32 sx1, sx2;
const INT32* check;
fixed_t x1, y1, x2, y2;
// Find the corners of the box
// that define the edges from current viewpoint.
@@ -532,9 +540,14 @@ static boolean R_CheckBBox(const fixed_t *bspcoord)
check = checkcoord[boxpos];
x1 = bspcoord[check[0]];
y1 = bspcoord[check[1]];
x2 = bspcoord[check[2]];
y2 = bspcoord[check[3]];
// big room fix
angle1 = R_PointToAngle64(bspcoord[check[0]], bspcoord[check[1]]) - viewangle;
angle2 = R_PointToAngle64(bspcoord[check[2]], bspcoord[check[3]]) - viewangle;
angle1 = R_PointToAngle64(x1, y1) - viewangle;
angle2 = R_PointToAngle64(x2, y2) - viewangle;
// cph - replaced old code, which was unclear and badly commented
// Much more efficient code now
+1 -1
View File
@@ -430,7 +430,7 @@ typedef struct line_s
INT16 tag;
// Visual appearance: sidedefs.
UINT16 sidenum[2]; // sidenum[1] will be 0xffff if one-sided
UINT16 sidenum[2]; // sidenum[1] will be NO_INDEX if one-sided
fixed_t alpha; // translucency
UINT8 blendmode; // blendmode
+5 -4
View File
@@ -387,10 +387,10 @@ void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjst
return;
}
out->x = R_LerpFixed(mobj->old_x, mobj->x, frac);
out->y = R_LerpFixed(mobj->old_y, mobj->y, frac);
out->z = R_LerpFixed(mobj->old_z, mobj->z, frac);
out->scale = mapobjectscale;
out->x = R_LerpFixed(mobj->old_x, mobj->x, frac);
out->y = R_LerpFixed(mobj->old_y, mobj->y, frac);
out->z = R_LerpFixed(mobj->old_z, mobj->z, frac);
out->scale = mapobjectscale;
}
static levelinterpolator_t *CreateInterpolator(levelinterpolator_type_e type, thinker_t *thinker)
@@ -807,6 +807,7 @@ void R_ResetMobjInterpolationState(mobj_t *mobj)
mobj->spriteyscale = mobj->realyscale;
mobj->spritexoffset = mobj->realxoffset;
mobj->spriteyoffset = mobj->realyoffset;
mobj->temprollangle = 0;
mobj->resetinterp = false;
}
+4 -1
View File
@@ -188,6 +188,7 @@ consvar_t cv_flipcammode = {"flipcammode", "Displayplayer", CV_SAVE, flipcammod
consvar_t cv_shadow = {"shadow", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_shadowoffs = {"offsetshadows", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_skybox = {"skybox", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_skydome = {"skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_ffloorclip = {"r_ffloorclip", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_spriteclip = {"r_spriteclip", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_softcyancut = {"softwarecyancut", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -1564,6 +1565,7 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_shadow);
CV_RegisterVar(&cv_shadowoffs);
CV_RegisterVar(&cv_skybox);
CV_RegisterVar(&cv_skydome);
CV_RegisterVar(&cv_ffloorclip);
CV_RegisterVar(&cv_spriteclip);
CV_RegisterVar(&cv_secbright);
@@ -1598,7 +1600,8 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_sliptideroll);
CV_RegisterVar(&cv_sloperolldist);
CV_RegisterVar(&cv_sparkroll);
CV_RegisterVar(&cv_spinoutroll);
CV_RegisterVar(&cv_stairjank);
CV_RegisterVar(&cv_stairjanksfx);
CV_RegisterVar(&cv_showhud);
CV_RegisterVar(&cv_translucenthud);
+1
View File
@@ -213,6 +213,7 @@ extern consvar_t cv_translucency;
extern consvar_t cv_drawdist, cv_drawdist_precip, cv_lessprecip;
extern consvar_t cv_fov, cv_fovchange;
extern consvar_t cv_skybox;
extern consvar_t cv_skydome;
extern consvar_t cv_tailspickup;
extern consvar_t cv_maxinterpdist;
extern consvar_t cv_playerfade;
+1 -1
View File
@@ -289,7 +289,7 @@ void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum)
sprinfoLumpLength = W_LumpLengthPwad(wadNum, lumpNum);
sprinfoText = (char *)Z_Malloc((sprinfoLumpLength+1)*sizeof(char),PU_STATIC,NULL);
// Now move the contents of the lump into this new location.
memmove(sprinfoText,sprinfoLump,sprinfoLumpLength);
memmove(sprinfoText, sprinfoLump, sprinfoLumpLength);
// Make damn well sure the last character in our new memory location is \0.
sprinfoText[sprinfoLumpLength] = '\0';
// Finally, free up the memory from the first data load, because we really
+6 -3
View File
@@ -785,6 +785,8 @@ static void R_DrawSkyPlane(visplane_t *pl, void(*skycolfunc)(drawcolumndata_t*),
drawcolumndata_t dc = {};
const INT32 texture = texturetranslation[skytexture];
const boolean skydome = cv_skydome.value != 0;
// Reset column drawer function (note: couldn't we just call colfuncs[BASEDRAWFUNC] directly?)
// (that is, unless we'll need to switch drawers in future for some reason)
R_SetColumnFunc(BASEDRAWFUNC);
@@ -830,8 +832,8 @@ static void R_DrawSkyPlane(visplane_t *pl, void(*skycolfunc)(drawcolumndata_t*),
INT32 angle = (pl->viewangle + xtoviewangle[x + i])>>ANGLETOSKYSHIFT;
angle -= (skytextureoffset >> FRACBITS);
dc.iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x + i]>>ANGLETOFINESHIFT));
if (skydome)
dc.iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x + i]>>ANGLETOFINESHIFT));
dc.x = x + i;
dc.source = R_GetColumn(texture, -angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18
@@ -866,7 +868,8 @@ static void R_DrawSkyPlane(visplane_t *pl, void(*skycolfunc)(drawcolumndata_t*),
INT32 angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT;
angle -= (skytextureoffset >> FRACBITS);
dc.iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT));
if (skydome)
dc.iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT));
dc.x = x;
dc.source =
R_GetColumn(texturetranslation[skytexture], -angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18
+19 -14
View File
@@ -311,6 +311,7 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
{
rw_scalestep = drawseg->scalestep;
spryscale = drawseg->scale1 + (x1 - drawseg->x1)*rw_scalestep;
if (dc->numlights)
{ // reset all lights to their starting heights
for (i = 0; i < dc->numlights; i++)
@@ -435,6 +436,7 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
windowtop = windowbottom + 1;
set_colormap_below_light();
}
windowbottom = realbot;
if (windowtop < windowbottom)
colfunc_2s(dc, col);
@@ -2204,7 +2206,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
topremap = (encoremap && !(curline->linedef->flags & ML_TFERLINE));
if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM))
&& linedef->sidenum[1] != 0xffff)
&& linedef->sidenum[1] != NO_INDEX)
{
// Special case... use offsets from 2nd side but only if it has a texture.
side_t *def = &sides[linedef->sidenum[1]];
@@ -2615,8 +2617,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
auto set_topstep_normal = [&]
{
topstep = -FixedMul (rw_scalestep, worldtop);
topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale);
topstep = -FixedMul(rw_scalestep, worldtop);
topfrac = (centeryfrac>>4) - FixedMul(worldtop, rw_scale);
};
// untextured seg
@@ -2625,7 +2627,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
const bool tophigh = (worldhigh <= worldtop && worldhighslope <= worldtopslope);
// if we cant see the goddamn skyplane, well there wont be any skybox
// we could kill skyVisible instead, but i want to keep the performance improvemnts it yields
// we could kill skyVisible instead, but i want to keep the performance improvements it yields
// so we do this absolute trash
if ((tophigh
&& (frontsector->floorpic != skyflatnum && frontsector->ceilingpic != skyflatnum)) // try to guess if its a "window"
@@ -2637,14 +2639,16 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// this is an attempt to fix issues with textureless single sided lines drawing nothing where they should just draw sky instead
if (tophigh && !backsector && frontsector->ceilingpic == skyflatnum)
{
topstep = -FixedMul (rw_scalestep, worldbottom);
topfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale);
// account for slopes to try and get rid of sharp edges from the black void
if (frontsector->f_slope || (backsector && backsector->f_slope))
{
topstep = -FixedMul (rw_scalestep, worldbottomslope);
topfrac = (centeryfrac>>4) - FixedMul (worldbottomslope, rw_scale);
topstep = -FixedMul(rw_scalestep, worldbottomslope);
topfrac = (centeryfrac>>4) - FixedMul(worldbottomslope, rw_scale);
}
else
{
topstep = -FixedMul(rw_scalestep, worldbottom);
topfrac = (centeryfrac>>4) - FixedMul(worldbottom, rw_scale);
}
}
else
@@ -2653,18 +2657,18 @@ void R_StoreWallRange(INT32 start, INT32 stop)
else
set_topstep_normal();
bottomstep = -FixedMul (rw_scalestep, worldbottom);
bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale);
bottomstep = -FixedMul(rw_scalestep, worldbottom);
bottomfrac = (centeryfrac>>4) - FixedMul(worldbottom, rw_scale);
if (frontsector->c_slope)
{
fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldtopslope, ds_p->scale2);
fixed_t topfracend = (centeryfrac>>4) - FixedMul(worldtopslope, ds_p->scale2);
topstep = (topfracend-topfrac)/(range);
}
if (frontsector->f_slope)
{
fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldbottomslope, ds_p->scale2);
fixed_t bottomfracend = (centeryfrac>>4) - FixedMul(worldbottomslope, ds_p->scale2);
bottomstep = (bottomfracend-bottomfrac)/(range);
}
}
@@ -2782,7 +2786,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (bottomtexture)
{
fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2);
fixed_t bottomfracend = (centeryfrac>>4) - FixedMul(worldlowslope, ds_p->scale2);
pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale);
pixlowstep = (bottomfracend-pixlow)/(range);
@@ -3045,6 +3049,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ds_p->silhouette |= SIL_BOTTOM;
ds_p->bsilheight = backsector->f_slope ? INT32_MAX : backsector->floorheight;
}
if (!(ds_p->silhouette & SIL_TOP))
{
ds_p->silhouette |= SIL_TOP;
+1 -1
View File
@@ -712,7 +712,7 @@ void R_AddSkins(UINT16 wadnum, boolean local)
// skip to end of this skin's frames
lastlump = lump;
while (W_CheckNameForNumPwad(wadnum, lastlump) && memcmp(W_CheckNameForNumPwad(wadnum, lastlump), csprname,4)==0)
while (W_CheckNameForNumPwad(wadnum, lastlump) && memcmp(W_CheckNameForNumPwad(wadnum, lastlump), csprname, 4) == 0)
lastlump++;
// allocate (or replace) sprite frames, and set spritedef
+1 -1
View File
@@ -131,7 +131,7 @@ void R_AddWallSplat(line_t *wallline, INT16 sectorside, const char *patchname, f
// set the splat
splat->patch = W_GetNumForName(patchname);
sectorside ^= 1;
if (wallline->sidenum[sectorside] != 0xffff)
if (wallline->sidenum[sectorside] != NO_INDEX)
{
backsector = sides[wallline->sidenum[sectorside]].sector;
+45 -32
View File
@@ -182,15 +182,14 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
UINT8 rightfactor = ((rotation == ROT_R) ? 4 : 0);
// the lump should be used for half of all rotations
if (sprtemp[frame].rotate == SRF_SINGLE)
if (sprtemp[frame].rotate == SRF_NONE)
sprtemp[frame].rotate = SRF_SINGLE;
else if (sprtemp[frame].rotate == SRF_SINGLE)
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has L/R rotations and a rot = 0 lump\n", spritename, cn);
else if (sprtemp[frame].rotate == SRF_3D)
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8 rotations\n", spritename, cn);
// Let's not complain about multiple L/R rotations. It's not worth the effort.
if (sprtemp[frame].rotate == SRF_NONE)
sprtemp[frame].rotate = SRF_SINGLE;
sprtemp[frame].rotate |= ((rotation == ROT_R) ? SRF_RIGHT : SRF_LEFT);
if (sprtemp[frame].rotate == (SRF_3D|SRF_2D))
@@ -233,6 +232,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
// when using sprites in pwad : the lumppat points the new graphics
sprtemp[frame].lumppat[rotation] = lumppat;
sprtemp[frame].lumpid[rotation] = lumpid;
if (flipped)
sprtemp[frame].flip |= (1<<rotation);
else
@@ -261,9 +261,11 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
softwarepatch_t patch;
UINT8 numadded = 0;
memset(sprtemp,0xFF, sizeof (sprtemp));
memset(sprtemp, 0xFF, sizeof(sprtemp));
maxframe = (size_t)-1;
spritename = sprname;
// are we 'patching' a sprite already loaded ?
// if so, it might patch only certain frames, not all
if (spritedef->numframes) // (then spriteframes is not null)
@@ -289,7 +291,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
if (frame >= 64 || !(R_ValidSpriteAngle(rotation))) // Give an actual NAME error -_-...
{
CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum,l));
CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum, l));
continue;
}
@@ -315,6 +317,15 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
{
frame = R_Char2Frame(lumpinfo[l].name[6]);
rotation = (UINT8)(lumpinfo[l].name[7] - '0');
/*
if (frame >= 64 || !(R_ValidSpriteAngle(rotation))) // Give an actual NAME error -_-...
{
CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum, l));
continue;
}
*/
R_InstallSpriteLump(wadnum, l, numspritelumps, frame, rotation, 1);
}
@@ -363,30 +374,32 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
switch (sprtemp[frame].rotate)
{
case SRF_NONE:
// no rotations were found for that frame at all
I_Error("R_AddSingleSpriteDef: No patches found for %.4s frame %c", sprname, R_Frame2Char(frame));
break;
// no rotations were found for that frame at all
I_Error("R_AddSingleSpriteDef: No patches found for %.4s frame %c", sprname, R_Frame2Char(frame));
break;
case SRF_SINGLE:
// only the first rotation is needed
break;
// only the first rotation is needed
break;
case SRF_2D: // both Left and Right rotations
// we test to see whether the left and right slots are present
if ((sprtemp[frame].lumppat[2] == LUMPERROR) || (sprtemp[frame].lumppat[6] == LUMPERROR))
I_Error("R_AddSingleSpriteDef: Sprite %s frame %c is missing rotations",
sprname, R_Frame2Char(frame));
break;
break;
default:
// must have all 8 frames
for (rotation = 0; rotation < 8; rotation++)
// we test the patch lump, or the id lump whatever
// if it was not loaded the two are LUMPERROR
if (sprtemp[frame].lumppat[rotation] == LUMPERROR)
I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations",
sprname, R_Frame2Char(frame));
break;
// must have all 8 frames
for (rotation = 0; rotation < 8; rotation++)
{
// we test the patch lump, or the id lump whatever
// if it was not loaded the two are LUMPERROR
if (sprtemp[frame].lumppat[rotation] == LUMPERROR)
I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations",
sprname, R_Frame2Char(frame));
}
break;
}
}
@@ -394,7 +407,6 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
if (spritedef->numframes && // has been allocated
spritedef->numframes < maxframe) // more frames are defined ?
{
Z_Free(spritedef->spriteframes);
spritedef->spriteframes = NULL;
}
@@ -451,12 +463,10 @@ void R_AddSpriteDefs(UINT16 wadnum)
//
for (i = 0; i < numsprites; i++)
{
spritename = sprnames[i];
if (spritename[4] && wadnum >= (UINT16)spritename[4])
if (sprnames[i][4] && wadnum >= (UINT16)sprnames[i][4])
continue;
if (R_AddSingleSpriteDef(spritename, &sprites[i], wadnum, start, end))
if (R_AddSingleSpriteDef(sprnames[i], &sprites[i], wadnum, start, end))
{
#ifdef HWRENDER
if (rendermode == render_opengl)
@@ -464,9 +474,7 @@ void R_AddSpriteDefs(UINT16 wadnum)
#endif
// if a new sprite was added (not just replaced)
addsprites++;
#ifndef ZDEBUG
CONS_Debug(DBG_SETUP, "sprite %s set in pwad %d\n", spritename, wadnum);
#endif
CONS_Debug(DBG_SETUP, "sprite %s set in pwad %d\n", sprnames[i], wadnum);
}
}
@@ -773,6 +781,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
R_SetColumnFunc(BASEDRAWFUNC); // hack: this isn't resetting properly somewhere.
dc.colormap = vis->colormap;
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
{
R_SetColumnFunc(COLDRAWFUNC_TRANS); // translate certain pixels to white
@@ -825,6 +834,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
else
dc.colormap = &vis->extra_colormap->colormap[dc.colormap - colormaps];
}
if (!dc.colormap)
dc.colormap = colormaps;
@@ -849,6 +859,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
vis->xiscale = FixedDiv(vis->xiscale, this_scale);
vis->isScaled = true;
}
dc.texturemid = FixedDiv(dc.texturemid, this_scale);
}
@@ -1265,7 +1276,7 @@ static void R_ProjectSprite(mobj_t *thing)
#ifdef ROTSPRITE
// determine here if sprite should rotate for optimization
const boolean sliprollrotate = (cv_sliptideroll.value && (thing->player && thing->player->sliproll));
const boolean shouldrotate = (interp.sloperoll || interp.slopepitch || interp.roll || interp.pitch || thing->rollangle || sliprollrotate);
const boolean shouldrotate = (interp.sloperoll || interp.slopepitch || interp.roll || interp.pitch || thing->rollangle || thing->temprollangle || sliprollrotate);
#endif
sprskin = K_GetMobjSkin(thing);
@@ -1365,16 +1376,18 @@ static void R_ProjectSprite(mobj_t *thing)
#ifdef ROTSPRITE
if (shouldrotate)
{
const fixed_t thingrollangle = (thing->rollangle - thing->temprollangle);
if (papersprite)
{
if (ang >= ANGLE_180)
{
// Makes Software act much more sane like OpenGL
rollangle = InvAngle(thing->rollangle);
rollangle = InvAngle(thingrollangle);
}
else
{
rollangle = thing->rollangle;
rollangle = thingrollangle;
}
}
else
@@ -1382,7 +1395,7 @@ static void R_ProjectSprite(mobj_t *thing)
// this is very messy, but it on-the-fly calculates rotations for all the
// pitch and roll variables
pitchnroll = R_RotationAngle(ang, camang, &interp);
rollangle = thing->rollangle;
rollangle = thingrollangle;
}
if (rollangle || pitchnroll || sliprollrotate)
+152 -129
View File
@@ -477,6 +477,11 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
{
player_t *player = &players[displayplayers[i]];
if (!player)
{
continue;
}
if (player->awayviewtics)
{
listenmobj[i] = player->awayviewmobj;
@@ -535,79 +540,84 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
i = 0; // sensible default
// Check to see if it is audible, and if not, modify the params
if (origin && !itsUs)
{
// Check to see if it is audible, and if not, modify the params
if (origin && !itsUs)
boolean audible = false;
if (splitscreen > 0)
{
boolean audible = false;
if (splitscreen > 0)
{
fixed_t recdist = INT32_MAX;
UINT8 j = 0;
fixed_t recdist = INT32_MAX;
UINT8 j = 0;
for (; j <= splitscreen; j++)
for (; j <= splitscreen; j++)
{
fixed_t thisdist = INT32_MAX;
if (!listenmobj[j])
{
fixed_t thisdist = INT32_MAX;
if (!listenmobj[j])
{
continue;
}
thisdist = P_AproxDistance(listener[j].x - origin->x, listener[j].y - origin->y);
if (thisdist >= recdist)
{
continue;
}
recdist = thisdist;
i = j;
continue;
}
}
if (listenmobj[i])
{
audible = S_AdjustSoundParams(listenmobj[i], origin, &volume, &sep, sfx);
}
thisdist = P_AproxDistance(listener[j].x - origin->x, listener[j].y - origin->y);
if (!audible)
{
return;
if (thisdist >= recdist)
{
continue;
}
recdist = thisdist;
i = j;
}
}
// This is supposed to handle the loading/caching.
// For some odd reason, the caching is done nearly
// each time the sound is needed?
if (listenmobj[i])
{
audible = S_AdjustSoundParams(listenmobj[i], origin, &volume, &sep, sfx);
}
if (!audible)
{
return;
}
}
// This is supposed to handle the loading/caching.
// For some odd reason, the caching is done nearly
// each time the sound is needed?
// cache data if necessary
// NOTE: set sfx->data NULL sfx->lump -1 to force a reload
if (!sfx->data)
{
sfx->data = I_GetSfx(sfx);
// cache data if necessary
// NOTE: set sfx->data NULL sfx->lump -1 to force a reload
if (!sfx->data)
{
sfx->data = I_GetSfx(sfx);
CONS_Alert(CONS_WARNING, "Tried to load invalid sfx_%s\n", sfx->name);
return; /* don't play it */
}
// Avoid channel reverse if surround
if (reverse)
{
sep = (~sep) & 255;
}
// At this point it is determined that a sound can and should be played, so find a free channel to play it on
cnum = S_getChannel(origin, sfx);
if (cnum < 0)
{
return; // If there's no free channels, there won't be any for anymore players either
}
// Now that we know we are going to play a sound, fill out this info
channels[cnum].sfxinfo = sfx;
channels[cnum].origin = origin;
channels[cnum].volume = initial_volume;
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, cnum);
}
// Avoid channel reverse if surround
if (reverse)
{
sep = (~sep) & 255;
}
// At this point it is determined that a sound can and should be played, so find a free channel to play it on
cnum = S_getChannel(origin, sfx);
if (cnum < 0)
{
return; // If there's no free channels, there won't be any for anymore players either
}
// Now that we know we are going to play a sound, fill out this info
channels[cnum].sfxinfo = sfx;
channels[cnum].origin = origin;
channels[cnum].volume = initial_volume;
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, cnum);
}
void S_StartSound(const void *origin, sfxenum_t sfx_id)
@@ -728,6 +738,11 @@ void S_UpdateSounds(void)
{
player_t *player = &players[displayplayers[i]];
if (!player)
{
continue;
}
if (player->awayviewtics)
{
listenmobj[i] = player->awayviewmobj;
@@ -761,84 +776,83 @@ void S_UpdateSounds(void)
{
c = &channels[cnum];
if (c->sfxinfo)
if (c->sfxinfo == NULL)
continue;
// if channel is allocated but sound has stopped, free it
if (!I_SoundIsPlaying(c->handle))
{
if (I_SoundIsPlaying(c->handle))
S_StopChannel(cnum);
continue;
}
if (c->origin == NULL)
continue;
// initialize parameters
volume = c->volume; // 8 bits internal volume precision
sep = NORM_SEP;
// check non-local sounds for distance clipping
// or modify their params
boolean itsUs = false;
for (i = splitscreen; i >= 0; i--)
{
if (camera[i].freecam)
continue;
if (c->origin != listenmobj[i])
continue;
itsUs = true;
}
if (itsUs == false)
{
const mobj_t *origin = c->origin;
i = 0;
if (splitscreen > 0)
{
// initialize parameters
volume = c->volume; // 8 bits internal volume precision
sep = NORM_SEP;
fixed_t recdist = INT32_MAX;
UINT8 j = 0;
// check non-local sounds for distance clipping
// or modify their params
if (c->origin)
for (; j <= splitscreen; j++)
{
boolean itsUs = false;
fixed_t thisdist = INT32_MAX;
for (i = splitscreen; i >= 0; i--)
if (!listenmobj[j])
{
if (camera[i].freecam)
continue;
if (c->origin != listenmobj[i])
continue;
itsUs = true;
continue;
}
if (itsUs == false)
thisdist = P_AproxDistance(listener[j].x - origin->x, listener[j].y - origin->y);
if (thisdist >= recdist)
{
const mobj_t *origin = c->origin;
i = 0;
if (splitscreen > 0)
{
fixed_t recdist = INT32_MAX;
UINT8 j = 0;
for (; j <= splitscreen; j++)
{
fixed_t thisdist = INT32_MAX;
if (!listenmobj[j])
{
continue;
}
thisdist = P_AproxDistance(listener[j].x - origin->x, listener[j].y - origin->y);
if (thisdist >= recdist)
{
continue;
}
recdist = thisdist;
i = j;
}
}
if (listenmobj[i])
{
audible = S_AdjustSoundParams(
listenmobj[i], c->origin,
&volume, &sep,
c->sfxinfo
);
}
if (audible)
I_UpdateSoundParams(c->handle, volume, sep);
else
S_StopChannel(cnum);
continue;
}
recdist = thisdist;
i = j;
}
}
else
if (listenmobj[i])
{
// if channel is allocated but sound has stopped, free it
S_StopChannel(cnum);
audible = S_AdjustSoundParams(
listenmobj[i], c->origin,
&volume, &sep,
c->sfxinfo
);
}
if (audible)
I_UpdateSoundParams(c->handle, volume, sep);
else
S_StopChannel(cnum);
}
}
@@ -866,7 +880,6 @@ void S_ClearSfx(void)
static void S_StopChannel(INT32 cnum)
{
INT32 i;
channel_t *c = &channels[cnum];
if (c->sfxinfo)
@@ -875,12 +888,6 @@ static void S_StopChannel(INT32 cnum)
if (I_SoundIsPlaying(c->handle))
I_StopSound(c->handle);
// check to see
// if other channels are playing the sound
for (i = 0; i < numofchannels; i++)
if (cnum != i && c->sfxinfo == channels[i].sfxinfo)
break;
c->sfxinfo = NULL;
}
@@ -930,6 +937,7 @@ static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source,
listener_t listensource;
INT32 i;
// e6y
if (!listener)
return false;
@@ -1046,12 +1054,14 @@ static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source,
INT32 S_OriginPlaying(void *origin)
{
INT32 cnum;
if (!origin)
return false;
for (cnum = 0; cnum < numofchannels; cnum++)
if (channels[cnum].origin == origin)
return 1;
return 0;
}
@@ -1064,6 +1074,7 @@ INT32 S_IdPlaying(sfxenum_t id)
for (cnum = 0; cnum < numofchannels; cnum++)
if ((size_t)(channels[cnum].sfxinfo - S_sfx) == (size_t)id)
return 1;
return 0;
}
@@ -1072,6 +1083,7 @@ INT32 S_IdPlaying(sfxenum_t id)
INT32 S_SoundPlaying(void *origin, sfxenum_t id)
{
INT32 cnum;
if (!origin)
return 0;
@@ -1081,6 +1093,7 @@ INT32 S_SoundPlaying(void *origin, sfxenum_t id)
&& (size_t)(channels[cnum].sfxinfo - S_sfx) == (size_t)id)
return 1;
}
return 0;
}
@@ -1093,6 +1106,7 @@ static sfxenum_t newsounds[MAXNEWSOUNDS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
void S_StartSoundName(void *mo, const char *soundname)
{
INT32 i, soundnum = 0;
// Search existing sounds...
for (i = sfx_None + 1; i < NUMSFX; i++)
{
@@ -2025,6 +2039,10 @@ static boolean S_SkipIntroMusic(void)
if (!cv_skipintromusic.value)
return false;
// dont skip if we disabled music, weird? but this would skip sounds that play on map start as well otherwise
if (music_disabled)
return false;
// check if menu music is playing, otherwise it may continue playing
if (fasticmp(music.name, "titles"))
return false;
@@ -2036,6 +2054,11 @@ static boolean S_SkipIntroMusic(void)
return false;
}
// without sound there wont be any intro playing
if (sound_disabled)
return true;
// yes i sometimes play with only music but no sound
return true;
}
+1 -1
View File
@@ -530,6 +530,6 @@ void SCR_DisplayLocalPing(void)
if (cv_showping.value == 1 || (cv_showping.value == 2 && ping > servermaxping)) // only show 2 (warning) if our ping is at a bad level
{
INT32 dispy = (cv_ticrate.value == 1) ? 165 : ((cv_ticrate.value == 2 || cv_ticrate.value == 4) ? 172 : ((cv_ticrate.value == 3) ? 163 : 181)); // absolute buttpain
HU_drawPlayerPing(308, dispy, consoleplayer, pingflags); // consoleplayer's ping is everyone's ping in a splitnetgame :P
HU_drawLocalPlayerPing(308, dispy, pingflags); // consoleplayer's ping is everyone's ping in a splitnetgame :P
}
}
+4 -8
View File
@@ -743,26 +743,22 @@ INT32 numcontrollers = 0;
//
void I_JoyScale(void)
{
Joystick[0].bGamepadStyle = cv_joyscale[0].value == 0;
JoyInfo[0].scale = Joystick[0].bGamepadStyle ? 1 : cv_joyscale[0].value;
JoyInfo[0].scale = DigitalGamepadStyle(0) ? 1 : cv_joyscale[0].value;
}
void I_JoyScale2(void)
{
Joystick[1].bGamepadStyle = cv_joyscale[1].value == 0;
JoyInfo[1].scale = Joystick[1].bGamepadStyle ? 1 : cv_joyscale[1].value;
JoyInfo[1].scale = DigitalGamepadStyle(1) ? 1 : cv_joyscale[1].value;
}
void I_JoyScale3(void)
{
Joystick[2].bGamepadStyle = cv_joyscale[2].value == 0;
JoyInfo[2].scale = Joystick[2].bGamepadStyle ? 1 : cv_joyscale[2].value;
JoyInfo[2].scale = DigitalGamepadStyle(2) ? 1 : cv_joyscale[2].value;
}
void I_JoyScale4(void)
{
Joystick[3].bGamepadStyle = cv_joyscale[3].value == 0;
JoyInfo[3].scale = Joystick[3].bGamepadStyle ? 1 : cv_joyscale[3].value;
JoyInfo[3].scale = DigitalGamepadStyle(3) ? 1 : cv_joyscale[3].value;
}
// Cheat to get the device index for a joystick handle
+4 -1
View File
@@ -454,7 +454,7 @@ static INT32 SDLJoyAxis(const Sint16 axis, evtype_t which)
return 0;
}
if (Joystick[pid].bGamepadStyle)
if (DigitalGamepadStyle(pid))
{
// gamepad control type, on or off, live or die
if (raxis < -(JOYAXISRANGE/2))
@@ -1855,6 +1855,9 @@ void I_StartupGraphics(void)
{
word = strtok(line, " \n");
if (!word)
continue;
if (rendermode == render_none)
{
if (fasticmp(word, "software"))
Binary file not shown.
+2 -2
View File
@@ -945,7 +945,7 @@ UINT32 I_GetSongLength(void)
boolean I_SetSongLoopPoint(UINT32 looppoint)
{
if (!music|| !is_looping)
if (!music || !is_looping)
return false;
const musictype_t mustype = I_SongType();
@@ -958,7 +958,7 @@ boolean I_SetSongLoopPoint(UINT32 looppoint)
if (length > 0)
looppoint %= length;
loop_point = max((float)(looppoint / 1000.0L), 0);
loop_point = max((float)(looppoint / 1000.0L), 0.0f);
return true;
}
+2 -1
View File
@@ -975,7 +975,7 @@ sfxinfo_t S_sfx[NUMSFX] =
char freeslotnames[sfx_freeslot0 + NUMSFXFREESLOTS + NUMSKINSFXSLOTS][7] = {};
// Prepare free sfx slots to add sfx at run time
void S_InitRuntimeSounds (void)
void S_InitRuntimeSounds(void)
{
sfxenum_t i;
INT32 value;
@@ -1040,6 +1040,7 @@ sfxenum_t S_AddSoundFx(const char *name, boolean singular, INT32 flags, boolean
return i;
}
}
I_Error("Out of Sound Freeslots while allocating \"%s\"\nLoad less addons to fix this.", name);
return 0;
}
+26 -4
View File
@@ -423,9 +423,9 @@ static void ApplyPaletteDelta(const RGBA_t *pal_in, RGBA_t *pal_out, const INT16
INT16 r = (INT16)pal_in[i].s.red + pal_delta[i][0];
INT16 g = (INT16)pal_in[i].s.green + pal_delta[i][1];
INT16 b = (INT16)pal_in[i].s.blue + pal_delta[i][2];
pal_out[i].s.red = (UINT8)CLAMP(r, 0 , 255);
pal_out[i].s.green = (UINT8)CLAMP(g, 0 , 255);
pal_out[i].s.blue = (UINT8)CLAMP(b, 0 , 255);
pal_out[i].s.red = (UINT8)CLAMP(r, 0, 255);
pal_out[i].s.green = (UINT8)CLAMP(g, 0, 255);
pal_out[i].s.blue = (UINT8)CLAMP(b, 0, 255);
pal_out[i].s.alpha = 0xFF; // pal_in[i].s.alpha
}
}
@@ -2203,6 +2203,7 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string)
{
if (!*ch)
break;
if (*ch & 0x80) //color parsing -x 2.16.09
{
// manually set flags override color codes
@@ -2213,6 +2214,7 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string)
}
continue;
}
if (*ch == '\n')
{
cx = x;
@@ -2247,6 +2249,7 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string)
if (cx > scrwidth)
break;
if (cx+left + w < 0) //left boundary check
{
cx += w;
@@ -2304,6 +2307,7 @@ void V_DrawKartString(INT32 x, INT32 y, INT32 option, const char *string)
{
if (!*ch)
break;
if (*ch & 0x80) //color parsing -x 2.16.09
{
// manually set flags override color codes
@@ -2314,6 +2318,7 @@ void V_DrawKartString(INT32 x, INT32 y, INT32 option, const char *string)
}
continue;
}
if (*ch == '\n')
{
cx = x;
@@ -2348,6 +2353,7 @@ void V_DrawKartString(INT32 x, INT32 y, INT32 option, const char *string)
if (cx > scrwidth)
break;
if (cx+left + w < 0) //left boundary check
{
cx += w;
@@ -2422,6 +2428,7 @@ void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string)
{
if (!*ch)
break;
if (*ch & 0x80) //color parsing -x 2.16.09
{
// manually set flags override color codes
@@ -2432,6 +2439,7 @@ void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string)
}
continue;
}
if (*ch == '\n')
{
cx = x;
@@ -2540,6 +2548,7 @@ void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string)
{
if (!*ch)
break;
if (*ch & 0x80) //color parsing -x 2.16.09
{
// manually set flags override color codes
@@ -2550,6 +2559,7 @@ void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string)
}
continue;
}
if (*ch == '\n')
{
cx = x;
@@ -2708,6 +2718,7 @@ void V_DrawSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *st
INT32 charflags = 0;
const UINT8 *colormap = NULL;
INT32 spacewidth = 2, charwidth = 0;
INT32 lowercase = (option & V_ALLOWLOWERCASE);
option &= ~V_FLIP; // which is also shared with V_ALLOWLOWERCASE...
@@ -2728,6 +2739,7 @@ void V_DrawSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *st
scrwidth *= vid.dup;
charflags = (option & V_CHARCOLORMASK);
colormap = V_GetStringColormap(charflags);
switch (option & V_SPACINGMASK)
{
@@ -2752,7 +2764,11 @@ void V_DrawSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *st
{
// manually set flags override color codes
if (!(option & V_CHARCOLORMASK))
{
charflags = ((*ch & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK;
colormap = V_GetStringColormap(charflags);
}
continue;
}
@@ -2796,7 +2812,6 @@ void V_DrawSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *st
continue;
}
colormap = V_GetStringColormap(charflags);
V_DrawFixedPatch(cx + (center<<FRACBITS), cy, FRACUNIT/2, option, hu_font[c], colormap);
cx += w<<FRACBITS;
}
@@ -2808,6 +2823,13 @@ void V_DrawCenteredSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const
V_DrawSmallStringAtFixed(x, y, option, string);
}
void V_DrawRightAlignedSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
{
x -= V_SmallStringWidth(string, option)<<FRACBITS;
V_DrawSmallStringAtFixed(x, y, option, string);
}
// Draws a thin string at a fixed_t location.
void V_DrawThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
{
fixed_t cx = x, cy = y;
+1
View File
@@ -252,6 +252,7 @@ void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
void V_DrawSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
void V_DrawCenteredSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
void V_DrawRightAlignedSmallStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
void V_DrawThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
+86 -29
View File
@@ -123,6 +123,9 @@ static const char pat_end[] = {0x50, 0x4b, 0x05, 0x06, 0x00};
UINT16 numwadfiles = 0; // number of active wadfiles
wadfile_t *wadfiles[MAX_WADFILES] = {}; // 0 to numwadfiles-1 are valid
// use strnlen as some lump names may not be null terminated
#define CHECKMAPMARKER(name) (memcmp(name, "MAP", 3) == 0 && strnlen(name, 8) == 5)
// W_Shutdown
// Closes all of the WAD files before quitting
// If not done on a Mac then open wad files
@@ -2392,7 +2395,7 @@ static int W_NameStartsWith(const char *name, lumpchecklist_t *checklist)
}
// Checks if file contains at least one lump which name starts with one of strings in checklist
static int W_CheckWADContains(FILE *fp, lumpchecklist_t *checklist)
static int W_CheckWADContainsEx(FILE *fp, lumpchecklist_t *checklist, boolean checkmap)
{
size_t i, j;
// if we're here it's a WAD file
@@ -2433,13 +2436,29 @@ static int W_CheckWADContains(FILE *fp, lumpchecklist_t *checklist)
if (!strncmp(lumpinfo.name, sprnames[j], 4)) // Sprites
continue;
if (W_NameStartsWith(lumpinfo.name, checklist))
if (checkmap)
{
if (CHECKMAPMARKER(lumpinfo.name))
return true;
}
else if (W_NameStartsWith(lumpinfo.name, checklist))
return true;
}
return false;
}
static int W_CheckPK3Contains(FILE *fp, lumpchecklist_t *checklist)
static int W_CheckWADContains(FILE *fp, lumpchecklist_t *checklist)
{
return W_CheckWADContainsEx(fp, checklist, false);
}
static int W_CheckWADContainsMap(FILE *fp)
{
return W_CheckWADContainsEx(fp, NULL, true);
}
static int W_CheckPK3ContainsEx(FILE *fp, lumpchecklist_t *checklist, boolean checkmap)
{
zend_t zend;
zlentry_t zlentry;
@@ -2513,13 +2532,23 @@ static int W_CheckPK3Contains(FILE *fp, lumpchecklist_t *checklist)
memset(lumpname, '\0', 9); // Making sure they're initialized to 0. Is it necessary?
strncpy(lumpname, trimname, min(8, dotpos - trimname));
if (W_NameStartsWith(lumpname, checklist))
if (checkmap)
{
if (CHECKMAPMARKER(lumpname))
return true;
}
else if (W_NameStartsWith(lumpname, checklist))
{
return true;
}
}
if (W_NameStartsWith(fullname, checklist))
if (checkmap)
{
if (CHECKMAPMARKER(fullname))
return true;
}
else if (W_NameStartsWith(fullname, checklist))
{
return true;
}
@@ -2561,12 +2590,24 @@ static int W_CheckPK3Contains(FILE *fp, lumpchecklist_t *checklist)
}
}
static int W_CheckFileContains(const char *filename, lumpchecklist_t *checklist)
static int W_CheckPK3Contains(FILE *fp, lumpchecklist_t *checklist)
{
return W_CheckPK3ContainsEx(fp, checklist, false);
}
static int W_CheckPK3ContainsMap(FILE *fp)
{
return W_CheckPK3ContainsEx(fp, NULL, true);
}
static int W_CheckFileContainsEx(const char *filename, lumpchecklist_t *checklist, boolean checkmap)
{
FILE *handle;
int contains = false;
if (!checklist)
// if we just check for maps this will be NULL
// hacky but i dont care
if (!checklist && !checkmap)
I_Error("No checklist for %s\n", filename);
// open wad file
@@ -2577,27 +2618,41 @@ static int W_CheckFileContains(const char *filename, lumpchecklist_t *checklist)
if (type == RET_PK3)
{
contains = W_CheckPK3Contains(handle, checklist);
if (checkmap)
contains = W_CheckPK3ContainsMap(handle);
else
contains = W_CheckPK3Contains(handle, checklist);
}
else if (type == RET_WAD)
{
contains = W_CheckWADContains(handle, checklist);
if (checkmap)
contains = W_CheckWADContainsMap(handle);
else
contains = W_CheckWADContains(handle, checklist);
}
fclose(handle);
return contains;
}
static int W_CheckFileContains(const char *filename, lumpchecklist_t *checklist)
{
return W_CheckFileContainsEx(filename, checklist, false);
}
static int W_CheckFileContainsMap(const char *filename)
{
return W_CheckFileContainsEx(filename, NULL, true);
}
// kinda stupid but we cant just check for any lump containing "MAP"
// we have to explicitly check if its MAP and 5 characters long
// the more correct way would be checking inside wad files nested within pk3´s
// and check the presence of actual map data like SSECTORS or something
// but man i cannot be assed to rework shit for that
int W_CheckAutoLoadContainsMap(const char *filename)
{
// for now this checks for map marker
static lumpchecklist_t autoloadblacklist[] =
{
{"MAP", 3},
{NULL, 0},
};
return W_CheckFileContains(filename, autoloadblacklist);
return W_CheckFileContainsMap(filename);
}
int W_CheckPostLoadList(const char *filename)
@@ -2676,8 +2731,9 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
vlumps[i].size = vsizecache[realentry];
const char *name = (fileinfo + realentry)->name;
I_Assert(name != NULL);
if (strnlen(name, 8) == 5 && memcmp(name, "MAP", 3) == 0)
if (CHECKMAPMARKER(name))
{
numlumps--; // We skip map marker, so 1 of entries becomes empty
continue; // This will skip i++ so we will write to same entry
@@ -2686,9 +2742,7 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
// Play it safe with the name in this case.
memcpy(vlumps[i].name, name, 8);
vlumps[i].name[8] = '\0';
vlumps[i].data = (UINT8 *)(
Z_Malloc(vlumps[i].size, PU_LEVEL, NULL) // This is memory inefficient, sorry about that.
);
vlumps[i].data = (UINT8 *)(Z_Malloc(vlumps[i].size, PU_LEVEL, NULL)); // This is memory inefficient, sorry about that.
memcpy(vlumps[i].data, wadData + LONG((fileinfo + realentry)->filepos), vlumps[i].size);
i++;
}
@@ -2698,15 +2752,19 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
}
else
{
// Count number of lumps until the end of resource OR up until next "MAPXX" lump.
// Count number of lumps until the end of resource OR up until next 0-length lump OR up until next "MAPXX" lump.
lumpnum_t lumppos = lumpnum + 1;
for (i = LUMPNUM(lumppos); i < wadfiles[WADFILENUM(lumpnum)]->numlumps; i++, lumppos++, numlumps++)
{
const char *name = W_CheckNameForNum(lumppos);
if (name == NULL)
continue;
if (W_LumpLength(lumppos) == 0)
{
break;
}
if (memcmp(name, "MAP", 3) == 0 || W_LumpLength(lumppos) == 0)
const char *name = W_CheckNameForNum(lumppos);
I_Assert(name != NULL);
if (CHECKMAPMARKER(name))
{
break;
}
@@ -2721,10 +2779,9 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
{
// Check if it is map marker. It is not always first lump sadly, so we need to expect it anywhere
const char *name = W_CheckNameForNum(lumpnum);
if (name == NULL)
continue;
I_Assert(name != NULL);
if (strlen(name) == 5 && memcmp(name, "MAP", 3) == 0)
if (CHECKMAPMARKER(name))
{
--i; // Decrement so on next iteration we write on same i, so we don't leave corrupted vlumps entry
numlumps--; // Just so we don't try to access the leftover vlumps entry
+1 -1
View File
@@ -586,7 +586,7 @@ void Y_Ticker(void)
if (data.rankingsmode && intertic > sorttic+16+(2*TICRATE))
{
INT32 q=0,r=0;
INT32 q = 0, r = 0;
boolean kaching = true;
for (q = 0; q < data.numplayers; q++)