Compare commits

...
182 Commits
Author SHA1 Message Date
Alug 5973004bb9 i_tcp: reset errno in UDP_Bind and SOCK_Send
on non WINSOCK systems
2025-10-29 20:10:12 +01:00
Alug 599ef7fad7 UDP_Bind: check for network send buffer and attempt to raise its size if its too small
exactly the same as the receive buffer
2025-10-29 20:06:24 +01:00
Alug 3220faac1e UDP_Bind: attempt to set receive buffer to 256kb if smaller
if that fails, try 128k, if that also somehow fails try 64k again
2025-10-29 19:06:45 +01:00
Gustaf Alhäll ea3e23e055 Fix buffer underflow when querying invalid nodes 2025-10-29 19:06:42 +01:00
Alug 112d389dcd SOCK_GetAddr: freeaddrinfo does not need to be called on getaddrinfo failure 2025-10-29 19:06:39 +01:00
Alug 0611d49455 some i_tcp fixes
- SOCK_Get return true when receiving good packet from a lan player
- SOCK_GetAddr fix handling of ipv6 addresses, so ipv6 servers can be found in the serverlist

taken from srb2/classic
2025-10-29 19:06:36 +01:00
Alug 45ee50b47d remove reduntant stuff from D_ClearState and G_StopDemo
we only need R_ExecuteSetViewSize from splitscreen_onchange, the rest doesent do anything due to SV_StopServer call earlier setting cl_mode to CL_ABORTED
SV_StopServer also calls Y_EndIntermission and Y_EndVote if necessary
2025-10-28 01:21:38 +01:00
Alug 694a8eeb69 P_TryMove: save one R_PointInSubsector call per player
by reusing the special sector calculated earlier, this didnt change for when its checked another time
also one fixedmul in P_SceneryTryMove in some cases
2025-10-28 00:50:02 +01:00
Alug 908bba2c8a rename subsector variable in P_TryCameraMove to be more descriptive 2025-10-28 00:49:58 +01:00
Alug 88363cf45d add NOHOLEPUNCH flag to disable holepunch entirely 2025-10-27 22:58:42 +01:00
Alug 509e7140e3 use strlcpy for filling playerinfo names
MAXPLAYERNAME+1 so it copies 21 and null terminates the last
2025-10-27 21:21:39 +01:00
Alug 056f919bbe DrawTiltedSpan: more micro optimize
- do pointerdiff outside the loops, no need to do them 16 times per span
- cache tiltilighting and planezlight, mark as const and restrict
2025-10-27 00:56:21 +01:00
Alug 548cad76b2 drawspan: some type fixes, mark const and reordering 2025-10-26 14:05:12 +01:00
Alug e26fb91350 simplify vhs effect interpolation 2025-10-25 22:32:58 +02:00
Alug 28685ea658 fix some tooltips issues, wording and inconsistencies
fbo also now supports from gl 2.1
2025-10-25 20:39:01 +02:00
Alug a69df8807d fix some messed up whitespaces lel 2025-10-24 21:57:57 +02:00
Alug 26fc417555 forgor about localskin menu
Zzz....
2025-10-24 16:09:53 +02:00
Alug bb3dd435f0 oop didnt mean to move this 2025-10-24 15:49:40 +02:00
indev 16a531272f Skip repeating backslashes in HU_DoCEcho when printing to console 2025-10-24 16:36:50 +03:00
Alug ba5b79e48a dont double print kitchen sink message to log
we already handle this in HU_DoCEcho
2025-10-24 15:37:11 +02:00
Alug 59470ddbd4 fix oob access in D_SetupVote
check if luamaps was set before
2025-10-24 15:37:08 +02:00
Alug 82c4191516 Revert "SDLSetMode: render immediately after resolution change to avoid 1-frame of texture presented at wrong size"
This reverts commit 0e2ffdeb1d.
2025-10-24 04:09:43 +02:00
Alug 8a305d3c79 move those to D_ClearState 2025-10-24 03:47:59 +02:00
Alug 7c507c7b3b do some cleanup g_demo
:shook:
use the CLEANUP macro everywhere
init some things that may not be initialized
and make this more readable
lets hope didnt break anything Zzz...
TODO: if there are still issues with demo records and stuff crashing might consider porting some of the fixes from RR
2025-10-24 03:44:56 +02:00
Alug ca27dad6c1 use D_ClearState in G_StopDemo
actually fixes issues with crashes AND palette reset
also resets a bunch of more stuff which def is good
2025-10-24 03:44:53 +02:00
Alug 383d55cac6 smol cleanup V_DrawVhsEffect
dont need to assign all the software stuff in gl mode
2025-10-24 03:37:45 +02:00
James R. 0e2ffdeb1d SDLSetMode: render immediately after resolution change to avoid 1-frame of texture presented at wrong size 2025-10-24 01:55:20 +02:00
Alug b84d101337 initialize sdl window,renderer and texture to something 2025-10-24 01:55:17 +02:00
Alug 852aa74d62 random style fixes and stuff 2025-10-23 21:01:20 +02:00
Alug aa06459c09 set special case for console key when using native keyboard input
ALWAYS make sure that remains in the same physical place
otherwise things might get very annoying
it already does so with my german layout
2025-10-23 21:01:20 +02:00
Alug c07502bf5a use strl instead of strn stuff to copy cecho text
ALOT safer than whatever this did before
2025-10-23 20:51:24 +02:00
Alug f751161693 fix CECHO text being overwritten with nothing
strlcat not strlcpy
2025-10-23 20:37:57 +02:00
toaster ed16c4fd9f Simplify intermission timer code
- We had two ways of ending the intermission, but only one would actually be used, and it resulted in code duplication.
- Combine the two ways.
- Disable the reached-but-didn't-do-anything-before-now code path for setting endtic.
2025-10-22 23:08:43 +02:00
Alug 41407538d4 cleanup + optimizations mixer_sound
thx indev for the better ms rounding code <3
2025-10-22 22:53:14 +02:00
Alug 5f394cd938 handle more memory allocation failure cases
reported with -Wformat-overflow
2025-10-22 16:02:35 +02:00
Alug e5bae89d0f fix namescrollbuf and mapmusic.name copies
ensure those are properly null terminated
as reported by ubsan
2025-10-22 15:34:43 +02:00
Alug f749800276 fix playersetup skin speen reading out of bounds
reported by ubsan
2025-10-22 15:34:40 +02:00
Alug 5289027272 uninline ctf resynch stuff
this wont ever be used and just makes lto and others complain occasionally (maybe frenmod uses ctf? forgor)
2025-10-22 15:34:38 +02:00
Alug 77f4d4ef3b fix replays occasionally crashing when stopping
due to R_ReInitColormaps our extra_colormaps pointer may be freed
so ensure it only gets called after gamestate has been set to GS_NULL so we dont risk doing this mid renderframe
fixes crashes in software and palette render mode
2025-10-22 13:48:56 +02:00
AJ Martinez a94740f5e9 Fix unsteady camera movement in demos 2025-10-22 13:44:32 +02:00
toaster ab27090ecf Don't send a netxcmd when using addfile outside of netgame
Was supposed to be happening already, but `multiplayer` is a useless variable...
2025-10-22 11:32:49 +02:00
Alug 93d0106c28 remove erronous ";" 2025-10-22 11:32:46 +02:00
Alug 27433f6fb5 call R_SetupFreelook in R_ExecuteSetViewSize
to instantly update our now stale yslope pointer!
fixes random crashes when switching numbers of splitviews in replays
2025-10-21 19:26:31 +02:00
Alug f8e5049d76 fix R_MakeSpans accessing "spanstart" out of bounds when in splitscreen
it gets allocated for viewheight not vid.height!
2025-10-21 19:26:27 +02:00
Alug 2009cdeaeb init few more things 2025-10-21 18:36:05 +02:00
Alug 0f43f19b71 remove unused maskdraw_t struct 2025-10-21 18:01:03 +02:00
Alug 1ac7852bd2 initialize a bunch of stuff that gets passed to realloc 2025-10-21 17:52:21 +02:00
indev f5e7b65ae0 Fix replay names not displaying if you have more than INT16_MAX replays 2025-10-21 17:11:45 +03:00
Alug 4c5d34e82c Revert "Fix ghost hitlist causing zone errors (closes #118)"
This reverts commit ab13b28106.
2025-10-21 16:09:02 +02:00
Alug 0dad927c05 fix 4th player background not drawin in gl in 3 player splitscreen 2025-10-21 15:42:33 +02:00
Alug f231417465 fix splitscreen view in gl 2025-10-21 15:27:05 +02:00
Alug 51b8dc9101 m_menu: add textinput special case for playername string
itself it already checks to not write out of bounds, this is mostly just to fix visual issues
kind hacky, but works for now
2025-10-21 14:45:10 +02:00
Alug 71e9c4f5af use "viewssnum" for shadowdir stuff 2025-10-21 14:34:33 +02:00
Alug 1acae3e4af use malloc for spawnstate mapdata copies
they might be somewhat large and get completely overwritten eitherway so save us the 0 init
2025-10-21 14:34:30 +02:00
Alug 4c04d09d18 rename 2025-10-21 14:34:28 +02:00
indev b99cd88947 Fix possible buffer overflow in M_TextInputSetString when string length is greatter than buffer length 2025-10-21 01:46:39 +03:00
Alug 4a786449c4 fix NIGHTS hoop hoopcenter
fixes visual issues when going through them
2025-10-20 19:48:28 +02:00
Alug aef6dcdbc9 handle ceepeepee 2025-10-20 19:25:41 +02:00
Alug 0e9ec096c2 slightly clean up makefile
- pass "-g" on mingw builds generally after everything (needs testing)
-use "libs" instead of "LDFLAGS" (identical purpose)
- pass "mno-ms-bitfields" on gcc, shouldnt be really needed but just in case
2025-10-20 17:02:36 +01:00
Alug 50ce3c4431 R_FlushQuad: dont use 64bit/8byte copy on 32bit targets
on 32bit targets this will just compile into two 32bit copies which gcc cant optimize as well as it can with the byte copy (it seems to love to do some AVX stuff atleast in my tests)
so this is only useful for 64bit capable platforms (compiler does not seem to do 64bit copys for the byte copy case, so this ends up being faster)
2025-10-20 16:32:48 +02:00
Alug c6c1dbd066 R_FlushQuad: also check "source" for alignment 2025-10-20 16:17:01 +02:00
Alug ece8d9e80c R_FlushQuad: fix column flush on odd width resolutions 2025-10-20 00:56:30 +02:00
Alug fdcbd276e9 remove unessecaary template branch in R_DrawColumnPixel 2025-10-19 23:07:21 +02:00
Alug 6d77672ee3 no need to pass anything to R_InitViewBuffer 2025-10-19 22:19:20 +02:00
Alug 28aec6cad5 add USEUBSAN compiler flag
to compile with ubsan duh
2025-10-19 21:59:39 +02:00
Alug 1f028f523e R_FlushQuad: fix unaligned memory access 2025-10-19 21:59:35 +02:00
Alug 349bf06e4b macrofy column function definitions 2025-10-19 21:59:32 +02:00
Alug e044db73f5 those should be initialised to something 2025-10-19 21:59:29 +02:00
Alug 7555d689db clear our column buffer after allocation 2025-10-19 21:59:27 +02:00
Alug a6438da531 use spawn sector and line tags for P_ReloadSaveLevelData
should speed up resynch a little, now that we properly save them
2025-10-18 23:11:00 +02:00
Alug 8c6893cff6 init taglists in P_LoadMapData
no reason to init them in P_SpawnSpecials
fixes join crashes on some maps
2025-10-18 23:04:25 +02:00
Alug af03b51191 add guard to vid.screens free
not super necessary but better safe than sorry
2025-10-18 21:34:23 +02:00
Alug 178d8b7b53 fix demo_slug compiler warning
Zzz....
2025-10-18 16:15:19 +02:00
NepDisk de99a3036d Update Discord RPC
Based on some of the changes from RR.
Accounts for the fact discord does not have tags anymore and makes skin code easier to manage
2025-10-18 16:15:17 +02:00
NepDisk 5c613f6c8f Use a constant for file path stuff 2025-10-18 16:15:14 +02:00
James R 59628377fa Resize menudemo_t filepath to fix -Wformat-truncation 2025-10-18 16:15:11 +02:00
Alug 278f3c3ef6 turnsmoothing splitscreen player support
i hate our menus Zzz....
2025-10-17 09:24:33 +02:00
Alug 3ba1596976 change wheel input "sensitivity"
200 maps perfectly to our turn values
so the wheel now actually better reflects the inputs and does not turn fully super early uhh
2025-10-16 23:15:42 +02:00
Alug 02f6fa0665 HACK: call texture precache when toggling a setting that flushes opengl textures
workaround for batching sort issues
should be good eitherway to reduce stutters after toggling them
2025-10-16 22:21:37 +02:00
Alug f4aec1d591 port "Lite Steer" from RR
took me a while to realize RR makes everything go though "analogue" input handlers
2025-10-16 21:53:40 +02:00
Alug 5c2a87dea6 fix off by one when playing with controller sticks
also simplify driftturn handling
2025-10-16 21:53:37 +02:00
Alug d5aa9ae0f1 fix 32bit windoze compile
again......
2025-10-16 15:07:35 +01:00
indev 6096822cbb Use str.resize(size) instead of str = str.substr(0, size) (ty lug <3) 2025-10-16 15:16:23 +03:00
Alug 0030367649 fix UB in R_PointOnSide
by not shifting a 32bit int by 31 bits
this is more in line with the original function eitherways
2025-10-16 14:08:30 +02:00
Alug 66f67c91e8 G_SaveDemo: fix oob reads/writes for replay names
demo.titlename has a size of 65! not 128!
also handles memory failure and checks bounds for the remaining lenght in the demo slug
2025-10-16 14:01:02 +02:00
Alug c73c1af2d5 let replays with empty name save
this does not crash for us
2025-10-16 14:00:57 +02:00
toaster 638e95325a G_SaveDemo: Resolve memory errors that could result in crashes
- Empty `demo.titlename` case
    - Don't try to save demo of name `.lmp`
    - Doesn't fall back to anything, because emptying out the name field can be reasonably treated as not wanting to save
- `demo.titlename` consists only of invalid characters
    - Don't try to save demo of name `-.lmp`
    - Falls back to the default demo title, because the user clearly wanted to save and just happened to provide invalid text
2025-10-16 14:00:55 +02:00
Alug 66ce745e91 add allocation failure case in R_DrawMasked 2025-10-16 14:00:51 +02:00
Alug 2b39d137b4 guard against null string in stringwidth functions
hud drawlists may actually pass null to them
2025-10-16 14:00:48 +02:00
Alug 1ed616dcef pass rover directly to check_fof_offscreen 2025-10-16 14:00:45 +02:00
indev 24ef2819b0 Merge pull request #205 from Indev450/dsdacol
Software Renderer: Implement Column buffering system
2025-10-15 21:52:45 +03:00
Alug a9732e9564 Merge branch 'Saturn-Next' into dsdacol 2025-10-15 20:51:47 +02:00
Alug c262d3f532 prevent potential 0 division in CV_AddValue
as repoted by clang-tidy
2025-10-15 20:41:57 +02:00
Alug ae456fee31 force inline savegame archive stuff 2025-10-15 17:05:05 +02:00
LJ Sonic 68f69049d4 Fix incorrect error message during Lua archiving 2025-10-15 17:05:02 +02:00
LJ Sonic e180918e48 Do not archive nil table keys 2025-10-15 17:04:59 +02:00
Alam Ed Arias 951c090b35 set CURLOPT_MAXREDIRS to 30 2025-10-15 17:04:55 +02:00
Gustaf Alhäll a87e07155a Remove WINSOCK1 support
WINSOCK2 has been supported since Windows XP and is required for IPv6,
so I don't see a reason to support it anymore.
2025-10-15 17:04:52 +02:00
Alug da16ce3a23 mark flush error functions with noreturn
silences clang
2025-10-15 06:28:54 +02:00
Alug 64bdae5e5d delet dead code ogl models 2025-10-15 06:16:46 +02:00
Alug 4f91a0b234 remove dead renderer code
remove
- broken viewborder code (if we really want it back for some reason, we should rather port RR´s fixed version of it)
- remove console clipping code for software (this was broken eiherway)
- remove hud message clearing stuff
- remove renderscreen and linesize variables (they just pointed to vid.screen and vid.widht)
2025-10-15 06:16:46 +02:00
Alug bb0a59540f use stdlibs abs for CompareDrawNodePlanes
we dont need our own abs for this
2025-10-15 06:16:46 +02:00
Alug dd9d6de0d6 delet gl_viewwidth, gl_viewheight, gl_baseviewwindowx, gl_baseviewwindowy gl_basewindowcenterx, gl_basewindowcentery
they were effectively unused
2025-10-15 06:16:46 +02:00
Alug 3de4c7cbad Merge branch 'Saturn-Next' into dsdacol 2025-10-14 23:14:24 +02:00
Alug 0eeacaf51e remove dead renderer code
remove
- broken viewborder code (if we really want it back for some reason, we should rather port RR´s fixed version of it)
- remove console clipping code for software (this was broken eiherway)
- remove hud message clearing stuff
- remove renderscreen and linesize variables (they just pointed to vid.screen and vid.widht)
2025-10-14 23:14:07 +02:00
Alug a4684b3004 use stdlibs abs for CompareDrawNodePlanes
we dont need our own abs for this
2025-10-14 23:13:52 +02:00
Alug 9c014eb2ea delet gl_viewwidth, gl_viewheight, gl_baseviewwindowx, gl_baseviewwindowy gl_basewindowcenterx, gl_basewindowcentery
they were effectively unused
the last two werent ever even initialized to anything, using HWR_DrawViewBorder wouldve crashed
2025-10-14 23:13:49 +02:00
Alug 37579187cc remove dead renderer code
remove
- broken viewborder code (if we really want it back for some reason, we should rather port RR´s fixed version of it)
- remove console clipping code for software (this was broken eiherway)
- remove hud message clearing stuff
- remove renderscreen and linesize variables (they just pointed to vid.screen and vid.widht)
2025-10-14 23:13:39 +02:00
Alug af8ce028ba use stdlibs abs for CompareDrawNodePlanes
we dont need our own abs for this
2025-10-14 23:12:50 +02:00
Alug 9310a68cff delet gl_viewwidth, gl_viewheight, gl_baseviewwindowx, gl_baseviewwindowy gl_basewindowcenterx, gl_basewindowcentery
they were effectively unused
the last two werent ever even initialized to anything, using HWR_DrawViewBorder wouldve crashed
2025-10-14 23:12:47 +02:00
Hanicef 89b8121282 Fix vertical aim being off when using lack of perspective 2025-10-14 22:28:18 +02:00
Alug b2260bbebb move R_SetColumnContext call
we set this later to flush eitherway for non skybox draw
2025-10-13 21:27:43 +02:00
Alug 6a9aea4dd1 use std::vector for our image buffers
this is just to have it cleaner and less code bloat
the resizing loop will almost never trigger, 1meg is enough to even rotate gigantamax eevee without needing to grow
2025-10-13 19:20:40 +02:00
Eidolon 6f4dfb35fa Calculate staging buffer maximum size in Picture_Convert 2025-10-13 19:20:37 +02:00
Alug 459b2e62ce oops missed this case 2025-10-12 23:12:26 +02:00
Alug 5765f3df5a this does not need marked as restrict 2025-10-12 22:30:25 +02:00
Alug 8488da4b1a smol style adjustment span stuff 2025-10-12 22:11:39 +02:00
Alug c82495f48b tiny optimization span drawers
if we dont "ripple" our spans, we dont need to increment an additional pointer for them
2025-10-12 22:11:36 +02:00
Alug f55b8793ec Merge branch 'Saturn-Next' into dsdacol 2025-10-12 22:11:23 +02:00
Alug b0b048c703 move "newview sky" check before skyplane loop
saves us some pointless work going through all planes if we dont need to draw the sky
2025-10-10 23:37:20 +02:00
Alug b7f1a0b631 speed up masked sprites a bit
thx eternity engine!
2025-10-10 22:33:04 +02:00
Alug 513613d83b dont update hud during skipped frames
this was to fix issues with some lua huds looking really bad during frameskip
but this causes issues with the hud flashing during gif recording
2025-10-09 19:13:09 +02:00
Alug f2afc5135c fix buffer overflows in dedi build too 2025-10-09 18:17:09 +02:00
K J 3783e30a8a fix: multiple additional buffer overruns
found by Zwip-Zwap_Zapony
2025-10-09 18:11:59 +02:00
Alug ff80a34627 unnest fsp counter and ping display stuff 2025-10-09 18:01:27 +02:00
Alug 38c96d5ec2 Merge branch 'Saturn-Next' into dsdacol 2025-10-08 21:38:26 +02:00
Alug 2ec467f062 check with "__SIZEOF_POINTER__" 2025-10-08 21:38:20 +02:00
Alug b3106d55d1 inline R_ThingLightLevel
just points to thing->lightlevel field eitherway
2025-10-08 21:38:17 +02:00
Alug 90c3d02dbf ensure columnbuffer gets flushed during portal traversal
in worst case this does nothing btw
2025-10-08 20:46:37 +02:00
Alug 48dc5461cd cleanup column flusher stuff
- properly make use of templates!, reduce code dupe
- inline the "DrawPixel" stuff
- use local "const" pointers everywhere
2025-10-08 16:50:17 +02:00
Alug 0843a586f8 fuckit, lets buffer 8 columns instead of 4
improves performance across the board on my ryzen 5600 cpu
between 10 -15fps + in best case and around 5fps+ in worst case
will need to check how this affects older cpus and 32bit builds since we do 64bit copies now
(if needed can always add 32bit specific code)
effectively, we also reduce the amount of flushing needed in many cases, writing more things at once during flushes
2025-10-08 16:47:54 +02:00
Alug 8c8f96cf49 force flush our column buffer directly after bsp traversal (again)
TODO: actually check what portals do
2025-10-08 16:47:54 +02:00
Alug 55afe9be7e update copyright header for draw flush stuff 2025-10-08 16:47:54 +02:00
Alug fe54f2fba2 add Column drawer context switching
reasoning explained in screen.c
effectively, there are cases where drawing our columns directly to the screen is the better choice
2025-10-08 16:47:54 +02:00
Alug b12989f51c lessen our manual column buffer resetting
not really needed
2025-10-08 16:47:54 +02:00
Alug 57990100c5 speed up masked sprites a bit
thx eternity engine!
2025-10-08 16:47:54 +02:00
Alug 32504b9e8e speed up Opague quad flush
from eternity engine
2025-10-08 16:47:54 +02:00
Alug ba3404d823 cleanup + type fixes 2025-10-08 16:47:54 +02:00
Alug c9f50ca0c8 sizeof(UINT8) is 1 lel 2025-10-08 16:47:54 +02:00
Alug b6943ce92e can check on compile if sizeof int == 4
can prob remove it alltogether we dont support 16 bit cpus kek
2025-10-08 16:47:54 +02:00
Alug 41b78feef5 remove R_GetColumnTranslucent 2025-10-08 16:47:54 +02:00
Alug c9b6276a02 merge sky column drawer back
lets hope this is safe lulul
2025-10-08 16:47:54 +02:00
Alug 39a5165d91 reset our column buffer directly after bsp traversal
we do not need to wait for sky draw since the sky gets instantly drawn
2025-10-08 16:47:54 +02:00
Alug e5a03dc3bb fix translucency being only half as translucent
oops lmao didnt notice in all of this doom uses the inverse of our blendlevels kek
2025-10-08 16:47:54 +02:00
Alug 4deebf8912 translucency is handled on the flush side! 2025-10-08 16:47:54 +02:00
Alug fa8901f6b0 fix ColumnFlushType enum 2025-10-08 16:47:54 +02:00
Alug 23512f0a6c align our tempbuf 2025-10-08 16:47:54 +02:00
Alug b44548b7ac dedupe those a bit 2025-10-08 16:47:54 +02:00
Alug 955812bd8d template the flush functions 2025-10-08 16:47:54 +02:00
indev e4ac394d29 Fix DC_COLORMAP and DC_TRANSMAP column drawers always using DC_COLORMAP|DC_TRANSMAP func 2025-10-08 16:47:54 +02:00
Alug 2b6185d7d6 reenable colormapped / translucent columns 2025-10-08 16:47:54 +02:00
Alug 2753052ee7 fix FlushColumns being called without being initialized
aack
2025-10-08 16:47:54 +02:00
Alug 3c9292c137 reorder column flush functions
also add some comments that used to be in drawcolumn X)
2025-10-08 16:47:54 +02:00
Alug e68136de3e remove tempbuf resolution limit
by allocating it dynamically per our actual screen resolution
2025-10-08 16:47:54 +02:00
Alug e852c23441 move the temp columndata into a struct
TODO:dynamic allocate our temporary screen buffer
2025-10-08 16:47:54 +02:00
Alug 031e8ee477 WIP: column buffering/flushing system
it "works" so far no performance improvement
everything but fully opague columns dont work for now until fixed
really messy and needs to be templated when working

from prboom & eternity engine
2025-10-08 16:47:54 +02:00
indev d7422b8ec9 Don't I_Error in W_InitFileError, that causes dedicated servers to bootloop 2025-10-06 17:44:47 +03:00
James R 0bbd8246cc Read only header bytes when creating textures list
R_LoadTextures was reading in the entirety of every
texture lump, now it only reads the 8 byte PNG header.
This saved more than 1 second for me (1.68 s -> 0.24 s).

PNG still need to be read in entirely to check their
dimensions; I didn't bother looking into optimizing it
since we don't have many PNG textures right now.
2025-10-05 20:59:40 +02:00
Alug 9e8ddd5f9e add a print to Joinable_OnChange
also change the other cvar messages to CONS_NOTICE
2025-10-05 20:39:09 +02:00
indev 3964d4e188 Always initialize all column offsets inside multi-patch textures 2025-10-05 21:12:46 +03:00
Alug 005af4362e remove unused W_LumpLenghtPwad call from R_GenerateTexture 2025-10-05 20:11:05 +02:00
Alug f817676033 fix uninitialized "i" counter in R_StoreWallRange 2025-10-05 20:10:49 +02:00
Alug 79140b3bdc fix oopsie in R_GenerateTexture 2025-10-05 20:10:46 +02:00
Alug 48722ef591 fix oob access in CV_AddValue and M_CanShowLevelInList
lets hope this doesent break anything Zzz....
2025-10-05 20:10:42 +02:00
Alug 6be5478fa8 dont free levelstate in D_ClearState
Titledemos be damned!
2025-10-05 20:10:36 +02:00
James R 953d9d15d6 Clear g_dc each frame
I was running into a memcpy of overlapping memory regions
in R_RenderMaskedSegRange.

- This is because of the reallocation of lightlists, which
  uses Z_Frame_Alloc.
- The memory pool that Z_Frame_Alloc draws from is cleared
  each frame.
- g_dc was not cleared though, so when the lightlists were
  reallocated, it'd try to copy from invalidated pointers.
- Access to invalid pointers within the memory pool does
  not cause a segfault directly (because the memory pool
  is allocated once). However, a memcpy involving such an
  invalid pointer leads to overlap, which may cause memory
  corruption.
2025-10-05 20:10:33 +02:00
Alug 0c56755e09 fix R_MarkSegBounds 2025-10-05 20:10:30 +02:00
Lactozilla c166075754 Don't generate textures in R_GetColumn 2025-10-05 20:10:27 +02:00
Alug 90ff1c4fc0 small fixups for r_segs 2025-10-05 20:10:23 +02:00
Alug 1d0fedddfd add bounds check to R_GetLinedefTransTable 2025-10-05 20:10:20 +02:00
Alug f5b60c3f36 port "Use separate table for maskedtexturecol"
from: https://git.do.srb2.org/STJr/SRB2/-/commit/97311dc5b00ab232a6e898c085c20d2f6bdbfa3b

~~cherry-picking this would be horrendous sry~~
2025-10-05 20:10:16 +02:00
Alug 78ad3e9710 some fixes for texture generation
- Fix negative y offsets for both normal and y-flipped patches
- simplify column wrapping/nonpow2 handling
- Single-patch textures: print an error if patch header is missing, cease memory errors

sadly does not fix our invalid columns we get occasionally
2025-10-05 20:10:13 +02:00
Alug b03d5c53ed simplify titledlighting stuff for span drawers
- use a std::vector for the tiltlightbufffer, only for easier checking if it needs to be resized from resolution change
- move stuff into its own function
- simplify R_CalcTiltedLighting
no functional change, no performance improvement, just looks neater
2025-10-04 22:05:07 +02:00
indev c5dce0e785 oops 2025-10-04 17:25:39 +03:00
indev f85c7ef961 Copyleft :3 2025-10-04 17:25:03 +03:00
Alug 4d211f8f82 Merge branch 'updatelibbacktrace' into Saturn-Next 2025-10-03 22:42:28 +01:00
Alug 8d3435291b fix windows compile 2025-10-03 22:41:02 +01:00
Alug 8f007155cd update libbacktrace (win x64) 2025-10-03 21:36:49 +01:00
Alug 58a38ac6c4 add "SATURN_TESTING" define
currently to hide the commit string from titlescreen on release builds
could be used for other crap
wish could use comptime to autogenerate this, but it runs after compile & linking
2025-10-03 16:40:31 +02:00
Alug 1e1dbfc450 oops all include guards 2025-10-03 16:39:51 +02:00
Alug 2eac9fc295 tiny cleanup p_map
also save a little division and abs
2025-10-03 16:39:48 +02:00
indev 4416be2ddc Merge pull request #203 from Indev450/curl-cli-args
CURL cli args
2025-10-02 19:00:29 +03:00
114 changed files with 3277 additions and 3366 deletions

No files matched your search

+4 -4
View File
@@ -5,13 +5,13 @@
# met:
# (1) Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# notice, this list of conditions and the following disclaimer.
# (2) Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# distribution.
# (3) The name of the author may not be used to
# endorse or promote products derived from this software without
# specific prior written permission.
@@ -26,4 +26,4 @@
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# POSSIBILITY OF SUCH DAMAGE.
+11 -1
View File
@@ -10,8 +10,18 @@ The libbacktrace library may be linked into a program or library and
used to produce symbolic backtraces.
Sample uses would be to print a detailed backtrace when an error
occurs or to gather detailed profiling information.
In general the functions provided by this library are async-signal-safe,
meaning that they may be safely called from a signal handler.
That said, on systems that use `dl_iterate_phdr`, such as GNU/Linux,
the first call to a libbacktrace function will call `dl_iterate_phdr`,
which is not in general async-signal-safe. Therefore, programs
that call libbacktrace from a signal handler should ensure that they
make an initial call from outside of a signal handler.
Similar considerations apply when arranging to call libbacktrace
from within malloc; `dl_iterate_phdr` can also call malloc,
so make an initial call to a libbacktrace function outside of
malloc before trying to call libbacktrace functions within malloc.
The libbacktrace library is provided under a BSD license.
See the source files for the exact license text.
@@ -25,7 +35,7 @@ will work.
See the source file backtrace-supported.h.in for the macros that it
defines.
As of October 2020, libbacktrace supports ELF, PE/COFF, Mach-O, and
As of July 2024, libbacktrace supports ELF, PE/COFF, Mach-O, and
XCOFF executables with DWARF debugging information.
In other words, it supports GNU/Linux, *BSD, macOS, Windows, and AIX.
The library is written to make it straightforward to add support for
Binary file not shown.
@@ -0,0 +1,41 @@
# libbacktrace.la - a libtool library file
# Generated by libtool (GNU libtool 1.3134 2009-11-29) 2.2.7a
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname=''
# Names of this library.
library_names=''
# The name of the static archive.
old_library='libbacktrace.a'
# Linker flags that can not go in dependency_libs.
inherited_linker_flags=''
# Libraries that this one depends upon.
dependency_libs=''
# Names of additional weak libraries provided by this library
weak_library_names=''
# Version information for libbacktrace.
current=0
age=0
revision=0
# Is this an already installed library?
installed=no
# Should we warn about portability when linking against -modules?
shouldnotlink=no
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/mingw64/lib'
@@ -0,0 +1,41 @@
# libbacktrace.la - a libtool library file
# Generated by libtool (GNU libtool 1.3134 2009-11-29) 2.2.7a
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname=''
# Names of this library.
library_names=''
# The name of the static archive.
old_library='libbacktrace.a'
# Linker flags that can not go in dependency_libs.
inherited_linker_flags=''
# Libraries that this one depends upon.
dependency_libs=''
# Names of additional weak libraries provided by this library
weak_library_names=''
# Version information for libbacktrace.
current=0
age=0
revision=0
# Is this an already installed library?
installed=yes
# Should we warn about portability when linking against -modules?
shouldnotlink=no
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/mingw64/lib'
+22 -13
View File
@@ -49,6 +49,7 @@
# Already enabled by default for 32-bit
# Windows.
# NOCURL=1 - Disable libcurl--HTTP capability.
# NOHOLEPUNCH=1 - Disable holepunch capability.
# NOLIBGME=1 - Disable game music emu, retro VGM support.
# NOOPENMPT=1 - Disable module (tracker) music support.
# NOMIXER=1 - Disable SDL Mixer (audio playback).
@@ -69,6 +70,7 @@
# VALGRIND=1 - Enable Valgrind memory debugging support.
# PROFILEMODE=1 - Enable performance profiling (gprof).
# USEASAN=1 - Enable building with Address Sanitizer.
# USEUBSAN=1 - Enable building with Undefined Behavior Sanitizer.
# NOLIBBACKTRACE=1 - Disable using Libbacktrace for crashlog traces.
#
# General flags for building:
@@ -243,10 +245,14 @@ ifdef STATIC
libs+=-static
endif
ifneq (,$(filter $(CC) $(CXX),gcc g++))
opts+=-mno-ms-bitfields
endif
# build with profiling information
ifdef PROFILEMODE
opts+=-pg
LDFLAGS+=-pg
libs+=-pg
endif
ifdef DEBUGMODE
@@ -256,29 +262,32 @@ debug_opts=-DNDEBUG
opts+=-O3
ifdef USELTO
# compile with LTO
ifdef MINGW
opts+=-flto=auto -g
LDFLAGS+=-flto=auto -g
else
opts+=-flto=auto
LDFLAGS+=-flto=auto
endif
libs+=-flto=auto
endif
endif
ifdef USEASAN
# compile with asan
ifdef MINGW
opts+=-fsanitize=address -g
libs+=-fsanitize=address -g
else
opts+=-fsanitize=address
libs+=-fsanitize=address
endif
ifdef USEUBSAN
# compile with asan
opts+=-fsanitize=undefined
libs+=-fsanitize=undefined
endif
ifeq ($(CC),clang)
LDFLAGS+= -fuse-ld=lld
ifneq (,$(filter $(CC) $(CXX),clang clang++))
libs+=-fuse-ld=lld
endif
ifdef MINGW
# mingw needs this passed AFTER lto and the likes were passed
# otherwise libbacktrace may break
opts+=-g
libs+=-g
endif
# debug_opts also get passed to windres
+2 -1
View File
@@ -6,7 +6,8 @@ passthru_opts+=\
NOHW NOMD5 NOPOSTPROCESSING\
MOBJCONSISTANCY PACKETDROP ZDEBUG\
HAVE_MINIUPNPC\
HAVE_DISCORDRPC DEVELOP
HAVE_DISCORDRPC DEVELOP\
NOHOLEPUNCH\
# build with debugging information
ifdef DEBUGMODE
+1 -1
View File
@@ -10,7 +10,7 @@
makedir:=$(makedir)/SDL
opts+=-DDIRECTFULLSCREEN -DHAVE_SDL
opts+=-DHAVE_SDL
sources+=$(call List,sdl/Sourcefile)
NOUPNP=1
+3 -1
View File
@@ -2,6 +2,8 @@
# Mingw, if you don't know, that's Win32/Win64
#
sources+=$(call List,win32/Sourcefile)
ifndef MINGW64
EXENAME?=srb2kart-saturn_32bit.exe
else
@@ -95,7 +97,7 @@ LIBBACKTRACE_libs:=-L$(lib)/lib/x86_64 -lbacktrace
$(eval $(call _set,LIBBACKTRACE))
else
lib:=../libs/drmingw
opts+=-I$(lib)/include
opts+=-I$(lib)/include -DHAVE_DRMINGW
libs+=-L$(lib)/lib/win32 -lmgwhelp -lexchndl
endif
+1 -1
View File
@@ -53,7 +53,7 @@ r_data.c
r_draw.c
r_fps.cpp
r_main.cpp
r_patch.c
r_patch.cpp
r_patchrotation.c
r_plane.cpp
r_segs.cpp
+2 -2
View File
@@ -110,7 +110,7 @@ void I_Error(const char *error, ...)
char logbuf[8192];
va_start(argptr, error);
vsprintf(logbuf, error, argptr);
vsnprintf(logbuf, 8192, error, argptr);
va_end(argptr);
LOGE(logbuf);
@@ -166,7 +166,7 @@ void I_OutputMsg(const char *fmt, ...)
char logbuf[8192];
va_start(argptr, fmt);
vsprintf(logbuf, fmt, argptr);
vsnprintf(logbuf, 8192, fmt, argptr);
va_end(argptr);
LOGD(logbuf);
+5
View File
@@ -10,8 +10,13 @@
/// \file b_bot.h
/// \brief Basic bot handling
#ifndef __B_BOT__
#define __B_BOT__
void B_BuildTiccmd(player_t *player, ticcmd_t *cmd);
void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward, boolean left, boolean right, boolean strafeleft, boolean straferight, boolean jump, boolean spin);
boolean B_CheckRespawn(player_t *player);
void B_MoveBlocked(player_t *player);
void B_RespawnBot(INT32 playernum);
#endif
+23 -20
View File
@@ -700,6 +700,7 @@ static void COM_Echo_f(void)
for (i = 1; i < COM_Argc(); i++)
CONS_Printf("%s ", COM_Argv(i));
CONS_Printf("\n");
}
@@ -708,11 +709,11 @@ static void COM_Echo_f(void)
static void COM_CEcho_f(void)
{
size_t i;
char cechotext[1024] = "";
char cechotext[1024] = {0};
for (i = 1; i < COM_Argc(); i++)
{
strlcpy(cechotext, COM_Argv(i), sizeof(cechotext)-1);
strlcat(cechotext, COM_Argv(i), sizeof(cechotext)-1);
strlcat(cechotext, " ", sizeof(cechotext)-1);
}
@@ -938,6 +939,8 @@ static void COM_Find_f(void)
}
help = COM_Argv(1);
if (!help)
return;
helplen = strlen(help);
CONS_Printf("\x82""Variables:\n");
matchesany = false;
@@ -1650,13 +1653,13 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
UINT8 *p = buf;
if (!(server || (IsPlayerAdmin(consoleplayer))))
{
CONS_Printf(M_GetText("Only the server or admin can change: %s %s\n"), var->name, var->string);
CONS_Alert(CONS_NOTICE, "Only the server or admin can change: %s %s\n", var->name, var->string);
return;
}
if (var == &cv_kartencore && !M_SecretUnlocked(SECRET_ENCORE))
{
CONS_Printf(M_GetText("You haven't unlocked Encore Mode yet!\n"));
CONS_Alert(CONS_NOTICE, "You haven't unlocked Encore Mode yet!\n");
return;
}
@@ -1664,7 +1667,7 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
{
if (!stricmp(value, "Hard") || atoi(value) == 2)
{
CONS_Printf(M_GetText("You haven't unlocked this yet!\n"));
CONS_Alert(CONS_NOTICE, "You haven't unlocked this yet!\n");
return;
}
}
@@ -1681,14 +1684,13 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
else
Setvalue(var, value, stealth);
}
else if ((var->flags & CV_NOTINNET) && netgame)
{
CONS_Alert(CONS_NOTICE, "This variable can't be changed while in netgame: %s %s\n", var->name, var->string);
return;
}
else
if ((var->flags & CV_NOTINNET) && netgame)
{
CONS_Printf(M_GetText("This variable can't be changed while in netgame: %s %s\n"), var->name, var->string);
return;
}
else
Setvalue(var, value, stealth);
Setvalue(var, value, stealth);
}
/** Sets a value to a variable without calling its callback function.
@@ -1771,7 +1773,7 @@ void CV_AddValue(consvar_t *var, INT32 increment)
newvalue = var->value - 1;
do
{
if(increment > 0) // Going up!
if (increment > 0) // Going up!
{
if (++newvalue == NUMMAPS)
newvalue = -1;
@@ -1785,7 +1787,7 @@ void CV_AddValue(consvar_t *var, INT32 increment)
if (newvalue == oldvalue)
break; // don't loop forever if there's none of a certain gametype
if(!mapheaderinfo[newvalue])
if (newvalue >= 0 && !mapheaderinfo[newvalue])
continue; // Don't allocate the header. That just makes memory usage skyrocket.
} while (!M_CanShowLevelInList(newvalue, gt));
@@ -1914,13 +1916,14 @@ void CV_AddValue(consvar_t *var, INT32 increment)
max = (M_SecretUnlocked(SECRET_HARDSPEED) ? 3 : 2);
}
#ifdef PARANOIA
if (currentindice == -1)
I_Error("CV_AddValue: current value %d not found in possible value\n",
var->value);
if (currentindice == -1 || max == 0)
I_Error("CV_AddValue: current value %d not found in possible value\n", var->value);
#endif
newindice = (currentindice + increment + max) % max;
CV_Set(var, var->PossibleValue[newindice].strvalue);
if (max > 0)
{
newindice = (currentindice + increment + max) % max;
CV_Set(var, var->PossibleValue[newindice].strvalue);
}
}
}
else
+2 -33
View File
@@ -69,14 +69,9 @@ static boolean consoleready; // console prompt is ready
INT32 con_destlines; // vid lines used by console at final position
static INT32 con_curlines; // vid lines currently used by console
INT32 con_clipviewtop; // (useless)
static UINT8 con_hudlines; // number of console heads up message lines
static UINT32 con_hudtime[MAXHUDLINES]; // remaining time of display for hud msg lines
INT32 con_clearlines; // top screen lines to refresh when view reduced
boolean con_hudupdate; // when messages scroll, we need a backgrnd refresh
// console text output
static char *con_line; // console text output current line
static size_t con_cx; // cursor position in current line
@@ -393,9 +388,6 @@ void CON_Init(void)
Lock_state();
//note: CON_Ticker should always execute at least once before D_Display()
con_clipviewtop = -1; // -1 does not clip
con_hudlines = atoi(cons_hudlines.defaultvalue);
Unlock_state();
@@ -727,7 +719,6 @@ void CON_ToggleOff(void)
con_curlines = 0;
CON_ClearHUD();
con_forcepic = 0;
con_clipviewtop = -1; // remove console clipping of view
I_SetTextInput(false);
@@ -779,18 +770,6 @@ void CON_Ticker(void)
}
}
// clip the view, so that the part under the console is not drawn
con_clipviewtop = -1;
if (cons_backpic.value) // clip only when using an opaque background
{
if (con_curlines > 0)
con_clipviewtop = con_curlines - viewwindowy - 1 - 10;
// NOTE: BIG HACK::SUBTRACT 10, SO THAT WATER DON'T COPY LINES OF THE CONSOLE
// WINDOW!!! (draw some more lines behind the bottom of the console)
if (con_clipviewtop < 0)
con_clipviewtop = -1; // maybe not necessary, provided it's < 0
}
// check if console ready for prompt
if (con_destlines >= minheight)
{
@@ -1100,9 +1079,6 @@ static void CON_Linefeed(void)
con_line = &con_buffer[(con_cy%con_totallines)*con_width];
memset(con_line, ' ', con_width);
// make sure the view borders are refreshed if hud messages scroll
con_hudupdate = true; // see HU_Erase()
}
// Outputs text into the console text buffer
@@ -1282,7 +1258,7 @@ void CONS_Alert(alerttype_t level, const char *fmt, ...)
txt = malloc(8192);
va_start(argptr, fmt);
vsprintf(txt, fmt, argptr);
vsnprintf(txt, 8192, fmt, argptr);
va_end(argptr);
switch (level)
@@ -1318,7 +1294,7 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...)
txt = malloc(8192);
va_start(argptr, fmt);
vsprintf(txt, fmt, argptr);
vsnprintf(txt, 8192, fmt, argptr);
va_end(argptr);
// Again I am lazy, oh well
@@ -1489,9 +1465,6 @@ static void CON_DrawHudlines(void)
//V_DrawCharacter(x, y, (p[c]&0xff) | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
y += charheight;
}
// top screen lines that might need clearing when view is reduced
con_clearlines = y; // this is handled by HU_Erase();
}
// draw the console background, text, and prompt if enough place
@@ -1509,10 +1482,6 @@ static void CON_DrawConsole(void)
if (con_curlines <= 0)
return;
//FIXME: refresh borders only when console bg is translucent
con_clearlines = con_curlines; // clear console draw from view borders
con_hudupdate = true; // always refresh while console is on
// draw console background
if (cons_backpic.value || con_forcepic)
{
-5
View File
@@ -30,14 +30,9 @@ extern boolean con_recalc;
extern boolean con_startup;
// top clip value for view render: do not draw part of view hidden by console
extern INT32 con_clipviewtop;
// 0 means console if off, or moving out
extern INT32 con_destlines;
extern INT32 con_clearlines; // lines of top of screen to refresh
extern boolean con_hudupdate; // hud messages have changed, need refresh
extern UINT32 con_scalefactor; // console text scale factor
extern consvar_t cons_backcolor, cons_menuhighlight;
+1 -1
View File
@@ -1,4 +1,4 @@
// BLANKART
// SONIC ROBO BLAST 2 KART
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
+1 -1
View File
@@ -1,4 +1,4 @@
// BLANKART
// SONIC ROBO BLAST 2 KART
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
+1 -1
View File
@@ -1,4 +1,4 @@
// BLANKART
// SONIC ROBO BLAST 2 KART
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
+6 -8
View File
@@ -823,7 +823,7 @@ static void resynch_read_player(resynch_pak *rsp)
P_SetThingPosition(players[i].mo);
}
static inline void resynch_write_ctf(resynchend_pak *rst)
static void resynch_write_ctf(resynchend_pak *rst)
{
mobj_t *mflag;
UINT8 i, j;
@@ -863,7 +863,7 @@ static inline void resynch_write_ctf(resynchend_pak *rst)
}
}
static inline void resynch_read_ctf(resynchend_pak *p)
static void resynch_read_ctf(resynchend_pak *p)
{
UINT8 i;
@@ -1656,12 +1656,7 @@ static void SV_SendPlayerInfo(INT32 node)
netbuffer->u.playerinfo[i].node = i;
// Can't really change this because net compatibility, but the warning is annoying
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-truncation"
strncpy(netbuffer->u.playerinfo[i].name, (const char *)&player_names[i], MAXPLAYERNAME+1);
#pragma GCC diagnostic pop
netbuffer->u.playerinfo[i].name[MAXPLAYERNAME] = '\0';
strlcpy(netbuffer->u.playerinfo[i].name, (const char *)&player_names[i], MAXPLAYERNAME+1);
//fetch IP address
//No, don't do that, you fuckface.
@@ -4161,7 +4156,10 @@ static void Joinable_OnChange(void)
UINT8 maxplayer;
if (!server)
{
CONS_Alert(CONS_NOTICE, ("Only the server can change: %s %s\n"), cv_allownewplayer.name, cv_allownewplayer.string);
return;
}
#ifdef SATURNJOIN
// disabling joins should also disable saturn joins unless its called with CV_StealthSet and vice versa to make life a bit easier
+70 -82
View File
@@ -347,11 +347,65 @@ static void D_Renderview(void)
}
}
for (i = 0; i <= splitscreen; i++)
{
if (!P_MobjWasRemoved(players[displayplayers[i]].mo) || players[displayplayers[i]].playerstate == PST_DEAD)
{
viewssnum = i;
switch (i)
{
case 1:
if (splitscreen > 1)
{
viewwindowx = viewwidth;
viewwindowy = 0;
}
else
{
viewwindowx = 0;
viewwindowy = viewheight;
}
break;
case 2:
viewwindowx = 0;
viewwindowy = viewheight;
break;
case 3:
viewwindowx = viewwidth;
viewwindowy = viewheight;
break;
default: // Initialize for P1
viewwindowy = viewwindowx = 0;
objectsdrawn = 0;
break;
}
#ifdef HWRENDER
if (rendermode == render_opengl)
{
HWR_RenderPlayerView();
}
else if (rendermode == render_soft)
#endif
R_RenderPlayerView(&players[displayplayers[i]]);
}
if (rendermode == render_soft)
{
if (i == 0)
R_ApplyViewMorph();
V_DoPostProcessor(i, postimgparam[i]);
}
}
// Draw over the fourth screen so you don't have to stare at a HOM :V
if (splitscreen == 2)
{
// V_DrawPatchFill, but for the fourth screen only
patch_t *pat = W_CachePatchName("SRB2BACK", PU_CACHE);
patch_t *pat = W_CachePatchName("SRB2BACK", PU_PATCH);
INT32 x, y, pw = SHORT(pat->width) * vid.dup, ph = SHORT(pat->height) * vid.dup;
for (x = vid.width>>1; x < vid.width; x += pw)
@@ -361,65 +415,6 @@ static void D_Renderview(void)
}
}
for (i = 0; i <= splitscreen; i++)
{
const boolean issplitscreen = (i > 0);
if (!P_MobjWasRemoved(players[displayplayers[i]].mo) || players[displayplayers[i]].playerstate == PST_DEAD)
{
viewssnum = i;
if (!issplitscreen) // Initialize for P1
{
viewwindowy = viewwindowx = 0;
objectsdrawn = 0;
}
#ifdef HWRENDER
if (rendermode == render_opengl)
{
HWR_RenderPlayerView();
R_RestoreLevelInterpolators();
continue;
}
#endif
if (issplitscreen) // Splitscreen-specific
{
switch (i)
{
case 1:
if (splitscreen > 1)
{
viewwindowx = viewwidth;
viewwindowy = 0;
}
else
{
viewwindowx = 0;
viewwindowy = viewheight;
}
break;
case 2:
viewwindowx = 0;
viewwindowy = viewheight;
break;
case 3:
viewwindowx = viewwidth;
viewwindowy = viewheight;
default:
break;
}
}
R_RenderPlayerView(&players[displayplayers[i]]);
}
if (!issplitscreen)
R_ApplyViewMorph();
V_DoPostProcessor(i, postimgparam[i]);
}
R_RestoreLevelInterpolators();
}
@@ -522,19 +517,16 @@ static boolean D_Display(void)
case GS_LEVEL:
if (!gametic)
break;
HU_Erase();
AM_Drawer();
break;
case GS_INTERMISSION:
Y_IntermissionDrawer();
HU_Erase();
HU_Drawer();
break;
case GS_VOTING:
Y_VoteDrawer();
HU_Erase();
HU_Drawer();
break;
@@ -549,7 +541,6 @@ static boolean D_Display(void)
case GS_CUTSCENE:
F_CutsceneDrawer();
HU_Erase();
HU_Drawer();
break;
@@ -559,7 +550,6 @@ static boolean D_Display(void)
case GS_EVALUATION:
F_GameEvaluationDrawer();
HU_Erase();
HU_Drawer();
break;
@@ -569,7 +559,6 @@ static boolean D_Display(void)
case GS_CREDITS:
F_CreditDrawer();
HU_Erase();
HU_Drawer();
break;
@@ -586,7 +575,6 @@ static boolean D_Display(void)
{
// I don't think HOM from nothing drawing is independent...
F_WaitingPlayersDrawer();
HU_Erase();
HU_Drawer();
}
case GS_TIMEATTACK:
@@ -774,6 +762,7 @@ void D_SRB2Loop(void)
precise_t capbudget;
precise_t enterprecise = I_GetPreciseTime();
memset(&g_dc, 0, sizeof(g_dc));
Z_Frame_Reset();
// Casting the return value of a function is bad practice (apparently)
@@ -889,12 +878,6 @@ void D_SRB2Loop(void)
// always update console and hud
// otherwise it may take minutes to open it
CON_Drawer();
if (gamestate == GS_LEVEL)
{
ST_Drawer();
HU_Drawer();
}
}
}
@@ -978,8 +961,11 @@ void D_ClearState(void)
{
INT32 i;
demo.title = false;
// okay, stop now
// (otherwise the game still thinks we're playing!)
CURLAbortFile();
SV_StopServer();
SV_ResetServer();
serverlistultimatecount = 0;
@@ -988,7 +974,10 @@ void D_ClearState(void)
CL_ClearPlayer(i);
splitscreen = 0;
SplitScreen_OnChange();
// recompute screen size
R_ExecuteSetViewSize();
botingame = false;
botskin = 0;
cv_debug = 0;
@@ -1007,7 +996,6 @@ void D_ClearState(void)
gameaction = ga_nothing;
memset(displayplayers, 0, sizeof(displayplayers));
consoleplayer = 0;
//demosequence = -1;
gametype = GT_RACE; // SRB2kart
paused = false;
@@ -1026,10 +1014,15 @@ void D_ClearState(void)
S_StopSounds();
S_ResetKeepAndSpecialMus(); // just in case
P_FreeLevelState();
//P_FreeLevelState();
G_SetGamestate(GS_NULL);
wipegamestate = GS_NULL;
M_ClearMenus(true);
// map palettes affect this
D_ResetDeviceLED();
}
//
@@ -1037,12 +1030,9 @@ void D_ClearState(void)
//
void D_StartTitle(void)
{
demo.title = false;
D_ClearState();
netgame = false; // title menu shouldnt be a netgame lmao
M_ClearMenus(true);
multiplayer = netgame = false; // title menu shouldnt be a netgame or multiplayer lmao
F_StartTitleScreen();
D_ResetDeviceLED();
}
//
@@ -1930,9 +1920,7 @@ void D_SRB2Main(void)
G_LoadGameData();
#if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL)
VID_PrepareModeList(); // Regenerate Modelist according to cv_fullscreen
#endif
// set user default mode or mode set at cmdline
SCR_CheckDefaultMode();
+2 -3
View File
@@ -1127,9 +1127,7 @@ boolean HGetPacket(void)
while (true)
{
I_NetGet();
if (doomcom->remotenode == -1) // No packet received
if (!I_NetGet()) // No packets received
return false;
getbytes += packetheaderlength + doomcom->datalength; // For stat
@@ -1165,6 +1163,7 @@ boolean HGetPacket(void)
GotAcks();
continue;
}
doomcom->datalength -= BASEPACKETSIZE;
break;
}
+31 -17
View File
@@ -964,10 +964,11 @@ void D_RegisterClientCommands(void)
// g_input.c
CV_RegisterVar(&cv_controlperkey);
CV_RegisterVar(&cv_turnsmooth);
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
CV_RegisterVar(&cv_turnsmooth[i]);
CV_RegisterVar(&cv_turnaxis[i]);
CV_RegisterVar(&cv_moveaxis[i]);
CV_RegisterVar(&cv_camturnaxis[i]);
@@ -984,6 +985,8 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_xdeadzone[i]);
CV_RegisterVar(&cv_ydeadzone[i]);
CV_RegisterVar(&cv_litesteer[i]);
CV_RegisterVar(&cv_usejoystick[i]);
CV_RegisterVar(&cv_joyscale[i]);
CV_RegisterVar(&cv_rumble[i]);
@@ -1991,11 +1994,6 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
}
else
SetPlayerSkinByNum(playernum, skin);
#ifdef HAVE_DISCORDRPC
if (playernum == consoleplayer)
DRPC_UpdatePresence();
#endif
}
void SendWeaponPref(void)
@@ -2489,15 +2487,18 @@ void D_SetupVote(void)
INT32 i;
UINT8 gt = (cv_kartgametypepreference.value == -1) ? gametype : cv_kartgametypepreference.value;
UINT8 secondgt = G_SometimesGetDifferentGametype(gt);
INT16 votebuffer[4] = {-1,-1,-1,0};
INT16 votebuffer[4] = {-1,-1,-1, 0};
INT16 luamaps[4] = {0, 0, 0, 0};
LUA_HookSetupVote(luamaps, sizeof(luamaps)/sizeof(luamaps[0]), gt, secondgt);
// Correct secondgt if needed
UINT8 typeoflevel = mapheaderinfo[luamaps[2]-1]->typeoflevel;
if (luamaps[2] && (typeoflevel & G_TOLFlag(secondgt&(~0x80))) == 0)
secondgt = ((typeoflevel & TOL_RACE) ? GT_RACE : GT_MATCH)|(secondgt&0x80);
if (luamaps[2])
{
UINT8 typeoflevel = mapheaderinfo[luamaps[2]-1]->typeoflevel;
if ((typeoflevel & G_TOLFlag(secondgt&(~0x80))) == 0)
secondgt = ((typeoflevel & TOL_RACE) ? GT_RACE : GT_MATCH)|(secondgt&0x80);
}
if (cv_kartencore.value && gt == GT_RACE)
WRITEUINT8(p, (gt|0x80));
@@ -2598,14 +2599,18 @@ ConcatCommandArgv (int start, int end)
size += strlen(COM_Argv(i)) + 1;
}
final = ZZ_Alloc(size);
p = final;
p = final = ZZ_Alloc(size);
if (!p)
I_Error("ConcatCommandArgv: Out of memory!\n");
--end;/* handle the final argument separately */
for (i = start; i < end; ++i)
{
p += sprintf(p, "%s ", COM_Argv(i));
}
/* at this point "end" is actually the last argument's position */
strcpy(p, COM_Argv(end));
@@ -4216,23 +4221,32 @@ static void Command_MotD_f(void)
mymotd = Z_Malloc(sizeof(motd), PU_STATIC, NULL);
strlcpy(mymotd, COM_Argv(1), sizeof motd);
if (!mymotd)
return;
//I_Error("Command_MotD_f: Out of memory!\n"); // idk if this aint a bit too much lel
strlcpy(mymotd, COM_Argv(1), sizeof(motd));
for (i = 2; i < j; i++)
{
strlcat(mymotd, " ", sizeof motd);
strlcat(mymotd, COM_Argv(i), sizeof motd);
strlcat(mymotd, " ", sizeof(motd));
strlcat(mymotd, COM_Argv(i), sizeof(motd));
}
// Disallow non-printing characters and semicolons.
for (i = 0; mymotd[i] != '\0'; i++)
{
if (!isprint(mymotd[i]) || mymotd[i] == ';')
{
Z_Free(mymotd);
return;
}
}
if ((netgame || multiplayer) && client)
{
SendNetXCmd(XD_SETMOTD, mymotd, i); // send the actual size of the motd string, not the full buffer's size
}
else
{
strcpy(motd, mymotd);
@@ -4431,7 +4445,7 @@ static void Command_Addfile(void)
}
// Add file on your client directly if it is trivial, or you aren't in a netgame.
if (!(netgame || multiplayer) || musiconly)
if (!netgame || musiconly)
{
P_AddWadFile(fn, false);
return;
@@ -4474,7 +4488,7 @@ static void Command_Addfile(void)
if (IsPlayerAdmin(consoleplayer) && (!server)) // Request to add file
SendNetXCmd(XD_REQADDFILE, buf, buf_p - buf);
else
SendNetXCmd(XD_ADDFILE, buf, buf_p - buf);;
SendNetXCmd(XD_ADDFILE, buf, buf_p - buf);
}
/** Adds something at runtime.
+5
View File
@@ -9,6 +9,9 @@
/// \file d_protocol.h
/// \brief srb2kart:// protocol stuff
#ifndef __D_PROTOCOL__
#define __D_PROTOCOL__
void D_SetupProtocol(void);
void D_CreateProtocol(void);
@@ -16,3 +19,5 @@ void D_DeleteProtocol(void);
#ifdef HAVE_CURL
void D_DownloadReplay(const char *url, const char *path);
#endif
#endif //__D_PROTOCOL__
+3 -3
View File
@@ -1442,7 +1442,7 @@ static INT32 errorcount = 0;
*/
static boolean shutdowning = false;
void I_Error(const char *error, ...)
FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...)
{
va_list argptr;
char buffer[8192];
@@ -1468,7 +1468,7 @@ void I_Error(const char *error, ...)
if (errorcount > 20)
{
va_start(argptr, error);
vsprintf(buffer, error, argptr);
vsnprintf(buffer, 8192, error, argptr);
va_end(argptr);
I_OutputMsg("SRB2Kart %s Recursive Error", buffer);
@@ -1482,7 +1482,7 @@ void I_Error(const char *error, ...)
// Display error message in the console before we start shutting it down
va_start(argptr, error);
vsprintf(buffer, error, argptr);
vsnprintf(buffer, 8192, error, argptr);
va_end(argptr);
I_OutputMsg("\nI_Error(): %s\n", buffer);
+27 -1
View File
@@ -49,6 +49,27 @@ discordRequest_t *discordRequestList = NULL;
static char self_ip[IP_SIZE+1];
/*--------------------------------------------------
* const char *DRPC_HideUsername(const char *input)
*
* See header file for description.
* --------------------------------------------------*/
const char *DRPC_HideUsername(const char *input)
{
static char buffer[5];
int i;
buffer[0] = input[0];
for (i = 1; i < 4; ++i)
{
buffer[i] = '.';
}
buffer[4] = '\0';
return buffer;
}
boolean drpc_init = false;
/*--------------------------------------------------
@@ -105,7 +126,7 @@ static void DRPC_HandleReady(const DiscordUser *user)
}
else
{
CONS_Printf("Discord: connected to %s#%s (%s)\n", user->username, user->discriminator, user->userId);
CONS_Printf("Discord: connected to %s (%s)\n", user->username, user->userId);
}
}
@@ -241,8 +262,10 @@ static void DRPC_HandleJoinRequest(const DiscordUser *requestUser)
newRequest->username = Z_Calloc(344, PU_STATIC, NULL);
snprintf(newRequest->username, 344, "%s", requestUser->username);
#if 0
newRequest->discriminator = Z_Calloc(8, PU_STATIC, NULL);
snprintf(newRequest->discriminator, 8, "%s", requestUser->discriminator);
#endif
newRequest->userID = Z_Calloc(32, PU_STATIC, NULL);
snprintf(newRequest->userID, 32, "%s", requestUser->userId);
@@ -308,6 +331,9 @@ void DRPC_RemoveRequest(discordRequest_t *removeRequest)
}
Z_Free(removeRequest->username);
#if 0
Z_Free(removeRequest->discriminator);
#endif
Z_Free(removeRequest->userID);
Z_Free(removeRequest);
}
+11
View File
@@ -29,7 +29,9 @@ extern struct discordInfo_s {
typedef struct discordRequest_s {
char *username; // Discord user name.
#if 0 // Good night, sweet prince...
char *discriminator; // Discord discriminator (The little hashtag thing after the username). Separated for a "hide discriminators" cvar.
#endif
char *userID; // The ID of the Discord user, gets used with Discord_Respond()
// HAHAHA, no.
@@ -44,6 +46,15 @@ typedef struct discordRequest_s {
extern discordRequest_t *discordRequestList;
/*--------------------------------------------------
* const char *DRPC_HideUsername(const char *input);
*
* Handle usernames while cv_discordstreamer is activated.
* (The loss of discriminators is still a dumbass regression
* that I will never forgive the Discord developers for.)
* --------------------------------------------------*/
const char *DRPC_HideUsername(const char *input);
/*--------------------------------------------------
void DRPC_RemoveRequest(void);
+5 -6
View File
@@ -90,12 +90,6 @@ extern FILE *logstream;
extern char logfilename[1024];
#endif
// not sure if this belongs here lul
// TODO: figure out whats preventing 32bit windows from working with libbacktrace
#if defined(_WIN32) && !defined(MINGW64)
#define HAVE_DRMINGW
#endif
#if defined (HAVE_LIBBACKTRACE)
#define CRASH_LOGFILE_NAME "srb2kart-crash-log.txt"
#elif defined (HAVE_DRMINGW)
@@ -120,6 +114,9 @@ extern char logfilename[1024];
#define SUBVERSION 6 // more precise version number
#define VERSIONSTRING "Saturn v9"
#define VERSIONSTRINGW L"Saturn v9"
#define SATURN_TESTING // comment out for saturn release builds!
// Hey! If you change this, add 1 to the MODVERSION below! Otherwise we can't force updates!
// And change CMakeLists.txt (not src/, but in root), for CMake users!
#endif
@@ -654,7 +651,9 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
#if defined (HAVE_CURL)
#define MASTERSERVER
#ifndef NOHOLEPUNCH
#define HOLEPUNCH
#endif
#else
#undef UPDATE_ALERT
#endif
-1
View File
@@ -43,7 +43,6 @@ extern "C" {
#define UINT64 uint64_t
#ifdef __APPLE_CC__
#define DIRECTFULLSCREEN 1
#define DEBUG_LOG
#define NOIPX
#endif
+1
View File
@@ -963,6 +963,7 @@ void F_StartTitleScreen(void)
finalecount = 0;
else
wipegamestate = GS_TITLESCREEN;
G_SetGamestate(GS_TITLESCREEN);
CON_ClearHUD();
+2 -2
View File
@@ -44,7 +44,7 @@ consvar_t cv_addons_search_case = {"addons_search_case", "No", CV_SAVE, CV_YesNo
static CV_PossibleValue_t addons_search_type_cons_t[] = {{0, "Start"}, {1, "Anywhere"}, {0, NULL}};
consvar_t cv_addons_search_type = {"addons_search_type", "Anywhere", CV_SAVE, addons_search_type_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
char menupath[1024];
char menupath[MAXFILEPATH];
size_t menupathindex[menudepth];
size_t menudepthleft = menudepth;
@@ -111,7 +111,7 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
int found = 0;
char *searchname;
int depthleft = maxsearchdepth;
char searchpath[1024];
char searchpath[MAXFILEPATH];
size_t *searchpathindex;
dirhandle = (DIR**)malloc(maxsearchdepth * sizeof(DIR*));
+2 -1
View File
@@ -34,7 +34,8 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
#define menudepth 20
extern char menupath[1024];
#define MAXFILEPATH 1024
extern char menupath[MAXFILEPATH];
extern size_t menupathindex[menudepth];
extern size_t menudepthleft;
+403 -323
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -67,7 +67,7 @@ typedef enum {
} menudemotype_e;
typedef struct menudemo_s {
char filepath[256];
char filepath[1023 + 256]; // see M_PrepReplayList and sizeof menupath
menudemotype_e type;
char title[65]; // Null-terminated for string prints
+27 -16
View File
@@ -452,6 +452,13 @@ consvar_t cv_ydeadzone[MAXSPLITSCREENPLAYERS] = {
{"joy4_ydeadzone", "0.5", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}
};
consvar_t cv_litesteer[MAXSPLITSCREENPLAYERS] = {
{"litesteer", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"litesteer2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"litesteer3", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
{"litesteer4", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}
};
static CV_PossibleValue_t driftsparkpulse_t[] = {{0, "MIN"}, {FRACUNIT*3, "MAX"}, {0, NULL}};
consvar_t cv_driftsparkpulse = {"driftsparkpulse", "1.4", CV_FLOAT | CV_SAVE, driftsparkpulse_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -1014,8 +1021,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
else
th = 0;
if (th < SLOWTURNTICS)
tspeed = cv_turnsmooth.value == 2 ? 2 : 0; // slow turn
if (th < (cv_turnsmooth[forplayer].value * 3))
tspeed = cv_turnsmooth[forplayer].value == 2 ? 2 : 0; // slow turn
else
tspeed = 1;
@@ -1024,30 +1031,32 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
// let movement keys cancel each other out
if (turnright && !(turnleft))
{
cmd->angleturn = (INT16)(cmd->angleturn - (angleturn[tspeed]));
cmd->driftturn = (INT16)(cmd->driftturn - (angleturn[tspeed]));
cmd->angleturn -= angleturn[tspeed];
side += sidemove[1];
}
else if (turnleft && !(turnright))
{
cmd->angleturn = (INT16)(cmd->angleturn + (angleturn[tspeed]));
cmd->driftturn = (INT16)(cmd->driftturn + (angleturn[tspeed]));
cmd->angleturn += angleturn[tspeed];
side -= sidemove[1];
}
if (analogjoystickmove && axis != 0)
{
// JOYAXISRANGE should be 1023 (divide by 1024)
cmd->angleturn = (INT16)(cmd->angleturn - (((axis * angleturn[1]) >> 10))); // ANALOG!
cmd->driftturn = (INT16)(cmd->driftturn - (((axis * angleturn[1]) >> 10)));
side += ((axis * sidemove[0]) >> 10);
cmd->angleturn -= (axis * KART_FULLTURN) / JOYAXISRANGE;
side += (axis * sidemove[0]) / JOYAXISRANGE;
}
if (cv_mouseturn.value)
{
//THIS WORKS WTF????????
cmd->angleturn = (INT16)(cmd->angleturn - ((mousex*(encoremode ? -1 : 1)*8)));
cmd->driftturn = (INT16)(cmd->driftturn - ((mousex*(encoremode ? -1 : 1)*8)));
cmd->angleturn -= (mousex*(encoremode ? -1 : 1)*8);
}
// Digital users can input diagonal-back for shallow turns.
if (cv_litesteer[forplayer].value && InputDown(gc_aimbackward, ssplayer)
&& abs(cmd->angleturn) == KART_FULLTURN) // My keyboard hits 1024 but my keyboard only hits 1023, video games
{
cmd->angleturn /= 2;
}
if (objectplacing) // SRB2Kart: spectators need special controls // not anymore huehuehue
@@ -1160,10 +1169,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
else if (cmd->angleturn < (-angleturn[1]))
cmd->angleturn = (-angleturn[1]);
if (cmd->driftturn > (angleturn[1]))
cmd->driftturn = (angleturn[1]);
else if (cmd->driftturn < (-angleturn[1]))
cmd->driftturn = (-angleturn[1]);
// until here both are the very same
cmd->driftturn = cmd->angleturn;
if (player->mo)
cmd->angleturn = K_GetKartTurnValue(player, cmd->angleturn);
@@ -4054,7 +4061,11 @@ char *G_BuildMapTitle(INT32 mapnum)
title = Z_Malloc(len, PU_STATIC, NULL);
if (!title)
return NULL;
sprintf(title, "%s", mapheaderinfo[mapnum-1]->lvlttl);
if (zonetext) sprintf(title + strlen(title), " %s", zonetext);
if (actnum) sprintf(title + strlen(title), " %s", actnum);
}
+2 -1
View File
@@ -72,6 +72,8 @@ extern consvar_t cv_custom3axis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_xdeadzone[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_ydeadzone[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_litesteer[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_ghost_besttime, cv_ghost_bestlap, cv_ghost_last, cv_ghost_guest, cv_ghost_staff;
// Hud offsets
@@ -153,7 +155,6 @@ typedef enum
// mouseaiming (looking up/down with the mouse or keyboard)
#define KB_LOOKSPEED (1<<25)
#define MAXPLMOVE (50)
#define SLOWTURNTICS (cv_turnsmooth.value * 3)
// build an internal map name MAPxx from map number
const char *G_BuildMapName(INT32 map);
+7 -1
View File
@@ -37,7 +37,13 @@ static CV_PossibleValue_t turnsmooth_cons_t[] = {{2, "Slow"}, {1, "Fast"}, {0, "
consvar_t cv_mousesens = {"mousesens", "20", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mouseysens = {"mouseysens", "20", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_controlperkey = {"controlperkey", "One", CV_SAVE, onecontrolperkey_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_turnsmooth = {"turnsmoothing", "Slow", CV_SAVE, turnsmooth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_turnsmooth[MAXSPLITSCREENPLAYERS] = {
{"turnsmoothing", "Slow", CV_SAVE, turnsmooth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"turnsmoothing2", "Slow", CV_SAVE, turnsmooth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"turnsmoothing3", "Slow", CV_SAVE, turnsmooth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
{"turnsmoothing4", "Slow", CV_SAVE, turnsmooth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}
};
static void G_ResetPlayerDeviceRumble(INT32 player);
static void rumble_off_handle(void);
+2 -1
View File
@@ -110,7 +110,8 @@ typedef enum
// mouse values are used once
extern consvar_t cv_mousesens, cv_mouseysens;
extern consvar_t cv_controlperkey, cv_turnsmooth;
extern consvar_t cv_controlperkey;
extern consvar_t cv_turnsmooth[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_rumble[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS];
+1 -1
View File
@@ -804,7 +804,7 @@ static void HWR_PrecacheLevelSprites(void)
void HWR_PrecacheLevel(void)
{
if (rendermode != render_opengl)
if (gamestate != GS_LEVEL)
return;
// Precache flats.
+30 -223
View File
@@ -31,11 +31,6 @@
#include "../st_stuff.h"
#include <fcntl.h>
#include "../i_video.h" // for rendermode != render_glide
#ifndef O_BINARY
#define O_BINARY 0
#endif
typedef struct
{
@@ -51,75 +46,13 @@ typedef struct
UINT8 image_descriptor; //18
} ATTRPACK TGAHeader; // sizeof is 18
static UINT8 softwaretranstogl[11] = { 0, 25, 51, 76,102,127,153,178,204,229,255};
static UINT8 softwaretranstogl_hi[11] = { 0, 51,102,153,204,255,255,255,255,255,255};
static UINT8 softwaretranstogl_lo[11] = { 0, 12, 24, 36, 48, 60, 71, 83, 95,111,127};
static const UINT8 softwaretranstogl[11] = { 0, 25, 51, 76,102,127,153,178,204,229,255};
static const UINT8 softwaretranstogl_hi[11] = { 0, 51,102,153,204,255,255,255,255,255,255};
static const UINT8 softwaretranstogl_lo[11] = { 0, 12, 24, 36, 48, 60, 71, 83, 95,111,127};
static const float FLOATBASEVIDWIDTH = (float)BASEVIDWIDTH;
static const float FLOATBASEVIDHEIGHT = (float)BASEVIDHEIGHT;
//
// -----------------+
// HWR_DrawPatch : Draw a 'tile' graphic
// Notes : x,y : positions relative to the original Doom resolution
// : textes(console+score) + menus + status bar
// -----------------+
void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option)
{
FOutVector v[4];
FBITFIELD flags;
GLPatch_t *hwrPatch;
// 3--2
// | /|
// |/ |
// 0--1
float sdup = FIXED_TO_FLOAT(vid.fdup)*2.0f;
float pdup = FIXED_TO_FLOAT(vid.fdup)*2.0f;
// make patch ready in hardware cache
HWR_GetPatch(gpatch);
hwrPatch = ((GLPatch_t *)gpatch->hardware);
switch (option & V_SCALEPATCHMASK)
{
case V_NOSCALEPATCH:
pdup = 2.0f;
break;
case V_SMALLSCALEPATCH:
pdup = 2.0f * FIXED_TO_FLOAT(vid.smalldup*FRACUNIT);
break;
case V_MEDSCALEPATCH:
pdup = 2.0f * FIXED_TO_FLOAT(vid.meddup*FRACUNIT);
break;
}
if (option & V_NOSCALESTART)
sdup = 2.0f;
v[0].x = v[3].x = (x*sdup-gpatch->leftoffset*pdup)/vid.width - 1;
v[2].x = v[1].x = (x*sdup+(gpatch->width - gpatch->leftoffset)*pdup)/vid.width - 1;
v[0].y = v[1].y = 1-(y*sdup-gpatch->topoffset*pdup)/vid.height;
v[2].y = v[3].y = 1-(y*sdup+(gpatch->height - gpatch->topoffset)*pdup)/vid.height;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].s = v[3].s = 0.0f;
v[2].s = v[1].s = hwrPatch->max_s;
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = hwrPatch->max_t;
flags = PF_Translucent|PF_NoDepthTest;
if (option & V_WRAPX)
flags |= PF_ForceWrapX;
if (option & V_WRAPY)
flags |= PF_ForceWrapY;
// clip it since it is used for bunny scroll in doom I
GL_DrawPolygon(NULL, v, 4, flags);
}
void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap, INT32 bflags)
{
FOutVector v[4];
@@ -154,15 +87,15 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
switch (option & V_SCALEPATCHMASK)
{
case V_NOSCALEPATCH:
dup = 1.0f;
break;
case V_SMALLSCALEPATCH:
dup = (float)vid.smalldup;
break;
case V_MEDSCALEPATCH:
dup = (float)vid.meddup;
break;
case V_NOSCALEPATCH:
dup = 1.0f;
break;
case V_SMALLSCALEPATCH:
dup = (float)vid.smalldup;
break;
case V_MEDSCALEPATCH:
dup = (float)vid.meddup;
break;
}
fscalew = fscaleh = FIXED_TO_FLOAT(pscale);
@@ -336,15 +269,15 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
switch (option & V_SCALEPATCHMASK)
{
case V_NOSCALEPATCH:
dup = 1.0f;
break;
case V_SMALLSCALEPATCH:
dup = (float)vid.smalldup;
break;
case V_MEDSCALEPATCH:
dup = (float)vid.meddup;
break;
case V_NOSCALEPATCH:
dup = 1.0f;
break;
case V_SMALLSCALEPATCH:
dup = (float)vid.smalldup;
break;
case V_MEDSCALEPATCH:
dup = (float)vid.meddup;
break;
}
fscale = FIXED_TO_FLOAT(pscale);
@@ -573,7 +506,7 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength)
if (color & 0xFF00) // Do COLORMAP fade.
{
if (HWR_ShouldUsePaletteRendering() && cv_glscreentextures.value)
if (cv_glscreentextures.value && HWR_ShouldUsePaletteRendering())
{
const hwdscreentexture_t scr_tex = HWD_SCREENTEXTURE_GENERIC2;
@@ -585,12 +518,10 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength)
GL_UnSetShader();
return;
}
else
{
Surf.PolyColor.rgba = UINT2RGBA(0x01010160);
Surf.PolyColor.s.alpha = (strength*8);
poly_flags |= PF_Translucent;
}
Surf.PolyColor.rgba = UINT2RGBA(0x01010160);
Surf.PolyColor.s.alpha = (strength*8);
poly_flags |= PF_Translucent;
}
else // Do TRANSMAP** fade.
{
@@ -636,133 +567,6 @@ void HWR_DrawConsoleBack(UINT32 color, INT32 height)
}
// ==========================================================================
// R_DRAW.C STUFF
// ==========================================================================
// ------------------
// HWR_DrawViewBorder
// Fill the space around the view window with a Doom flat texture, draw the
// beveled edges.
// 'clearlines' is useful to clear the heads up messages, when the view
// window is reduced, it doesn't refresh all the view borders.
// ------------------
void HWR_DrawViewBorder(INT32 clearlines)
{
INT32 x, y;
INT32 top, side;
INT32 baseviewwidth, baseviewheight;
INT32 basewindowx, basewindowy;
patch_t *patch;
if (!clearlines)
clearlines = BASEVIDHEIGHT; // refresh all
// calc view size based on original game resolution
baseviewwidth = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewwidth), vid.fdup)); //(cv_viewsize.value * BASEVIDWIDTH/10)&~7;
baseviewheight = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewheight), vid.fdup));
top = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_baseviewwindowy), vid.fdup));
side = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_baseviewwindowx), vid.fdup));
// top
HWR_DrawFlatFill(0, 0,
BASEVIDWIDTH, (top < clearlines ? top : clearlines),
st_borderpatchnum);
// left
if (top < clearlines)
HWR_DrawFlatFill(0, top, side,
(clearlines-top < baseviewheight ? clearlines-top : baseviewheight),
st_borderpatchnum);
// right
if (top < clearlines)
HWR_DrawFlatFill(side + baseviewwidth, top, side,
(clearlines-top < baseviewheight ? clearlines-top : baseviewheight),
st_borderpatchnum);
// bottom
if (top + baseviewheight < clearlines)
HWR_DrawFlatFill(0, top + baseviewheight,
BASEVIDWIDTH, BASEVIDHEIGHT, st_borderpatchnum);
//
// draw the view borders
//
basewindowx = (BASEVIDWIDTH - baseviewwidth)>>1;
if (baseviewwidth == BASEVIDWIDTH)
basewindowy = 0;
else
basewindowy = top;
// top edge
if (clearlines > basewindowy - 8)
{
patch = W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH);
for (x = 0; x < baseviewwidth; x += 8)
HWR_DrawPatch(patch, basewindowx + x, basewindowy - 8,
0);
}
// bottom edge
if (clearlines > basewindowy + baseviewheight)
{
patch = W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH);
for (x = 0; x < baseviewwidth; x += 8)
HWR_DrawPatch(patch, basewindowx + x,
basewindowy + baseviewheight, 0);
}
// left edge
if (clearlines > basewindowy)
{
patch = W_CachePatchNum(viewborderlump[BRDR_L], PU_PATCH);
for (y = 0; y < baseviewheight && basewindowy + y < clearlines;
y += 8)
{
HWR_DrawPatch(patch, basewindowx - 8, basewindowy + y,
0);
}
}
// right edge
if (clearlines > basewindowy)
{
patch = W_CachePatchNum(viewborderlump[BRDR_R], PU_PATCH);
for (y = 0; y < baseviewheight && basewindowy+y < clearlines;
y += 8)
{
HWR_DrawPatch(patch, basewindowx + baseviewwidth,
basewindowy + y, 0);
}
}
// Draw beveled corners.
if (clearlines > basewindowy - 8)
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TL],
PU_PATCH),
basewindowx - 8, basewindowy - 8, 0);
if (clearlines > basewindowy - 8)
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TR],
PU_PATCH),
basewindowx + baseviewwidth, basewindowy - 8, 0);
if (clearlines > basewindowy+baseviewheight)
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BL],
PU_PATCH),
basewindowx - 8, basewindowy + baseviewheight, 0);
if (clearlines > basewindowy + baseviewheight)
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BR],
PU_PATCH),
basewindowx + baseviewwidth,
basewindowy + baseviewheight, 0);
}
// ==========================================================================
// AM_MAP.C DRAWING STUFF
// ==========================================================================
@@ -1084,11 +888,13 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
if (fx >= vid.width || fy >= vid.height)
return;
if (fx < 0)
{
fw += fx;
fx = 0;
}
if (fy < 0)
{
fh += fy;
@@ -1100,6 +906,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
if (fx + fw > vid.width)
fw = fvw - fx;
if (fy + fh > vid.height)
fh = fvh - fy;
@@ -1168,7 +975,7 @@ static inline boolean saveTGA(const char *file_name, void *buffer,
INT32 i;
UINT8 *buf8 = buffer;
fd = open(file_name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
fd = open(file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd < 0)
return false;
+38 -70
View File
@@ -65,8 +65,6 @@
// Globals
// ==========================================================================
#define ABS(x) ((x) < 0 ? -(x) : (x))
// false if shaders have not been initialized yet, or if shaders are not available
boolean gl_shadersavailable = false;
@@ -77,11 +75,6 @@ boolean gl_drawing_stencil = false;
static INT32 current_bsp_culling_distance = 0;
// base values set at SetViewSize
float gl_baseviewwindowy, gl_baseviewwindowx;
static float gl_viewwindowy, gl_viewwindowx; // top left corner of view window
float gl_viewwidth, gl_viewheight; // viewport clipping boundaries (screen coords)
FTransform atransform;
// Float variants of viewx, viewy, viewz, etc.
@@ -284,6 +277,7 @@ static void CV_glshaders_OnChange(void)
{
// can't do palette rendering without shaders, so update the state if needed
HWR_TogglePaletteRendering();
HWR_PrecacheLevel();
}
M_UpdateOGLMenu();
}
@@ -301,18 +295,21 @@ static void CV_gltextureformat_OnChange(void)
{
ONLY_IF_GL_LOADED
GL_SetSpecialState(HWD_SET_TEXTURE_FORMAT, cv_gltexturedepth.value);
HWR_PrecacheLevel();
}
static void CV_filtermode_OnChange(void)
{
ONLY_IF_GL_LOADED
GL_SetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_glfiltermode.value);
HWR_PrecacheLevel();
}
static void CV_anisotropic_OnChange(void)
{
ONLY_IF_GL_LOADED
GL_SetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_glanisotropicmode.value);
HWR_PrecacheLevel();
}
static void CV_glpaletterendering_OnChange(void)
@@ -325,7 +322,9 @@ static void CV_glpaletterendering_OnChange(void)
{
HWR_CompileShaders();
HWR_TogglePaletteRendering();
HWR_PrecacheLevel();
}
M_UpdateOGLMenu();
}
@@ -3377,6 +3376,9 @@ static void HWR_DrawSpriteShadow(gl_vissprite_t *spr, patch_t *gpatch, GLPatch_t
fixed_t slopez;
float offset = 0;
if (!spr->mobj)
return;
R_GetShadowZ(spr->mobj, &floorslope);
mobjfloor = HWR_OpaqueFloorAtPos(
@@ -3388,14 +3390,7 @@ static void HWR_DrawSpriteShadow(gl_vissprite_t *spr, patch_t *gpatch, GLPatch_t
angle_t shadowdir;
// Set direction
if (splitscreen && R_GetViewNumber() == 1)
shadowdir = localangle[1] + FixedAngle(cv_cam_rotate[1].value);
else if (splitscreen > 1 && R_GetViewNumber() == 2)
shadowdir = localangle[2] + FixedAngle(cv_cam_rotate[2].value);
else if (splitscreen > 2 && R_GetViewNumber() == 3)
shadowdir = localangle[3] + FixedAngle(cv_cam_rotate[3].value);
else
shadowdir = localangle[0] + FixedAngle(cv_cam_rotate[0].value);
shadowdir = localangle[viewssnum] + FixedAngle(cv_cam_rotate[viewssnum].value);
// Find floorheight
floorheight = HWR_OpaqueFloorAtPos(
@@ -3407,18 +3402,17 @@ static void HWR_DrawSpriteShadow(gl_vissprite_t *spr, patch_t *gpatch, GLPatch_t
// Don't draw it, then!
if (spr->mobj->z < floorheight)
return;
else
{
fixed_t floorz;
floorz = HWR_OpaqueFloorAtPos(
spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - floorheight),
spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - floorheight),
spr->mobj->z, spr->mobj->height);
// The shadow would be falling on a wall? Don't draw it, then.
// Would draw midair otherwise.
if (floorz < floorheight)
return;
}
fixed_t floorz;
floorz = HWR_OpaqueFloorAtPos(
spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - floorheight),
spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - floorheight),
spr->mobj->z, spr->mobj->height);
// The shadow would be falling on a wall? Don't draw it, then.
// Would draw midair otherwise.
if (floorz < floorheight)
return;
floorheight = FixedInt(spr->mobj->z - floorheight);
@@ -3428,12 +3422,11 @@ static void HWR_DrawSpriteShadow(gl_vissprite_t *spr, patch_t *gpatch, GLPatch_t
floorheight = FixedInt(spr->mobj->z - mobjfloor);
// technically this_scale gets multiplied and added to sprite y/x scale, but this thing needs it for some crap so ill just throw it in here again
const boolean hires = (spr->mobj && spr->mobj->skin && K_GetMobjSkin(spr->mobj)->flags & SF_HIRES);
this_scale = FixedToFloat(spr->mobj->scale);
if (spr->mobj)
this_scale = FixedToFloat(spr->mobj->scale);
if (hires)
this_scale = this_scale * FixedToFloat(K_GetMobjSkin(spr->mobj)->highresscale);
const skin_t *moskin = K_GetMobjSkin(spr->mobj);
if (moskin && moskin->flags & SF_HIRES)
this_scale *= FixedToFloat(moskin->highresscale);
// create the sprite billboard
//
@@ -4054,7 +4047,7 @@ static void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
const precipmobj_t *sprmo = spr->precip;
if (UNLIKELY(!sprmo || !sprmo->subsector))
if (UNLIKELY(!sprmo->subsector))
return;
// cache sprite graphics
@@ -4335,7 +4328,7 @@ static int CompareDrawNodePlanes(const void *p1, const void *p2)
const INT32 n1 = *(const INT32*)p1;
const INT32 n2 = *(const INT32*)p2;
return ABS(drawnodes[n2].u.plane.fixedheight - viewz) - ABS(drawnodes[n1].u.plane.fixedheight - viewz);
return abs(drawnodes[n2].u.plane.fixedheight - viewz) - abs(drawnodes[n1].u.plane.fixedheight - viewz);
}
//
@@ -5316,10 +5309,10 @@ static void HWR_DrawSkyBackground(void)
// -----------------+
static inline void HWR_ClearView(void)
{
GL_GClipRect((INT32)gl_viewwindowx,
(INT32)gl_viewwindowy,
(INT32)(gl_viewwindowx + gl_viewwidth),
(INT32)(gl_viewwindowy + gl_viewheight),
GL_GClipRect(viewwindowx,
viewwindowy,
(viewwindowx + viewwidth),
(viewwindowy + viewheight),
ZCLIP_PLANE, FAR_ZCLIP_DEFAULT);
GL_ClearBuffer(false, true, true, NULL);
}
@@ -5329,19 +5322,6 @@ static inline void HWR_ClearView(void)
// -----------------+
void HWR_SetViewSize(void)
{
// setup view size
gl_viewwidth = (float)vid.width;
gl_viewheight = (float)vid.height;
if (splitscreen)
gl_viewheight /= 2;
if (splitscreen > 1)
gl_viewwidth /= 2;
gl_baseviewwindowy = 0;
gl_baseviewwindowx = 0;
GL_FlushScreenTextures();
}
@@ -5352,7 +5332,9 @@ static void HWR_SetTransformAiming(FTransform *trans)
if (cv_glshearing.value)
{
fixed_t fixedaiming = AIMINGTODY(aimingangle);
trans->viewaiming = FixedToFloat(fixedaiming);
trans->viewaiming = FixedToFloat(fixedaiming) * ((float)vid.width / vid.height) / ((float)BASEVIDWIDTH / BASEVIDHEIGHT);
if (splitscreen == 1) // only for 2 player splitscreen
trans->viewaiming *= 2.125; // splitscreen adjusts fov with 0.8, so compensate (but only halfway, since splitscreen means only half the screen is used)
trans->shearing = true;
gl_aimingangle = 0;
}
@@ -5594,20 +5576,6 @@ extern "C" {
// ==========================================================================
static void HWR_RenderFrame(player_t *player, boolean skybox)
{
// set window position
gl_viewwindowx = gl_baseviewwindowx;
gl_viewwindowy = gl_baseviewwindowy;
if ((splitscreen == 1 && viewssnum == 1) || (splitscreen > 1 && viewssnum > 1))
{
gl_viewwindowy += gl_viewheight;
}
if (splitscreen > 1 && viewssnum & 1)
{
gl_viewwindowx += gl_viewwidth;
}
// check for new console commands.
NetUpdate();
@@ -5623,10 +5591,10 @@ static void HWR_RenderFrame(player_t *player, boolean skybox)
if (!skybox && cv_glrenderdistance.value)
{
GL_GClipRect((INT32)gl_viewwindowx,
(INT32)gl_viewwindowy,
(INT32)(gl_viewwindowx + gl_viewwidth),
(INT32)(gl_viewwindowy + gl_viewheight),
GL_GClipRect(viewwindowx,
viewwindowy,
(viewwindowx + viewwidth),
(viewwindowy + viewheight),
ZCLIP_PLANE, clipping_distances[cv_glrenderdistance.value - 1]);
current_bsp_culling_distance = bsp_culling_distances[cv_glrenderdistance.value - 1];
}
-6
View File
@@ -42,10 +42,6 @@ extern "C" {
void HWR_Startup(void);
void HWR_Shutdown(void);
extern float gl_viewwidth, gl_viewheight, gl_baseviewwindowx, gl_baseviewwindowy;
extern float gl_basewindowcenterx, gl_basewindowcentery;
extern unsigned msaa;
extern boolean a2c;
@@ -89,7 +85,6 @@ extern ps_metric_t ps_hw_batchdrawtime;
extern boolean gl_shadersavailable;
// hw_draw.c
void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option);
void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap, INT32 bflags);
void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h);
void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color);
@@ -98,7 +93,6 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color);
void HWR_drawAMline(const fline_t *fl, INT32 color);
void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength);
void HWR_DrawConsoleBack(UINT32 color, INT32 height);
void HWR_DrawViewBorder(INT32 clearlines);
void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum);
UINT8 *HWR_GetScreenshot(INT32 scale);
-145
View File
@@ -114,7 +114,6 @@ void UnloadModel(model_t *model)
if (model->materials)
Z_Free(model->materials);
DeleteVBOs(model);
Z_Free(model);
}
@@ -194,7 +193,6 @@ model_t *LoadModel(const char *filename, int ztag)
strcpy(model->mdlFilename, filename);
Optimize(model);
GeneratePolygonNormals(model, ztag);
// Default material properties
for (i = 0 ; i < model->numMaterials; i++)
@@ -246,13 +244,6 @@ void GenerateVertexNormals(model_t *model)
M_Memcpy(newNormals, frame->normals, sizeof(float)*3*mesh->numTriangles*3);
/* if (!systemSucks)
{
memTag = Z_GetTag(frame->tangents);
float *newTangents = (float*)Z_Malloc(sizeof(float)*3*mesh->numTriangles*3, memTag);
M_Memcpy(newTangents, frame->tangents, sizeof(float)*3*mesh->numTriangles*3);
}*/
for (k = 0; k < mesh->numVertices; k++)
{
float x, y, z;
@@ -288,32 +279,15 @@ void GenerateVertexNormals(model_t *model)
if (vCount > 1)
{
// Vector::Normalize(&normal);
newNormals[3 * k + 0] = (float)normal.x;
newNormals[3 * k + 1] = (float)normal.y;
newNormals[3 * k + 2] = (float)normal.z;
/* if (!systemSucks)
{
Vector::vector_t tangent;
Vector::Tangent(&normal, &tangent);
newTangents[3 * k + 0] = tangent.x;
newTangents[3 * k + 1] = tangent.y;
newTangents[3 * k + 2] = tangent.z;
}*/
}
}
oldNormals = frame->normals;
frame->normals = newNormals;
Z_Free(oldNormals);
/* if (!systemSucks)
{
float *oldTangents = frame->tangents;
frame->tangents = newTangents;
Z_Free(oldTangents);
}*/
}
}
}
@@ -404,15 +378,11 @@ void Optimize(model_t *model)
newMesh->numTriangles = numTriangles;
newMesh->numVertices = numTriangles * 3;
newMesh->uvs = (float*)Z_Malloc(sizeof(float)*2*numTriangles*3, memTag, 0);
// if (node->material->lightmap)
// newMesh->lightuvs = (float*)Z_Malloc(sizeof(float)*2*numTriangles*3, memTag, 0);
newMesh->frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t), memTag, 0);
curFrame = &newMesh->frames[0];
curFrame->material = curMat;
curFrame->normals = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0);
// if (!systemSucks)
// curFrame->tangents = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0);
curFrame->vertices = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0);
curFrame->colors = (char*)Z_Malloc(sizeof(char)*4*numTriangles*3, memTag, 0);
@@ -436,12 +406,6 @@ void Optimize(model_t *model)
curMesh->uvs,
sizeof(float)*2*curMesh->numTriangles*3);
/* if (node->material->lightmap)
{
M_Memcpy(&newMesh->lightuvs[uvCount],
curMesh->lightuvs,
sizeof(float)*2*curMesh->numTriangles*3);
}*/
uvCount += 2*curMesh->numTriangles*3;
dest = (float*)newMesh->frames[0].vertices;
@@ -456,15 +420,6 @@ void Optimize(model_t *model)
src,
sizeof(float)*3*curMesh->numTriangles*3);
/* if (!systemSucks)
{
dest = (float*)newMesh->frames[0].tangents;
src = (float*)curMesh->frames[0].tangents;
M_Memcpy(&dest[vertCount],
src,
sizeof(float)*3*curMesh->numTriangles*3);
}*/
vertCount += 3 * curMesh->numTriangles * 3;
destByte = (char*)newMesh->frames[0].colors;
@@ -494,103 +449,3 @@ void Optimize(model_t *model)
model->meshes = newMeshes;
model->numMeshes = numMeshes;
}
void GeneratePolygonNormals(model_t *model, int ztag)
{
int i;
for (i = 0; i < model->numMeshes; i++)
{
int j;
mesh_t *mesh = &model->meshes[i];
if (!mesh->frames)
continue;
for (j = 0; j < mesh->numFrames; j++)
{
int k;
mdlframe_t *frame = &mesh->frames[j];
const float *vertices = frame->vertices;
vector_t *polyNormals;
frame->polyNormals = (vector_t*)Z_Malloc(sizeof(vector_t) * mesh->numTriangles, ztag, 0);
polyNormals = frame->polyNormals;
for (k = 0; k < mesh->numTriangles; k++)
{
/// TODO: normalize vectors
(void)vertices;
(void)polyNormals;
// Vector::Normal(vertices, polyNormals);
vertices += 3 * 3;
polyNormals++;
}
}
}
}
//
// Reload
//
// Reload VBOs
//
#if 0
static void Reload(void)
{
/* model_t *node;
for (node = modelHead; node; node = node->next)
{
int i;
for (i = 0; i < node->numMeshes; i++)
{
mesh_t *mesh = &node->meshes[i];
if (mesh->frames)
{
int j;
for (j = 0; j < mesh->numFrames; j++)
CreateVBO(mesh, &mesh->frames[j]);
}
else if (mesh->tinyframes)
{
int j;
for (j = 0; j < mesh->numFrames; j++)
CreateVBO(mesh, &mesh->tinyframes[j]);
}
}
}*/
}
#endif
void DeleteVBOs(model_t *model)
{
(void)model;
/* for (int i = 0; i < model->numMeshes; i++)
{
mesh_t *mesh = &model->meshes[i];
if (mesh->frames)
{
for (int j = 0; j < mesh->numFrames; j++)
{
mdlframe_t *frame = &mesh->frames[j];
if (!frame->vboID)
continue;
bglDeleteBuffers(1, &frame->vboID);
frame->vboID = 0;
}
}
else if (mesh->tinyframes)
{
for (int j = 0; j < mesh->numFrames; j++)
{
tinyframe_t *frame = &mesh->tinyframes[j];
if (!frame->vboID)
continue;
bglDeleteBuffers(1, &frame->vboID);
frame->vboID = 0;
}
}
}*/
}
-6
View File
@@ -28,8 +28,6 @@ typedef struct
float ambient[4], diffuse[4], specular[4], emissive[4];
float shininess;
boolean spheremap;
// Texture::texture_t *texture;
// Texture::texture_t *lightmap;
} material_t;
typedef struct
@@ -40,7 +38,6 @@ typedef struct
float *tangents;
char *colors;
unsigned int vboID;
vector_t *polyNormals;
} mdlframe_t;
typedef struct
@@ -70,7 +67,6 @@ typedef struct mesh_s
typedef struct tag_s
{
char name[64];
// matrix_t transform;
} tag_t;
typedef struct model_s
@@ -96,9 +92,7 @@ model_t *LoadModel(const char *filename, int ztag);
void UnloadModel(model_t *model);
void Optimize(model_t *model);
void GenerateVertexNormals(model_t *model);
void GeneratePolygonNormals(model_t *model, int ztag);
void CreateVBOTiny(mesh_t *mesh, tinyframe_t *frame);
void CreateVBO(mesh_t *mesh, mdlframe_t *frame);
void DeleteVBOs(model_t *model);
#endif
+3
View File
@@ -253,6 +253,9 @@ HMS_connect (const char *format, ...)
cc = curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)cv_masterserver_timeout.value);
if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf);
cc = curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 30L);
if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf);
cc = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read);
if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf);
+110 -161
View File
@@ -431,7 +431,7 @@ void HU_Start(void)
void HU_Shiftform(void)
{
shiftxform = cv_keyboardlayout.value == 3 ? french_shiftxform : english_shiftxform;
shiftxform = (cv_keyboardlayout.value == 3) ? french_shiftxform : english_shiftxform;
}
//======================================================================
@@ -465,8 +465,8 @@ static INT16 addy = 0; // use this to make the messages scroll smoothly when one
static void HU_removeChatText_Mini(void)
{
// MPC: Don't create new arrays, just iterate through an existing one
size_t i;
for(i=0;i<chat_nummsg_min-1;i++) {
for (size_t i = 0; i < chat_nummsg_min - 1; i++)
{
strcpy(chat_mini[i], chat_mini[i+1]);
chat_timers[i] = chat_timers[i+1];
}
@@ -485,8 +485,8 @@ static void HU_removeChatText_Log(void)
return;
free(chat_log[0]);
size_t i;
for(i=0;i<chat_nummsg_log-1;i++)
for (size_t i = 0; i < chat_nummsg_log - 1;i++)
{
chat_log[i] = chat_log[i+1];
}
@@ -1101,14 +1101,14 @@ 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]--;
}
// handle chat timers
for (i=0; (i<chat_nummsg_min); i++)
for (i = 0; (i < chat_nummsg_min); i++)
{
if (chat_timers[i] > 0)
chat_timers[i]--;
@@ -1231,7 +1231,7 @@ static void HU_SendChatMessage(void)
nodenum[2] = '\0';
// check for undesirable characters in our "number"
if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9')))
if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9')))
{
// check if nodenum[1] is a space
if (nodenum[1] == ' ')
@@ -1499,7 +1499,7 @@ static void HU_drawMiniChat(void)
if (splitscreen > 1)
boxw = max(64, boxw/2);
for (; i>0; i--)
for (; i > 0; i--)
{
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
size_t j = 0;
@@ -1572,7 +1572,7 @@ static void HU_drawMiniChat(void)
i = 0;
prev_linereturn = false;
for (; i<=(chat_nummsg_min-1); i++) // iterate through our hot messages
for (; i <= (chat_nummsg_min-1); i++) // iterate through our hot messages
{
INT32 clrflag = 0;
INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
@@ -1749,7 +1749,6 @@ static void HU_drawChatLog(INT32 offset)
Z_Free(msg);
}
if (((chat_scroll >= chat_maxscroll) || (chat_scrollmedown)) && !(justscrolleddown || justscrolledup || chat_scrolltime)) // was already at the bottom of the page before new maxscroll calculation and was NOT scrolling.
{
atbottom = true; // we should scroll
@@ -2284,6 +2283,7 @@ static void HU_DrawSongCreditsBox(void)
V_DrawFill(x, y, strwidth*dup, BOXCREDITHEIGHT*dup, 28|flags|(bgt<<V_ALPHASHIFT));
V_DrawFill(x+dup, y+dup, (strwidth-2)*dup, (BOXCREDITHEIGHT-2)*dup, 30|flags|(bgt<<V_ALPHASHIFT));
}
if (cursongcredit.trans < NUMTRANSMAPS)
{
V_DrawSmallString(x+2*dup, y+2*dup, V_ALLOWLOWERCASE|flags|(cursongcredit.trans<<V_ALPHASHIFT), str);
@@ -2391,76 +2391,6 @@ void HU_Drawer(void)
}
}
//======================================================================
// HUD MESSAGES CLEARING FROM SCREEN
//======================================================================
// Clear old messages from the borders around the view window
// (only for reduced view, refresh the borders when needed)
//
// startline: y coord to start clear,
// clearlines: how many lines to clear.
//
static INT32 oldclearlines;
void HU_Erase(void)
{
INT32 topline, bottomline;
INT32 y, yoffset;
#ifdef HWRENDER
// clear hud msgs on double buffer (OpenGL mode)
boolean secondframe;
static INT32 secondframelines;
#endif
if (con_clearlines == oldclearlines && !con_hudupdate && !chat_on)
return;
#ifdef HWRENDER
// clear the other frame in double-buffer modes
secondframe = (con_clearlines != oldclearlines);
if (secondframe)
secondframelines = oldclearlines;
#endif
// clear the message lines that go away, so use _oldclearlines_
bottomline = oldclearlines;
oldclearlines = con_clearlines;
if (chat_on && OLDCHAT)
if (bottomline < 8)
bottomline = 8; // only do it for consolechat. consolechat is gay.
if (automapactive || viewwindowx == 0) // hud msgs don't need to be cleared
return;
// software mode copies view border pattern & beveled edges from the backbuffer
if (rendermode == render_soft)
{
topline = 0;
for (y = topline, yoffset = y*vid.width; y < bottomline; y++, yoffset += vid.width)
{
if (y < viewwindowy || y >= viewwindowy + viewheight)
R_VideoErase(yoffset, vid.width); // erase entire line
else
{
R_VideoErase(yoffset, viewwindowx); // erase left border
// erase right border
R_VideoErase(yoffset + viewwindowx + viewwidth, viewwindowx);
}
}
con_hudupdate = false; // if it was set..
}
#ifdef HWRENDER
else if (rendermode != render_none)
{
// refresh just what is needed from the view borders
HWR_DrawViewBorder(secondframelines);
con_hudupdate = secondframe;
}
#endif
}
//======================================================================
// IN-LEVEL MULTIPLAYER RANKINGS
//======================================================================
@@ -2540,17 +2470,91 @@ Ping_conversion (UINT32 lag)
// HU_drawPing
//
static void HU_drawOldPing(INT32 x, INT32 y, UINT32 lag, INT32 flags, boolean gentleman)
{
const INT32 measureid = cv_pingmeasurement.value ? 1 : 0;
if (vid.width >= 640) // how sad, we're using a shit resolution.
{
if (measureid == 1)
{
V_DrawRightAlignedSmallString(x+12, y+13, V_ALLOWLOWERCASE|flags, va("%dms", Ping_conversion(lag)));
}
else if (measureid == 0)
{
V_DrawRightAlignedSmallString(x+12, y+13, flags, va("d%d", Ping_conversion(lag)));
}
}
if (cv_pingicon.value)
{
UINT8 numbars = 0; // how many ping bars do we draw?
UINT8 barcolor = 31; // color we use for the bars (green, yellow, red or black)
SINT8 i = 0;
SINT8 yoffset = 6;
switch (lag)
{
case 0 ... 1:
numbars = 3;
barcolor = 215; // Blue
break;
case 2 ... 3:
numbars = 3;
barcolor = 184; // Green
break;
case 4 ... 6:
numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it.
barcolor = 103; // Yellow
break;
case 7 ... 9:
numbars = 1;
barcolor = 155; // Red
break;
default: // Brazil
numbars = 0;
barcolor = 31; // black
break;
}
if (gentleman)
{
barcolor = 194; // make it purplish
// bars get indirectly set earlier
}
for (i = 0; (i < 3); i++) // Draw the ping bar
{
V_DrawFill(x+2 *(i-1)+7, y+8+yoffset-4, 2, 8-yoffset, 31|flags);
if (i < numbars)
V_DrawFill(x+2 *(i-1)+7, y+8+yoffset-3, 1, 8-yoffset-1, barcolor|flags);
yoffset -= 2;
}
}
}
static void HU_drawKartPing(INT32 x, INT32 y, UINT32 lag, INT32 flags, boolean gentleman)
{
const INT32 measureid = cv_pingmeasurement.value ? 1 : 0;
if (measureid == 1)
V_DrawScaledPatch(x+11 - pingmeasure[measureid]->width, y+9, flags, pingmeasure[measureid]);
if (cv_pingicon.value)
{
INT32 gfxnum = Ping_gfx_num(lag); // gfx to draw
V_DrawScaledPatch(x+2, y, flags, pinggfx[gfxnum]);
}
x = V_DrawPingNum(x + (measureid == 1 ? 11 - pingmeasure[measureid]->width : 10), y+9, flags, Ping_conversion(lag), Ping_gfx_colormap(lag, gentleman));
if (measureid == 0)
V_DrawScaledPatch(x+1 - pingmeasure[measureid]->width, y+9, flags, pingmeasure[measureid]);
}
void HU_drawPlayerPing(INT32 x, INT32 y, INT32 pnum, INT32 flags)
{
INT32 measureid = cv_pingmeasurement.value ? 1 : 0;
INT32 gfxnum; // gfx to draw
//SRB2/Kart v1.0 style
UINT8 numbars = 0; // how many ping bars do we draw?
UINT8 barcolor = 31; // color we use for the bars (green, yellow, red or black)
SINT8 i = 0;
SINT8 yoffset = 6;
UINT32 lag = playerpingtable[pnum];
const boolean gentleman = (cv_mindelay.value && (lag < (tic_t)simulated_lag));
@@ -2561,74 +2565,11 @@ void HU_drawPlayerPing(INT32 x, INT32 y, INT32 pnum, INT32 flags)
if (cv_pingstyle.value == 0) // kart
{
gfxnum = Ping_gfx_num(lag);
if (measureid == 1)
V_DrawScaledPatch(x+11 - pingmeasure[measureid]->width, y+9, flags, pingmeasure[measureid]);
if (cv_pingicon.value)
V_DrawScaledPatch(x+2, y, flags, pinggfx[gfxnum]);
x = V_DrawPingNum(x + (measureid == 1 ? 11 - pingmeasure[measureid]->width : 10), y+9, flags, Ping_conversion(lag), Ping_gfx_colormap(lag, gentleman));
if (measureid == 0)
V_DrawScaledPatch(x+1 - pingmeasure[measureid]->width, y+9, flags, pingmeasure[measureid]);
HU_drawKartPing(x, y, lag, flags, gentleman);
}
else if (cv_pingstyle.value == 1) // old style ping
{
if (vid.width >= 640) // how sad, we're using a shit resolution.
{
if (measureid == 1)
{
V_DrawRightAlignedSmallString(x+12, y+13, V_ALLOWLOWERCASE|flags, va("%dms", Ping_conversion(lag)));
}
else if (measureid == 0)
{
V_DrawRightAlignedSmallString(x+12, y+13, flags, va("d%d", Ping_conversion(lag)));
}
}
if (cv_pingicon.value)
{
switch (lag)
{
case 0 ... 1:
numbars = 3;
barcolor = 215; // Blue
break;
case 2 ... 3:
numbars = 3;
barcolor = 184; // Green
break;
case 4 ... 6:
numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it.
barcolor = 103; // Yellow
break;
case 7 ... 9:
numbars = 1;
barcolor = 155; // Red
break;
default: // Brazil
numbars = 0;
barcolor = 31; // black
break;
}
if (gentleman)
{
barcolor = 194; // make it purplish
// bars get indirectly set earlier
}
for (i = 0; (i < 3); i++) // Draw the ping bar
{
V_DrawFill(x+2 *(i-1)+7, y+8+yoffset-4, 2, 8-yoffset, 31|flags);
if (i < numbars)
V_DrawFill(x+2 *(i-1)+7, y+8+yoffset-3, 1, 8-yoffset-1, barcolor|flags);
yoffset -= 2;
}
}
HU_drawOldPing(x, y, lag, flags, gentleman);
}
}
@@ -2904,12 +2845,8 @@ void HU_SetCEchoFlags(INT32 flags)
void HU_DoCEcho(const char *msg)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-truncation" // This is fine, we set null byte later
strncpy(cechotext, msg, sizeof(cechotext));
#pragma GCC diagnostic pop
strncat(cechotext, "\\", sizeof(cechotext) - strlen(cechotext) - 1);
cechotext[sizeof(cechotext) - 1] = '\0';
strlcpy(cechotext, msg, sizeof(cechotext));
strlcat(cechotext, "\\", sizeof(cechotext));
// just print it to console
if (cv_cechotoggle.value == 2)
@@ -2918,8 +2855,20 @@ void HU_DoCEcho(const char *msg)
strncpy(temp, cechotext, sizeof(temp));
for (char *p = temp; *p != '\0'; ++p)
{
if (*p == '\\')
{
*p = '\n';
++p;
char *skip_p = p; // Point at which we will move part of string after all \'s
while (*p == '\\')
++p;
memmove(skip_p, p, strlen(p)+1); // move the rest of string with null byte
p = skip_p; // Restore p
}
}
CONS_Printf("%s\n", temp);
-1
View File
@@ -117,7 +117,6 @@ void HU_TickSongCredits(void);
void HU_DrawSongCredits(void);
void HU_Drawer(void);
char HU_dequeueChatChar(void);
void HU_Erase(void);
void HU_clearChatChars(void);
void HU_drawPlayerPing(INT32 x, INT32 y, INT32 pnum, INT32 flags); // Lat': Ping drawer for scoreboard.
//void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer);
-680
View File
@@ -1,680 +0,0 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2011-2018 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file i_addrinfo.c
/// \brief getaddr stubs, for lesser OSes
///
/// Some systems/SDKs, like PSL1GHT v2 does not have addrinfo functions
/// So a stub is needed
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#ifdef _WIN32
#ifdef USE_WINSOCK2
#include <ws2tcpip.h>
#else
#include <winsock.h>
#endif
#else
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif
#include "i_addrinfo.h"
/*
* This addrinfo stub have a testcases:
* To test the stub, use this command to compile the stub testcase:
* gcc -g -DTESTCASE -Dtest_stub -Wall -W i_addrinfo.c -o stub
* To test the real getaddrinfo API, use this command to get real one:
* gcc -g -DTESTCASE -Utest_stub -Wall -W i_addrinfo.c -o real
* For Win32,you need the WinSock library, version 1.1 or 2.2
* for 1.1, add -lwsock32
* i686-w64-mingw32-gcc -g -DTESTCASE -Dtest_stub -UUSE_WINSOCK2 -Wall -W i_addrinfo.c -o stub.exe -lwsock32
* for 2.2, add -DUSE_WINSOCK2 -lws2_32
* i686-w64-mingw32-gcc -g -DTESTCASE -Utest_stub -DUSE_WINSOCK2 -Wall -W i_addrinfo.c -o real.exe -lws2_32
*/
#ifndef I_getaddrinfo
#include <stdbool.h>
#ifdef _WIN32
// it seems windows doesn't define that... maybe some other OS? OS/2
static int inet_aton(const char *cp, struct in_addr *addr)
{
if( cp == NULL || addr == NULL )
{
return(0);
}
if (strcmp(cp, "255.255.255.225") == 0)
{
addr->s_addr = htonl(INADDR_BROADCAST);
return 0;
}
return (addr->s_addr = inet_addr(cp)) != htonl(INADDR_NONE);
}
#endif
#ifdef USE_WINSOCK2
static HMODULE ipv6dll = NULL;
typedef int (WSAAPI *p_getaddrinfo) (const char *, const char *,
const struct my_addrinfo *,
struct my_addrinfo **);
typedef void (WSAAPI *p_freeaddrinfo) (struct my_addrinfo *);
static p_getaddrinfo WS_getaddrinfo = NULL;
static p_freeaddrinfo WS_freeaddrinfo = NULL;
static HMODULE WS_getfunctions(HMODULE tmp)
{
if (tmp != NULL)
{
WS_getaddrinfo = (p_getaddrinfo)(LPVOID)GetProcAddress(tmp, "getaddrinfo");
if (WS_getaddrinfo == NULL)
return NULL;
WS_freeaddrinfo = (p_freeaddrinfo)(LPVOID)GetProcAddress(tmp, "freeaddrinfo");
if (WS_freeaddrinfo == NULL)
{
WS_getaddrinfo = NULL;
return NULL;
}
}
return tmp;
}
static void WS_addrinfosetup(void)
{
if (WS_getaddrinfo && WS_freeaddrinfo)
return; // already have the functions
// why not hold it into ipv6dll? becase we already link with ws2_32, silly!
if (WS_getfunctions(GetModuleHandleA("ws2_32.dll")) == NULL)
ipv6dll = WS_getfunctions(LoadLibraryA("wship6.dll"));
}
void WS_addrinfocleanup(void)
{
if (ipv6dll)
FreeLibrary(ipv6dll);
ipv6dll = NULL;
WS_getaddrinfo = NULL;
WS_freeaddrinfo = NULL;
}
#else
void WS_addrinfocleanup(void) {}
#endif
int I_getaddrinfo(const char *node, const char *service,
const struct my_addrinfo *hints,
struct my_addrinfo **res)
{
struct hostent *nodename = NULL;
bool hostlookup = true, passivemode = false;
int flags = 0;
int socktype = 0;
int sockport = 0;
struct my_addrinfo *ai;
struct sockaddr_in *addr;
struct in_addr ipv4;
size_t addrlen = 1;
size_t ailen = 1, i = 0, j;
size_t famsize = sizeof(struct sockaddr_in);
#ifdef USE_WINSOCK2
WS_addrinfosetup();
if (WS_getaddrinfo)
return WS_getaddrinfo(node, service, hints, res);
#endif
// param check
if (node == NULL && service == NULL)
return EAI_NONAME;
//note: testcase show NULL as res crashes libc
if (res == NULL)
return -1;
// check hints
if (hints)
{
// no support for IPv6
if (hints->ai_family != AF_INET && hints->ai_family != AF_UNSPEC)
return -1; //EAI_FAMILY
#ifdef AI_NUMERICHOST
// do not look up hostnames
if ((hints->ai_flags & AI_NUMERICHOST) == AI_NUMERICHOST)
{
hostlookup = false;
flags |= AI_NUMERICHOST;
}
#endif
#ifdef AI_PASSIVE
// return loopback or any address?
if ((hints->ai_flags & AI_PASSIVE) == AI_PASSIVE)
{
passivemode = true;
flags |= AI_PASSIVE;
}
#endif
// why no support for canon names? lazy
//AI_CANONNAME
// what kind of socket?
socktype = hints->ai_socktype;
}
else
{
#ifdef AI_V4MAPPED
flags |= AI_V4MAPPED;
#endif
#ifdef AI_ADDRCONFIG
flags |= AI_ADDRCONFIG;
#endif
}
// we need gethostbyname to convert numeric strings
if (node && hostlookup)
{
if (node == NULL)
return -1;
nodename = gethostbyname(node);
if (nodename == NULL)
{
if (inet_aton(node, &ipv4) != 0)
addrlen = 1;
else
return -1;
}
else while (nodename->h_addr_list[addrlen] != NULL)
addrlen++;
}
else if (node)
{
if (inet_aton(node, &ipv4) != 0)
addrlen = 1;
else if (!hostlookup)
return EAI_NONAME;
}
else
addrlen = 1;
if (service) //AI_NUMERICSERV
sockport = atoi(service);
if (socktype == 0)
ailen = addrlen*3;
else
ailen = addrlen;
ai = calloc(ailen, sizeof(struct my_addrinfo));
if (ai == NULL)
return -1;
else
*res = ai;
addr = calloc(ailen*2, famsize);
if (addr == NULL)
{
free(ai);
return -1;
}
else
ai->ai_addr = memset(addr, 0x00, ailen*ai->ai_addrlen);
for (i = 0; i < ailen; i++)
{
ai = *res+i;
ai->ai_flags = flags;
ai->ai_family = AF_INET;
ai->ai_socktype = socktype;
switch (ai->ai_socktype)
{
case SOCK_STREAM:
ai->ai_protocol = IPPROTO_TCP;
break;
case SOCK_DGRAM:
ai->ai_protocol = IPPROTO_UDP;
break;
default:
ai->ai_protocol = 0;
}
ai->ai_addrlen = famsize;
ai->ai_addr = (struct sockaddr *)&addr[i];
//ai_cannonname
ai->ai_next = ai+1;
}
ai->ai_next = NULL;
ai = *res;
for (i = 0, j = 0; i < ailen; i++, j++)
{
ai = *res+i;
addr[i].sin_port = htons((UINT16)sockport);
if (nodename)
{
memcpy(&addr[i].sin_addr, nodename->h_addr_list[j], ai->ai_addrlen);
addr[i].sin_family = nodename->h_addrtype;
}
else if (node)
{
memcpy(&addr[i].sin_addr, &ipv4, ai->ai_addrlen);
addr[i].sin_family = AF_INET;
}
else
{
if (passivemode)
addr[i].sin_addr.s_addr = htonl(INADDR_ANY);
else
addr[i].sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr[i].sin_family = AF_INET;
}
if (socktype == 0)
{
ai->ai_socktype = SOCK_STREAM;
ai->ai_protocol = IPPROTO_TCP;
memcpy(&addr[i+1], &addr[i], ai->ai_addrlen);
i++; ai++;
ai->ai_socktype = SOCK_DGRAM;
ai->ai_protocol = IPPROTO_UDP;
memcpy(&addr[i+1], &addr[i], ai->ai_addrlen);
i++; ai++;
ai->ai_socktype = SOCK_RAW;
ai->ai_protocol = IPPROTO_IP;
}
}
return 0;
}
#endif
#ifndef I_freeaddrinfo
void I_freeaddrinfo(struct my_addrinfo *res)
{
#ifdef USE_WINSOCK2
if (WS_freeaddrinfo)
{
WS_freeaddrinfo(res);
return;
}
#endif
if (!res)
return;
free(res->ai_addr);
free(res);
}
#endif
#ifdef TESTCASE
#include <stdio.h>
#ifdef USE_WINSOCK2
#define inet_ntop inet_ntopA
#define HAVE_NTOP
static const char* inet_ntopA(int af, const void *cp, char *buf, socklen_t len)
{
DWORD Dlen = len, AFlen = 0;
SOCKADDR_STORAGE any;
LPSOCKADDR anyp = (LPSOCKADDR)&any;
LPSOCKADDR_IN any4 = (LPSOCKADDR_IN)&any;
LPSOCKADDR_IN6 any6 = (LPSOCKADDR_IN6)&any;
if (!buf)
{
WSASetLastError(STATUS_INVALID_PARAMETER);
return NULL;
}
if (af != AF_INET && af != AF_INET6)
{
WSASetLastError(WSAEAFNOSUPPORT);
return NULL;
}
ZeroMemory(&any, sizeof(SOCKADDR_STORAGE));
any.ss_family = af;
switch (af)
{
case AF_INET:
{
CopyMemory(&any4->sin_addr, cp, sizeof(IN_ADDR));
AFlen = sizeof(SOCKADDR_IN);
break;
}
case AF_INET6:
{
CopyMemory(&any6->sin6_addr, cp, sizeof(IN6_ADDR));
AFlen = sizeof(SOCKADDR_IN6);
break;
}
}
if (WSAAddressToStringA(anyp, AFlen, NULL, buf, &Dlen) == SOCKET_ERROR)
return NULL;
return buf;
}
#elif defined (_WIN32)
// w32api, ws2tcpip.h, r1.12
static inline char* gai_strerror(int ecode)
{
static char message[1024+1];
DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS
| FORMAT_MESSAGE_MAX_WIDTH_MASK;
DWORD dwLanguageId = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
FormatMessageA(dwFlags, NULL, ecode, dwLanguageId, message, 1024, NULL);
return message;
}
#else
#define HAVE_NTOP
#endif
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
#endif
static inline void printflags(int ai_flags)
{
printf("flags: %x(", ai_flags);
if (ai_flags == 0)
printf("NONE|");
#ifdef AI_PASSIVE
if ((ai_flags & AI_PASSIVE) == AI_PASSIVE)
printf("AI_PASSIVE|");
ai_flags &= ~AI_PASSIVE;
#endif
#ifdef AI_CANONNAME
if ((ai_flags & AI_CANONNAME) == AI_CANONNAME)
printf("AI_CANONNAME|");
ai_flags &= ~AI_CANONNAME;
#endif
#ifdef AI_NUMERICHOST
if ((ai_flags & AI_NUMERICHOST) == AI_NUMERICHOST)
printf("AI_NUMERICHOST|");
ai_flags &= ~AI_NUMERICHOST;
#endif
#ifdef AI_V4MAPPED
if ((ai_flags & AI_V4MAPPED) == AI_V4MAPPED)
printf("AI_V4MAPPED|");
ai_flags &= ~AI_V4MAPPED;
#endif
#ifdef AI_ALL
if ((ai_flags & AI_ALL) == AI_ALL)
printf("AI_ALL|");
ai_flags &= ~AI_ALL;
#endif
#ifdef AI_ADDRCONFIG
if ((ai_flags & AI_ADDRCONFIG) == AI_ADDRCONFIG)
printf("AI_ADDRCONFIG|");
ai_flags &= ~AI_ADDRCONFIG;
#endif
#ifdef AI_IDN
if ((ai_flags & AI_IDN) == AI_IDN)
printf("AI_IDN|");
ai_flags &= ~AI_IDN;
#endif
#ifdef AI_CANONIDN
if ((ai_flags & AI_CANONIDN) == AI_CANONIDN)
printf("AI_CANONIDN|");
ai_flags &= ~AI_CANONIDN;
#endif
#ifdef AI_IDN_ALLOW_UNASSIGNED
if ((ai_flags & AI_IDN_ALLOW_UNASSIGNED) == AI_IDN_ALLOW_UNASSIGNED)
printf("AI_IDN_ALLOW_UNASSIGNED|");
ai_flags &= ~AI_IDN_ALLOW_UNASSIGNED;
#endif
#ifdef AI_IDN_USE_STD3_ASCII_RULES
if ((ai_flags & AI_IDN_USE_STD3_ASCII_RULES) == AI_IDN_USE_STD3_ASCII_RULES)
printf("AI_IDN_USE_STD3_ASCII_RULES|");
ai_flags &= ~AI_PASSIVE;
#endif
#ifdef AI_NUMERICSERV
if ((ai_flags & AI_NUMERICSERV) == AI_NUMERICSERV)
printf("AI_NUMERICSERV|");
ai_flags &= ~AI_NUMERICSERV;
#endif
printf("%x", ai_flags);
printf(")\n");
}
static inline void printsocktype(int ai_socktype)
{
printf("socktype: %d(", ai_socktype);
switch (ai_socktype)
{
case 0:
printf("SOCK_ Woe32");
break;
case SOCK_STREAM:
printf("SOCK_STREAM");
break;
case SOCK_DGRAM:
printf("SOCK_DGRAM");
break;
case SOCK_RAW:
printf("SOCK_RAW");
break;
default:
printf("SOCK_ERROR\n");
exit(-1);
}
printf(")\n");
}
static inline void printprotocol(int ai_protocol)
{
printf("protocol: %d(", ai_protocol);
switch (ai_protocol)
{
case IPPROTO_IP:
printf("IPPROTO_IP");
break;
case IPPROTO_TCP:
printf("IPPROTO_TCP");
break;
case IPPROTO_UDP:
printf("IPPROTO_UDP");
break;
default:
printf("IPPROTO_ERROR\n");
exit(-1);
}
printf(")\n");
}
static inline void printaddr(int ai_family, const struct sockaddr *ai_addr)
{
char str[INET_ADDRSTRLEN+1] = "FAKE";
printf("family: %d(", ai_family);
switch (ai_family)
{
case AF_UNSPEC:
printf("AF_UNSPEC");
break;
case AF_INET:
printf("AF_INET");
break;
#ifdef AF_INET6
case AF_INET6:
printf("AF_INET6");
break;
#endif
default:
printf("AF_ERROR\n");
exit(-1);
}
printf(")\n");
if (ai_family == AF_INET && ai_addr)
{
const struct sockaddr_in *ip4 = (void *)ai_addr;
#ifdef HAVE_NTOP
inet_ntop(ai_family, &ip4->sin_addr, str, INET_ADDRSTRLEN);
#else
strncpy(str, inet_ntoa(ip4->sin_addr), INET_ADDRSTRLEN);
#endif
printf("port: %d\n", ntohs(ip4->sin_port));
}
printf("addr: %s\n", str);
}
void printaddrinfo(const struct my_addrinfo *data)
{
if(data == NULL)
{
printf("no data\n");
return;
}
else
printf("starting addrinfo dump\n");
while (data != NULL)
{
printflags(data->ai_flags);
printsocktype(data->ai_socktype);
printaddr(data->ai_family, data->ai_addr);
printprotocol(data->ai_protocol);
//addrlen
data = data->ai_next;
}
}
int main(int argc, char **argv)
{
struct my_addrinfo *res = NULL, hints;
int gaie;
(void)argc;
(void)argv;
memset(&hints, 0x00, sizeof(struct my_addrinfo));
hints.ai_family = AF_INET;
#ifdef _WIN32
{
#ifdef USE_WINSOCK2
const WORD VerNeed = MAKEWORD(2,2);
#else
const WORD VerNeed = MAKEWORD(1,1);
#endif
WSADATA WSAData;
WSAStartup(VerNeed, &WSAData);
}
#endif
printf("-----------------------------------------------------------\n");
#ifndef _WIN32 //NULL as res crashes Win32
gaie = I_getaddrinfo(NULL, NULL, &hints, NULL);
if (gaie != EAI_NONAME)
printf("NULLs test returned: %s(%d)\n", gai_strerror(gaie), gaie);
I_freeaddrinfo(res);
#endif
#if 0 //NULL as res crashes
gaie = I_getaddrinfo("localhost", "5029", NULL, NULL);
if (gaie == 0)
printf("NULL crashes: %s(%d)\n", gai_strerror(gaie), gaie);
I_freeaddrinfo(res);
#endif
gaie = I_getaddrinfo("localhost", NULL, &hints, &res);
//if (gaie != 0)
printf("NULL service test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
gaie = I_getaddrinfo(NULL, "5029", &hints, &res);
//if (gaie != 0)
printf("NULLs test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
gaie = I_getaddrinfo("localhost", "5029", &hints, &res);
//if (gaie != 0)
printf("no hints test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
printf("-----------------------------------------------------------\n");
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
gaie = I_getaddrinfo("localhost", NULL, &hints, &res);
//if (gaie != 0)
printf("NULL service test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
gaie = I_getaddrinfo(NULL, "5029", &hints, &res);
//if (gaie != 0)
printf("NULLs test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
gaie = I_getaddrinfo("localhost", "5029", &hints, &res);
//if (gaie != 0)
printf("no hints test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
printf("-----------------------------------------------------------\n");
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
gaie = I_getaddrinfo("localhost", NULL, &hints, &res);
//if (gaie != 0)
printf("NULL service test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
gaie = I_getaddrinfo(NULL, "5029", &hints, &res);
//if (gaie != 0)
printf("NULLs test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
gaie = I_getaddrinfo("localhost", "5029", &hints, &res);
//if (gaie != 0)
printf("no hints test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
printf("-----------------------------------------------------------\n");
hints.ai_flags = AI_NUMERICHOST;
gaie = I_getaddrinfo("localhost", NULL, &hints, &res);
//if (gaie != 0)
printf("NULL service test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
gaie = I_getaddrinfo(NULL, "5029", &hints, &res);
//if (gaie != 0)
printf("NULLs test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
gaie = I_getaddrinfo("localhost", "5029", &hints, &res);
//if (gaie != 0)
printf("no hints test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
printf("-----------------------------------------------------------\n");
gaie = I_getaddrinfo("127.0.0.1", NULL, &hints, &res);
//if (gaie != 0)
printf("NULL service test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
gaie = I_getaddrinfo("127.0.0.1", "5029", &hints, &res);
//if (gaie != 0)
printf("no hints test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
printf("-----------------------------------------------------------\n");
gaie = I_getaddrinfo("255.255.255.255", NULL, &hints, &res);
//if (gaie != 0)
printf("NULL service test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
gaie = I_getaddrinfo("255.255.255.255", "5029", &hints, &res);
//if (gaie != 0)
printf("no hints test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
printf("-----------------------------------------------------------\n");
hints.ai_flags = AI_PASSIVE;
gaie = I_getaddrinfo("0.0.0.0", NULL, &hints, &res);
//if (gaie != 0)
printf("NULL service test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
gaie = I_getaddrinfo("0.0.0.0", "5029", &hints, &res);
//if (gaie != 0)
printf("no hints test returned: %s(%d)\n", gai_strerror(gaie), gaie);
printaddrinfo(res);
I_freeaddrinfo(res); res = NULL;
return 0;
}
#endif
-71
View File
@@ -1,71 +0,0 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2011-2018 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file i_addrinfo.h
/// \brief getaddrinfo stub
#ifndef __I_ADDRINFO__
#define __I_ADDRINFO__
#ifdef __GNUG__
#pragma interface
#endif
#ifndef AI_PASSIVE
#define AI_PASSIVE 0x01
#endif
#ifndef AI_NUMERICHOST
#define AI_NUMERICHOST 0x04
#endif
#ifndef AI_V4MAPPED
#define AI_V4MAPPED 0x08
#endif
#ifndef AI_ADDRCONFIG
#define AI_ADDRCONFIG 0x20
#endif
#ifdef _WIN32
#ifndef EAI_NONAME
#define EAI_NONAME WSAHOST_NOT_FOUND
#endif
#endif
#ifndef EAI_NONAME
#define EAI_NONAME -2
#endif
#ifdef _WIN32 // already use the stub for Win32
// w32api, ws2tcpip.h, r1.12
struct my_addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
char *ai_canonname;
struct sockaddr *ai_addr;
struct my_addrinfo *ai_next;
};
#else
#define my_addrinfo addrinfo
#endif
void WS_addrinfocleanup(void);
#ifndef my_addrinfo
void I_freeaddrinfo(struct my_addrinfo *res);
int I_getaddrinfo(const char *node, const char *service,
const struct my_addrinfo *hints,
struct my_addrinfo **res);
#elif !defined (test_stub)
#define I_getaddrinfo getaddrinfo
#define I_freeaddrinfo freeaddrinfo
#endif
#endif
+156 -132
View File
@@ -28,43 +28,37 @@
#endif
#ifdef _WIN32
#define USE_WINSOCK
#if defined (_WIN64) || defined (HAVE_IPV6)
#define USE_WINSOCK2
#else //_WIN64/HAVE_IPV6
#define USE_WINSOCK1
#endif
#define USE_WINSOCK
#endif //WIN32 OS
#ifdef USE_WINSOCK2
#include <ws2tcpip.h>
#ifdef USE_WINSOCK
#include <ws2tcpip.h>
#define addrinfo_t ADDRINFOA
#else
#define addrinfo_t struct addrinfo
#endif
#include "doomdef.h"
#ifndef USE_WINSOCK
#include <arpa/inet.h>
#ifdef __APPLE_CC__
#ifndef _BSD_SOCKLEN_T_
#define _BSD_SOCKLEN_T_
#endif //_BSD_SOCKLEN_T_
#endif //__APPLE_CC__
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/ioctl.h>
#endif //normal BSD API
#include <errno.h>
#include <time.h>
#ifdef USE_WINSOCK1
#include <winsock.h>
#else
#ifndef USE_WINSOCK
#include <arpa/inet.h>
#ifdef __APPLE_CC__
#ifndef _BSD_SOCKLEN_T_
#define _BSD_SOCKLEN_T_
#endif //_BSD_SOCKLEN_T_
#endif //__APPLE_CC__
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/ioctl.h>
#endif //normal BSD API
#include <errno.h>
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
#include <sys/time.h>
#endif // UNIXCOMMON
#endif
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
#include <sys/time.h>
#endif // UNIXCOMMON
#ifdef USE_WINSOCK
// some undefined under win32
@@ -152,27 +146,22 @@ static UINT8 UPNP_support = TRUE;
#define close closesocket
#endif
#include "i_addrinfo.h"
#define DEFAULTPORT "5029"
#if defined (USE_WINSOCK)
typedef SOCKET SOCKET_TYPE;
#define ERRSOCKET (SOCKET_ERROR)
#ifdef USE_WINSOCK
typedef SOCKET SOCKET_TYPE;
#define ERRSOCKET (SOCKET_ERROR)
#else
#if defined (__unix__) || defined (__APPLE__) || defined (__HAIKU__)
typedef int SOCKET_TYPE;
#else
typedef unsigned long SOCKET_TYPE;
#endif
#define ERRSOCKET (-1)
#if defined (__unix__) || defined (__APPLE__) || defined (__HAIKU__)
typedef int SOCKET_TYPE;
#else
typedef unsigned long SOCKET_TYPE;
#endif
#define ERRSOCKET (-1)
#endif
#define IPV6_MULTICAST_ADDRESS "ff15::57e1:1a12"
#ifdef USE_WINSOCK1
typedef int socklen_t;
#endif
typedef struct
{
mysockaddr_t address;
@@ -232,9 +221,8 @@ static char *get_WSAErrorStr(int e)
#define strerror get_WSAErrorStr
#endif
#ifdef USE_WINSOCK2
#ifdef USE_WINSOCK
#define inet_ntop inet_ntopA
#define HAVE_NTOP
static const char* inet_ntopA(short af, const void *cp, char *buf, socklen_t len)
{
DWORD Dlen = len, AFlen = 0;
@@ -278,8 +266,6 @@ static const char* inet_ntopA(short af, const void *cp, char *buf, socklen_t len
return NULL;
return buf;
}
#elif !defined (USE_WINSOCK1)
#define HAVE_NTOP
#endif
#ifdef HAVE_MINIUPNPC // based on old XChat patch
@@ -359,18 +345,15 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
{
static char s[64]; // 255.255.255.255:65535 or
// [ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535
#ifdef HAVE_NTOP
#ifdef HAVE_IPV6
int v6 = (sk->any.sa_family == AF_INET6);
#else
int v6 = 0;
#endif
void *addr;
int e = 0; // save error code so it can't be modified later code and avoid calling WSAGetLastError() more then once
if(sk->any.sa_family == AF_INET)
if (sk->any.sa_family == AF_INET)
addr = &sk->ip4.sin_addr;
#ifdef HAVE_IPV6
else if(sk->any.sa_family == AF_INET6)
@@ -379,9 +362,11 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
else
addr = NULL;
if(addr == NULL)
if (addr == NULL)
{
sprintf(s, "No address");
else if(inet_ntop(sk->any.sa_family, addr, &s[v6], sizeof (s) - v6) == NULL)
}
else if (inet_ntop(sk->any.sa_family, addr, &s[v6], sizeof (s) - v6) == NULL)
{
e = errno;
sprintf(s, "Unknown family type, error #%u: %s", e, strerror(e));
@@ -396,17 +381,9 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
strcat(s, va(":%d", ntohs(sk->ip6.sin6_port)));
}
#endif
else if(sk->any.sa_family == AF_INET && sk->ip4.sin_port != 0)
else if (sk->any.sa_family == AF_INET && sk->ip4.sin_port != 0)
strcat(s, va(":%d", ntohs(sk->ip4.sin_port)));
#else
if (sk->any.sa_family == AF_INET)
{
strcpy(s, inet_ntoa(sk->ip4.sin_addr));
if (sk->ip4.sin_port != 0) strcat(s, va(":%d", ntohs(sk->ip4.sin_port)));
}
else
sprintf(s, "Unknown type");
#endif
return s;
}
@@ -504,7 +481,6 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
return false;
}
// This is a hack. For some reason, nodes aren't being freed properly.
// This goes through and cleans up what nodes were supposed to be freed.
/** \warning This function causes the file downloading to stop if someone joins.
@@ -659,7 +635,7 @@ static boolean SOCK_Get(void)
c = recvfrom(mysockets[n], (char *)&doomcom->data, MAXPACKETLENGTH, 0,
(void *)&fromaddress, &fromlen);
if (c > 0)
if (c != ERRSOCKET)
{
#ifdef USE_STUN
if (STUN_got_response(doomcom->data, c))
@@ -675,20 +651,21 @@ static boolean SOCK_Get(void)
#endif
// find remote node number
for (j = 1; j <= MAXNETNODES; j++) //include LAN
for (j = 1; j <= MAXNETNODES; j++) // include LAN
{
if (SOCK_cmpaddr(&fromaddress, &clientaddress[j], 0))
{
doomcom->remotenode = (INT16)j; // good packet from a game player
doomcom->datalength = (INT16)c;
nodesocket[j] = mysockets[n];
return false;
return true;
}
}
// not found
// find a free slot
j = getfreenode();
if (j > 0)
{
const time_t curTime = time(NULL);
@@ -769,13 +746,19 @@ static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr
#define ALLOWEDERROR(x) ((x) == ECONNREFUSED || (x) == EWOULDBLOCK || (x) == EHOSTUNREACH || (x) == ENETUNREACH || (x) == EADDRNOTAVAIL)
// FIXME: maybe retry if this failed somehow?
// windows kinda dies rather often when some other network heavy thing runs besides kart
static void SOCK_Send(void)
{
ssize_t c = ERRSOCKET;
int e = 0; // save error code so it can't be modified later code and avoid calling WSAGetLastError() more then once
size_t i, j;
if (!nodeconnected[doomcom->remotenode])
#ifndef USE_WINSOCK
errno = 0;
#endif
if (doomcom->remotenode < 0 || !nodeconnected[doomcom->remotenode])
return;
if (doomcom->remotenode == BROADCASTADDR)
@@ -863,20 +846,20 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
mysockaddr_t straddr;
socklen_t len = sizeof(straddr);
#ifndef USE_WINSOCK
errno = 0;
#endif
if (s == (SOCKET_TYPE)ERRSOCKET)
return (SOCKET_TYPE)ERRSOCKET;
#ifdef USE_WINSOCK
{ // Alam_GBC: disable the new UDP connection reset behavior for Win2k and up
#ifdef USE_WINSOCK2
DWORD dwBytesReturned = 0;
BOOL bfalse = FALSE;
rc = WSAIoctl(s, SIO_UDP_CONNRESET, &bfalse, sizeof(bfalse),
NULL, 0, &dwBytesReturned, NULL, NULL);
#else
unsigned long falseval = false;
rc = ioctl(s, SIO_UDP_CONNRESET, &falseval);
#endif
if (rc == -1)
{
e = errno;
@@ -997,30 +980,90 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
e = errno;
I_OutputMsg("getting SO_RCVBUF failed: #%u, %s\n", e, strerror(e));
}
CONS_Printf(M_GetText("Network system buffer: %dKb\n"), opt>>10);
CONS_Printf(M_GetText("Network receive buffer: %dKb\n"), opt>>10);
if (opt < 64<<10) // 64k
//if (opt < 64<<10) // 64k minimum
if (opt < 256<<10) // no try 256k first
{
opt = 64<<10;
opts = (socklen_t)sizeof(opt);
rc = setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, opts);
if (rc <= -1)
const int buf_sizes[] = {256<<10, 128<<10, 64<<10}; // Try 256k, 128k, then 64k
size_t i;
for (i = 0; i < sizeof(buf_sizes) / sizeof(buf_sizes[0]); i++)
{
e = errno;
I_OutputMsg("setting SO_RCVBUF failed: #%u, %s\n", e, strerror(e));
}
opt = 0;
rc = getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &opts);
if (rc <= -1)
{
e = errno;
I_OutputMsg("getting SO_RCVBUF failed: #%u, %s\n", e, strerror(e));
opt = buf_sizes[i];
opts = (socklen_t)sizeof(opt);
rc = setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, opts);
if (rc <= -1)
{
e = errno;
I_OutputMsg("setting SO_RCVBUF to %dKb failed: #%u, %s\n", opt>>10, e, strerror(e));
continue;
}
opt = 0;
rc = getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &opts);
if (rc <= -1)
{
e = errno;
I_OutputMsg("getting SO_RCVBUF failed: #%u, %s\n", e, strerror(e));
}
if (opt >= buf_sizes[i])
{
CONS_Printf(M_GetText("Network system receive buffer set to: %dKb\n"), opt>>10);
break;
}
}
if (opt < 64<<10)
CONS_Alert(CONS_WARNING, M_GetText("Can't set buffer length to 64k, file transfer will be bad\n"));
else
CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10);
CONS_Alert(CONS_WARNING, M_GetText("Can't set receive buffer length to at least 64k, file transfer will be bad\n"));
}
opt = 0;
opts = (socklen_t)sizeof(opt);
rc = getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&opt, &opts);
if (rc <= -1)
{
e = errno;
I_OutputMsg("getting SO_SNDBUF failed: #%u, %s\n", e, strerror(e));
}
CONS_Printf(M_GetText("Network send buffer: %dKb\n"), opt>>10);
//if (opt < 64<<10) // 64k minimum
if (opt < 256<<10) // no try 256k first
{
int buf_sizes[] = {256<<10, 128<<10, 64<<10}; // Try 256k, 128k, then 64k
size_t i;
for (i = 0; i < sizeof(buf_sizes) / sizeof(buf_sizes[0]); i++)
{
opt = buf_sizes[i];
opts = (socklen_t)sizeof(opt);
rc = setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&opt, opts);
if (rc <= -1)
{
e = errno;
I_OutputMsg("setting SO_SNDBUF to %dKb failed: #%u, %s\n", opt>>10, e, strerror(e));
continue;
}
opt = 0;
rc = getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&opt, &opts);
if (rc <= -1)
{
e = errno;
I_OutputMsg("getting SO_SNDBUF failed: #%u, %s\n", e, strerror(e));
}
if (opt >= buf_sizes[i])
{
CONS_Printf(M_GetText("Network system send buffer set to: %dKb\n"), opt>>10);
break;
}
}
if (opt < 64<<10)
CONS_Alert(CONS_WARNING, M_GetText("Can't set send buffer length to at least 64k, file transfer will be bad\n"));
}
rc = getsockname(s, &straddr.any, &len);
@@ -1046,7 +1089,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
static boolean UDP_Socket(void)
{
size_t s;
struct my_addrinfo *ai, *runp, hints;
addrinfo_t *ai, *runp, hints;
int gaie;
#ifdef HAVE_IPV6
const INT32 b_ipv6 = M_CheckParm("-ipv6");
@@ -1075,7 +1118,7 @@ static boolean UDP_Socket(void)
{
while (M_IsNextParm())
{
gaie = I_getaddrinfo(M_GetNextParm(), serv, &hints, &ai);
gaie = getaddrinfo(M_GetNextParm(), serv, &hints, &ai);
if (gaie == 0)
{
runp = ai;
@@ -1089,13 +1132,13 @@ static boolean UDP_Socket(void)
}
runp = runp->ai_next;
}
I_freeaddrinfo(ai);
freeaddrinfo(ai);
}
}
}
else
{
gaie = I_getaddrinfo("0.0.0.0", serv, &hints, &ai);
gaie = getaddrinfo("0.0.0.0", serv, &hints, &ai);
if (gaie == 0)
{
runp = ai;
@@ -1116,7 +1159,7 @@ static boolean UDP_Socket(void)
}
runp = runp->ai_next;
}
I_freeaddrinfo(ai);
freeaddrinfo(ai);
}
}
@@ -1128,7 +1171,7 @@ static boolean UDP_Socket(void)
{
while (M_IsNextParm())
{
gaie = I_getaddrinfo(M_GetNextParm(), serv, &hints, &ai);
gaie = getaddrinfo(M_GetNextParm(), serv, &hints, &ai);
if (gaie == 0)
{
runp = ai;
@@ -1142,13 +1185,13 @@ static boolean UDP_Socket(void)
}
runp = runp->ai_next;
}
I_freeaddrinfo(ai);
freeaddrinfo(ai);
}
}
}
else
{
gaie = I_getaddrinfo("::", serv, &hints, &ai);
gaie = getaddrinfo("::", serv, &hints, &ai);
if (gaie == 0)
{
runp = ai;
@@ -1162,7 +1205,7 @@ static boolean UDP_Socket(void)
}
runp = runp->ai_next;
}
I_freeaddrinfo(ai);
freeaddrinfo(ai);
}
}
}
@@ -1216,11 +1259,7 @@ boolean I_InitTcpDriver(void)
if (!init_tcp_driver)
{
#ifdef USE_WINSOCK
#ifdef USE_WINSOCK2
const WORD VerNeed = MAKEWORD(2,2);
#else
const WORD VerNeed = MAKEWORD(1,1);
#endif
WSADATA WSAData;
const int WSAresult = WSAStartup(VerNeed, &WSAData);
if (WSAresult != 0)
@@ -1247,21 +1286,14 @@ boolean I_InitTcpDriver(void)
if (WSAresult != WSAVERNOTSUPPORTED)
CONS_Debug(DBG_NETPLAY, "WinSock(TCP/IP) error: %s\n",WSError);
}
#ifdef USE_WINSOCK2
if(LOBYTE(WSAData.wVersion) != 2 ||
if (LOBYTE(WSAData.wVersion) != 2 ||
HIBYTE(WSAData.wVersion) != 2)
{
WSACleanup();
CONS_Debug(DBG_NETPLAY, "No WinSock(TCP/IP) 2.2 driver detected\n");
}
#else
if (LOBYTE(WSAData.wVersion) != 1 ||
HIBYTE(WSAData.wVersion) != 1)
{
WSACleanup();
CONS_Debug(DBG_NETPLAY, "No WinSock(TCP/IP) 1.1 driver detected\n");
}
#endif
CONS_Debug(DBG_NETPLAY, "WinSock description: %s\n",WSAData.szDescription);
CONS_Debug(DBG_NETPLAY, "WinSock System Status: %s\n",WSAData.szSystemStatus);
#endif
@@ -1301,35 +1333,31 @@ void I_ShutdownTcpDriver(void)
CONS_Printf("I_ShutdownTcpDriver: ");
#ifdef USE_WINSOCK
WS_addrinfocleanup();
WSACleanup();
#endif
CONS_Printf("shut down\n");
init_tcp_driver = false;
}
static boolean SOCK_GetAddr(struct sockaddr_in *sin, const char *address, const char *port, boolean test)
static boolean SOCK_GetAddr(mysockaddr_t *sin, const char *address, const char *port, boolean test)
{
struct my_addrinfo *ai = NULL, *runp, hints;
addrinfo_t *ai, *runp, hints;
int gaie;
size_t i;
if (!port || !port[0])
port = DEFAULTPORT;
memset (&hints, 0x00, sizeof (hints));
memset(&hints, 0x00, sizeof (hints));
hints.ai_flags = AI_ADDRCONFIG;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
gaie = I_getaddrinfo(address, port, &hints, &ai);
gaie = getaddrinfo(address, port, &hints, &ai);
if (gaie != 0)
{
I_freeaddrinfo(ai);
return false;
}
runp = ai;
@@ -1356,7 +1384,7 @@ static boolean SOCK_GetAddr(struct sockaddr_in *sin, const char *address, const
if (runp != NULL)
memcpy(sin, runp->ai_addr, runp->ai_addrlen);
I_freeaddrinfo(ai);
freeaddrinfo(ai);
return (runp != NULL);
}
@@ -1369,7 +1397,7 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
if (newnode != -1)
{
if (!SOCK_GetAddr(&clientaddress[newnode].ip4, address, port, true))
if (!SOCK_GetAddr(&clientaddress[newnode], address, port, true))
{
nodeconnected[newnode] = false;
return -1;
@@ -1397,7 +1425,7 @@ static void rendezvous(int size)
if (tic != refreshtic)
{
if (SOCK_GetAddr(&rzv.ip4, host, (port ? port : "7777"), false))
if (SOCK_GetAddr(&rzv, host, (port ? port : "7777"), false))
{
refreshtic = tic;
}
@@ -1554,7 +1582,7 @@ static boolean SOCK_SetUnbanTime(time_t timestamp)
static boolean SOCK_SetBanAddress(const char *address, const char *mask)
{
struct my_addrinfo *ai, *runp, hints;
addrinfo_t *ai, *runp, hints;
int gaie;
if (!address)
@@ -1566,7 +1594,7 @@ static boolean SOCK_SetBanAddress(const char *address, const char *mask)
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
gaie = I_getaddrinfo(address, "0", &hints, &ai);
gaie = getaddrinfo(address, "0", &hints, &ai);
if (gaie != 0)
return false;
@@ -1611,7 +1639,7 @@ static boolean SOCK_SetBanAddress(const char *address, const char *mask)
runp = runp->ai_next;
}
I_freeaddrinfo(ai);
freeaddrinfo(ai);
return true;
}
@@ -1660,8 +1688,6 @@ boolean I_InitTcpNetwork(void)
// FIXME: for dedicated server, numnodes needs to be set to 0 upon start
if (dedicated)
doomcom->numnodes = 0;
/* else if (M_IsNextParm())
doomcom->numnodes = (INT16)atoi(M_GetNextParm());*/
else
doomcom->numnodes = 1;
@@ -1746,5 +1772,3 @@ boolean I_InitTcpNetwork(void)
return ret;
}
#include "i_addrinfo.c"
+1 -1
View File
@@ -94,8 +94,8 @@ INT32 VID_SetMode(INT32 modenum);
\return name of video mode
*/
const char *VID_GetModeName(INT32 modenum);
void VID_PrepareModeList(void); /// note hack for SDL
void VID_PrepareModeList(void);
/** \brief can video system do fullscreen
*/
+5
View File
@@ -10,9 +10,14 @@
/// \file k_director.h
/// \brief SRB2kart automatic spectator camera.
#ifndef __K_DIRECTOR__
#define __K_DIRECTOR__
boolean K_DirectorIsAvailable(void);
void K_InitDirector(void);
void K_UpdateDirector(void);
void K_DrawDirectorDebugger(void);
void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source);
void K_ToggleDirector(void);
#endif
+1 -1
View File
@@ -4333,7 +4333,7 @@ static void K_drawInput(void)
target = 0;
else // turning of multiple strengths!
{
target = ((abs(cmd->driftturn) - 1)/125)+1;
target = ((abs(cmd->driftturn) - 1)/200)+1; // was 125, do we need another toggle for this? Zzz...
if (target > 4)
target = 4;
if (cmd->driftturn < 0)
-3
View File
@@ -608,9 +608,6 @@ void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color, bo
if (color >= MAXTRANSLATIONS)
I_Error("Invalid skin color #%hu.", (UINT16)color);
if (skinnum < 0 && skinnum > TC_DEFAULT)
I_Error("Invalid translation colormap index %d.", skinnum);
starttranscolor = (skinnum != TC_DEFAULT) ? K_GetSkinArray(local)[skinnum].starttranscolor : DEFAULT_STARTTRANSCOLOR;
if (starttranscolor >= NUM_PALETTE_ENTRIES)
+11
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file k_stats.c
/// \brief Game statistics handling
#include "k_stats.h"
#include "doomstat.h"
#include "g_game.h"
+11
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file k_stats.h
/// \brief Game statistics handling
#ifndef __K_STATS__
#define __K_STATS__
+5
View File
@@ -10,6 +10,9 @@
/// \file lua_hook.h
/// \brief hooks for Lua scripting
#ifndef __LUA_HOOK__
#define __LUA_HOOK__
#include "r_defs.h"
#include "d_player.h"
#include "s_sound.h"
@@ -146,3 +149,5 @@ boolean LUA_HookPlayerSquish(player_t *player, mobj_t *inflictor, mobj_t *source
// (note: function format in lua doesn't include maxresults, so its function(result, gametype, secondgametype, prevmap)
// to get maxresults use #result)
void LUA_HookSetupVote(INT16 result[], INT16 maxresults, UINT8 gt, UINT8 secondgt);
#endif //__LUA_HOOK__
+5
View File
@@ -10,6 +10,9 @@
/// \file lua_libs.h
/// \brief libraries for Lua scripting
#ifndef __LUA_LIBS__
#define __LUA_LIBS__
#include "doomtype.h"
#include "blua/lua.h"
@@ -73,3 +76,5 @@ int LUA_ThinkerLib(lua_State *L);
int LUA_MapLib(lua_State *L);
int LUA_BlockmapLib(lua_State *L);
int LUA_HudLib(lua_State *L);
#endif //__LUA_LIBS__
+64 -16
View File
@@ -288,6 +288,10 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump];
len += 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name
name = malloc(len+1);
if (!name)
I_Error("LUA_LoadLump: Out of memory!\n");
sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->fullname);
name[len] = '\0';
}
@@ -797,8 +801,12 @@ static UINT8 ArchiveValue(UINT8 **p, int TABLESINDEX, int myindex)
{
mobj_t *mobj = *((mobj_t **)lua_touserdata(gL, myindex));
if (!mobj)
{
WRITEUINT8(*p, ARCH_NULL);
else {
return 3;
}
else
{
WRITEUINT8(*p, ARCH_MOBJ);
WRITEUINT32(*p, mobj->mobjnum);
}
@@ -808,8 +816,12 @@ static UINT8 ArchiveValue(UINT8 **p, int TABLESINDEX, int myindex)
{
player_t *player = *((player_t **)lua_touserdata(gL, myindex));
if (!player)
{
WRITEUINT8(*p, ARCH_NULL);
else {
return 3;
}
else
{
WRITEUINT8(*p, ARCH_PLAYER);
WRITEUINT8(*p, player - players);
}
@@ -819,8 +831,12 @@ static UINT8 ArchiveValue(UINT8 **p, int TABLESINDEX, int myindex)
{
mapthing_t *mapthing = *((mapthing_t **)lua_touserdata(gL, myindex));
if (!mapthing)
{
WRITEUINT8(*p, ARCH_NULL);
else {
return 3;
}
else
{
WRITEUINT8(*p, ARCH_MAPTHING);
WRITEUINT16(*p, mapthing - mapthings);
}
@@ -830,8 +846,12 @@ static UINT8 ArchiveValue(UINT8 **p, int TABLESINDEX, int myindex)
{
vertex_t *vertex = *((vertex_t **)lua_touserdata(gL, myindex));
if (!vertex)
{
WRITEUINT8(*p, ARCH_NULL);
else {
return 3;
}
else
{
WRITEUINT8(*p, ARCH_VERTEX);
WRITEUINT16(*p, vertex - vertexes);
}
@@ -841,8 +861,12 @@ static UINT8 ArchiveValue(UINT8 **p, int TABLESINDEX, int myindex)
{
line_t *line = *((line_t **)lua_touserdata(gL, myindex));
if (!line)
{
WRITEUINT8(*p, ARCH_NULL);
else {
return 3;
}
else
{
WRITEUINT8(*p, ARCH_LINE);
WRITEUINT16(*p, line - lines);
}
@@ -852,8 +876,12 @@ static UINT8 ArchiveValue(UINT8 **p, int TABLESINDEX, int myindex)
{
side_t *side = *((side_t **)lua_touserdata(gL, myindex));
if (!side)
{
WRITEUINT8(*p, ARCH_NULL);
else {
return 3;
}
else
{
WRITEUINT8(*p, ARCH_SIDE);
WRITEUINT16(*p, side - sides);
}
@@ -863,8 +891,12 @@ static UINT8 ArchiveValue(UINT8 **p, int TABLESINDEX, int myindex)
{
subsector_t *subsector = *((subsector_t **)lua_touserdata(gL, myindex));
if (!subsector)
{
WRITEUINT8(*p, ARCH_NULL);
else {
return 3;
}
else
{
WRITEUINT8(*p, ARCH_SUBSECTOR);
WRITEUINT16(*p, subsector - subsectors);
}
@@ -874,8 +906,12 @@ static UINT8 ArchiveValue(UINT8 **p, int TABLESINDEX, int myindex)
{
sector_t *sector = *((sector_t **)lua_touserdata(gL, myindex));
if (!sector)
{
WRITEUINT8(*p, ARCH_NULL);
else {
return 3;
}
else
{
WRITEUINT8(*p, ARCH_SECTOR);
WRITEUINT16(*p, sector - sectors);
}
@@ -885,8 +921,12 @@ static UINT8 ArchiveValue(UINT8 **p, int TABLESINDEX, int myindex)
{
pslope_t *slope = *((pslope_t **)lua_touserdata(gL, myindex));
if (!slope)
{
WRITEUINT8(*p, ARCH_NULL);
else {
return 3;
}
else
{
WRITEUINT8(*p, ARCH_SLOPE);
WRITEUINT16(*p, slope->id);
}
@@ -896,8 +936,12 @@ static UINT8 ArchiveValue(UINT8 **p, int TABLESINDEX, int myindex)
{
mapheader_t *header = *((mapheader_t **)lua_touserdata(gL, myindex));
if (!header)
{
WRITEUINT8(*p, ARCH_NULL);
else {
return 3;
}
else
{
WRITEUINT8(*p, ARCH_MAPHEADER);
WRITEUINT16(*p, header - *mapheaderinfo);
}
@@ -1003,19 +1047,23 @@ static void ArchiveTables(UINT8 **p)
e = ArchiveValue(p, TABLESINDEX, -2); // key should be either a number or a string, ArchiveValue can handle this.
if (e == 2) // invalid key type (function, thread, lightuserdata, or anything we don't recognise)
{
lua_pushvalue(gL, -2);
CONS_Alert(CONS_ERROR, "Index '%s' (%s) of table %d could not be archived!\n", lua_tostring(gL, -1), luaL_typename(gL, -1), i);
lua_pop(gL, 1);
CONS_Alert(CONS_ERROR, "Index '%s' (%s) of table %d could not be archived!\n", lua_tostring(gL, -2), luaL_typename(gL, -2), i);
}
else if (e == 3) // nil key due to invalid userdata. NOT an error.
{
lua_pop(gL, 1);
continue;
}
// Write value
e = ArchiveValue(p, TABLESINDEX, -1);
if (e == 1)
{
n++; // the table contained a new table we'll have to archive. :(
}
else if (e == 2) // invalid value type
{
lua_pushvalue(gL, -2);
CONS_Alert(CONS_ERROR, "Type of value for table %d entry '%s' (%s) could not be archived!\n", i, lua_tostring(gL, -1), luaL_typename(gL, -1));
lua_pop(gL, 1);
CONS_Alert(CONS_ERROR, "Type of value for table %d entry '%s' (%s) could not be archived!\n", i, lua_tostring(gL, -2), luaL_typename(gL, -1));
}
lua_pop(gL, 1);
+11
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file lua_udatalib.c
/// \brief Implementation of lua userdata object metatables based on getter/setter functions
#include "doomtype.h"
#include "m_fixed.h"
#include "lua_udatalib.h"
+12 -1
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file lua_udatalib.h
/// \brief Implementation of lua userdata object metatables based on getter/setter functions
#ifndef __LUA_UDATALIB_H__
#define __LUA_UDATALIB_H__
@@ -100,4 +111,4 @@ void udatalib_addfields(lua_State *L, int mt, const udata_field_t fields[]);
return 0; \
}
#endif
#endif
+5 -3
View File
@@ -69,16 +69,18 @@ INT32 M_CheckProtoParam(const char *check)
for (i = 1; i < myargc; i++)
{
if (strncmp(myargv[i], "srb2kart://", 11) == 0)
if (strncmp(myargv[i], "srb2kart://", 11) == 0)
{
if (strncmp(myargv[i]+11, check, strlen(check))==0)
if (strncmp(myargv[i]+11, check, strlen(check)) == 0)
{
found = i;
return i;
}
}
}
found = 0;
return 0;
}
@@ -93,7 +95,7 @@ const char *M_GetProtoParam(void)
for (i = 1; i < myargc; i++)
{
if (strncmp(myargv[i], "srb2kart://", 11) == 0)
if (strncmp(myargv[i], "srb2kart://", 11) == 0)
{
string = strchr(myargv[i], '/');
string = strchr(string+1, '/');
+5
View File
@@ -10,6 +10,9 @@
/// \file m_cond.h
/// \brief Unlockable condition system for SRB2 version 2.1
#ifndef __M_COND__
#define __M_COND__
#include "doomdef.h"
// --------
@@ -182,3 +185,5 @@ UINT8 M_GotLowEnoughTime(INT32 tictime);
//UINT8 M_GotHighEnoughRings(INT32 trings);
#define M_Achieved(a) ((a) >= MAXCONDITIONSETS || conditionSets[a].achieved)
#endif //__M_COND__
+11
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file m_curl.c
/// \brief Common curl-related functions shared across http-mserv and file download
#include "m_curl.h"
#include "doomtype.h"
#include "i_system.h" // I_OutputMsg
+11
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file m_curl.h
/// \brief Common curl-related functions shared across http-mserv and file download
#ifndef __M_CURL__
#define __M_CURL__
+13 -2
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file m_emotes.cpp
/// \brief Chat emotes handling
#include <map>
#include <string>
#include <sstream>
@@ -81,7 +92,7 @@ void M_LoadEmotes(UINT16 wadnum)
if (emote_name.size() > MAXEMOTENAME)
{
CONS_Alert(CONS_WARNING, "EMOTES: Emote name is too long, truncating. (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
emote_name = emote_name.substr(0, MAXEMOTENAME);
emote_name.resize(MAXEMOTENAME);
}
emote = &emotes[emote_name];
@@ -128,7 +139,7 @@ void M_LoadEmotes(UINT16 wadnum)
if (framelumpname.size() > 8)
{
CONS_Alert(CONS_WARNING, "EMOTES: Frame %d name is too long. (file %s, line %d)", numframes, wadfiles[wadnum]->filename, linenum);
framelumpname = framelumpname.substr(0, 8);
framelumpname.resize(8);
}
std::strncpy(emote->frames[numframes], framelumpname.c_str(), framelumpname.size()+1);
+11
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file m_emotes.h
/// \brief Chat emotes handling
#ifndef __M_EMOTES__
#define __M_EMOTES__
+39 -27
View File
@@ -702,7 +702,13 @@ static void M_CheckStringItem(void)
// Just in case
memset(menu_text_input_buf, 0, sizeof menu_text_input_buf);
M_TextInputInit(&menuinput, menu_text_input_buf, sizeof menu_text_input_buf);
// special case: name input, cap it to prevent writing outside the textbox
// kinda ugly but itll work
if (cv == &cv_playername)
M_TextInputInit(&menuinput, menu_text_input_buf, MAXPLAYERNAME +1);
else
M_TextInputInit(&menuinput, menu_text_input_buf, sizeof menu_text_input_buf);
M_TextInputSetString(&menuinput, cv->string);
}
@@ -1432,10 +1438,11 @@ void M_Drawer(void)
V_DrawThinString(vid.dup, vid.height - 20*vid.dup, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, compbranch);
V_DrawThinString(vid.dup, vid.height - 10*vid.dup, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, comprevision);
#else // Regular build
V_DrawThinString(vid.dup, vid.height - 20*vid.dup, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, comprevision); // Removeur this for release! im just lazy to make a new flag or smth
#ifdef SATURN_TESTING // ok not regular build lmao, we dont need to show this stuff in Saturn release builds
V_DrawThinString(vid.dup, vid.height - 20*vid.dup, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, comprevision);
#endif
V_DrawThinString(vid.dup, vid.height - 10*vid.dup, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s", VERSIONSTRING));
#endif
#ifdef HWRENDER
if (rendermode == render_opengl)
V_DrawThinString(0, 0, V_GREENMAP|V_SNAPTOTOP|V_SNAPTOLEFT|V_TRANSLUCENT|V_ALLOWLOWERCASE, ("Opengl"));
@@ -2712,6 +2719,10 @@ static void M_PrepareLevelSelect(void)
//
boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt)
{
// invalid mapnum
if (mapnum < -1)
return false;
// Random map!
if (mapnum == -1)
return (gamestate != GS_TIMEATTACK && !modeattacking);
@@ -3102,7 +3113,7 @@ static void M_AddonsInternal(void)
break;
}
strlcpy(menupath, pathname, 1024);
strlcpy(menupath, pathname, MAXFILEPATH);
menupathindex[(menudepthleft = menudepth-1)] = strlen(menupath) + 1;
if (menupath[menupathindex[menudepthleft]-2] != PATHSEP[0])
@@ -3215,9 +3226,9 @@ static void M_DrawTemperature(INT32 x, fixed_t t)
static char *M_AddonsHeaderPath(void)
{
UINT32 len;
static char header[1024];
static char header[MAXFILEPATH];
strlcpy(header, va("%s folder%s", cv_addons_option.string, menupath+menupathindex[menudepth-1]-1), 1024);
strlcpy(header, va("%s folder%s", cv_addons_option.string, menupath+menupathindex[menudepth-1]-1), MAXFILEPATH);
len = strlen(header);
if (len > 34)
{
@@ -3953,9 +3964,7 @@ static void PrepReplayList(boolean reset)
Lock_search_state();
if (demolist_all)
Z_Free(demolist_all);
Z_Free(demolist_all);
demolist_all = Z_Calloc(sizeof(menudemo_t) * sizedirmenu, PU_STATIC, NULL);
for (i = 0; i < sizedirmenu; i++)
@@ -3973,9 +3982,9 @@ static void PrepReplayList(boolean reset)
else
{
demolist_all[i].type = MD_NOTLOADED;
// FIXME - do something with buffer sizes. menupath is 1024 chars but filepath is only
// 256. I'm not really sure what to do here but don't want to leave warnings...
snprintf(demolist_all[i].filepath, 255, "%.254s%s", menupath, dirmenu[i] + DIR_STRING);
snprintf(demolist_all[i].filepath, sizeof(demolist_all[i].filepath),
// 255 = UINT8 limit. dirmenu entries are restricted to this length (see DIR_LEN).
"%s%.255s", menupath, dirmenu[i] + DIR_STRING);
sprintf(demolist_all[i].title, ".....");
}
}
@@ -4330,7 +4339,7 @@ static void DrawReplayHutReplayInfo(void)
static void M_DrawReplayHut(void)
{
INT32 x, y, cursory = 0;
INT16 i;
INT32 i;
INT16 replaylistitem = currentMenu->numitems-2;
boolean processed_one_this_frame = false;
const INT32 scaledviewheight = (vid.height/vid.dup);
@@ -4403,7 +4412,7 @@ static void M_DrawReplayHut(void)
V_DrawCenteredString(160, 100, V_ALLOWLOWERCASE, msg);
}
for (i = 0; i < (INT16)replayqueryfound; i++)
for (i = 0; i < (INT32)replayqueryfound; i++)
{
INT32 localy = y+i*10;
INT32 localx = x;
@@ -7170,17 +7179,21 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade)
namescroll = 0;
}
if (renderisnewtic) namescroll++;
if (renderisnewtic)
namescroll++;
char *addonname = wadfiles[mapwads[cv_nextmap.value-1]]->filename;
INT32 len;
INT32 charlimit = min((size_t)(21 + (dupadjust/5)), sizeof(namescrollbuf)-1);
nameonly(addonname);
len = strlen(addonname);
if (len > charlimit)
M_ScrollString(addonname, len, namescrollbuf, charlimit, namescroll);
else
strncpy(namescrollbuf, addonname, sizeof(namescrollbuf));
strncpy(namescrollbuf, addonname, sizeof(namescrollbuf) - 1);
V_DrawThinString(x+w+5, y+i-8, V_TRANSLUCENT|MENUCAPS, namescrollbuf); // variable reuse...
}
@@ -7219,7 +7232,7 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade)
if (i == oldval)
return;
if(!mapheaderinfo[i])
if (i >= 0 && !mapheaderinfo[i])
continue; // Don't allocate the header. That just makes memory usage skyrocket.
} while (!M_CanShowLevelInList(i, cv_newgametype.value));
@@ -7257,7 +7270,7 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade)
if (i == oldval)
return;
if(!mapheaderinfo[i])
if (i >= 0 && !mapheaderinfo[i])
continue; // Don't allocate the header. That just makes memory usage skyrocket.
} while (!M_CanShowLevelInList(i, cv_newgametype.value));
@@ -8270,12 +8283,12 @@ static void M_DrawSetupMultiPlayerMenu(void)
sprframe = &sprdef->spriteframes[frame];
//minenice's speen css, it's a piece of shit but hey
// minenice's speen css, it's a piece of shit but hey
speenframe = (I_GetTime()*cv_skinselectspin.value/TICRATE + 1)%8;
//this is a very shitty solution for checking if a sprite needs flipping
//but it works
if ((sprframe->lumppat[speenframe] == sprframe->lumppat[8-speenframe]) && (speenframe > 4))
// this is a very shitty solution for checking if a sprite needs flipping
// but it works
if ((speenframe > 4) && (sprframe->lumppat[speenframe] == sprframe->lumppat[8-speenframe]))
flags = V_FLIP; // This sprite is left/right flipped!
patch = (patch_t *)W_CachePatchNum(sprframe->lumppat[speenframe], PU_PATCH);
@@ -9437,9 +9450,8 @@ static void M_VideoModeMenu(INT32 choice)
memset(modedescs, 0, sizeof(modedescs));
#if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL)
VID_PrepareModeList(); // FIXME: hack
#endif
vidm_nummodes = 0;
vidm_selected = 0;
nummodes = VID_NumModes();
@@ -9631,7 +9643,7 @@ static void M_DrawLocalSkinMenu(void)
//this is a very shitty solution for checking if a sprite needs flipping
//but it works
if ((sprframe->lumppat[speenframe] == sprframe->lumppat[8-speenframe]) && (speenframe > 4))
if ((speenframe > 4) && (sprframe->lumppat[speenframe] == sprframe->lumppat[8-speenframe]))
{
flags = V_FLIP; // This sprite is left/right flipped!
}
@@ -10330,9 +10342,9 @@ static const char *M_GetDiscordName(discordRequest_t *r)
return "";
if (cv_discordstreamer.value)
return r->username;
return DRPC_HideUsername(r->username);
return va("%s#%s", r->username, r->discriminator);
return r->username;
}
// (this goes in k_hud.c when merged into v2)
+35 -17
View File
@@ -645,10 +645,20 @@ static menuitem_t OP_ControlsMenu[] =
{IT_CALL | IT_STRING, NULL, "Player 3 Controls...", &M_Setup3PControlsMenu, 30},
{IT_CALL | IT_STRING, NULL, "Player 4 Controls...", &M_Setup4PControlsMenu, 40},
{IT_SUBMENU | IT_STRING, NULL, "Mouse Options...", &OP_MouseOptionsDef, 60},
{IT_SUBMENU | IT_STRING, NULL, "Mouse Options...", &OP_MouseOptionsDef, 55},
{IT_STRING | IT_CVAR, NULL, "Controls per key", &cv_controlperkey, 80},
{IT_STRING | IT_CVAR, NULL, "Digital turn easing", &cv_turnsmooth, 90},
{IT_STRING | IT_CVAR, NULL, "Controls per key", &cv_controlperkey, 75},
{IT_STRING | IT_CVAR, NULL, "Digital turn easing (P1)", &cv_turnsmooth[0], 85},
{IT_STRING | IT_CVAR, NULL, "Digital turn easing (P2)", &cv_turnsmooth[1], 95},
{IT_STRING | IT_CVAR, NULL, "Digital turn easing (P3)", &cv_turnsmooth[2], 105},
{IT_STRING | IT_CVAR, NULL, "Digital turn easing (P4)", &cv_turnsmooth[3], 115},
// i hate our menus sincerly
{IT_STRING | IT_CVAR, NULL, "Lite Steer (P1)", &cv_litesteer[0], 135},
{IT_STRING | IT_CVAR, NULL, "Lite Steer (P2)", &cv_litesteer[1], 145},
{IT_STRING | IT_CVAR, NULL, "Lite Steer (P3)", &cv_litesteer[2], 155},
{IT_STRING | IT_CVAR, NULL, "Lite Steer (P4)", &cv_litesteer[3], 165},
};
static const char* OP_ControlsTooltips[] =
@@ -659,7 +669,15 @@ static const char* OP_ControlsTooltips[] =
"Setup player 4 controls.",
"Options for mouse control.",
"Allowed amount of controls per key.",
"Turn smoothing for non-analog turning.",
"Turn smoothing for non-analog turning (Player 1).",
"Turn smoothing for non-analog turning (Player 2).",
"Turn smoothing for non-analog turning (Player 3).",
"Turn smoothing for non-analog turning (Player 4).",
"Hold DOWN on d-pad/keyboard for shallow turns (Player 1).",
"Hold DOWN on d-pad/keyboard for shallow turns (Player 2).",
"Hold DOWN on d-pad/keyboard for shallow turns (Player 3).",
"Hold DOWN on d-pad/keyboard for shallow turns (Player 4).",
};
static menuitem_t OP_AllControlsMenu[] =
@@ -950,16 +968,16 @@ static const char* OP_ExpTooltips[] =
NULL,
"How far Mobj interpolation should take effect.",
"When weather is on this will cut the object amount used in half.",
"Sets minimum sector brightness, useful for dark areas",
"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.",
"Change the FPS counter sampling method\nInaccurate updates slower and might miss frame drops and such\nAccurate updates faster and is more accurate, but might be less readable", // how to ingles??
"Skips rendering frames if game logic takes too long preventing issues during performance drops." // idk im shit as describing things
"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
"Should the game do Screen Textures? Provides a good boost to frames\nat the cost of some visual effects not working when disabled.",
#ifdef USE_FBO_OGL
"Allows the game to downsample from a higher resolution than your display\nin OpenGL renderer mode. Requires a GPU with atleast OpenGL 3.0 support.",
"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
"Change the bit depth of the Lookup Palette in Palette rendering mode\n 16 bits is like software looks ingame\nwhile 24 bits is how software looks in screenshots.",
#endif
@@ -1357,15 +1375,15 @@ static menuitem_t OP_Player4CamOptionsMenu[] =
static const char* OP_PlayerCamOptionsTooltips[] =
{
NULL,
"Should the Camera flip on gravity flipped sections?.",
"Should the Camera flip on gravity flipped sections?",
"Camera distance relative to the Player.",
"Height of the Camera",
"Pitch Camera on Upwards or Downhill Slopes",
"Speed of the Camera",
"Should looking back inherit the Players Momentum?\nEither inherit Player Momentum or double of it\nmay make looking back while boosting or going in high speed less jarring",
"Height of the Camera.",
"Pitch Camera on Upwards or Downhill Slopes.",
"Speed of the Camera.",
"Should looking back inherit the Players Momentum?\nEither inherit Player Momentum or double of it\nmay make looking back while boosting or going in high speed less jarring.",
"Allows looking up/down by holding\naim forward/backward while standing still.",
"Speed of the Freecam/Spectator Camera",
"Toggle between Third or First Person camera",
"Speed of the Freecam/Spectator Camera.",
"Toggle between Third or First Person camera.",
};
// Ok it's still called chatoptions but we'll put ping display in here to be clean
@@ -1745,7 +1763,7 @@ static const char* OP_PlayerDistortTooltips[] =
"Distance object rotation should be visable.",
"Player rotation when sliptiding.",
"Rotation of a player's boost trails and drift sparks.",
"Should banans rotate when thrown?\nAnd should they stay rotated when on the ground?.",
"Should banans rotate when thrown?\nAnd should they stay rotated when on the ground?",
"Player squash and stretch.",
"Player landing sound effect.",
"Kart hopping while drifting. This is purely visual.",
@@ -2424,7 +2442,7 @@ menu_t OP_MainDef =
NULL
};
menu_t OP_ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_ControlsMenu, &OP_MainDef, 60, 30, OP_ControlsTooltips);
menu_t OP_ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_ControlsMenu, &OP_MainDef, 40, 15, OP_ControlsTooltips);
//WTF
menu_t OP_MouseOptionsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_MouseOptionsMenu, &OP_ControlsDef, 60, 30, OP_MouseTooltips);
menu_t OP_AllControlsDef = CONTROLMENUSTYLE(OP_AllControlsMenu, &OP_ControlsDef);
+13 -2
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file m_textinput.c
/// \brief User text input implementation
#include "m_textinput.h"
#include "m_menu.h" // MAXSTRINGLENGTH
#include "v_video.h"
@@ -228,8 +239,8 @@ void M_TextInputClear(textinput_t *input)
void M_TextInputSetString(textinput_t *input, const char *c)
{
memset(input->buffer, 0, input->buffer_size);
strcpy(input->buffer, c);
input->cursor = input->select = input->length = strlen(c);
strncpy(input->buffer, c, input->buffer_size);
input->cursor = input->select = input->length = strlen(input->buffer);
}
static boolean M_TextInputHandleBase(textinput_t *input, INT32 key, boolean emotes)
+11
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file m_textinput.h
/// \brief User text input implementation
#ifndef __M_TEXTINPUT__
#define __M_TEXTINPUT__
+134 -69
View File
@@ -345,6 +345,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
blockdist = thing->radius + tmthing->radius;
if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist)
return true; // didn't hit it
// see if it went over / under
if (tmthing->z > thing->z + thing->height)
return true; // overhead
@@ -707,7 +708,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\was hit by a kitchen sink.\\\\\\\\", player_names[thing->player-players]));
I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[thing->player-players]);
//I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[thing->player-players]);
P_DamageMobj(thing, tmthing, tmthing->target, DMG_INSTAKILL);
P_KillMobj(tmthing, thing, thing);
}
@@ -976,7 +977,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\was hit by a kitchen sink.\\\\\\\\", player_names[tmthing->player-players]));
I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[tmthing->player-players]);
//I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[tmthing->player-players]);
P_DamageMobj(tmthing, thing, thing->target, DMG_INSTAKILL);
P_KillMobj(thing, tmthing, tmthing);
}
@@ -1712,10 +1713,14 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
tmbbox[BOXRIGHT] = x + tmthing->radius;
tmbbox[BOXLEFT] = x - tmthing->radius;
if (thing->x != x || thing->y != y || thing->subsector == NULL)
if (thing->x != x || thing->y != y || !thing->subsector)
{
newsec = R_PointInSubsector(x, y)->sector;
}
else
{
newsec = thing->subsector->sector;
}
ceilingline = blockingline = NULL;
@@ -1808,17 +1813,17 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
midheight = (bottomheight + ((topheight - bottomheight)/2));
delta1 = thing->z - midheight;
delta2 = thingtop - midheight;
delta1 = abs(thing->z - midheight);
delta2 = abs(thingtop - midheight);
if (topheight > tmfloorz && abs(delta1) < abs(delta2)
if (topheight > tmfloorz && delta1 < delta2
&& !(rover->flags & FF_REVERSEPLATFORM))
{
tmfloorz = tmdropoffz = topheight;
tmfloorslope = *rover->t_slope;
}
if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2)
if (bottomheight < tmceilingz && delta1 >= delta2
&& !(rover->flags & FF_PLATFORM)
&& !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE)))
{
@@ -1869,7 +1874,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
{
sector_t *polysec;
fixed_t delta1, delta2, thingtop;
fixed_t polytop, polybottom;
fixed_t polytop, polybottom, polymid;
po->validcount = validcount;
@@ -1895,21 +1900,24 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
}
thingtop = thing->z + thing->height;
delta1 = thing->z - (polybottom + ((polytop - polybottom)/2));
delta2 = thingtop - (polybottom + ((polytop - polybottom)/2));
polymid = (polybottom + ((polytop - polybottom)/2));
if (polytop > tmfloorz && abs(delta1) < abs(delta2))
delta1 = abs(thing->z - polymid);
delta2 = abs(thingtop - polymid);
if (polytop > tmfloorz && delta1 < delta2)
{
tmfloorz = tmdropoffz = polytop;
tmfloorslope = NULL;
}
if (polybottom < tmceilingz && abs(delta1) >= abs(delta2))
if (polybottom < tmceilingz && delta1 >= delta2)
{
tmceilingz = tmdrpoffceilz = polybottom;
tmceilingslope = NULL;
}
}
plink = (polymaplink_t *)(plink->link.next);
}
}
@@ -1994,10 +2002,14 @@ static boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
tmbbox[BOXRIGHT] = x + thiscam->radius;
tmbbox[BOXLEFT] = x - thiscam->radius;
if (thiscam->x != x || thiscam->y != y || thiscam->subsector == NULL)
newsec = R_PointInSubsectorFast(x, y)->sector;
if (thiscam->x != x || thiscam->y != y || !thiscam->subsector)
{
newsec = R_PointInSubsector(x, y)->sector;
}
else
{
newsec = thiscam->subsector->sector;
}
ceilingline = blockingline = NULL;
@@ -2042,24 +2054,25 @@ static boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
for (rover = newsec->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
fixed_t topheight, bottomheight, midheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL)
|| UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
continue;
topheight = P_CameraGetFOFTopZ(thiscam, newsec, rover, x, y, NULL);
bottomheight = P_CameraGetFOFBottomZ(thiscam, newsec, rover, x, y, NULL);
midheight = (bottomheight + ((topheight - bottomheight)/2));
delta1 = thiscam->z - (bottomheight
+ ((topheight - bottomheight)/2));
delta2 = thingtop - (bottomheight
+ ((topheight - bottomheight)/2));
delta1 = abs(thiscam->z - midheight);
delta2 = abs(thingtop - midheight);
if (topheight > tmfloorz && abs(delta1) < abs(delta2))
if (topheight > tmfloorz && delta1 < delta2)
{
tmfloorz = tmdropoffz = topheight;
}
if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2))
if (bottomheight < tmceilingz && delta1 >= delta2)
{
tmceilingz = tmdrpoffceilz = bottomheight;
}
@@ -2085,6 +2098,7 @@ static boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
validcount++;
for (by = yl; by <= yh; by++)
{
for (bx = xl; bx <= xh; bx++)
{
INT32 offset;
@@ -2106,7 +2120,7 @@ static boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
{
sector_t *polysec;
fixed_t delta1, delta2, thingtop;
fixed_t polytop, polybottom;
fixed_t polytop, polybottom, polymid;
po->validcount = validcount;
@@ -2137,18 +2151,21 @@ static boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
}
thingtop = thiscam->z + thiscam->height;
delta1 = thiscam->z - (polybottom + ((polytop - polybottom)/2));
delta2 = thingtop - (polybottom + ((polytop - polybottom)/2));
polymid = (polybottom + ((polytop - polybottom)/2));
if (polytop > tmfloorz && abs(delta1) < abs(delta2))
delta1 = abs(thiscam->z - polymid);
delta2 = abs(thingtop - polymid);
if (polytop > tmfloorz && delta1 < delta2)
tmfloorz = tmdropoffz = polytop;
if (polybottom < tmceilingz && abs(delta1) >= abs(delta2))
if (polybottom < tmceilingz && delta1 >= delta2)
tmceilingz = tmdrpoffceilz = polybottom;
}
plink = (polymaplink_t *)(plink->link.next);
}
}
}
}
// check lines
@@ -2172,7 +2189,7 @@ static boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
//
boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
{
subsector_t *s;
subsector_t *subsec;
UINT8 i;
floatok = false;
@@ -2181,9 +2198,9 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
return false;
if (thiscam->x != x || thiscam->y != y || thiscam->subsector == NULL)
s = R_PointInSubsectorFast(x, y);
subsec = R_PointInSubsectorFast(x, y);
else
s = thiscam->subsector;
subsec = thiscam->subsector;
if (players[displayplayers[0]].mo)
{
@@ -2203,7 +2220,7 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
thiscam->ceilingz = thiscam->z + thiscam->height;
thiscam->x = x;
thiscam->y = y;
thiscam->subsector = s;
thiscam->subsector = subsec;
return true;
}
}
@@ -2215,6 +2232,7 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
tryx -= MAXRADIUS;
else
tryx = x;
if (y-tryy > MAXRADIUS)
tryy += MAXRADIUS;
else if (y-tryy < -MAXRADIUS)
@@ -2232,14 +2250,14 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
if (tmceilingz - thiscam->z < thiscam->height)
{
if (s == thiscam->subsector && tmceilingz >= thiscam->z)
if (subsec == thiscam->subsector && tmceilingz >= thiscam->z)
{
floatok = true;
thiscam->floorz = tmfloorz;
thiscam->ceilingz = tmfloorz + thiscam->height;
thiscam->x = x;
thiscam->y = y;
thiscam->subsector = s;
thiscam->subsector = subsec;
return true;
}
else
@@ -2264,7 +2282,7 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
thiscam->ceilingz = tmceilingz;
thiscam->x = x;
thiscam->y = y;
thiscam->subsector = s;
thiscam->subsector = subsec;
return true;
}
@@ -2377,6 +2395,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
tryx -= radius;
else
tryx = x;
if (y-tryy > radius)
tryy += radius;
else if (y-tryy < -radius)
@@ -2392,28 +2411,34 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
{
//All things are affected by their scale.
fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapobjectscale);
INT32 special = 0;
if (thing->player)
{
const INT32 special = GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1);
special = GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1);
// If using type Section1:13, double the maxstep.
if (P_PlayerTouchingSectorSpecial(thing->player, 1, 13)
|| special == 13)
if (P_PlayerTouchingSectorSpecial(thing->player, 1, 13) || special == 13)
{
maxstep <<= 1;
}
// If using type Section1:12, no maxstep. For ledges you don't want the player to climb! (see: Egg Zeppelin & SMK port walls)
else if (P_PlayerTouchingSectorSpecial(thing->player, 1, 12)
|| special == 12)
else if (P_PlayerTouchingSectorSpecial(thing->player, 1, 12) || special == 12)
{
maxstep = 0;
}
}
if (thing->type == MT_SKIM)
{
maxstep = 0;
}
if (tmceilingz - tmfloorz < thing->height)
{
if (tmfloorthing)
tmhitthing = tmfloorthing;
return false; // doesn't fit
}
@@ -2446,11 +2471,8 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
return false; // mobj must lower itself to fit
}
}
else if (maxstep > 0 && !(
thing->player && (
P_PlayerTouchingSectorSpecial(thing->player, 1, 14)
|| GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 14)
)) // Step down
else if (maxstep > 0 && !(thing->player &&
(P_PlayerTouchingSectorSpecial(thing->player, 1, 14) || special == 14))) // Step down
{
// If the floor difference is MAXSTEPMOVE or less, and the sector isn't Section1:14, ALWAYS
// step down! Formerly required a Section1:13 sector for the full MAXSTEPMOVE, but no more.
@@ -2472,10 +2494,14 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (thing->eflags & MFE_VERTICALFLIP)
{
if (tmdrpoffceilz - tmceilingz > maxstep)
{
return false;
}
}
else if (tmfloorz - tmdropoffz > maxstep)
{
return false; // don't stand over a dropoff
}
}
}
} while (tryx != x || tryy != y);
@@ -2551,6 +2577,7 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
tryx = thing->x;
tryy = thing->y;
do {
if (x-tryx > MAXRADIUS)
tryx += MAXRADIUS;
@@ -2558,6 +2585,7 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
tryx -= MAXRADIUS;
else
tryx = x;
if (y-tryy > MAXRADIUS)
tryy += MAXRADIUS;
else if (y-tryy < -MAXRADIUS)
@@ -2570,14 +2598,14 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
if (!(thing->flags & MF_NOCLIP))
{
const fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapobjectscale);
if (tmceilingz - tmfloorz < thing->height)
return false; // doesn't fit
if (tmceilingz - thing->z < thing->height)
return false; // mobj must lower itself to fit
const fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapobjectscale);
if (tmfloorz - thing->z > maxstep)
return false; // too big a step up
}
@@ -2911,6 +2939,7 @@ static boolean PTR_SlideTraverse(intercept_t *in)
{
if (P_PointOnLineSide(slidemo->x, slidemo->y, li))
return true; // don't hit the back side
goto isblocking;
}
@@ -3202,32 +3231,46 @@ stairstep:
}
do {
if (tmxmove > mo->radius) {
if (tmxmove > mo->radius)
{
newx = mo->x + mo->radius;
tmxmove -= mo->radius;
} else if (tmxmove < -mo->radius) {
}
else if (tmxmove < -mo->radius)
{
newx = mo->x - mo->radius;
tmxmove += mo->radius;
} else {
}
else
{
newx = mo->x + tmxmove;
tmxmove = 0;
}
if (tmymove > mo->radius) {
if (tmymove > mo->radius)
{
newy = mo->y + mo->radius;
tmymove -= mo->radius;
} else if (tmymove < -mo->radius) {
}
else if (tmymove < -mo->radius)
{
newy = mo->y - mo->radius;
tmymove += mo->radius;
} else {
}
else
{
newy = mo->y + tmymove;
tmymove = 0;
}
if (!P_TryMove(mo, newx, newy, true)) {
if (!P_TryMove(mo, newx, newy, true))
{
if (success)
return; // Good enough!!
else
goto retry;
}
success = true;
} while(tmxmove || tmymove);
}
@@ -3315,10 +3358,12 @@ void P_BouncePlayerMove(mobj_t *mo)
{
mobj_t *fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP);
if (mo->eflags & MFE_VERTICALFLIP)
fx->eflags |= MFE_VERTICALFLIP;
else
fx->eflags &= ~MFE_VERTICALFLIP;
fx->scale = mo->scale;
S_StartSound(mo, sfx_s3k49);
@@ -3332,7 +3377,8 @@ void P_BouncePlayerMove(mobj_t *mo)
mo->player->cmomx = tmxmove;
mo->player->cmomy = tmymove;
if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true)) {
if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true))
{
P_TryMove(mo, mo->x - oldmomx, mo->y - oldmomy, true);
}
}
@@ -3603,7 +3649,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
if (thing->subsector->sector->ffloors && (realcrush || thing->flags & MF_PUSHABLE))
{
ffloor_t *rover;
fixed_t topheight, bottomheight;
fixed_t topheight, bottomheight, midheight;
fixed_t delta1, delta2;
INT32 thingtop = thing->z + thing->height;
@@ -3615,10 +3661,12 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
topheight = *rover->topheight;
bottomheight = *rover->bottomheight;
midheight = ((bottomheight + topheight)/2);
delta1 = thing->z - (bottomheight + topheight)/2;
delta2 = thingtop - (bottomheight + topheight)/2;
if (bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2))
delta1 = abs(thing->z - midheight);
delta2 = abs(thingtop - midheight);
if (bottomheight <= thing->ceilingz && delta1 >= delta2)
{
if (thing->flags & MF_PUSHABLE)
{
@@ -3667,6 +3715,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
killer = P_SpawnMobj(thing->x, thing->y, thing->z, MT_NULL);
killer->threshold = 44; // Special flag for crushing
}
if (!thing->player)
P_DamageMobj(thing, killer, killer, DMG_INSTAKILL);
else
@@ -3706,6 +3755,7 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
{
size_t i;
sector_t *sec;
for (i = 0; i < sector->numattached; i++)
{
sec = &sectors[sector->attached[i]];
@@ -3746,9 +3796,11 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
do
{
for (n = sector->touching_thinglist; n; n = n->m_thinglist_next) // go through list
{
if (!n->visited) // unprocessed thing found
{
n->visited = true; // mark thing as processed
if (!(n->m_thing->flags & MF_NOBLOCKMAP)) //jff 4/7/98 don't do these
{
if (!PIT_ChangeSector(n->m_thing, false)) // process it
@@ -3757,8 +3809,10 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
return nofit;
}
}
break; // exit and start over
}
}
} while (n); // repeat from scratch until all things left are marked valid
// Nothing blocked us, so lets crush for real!
@@ -3780,15 +3834,18 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
do
{
for (n = sec->touching_thinglist; n; n = n->m_thinglist_next)
if (!n->visited)
{
n->visited = true;
if (!(n->m_thing->flags & MF_NOBLOCKMAP))
if (!n->visited)
{
PIT_ChangeSector(n->m_thing, true);
return nofit;
n->visited = true;
if (!(n->m_thing->flags & MF_NOBLOCKMAP))
{
PIT_ChangeSector(n->m_thing, true);
return nofit;
}
break;
}
break;
}
} while (n);
}
@@ -3803,9 +3860,11 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
do
{
for (n = sector->touching_thinglist; n; n = n->m_thinglist_next) // go through list
{
if (!n->visited) // unprocessed thing found
{
n->visited = true; // mark thing as processed
if (!(n->m_thing->flags & MF_NOBLOCKMAP)) //jff 4/7/98 don't do these
{
PIT_ChangeSector(n->m_thing, true); // process it
@@ -3813,6 +3872,7 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
}
break; // exit and start over
}
}
} while (n); // repeat from scratch until all things left are marked valid
return nofit;
@@ -3902,6 +3962,7 @@ static msecnode_t *P_DelSecnode(msecnode_t *node)
tp = node->m_sectorlist_prev;
tn = node->m_sectorlist_next;
if (tp)
tp->m_sectorlist_next = tn;
if (tn)
@@ -3912,6 +3973,7 @@ static msecnode_t *P_DelSecnode(msecnode_t *node)
sp = node->m_thinglist_prev;
sn = node->m_thinglist_next;
if (sp)
sp->m_thinglist_next = sn;
else
@@ -3959,7 +4021,7 @@ static inline boolean PIT_GetSectors(line_t *ld)
// allowed to move to this position, then the sector_list
// will be attached to the Thing's mobj_t at touching_sectorlist.
sector_list = P_AddSecnode(ld->frontsector,tmthing,sector_list);
sector_list = P_AddSecnode(ld->frontsector, tmthing, sector_list);
// Don't assume all lines are 2-sided, since some Things
// like MT_TFOG are allowed regardless of whether their radius takes
@@ -4087,7 +4149,7 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
for (rover = sec->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
fixed_t topheight, bottomheight, midheight;
if (!(rover->flags & FF_EXISTS))
continue;
@@ -4105,13 +4167,16 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
if (floorz < z)
floorz = z;
}
continue;
}
delta1 = z - (bottomheight + ((topheight - bottomheight)/2));
delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2));
midheight = (bottomheight + ((topheight - bottomheight)/2));
if (topheight > floorz && abs(delta1) < abs(delta2))
delta1 = abs(z - midheight);
delta2 = abs(thingtop - midheight);
if (topheight > floorz && delta1 < delta2)
floorz = topheight;
}
}
+1 -1
View File
@@ -11889,7 +11889,7 @@ void P_SpawnHoops(mapthing_t *mthing)
z += P_GetSectorFloorZAt(sec, x, y);
hoopcenter->z -= hoopcenter->height/2;
hoopcenter->z = z - hoopcenter->height/2;
P_UnsetThingPosition(hoopcenter);
hoopcenter->x = x;
+36 -36
View File
@@ -61,7 +61,7 @@ typedef enum
//
// P_ArchivePlayer
//
static inline void P_ArchivePlayer(savebuffer_t *save)
FUNCINLINE static ATTRINLINE void P_ArchivePlayer(savebuffer_t *save)
{
const player_t *player = &players[consoleplayer];
INT32 pllives = player->lives;
@@ -85,7 +85,7 @@ static inline void P_ArchivePlayer(savebuffer_t *save)
//
// P_UnArchivePlayer
//
static inline void P_UnArchivePlayer(savebuffer_t *save)
FUNCINLINE static ATTRINLINE void P_UnArchivePlayer(savebuffer_t *save)
{
savedata.skincolor = READUINT8(save->p);
savedata.skin = READUINT8(save->p);
@@ -1043,25 +1043,25 @@ typedef enum
tc_end
} specials_e;
static inline UINT32 SaveMobjnum(const mobj_t *mobj)
FUNCINLINE static ATTRINLINE UINT32 SaveMobjnum(const mobj_t *mobj)
{
if (mobj) return mobj->mobjnum;
return 0;
}
static inline UINT32 SaveSector(const sector_t *sector)
FUNCINLINE static ATTRINLINE UINT32 SaveSector(const sector_t *sector)
{
if (sector) return (UINT32)(sector - sectors);
return 0xFFFFFFFF;
}
static inline UINT32 SaveLine(const line_t *line)
FUNCINLINE static ATTRINLINE UINT32 SaveLine(const line_t *line)
{
if (line) return (UINT32)(line - lines);
return 0xFFFFFFFF;
}
static inline UINT32 SavePlayer(const player_t *player)
FUNCINLINE static ATTRINLINE UINT32 SavePlayer(const player_t *player)
{
if (player) return (UINT32)(player - players);
return 0xFFFFFFFF;
@@ -1476,7 +1476,7 @@ static void SaveElevatorThinker(savebuffer_t *save, const thinker_t *th, const U
//
// Saves a scroll_t thinker
//
static inline void SaveScrollThinker(savebuffer_t *save, const thinker_t *th, const UINT8 type)
FUNCINLINE static ATTRINLINE void SaveScrollThinker(savebuffer_t *save, const thinker_t *th, const UINT8 type)
{
const scroll_t *ht = (const void *)th;
WRITEUINT8(save->p, type);
@@ -1497,7 +1497,7 @@ static inline void SaveScrollThinker(savebuffer_t *save, const thinker_t *th, co
//
// Saves a friction_t thinker
//
static inline void SaveFrictionThinker(savebuffer_t *save, const thinker_t *th, const UINT8 type)
FUNCINLINE static ATTRINLINE void SaveFrictionThinker(savebuffer_t *save, const thinker_t *th, const UINT8 type)
{
const friction_t *ht = (const void *)th;
WRITEUINT8(save->p, type);
@@ -1513,7 +1513,7 @@ static inline void SaveFrictionThinker(savebuffer_t *save, const thinker_t *th,
//
// Saves a pusher_t thinker
//
static inline void SavePusherThinker(savebuffer_t *save, const thinker_t *th, const UINT8 type)
FUNCINLINE static ATTRINLINE void SavePusherThinker(savebuffer_t *save, const thinker_t *th, const UINT8 type)
{
const pusher_t *ht = (const void *)th;
WRITEUINT8(save->p, type);
@@ -1598,7 +1598,7 @@ static void SaveDisappearThinker(savebuffer_t *save, const thinker_t *th, const
//
// Saves a polyrotate_t thinker
//
static inline void SavePolyrotatetThinker(savebuffer_t *save, const thinker_t *th, const UINT8 type)
FUNCINLINE static ATTRINLINE void SavePolyrotatetThinker(savebuffer_t *save, const thinker_t *th, const UINT8 type)
{
const polyrotate_t *ht = (const void *)th;
WRITEUINT8(save->p, type);
@@ -1935,25 +1935,25 @@ mobj_t *P_FindNewPosition(UINT32 oldposition)
return NULL;
}
static inline mobj_t *LoadMobj(UINT32 mobjnum)
FUNCINLINE static ATTRINLINE mobj_t *LoadMobj(UINT32 mobjnum)
{
if (mobjnum == 0) return NULL;
return (mobj_t *)(size_t)mobjnum;
}
static inline sector_t *LoadSector(UINT32 sector)
FUNCINLINE static ATTRINLINE sector_t *LoadSector(UINT32 sector)
{
if (sector >= numsectors) return NULL;
return &sectors[sector];
}
static inline line_t *LoadLine(UINT32 line)
FUNCINLINE static ATTRINLINE line_t *LoadLine(UINT32 line)
{
if (line >= numlines) return NULL;
return &lines[line];
}
static inline player_t *LoadPlayer(UINT32 player)
FUNCINLINE static ATTRINLINE player_t *LoadPlayer(UINT32 player)
{
if (player >= MAXPLAYERS) return NULL;
return &players[player];
@@ -2529,7 +2529,7 @@ static void LoadScrollThinker(savebuffer_t *save, actionf_p1 thinker)
//
// Loads a friction_t from a save game
//
static inline void LoadFrictionThinker(savebuffer_t *save, actionf_p1 thinker)
FUNCINLINE static ATTRINLINE void LoadFrictionThinker(savebuffer_t *save, actionf_p1 thinker)
{
friction_t *ht = (friction_t*)Z_LevelPoolMalloc(sizeof (*ht));
ht->thinker.alloctype = TAT_LEVELPOOL;
@@ -2576,7 +2576,7 @@ static void LoadPusherThinker(savebuffer_t *save, actionf_p1 thinker)
//
// Loads a laserthink_t from a save game
//
static inline void LoadLaserThinker(savebuffer_t *save, actionf_p1 thinker)
FUNCINLINE static ATTRINLINE void LoadLaserThinker(savebuffer_t *save, actionf_p1 thinker)
{
laserthink_t *ht = (laserthink_t*)Z_LevelPoolMalloc(sizeof (*ht));
ht->thinker.alloctype = TAT_LEVELPOOL;
@@ -2621,7 +2621,7 @@ FUNCINLINE static ATTRINLINE void LoadLightlevelThinker(savebuffer_t *save, acti
//
// Loads a executor_t from a save game
//
static inline void LoadExecutorThinker(savebuffer_t *save, actionf_p1 thinker)
FUNCINLINE static ATTRINLINE void LoadExecutorThinker(savebuffer_t *save, actionf_p1 thinker)
{
executor_t *ht = (executor_t*)Z_LevelPoolMalloc(sizeof (*ht));
ht->thinker.alloctype = TAT_LEVELPOOL;
@@ -2639,7 +2639,7 @@ static inline void LoadExecutorThinker(savebuffer_t *save, actionf_p1 thinker)
//
// Loads a disappear_t thinker
//
static inline void LoadDisappearThinker(savebuffer_t *save, actionf_p1 thinker)
FUNCINLINE static ATTRINLINE void LoadDisappearThinker(savebuffer_t *save, actionf_p1 thinker)
{
disappear_t *ht = (disappear_t*)Z_LevelPoolMalloc(sizeof (*ht));
ht->thinker.alloctype = TAT_LEVELPOOL;
@@ -2660,7 +2660,7 @@ static inline void LoadDisappearThinker(savebuffer_t *save, actionf_p1 thinker)
//
// Loads a polyrotate_t thinker
//
static inline void LoadPolyrotatetThinker(savebuffer_t *save, actionf_p1 thinker)
FUNCINLINE static ATTRINLINE void LoadPolyrotatetThinker(savebuffer_t *save, actionf_p1 thinker)
{
polyrotate_t *ht = (polyrotate_t*)Z_LevelPoolMalloc(sizeof (*ht));
ht->thinker.alloctype = TAT_LEVELPOOL;
@@ -2720,7 +2720,7 @@ static void LoadPolymoveThinker(savebuffer_t *save, actionf_p1 thinker)
//
// Loads a polywaypoint_t thinker
//
static inline void LoadPolywaypointThinker(savebuffer_t *save, actionf_p1 thinker)
FUNCINLINE static ATTRINLINE void LoadPolywaypointThinker(savebuffer_t *save, actionf_p1 thinker)
{
polywaypoint_t *ht = (polywaypoint_t*)Z_LevelPoolMalloc(sizeof (*ht));
ht->thinker.alloctype = TAT_LEVELPOOL;
@@ -2776,7 +2776,7 @@ static inline void LoadPolywaypointThinker(savebuffer_t *save, actionf_p1 thinke
//
// loads a polyslidedoor_t thinker
//
static inline void LoadPolyslidedoorThinker(savebuffer_t *save, actionf_p1 thinker)
FUNCINLINE static ATTRINLINE void LoadPolyslidedoorThinker(savebuffer_t *save, actionf_p1 thinker)
{
polyslidedoor_t *ht = (polyslidedoor_t*)Z_LevelPoolMalloc(sizeof (*ht));
ht->thinker.alloctype = TAT_LEVELPOOL;
@@ -2814,7 +2814,7 @@ static inline void LoadPolyslidedoorThinker(savebuffer_t *save, actionf_p1 think
//
// Loads a polyswingdoor_t thinker
//
static inline void LoadPolyswingdoorThinker(savebuffer_t *save, actionf_p1 thinker)
FUNCINLINE static ATTRINLINE void LoadPolyswingdoorThinker(savebuffer_t *save, actionf_p1 thinker)
{
polyswingdoor_t *ht = (polyswingdoor_t*)Z_LevelPoolMalloc(sizeof (*ht));
ht->thinker.alloctype = TAT_LEVELPOOL;
@@ -2847,7 +2847,7 @@ static inline void LoadPolyswingdoorThinker(savebuffer_t *save, actionf_p1 think
//
// Loads a polydisplace_t thinker
//
static inline void LoadPolydisplaceThinker(savebuffer_t *save, actionf_p1 thinker)
FUNCINLINE static ATTRINLINE void LoadPolydisplaceThinker(savebuffer_t *save, actionf_p1 thinker)
{
polydisplace_t *ht = (polydisplace_t*)Z_LevelPoolMalloc(sizeof (*ht));
ht->thinker.alloctype = TAT_LEVELPOOL;
@@ -3115,7 +3115,7 @@ static void P_NetUnArchiveThinkers(savebuffer_t *save)
#define PD_FLAGS 0x01
#define PD_TRANS 0x02
static inline void P_ArchivePolyObj(savebuffer_t *save, polyobj_t *po)
FUNCINLINE static ATTRINLINE void P_ArchivePolyObj(savebuffer_t *save, polyobj_t *po)
{
UINT8 diff = 0;
WRITEINT32(save->p, po->id);
@@ -3137,7 +3137,7 @@ static inline void P_ArchivePolyObj(savebuffer_t *save, polyobj_t *po)
WRITEINT32(save->p, po->translucency);
}
static inline void P_UnArchivePolyObj(savebuffer_t *save, polyobj_t *po)
FUNCINLINE static ATTRINLINE void P_UnArchivePolyObj(savebuffer_t *save, polyobj_t *po)
{
INT32 id;
UINT32 angle;
@@ -3172,7 +3172,7 @@ static inline void P_UnArchivePolyObj(savebuffer_t *save, polyobj_t *po)
Polyobj_MoveOnLoad(po, angle, x, y);
}
static inline void P_ArchivePolyObjects(savebuffer_t *save)
FUNCINLINE static ATTRINLINE void P_ArchivePolyObjects(savebuffer_t *save)
{
INT32 i;
@@ -3185,7 +3185,7 @@ static inline void P_ArchivePolyObjects(savebuffer_t *save)
P_ArchivePolyObj(save, &PolyObjects[i]);
}
static inline void P_UnArchivePolyObjects(savebuffer_t *save)
FUNCINLINE static ATTRINLINE void P_UnArchivePolyObjects(savebuffer_t *save)
{
INT32 i, numSavedPolys;
@@ -3203,7 +3203,7 @@ static inline void P_UnArchivePolyObjects(savebuffer_t *save)
//
// P_FinishMobjs
//
static inline void P_FinishMobjs(void)
FUNCINLINE static ATTRINLINE void P_FinishMobjs(void)
{
thinker_t *currentthinker;
mobj_t *mobj;
@@ -3220,7 +3220,7 @@ static inline void P_FinishMobjs(void)
}
}
static inline mobj_t *RelinkMobj(mobj_t **ptr)
FUNCINLINE static ATTRINLINE mobj_t *RelinkMobj(mobj_t **ptr)
{
UINT32 temp = (UINT32)(size_t)*ptr;
*ptr = NULL;
@@ -3269,7 +3269,7 @@ static void P_RelinkPointers(void)
//
// P_NetArchiveSpecials
//
static inline void P_NetArchiveSpecials(savebuffer_t *save)
FUNCINLINE static ATTRINLINE void P_NetArchiveSpecials(savebuffer_t *save)
{
size_t i, z;
@@ -3347,7 +3347,7 @@ static void P_NetUnArchiveSpecials(savebuffer_t *save)
// =======================================================================
// Misc
// =======================================================================
static inline void P_ArchiveMisc(savebuffer_t *save)
FUNCINLINE static ATTRINLINE void P_ArchiveMisc(savebuffer_t *save)
{
if (gamecomplete)
WRITEINT16(save->p, gamemap | 8192);
@@ -3360,7 +3360,7 @@ static inline void P_ArchiveMisc(savebuffer_t *save)
WRITESTRINGN(save->p, timeattackfolder, sizeof(timeattackfolder));
}
static inline void P_UnArchiveSPGame(savebuffer_t *save, INT16 mapoverride)
FUNCINLINE static ATTRINLINE void P_UnArchiveSPGame(savebuffer_t *save, INT16 mapoverride)
{
char testname[sizeof(timeattackfolder)];
@@ -3531,7 +3531,8 @@ static void P_ReloadSaveLevelData(void)
ss->floorpic_angle = spawnss->floorpic_angle;
ss->ceilingpic_angle = spawnss->ceilingpic_angle;
ss->tag = spawnss->tag;
ss->firsttag = ss->nexttag = -1;
ss->firsttag = spawnss->firsttag;
ss->nexttag = spawnss->nexttag;
if (ss->ffloors)
{
@@ -3556,7 +3557,8 @@ static void P_ReloadSaveLevelData(void)
li->callcount = 0;
li->tag = spawnli->tag;
li->firsttag = li->nexttag = -1;
li->firsttag = spawnli->firsttag;
li->nexttag = spawnli->nexttag;
if (li->sidenum[0] != 0xffff)
{
@@ -3580,8 +3582,6 @@ static void P_ReloadSaveLevelData(void)
si->midtexture = spawnsi->midtexture;
}
}
P_InitTagLists();
}
FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(savebuffer_t *save, boolean reloading)
+4 -3
View File
@@ -1983,11 +1983,12 @@ static void P_LoadMapData(const virtres_t* virt)
P_LoadLinedefs(virtlinedefs->data);
P_LoadSidedefs(virtsidedefs->data);
P_LoadThings(virtthings->data);
P_InitTagLists(); // Create xref tables for tags
// Copy relevant map data for NetArchive purposes.
spawnsectors = Z_Calloc(numsectors * sizeof(*sectors), PU_LEVEL, NULL);
spawnlines = Z_Calloc(numlines * sizeof(*lines), PU_LEVEL, NULL);
spawnsides = Z_Calloc(numsides * sizeof(*sides), PU_LEVEL, NULL);
spawnsectors = Z_Malloc(numsectors * sizeof(*sectors), PU_LEVEL, NULL);
spawnlines = Z_Malloc(numlines * sizeof(*lines), PU_LEVEL, NULL);
spawnsides = Z_Malloc(numsides * sizeof(*sides), PU_LEVEL, NULL);
memcpy(spawnsectors, sectors, numsectors * sizeof(*sectors));
memcpy(spawnlines, lines, numlines * sizeof(*lines));
+1 -3
View File
@@ -2091,8 +2091,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
// Change the music and apply position/fade operations
else
{
strncpy(mapmusic.name, sides[line->sidenum[0]].text, 7);
mapmusic.name[6] = 0;
strlcpy(mapmusic.name, sides[line->sidenum[0]].text, sizeof(mapmusic.name));
mapmusic.flags = tracknum & MUSIC_TRACKMASK;
if (!(line->flags & ML_BLOCKMONSTERS))
@@ -5387,7 +5386,6 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
// set current weather
curWeather = mapheaderinfo[gamemap-1]->weather;
P_InitTagLists(); // Create xref tables for tags
P_SearchForDisableLinedefs(); // Disable linedefs are now allowed to disable *any* line
P_SpawnScrollers(); // Add generalized scrollers
+8 -2
View File
@@ -3315,7 +3315,7 @@ static ticcmd_t *P_CameraCmd(camera_t *cam, UINT8 num)
cmd->sidemove = (SINT8)(cmd->sidemove + side);
}
lang += (cmd->angleturn<<16);
lang += (cmd->angleturn << 16);
cam->localangle = lang;
if (!cam->reset_aiming)
@@ -3821,7 +3821,13 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
if (demo.playback)
{
focusangle = mo->angle;
// Hack-adjacent.
// Sometimes stale ticcmds send a weird angle at the start of the race.
// P_UpdatePlayerAngle knows to ignore cmd angle when you literally can't turn, so we do the same here.
if (leveltime > starttime)
focusangle = player->cmd.angleturn << 16;
else
focusangle = mo->angle; // Just use something known sane.
focusaiming = 0;
}
else if (P_IsLocalPlayer(player))
+1 -2
View File
@@ -18,7 +18,6 @@
#include <stdint.h>
#include "qs22j.h"
#include "doomdef.h"
#define INSORTTHRESH 5 // if n < this use insertion sort
// MUST be >= 2
@@ -89,7 +88,7 @@ static inline char *med3(char *a, char *b, char *c, int (*compar)(const void *,
void qs22j(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *))
{
// we have nothing to sort
if (UNLIKELY(nmemb <= 1))
if (__builtin_expect(!!(nmemb <= 1), 0) ) //UNLIKELY - thx windoze
{
return;
}
+1 -1
View File
@@ -77,7 +77,7 @@ void R_ClearDrawSegs(void)
// CPhipps -
// Instead of clipsegs, let's try using an array with one entry for each column,
// indicating whether it's blocked by a solid wall yet or not.
UINT8 *solidcol;
UINT8 *solidcol = NULL;
void R_AllocClipSegMemory(void)
{
+121 -83
View File
@@ -90,21 +90,21 @@ INT32 numtextures = 0; // total number of textures found,
// size of following tables
texture_t **textures = NULL;
static UINT32 **texturecolumnofs; // column offset lookup table for each texture
UINT8 **texturecache; // graphics data for each generated full-size texture
static UINT32 **texturecolumnofs = NULL; // column offset lookup table for each texture
UINT8 **texturecache = NULL; // graphics data for each generated full-size texture
// texture width is a power of 2, so it can easily repeat along sidedefs using a simple mask
static INT32 *texturewidthmask;
static INT32 *texturewidth = NULL;
fixed_t *textureheight; // needed for texture pegging
fixed_t *textureheight = NULL; // needed for texture pegging
INT32 *texturetranslation;
INT32 *texturetranslation = NULL;
// needed for pre rendering
sprcache_t *spritecachedinfo;
sprcache_t *spritecachedinfo = NULL;
lighttable_t *colormaps;
UINT8 *encoremap;
lighttable_t *colormaps = NULL;
UINT8 *encoremap = NULL;
#ifdef HASINVERT
UINT8 invertmap[256];
#endif
@@ -241,11 +241,12 @@ static INT32 tidcachelen = 0;
// R_DrawColumnInCache
// Clip and draw a column from a patch into a cached post.
//
static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, INT32 originy, INT32 cacheheight)
static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight)
{
INT32 count, position;
UINT8 *source;
INT32 topdelta, prevdelta = -1;
INT32 originy = originPatch->originy;
while (patch->topdelta != 0xff)
{
@@ -260,6 +261,7 @@ static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, INT32 orig
if (position < 0)
{
count += position;
source -= position; // start further down the column
position = 0;
}
@@ -273,6 +275,50 @@ static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, INT32 orig
}
}
static UINT8 *R_AllocateTextureBlock(size_t blocksize, UINT8 **user)
{
texturememory += blocksize;
return Z_Malloc(blocksize, PU_LEVEL, user);
}
static UINT8 *R_AllocateDummyTextureBlock(size_t width, UINT8 **user)
{
// Allocate dummy data. Keep 4-bytes aligned.
// Column offsets will be initialized to 0, which points to the 0xff byte (empty column flag).
size_t blocksize = 4 + (width * 4);
UINT8 *block = R_AllocateTextureBlock(blocksize, user);
memset(block, 0, blocksize);
block[0] = 0xff;
return block;
}
static boolean R_CheckTextureLumpLength(texture_t *texture, size_t patch)
{
UINT16 wadnum = texture->patches[patch].wad;
UINT16 lumpnum = texture->patches[patch].lump;
size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum);
// The header does not exist
if (lumplength < offsetof(softwarepatch_t, columnofs))
{
CONS_Alert(
CONS_ERROR,
"%.8s: texture lump data is too small. Expected %s bytes, got %s. (%s)\n",
texture->name,
sizeu1(offsetof(softwarepatch_t, columnofs)),
sizeu2(lumplength),
wadfiles[wadnum]->lumpinfo[lumpnum].fullname
);
return false;
}
return true;
}
//
// R_GenerateTexture
//
@@ -297,6 +343,10 @@ UINT8 *R_GenerateTexture(size_t texnum)
column_t *patchcol;
UINT8 *colofs;
UINT16 wadnum;
lumpnum_t lumpnum;
size_t lumplength;
I_Assert(texnum <= (size_t)numtextures);
texture = textures[texnum];
I_Assert(texture != NULL);
@@ -311,45 +361,57 @@ UINT8 *R_GenerateTexture(size_t texnum)
{
boolean holey = false;
patch = texture->patches;
pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_LEVEL);
wadnum = patch->wad;
lumpnum = patch->lump;
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
// The header does not exist
if (R_CheckTextureLumpLength(texture, 0) == false)
{
block = R_AllocateDummyTextureBlock(texture->width, &texturecache[texnum]);
texturecolumnofs[texnum] = (UINT32*)&block[4];
textures[texnum]->holes = true;
return block;
}
pdata = (UINT8*)W_CacheLumpNumPwad(wadnum, lumpnum, PU_LEVEL);
realpatch = (softwarepatch_t *)pdata;
// Check the patch for holes.
if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height))
holey = true;
else
colofs = (UINT8 *)realpatch->columnofs;
for (x = 0; x < texture->width && !holey; x++)
{
colofs = (UINT8 *)realpatch->columnofs;
column_t *col = (column_t *)((UINT8 *)realpatch + LONG(*(UINT32 *)&colofs[x<<2]));
for (x = 0; x < texture->width; x++)
INT32 topdelta, prevdelta = -1, y = 0;
while (col->topdelta != 0xff)
{
column_t *col = (column_t *)((UINT8 *)realpatch + LONG(*(UINT32 *)&colofs[x<<2]));
INT32 topdelta, prevdelta = -1, y = 0;
while (col->topdelta != 0xff)
{
topdelta = col->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
if (topdelta > y)
break;
y = topdelta + col->length + 1;
col = (column_t *)((UINT8 *)col + col->length + 4);
}
if (y < texture->height)
holey = true; // this texture is HOLEy! D:
topdelta = col->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
if (topdelta > y)
break;
y = topdelta + col->length + 1;
col = (column_t *)((UINT8 *)col + col->length + 4);
}
if (y < texture->height)
holey = true; // this texture is HOLEy! D:
}
// If the patch uses transparency, we have to save it this way.
if (holey)
{
texture->holes = true;
blocksize = W_LumpLengthPwad(patch->wad, patch->lump);
block = Z_Calloc(blocksize, PU_LEVEL, &texturecache[texnum]);
blocksize = lumplength;
block = Z_Calloc(blocksize, PU_LEVEL, &texturecache[texnum]); // will change tag at end of this function
M_Memcpy(block, realpatch, blocksize);
texturememory += blocksize;
@@ -365,7 +427,6 @@ UINT8 *R_GenerateTexture(size_t texnum)
goto done;
}
// Otherwise, do multipatch format.
}
@@ -384,10 +445,18 @@ UINT8 *R_GenerateTexture(size_t texnum)
// texture data after the lookup table
blocktex = block + (texture->width*4);
for (x = 0; x < texture->width; ++x)
{
// generate column ofset lookup
*(UINT32 *)&colofs[x<<2] = LONG((x * texture->height) + (texture->width*4));
}
// Composite the columns together.
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
{
pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_LEVEL);
wadnum = patch->wad;
lumpnum = patch->lump;
pdata = (UINT8*)W_CacheLumpNumPwad(wadnum, lumpnum, PU_LEVEL);
realpatch = (softwarepatch_t *)pdata;
x1 = patch->originx;
@@ -418,9 +487,7 @@ UINT8 *R_GenerateTexture(size_t texnum)
{
patchcol = (column_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[x-x1]));
// generate column ofset lookup
*(UINT32 *)&colofs[x<<2] = LONG((x * texture->height) + (texture->width*4));
R_DrawColumnInCache(patchcol, block + LONG(*(UINT32 *)&colofs[x<<2]), patch->originy, texture->height);
R_DrawColumnInCache(patchcol, block + LONG(*(UINT32 *)&colofs[x<<2]), patch, texture->height);
}
}
@@ -439,6 +506,7 @@ INT32 R_GetTextureNum(INT32 texnum)
{
if (texnum < 0 || texnum >= numtextures)
return 0;
return texturetranslation[texnum];
}
@@ -456,17 +524,12 @@ void R_CheckTextureCache(INT32 tex)
static inline INT32 wrap_column(fixed_t tex, INT32 col)
{
if (texturewidthmask[tex])
col &= texturewidthmask[tex]; // set by load textures
else
{
const INT16 texwidth = textures[tex]->width;
INT32 width = texturewidth[tex];
// Odd width texture, cannot just mask.
// Sometime gets colnum = -1 or = width, even without tiling.
// Test LostCiv, Map 20, crates.
col = ((col % texwidth) + texwidth) % texwidth;
}
if (width & (width - 1))
col = (UINT32)col % width;
else
col &= (width - 1);
return col;
}
@@ -476,13 +539,6 @@ static inline INT32 wrap_column(fixed_t tex, INT32 col)
//
UINT8 *R_GetColumn(fixed_t tex, INT32 col)
{
if (!texturecache[tex])
{
// This must be here because cache can be freed by other operations.
// To prevent must lock individual texture cache on every draw.
R_GenerateTexture(tex);
}
return texturecache[tex] + LONG(texturecolumnofs[tex][wrap_column(tex, col)]);
}
@@ -516,11 +572,10 @@ static INT32
Rloadtextures (INT32 i, INT32 w)
{
UINT16 j, numlumps = 0;
INT32 k;
UINT16 texstart, texend, texturesLumpPos;
softwarepatch_t *patchlump;
texpatch_t *patch;
texture_t *texture;
softwarepatch_t patchlump;
// Get the lump numbers for the markers in the WAD, if they exist.
if (W_FileHasFolders(wadfiles[w]))
@@ -560,7 +615,7 @@ Rloadtextures (INT32 i, INT32 w)
continue; // If it is then SKIP IT
}
patchlump = (softwarepatch_t *)W_CacheLumpNumPwad(wadnum, lumpnum, PU_STATIC);
W_ReadLumpHeaderPwad(wadnum, lumpnum, &patchlump, PNG_HEADER_SIZE, 0);
//CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((wadnum, lumpnum), patchlump->width, patchlump->height);
texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL);
@@ -568,8 +623,10 @@ Rloadtextures (INT32 i, INT32 w)
// Set texture properties.
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
texture->hash = quickncasehash(texture->name, 8);
texture->width = SHORT(patchlump->width);
texture->height = SHORT(patchlump->height);
texture->width = SHORT(patchlump.width);
texture->height = SHORT(patchlump.height);
texture->type = TEXTURETYPE_SINGLEPATCH;
texture->patchcount = 1;
texture->holes = false;
@@ -581,27 +638,7 @@ Rloadtextures (INT32 i, INT32 w)
patch->wad = wadnum;
patch->lump = texstart + j;
Z_Free(patchlump);
// determine width power of 2
#if 1
// [WDJ] only need to determine if exact power of 2.
k = 1;
while (k < texture->width)
k<<=1;
#else
// Largest power of 2 that fits within width.
k = 1;
while (k << 1 <= texture->width)
k <<= 1;
#endif
if (k != texture->width)
{
// Odd width
k = 1; // make texturewidthmask = 0
}
texturewidthmask[i] = k - 1;
texturewidth[i] = texture->width;
textureheight[i] = texture->height << FRACBITS;
i++;
}
@@ -709,7 +746,7 @@ static void R_AllocateTextures(INT32 add)
// Allocate texture referencing cache.
recallocuser(&texturecache, oldsize, newsize);
// Allocate texture width table.
recallocuser(&texturewidthmask, oldsize, newsize);
recallocuser(&texturewidth, oldsize, newsize);
// Allocate texture height table.
recallocuser(&textureheight, oldsize, newsize);
// Create translation table for global animation.
@@ -1181,7 +1218,7 @@ void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *texindex)
newTexture = R_ParseTexture(true);
// Store the new texture
textures[*texindex] = newTexture;
texturewidthmask[*texindex] = newTexture->width - 1;
texturewidth[*texindex] = newTexture->width;
textureheight[*texindex] = newTexture->height << FRACBITS;
// Increment i back in R_LoadTextures()
(*texindex)++;
@@ -1354,6 +1391,7 @@ void R_ReInitColormaps(UINT16 num, lumpnum_t newencoremap)
// Load in the light tables, now 64k aligned for smokie...
lump = W_GetNumForName(colormap);
if (lump == LUMPERROR)
lump = basecolormaplump;
else
+2 -2
View File
@@ -615,12 +615,12 @@ typedef struct drawseg_s
// Pointers to lists for sprite clipping, all three adjusted so [x1] is first value.
INT16 *sprtopclip;
INT16 *sprbottomclip;
INT16 *maskedtexturecol;
fixed_t *maskedtexturecol;
struct visplane_s *ffloorplanes[MAXFFLOORS];
INT32 numffloorplanes;
struct ffloor_s *thicksides[MAXFFLOORS];
INT16 *thicksidecol;
fixed_t *thicksidecol;
INT32 numthicksides;
fixed_t *frontscale;
+107 -150
View File
@@ -41,8 +41,7 @@
/** \brief view info
*/
INT32 linesize, viewwidth, viewheight, viewwindowx, viewwindowy;
UINT8 *renderscreen; // haleyjd
INT32 viewwidth, viewheight, viewwindowx, viewwindowy;
// =========================================================================
// COLUMN DRAWING CODE STUFF
@@ -489,6 +488,92 @@ void R_FlushTranslationColormapCache(void)
// in reality, the few routines that can work for either mode, are
// put here
enum columncontext_e columncontext = COLUMNCONTEXT_DIRECT;
enum ColumnFlushType
{
FLUSH_NONE = 0x0000,
FLUSH_OPAQUE = 0x0001,
FLUSH_TRANS = 0x0002,
FLUSH_COLORMAP = 0x0004,
FLUSH_COLORMAP_TRANS = 0x0008,
};
typedef struct drawcolumndata_temp_s
{
INT32 x;
INT32 yl[8], yh[8];
// e6y: resolution limitation is removed
UINT8 *buf;
INT32 startx;
ColumnFlushType type;
INT32 commontop, commonbot;
UINT8 *transmap;
// SoM 7-28-04: Fix the fuzz problem.
UINT8 *translation;
} drawcolumndata_temp_t;
drawcolumndata_temp_t temp_dc = {};
//
// Error functions that will abort if R_FlushColumns tries to flush
// columns without a column type.
//
FUNCNORETURN static ATTRNORETURN void R_FlushWholeError(void)
{
I_Error("R_FlushWholeColumns called without being initialized.\n");
}
FUNCNORETURN static ATTRNORETURN void R_FlushHTError(void)
{
I_Error("R_FlushHTColumns called without being initialized.\n");
}
FUNCNORETURN static ATTRNORETURN void R_QuadFlushError(void)
{
I_Error("R_FlushQuadColumn called without being initialized.\n");
}
static void (*R_FlushWholeColumns)(void) = R_FlushWholeError;
static void (*R_FlushHTColumns)(void) = R_FlushHTError;
static void (*R_FlushQuadColumn)(void) = R_QuadFlushError;
static void R_FlushColumns(void)
{
if (temp_dc.x != 8 || temp_dc.commontop >= temp_dc.commonbot)
R_FlushWholeColumns();
else
{
R_FlushHTColumns();
R_FlushQuadColumn();
}
temp_dc.x = 0;
}
//
// R_ResetColumnBuffer
//
// haleyjd 09/13/04: new function to call from main rendering loop
// which gets rid of the unnecessary reset of various variables during
// column drawing.
//
void R_ResetColumnBuffer(void)
{
// haleyjd 10/06/05: this must not be done if x == 0!
if (temp_dc.x)
{
R_FlushColumns();
}
temp_dc.type = FLUSH_NONE;
R_FlushWholeColumns = R_FlushWholeError;
R_FlushHTColumns = R_FlushHTError;
R_FlushQuadColumn = R_QuadFlushError;
}
/** \brief The R_InitViewBuffer function
Creates lookup tables for getting the framebuffer address
@@ -521,40 +606,35 @@ static void R_AllocViewMemory(void)
R_AllocVisSpriteMemory();
}
void R_InitViewBuffer(INT32 width, INT32 height)
void R_InitViewBuffer(void)
{
if (width > MAXVIDWIDTH)
width = MAXVIDWIDTH;
if (height > MAXVIDHEIGHT)
height = MAXVIDHEIGHT;
R_AllocViewMemory();
viewwindowx = 0;
viewwindowy = 0;
linesize = vid.width; // killough 11/98
renderscreen = vid.screens[0]; // haleyjd 07/02/14
}
INT32 bufsize = (vid.width * 8) * sizeof(*temp_dc.buf);
/** \brief viewborder patches lump numbers
*/
lumpnum_t viewborderlump[8];
if (temp_dc.buf)
{
#if defined(__SSE__)
aligned_free(temp_dc.buf);
#else
Z_Free(temp_dc.buf);
#endif
}
/** \brief Store the lumpnumber of the viewborder patches
*/
memset(&temp_dc, 0, sizeof(temp_dc));
void R_InitViewBorder(void)
{
viewborderlump[BRDR_T] = W_GetNumForName("brdr_t");
viewborderlump[BRDR_B] = W_GetNumForName("brdr_b");
viewborderlump[BRDR_L] = W_GetNumForName("brdr_l");
viewborderlump[BRDR_R] = W_GetNumForName("brdr_r");
viewborderlump[BRDR_TL] = W_GetNumForName("brdr_tl");
viewborderlump[BRDR_BL] = W_GetNumForName("brdr_bl");
viewborderlump[BRDR_TR] = W_GetNumForName("brdr_tr");
viewborderlump[BRDR_BR] = W_GetNumForName("brdr_br");
#if defined(__SSE__)
while (bufsize & 15)
bufsize++;
temp_dc.buf = static_cast<UINT8*>(aligned_alloc(16, bufsize));
#else
temp_dc.buf = static_cast<UINT8*>(Z_Malloc(bufsize, PU_STATIC, NULL));
#endif
memset(temp_dc.buf, 0, bufsize);
}
/** \brief The R_VideoErase function
@@ -578,129 +658,6 @@ void R_VideoErase(size_t ofs, INT32 count)
M_Memcpy(vid.screens[0] + ofs, vid.screens[1] + ofs, count);
}
#if 0
/** \brief R_FillBackScreen
Fills the back screen with a pattern for variable screen sizes
Also draws a beveled edge.
*/
void R_FillBackScreen(void)
{
UINT8 *src, *dest;
patch_t *patch;
INT32 x, y, step, boff;
// quickfix, don't cache lumps in both modes
if (rendermode != render_soft)
return;
// draw pattern around the status bar too (when hires),
// so return only when in full-screen without status bar.
if (scaledviewwidth == vid.width && viewheight == vid.height)
return;
src = scr_borderpatch;
dest = vid.screens[1];
for (y = 0; y < vid.height; y++)
{
for (x = 0; x < vid.width/128; x++)
{
M_Memcpy (dest, src+((y&127)<<7), 128);
dest += 128;
}
if (vid.width&127)
{
M_Memcpy(dest, src+((y&127)<<7), vid.width&127);
dest += (vid.width&127);
}
}
// don't draw the borders when viewwidth is full vid.width.
if (scaledviewwidth == vid.width)
return;
step = 8;
boff = 8;
patch = W_CacheLumpNum(viewborderlump[BRDR_T], PU_CACHE);
for (x = 0; x < scaledviewwidth; x += step)
V_DrawPatch(viewwindowx + x, viewwindowy - boff, 1, patch);
patch = W_CacheLumpNum(viewborderlump[BRDR_B], PU_CACHE);
for (x = 0; x < scaledviewwidth; x += step)
V_DrawPatch(viewwindowx + x, viewwindowy + viewheight, 1, patch);
patch = W_CacheLumpNum(viewborderlump[BRDR_L], PU_CACHE);
for (y = 0; y < viewheight; y += step)
V_DrawPatch(viewwindowx - boff, viewwindowy + y, 1, patch);
patch = W_CacheLumpNum(viewborderlump[BRDR_R],PU_CACHE);
for (y = 0; y < viewheight; y += step)
V_DrawPatch(viewwindowx + scaledviewwidth, viewwindowy + y, 1,
patch);
// Draw beveled corners.
V_DrawPatch(viewwindowx - boff, viewwindowy - boff, 1,
W_CacheLumpNum(viewborderlump[BRDR_TL], PU_CACHE));
V_DrawPatch(viewwindowx + scaledviewwidth, viewwindowy - boff, 1,
W_CacheLumpNum(viewborderlump[BRDR_TR], PU_CACHE));
V_DrawPatch(viewwindowx - boff, viewwindowy + viewheight, 1,
W_CacheLumpNum(viewborderlump[BRDR_BL], PU_CACHE));
V_DrawPatch(viewwindowx + scaledviewwidth, viewwindowy + viewheight, 1,
W_CacheLumpNum(viewborderlump[BRDR_BR], PU_CACHE));
}
/** \brief The R_DrawViewBorder
Draws the border around the view
for different size windows?
*/
void R_DrawViewBorder(void)
{
INT32 top, side, ofs;
if (rendermode == render_none)
return;
#ifdef HWRENDER
if (rendermode != render_soft)
{
HWR_DrawViewBorder(0);
return;
}
else
#endif
#ifdef DEBUG
fprintf(stderr,"RDVB: vidwidth %d vidheight %d scaledviewwidth %d viewheight %d\n",
vid.width, vid.height, scaledviewwidth, viewheight);
#endif
if (scaledviewwidth == vid.width)
return;
top = (vid.height - viewheight)>>1;
side = (vid.width - scaledviewwidth)>>1;
// copy top and one line of left side
R_VideoErase(0, top*vid.width+side);
// copy one line of right side and bottom
ofs = (viewheight+top)*vid.width - side;
R_VideoErase(ofs, top*vid.width + side);
// copy sides using wraparound
ofs = top*vid.width + vid.width-side;
side <<= 1;
// simpler using our VID_Blit routine
VID_BlitLinearScreen(vid.screens[1] + ofs, vid.screens[0] + ofs, side, viewheight - 1,
vid.width, vid.width);
}
#endif
// ==========================================================================
// INCLUDE DRAWING CODE HERE
// ==========================================================================
+24 -35
View File
@@ -25,15 +25,12 @@ extern "C" {
// -------------------------------
// COMMON STUFF FOR 8bpp AND 16bpp
// -------------------------------
extern UINT8 *renderscreen;
extern INT32 linesize;
FUNCINLINE static ATTRINLINE UINT8 *R_Address(INT32 px, INT32 py)
{
return renderscreen + (py + viewwindowy) * linesize + (viewwindowx + px);
return vid.screens[0] + (py + viewwindowy) * vid.width + (viewwindowx + px);
}
typedef struct {
float x, y, z;
} floatv3_t;
@@ -102,6 +99,16 @@ extern floatv3_t *ds_su, *ds_sv, *ds_sz;
extern float focallengthf;
enum columncontext_e
{
COLUMNCONTEXT_DIRECT = 0,
COLUMNCONTEXT_FLUSH,
};
extern enum columncontext_e columncontext;
void R_SetColumnContext(enum columncontext_e _columncontext);
void R_ResetColumnBuffer(void);
typedef void (coldrawfunc_t)(drawcolumndata_t*);
typedef void (spandrawfunc_t)(drawspandata_t*);
@@ -152,29 +159,12 @@ extern spandrawfunc_t *spanfuncs[SPANDRAWFUNC_MAX];
void R_DrawMaskedColumn(drawcolumndata_t* dc, column_t *column);
/// \brief Top border
#define BRDR_T 0
/// \brief Bottom border
#define BRDR_B 1
/// \brief Left border
#define BRDR_L 2
/// \brief Right border
#define BRDR_R 3
/// \brief Topleft border
#define BRDR_TL 4
/// \brief Topright border
#define BRDR_TR 5
/// \brief Bottomleft border
#define BRDR_BL 6
/// \brief Bottomright border
#define BRDR_BR 7
extern lumpnum_t viewborderlump[8];
// ------------------------------------------------
// r_draw.c COMMON ROUTINES FOR BOTH 8bpp and 16bpp
// r_draw.c
// ------------------------------------------------
// Custom player skin translation
#define GTC_CACHE 1
#define GTC_MENUCACHE GTC_CACHE
//@TODO Add a separate caching mechanism for menu colormaps distinct from in-level GTC_CACHE. For now this is still preferable to memory leaks...
@@ -219,19 +209,9 @@ UINT8 *R_GetBlendTable(int style, INT32 alphalevel);
boolean R_BlendLevelVisible(INT32 blendmode, INT32 alphalevel);
// Custom player skin translation
void R_InitViewBuffer(INT32 width, INT32 height);
void R_InitViewBorder(void);
void R_InitViewBuffer(void);
void R_VideoErase(size_t ofs, INT32 count);
// Rendering function.
#if 0
void R_FillBackScreen(void);
// If the view size is not full screen, draws a border around it.
void R_DrawViewBorder(void);
#endif
#define TRANSPARENTPIXEL 247
// -----------------
@@ -250,6 +230,15 @@ void R_DrawTranslatedTranslucentColumn(drawcolumndata_t* dc);
void R_Draw2sMultiPatchColumn(drawcolumndata_t* dc);
void R_Draw2sMultiPatchTranslucentColumn(drawcolumndata_t* dc);
// column drawers which use buffered drawing with flush
void R_DrawColumn_Flush(drawcolumndata_t* dc);
void R_DrawTranslucentColumn_Flush(drawcolumndata_t* dc);
void R_DrawTranslatedColumn_Flush(drawcolumndata_t* dc);
void R_DrawColumnShadowed_Flush(drawcolumndata_t* dc);
void R_DrawTranslatedTranslucentColumn_Flush(drawcolumndata_t* dc);
void R_Draw2sMultiPatchColumn_Flush(drawcolumndata_t* dc);
void R_Draw2sMultiPatchTranslucentColumn_Flush(drawcolumndata_t* dc);
void R_DrawFogColumn(drawcolumndata_t* dc);
// span drawers
+64 -18
View File
@@ -21,6 +21,8 @@
// a has a constant z depth from top to bottom.
//
#include "r_draw_flush.cpp"
enum DrawColumnType
{
DC_BASIC = 0x0000,
@@ -28,10 +30,12 @@ enum DrawColumnType
DC_TRANSMAP = 0x0002,
DC_HOLES = 0x0004,
DC_LIGHTLIST = 0x0008,
DC_DIRECT = 0x0010, // draw our columns directly to screen!
};
template<DrawColumnType Type>
static constexpr UINT8 R_GetColumnTranslated(drawcolumndata_t* dc, UINT8 col, const UINT8 * restrict colormap)
FUNCINLINE static ATTRINLINE constexpr UINT8
R_GetColumnTranslated(const drawcolumndata_t* dc, UINT8 col, const UINT8 * restrict colormap)
{
if constexpr (Type & DrawColumnType::DC_COLORMAP)
{
@@ -41,8 +45,10 @@ static constexpr UINT8 R_GetColumnTranslated(drawcolumndata_t* dc, UINT8 col, co
return colormap[col];
}
// translucency is handled on flush side now!
template<DrawColumnType Type>
static constexpr UINT8 R_GetColumnTranslucent(drawcolumndata_t* dc, UINT8 * restrict dest, UINT8 col, const UINT8 * restrict colormap)
FUNCINLINE static ATTRINLINE constexpr UINT8
R_GetColumnTranslucent(const drawcolumndata_t* dc, UINT8 * restrict dest, UINT8 col, const UINT8 * restrict colormap)
{
col = R_GetColumnTranslated<Type>(dc, col, colormap);
@@ -57,7 +63,8 @@ static constexpr UINT8 R_GetColumnTranslucent(drawcolumndata_t* dc, UINT8 * rest
}
template<DrawColumnType Type>
static constexpr UINT8 R_DrawColumnPixel(drawcolumndata_t* dc, UINT8 * restrict dest, UINT32 bit, const UINT8 * restrict source, const UINT8 * restrict colormap)
FUNCINLINE static ATTRINLINE constexpr UINT8
R_DrawColumnPixel(const drawcolumndata_t* dc, UINT8 * restrict dest, UINT32 bit, const UINT8 * restrict source, const UINT8 * restrict colormap)
{
UINT8 col = source[bit];
@@ -69,6 +76,7 @@ static constexpr UINT8 R_DrawColumnPixel(drawcolumndata_t* dc, UINT8 * restrict
}
}
// if we dont buffer our columns, we need to handle translucency again
return R_GetColumnTranslucent<Type>(dc, dest, col, colormap);
}
@@ -80,8 +88,18 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
{
INT32 count;
// leban 1/17/99:
// removed the + 1 here, adjusted the if test, and added an increment
// later. this helps a compiler pipeline a bit better. the x86
// assembler also does this.
count = dc->yh - dc->yl;
// leban 1/17/99:
// this case isn't executed too often. depending on how many instructions
// there are between here and the second if test below, this case could
// be moved down and might save instructions overall. since there are
// probably different wads that favor one way or the other, i'll leave
// this alone for now.
if (count < 0) // Zero length, column does not exceed a pixel.
{
return;
@@ -150,6 +168,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
}
R_DrawColumnTemplate<NewType>(&dc_copy);
if (solid)
{
dc_copy.yl = bheight;
@@ -183,19 +202,37 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
// killough 2/1/98: more performance tuning
intptr_t frac;
// Looks familiar.
const intptr_t fracstep = dc->iscale;
const intptr_t heightmask = dc->sourcelength-1;
const intptr_t heightmask = dc->sourcelength-1; // CPhipps - specify type
constexpr INT32 npow2min = -1;
const INT32 npow2max = dc->sourcelength;
const INT32 stride = vid.width;
const UINT8 * restrict source = dc->source;
const lighttable_t * restrict colormap = dc->colormap;
// Framebuffer destination address.
UINT8 * restrict dest = R_Address(dc->x, dc->yl);
// SoM: MAGIC
UINT8 * restrict dest;
count++;
if constexpr (Type & DrawColumnType::DC_DIRECT)
dest = R_Address(dc->x, dc->yl);
else if constexpr ((Type & (DrawColumnType::DC_COLORMAP | DrawColumnType::DC_TRANSMAP))
== (DrawColumnType::DC_COLORMAP | DrawColumnType::DC_TRANSMAP))
dest = R_GetBufferColormapTrans(dc);
else if constexpr (Type & DrawColumnType::DC_TRANSMAP)
dest = R_GetBufferTrans(dc);
else if constexpr (Type & DrawColumnType::DC_COLORMAP)
dest = R_GetBufferColormap(dc);
else
dest = R_GetBufferOpaque(dc);
INT32 stride = 8; //SoM: Oh, Oh it's MAGIC! You know...
if constexpr (Type & DrawColumnType::DC_DIRECT)
stride = vid.width;
count++; // killough 1/99: minor tuning
// Determine scaling, which is the only mapping to be done.
frac = (dc->texturemid + FixedMul((dc->yl << FRACBITS) - centeryfrac, fracstep));
@@ -205,15 +242,16 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
case 255:
case 127:
{
while(count--)
while (count--)
{
*dest = R_DrawColumnPixel<Type>(dc, dest, (frac>>FRACBITS) & heightmask, source, colormap);
dest += stride;
frac += fracstep;
}
}
break;
case -1:
case npow2min:
{
if (frac < 0)
// adjust in case we underread
@@ -222,7 +260,8 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
// texture has no height, so just go
while (--count >= 0)
{
*dest = R_DrawColumnPixel<Type>(dc, dest, frac>>FRACBITS, source, colormap);
*dest = R_DrawColumnPixel<Type>(dc, dest, (frac>>FRACBITS), source, colormap);
dest += stride;
frac += fracstep;
}
@@ -235,10 +274,12 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
while ((count -= 2) >= 0) // texture height is a power of 2 -- killough
{
*dest = R_DrawColumnPixel<Type>(dc, dest, (frac>>FRACBITS) & heightmask, source, colormap);
dest += stride;
frac += fracstep;
*dest = R_DrawColumnPixel<Type>(dc, dest, (frac>>FRACBITS) & heightmask, source, colormap);
dest += stride;
frac += fracstep;
}
@@ -271,7 +312,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
{
// Re-map color indices from wall texture column
// using a lighting/special effects LUT.
// heightmask is the Tutti-Frutti fix
// heightmask is the Tutti-Frutti fix -- killough
// -1 is the lower clamp bound because column posts have a "safe" byte before the real data
// and a few bytes after as well
@@ -311,13 +352,18 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
R_DrawColumnTemplate<opt>(dc); \
}
DEFINE_COLUMN_FUNC(R_DrawColumn, DC_BASIC)
DEFINE_COLUMN_FUNC(R_DrawTranslucentColumn, DC_TRANSMAP)
DEFINE_COLUMN_FUNC(R_DrawTranslatedColumn, DC_COLORMAP)
DEFINE_COLUMN_FUNC(R_DrawColumnShadowed, DC_LIGHTLIST)
DEFINE_COLUMN_FUNC(R_DrawTranslatedTranslucentColumn, DC_COLORMAP|DC_TRANSMAP)
DEFINE_COLUMN_FUNC(R_Draw2sMultiPatchColumn, DC_HOLES)
DEFINE_COLUMN_FUNC(R_Draw2sMultiPatchTranslucentColumn, DC_HOLES|DC_TRANSMAP)
#define DEFINE_COLUMN_COMBO(name, flags) \
DEFINE_COLUMN_FUNC(name, flags|DC_DIRECT) \
DEFINE_COLUMN_FUNC(name ## _Flush, flags)
DEFINE_COLUMN_COMBO(R_DrawColumn, DC_BASIC)
DEFINE_COLUMN_COMBO(R_DrawTranslucentColumn, DC_TRANSMAP)
DEFINE_COLUMN_COMBO(R_DrawTranslatedColumn, DC_COLORMAP)
DEFINE_COLUMN_COMBO(R_DrawColumnShadowed, DC_LIGHTLIST)
DEFINE_COLUMN_COMBO(R_DrawTranslatedTranslucentColumn, DC_COLORMAP|DC_TRANSMAP)
DEFINE_COLUMN_COMBO(R_Draw2sMultiPatchColumn, DC_HOLES)
DEFINE_COLUMN_COMBO(R_Draw2sMultiPatchTranslucentColumn, DC_HOLES|DC_TRANSMAP)
/** \brief The R_DrawFogColumn function
Fog wall.
+269
View File
@@ -0,0 +1,269 @@
// SONIC ROBO BLAST 2 KART
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
// Copyright (C) 2000 by DooM Legacy Team.
// Copyright (C) 1996 by id Software, Inc.
// Copyright (C) 1999 by Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
// Copyright (C) 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
// Copyright (C) Copyright 2005, 2006 by Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
// Copyright (C) 2013 by James Haley, Stephen McGranahan, et al.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file r_draw_flush.cpp
/// \brief Optimized quad column buffer code. By SoM.
/// \note no includes because this is included as part of r_draw.cpp
template<ColumnFlushType Type>
FUNCINLINE static ATTRINLINE constexpr UINT8
R_GetFlushPixelTranslated(const drawcolumndata_temp_t *t_dc, UINT8 col)
{
if constexpr (Type & (ColumnFlushType::FLUSH_COLORMAP | ColumnFlushType::FLUSH_COLORMAP_TRANS))
{
col = t_dc->translation[col];
}
return col;
}
template<ColumnFlushType Type>
FUNCINLINE static ATTRINLINE constexpr UINT8
R_GetFlushPixelTranslucent(const drawcolumndata_temp_t *t_dc, UINT8 * restrict dest, UINT8 col)
{
col = R_GetFlushPixelTranslated<Type>(t_dc, col);
if constexpr (Type & (ColumnFlushType::FLUSH_TRANS | ColumnFlushType::FLUSH_COLORMAP_TRANS))
{
// haleyjd 09/11/04: use temptranmap here
return *(t_dc->transmap + (col << 8) + (*dest));
}
else
{
return col;
}
}
template<ColumnFlushType Type>
FUNCINLINE static ATTRINLINE constexpr UINT8
R_DrawFlushPixel(const drawcolumndata_temp_t *t_dc, UINT8 * restrict dest, const UINT8 * restrict source)
{
UINT8 col = *source;
return R_GetFlushPixelTranslucent<Type>(t_dc, dest, col);
}
//
// R_FlushWhole
//
// Flushes the entire columns in the buffer, one at a time.
// This is used when a quad flush isn't possible.
//
template<ColumnFlushType Type>
static void R_FlushWhole(void)
{
UINT8 * restrict source;
UINT8 * restrict dest;
INT32 count, yl;
const INT32 stride = vid.width;
drawcolumndata_temp_t *t_dc = &temp_dc;
UINT8 *restrict buf = t_dc->buf;
while (--t_dc->x >= 0)
{
yl = t_dc->yl[t_dc->x];
source = &buf[t_dc->x + (yl << 3)];
dest = R_Address(t_dc->startx + t_dc->x, yl);
count = t_dc->yh[t_dc->x] - yl + 1;
while (--count >= 0)
{
*dest = R_DrawFlushPixel<Type>(t_dc, dest, source);
source += 8;
dest += stride;
}
}
}
//
// R_FlushHT
//
// Flushes the head and tail of columns in the buffer in
// preparation for a quad flush.
//
template<ColumnFlushType Type>
static void R_FlushHT(void)
{
UINT8 * restrict source;
UINT8 * restrict dest;
INT32 count, colnum = 0;
INT32 yl, yh;
const INT32 stride = vid.width;
const drawcolumndata_temp_t *t_dc = &temp_dc;
UINT8 *restrict buf = t_dc->buf;
while (colnum < 8)
{
yl = t_dc->yl[colnum];
yh = t_dc->yh[colnum];
// flush column head
if (yl < t_dc->commontop)
{
source = &buf[colnum + (yl << 3)];
dest = R_Address(t_dc->startx + colnum, yl);
count = t_dc->commontop - yl;
while (--count >= 0)
{
*dest = R_DrawFlushPixel<Type>(t_dc, dest, source);
source += 8;
dest += stride;
}
}
// flush column tail
if (yh > t_dc->commonbot)
{
source = &buf[colnum + ((t_dc->commonbot + 1) << 3)];
dest = R_Address(t_dc->startx + colnum, t_dc->commonbot + 1);
count = yh - t_dc->commonbot;
while (--count >= 0)
{
*dest = R_DrawFlushPixel<Type>(t_dc, dest, source);
source += 8;
dest += stride;
}
}
++colnum;
}
}
// Begin: Quad column flushing functions.
template<ColumnFlushType Type>
static void R_FlushQuad(void)
{
const INT32 stride = vid.width;
const drawcolumndata_temp_t *t_dc = &temp_dc;
INT32 count = t_dc->commonbot - t_dc->commontop + 1;
const UINT8 *restrict buf = t_dc->buf;
const UINT8 * restrict source = buf + (t_dc->commontop << 3);
UINT8 * restrict dest = R_Address(t_dc->startx, t_dc->commontop);
if constexpr (Type & ColumnFlushType::FLUSH_OPAQUE)
{
#if __SIZEOF_POINTER__ >= 8 // does not make much sense on 32bit targets
// 8 byte aligned copy -- make sure our dest ptr, source ptr AND stride are a multiple of 8!
if ((((uintptr_t)dest | (uintptr_t)source | stride) & 7) == 0)
{
const INT64 *source64 = reinterpret_cast<const INT64 *>(source);
INT64 *dest64 = reinterpret_cast<INT64 *>(dest);
const INT32 deststep = stride / 8;
while (--count >= 0)
{
*dest64 = *source64++;
dest64 += deststep;
}
}
else
#endif
{
while (--count >= 0)
{
dest[0] = source[0];
dest[1] = source[1];
dest[2] = source[2];
dest[3] = source[3];
dest[4] = source[4];
dest[5] = source[5];
dest[6] = source[6];
dest[7] = source[7];
source += 8;
dest += stride;
}
}
}
else
{
while (--count >= 0)
{
dest[0] = R_DrawFlushPixel<Type>(t_dc, &dest[0], &source[0]);
dest[1] = R_DrawFlushPixel<Type>(t_dc, &dest[1], &source[1]);
dest[2] = R_DrawFlushPixel<Type>(t_dc, &dest[2], &source[2]);
dest[3] = R_DrawFlushPixel<Type>(t_dc, &dest[3], &source[3]);
dest[4] = R_DrawFlushPixel<Type>(t_dc, &dest[4], &source[4]);
dest[5] = R_DrawFlushPixel<Type>(t_dc, &dest[5], &source[5]);
dest[6] = R_DrawFlushPixel<Type>(t_dc, &dest[6], &source[6]);
dest[7] = R_DrawFlushPixel<Type>(t_dc, &dest[7], &source[7]);
source += 8;
dest += stride;
}
}
}
// haleyjd 09/12/04: split up R_GetBuffer into various different
// functions to minimize the number of branches and take advantage
// of as much precalculated information as possible.
template<ColumnFlushType Type>
static UINT8 *R_GetBuffer(drawcolumndata_t *dc)
{
drawcolumndata_temp_t *t_dc = &temp_dc;
// haleyjd: reordered predicates
if (t_dc->x == 8 ||
(t_dc->x && (t_dc->type != Type || t_dc->x + t_dc->startx != dc->x)))
R_FlushColumns();
if (!t_dc->x)
{
++t_dc->x;
t_dc->startx = dc->x;
t_dc->yl[0] = t_dc->commontop = dc->yl;
t_dc->yh[0] = t_dc->commonbot = dc->yh;
t_dc->type = Type;
if constexpr (Type & (ColumnFlushType::FLUSH_TRANS | ColumnFlushType::FLUSH_COLORMAP_TRANS))
{
t_dc->transmap = dc->transmap;
}
if constexpr (Type & (ColumnFlushType::FLUSH_COLORMAP | ColumnFlushType::FLUSH_COLORMAP_TRANS))
{
t_dc->translation = dc->translation;
}
R_FlushWholeColumns = R_FlushWhole<Type>;
R_FlushHTColumns = R_FlushHT<Type>;
R_FlushQuadColumn = R_FlushQuad<Type>;
return &t_dc->buf[dc->yl << 3];
}
t_dc->yl[t_dc->x] = dc->yl;
t_dc->yh[t_dc->x] = dc->yh;
if (dc->yl > t_dc->commontop)
t_dc->commontop = dc->yl;
if (dc->yh < t_dc->commonbot)
t_dc->commonbot = dc->yh;
return &t_dc->buf[(dc->yl << 3) + t_dc->x++];
}
#define DEFINE_GETBUF_FUNC(name, flags) \
FUNCINLINE static ATTRINLINE UINT8 *name(drawcolumndata_t *dc) \
{ \
constexpr ColumnFlushType opt = static_cast<ColumnFlushType>(flags); \
return R_GetBuffer<opt>(dc); \
}
DEFINE_GETBUF_FUNC(R_GetBufferOpaque, FLUSH_OPAQUE)
DEFINE_GETBUF_FUNC(R_GetBufferTrans, FLUSH_TRANS)
DEFINE_GETBUF_FUNC(R_GetBufferColormap, FLUSH_COLORMAP)
DEFINE_GETBUF_FUNC(R_GetBufferColormapTrans, FLUSH_COLORMAP_TRANS)
+87 -84
View File
@@ -25,6 +25,9 @@
#define local_for_thread static
#endif
#include <vector>
#include <algorithm>
// ==========================================================================
// SPANS
// ==========================================================================
@@ -47,7 +50,8 @@ enum DrawSpanType
};
template<DrawSpanType Type>
static constexpr UINT8 R_GetSpanTranslated(drawspandata_t* ds, UINT8 col)
FUNCINLINE static ATTRINLINE constexpr UINT8
R_GetSpanTranslated(const drawspandata_t* ds, UINT8 col)
{
if constexpr (Type & DrawSpanType::DS_COLORMAP)
{
@@ -60,7 +64,8 @@ static constexpr UINT8 R_GetSpanTranslated(drawspandata_t* ds, UINT8 col)
}
template<DrawSpanType Type>
static constexpr UINT8 R_GetSpanTranslucent(drawspandata_t* ds, UINT8 *dsrc, const UINT8 *colormap, UINT8 col)
FUNCINLINE static ATTRINLINE constexpr UINT8
R_GetSpanTranslucent(const drawspandata_t* ds, UINT8 *dsrc, const UINT8 *colormap, UINT8 col)
{
col = colormap[R_GetSpanTranslated<Type>(ds, col)];
@@ -75,7 +80,8 @@ static constexpr UINT8 R_GetSpanTranslucent(drawspandata_t* ds, UINT8 *dsrc, con
}
template<DrawSpanType Type>
static constexpr UINT8 R_DrawSpanPixel(drawspandata_t* ds, UINT8 *dsrc, const UINT8 *colormap, UINT32 bit, const UINT8 *source)
FUNCINLINE static ATTRINLINE constexpr UINT8
R_DrawSpanPixel(const drawspandata_t* ds, UINT8 *dsrc, const UINT8 *colormap, UINT32 bit, const UINT8 *source)
{
UINT8 col = source[bit];
@@ -154,14 +160,18 @@ static void R_DrawSpanTemplate(drawspandata_t* ds)
{
bit = ((yposition >> ds->nflatyshift) & ds->nflatmask) | (xposition >> ds->nflatxshift);
dest[i] = R_DrawSpanPixel<Type>(ds, &dsrc[i], colormap, bit, source);
if constexpr (Type & DS_RIPPLE)
dest[i] = R_DrawSpanPixel<Type>(ds, &dsrc[i], colormap, bit, source);
else
dest[i] = R_DrawSpanPixel<Type>(ds, &dest[i], colormap, bit, source);
xposition += xstep;
yposition += ystep;
}
dest += 8;
dsrc += 8;
if constexpr (Type & DS_RIPPLE)
dsrc += 8;
count -= 8;
}
@@ -170,10 +180,14 @@ static void R_DrawSpanTemplate(drawspandata_t* ds)
{
bit = ((yposition >> ds->nflatyshift) & ds->nflatmask) | (xposition >> ds->nflatxshift);
*dest = R_DrawSpanPixel<Type>(ds, dsrc, colormap, bit, source);
if constexpr (Type & DS_RIPPLE)
*dest = R_DrawSpanPixel<Type>(ds, dsrc, colormap, bit, source);
else
*dest = R_DrawSpanPixel<Type>(ds, dest, colormap, bit, source);
dest++;
dsrc++;
if constexpr (Type & DS_RIPPLE)
dsrc++;
xposition += xstep;
yposition += ystep;
@@ -182,35 +196,43 @@ static void R_DrawSpanTemplate(drawspandata_t* ds)
// R_CalcTiltedLighting
// Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly.
static void R_CalcTiltedLighting(INT32 *lightbuffer, INT32 x1, INT32 x2, fixed_t start, fixed_t end)
static void R_CalcTiltedLighting(std::vector<INT32>& lightbuffer, INT32 x1, INT32 x2, fixed_t start, fixed_t end)
{
// ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version
// of this function. Here's my own.
INT32 i, left = x1, right = x2;
INT32 i;
const fixed_t step = (end-start)/(x2 - x1 + 1);
// I wanna do some optimizing by checking for out-of-range segments on either side to fill in all at once,
// but I'm too bad at coding to not crash the game trying to do that. I guess this is fast enough for now...
for (i = left; i <= right; i++)
for (i = x1; i <= x2; i++)
{
lightbuffer[i] = (start += step) >> FRACBITS;
if (lightbuffer[i] < 0)
{
lightbuffer[i] = 0;
}
else if (lightbuffer[i] >= MAXLIGHTSCALE)
{
lightbuffer[i] = MAXLIGHTSCALE-1;
}
const fixed_t light = start >> FRACBITS;
lightbuffer[i] = CLAMP(light, 0, MAXLIGHTSCALE - 1);
start += step;
}
}
static void R_GetTiltedLighting(std::vector<INT32>& tiltlighting, const drawspandata_t* ds, const float iz, const INT32 width, const INT32 stride)
{
const float planelightfloat = PLANELIGHTFLOAT;
const fixed_t lightstart = FloatToFixed(iz * planelightfloat);
const fixed_t lightend = FloatToFixed((iz + ds->szp.x * width) * planelightfloat);
if (tiltlighting.size() != (size_t)viewwidth)
{
tiltlighting.resize(viewwidth);
}
R_CalcTiltedLighting(tiltlighting, ds->x1, ds->x2, lightstart, lightend);
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", FixedToFloat(lightstart), FixedToFloat(lightend), focallengthf);
}
template<DrawSpanType Type>
static void R_DrawTiltedSpanTemplate(drawspandata_t* ds)
{
int width = ds->x2 - ds->x1;
INT32 width = ds->x2 - ds->x1;
float iz, uz, vz;
UINT32 u, v;
int i;
@@ -223,41 +245,27 @@ static void R_DrawTiltedSpanTemplate(drawspandata_t* ds)
float endz, endu, endv;
UINT32 stepu, stepv;
UINT32 bit;
local_for_thread INT32 *tiltlighting = NULL;
local_for_thread INT32 oldviewwidth = 0;
// dont realloc every frame pls thx
if (tiltlighting == NULL || oldviewwidth != viewwidth)
{
tiltlighting = static_cast<INT32*>(realloc(tiltlighting, sizeof(*tiltlighting) * viewwidth));
oldviewwidth = viewwidth;
}
INT32 x1 = ds->x1;
const INT32 nflatxshift = ds->nflatxshift;
const INT32 nflatyshift = ds->nflatyshift;
const INT32 nflatmask = ds->nflatmask;
const INT32 stride = vid.width;
local_for_thread std::vector<INT32> tiltlighting;
iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds->szp.x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(tiltlighting, ds->x1, ds->x2, FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
uz = ds->sup.z + ds->sup.y*(centery-ds->y) + ds->sup.x*(ds->x1-centerx);
vz = ds->svp.z + ds->svp.y*(centery-ds->y) + ds->svp.x*(ds->x1-centerx);
const UINT8 *source = ds->source;
const UINT8 *colormap = ds->colormap;
// Lighting is simple. It's just linear interpolation from start to end
R_GetTiltedLighting(tiltlighting, ds, iz, width, stride);
const UINT8 * restrict source = ds->source;
const UINT8 * restrict colormap = ds->colormap;
const ptrdiff_t colormap_diff = (colormap - colormaps);
const INT32 * restrict tiltlight = tiltlighting.data();
lighttable_t * const * restrict planezlight = ds->planezlight;
if constexpr (Type & DS_RIPPLE)
{
@@ -296,7 +304,6 @@ static void R_DrawTiltedSpanTemplate(drawspandata_t* ds)
izstep = ds->szp.x * SPANSIZE;
uzstep = ds->sup.x * SPANSIZE;
vzstep = ds->svp.x * SPANSIZE;
//x1 = 0;
width++;
while (width >= SPANSIZE)
@@ -313,18 +320,22 @@ static void R_DrawTiltedSpanTemplate(drawspandata_t* ds)
u = (INT64)(startu);
v = (INT64)(startv);
x1 = ds->x1;
const INT32 x1 = ds->x1;
for (i = 0; i < SPANSIZE; i++)
{
bit = (((v + stepv * i) >> nflatyshift) & nflatmask) | ((u + stepu * i) >> nflatxshift);
colormap = ds->planezlight[tiltlighting[x1 + i]] + (ds->colormap - colormaps);
dest[i] = R_DrawSpanPixel<Type>(ds, &dsrc[i], colormap, bit, source);
colormap = planezlight[tiltlight[x1 + i]] + colormap_diff;
if constexpr (Type & DS_RIPPLE)
dest[i] = R_DrawSpanPixel<Type>(ds, &dsrc[i], colormap, bit, source);
else
dest[i] = R_DrawSpanPixel<Type>(ds, &dest[i], colormap, bit, source);
}
ds->x1 += SPANSIZE;
dest += SPANSIZE;
dsrc += SPANSIZE;
if constexpr (Type & DS_RIPPLE)
dsrc += SPANSIZE;
startu = endu;
startv = endv;
width -= SPANSIZE;
@@ -337,8 +348,11 @@ static void R_DrawTiltedSpanTemplate(drawspandata_t* ds)
u = (INT64)(startu);
v = (INT64)(startv);
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
colormap = ds->planezlight[tiltlighting[ds->x1]] + (ds->colormap - colormaps);
*dest = R_DrawSpanPixel<Type>(ds, dsrc, colormap, bit, source);
colormap = planezlight[tiltlight[ds->x1]] + colormap_diff;
if constexpr (Type & DS_RIPPLE)
*dest = R_DrawSpanPixel<Type>(ds, dsrc, colormap, bit, source);
else
*dest = R_DrawSpanPixel<Type>(ds, dest, colormap, bit, source);
ds->x1++;
}
else
@@ -360,11 +374,15 @@ static void R_DrawTiltedSpanTemplate(drawspandata_t* ds)
for (; width != 0; width--)
{
bit = ((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift);
colormap = ds->planezlight[tiltlighting[ds->x1]] + (ds->colormap - colormaps);
*dest = R_DrawSpanPixel<Type>(ds, dsrc, colormap, bit, source);
colormap = planezlight[tiltlight[ds->x1]] + colormap_diff;
if constexpr (Type & DS_RIPPLE)
*dest = R_DrawSpanPixel<Type>(ds, dsrc, colormap, bit, source);
else
*dest = R_DrawSpanPixel<Type>(ds, dest, colormap, bit, source);
dest++;
if constexpr (Type & DS_RIPPLE)
dsrc++;
ds->x1++;
dsrc++;
u += stepu;
v += stepv;
}
@@ -395,11 +413,11 @@ DEFINE_SPAN_COMBO(R_DrawTranslucentWaterSpan, DS_TRANSMAP|DS_RIPPLE)
*/
void R_DrawFogSpan(drawspandata_t* ds)
{
intptr_t count = ds->x2 - ds->x1 + 1;
const UINT8 * restrict colormap = ds->colormap;
UINT8 * restrict dest = R_Address(ds->x1, ds->y);
intptr_t count = ds->x2 - ds->x1 + 1;
while (count >= 4)
{
dest[0] = colormap[dest[0]];
@@ -407,7 +425,7 @@ void R_DrawFogSpan(drawspandata_t* ds)
dest[2] = colormap[dest[2]];
dest[3] = colormap[dest[3]];
dest += 4;
dest += 4;
count -= 4;
}
@@ -420,38 +438,23 @@ void R_DrawFogSpan(drawspandata_t* ds)
void R_DrawFogSpan_Tilted(drawspandata_t* ds)
{
int width = ds->x2 - ds->x1;
float iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx);
UINT8 * restrict dest;
local_for_thread INT32 *tiltlighting = NULL;
local_for_thread INT32 oldviewwidth = 0;
// dont realloc every frame pls thx
if (tiltlighting == NULL || oldviewwidth != viewwidth)
{
tiltlighting = static_cast<INT32*>(realloc(tiltlighting, sizeof(*tiltlighting) * viewwidth));
oldviewwidth = viewwidth;
}
dest = R_Address(ds->x1, ds->y);
INT32 width = ds->x2 - ds->x1;
const INT32 stride = vid.width;
const float iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx);
UINT8 * restrict dest = R_Address(ds->x1, ds->y);
const ptrdiff_t colormap_diff = (ds->colormap - colormaps);
local_for_thread std::vector<INT32> tiltlighting;
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
R_GetTiltedLighting(tiltlighting, ds, iz, width, stride);
lightend = (iz + ds->szp.x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(tiltlighting, ds->x1, ds->x2, FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
const INT32 * restrict tiltlight = tiltlighting.data();
lighttable_t * const * restrict planezlight = ds->planezlight;
do
{
UINT8 *colormap = ds->planezlight[tiltlighting[ds->x1++]] + (ds->colormap - colormaps);
UINT8 *colormap = planezlight[tiltlight[ds->x1++]] + colormap_diff;
*dest = colormap[*dest];
dest++;
}
+1 -1
View File
@@ -172,7 +172,7 @@ static vector3_t *R_LerpVector3(const vector3_t *from, const vector3_t *to, fixe
// recalc necessary stuff for mouseaiming
// slopes are already calculated for the full possible view (which is 4*viewheight).
// 18/08/18: (No it's actually 16*viewheight, thanks Lactozilla for finding this out)
static void R_SetupFreelook(void)
void R_SetupFreelook(void)
{
// clip it in the case we are looking a hardware 90 degrees full aiming
// (lmps, network and use F12...)
+1
View File
@@ -151,6 +151,7 @@ typedef struct levelinterpolator_s {
};
} levelinterpolator_t;
void R_SetupFreelook(void);
// Interpolates the current view variables (r_state.h) against the selected view context in R_SetViewContext
void R_InterpolateView(fixed_t frac, boolean forceinvalid);
// Special function just for software
+18 -7
View File
@@ -63,7 +63,7 @@ size_t loopcount;
fixed_t viewx, viewy, viewz;
angle_t viewangle, aimingangle, viewroll;
UINT8 viewssnum;
UINT8 viewssnum = 0;
fixed_t viewcos, viewsin;
boolean skyVisible;
boolean skyVisiblePerPlayer[MAXSPLITSCREENPLAYERS]; // saved values of skyVisible for each splitscreen player
@@ -88,7 +88,7 @@ INT32 viewangletox[FINEANGLES/2];
// The xtoviewangleangle[] table maps a screen pixel
// to the lowest viewangle that maps back to x ranges
// from clipangle to -clipangle.
angle_t *xtoviewangle;
angle_t *xtoviewangle = NULL;
lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
lighttable_t *scalelightfixed[MAXLIGHTSCALE];
@@ -253,6 +253,7 @@ void SplitScreen_OnChange(void)
if (playeringame[i] && i != consoleplayer)
{
UINT8 j;
for (j = 1; j < MAXSPLITSCREENPLAYERS; j++)
{
if (displayplayers[j] == consoleplayer)
@@ -268,6 +269,7 @@ void SplitScreen_OnChange(void)
}
}
}
static void Fov_OnChange(void)
{
R_SetViewSize();
@@ -943,9 +945,10 @@ void R_ExecuteSetViewSize(void)
memset(scalelight, 0xFF, sizeof(scalelight));
// Calculate the light levels to use for each level/scale combination.
for (i = 0; i< LIGHTLEVELS; i++)
for (i = 0; i < LIGHTLEVELS; i++)
{
startmapl = ((LIGHTLEVELS - 1 - i)*2)*NUMCOLORMAPS/LIGHTLEVELS;
for (j = 0; j < MAXLIGHTSCALE; j++)
{
level = startmapl - j*vid.width/(viewwidth)/DISTMAP;
@@ -960,6 +963,8 @@ void R_ExecuteSetViewSize(void)
}
}
R_SetupFreelook();
am_recalc = true;
}
@@ -1003,7 +1008,7 @@ static void R_InitViewMapping(void)
static void R_SetupViewBuffers(void)
{
R_CalcFov(cv_fov.value);
R_InitViewBuffer(viewwidth, viewheight);
R_InitViewBuffer();
R_InitViewMapping();
}
@@ -1023,8 +1028,6 @@ void R_Init(void)
//I_OutputMsg("\nR_InitData");
R_InitData();
//I_OutputMsg("\nR_InitViewBorder");
R_InitViewBorder();
R_SetViewSize(); // setsizeneeded is set true
// this is now done by SCR_Recalc() at the first mode set
@@ -1400,12 +1403,16 @@ void R_RenderPlayerView(player_t *player)
R_ClearClipSegs();
R_ClearDrawSegs();
R_ClearSegTables();
R_ClearPlanes();
R_ClearSprites();
R_SetColumnContext(COLUMNCONTEXT_FLUSH);
R_RenderViewpoint(&masks[nummasks - 1], false);
R_ClipSprites(drawsegs, NULL);
R_ResetColumnBuffer();
R_SetColumnContext(COLUMNCONTEXT_DIRECT);
R_DrawSkyPlanes(); // draw the fucker again to prevent some artifacts
R_DrawPlanes();
R_DrawMasked(masks, nummasks);
@@ -1434,11 +1441,13 @@ void R_RenderPlayerView(player_t *player)
R_ClearClipSegs();
}
R_ClearDrawSegs();
R_ClearSegTables();
R_ClearSprites();
// check for new console commands.
NetUpdate();
R_SetColumnContext(COLUMNCONTEXT_FLUSH);
ps_numbspcalls.value.i = ps_numpolyobjects.value.i = ps_numdrawnodes.value.i = 0;
PS_START_TIMING(ps_bsptime);
R_RenderViewpoint(&masks[nummasks - 1], true);
@@ -1446,6 +1455,7 @@ void R_RenderPlayerView(player_t *player)
PS_START_TIMING(ps_sw_spritecliptime);
R_ClipSprites(drawsegs, NULL);
PS_STOP_TIMING(ps_sw_spritecliptime);
R_ResetColumnBuffer();
ps_numsprites.value.i = numvisiblesprites;
@@ -1482,12 +1492,14 @@ void R_RenderPlayerView(player_t *player)
R_RenderViewpoint(&masks[nummasks - 1], true);
R_ClipSprites(ds_p - (masks[nummasks - 1].drawsegs[1] - masks[nummasks - 1].drawsegs[0]), portal);
R_ResetColumnBuffer();
Portal_Remove(portal);
}
}
PS_STOP_TIMING(ps_sw_portaltime);
R_SetColumnContext(COLUMNCONTEXT_DIRECT);
PS_START_TIMING(ps_sw_planetime);
if (!skybox)
R_DrawSkyPlanes();
@@ -1498,7 +1510,6 @@ void R_RenderPlayerView(player_t *player)
PS_START_TIMING(ps_sw_maskedtime);
R_DrawMasked(masks, nummasks);
PS_STOP_TIMING(ps_sw_maskedtime);
free(masks);
// Check for new console commands.
+1 -1
View File
@@ -97,7 +97,7 @@ FUNCINLINE static ATTRINLINE PUREFUNC INT32 R_PointOnSide(fixed_t x, fixed_t y,
// Try to quickly decide by looking at sign bits.
// also use a mask to avoid branch prediction
INT32 mask = (node->dy ^ node->dx ^ x ^ y) >> 31;
INT32 mask = (((node->dy ^ node->dx ^ x ^ y) < 0) ? -1 : 0);
return (mask & ((node->dy ^ x) < 0)) | // (left is negative)
(~mask & (FixedMul(y, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, x)));
}
+47 -25
View File
@@ -19,6 +19,7 @@
#include "r_skins.h"
#include "z_zone.h"
#include "w_wad.h"
#include <vector>
#ifdef HWRENDER
#include "hardware/hw_glob.h"
@@ -37,7 +38,7 @@ static void R_ParseSpriteInfoFrame(spriteinfo_t *info)
UINT8 frameFrame = 0xFF;
INT16 frameXPivot = 0;
INT16 frameYPivot = 0;
rotaxis_t frameRotAxis = 0;
rotaxis_t frameRotAxis = ROTAXIS_X;
// Sprite identifier
sprinfoToken = M_GetToken(NULL);
@@ -158,14 +159,14 @@ static void R_ParseSpriteInfo(boolean spr2)
I_Error("Error parsing SPRTINFO lump: Unknown sprite name \"%s\"", newSpriteName);
if (!memcmp(newSpriteName,sprnames[i],4))
{
sprnum = i;
sprnum = static_cast<spritenum_t>(i);
break;
}
}
}
// allocate a spriteinfo
info = Z_Calloc(sizeof(spriteinfo_t), PU_STATIC, NULL);
info = static_cast<spriteinfo_t*>(Z_Calloc(sizeof(spriteinfo_t), PU_STATIC, NULL));
info->available = true;
// Left Curly Brace
@@ -329,7 +330,7 @@ void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps)
patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest)
{
patch_t *patch = (dest == NULL) ? Z_Calloc(sizeof(patch_t), PU_PATCH, NULL) : (patch_t *)(dest);
patch_t *patch = static_cast<patch_t*>((dest == NULL) ? Z_Calloc(sizeof(patch_t), PU_PATCH, NULL) : dest);
if (source)
{
@@ -341,7 +342,7 @@ patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest)
patch->height = SHORT(source->height);
patch->leftoffset = SHORT(source->leftoffset);
patch->topoffset = SHORT(source->topoffset);
patch->columnofs = Z_Calloc(size, PU_PATCH_DATA, NULL);
patch->columnofs = static_cast<INT32*>(Z_Calloc(size, PU_PATCH_DATA, NULL));
for (col = 0; col < source->width; col++)
{
@@ -357,7 +358,7 @@ patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest)
if (colsize <= 0)
I_Error("Patch_Create: no column data!");
patch->columns = Z_Calloc(colsize, PU_PATCH_DATA, NULL);
patch->columns = static_cast<UINT8*>(Z_Calloc(colsize, PU_PATCH_DATA, NULL));
M_Memcpy(patch->columns, ((UINT8 *)source + LONG(source->columnofs[0])), colsize);
}
@@ -429,8 +430,8 @@ void *Patch_AllocateHardwarePatch(patch_t *patch)
{
if (!patch->hardware)
{
GLPatch_t *glPatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, &patch->hardware);
glPatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, &glPatch->mipmap);
GLPatch_t *glPatch = static_cast<GLPatch_t*>(Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, &patch->hardware));
glPatch->mipmap = static_cast<GLMipmap_t*>(Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, &glPatch->mipmap));
}
return (void *)(patch->hardware);
}
@@ -448,7 +449,8 @@ void *Patch_CreateGL(patch_t *patch)
}
#endif // HWRENDER
static UINT8 *imgbuf = NULL;
// 1 MB should be enough for most cases
static std::vector<UINT8> imgbuf(1024 * 1024);
//
// R_MaskedFlatToPatch
@@ -458,17 +460,27 @@ static UINT8 *imgbuf = NULL;
void *R_PixelsToPatch(UINT8 *raw, INT16 width, INT16 height, INT16 leftoffset, INT16 topoffset, size_t *destsize)
{
INT16 x, y;
UINT8 *img;
UINT8 *img, *imgptr;
UINT8 *colpointers, *startofspan;
size_t size = 0;
if (!raw)
return NULL;
if (!imgbuf)
imgbuf = Z_Malloc(1<<26, PU_STATIC, NULL);
// Allocate a staging buffer with the maximum size needed for a patch of the same size as the input.
UINT8 *imgptr = imgbuf;
// round up to nearest multiple of 254-pixel posts, plus 1 more 254-pixel post for paranoia reasons
size_t maxcolumnsize = (2 + (height - 1) / 256) * 256;
// the patch header, and width columns of the max column size
size_t maxoutsize = maxcolumnsize * width + (8 + 4 * width);
// so, a 512x512 flat should maximally need 393,760 (384.53 KiB) bytes.
// quite a bit smaller than 64 megabytes, and much less annoying to the windows debug allocator!
while (imgbuf.size() < maxoutsize)
{
imgbuf.resize(imgbuf.size() * 2);
}
imgptr = imgbuf.data();
// Write image size and offset
WRITEINT16(imgptr, width);
@@ -488,7 +500,7 @@ void *R_PixelsToPatch(UINT8 *raw, INT16 width, INT16 height, INT16 leftoffset, I
startofspan = NULL;
// Write column pointer
WRITEINT32(colpointers, imgptr - imgbuf);
WRITEINT32(colpointers, imgptr - imgbuf.data());
// Write pixels
for (y = 0; y < height; y++)
@@ -557,9 +569,9 @@ void *R_PixelsToPatch(UINT8 *raw, INT16 width, INT16 height, INT16 leftoffset, I
WRITEUINT8(imgptr, 0xFF);
}
size = imgptr-imgbuf;
img = Z_Malloc(size, PU_STATIC, NULL);
memcpy(img, imgbuf, size);
size = imgptr-imgbuf.data();
img = static_cast<UINT8*>(Z_Malloc(size, PU_STATIC, NULL));
memcpy(img, imgbuf.data(), size);
if (destsize != NULL)
*destsize = size;
@@ -582,17 +594,27 @@ void *R_PixelsToPatch(UINT8 *raw, INT16 width, INT16 height, INT16 leftoffset, I
void *R_MaskedFlatToPatch(UINT16 *raw, INT16 width, INT16 height, INT16 leftoffset, INT16 topoffset, size_t *destsize)
{
INT16 x, y;
UINT8 *img;
UINT8 *img, *imgptr;
UINT8 *colpointers, *startofspan;
size_t size = 0;
if (!raw)
return NULL;
if (!imgbuf)
imgbuf = Z_Malloc(1<<26, PU_STATIC, NULL);
// Allocate a staging buffer with the maximum size needed for a patch of the same size as the input.
UINT8 *imgptr = imgbuf;
// round up to nearest multiple of 254-pixel posts, plus 1 more 254-pixel post for paranoia reasons
size_t maxcolumnsize = (2 + (height - 1) / 256) * 256;
// the patch header, and width columns of the max column size
size_t maxoutsize = maxcolumnsize * width + (8 + 4 * width);
// so, a 512x512 flat should maximally need 393,760 (384.53 KiB) bytes.
// quite a bit smaller than 64 megabytes, and much less annoying to the windows debug allocator!
while (imgbuf.size() < maxoutsize)
{
imgbuf.resize(imgbuf.size() * 2);
}
imgptr = imgbuf.data();
// Write image size and offset
WRITEINT16(imgptr, width);
@@ -612,7 +634,7 @@ void *R_MaskedFlatToPatch(UINT16 *raw, INT16 width, INT16 height, INT16 leftoffs
startofspan = NULL;
// Write column pointer
WRITEINT32(colpointers, imgptr - imgbuf);
WRITEINT32(colpointers, imgptr - imgbuf.data());
// Write pixels
for (y = 0; y < height; y++)
@@ -682,9 +704,9 @@ void *R_MaskedFlatToPatch(UINT16 *raw, INT16 width, INT16 height, INT16 leftoffs
WRITEUINT8(imgptr, 0xFF);
}
size = imgptr-imgbuf;
img = Z_Malloc(size, PU_STATIC, NULL);
memcpy(img, imgbuf, size);
size = imgptr-imgbuf.data();
img = static_cast<UINT8*>(Z_Malloc(size, PU_STATIC, NULL));
memcpy(img, imgbuf.data(), size);
if (destsize != NULL)
*destsize = size;
+10
View File
@@ -14,6 +14,10 @@
#ifndef __R_PATCH__
#define __R_PATCH__
#ifdef __cplusplus
extern "C" {
#endif
#include "r_defs.h"
// Structs
@@ -36,6 +40,8 @@ typedef struct
boolean available;
} spriteinfo_t;
#define PNG_HEADER_SIZE (8)
// Patch functions
patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest);
void Patch_Free(patch_t *patch);
@@ -61,4 +67,8 @@ void *R_PixelsToPatch(UINT8 *raw, INT16 width, INT16 height, INT16 leftoffset, I
UINT16 R_GetPatchPixel(patch_t *patch, INT32 x, INT32 y, boolean flip);
void R_PatchToPixels(patch_t *patch, UINT8 *dst); // Important: dst must have enough space for patch->width*patch->height pixels!
#ifdef __cplusplus
} // extern "C"
#endif
#endif // __R_PATCH__
@@ -15,6 +15,7 @@
#include "r_patchrotation.h"
#include "z_zone.h"
#include "w_wad.h"
#include <vector>
#ifdef ROTSPRITE
//
@@ -89,14 +90,14 @@ patch_t *Patch_GetRotatedSprite(spriteframe_t *sprite, size_t frame, size_t spri
RotatedPatch_DoRotation(rotsprite, patch, rotationangle, xpivot, ypivot, flip);
}
return rotsprite->patches[idx];
return static_cast<patch_t*>(rotsprite->patches[idx]);
}
rotsprite_t *RotatedPatch_Create(INT32 numangles)
{
rotsprite_t *rotsprite = Z_Calloc(sizeof(rotsprite_t), PU_STATIC, NULL);
rotsprite_t *rotsprite = static_cast<rotsprite_t*>(Z_Calloc(sizeof(rotsprite_t), PU_STATIC, NULL));
rotsprite->angles = numangles;
rotsprite->patches = Z_Calloc(rotsprite->angles * 2 * sizeof(void *), PU_STATIC, NULL);
rotsprite->patches = static_cast<void**>(Z_Calloc(rotsprite->angles * 2 * sizeof(void *), PU_STATIC, NULL));
return rotsprite;
}
@@ -118,30 +119,8 @@ static void RotatedPatch_CalculateDimensions(
h1 = FixedInt(FixedCeil(h1 + (FRACUNIT/2)));
h2 = FixedInt(FixedCeil(h2 + (FRACUNIT/2)));
*newwidth = max(width, max(w1, w2));
*newheight = max(height, max(h1, h2));
}
static void RotatedPatch_AllocImgBuf(UINT16 **buf, size_t size, size_t *capacity)
{
if (!*buf)
{
*buf = Z_Malloc(*capacity, PU_STATIC, NULL);
}
size_t allocsize = size * sizeof(UINT16);
// make sure our buffer always fits with what we need
if (allocsize > *capacity)
{
while (*capacity < allocsize)
*capacity *= 2;
Z_Free(*buf);
*buf = Z_Malloc(*capacity, PU_STATIC, NULL);
}
//CONS_Printf("RotatedPatch_AllocBuf: Allocated %.2f KB\n", *capacity / 1024.0);
*newwidth = std::max(width, std::max(w1, w2));
*newheight = std::max(height, std::max(h1, h2));
}
void RotatedPatch_DoRotation(rotsprite_t *rotsprite, patch_t *patch, INT32 angle, INT32 xpivot, INT32 ypivot, boolean flip)
@@ -149,10 +128,10 @@ void RotatedPatch_DoRotation(rotsprite_t *rotsprite, patch_t *patch, INT32 angle
UINT32 i;
patch_t *rotated;
static UINT16 *rawdst = NULL, *rawconv = NULL;
static std::vector<UINT16> rawdst(1024 * 1024), rawconv(1024 * 1024); // 1 MB should be enough for most cases
UINT16 *rawout;
size_t size;
static size_t dst_capacity = (1024 * 1024), conv_capacity = (1024 * 1024); // 1 MB should be enough for most cases
INT32 bflip = (flip != 0x00);
INT32 width = patch->width;
@@ -206,7 +185,10 @@ void RotatedPatch_DoRotation(rotsprite_t *rotsprite, patch_t *patch, INT32 angle
if (!size)
size = (width * height);
RotatedPatch_AllocImgBuf(&rawdst, size, &dst_capacity);
while (rawdst.size() < size)
{
rawdst.resize(rawdst.size() * 2);
}
for (i = 0; i < size; i++)
rawdst[i] = 0xFF00;
@@ -250,11 +232,11 @@ void RotatedPatch_DoRotation(rotsprite_t *rotsprite, patch_t *patch, INT32 angle
size = (width * height);
RotatedPatch_AllocImgBuf(&rawconv, size, &conv_capacity);
memset(rawconv, 0, conv_capacity * sizeof(UINT16));
rawconv.resize(size);
memset(rawconv.data(), 0, size * sizeof(UINT16));
src = &rawdst[(miny * newwidth) + minx];
dest = rawconv;
dest = rawconv.data();
dy = height;
while (dy--)
@@ -267,14 +249,14 @@ void RotatedPatch_DoRotation(rotsprite_t *rotsprite, patch_t *patch, INT32 angle
ox -= minx;
oy -= miny;
rawout = rawconv;
rawout = rawconv.data();
}
else
{
width = newwidth;
height = newheight;
rawout = rawdst;
rawout = rawdst.data();
}
// make patch
+38 -52
View File
@@ -46,31 +46,27 @@
// good night sweet prince
//#define SHITPLANESPARENCY
visplane_t *visplanes[MAXVISPLANES];
visplane_t *visplanes[MAXVISPLANES] = {};
static visplane_t *freetail;
static visplane_t **freehead = &freetail;
visplane_t *floorplane;
visplane_t *ceilingplane;
visplane_t *floorplane = NULL;
visplane_t *ceilingplane = NULL;
visffloor_t visffloor[MAXFFLOORS];
INT32 numffloors;
visffloor_t visffloor[MAXFFLOORS] = {};
INT32 numffloors = 0;
//SoM: 3/23/2000: Boom visplane hashing routine.
#define visplane_hash(picnum,lightlevel,height) \
((unsigned)((picnum)*3+(lightlevel)+(height)*7) & VISPLANEHASHMASK)
//SoM: 3/23/2000: Use boom opening limit removal
size_t maxopenings;
INT16 *openings, *lastopening; /// \todo free leak
//
// Clip values are the solid pixel bounding the range.
// floorclip starts out SCREENHEIGHT
// ceilingclip starts out -1
//
INT16 *floorclip, *ceilingclip;
fixed_t *frontscale;
INT16 *floorclip = NULL, *ceilingclip = NULL;
fixed_t *frontscale = NULL;
//
// spanstart holds the start of a plane span
@@ -85,13 +81,13 @@ static INT32 *spanstart;
// (this is to calculate yslopes only when really needed)
// (when mouselookin', yslope is moving into yslopetab)
// Check R_SetupFrame, R_SetViewSize for more...
fixed_t *yslopetab;
fixed_t *yslope;
fixed_t *yslopetab = NULL;
fixed_t *yslope = NULL;
fixed_t basexscale, baseyscale;
fixed_t basexscale = 0, baseyscale = 0;
static INT16 *ffloor_f_clip;
static INT16 *ffloor_c_clip;
static INT16 *ffloor_f_clip = NULL;
static INT16 *ffloor_c_clip = NULL;
static void R_SetTiltedSpan(drawspandata_t* ds, INT32 span);
static void R_SetSlopePlaneVectors(drawspandata_t* ds, visplane_t *pl, INT32 y, fixed_t xoff, fixed_t yoff);
@@ -339,13 +335,13 @@ void R_ClearPlanes(void)
R_ClearFFloorClips();
for (i = 0; i < MAXVISPLANES; i++)
{
for (*freehead = visplanes[i], visplanes[i] = NULL;
freehead && *freehead ;)
{
freehead = &(*freehead)->next;
}
lastopening = openings;
}
// left to right mapping
angle = (viewangle-ANGLE_90)>>ANGLETOFINESHIFT;
@@ -620,14 +616,12 @@ void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop)
//
static void R_MakeSpans(void (*mapfunc)(drawspandata_t* ds, void(*spanfunc)(drawspandata_t*), INT32, INT32, INT32, boolean), spandrawfunc_t* localspanfunc, drawspandata_t* ds, INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2, boolean allow_parallel)
{
const INT32 vidheight = vid.height;
// Alam: from r_splats's R_RenderFloorSplat
if (t1 >= vidheight) t1 = vidheight-1;
if (b1 >= vidheight) b1 = vidheight-1;
if (t2 >= vidheight) t2 = vidheight-1;
if (b2 >= vidheight) b2 = vidheight-1;
if (x-1 >= vid.width) x = vid.width;
if (t1 >= viewheight) t1 = viewheight-1;
if (b1 >= viewheight) b1 = viewheight-1;
if (t2 >= viewheight) t2 = viewheight-1;
if (b2 >= viewheight) b2 = viewheight-1;
if (x-1 >= viewwidth) x = viewwidth;
#ifdef HAVE_THREADS
// We want to draw N spans per subtask to ensure the work is
@@ -720,13 +714,10 @@ void R_DrawPlanes(void)
visplane_t *pl;
INT32 i;
drawspandata_t ds = {};
#ifdef HAVE_THREADS
srb2::ThreadPool::Sema tp_sema;
#endif
R_UpdatePlaneRipple(&ds);
#ifdef HAVE_THREADS
srb2::ThreadPool::Sema tp_sema;
srb2::g_main_threadpool->begin_sema();
#endif
for (i = 0; i < MAXVISPLANES; i++, pl++)
@@ -746,13 +737,20 @@ void R_DrawPlanes(void)
#endif
}
static void R_DrawSkyPlane(visplane_t *pl, void(*colfunc2)(drawcolumndata_t*), boolean allow_parallel);
static void R_DrawSkyPlane(visplane_t *pl, void(*skycolfunc)(drawcolumndata_t*), boolean allow_parallel);
void R_DrawSkyPlanes(void)
{
visplane_t *pl;
INT32 i;
// If we're not supposed to draw the sky (e.g. for skyboxes), don't do anything!
// This probably utterly ruins sky rendering for FOFs and polyobjects, unfortunately
if (!newview->sky)
{
return;
}
#ifdef HAVE_THREADS
srb2::ThreadPool::Sema tp_sema;
srb2::g_main_threadpool->begin_sema();
@@ -774,23 +772,17 @@ void R_DrawSkyPlanes(void)
#endif
}
static void R_DrawSkyPlane(visplane_t *pl, void(*colfunc2)(drawcolumndata_t*), boolean allow_parallel)
static void R_DrawSkyPlane(visplane_t *pl, void(*skycolfunc)(drawcolumndata_t*), boolean allow_parallel)
{
INT32 x;
if (!(pl->minx <= pl->maxx))
return;
// If we're not supposed to draw the sky (e.g. for skyboxes), don't do anything!
// This probably utterly ruins sky rendering for FOFs and polyobjects, unfortunately
if (!newview->sky)
{
return;
}
drawcolumndata_t dc = {};
const INT32 texture = texturetranslation[skytexture];
// Reset column drawer function (note: couldn't we just call walldrawerfunc directly?)
// 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);
@@ -807,16 +799,13 @@ static void R_DrawSkyPlane(visplane_t *pl, void(*colfunc2)(drawcolumndata_t*), b
dc.colormap += COLORMAP_REMAPOFFSET;
dc.texturemid = skytexturemid;
dc.texheight = textureheight[skytexture] >>FRACBITS;
dc.texheight = textureheight[texture] >>FRACBITS;
dc.sourcelength = dc.texheight;
x = pl->minx;
// Precache the texture so we don't corrupt the zoned heap off-main thread
if (!texturecache[texturetranslation[skytexture]])
{
R_GenerateTexture(texturetranslation[skytexture]);
}
R_CheckTextureCache(texture);
#ifdef HAVE_THREADS
while (x <= pl->maxx)
@@ -841,11 +830,9 @@ static void R_DrawSkyPlane(visplane_t *pl, void(*colfunc2)(drawcolumndata_t*), b
dc.iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x + i]>>ANGLETOFINESHIFT));
dc.x = x + i;
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
dc.source = R_GetColumn(texture, -angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18
colfunc2(&dc);
skycolfunc(&dc);
}
};
@@ -879,10 +866,9 @@ static void R_DrawSkyPlane(visplane_t *pl, void(*colfunc2)(drawcolumndata_t*), b
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
R_GetColumn(texturetranslation[skytexture], -angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18
colfunc2(&dc);
skycolfunc(&dc);
}
#endif
}
@@ -1167,7 +1153,7 @@ void R_DrawSinglePlane(drawspandata_t* ds, visplane_t *pl, boolean allow_paralle
offset = (scry*vid.width) + scrx;
// No idea if this works
VID_BlitLinearScreen(renderscreen + offset,
VID_BlitLinearScreen(vid.screens[0] + offset,
vid.screens[1] + (top*vid.width), // intentionally not +offset
viewwidth, bottom-top,
vid.width, vid.width);
-2
View File
@@ -67,8 +67,6 @@ extern visplane_t *floorplane;
extern visplane_t *ceilingplane;
// Visplane related.
extern INT16 *lastopening, *openings;
extern size_t maxopenings;
extern INT16 *floorclip, *ceilingclip;
extern fixed_t *frontscale, *yslopetab;
+275 -214
View File
@@ -26,7 +26,6 @@
#include "p_local.h" // Camera...
#include "p_setup.h"
#include "p_slopes.h"
#include "console.h" // con_clipviewtop
#include "screen.h"
#include "core/memory.h"
@@ -78,9 +77,21 @@ static fixed_t topfrac, topstep;
static fixed_t bottomfrac, bottomstep;
static lighttable_t **walllights;
static INT16 *maskedtexturecol;
static fixed_t *maskedtexturecol;
static fixed_t *maskedtextureheight = NULL;
static size_t numopenings;
static INT16 *openings, *lastopening;
static size_t texturecolumntablesize;
static fixed_t *texturecolumntable, *curtexturecolumntable;
void R_ClearSegTables(void)
{
lastopening = openings;
curtexturecolumntable = texturecolumntable;
}
// ==========================================================================
// R_RenderMaskedSegRange
// ==========================================================================
@@ -140,7 +151,18 @@ static void R_Render2sidedMultiPatchColumn(drawcolumndata_t* dc, column_t *colum
transnum_t R_GetLinedefTransTable(fixed_t alpha)
{
return static_cast<transnum_t>((20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1));
if (alpha >= FRACUNIT)
{
return static_cast<transnum_t>(0);
}
else if (alpha <= 0)
{
return NUMTRANSMAPS;
}
else
{
return static_cast<transnum_t>((20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1));
}
}
static inline boolean R_OverflowTest(drawcolumndata_t* dc)
@@ -173,7 +195,7 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
ldef = curline->linedef;
range = std::max(drawseg->x2-drawseg->x1, 1);
range = std::max<INT32>(drawseg->x2-drawseg->x1, 1);
// Setup lighting based on the presence/lack-of 3D floors.
dc->numlights = 0;
@@ -306,141 +328,137 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
else
dc->texturemid -= (textureheight[texnum])*times;
const INT16 colnum = maskedtexturecol[dc->x];
// Check for overflows first
if (R_OverflowTest(dc))
{
// Eh, no, go away, don't waste our time
if (dc->numlights)
{
for (i = 0; i < dc->numlights; i++)
{
rlight = &dc->lightlist[i];
rlight->height += rlight->heightstep;
}
}
spryscale += rw_scalestep;
continue;
}
// calculate lighting
if (colnum != INT16_MAX)
if (dc->numlights)
{
// Check for overflows first
if (R_OverflowTest(dc))
lighttable_t **xwalllights;
sprbotscreen = INT32_MAX;
sprtopscreen = windowtop = (centeryfrac - FixedMul(dc->texturemid, spryscale));
realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen;
dc->iscale = 0xffffffffu / (unsigned)spryscale;
// draw the texture
col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc->x] >> FRACBITS)) - 3);
auto set_light_vars = [&](INT32 k)
{
// Eh, no, go away, don't waste our time
if (dc->numlights)
rlight = &dc->lightlist[k];
lightnum = rlight->lightnum;
if (lightnum < 0)
xwalllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
xwalllights = scalelight[LIGHTLEVELS-1];
else
xwalllights = scalelight[lightnum];
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE - 1;
if (rlight->extra_colormap)
rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps);
else
rlight->rcolormap = xwalllights[pindex];
};
auto set_colormap_below_light = [&]
{
dc->colormap = rlight->rcolormap;
if (encoremap && !(ldef->flags & ML_TFERLINE))
dc->colormap += COLORMAP_REMAPOFFSET;
};
// Use the base sector's light level above the first FOF.
// You can imagine it as the sky casting its light on top of the highest FOF.
set_light_vars(0);
set_colormap_below_light();
for (i = 0; i < dc->numlights; i++)
{
if ((dc->lightlist[i].flags & FF_NOSHADE))
continue;
set_light_vars(i);
height = rlight->height;
rlight->height += rlight->heightstep;
if (height <= windowtop)
{
for (i = 0; i < dc->numlights; i++)
set_colormap_below_light();
continue;
}
windowbottom = height;
if (windowbottom >= realbot)
{
windowbottom = realbot;
colfunc_2s(dc, col);
for (i++; i < dc->numlights; i++)
{
rlight = &dc->lightlist[i];
rlight->height += rlight->heightstep;
}
continue;
}
spryscale += rw_scalestep;
continue;
}
colfunc_2s(dc, col);
if (dc->numlights)
{
lighttable_t **xwalllights;
sprbotscreen = INT32_MAX;
sprtopscreen = windowtop = (centeryfrac - FixedMul(dc->texturemid, spryscale));
realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen;
dc->iscale = 0xffffffffu / (unsigned)spryscale;
// draw the texture
col = (column_t *)((UINT8 *)R_GetColumn(texnum, colnum) - 3);
auto set_light_vars = [&](INT32 k)
{
rlight = &dc->lightlist[k];
lightnum = rlight->lightnum;
if (lightnum < 0)
xwalllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
xwalllights = scalelight[LIGHTLEVELS-1];
else
xwalllights = scalelight[lightnum];
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE - 1;
if (rlight->extra_colormap)
rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps);
else
rlight->rcolormap = xwalllights[pindex];
};
auto set_colormap_below_light = [&]
{
dc->colormap = rlight->rcolormap;
if (encoremap && !(ldef->flags & ML_TFERLINE))
dc->colormap += COLORMAP_REMAPOFFSET;
};
// Use the base sector's light level above the first FOF.
// You can imagine it as the sky casting its light on top of the highest FOF.
set_light_vars(0);
windowtop = windowbottom + 1;
set_colormap_below_light();
for (i = 0; i < dc->numlights; i++)
{
if ((dc->lightlist[i].flags & FF_NOSHADE))
continue;
set_light_vars(i);
height = rlight->height;
rlight->height += rlight->heightstep;
if (height <= windowtop)
{
set_colormap_below_light();
continue;
}
windowbottom = height;
if (windowbottom >= realbot)
{
windowbottom = realbot;
colfunc_2s(dc, col);
for (i++; i < dc->numlights; i++)
{
rlight = &dc->lightlist[i];
rlight->height += rlight->heightstep;
}
continue;
}
colfunc_2s(dc, col);
windowtop = windowbottom + 1;
set_colormap_below_light();
}
windowbottom = realbot;
if (windowtop < windowbottom)
colfunc_2s(dc, col);
spryscale += rw_scalestep;
continue;
}
windowbottom = realbot;
if (windowtop < windowbottom)
colfunc_2s(dc, col);
// calculate lighting
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE - 1;
dc->colormap = walllights[pindex];
if (encoremap && !(ldef->flags & ML_TFERLINE))
dc->colormap += COLORMAP_REMAPOFFSET;
if (frontsector->extra_colormap)
dc->colormap = frontsector->extra_colormap->colormap + (dc->colormap - colormaps);
sprtopscreen = centeryfrac - FixedMul(dc->texturemid, spryscale);
dc->iscale = 0xffffffffu / (unsigned)spryscale;
// draw the texture
col = (column_t *)((UINT8 *)R_GetColumn(texnum, colnum) - 3);
colfunc_2s(dc, col);
spryscale += rw_scalestep;
continue;
}
// calculate lighting
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE - 1;
dc->colormap = walllights[pindex];
if (encoremap && !(ldef->flags & ML_TFERLINE))
dc->colormap += COLORMAP_REMAPOFFSET;
if (frontsector->extra_colormap)
dc->colormap = frontsector->extra_colormap->colormap + (dc->colormap - colormaps);
sprtopscreen = centeryfrac - FixedMul(dc->texturemid, spryscale);
dc->iscale = 0xffffffffu / (unsigned)spryscale;
// draw the texture
col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc->x] >> FRACBITS)) - 3);
colfunc_2s(dc, col);
spryscale += rw_scalestep;
}
}
@@ -609,8 +627,6 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
sector_t tempsec;
INT32 templight;
INT32 i, p;
fixed_t bottombounds = viewheight << FRACBITS;
fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS;
fixed_t offsetvalue = 0;
lightlist_t *light;
r_lightlist_t *rlight;
@@ -632,6 +648,7 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
void (*colfunc_2s) (drawcolumndata_t* dc, column_t *);
// Calculate light table.
// Use different light tables
// for horizontal / vertical / diagonal. Diagonal?
@@ -674,7 +691,7 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
fog = true;
}
range = std::max(drawseg->x2-drawseg->x1, 1);
range = std::max<INT32>(drawseg->x2-drawseg->x1, 1);
//SoM: Moved these up here so they are available for my lightlist calculations
rw_scalestep = drawseg->scalestep;
spryscale = drawseg->scale1 + (x1 - drawseg->x1)*rw_scalestep;
@@ -899,14 +916,11 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
// draw the columns
for (dc->x = x1; dc->x <= x2; dc->x++)
{
if (maskedtexturecol[dc->x] == INT16_MAX)
continue;
// skew FOF walls
if (ffloortextureslide)
{
if (oldx != -1)
dc->texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc->x])<<FRACBITS);
dc->texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc->x]));
oldx = dc->x;
}
@@ -919,7 +933,7 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
bottom_frac += bottom_step;
// SoM: If column is out of range, why bother with it??
if (windowbottom < topbounds || windowtop > bottombounds)
if (windowbottom < 0 || windowtop > (viewheight << FRACBITS))
{
if (dc->numlights)
{
@@ -936,9 +950,6 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
continue;
}
// Get data for the column
col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc->x]) - 3);
if (!fog)
{
dc->iscale = 0xffffffffu / (unsigned)spryscale;
@@ -949,6 +960,9 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
R_SetColumnFunc(BASEDRAWFUNC);
}
// Get data for the column
col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc->x] >> FRACBITS)) - 3);
// SoM: New code does not rely on R_DrawColumnShadowed which
// will (hopefully) put less strain on the stack.
if (dc->numlights)
@@ -1159,13 +1173,14 @@ static inline void R_ExpandPlaneY(visplane_t *pl, INT32 x, INT16 top, INT16 bott
static void R_DrawWallColumn(drawcolumndata_t* dc, INT32 yl, INT32 yh, fixed_t mid, fixed_t texturecolumn, INT32 texture, boolean remap)
{
const INT32 itexturecolumn = texturecolumn >> FRACBITS;
dc->yl = yl;
dc->yh = yh;
dc->texturemid = mid;
dc->source = R_GetColumn(texture, texturecolumn);
dc->source = R_GetColumn(texture, itexturecolumn);
dc->texheight = textureheight[texture] >> FRACBITS;
dc->sourcelength = dc->texheight;
//R_SetColumnFunc(colfunctype);
R_SetColumnFunc(colfunctype);
coldrawfunc_t* colfunccopy = colfunc;
drawcolumndata_t dc_copy = *dc;
if (remap)
@@ -1191,13 +1206,21 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
INT32 bottom;
INT32 i;
if (midtexture)
R_CheckTextureCache(midtexture);
if (toptexture)
R_CheckTextureCache(toptexture);
if (bottomtexture)
R_CheckTextureCache(bottomtexture);
// Loop over width
for (; rw_x < rw_stopx; rw_x++)
{
// mark floor / ceiling areas
yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS;
yh = bottomfrac>>HEIGHTBITS;
// no space above wall?
// Mark ceiling
top = ceilingclip[rw_x]+1;
// no space above wall?
@@ -1214,10 +1237,10 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
}
}
yh = bottomfrac>>HEIGHTBITS;
// Mark floor
bottom = floorclip[rw_x]-1;
// no space below floor?
if (yh > bottom)
yh = bottom;
@@ -1346,7 +1369,7 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
// calculate texture offset
angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT;
// Mask 4095 to guarantee this index is within bounds
texturecolumn = rw_offset-FixedMul(FINETANGENT(angle & 4095),rw_distance);
texturecolumn = rw_offset-FixedMul(FINETANGENT(angle & 4095), rw_distance);
if (oldtexturecolumn != -1)
{
@@ -1357,8 +1380,6 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
}
oldtexturecolumn = texturecolumn;
texturecolumn >>= FRACBITS;
// texturecolumn and lighting are independent of wall tiers
if (segtextured)
{
@@ -1515,7 +1536,7 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
if (maskedtexture || numthicksides)
{
// save texturecol for backdrawing of masked mid texture
maskedtexturecol[rw_x] = (INT16)texturecolumn;
maskedtexturecol[rw_x] = texturecolumn;
if (maskedtextureheight != NULL)
{
@@ -1561,7 +1582,7 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
static void R_MarkSegBounds(void)
{
INT32 yl, yh;
INT32 yl, yh;
INT32 top, bottom;
INT16 topclip, bottomclip;
@@ -1570,8 +1591,9 @@ static void R_MarkSegBounds(void)
{
// mark floor / ceiling areas
yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS;
yh = bottomfrac>>HEIGHTBITS;
// no space above wall?
// Mark ceiling
top = ceilingclip[rw_x]+1;
// no space above wall?
@@ -1588,10 +1610,10 @@ static void R_MarkSegBounds(void)
}
}
yh = bottomfrac>>HEIGHTBITS;
// Mark floor
bottom = floorclip[rw_x]-1;
// no space below floor?
if (yh > bottom)
yh = bottom;
@@ -1616,12 +1638,6 @@ static void R_MarkSegBounds(void)
if (markfloor) // no bottom wall
floorclip[rw_x] = bottomclip;
if (floorclip[rw_x] <= ceilingclip[rw_x] + 1)
{
solidcol[rw_x] = 1;
didsolidcol = true;
}
rw_scale += rw_scalestep;
topfrac += topstep;
bottomfrac += bottomstep;
@@ -1663,15 +1679,87 @@ void R_AllocSegMemory(void)
fixed_t *frontscale_p = frontscaletable;
fixed_t *maskedheight_p = maskedheighttable;
for (drawseg_t *ds = drawsegs; ds < lastseg; ds++)
for (drawseg_t *drawseg = drawsegs; drawseg < lastseg; drawseg++)
{
ds->frontscale = frontscale_p;
ds->maskedtextureheight = maskedheight_p;
drawseg->frontscale = frontscale_p;
drawseg->maskedtextureheight = maskedheight_p;
frontscale_p += viewwidth;
maskedheight_p += viewwidth;
}
}
//SoM: Code to remove limits on openings.
static void R_AllocClippingTables(size_t range)
{
size_t pos = lastopening - openings;
size_t need = range * 2; // for both sprtopclip and sprbottomclip
if (pos + need < numopenings)
return;
INT16 *oldopenings = openings;
INT16 *oldlast = lastopening;
if (numopenings == 0)
numopenings = 16384;
numopenings += need;
openings = static_cast<INT16*>(Z_Realloc(openings, numopenings * sizeof (*openings), PU_STATIC, NULL));
lastopening = openings + pos;
if (oldopenings == NULL)
return;
// borrowed fix from *cough* zdoom *cough*
// [RH] We also need to adjust the openings pointers that
// were already stored in drawsegs.
for (drawseg_t *drawseg = drawsegs; drawseg < ds_p; drawseg++)
{
// Check if it's in range of the openings
#define CHECK(which) \
if (which + drawseg->x1 >= oldopenings && which + drawseg->x1 <= oldlast) \
which = (which - oldopenings) + openings
CHECK(drawseg->sprtopclip);
CHECK(drawseg->sprbottomclip);
#undef CHECK
}
}
static void R_AllocTextureColumnTables(size_t range)
{
size_t pos = curtexturecolumntable - texturecolumntable;
// For both tables, we reserve exactly an amount of memory that's equivalent to
// how many columns the seg will take on the entire screen (think about it)
if (pos + range < texturecolumntablesize)
return;
fixed_t *oldtable = texturecolumntable;
fixed_t *oldlast = curtexturecolumntable;
if (texturecolumntablesize == 0)
texturecolumntablesize = 16384;
texturecolumntablesize += range;
texturecolumntable = static_cast<fixed_t*>(Z_Realloc(texturecolumntable, texturecolumntablesize * sizeof (*texturecolumntable), PU_STATIC, NULL));
curtexturecolumntable = texturecolumntable + pos;
if (oldtable == NULL)
return;
for (drawseg_t *drawseg = drawsegs; drawseg < ds_p; drawseg++)
{
// Check if it's in range of the tables
#define CHECK(which) \
if (which + drawseg->x1 >= oldtable && which + drawseg->x1 <= oldlast) \
which = (which - oldtable) + texturecolumntable
CHECK(drawseg->maskedtexturecol);
CHECK(drawseg->thicksidecol);
#undef CHECK
}
}
//
// R_StoreWallRange
// A wall segment will be drawn
@@ -1684,12 +1772,13 @@ void R_StoreWallRange(INT32 start, INT32 stop)
angle_t distangle, offsetangle;
boolean longboi;
INT32 lightnum;
INT32 i, p;
INT32 i = 0, p;
lightlist_t *light;
r_lightlist_t *rlight;
INT32 range;
vertex_t segleft, segright;
fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide;
const INT32 twosidedmidtexture = R_GetTextureNum(curline->sidedef->midtexture);
drawcolumndata_t dc = {};
maskedtextureheight = NULL;
@@ -1745,41 +1834,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ds_p->curline = curline;
rw_stopx = stop+1;
//SoM: Code to remove limits on openings.
{
size_t pos = lastopening - openings;
size_t need = (rw_stopx - start)*4 + pos;
if (need > maxopenings)
{
drawseg_t *ds; //needed for fix from *cough* zdoom *cough*
INT16 *oldopenings = openings;
INT16 *oldlast = lastopening;
do
maxopenings = maxopenings ? maxopenings*2 : 16384;
while (need > maxopenings);
openings = static_cast<INT16*>(Z_Realloc(openings, maxopenings * sizeof (*openings), PU_STATIC, NULL));
lastopening = openings + pos;
if (oldopenings == NULL)
return;
// borrowed fix from *cough* zdoom *cough*
// [RH] We also need to adjust the openings pointers that
// were already stored in drawsegs.
for (ds = drawsegs; ds < ds_p; ds++)
{
#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = (ds->p - oldopenings) + openings;
ADJUST(maskedtexturecol);
ADJUST(sprtopclip);
ADJUST(sprbottomclip);
ADJUST(thicksidecol);
#undef ADJUST
}
}
} // end of code to remove limits on openings
// calculate scale at both ends and step
ds_p->scale1 = rw_scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]);
@@ -1874,8 +1928,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
numbackffloors = 0;
for (i = 0; i < MAXFFLOORS; i++)
ds_p->thicksides[i] = NULL;
memset(ds_p->thicksides, 0, MAXFFLOORS * sizeof(*ds_p->thicksides));
if (numffloors)
{
@@ -2160,6 +2213,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
rw_toptexturemid += sidedef->rowoffset;
rw_bottomtexturemid += sidedef->rowoffset;
R_AllocTextureColumnTables(rw_stopx - start);
// allocate space for masked texture tables
if (frontsector && backsector && (frontsector->tag != backsector->tag) && (backsector->ffloors || frontsector->ffloors))
{
@@ -2173,15 +2228,15 @@ void R_StoreWallRange(INT32 start, INT32 stop)
maskedtexture = true;
ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x;
lastopening += rw_stopx - rw_x;
ds_p->thicksidecol = maskedtexturecol = curtexturecolumntable - rw_x;
curtexturecolumntable += rw_stopx - rw_x;
lowcut = std::max(worldbottom, worldlow) + viewz;
highcut = std::min(worldtop, worldhigh) + viewz;
lowcutslope = std::max(worldbottomslope, worldlowslope) + viewz;
highcutslope = std::min(worldtopslope, worldhighslope) + viewz;
auto check_fof_offscreen = [&](INT32 bottom, INT32 bottomslope, INT32 top, INT32 topslope)
auto check_fof_offscreen = [&](ffloor_t* rover, INT32 bottom, INT32 bottomslope, INT32 top, INT32 topslope)
{
return ((P_GetFFloorTopZAt (rover, segleft .x, segleft .y) <= bottom + viewz
&& P_GetFFloorTopZAt (rover, segright.x, segright.y) <= bottomslope + viewz)
@@ -2321,7 +2376,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
continue;
// Oy vey.
if (check_fof_offscreen(worldbottom, worldbottomslope, worldtop, worldtopslope))
if (check_fof_offscreen(rover, worldbottom, worldbottomslope, worldtop, worldtopslope))
continue;
ds_p->thicksides[i] = rover;
@@ -2339,10 +2394,10 @@ void R_StoreWallRange(INT32 start, INT32 stop)
continue;
// Oy vey.
if (check_fof_offscreen(worldbottom, worldbottomslope, worldtop, worldtopslope))
if (check_fof_offscreen(rover, worldbottom, worldbottomslope, worldtop, worldtopslope))
continue;
if (check_fof_offscreen(worldlow, worldlowslope, worldhigh, worldhighslope))
if (check_fof_offscreen(rover, worldlow, worldlowslope, worldhigh, worldhighslope))
continue;
ds_p->thicksides[i] = rover;
@@ -2353,13 +2408,14 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ds_p->numthicksides = numthicksides = i;
}
if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures)
if (twosidedmidtexture)
{
// masked midtexture
if (!ds_p->thicksidecol)
{
ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x;
lastopening += rw_stopx - rw_x;
ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x;
curtexturecolumntable += rw_stopx - rw_x;
}
else
ds_p->maskedtexturecol = ds_p->thicksidecol;
@@ -2939,18 +2995,23 @@ void R_StoreWallRange(INT32 start, INT32 stop)
}
// save sprite clipping info
if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip)
if (maskedtexture || (ds_p->silhouette & (SIL_TOP | SIL_BOTTOM)))
{
M_Memcpy(lastopening, ceilingclip+start, 2*(rw_stopx - start));
ds_p->sprtopclip = lastopening - start;
lastopening += rw_stopx - start;
}
R_AllocClippingTables(rw_stopx - start);
if (((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && !ds_p->sprbottomclip)
{
M_Memcpy(lastopening, floorclip + start, 2*(rw_stopx-start));
ds_p->sprbottomclip = lastopening - start;
lastopening += rw_stopx - start;
if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip)
{
M_Memcpy(lastopening, ceilingclip + start, 2*(rw_stopx - start));
ds_p->sprtopclip = lastopening - start;
lastopening += rw_stopx - start;
}
if (((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && !ds_p->sprbottomclip)
{
M_Memcpy(lastopening, floorclip + start, 2*(rw_stopx - start));
ds_p->sprbottomclip = lastopening - start;
lastopening += rw_stopx - start;
}
}
if (maskedtexture)
@@ -2958,13 +3019,13 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (!(ds_p->silhouette & SIL_TOP))
{
ds_p->silhouette |= SIL_TOP;
ds_p->tsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MIN: INT32_MAX;
ds_p->tsilheight = (twosidedmidtexture) ? INT32_MIN : INT32_MAX;
}
if (!(ds_p->silhouette & SIL_BOTTOM))
{
ds_p->silhouette |= SIL_BOTTOM;
ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX: INT32_MIN;
ds_p->bsilheight = (twosidedmidtexture) ? INT32_MAX : INT32_MIN;
}
}
+1
View File
@@ -25,6 +25,7 @@ extern "C" {
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2);
void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor);
void R_StoreWallRange(INT32 start, INT32 stop);
void R_ClearSegTables(void);
void R_AllocSegMemory(void);
+8
View File
@@ -35,6 +35,8 @@
CV_PossibleValue_t Forceskin_cons_t[MAXSKINS+2];
#include "discord.h"
INT32 numskins = 0;
INT32 numallskins = 0;
INT32 numlocalskins = 0;
@@ -328,8 +330,14 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
if (player->mo)
P_SetScale(player->mo, player->mo->scale);
// for replays: We have changed our skin mid-game; let the game know so it can do the same in the replay!
demo_extradata[playernum] |= DXD_SKIN;
#ifdef HAVE_DISCORDRPC
if (player - players == consoleplayer)
DRPC_UpdatePresence();
#endif
return;
}
+1
View File
@@ -15,6 +15,7 @@
#ifndef __R_SKINS__
#define __R_SKINS__
#ifdef __cplusplus
extern "C" {
#endif
+25 -33
View File
@@ -43,13 +43,6 @@
#define MINZ (FRACUNIT*16)
#define BASEYCENTER (BASEVIDHEIGHT/2)
typedef struct
{
INT32 x1, x2;
INT32 column;
INT32 topclip, bottomclip;
} maskdraw_t;
//
// Sprite rotation 0 is facing the viewer,
// rotation 1 is one angle turn CLOCKWISE around the axis.
@@ -60,8 +53,8 @@ typedef struct
static lighttable_t **spritelights;
// constant arrays used for psprite clipping and initializing clipping
INT16 *negonearray;
INT16 *screenheightarray;
INT16 *negonearray = NULL;
INT16 *screenheightarray = NULL;
//
// INITIALIZATION FUNCTIONS
@@ -94,13 +87,6 @@ static drawseg_xrange_item_t *drawsegs_xrange;
static size_t drawsegs_xrange_size = 0;
static INT32 drawsegs_xrange_count = 0;
INT32 R_ThingLightLevel(mobj_t* thing)
{
INT32 lightlevel = thing->lightlevel;
return lightlevel;
}
//
// Sprite rotation 0 is facing the viewer,
// rotation 1 is one angle turn CLOCKWISE around the axis.
@@ -312,7 +298,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
// store sprite info in lookup tables
//FIXME : numspritelumps do not duplicate sprite replacements
W_ReadLumpHeaderPwad(wadnum, l, &patch, (sizeof(INT16) *4), 0);
W_ReadLumpHeaderPwad(wadnum, l, &patch, PNG_HEADER_SIZE, 0);
spritecachedinfo[numspritelumps].width = (INT32)(SHORT(patch.width))<<FRACBITS;
spritecachedinfo[numspritelumps].offset = (INT32)(SHORT(patch.leftoffset))<<FRACBITS;
spritecachedinfo[numspritelumps].topoffset = (INT32)(SHORT(patch.topoffset))<<FRACBITS;
@@ -546,8 +532,8 @@ void R_ClearSprites(void)
visspritecount = numvisiblesprites = clippedvissprites = 0;
}
static INT16 *vissprite_clipbot[MAXVISSPRITES >> VISSPRITECHUNKBITS];
static INT16 *vissprite_cliptop[MAXVISSPRITES >> VISSPRITECHUNKBITS];
static INT16 *vissprite_clipbot[MAXVISSPRITES >> VISSPRITECHUNKBITS] = {0};
static INT16 *vissprite_cliptop[MAXVISSPRITES >> VISSPRITECHUNKBITS] = {0};
static void R_AllocVisSpriteChunkMemory(UINT32 chunk)
{
@@ -581,16 +567,16 @@ static vissprite_t overflowsprite;
static vissprite_t *R_GetVisSprite(UINT32 num)
{
UINT32 chunk = num >> VISSPRITECHUNKBITS;
UINT32 chunk = num >> VISSPRITECHUNKBITS;
// Allocate chunk if necessary
if (!visspritechunks[chunk])
{
Z_Malloc(sizeof(vissprite_t) * VISSPRITESPERCHUNK, PU_LEVEL, &visspritechunks[chunk]);
R_AllocVisSpriteChunkMemory(chunk);
}
// Allocate chunk if necessary
if (!visspritechunks[chunk])
{
Z_Malloc(sizeof(vissprite_t) * VISSPRITESPERCHUNK, PU_LEVEL, &visspritechunks[chunk]);
R_AllocVisSpriteChunkMemory(chunk);
}
return visspritechunks[chunk] + (num & VISSPRITEINDEXMASK);
return visspritechunks[chunk] + (num & VISSPRITEINDEXMASK);
}
static vissprite_t *R_NewVisSprite(void)
@@ -607,8 +593,8 @@ static vissprite_t *R_NewVisSprite(void)
// Masked means: partly transparent, i.e. stored
// in posts/runs of opaque pixels.
//
INT16 *mfloorclip;
INT16 *mceilingclip;
INT16 *mfloorclip = NULL;
INT16 *mceilingclip = NULL;
fixed_t spryscale = 0, sprtopscreen = 0, sprbotscreen = 0;
fixed_t windowtop = 0, windowbottom = 0;
@@ -737,7 +723,6 @@ static void R_DrawFlippedMaskedColumn(drawcolumndata_t* dc, column_t *column)
dc->texturemid = basetexturemid;
}
// Based off of R_GetLinedefTransTable
transnum_t R_GetThingTransTable(fixed_t alpha, transnum_t transmap)
{
@@ -2249,11 +2234,13 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
}
ds->curline->polyseg->visplane = NULL;
}
if (ds->maskedtexturecol)
{
entry = R_CreateDrawNode(head);
entry->seg = ds;
}
if (ds->numffloorplanes)
{
for (i = 0; i < ds->numffloorplanes; i++)
@@ -2523,8 +2510,6 @@ void R_InitDrawNodes(void)
// R_DrawSprite
//
//Fab : 26-04-98:
// NOTE : uses con_clipviewtop, so that when console is on,
// don't draw the part of sprites hidden under the console
static void R_DrawSprite(vissprite_t *spr)
{
mfloorclip = spr->clipbot;
@@ -2824,6 +2809,7 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal)
if (drawsegs_xrange_size < maxdrawsegs)
{
// haleyjd: fix reallocation to track 2x size
drawsegs_xrange_size = 2 * maxdrawsegs;
for (i = 0; i < DS_RANGES_COUNT; i++)
@@ -2863,6 +2849,9 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal)
}
}
// haleyjd: terminate with a nullptr user for faster loop - adds ~3 FPS
drawsegs_xranges[0].items[drawsegs_xranges[0].count].user = nullptr;
for (; clippedvissprites < visspritecount; clippedvissprites++)
{
vissprite_t *spr = R_GetVisSprite(clippedvissprites);
@@ -3028,7 +3017,7 @@ static void R_DrawMaskedList(drawnode_t* head)
else if (r2->seg && r2->seg->maskedtexturecol != NULL)
{
next = r2->prev;
R_RenderMaskedSegRange( r2->seg, r2->seg->x1, r2->seg->x2);
R_RenderMaskedSegRange(r2->seg, r2->seg->x1, r2->seg->x2);
r2->seg->maskedtexturecol = NULL;
R_DoneWithNode(r2);
r2 = next;
@@ -3067,6 +3056,9 @@ void R_DrawMasked(maskcount_t* masks, INT32 nummasks)
heads = static_cast<drawnode_t*>(calloc(nummasks, sizeof(drawnode_t)));
if (!heads)
I_Error("R_DrawMasked: No more free memory\n");
for (i = 0; i < nummasks; i++)
{
heads[i].next = heads[i].prev = &heads[i];
+8 -5
View File
@@ -23,10 +23,10 @@ extern "C" {
// number of sprite lumps for spritewidth,offset,topoffset lookup tables
// Fab: this is a hack : should allocate the lookup tables per sprite
#if defined(__x86_64__) || defined(__amd64__) || defined(__aarch64__) || defined(__arm64__) // only for 64bit (idk how else to proper check lmao)
#define MAXVISSPRITES 4096
#else
#if __SIZEOF_POINTER__ < 8
#define MAXVISSPRITES 2048 // added 2-2-98 was 128
#else
#define MAXVISSPRITES 4096 // only for 64bit
#endif
#define VISSPRITECHUNKBITS 6 // 2^6 = 64 sprites per chunk
@@ -63,7 +63,10 @@ extern fixed_t windowtop;
extern fixed_t windowbottom;
extern INT32 lengthcol;
INT32 R_ThingLightLevel(mobj_t *thing);
FUNCINLINE static ATTRINLINE INT32 R_ThingLightLevel(mobj_t* thing)
{
return (INT32)thing->lightlevel;
}
fixed_t R_GetSpriteDirectionalLighting(angle_t angle);
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
@@ -83,7 +86,7 @@ typedef struct
{
size_t drawsegs[2];
size_t vissprites[2];
fixed_t viewx, viewy, viewz; /**< View z stored at the time of the BSP traversal for the view/portal. Masked sorting/drawing needs it. */
fixed_t viewx, viewy, viewz; /**< View z stored at the time of the BSP traversal for the view/portal. Masked sorting/drawing needs it. */
sector_t* viewsector;
} maskcount_t;
Loaded 100 of 114 files, more files were not shown because too many files have changed in this diff. Show more