Compare commits

..
298 Commits
Author SHA1 Message Date
Alug 54cbfbe699 forgor ifdef here 2024-11-03 15:33:26 +01:00
Alug 05f454157f Merge pull request #138 from Indev450/Saturn-Next
Saturn v7.2
2024-11-03 16:24:00 +01:00
Alug c451f0f1a6 windoze 2024-11-03 14:23:26 +01:00
Alug 35b85bec36 bleh pls 2024-11-03 14:18:59 +01:00
Alug b0c64be31d try to simplify this alteast a little
shit is awful
2024-11-03 03:40:55 +01:00
Alug d09a28e3da missed this 2024-11-03 03:13:15 +01:00
Alug 550c66b25b add some more checks for this 2024-11-03 02:59:23 +01:00
Alug dfec9e24f3 add just a little more extra safety for fbo 2024-11-03 02:44:42 +01:00
indev 2350889445 Fix normal skin being unable to load if localskins limit is reached (thx Alug for pointing out <3) 2024-11-03 00:26:18 +03:00
indev 990854e176 Fix localskins being unable to load if normal skin limit is reached 2024-11-03 00:16:15 +03:00
Alug 8c727b979c initialise this to null aswell
just in case
2024-11-02 14:19:53 +01:00
Alug 60de48ad65 add accurate fps counter crap to menu + rename it to force it back on
since shit more or less was broken in saturn before and always showed the more accurate one, force it again since stuff caused confusion
2024-11-02 12:57:17 +01:00
Alug 2fd1abce5c v7.2 2024-11-02 01:20:02 +01:00
Alug 691a61de72 oops 2024-11-02 01:12:56 +01:00
Alug 3a153c3abe Merge pull request #137 from Indev450/refactorogl
Cleanup and slightly refactor ogl files
2024-11-02 00:57:49 +01:00
Alug d22645e56a use a "-" here for consistancy 2024-11-02 00:50:28 +01:00
Alug 08fe3beef1 respect cv_showdirectorhud 2024-11-02 00:49:35 +01:00
Alug 2c54c92e14 spec cam disables director, but you can toggle it from speccam
uhhhhhhh
2024-11-02 00:49:32 +01:00
Alug c127cd9016 fix wanted reticle offsets
Zzz...
2024-11-01 20:29:33 +01:00
Alug 9cb790ac23 oops broke encore 2024-11-01 20:01:50 +01:00
Alug c2c7381bc1 use precalced minimap stuff for v.drawOnMinimap 2024-11-01 19:55:23 +01:00
Alug 1e4eeb2bcf fix some issues with cv_minihead and minimap icon drawing 2024-11-01 19:55:20 +01:00
Alug b1f99f8d2f fix minimap not being initialised
causes issues when you switch to maps that dont have a minimap
2024-11-01 18:39:36 +01:00
Alug f752da7d03 formatting stuff lul 2024-10-31 12:02:48 +01:00
Alug 7ddcf6d0d4 Merge branch 'Saturn-Next' into refactorogl 2024-10-31 11:59:33 +01:00
indev b21776183e Add shift+insert shortcut for pasting text 2024-10-30 22:14:17 +03:00
indev 9c0dcac5c6 Fix mapmusname global in lua being renamed to (*mapmusname) 2024-10-30 19:21:07 +01:00
indev 1b75d8b8e2 Fix mapmusname global in lua being renamed to (*mapmusname) 2024-10-30 20:35:17 +03:00
Alug 145e305494 Merge branch 'Saturn-Next' into refactorogl 2024-10-30 16:04:06 +01:00
Alug 8f4d185ea6 Revert "use highly optmized (but slightly inaccurate) version of R_PointOnSide for rendering"
This reverts commit 9314a24cb2.
2024-10-30 16:03:35 +01:00
Alug 4b5ff6be5d Merge branch 'Saturn-Next' into refactorogl 2024-10-30 15:34:43 +01:00
Alug d27ef85b9e remove some unused stuff in portal struct 2024-10-30 13:52:06 +01:00
Alug 1ac210c2fc improve ogl portal clipping 2024-10-30 13:05:30 +01:00
Alug 878b7f4b43 fix portal culling 2024-10-28 20:25:03 +01:00
Alug 7cbac66935 throw this into an inline func 2024-10-28 20:25:01 +01:00
Alug 7e09223e6e gu 2024-10-28 16:36:04 +01:00
Alug b4e1be5bee dont always call HWR_Startup again 2024-10-28 16:35:44 +01:00
Alug d3e5e236ac those do nothing 2024-10-28 16:34:40 +01:00
Alug 238ce98c44 dont always call HWR_Startup again 2024-10-28 07:21:13 +01:00
Alug 2824e5d850 no need to update this witouth water ripples 2024-10-28 06:49:09 +01:00
Alug cd154d5748 grey out some stuffs in the ogl and advanced video menus 2024-10-28 06:40:23 +01:00
Alug c0a8153a10 sort those a bit 2024-10-28 06:40:19 +01:00
Alug 3433fc7651 those should be disabled 2024-10-28 06:40:17 +01:00
Alug 22d1ee8f60 move CV_PossibleValue_t to their own section like other files 2024-10-28 06:40:14 +01:00
Alug 5155958ade add "gl" to secbright and lightdither cvars
theyre only used in ogl so follow the naming convention
2024-10-28 05:40:59 +01:00
Alug 5fdd486bab reorder all of this to be in same order lol 2024-10-28 05:40:56 +01:00
Alug 4672037bcd check if those are already off before trying to turn them off lol 2024-10-28 05:40:54 +01:00
Alug 2281b82b5a replace last remaining "gr" 2024-10-28 04:28:25 +01:00
Alug 3fe096c7d4 gr -> gl
this has been annoying me since ages lol
2024-10-28 04:23:15 +01:00
Alug dd3ca0e161 change cvar register order for ogl stuff 2024-10-28 03:39:05 +01:00
Alug d8da78f900 more cleanup 2024-10-28 03:38:52 +01:00
Alug 9325e7be8f make a bunch of hwr stuff static and cleanup 2024-10-28 03:38:48 +01:00
Alug f3f94bf80e fr*nch 2024-10-28 03:38:36 +01:00
Alug 506dc2455a fr*nch 2024-10-26 23:24:01 +02:00
Alug 94d6ee15b5 this should be portalcullsector lol 2024-10-26 19:44:32 +02:00
Alug 2d918d32a1 reduce the scope of this since not needed 2024-10-26 19:44:28 +02:00
Alug dd516b573b rename this to avoid confusion 2024-10-26 19:31:14 +02:00
Alug de9698efc8 just use the same as software lol
i never saw any differernce except in performance for this
also viewsin and viewcos get calced in r_fps so no need to do here again
2024-10-26 19:29:53 +02:00
Alug 14b026f04b slight cleanup ogl portals again 2024-10-26 19:29:51 +02:00
Alug 9dd45440c0 rename and slight cleanup 2024-10-26 19:29:46 +02:00
Alug c59e8387ca smth smth shadows a global declaration 2024-10-26 19:29:35 +02:00
Alug 772ad9f04f throw ogl portals into their own files 2024-10-26 19:29:32 +02:00
Alug 6053c2c619 readd mobj null check here 2024-10-26 16:40:08 +02:00
Alug a515b133c5 inline this since its super smol 2024-10-26 16:40:04 +02:00
Alug 240dae9a1a move chasecam postimg stuff into own function + add comments for what stuff does lol
shit got me really confused
2024-10-26 16:12:43 +02:00
Alug b8a703233a forgor to remove this 2024-10-26 00:51:58 +02:00
Alug bf44c95d00 clean up portals 2024-10-26 00:51:55 +02:00
Alug c3dd1755dc port srb2 software portal refactor 2024-10-26 00:51:44 +02:00
indev b6e766ee44 Fix A_Lua not removing error handler from lua stack 2024-10-25 23:15:52 +03:00
Alug 5437040b78 move the return ealier in V_DoPostProcessor 2024-10-25 20:21:10 +02:00
Alug c786569981 Merge branch 'refactorpostimg' into Saturn-Next 2024-10-25 20:12:56 +02:00
Alug 7064b14539 Merge branch 'autoloadagain' into Saturn-Next 2024-10-25 20:12:53 +02:00
Alug f275ae98f5 this is needed for postimg stuff in first person
lol
also adds break in splitscreen lööp
2024-10-25 20:12:14 +02:00
Alug ef07d89e29 Revert "update lzf compression to 1.6"
This reverts commit 48e71afec1.
2024-10-25 19:50:16 +02:00
Alug b9bbd45e15 Revert "shut up mingw"
This reverts commit 75637e361c.
2024-10-25 19:50:10 +02:00
Alug 2bda27b80d Revert "those should be size_t"
This reverts commit b357c09171.
2024-10-25 19:49:26 +02:00
Alug 6ebf90cc50 Merge branch 'Saturn-Next' into autoloadagain 2024-10-25 03:28:43 +02:00
Alug ea00bebb04 Merge branch 'Saturn-Next' into refactorpostimg 2024-10-25 03:28:20 +02:00
Alug b862d835a5 save one calc lol 2024-10-25 03:27:51 +02:00
Alug d6602747ae oops forgor lol 2024-10-25 03:26:22 +02:00
Alug 9f79429d03 slight cleanup + make static + smol optimize ogl sprite drawers 2024-10-25 03:26:19 +02:00
Alug 5ff0c09868 just check for noencore bool in hwr_processseg instead of checked line flags everytime 2024-10-23 21:33:31 +02:00
Alug ad1c3e63a4 why not reuse those? 2024-10-23 21:33:28 +02:00
Alug 24dd6ba675 cleanup HWR_ProcessSeg
stuff was quite the mess
2024-10-23 21:33:21 +02:00
Alug 85f036a45b dont always calc this twice 2024-10-23 21:33:14 +02:00
Alug 6f8342b9a8 remove cv_splitwallfix
tbh i dont think anyone even knows about this, never heard any complains, never had any issues, neither visually or performancewise.
its just clutter at this point
2024-10-23 21:33:04 +02:00
Alug c5c6f6b820 this does nothing 2024-10-23 21:30:21 +02:00
Alug 3d472c34a1 no need to check stuff in already postload marked addons 2024-10-23 15:48:44 +02:00
Alug 63ca366bd8 dont play rain sounds when weather is disabled 2024-10-23 13:00:36 +02:00
Alug e9e888ab7f remove debug print 2024-10-23 02:41:28 +02:00
indev 5ea55b3e3a Add W_CheckFileContains for W_CheckPostLoadList 2024-10-23 02:41:25 +02:00
Alug 8b1797927a attempt to check for things in file for postload detection 2024-10-23 02:41:23 +02:00
Alug 05a98964fb split auto and postload, let autoload run on gamestart again
prep for smth
2024-10-23 02:41:20 +02:00
Alug 8cbf798de8 redo rain sound overflow fix
https://git.do.srb2.org/KartKrew/RingRacers/-/commit/3eac1fed0f44a8285a9f6b82a12e86997bbb0d34
2024-10-23 02:37:32 +02:00
Alug 9314a24cb2 use highly optmized (but slightly inaccurate) version of R_PointOnSide for rendering 2024-10-23 02:37:08 +02:00
Alug 19b1683e61 make those not look terrible thx 2024-10-22 01:18:13 +02:00
Alug d029107e75 refactor postimg stuff so it can be combined with each other better
thx much indev! <3
everything now works with encore!
software now also supports screen effects in splitscreen!
2024-10-22 01:17:57 +02:00
Alug bc97e0b703 actually remove "renderflags" lol 2024-10-21 22:53:44 +02:00
Alug f47c663f79 remove renderflags
those literally did nothing
2024-10-21 22:47:32 +02:00
Alug 6f9d41eadb fix R_ThingVisible
those are "eflags" in kart smh
2024-10-21 22:46:59 +02:00
Alug 1b512edc56 add proper null check here too 2024-10-21 21:28:08 +02:00
Alug 884a6da2bd dont use cv_sloperolldist in splitscreen + save some assignments and one fixedhypot call
also use tabs lul
2024-10-21 21:07:32 +02:00
Alug 7a3d958fc1 tab pls 2024-10-21 18:43:08 +02:00
Alug 7223581539 Clarify we're calculating a cross product 2024-10-21 18:10:29 +02:00
Alug 664bd2de3f dont draw fadescreen when minimap iss active 2024-10-21 17:47:44 +02:00
indev 63568e3861 Fix off-by-one error for using '?' as map name 2024-10-21 18:43:37 +03:00
indev f149d058a1 Fix off-by-one error in lib_setSfxInfo 2024-10-21 18:06:35 +03:00
Alug 970251ced3 also check here ig? 2024-10-21 17:01:27 +02:00
Alug dba7a7dc3c prevent map command crash from maps with invalid or non existing mapinfo 2024-10-21 15:37:44 +02:00
Alug 393c0be407 Revert "attempt to optimize some p_maputl stuff"
This reverts commit 81d415c5ba.
2024-10-21 14:19:35 +02:00
Alug 5e9ea2429b replace those two P_MobjWasRemoved with simple null check insteead
since those may actually segfault if null anyways
2024-10-21 06:23:14 +02:00
Alug 81a14995da trailing space hell 2024-10-21 06:14:24 +02:00
Alug 4267ac9a8d remove more P_MobjWasRemoved checks
same as before, those may be not synchsafe
2024-10-21 06:04:47 +02:00
Alug bcf72cc0e8 revert some P_MobjWasRemoved checks i forgor about
those may NOT be vanilla netsafe
2024-10-21 06:04:17 +02:00
Alug 54d9a98090 rotsprite stuff also should be SHORT 2024-10-20 19:11:54 +02:00
Alug 81d415c5ba attempt to optimize some p_maputl stuff 2024-10-20 16:25:12 +02:00
Alug de1b801bda try to take some registers for span drawers too 2024-10-20 16:24:02 +02:00
Alug 2c665fef6f remove this again 2024-10-20 15:21:42 +02:00
Alug c6fbf405bf optimize R_PointOnSegSide
its only used for 2 rendering functions, so being potentially inaccurate is not that dangerous and the speedup in some instances might be worth the tradeoff
2024-10-20 15:16:37 +02:00
Alug 7076c35521 HWR_RenderPlane can be static 2024-10-20 14:57:28 +02:00
Alug 86ed1b709e fix some rendering issues and crashes in software renderer
- Increase MINZ from 4 fracunits to 16
- R_StoreWallRange: do not render textures with holes
- fix off-by-one error in R_ProjectSprite
- Avoid rendering unused left/right edges of screen while rolling
- Clamp patch column post drawing bounds
- Vissprites: set dc.texheight
- Add null check for column in R_DrawMaskedColumn
2024-10-20 14:57:22 +02:00
Alug 0be25bd362 Merge branch 'Saturn-Next' into Saturn 2024-10-20 14:56:56 +02:00
Alug d30c96e8cb fix a maybe-uninitialized warning 2024-10-20 00:22:06 +02:00
Alug 0af52ba3ae dont need to always check this 16 times if we already know theres more than one player ingame 2024-10-19 21:15:11 +02:00
Alug fbe97556de change versionstring
also remove the fbo one, its honestly not necessary anymore
2024-10-18 20:36:16 +02:00
Alug 7a6f43bece dont show encore toggle text in record attack menu
dont think you can even record attack in encore hmm
2024-10-18 20:34:22 +02:00
Alug afca521fe5 dont run director if theres only one player ingame
idk if this is good lol
2024-10-18 19:53:44 +02:00
Alug d3e2875c94 those can be registered in lööp 2024-10-16 13:14:31 +02:00
Alug 1daac9a124 revert all the cam things for now here
Dont wanna deal with this shit for 7.1 anymore
2024-10-14 22:15:27 +02:00
Alug 38f3e48aed only do this in software renderer
doesent work even with pal rendering in ogl
2024-10-13 23:07:37 +02:00
indev 4cf4d49f48 Fix error handler staying on lua stack after lua commands being called 2024-10-13 15:37:39 +03:00
indev a19c4dc5e5 Fix game crashing when using P_DoPlayerExit on player without mobj 2024-10-13 15:37:39 +03:00
Alug d37505ff06 this should be SHORT 2024-10-13 02:59:10 +02:00
Alug 7f6ce1f299 this uhhh actually makes things crash lol 2024-10-13 02:47:57 +02:00
Alug 262a84aac6 fix ogl shearing
no clue wtf kart was doing here lmao
2024-10-13 02:42:37 +02:00
Alug 3f12ebb2bd only interp cam during pause for replay freecam to not jitter during pause 2024-10-13 01:11:59 +02:00
Alug b58fcf331c ignore keepmusic when called from P_RestoreMusic
most of the sound handling just calls this and this may just stop the music entirely on some occasions so just ignore keepmusic for that
2024-10-13 00:40:51 +02:00
Alug fe51278295 Merge branch 'newmusicstuff' into Saturn-Next 2024-10-13 00:04:59 +02:00
Alug c3fb84981e Merge branch 'pakcheck' into Saturn-Next 2024-10-13 00:02:32 +02:00
Alug 919aad4f30 Merge branch 'vres-skip-map-marker' into Saturn-Next 2024-10-12 23:57:27 +02:00
Alug 818e6046b7 Merge branch 'Saturn-Next' into vres-skip-map-marker 2024-10-12 23:30:03 +02:00
Alug f01d2a0ba6 print saturnpak print into debfile instead of console 2024-10-12 23:29:11 +02:00
Alug 8df0a2d059 Merge branch 'Saturn-Next' into pakcheck 2024-10-12 23:28:05 +02:00
Alug d7ed91af1d Refactor TTY input handling
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2451#b2f76b3273f1780347c35ec752bcde560c5f73a5
2024-10-12 23:26:14 +02:00
Alug 081dcc021b fix tty converting everything to lowercase 2024-10-12 23:21:11 +02:00
Alug 70ebd0d475 Merge remote-tracking branch 'origin/unified-text-input' into Saturn-Next 2024-10-12 23:19:38 +02:00
Alug 02bbb38606 Fix insane TTY input latency
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2360
2024-10-12 23:16:42 +02:00
indev d00014ea59 If corrupted save received, leave netgame 2024-10-12 22:10:58 +02:00
indev 210d6ac8ac Add few checks to prevent game crashing if netgame archive becomes corrupted 2024-10-12 22:10:48 +02:00
indev 55248e7fcf Attempt to fix a lua panic when unarchiveing extvars (print error to console instead. Not sure if it would be safe for game to read from save afterwards though) 2024-10-12 22:09:51 +02:00
Alug 23b36b5074 oops 2024-10-12 21:29:49 +02:00
Alug 2e7f0721b9 make s_sound a little prettier 2024-10-12 21:24:43 +02:00
Alug 4927e55c7e fix some warnings when compiling with older sdl version 2024-10-12 21:24:04 +02:00
Alug c51d33fa6e save 1 G_BuildMapTitle call kek 2024-10-12 20:19:53 +02:00
Alug 8630d8cd47 clean bird music stuff again
we dont need to return everywhere but instead stuff can be mostly just set to 0
this also somewhat ensures stuff works after toggling without having to restart the game or map
2024-10-12 19:55:02 +02:00
Alug 659243baa1 always assign stutter_threshold 2024-10-12 19:44:21 +02:00
Alug b6a84c1646 readd music_resync_powerups_only 2024-10-12 19:40:12 +02:00
Alug c33afa4a3b shut up mingw 2024-10-11 19:09:49 +02:00
Alug 1428c3c2bf fix spec cam bug + more cleanup 2024-10-11 21:00:13 +02:00
Alug aa0cbfda74 Revert "rendertimefrac_unpaused should be fracunit on netlag"
This reverts commit 6722b43244.
2024-10-09 15:33:19 +02:00
Alug 9d13ff3c9f proper inline P_MobjWasRemoved 2024-10-07 23:01:52 +02:00
Alug e47c13b7ac proper inline M_Memcpy 2024-10-07 23:01:45 +02:00
Alug 3f5b96bd45 this shouldnt be here lol 2024-10-07 13:15:08 +02:00
Alug 63c1372c34 keep debug print for now 2024-10-07 12:57:55 +02:00
Alug 8b915f9ac1 make this less ugly 2024-10-07 12:53:31 +02:00
Alug f3a18a0655 false 2024-10-07 12:48:36 +02:00
Alug e8351d44b6 add crap to menu 2024-10-07 12:45:03 +02:00
Alug 297af069cb doubt anyone wants this
also psure this will cause some weird issues somewhere idk
2024-10-07 12:41:59 +02:00
Alug baa5d6630d Merge branch 'Saturn-Next' into newmusicstuff 2024-10-07 12:39:41 +02:00
Alug 0c30730ef6 Merge branch 'Saturn-Next' into pakcheck 2024-10-06 18:52:24 +02:00
Alug c82148fafc prevent this from become super large somehow lol
just like cap it at 19 it works just fine
2024-10-06 18:50:32 +02:00
Alug d1346dee53 shouldnt that be a bool? 2024-10-06 18:31:54 +02:00
Alug 6722b43244 rendertimefrac_unpaused should be fracunit on netlag
makes this a little more sane tbh
2024-10-06 18:31:51 +02:00
Alug cfdbf1f4ad hopefully fix awayview cam interp crap 2024-10-06 14:53:10 +02:00
Alug 48a00ba911 this needs to be set twice
Zzz...
2024-10-06 14:52:54 +02:00
Alug 4b1102357a only do this in replays
otherwise shit will jitter during netlag
2024-10-06 14:46:11 +02:00
Alug e3b0204b2c fix main menu interpolation
apparently in main menu, opening the menu pauses the game so rendertimefrac was FRACUNIT and didnt interpolate
2024-10-06 14:46:06 +02:00
Alug a2799ddcca Interpolate view, even when paused
https://github.com/KartKrewDev/RingRacers/commit/3320faec8cebecb124882d38c7ec0ad37b79340a#diff-607b68058edc6124b3061267d902aabeddb6ba338c6483df0af8b1a7cf796a01R43
2024-10-06 14:46:03 +02:00
Alug 76198f61de add missing break 2024-10-06 14:45:50 +02:00
Alug ff2006ad74 smol fix 2024-10-06 12:40:01 +02:00
Alug 55c9c7297f throw this into own function too 2024-10-06 12:39:56 +02:00
Alug 4b083ee72e make function for quakes, scale with mobjscale 2024-10-06 12:39:54 +02:00
Alug 6574ec2fb9 attempt to cleanup R_SetupFrame 2024-10-06 12:39:48 +02:00
Alug f54bb349b5 add G_FixCamera 2024-10-06 12:39:44 +02:00
Alug 6f1252e27d set timeinmap for demo rewind
idk maybe this helps with that feature desynching all the time lol
2024-10-06 12:39:26 +02:00
Alug 7d65b5369f add some brackets lul 2024-10-06 12:34:51 +02:00
Alug 4877c81728 comment this out for now so v7 clients dont use vanilla resynch system
keep sending PT_WILLRESENDGAMESTATE packets to everyone for now
saturnpak will still mark the right clients so they will use the right consistency check without having to desynch first
2024-10-06 12:32:57 +02:00
Alug 5cb207edfa add debfile prints whenever gamestate counter changes 2024-10-06 12:14:32 +02:00
Alug fc39a0dedf make the debug print a little better 2024-10-06 12:12:59 +02:00
Alug 0b3e7240a8 use saturn packet to determine if client can receive gamestate
before the server always assumed every client cant receive the gamestate using the vanilla consistency check for everyone.
aswell as before the first resynch it tried to send the gamestate resend packets to everyone
2024-10-06 12:07:17 +02:00
Alug f32c346534 this needs gamestate check
sometimes the title music kept playing
2024-10-05 06:56:31 +02:00
Alug 3165004d0e add comment to try and explain this crap 2024-10-03 18:15:19 +02:00
Alug ec3b1cf130 make this more readable 2024-10-03 17:55:08 +02:00
Alug a0437713bf smol dupe 2024-10-02 14:40:03 +02:00
Alug 96f7ff550c prevent this from overflowing
ye well idk anymore.
2024-10-02 14:22:48 +02:00
Alug 837216d78e we dont need any of this in ogl 2024-10-02 14:22:39 +02:00
Alug dfb6006f9c fix up old fps counter 2024-10-02 12:14:40 +02:00
indev fb0765a5f3 Fix selection in replay save prompt 2024-10-01 20:55:27 +03:00
indev 2e8769496f Use textinput_t for replay save prompt too 2024-10-01 20:39:04 +03:00
Alug bdb39fcd8d dont leak pls 2024-10-01 17:57:45 +02:00
Alug 31516c7987 fix G_BuildMapTitle leaks 2024-10-01 17:56:15 +02:00
Alug b985ce06a2 lol 2024-10-01 16:03:56 +02:00
Alug 12d6546062 dumb special case for wandering balls Zzz... 2024-10-01 16:03:00 +02:00
indev fb71da3627 Remove debug print 2024-10-01 16:50:44 +03:00
indev a90ffff320 Fix (hopefully) all other menu types that use IT_CV_STRING 2024-10-01 16:49:59 +03:00
Alug 9abf2bca75 fix some stuff 2024-10-01 15:46:22 +02:00
indev 3db6770dfd Fix IT_CV_STRING crashing game in M_DrawGenericMenu 2024-10-01 16:24:14 +03:00
Alug 3a951576ee use stricmp for this 2024-10-01 15:22:29 +02:00
Alug 6b0d67ac36 more 2024-10-01 15:22:25 +02:00
Alug d06b8ac398 cleanup + comments 2024-10-01 15:22:22 +02:00
Alug 67435ebf9e work around encore music again
S_InitMapMusic would play before the level actually started thus playing a smol bit of non encore music in encore
2024-10-01 15:22:19 +02:00
Alug 2ee29630fb fix encore music again lol 2024-10-01 15:22:16 +02:00
Alug 7fa21e9aea work around custom vote theme music + rename a bunch of stuff
please help me
2024-10-01 15:22:08 +02:00
Alug b4b206f575 encoremusic... 2024-10-01 15:22:04 +02:00
Alug f363663b3e fix up everything and make stuff work
i hope lmao
2024-10-01 15:22:01 +02:00
Alug 42d957e21b change how keepmusic works
compare map and encore instead of the music itself
2024-10-01 15:21:57 +02:00
Alug 07f9756bc8 forgor about encore music 2024-10-01 15:21:54 +02:00
Alug e958e43b49 update comments a little 2024-10-01 15:21:51 +02:00
Alug 0d150e4b08 add some basics of what i wanna have for music stuff
- basic keepmusic implementation (currently checks for if the song changes instead of the map, idk if i keep this, since this allows certain maps to change the music on start, ex abstract avenue or wandering balls)
- Toggle to ignore any kind of music change during the level (includes intermission music, depends on how custom intermission music works)
-toggle to start map music instantly on levelload and skip the intro fanfare (also skips any linedef executed sound so some map intros dont interfere with this)
2024-10-01 15:21:47 +02:00
Alug 0deff73a46 make a function for the music level start stuff 2024-10-01 15:21:43 +02:00
Alug b24caf397a add "map ?" shortcut for random map 2024-10-01 14:49:46 +02:00
Alug f051e33a0c cv_showdirectorhud didnt save Zzz... 2024-09-30 23:00:39 +02:00
indev ff2b28ac73 Use m_textinput for chat too 2024-09-30 12:13:25 +03:00
indev e2367d26d1 Use same keyboardlayout code as in chat for textinput, also add a null terminator after ctrl-v just in case string is not always zeroed out already 2024-09-30 12:08:21 +03:00
indev e1a65add5d Put all text input logic into separate file and use it for all text input fields 2024-09-30 10:35:27 +03:00
Alug 913426bfdb let SOC also use PRECIP_BLANK/ weather = 4
no idea why it couldnt doesent make any sense
2024-09-29 22:28:35 +02:00
Alug d7b0726e42 no need to even traverse part of the blockmap when PRECIP_STORM_NORAIN and PRECIP_BLANK 2024-09-29 22:28:31 +02:00
Alug cadb67e6c9 move this stuff
so dont need check for renderisnewtic multiple  times and dont need to check for menu and dpad stuff every single frame
2024-09-29 15:15:53 +02:00
Alug 564838a439 only draw lua hud stuff when patch exists 2024-09-29 15:15:49 +02:00
Alug 4554bcc565 reset rumble on some conditions 2024-09-28 03:29:12 +02:00
Alug fd48335688 Replace portalline boolean with g_portal pointer to current portal Beta 2024-09-28 03:29:09 +02:00
Alug 222f56d1b2 smol director stuffs 2024-09-28 01:03:44 +02:00
Alug b71870f57b this needs no dedi check actually 2024-09-28 01:03:41 +02:00
Alug 01c9632025 set those in P_SpawnGhostMobj too 2024-09-28 01:03:39 +02:00
Alug 1533e13d68 let player pointer be const in P_IsLocalPlayer and P_IsDisplayPlayer 2024-09-28 01:03:34 +02:00
Alug 89965ad718 forgor remove this 2024-09-28 01:03:31 +02:00
Alug eb74f3525a consolidate this 2024-09-28 01:03:29 +02:00
Alug 536f88dee0 this does nothing 2024-09-28 01:03:26 +02:00
Alug 2622ba286e z 2024-09-28 01:03:18 +02:00
Alug a1d490cb49 R_DrawMaskedColumn: do not draw zero length column 2024-09-28 01:03:15 +02:00
Alug b357c09171 those should be size_t 2024-09-28 01:03:11 +02:00
Alug 48e71afec1 update lzf compression to 1.6 2024-09-28 01:03:08 +02:00
Alug 1c6fce9339 fix encore minimap 2024-09-27 15:05:38 +02:00
Alug 96551d3b75 use qs22j here again
it is really faster
thought it wasnt in this case
2024-09-27 15:05:34 +02:00
Alug 7a832df4d3 cleanup + reformatting 2024-09-27 15:05:31 +02:00
Alug c3b6121968 forgor this 2024-09-27 15:04:15 +02:00
Alug b3b2b65c5f reformat this 2024-09-27 15:04:12 +02:00
Alug 7a3ccec38d ; 2024-09-26 18:18:42 +02:00
Alug d8da0a11a2 gamestate resend counter was never proper reset for nodes
means it would carry over to the next person occupieing that node and made them have less chances to get the gamestate resent
2024-09-25 19:31:25 +02:00
Alug d5c3332635 those can be static 2024-09-24 22:23:29 +02:00
Alug 0137f2254d add toggle for water ripples Zzz... 2024-09-24 22:18:27 +02:00
Alug da769ce524 only allow director toggling with button when you spec someone 2024-09-24 16:57:25 +02:00
Alug 2e99636bb0 make director text disappear after 13 seconds, and in replays after 4 2024-09-24 15:25:56 +02:00
indev ff7f68f5b4 Expose demo.freecam as replayfreecam 2024-09-24 16:05:22 +03:00
Alug 14eec0c902 dont show director text when in replay freecam 2024-09-24 15:03:31 +02:00
Alug b064c534d8 hide viewpoint text when in replay freecam 2024-09-24 15:03:28 +02:00
Alug e7c0f322ee dont show driftgauge when in replay freecam 2024-09-24 15:03:14 +02:00
Alug 725754c427 dont run director when you use spectator freecam 2024-09-24 15:03:07 +02:00
Alug 9a6c0a0280 check vres data before freeing it 2024-09-23 23:13:08 +02:00
Alug 26d8c05ce7 forgor some casting 2024-09-23 23:13:05 +02:00
indev 91a9f20af7 Skip map marker in vres_GetMap 2024-09-24 00:08:48 +03:00
indev 90745d91aa Add showdownloadprompt cvar, so addon download prompt can be disabled 2024-09-23 23:39:25 +03:00
Alug 0dbae34998 completely forgor to revert this lol 2024-09-23 15:53:05 +02:00
Alug eec93b8013 Revert "beta hud driftgauge"
This reverts commit 26e8c2ca2b.
2024-09-23 01:35:14 +02:00
Alug cfe3f01b32 Revert "extra check"
This reverts commit 0bb1efcd50.
2024-09-23 01:35:11 +02:00
Alug 43452e1af4 dont actually call Nullprecipthinker 2024-09-23 01:03:59 +02:00
Alug a4706e0785 read precip row in perfstats 2 2024-09-23 01:03:24 +02:00
Alug c921ab463c dont count precip towards thinkers in perfstats 2024-09-23 01:03:20 +02:00
Alug 892816dadf fix precip performance issuess on certain maps 2024-09-23 01:03:17 +02:00
Alug e7e1fd711e dont check consistency/attempt to resend the gamestate while a client is currently getting the save resend
perhaps that makes mass synchs less bad
2024-09-22 22:16:21 +02:00
Alug ba5459eeb6 Revert "clean up leveload a bit"
This reverts commit c14af4a136.
2024-09-22 17:52:26 +02:00
Alug 0bd9c696df try to prevent unknown packet type spam when client attempt to connect while levelloading 2024-09-22 16:53:31 +02:00
Alug c14af4a136 clean up leveload a bit 2024-09-22 16:53:25 +02:00
Alug 8dfa841a7b Load palette before map data 2024-09-22 16:52:07 +02:00
Alug a6de843c75 cleanup r_draw8 2024-09-22 16:52:04 +02:00
Alug 0bb1efcd50 extra check 2024-09-22 04:14:31 +02:00
Alug 26e8c2ca2b beta hud driftgauge
eh needs some stuff for menu still
also should replace driftgauge gfx sometime
2024-09-22 04:13:53 +02:00
Alug 12ffca7374 precalc automap and minimap stuff on mapload instead of every frame 2024-09-22 04:13:02 +02:00
Alug 6ecf65d83a Merge remote-tracking branch 'origin/Saturn-Next' into Saturn-Next 2024-09-21 16:03:17 +02:00
Alug 231c173545 move this so speccing resets your laptime 2024-09-21 16:03:13 +02:00
Alug f12b7fd772 move this 2024-09-19 12:41:40 +02:00
Alug 14ea041c72 always reset cam subsector regardless of splitscreen 2024-09-18 12:11:14 +02:00
Alug 6fb804292c Prevent integer div by 0 in curl progress callback 2024-09-18 01:07:43 +02:00
Alug f77f7361a9 this also does nothing 2024-09-18 01:06:54 +02:00
Alug d6d19d5dab smol cleanup 2024-09-18 01:02:42 +02:00
Alug 8074bfacb6 this does nothing 2024-09-18 00:58:37 +02:00
Alug f5f7b99479 Fix crash if a packet fails to reach the client
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2480 but keeps the returns;
2024-09-17 21:02:05 +02:00
Alug f0a8c27829 Fix crash when trying to send to an unreachable client
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2232
2024-09-17 20:58:23 +02:00
Alug 30024f2341 this is the correct value 2024-09-17 19:47:30 +02:00
Alug ff0dcafeea make ticcmds on gamestateresend
resynch will still stop making em
should hopefully fix some weird issues where you might end up somewhere weird if the resend takes a little longer
2024-09-17 16:47:34 +02:00
Alug 8580451bce properly reset all splitscreen cameras on resynch
also fix some casting
2024-09-17 16:47:31 +02:00
Alug d867868854 Revert "dont run playerjoin hook on resynch"
This reverts commit 5f7bf4164d.
2024-09-17 16:43:25 +02:00
indev b1644d4817 Ignore case here 2024-09-17 17:23:16 +03:00
indev a9a3a04379 Add proper skin search in skin command 2024-09-17 17:16:35 +03:00
Alug 7ac9f0cbef dont rerun mapload hook on resynch 2024-09-16 00:54:29 +02:00
Alug 5f7bf4164d dont run playerjoin hook on resynch 2024-09-16 00:54:26 +02:00
Alug 43690c9b2c fix sound bug lol 2024-09-16 00:08:21 +02:00
Alug 02c14bfa5c Merge branch 'Saturn' into Saturn-Next 2024-09-16 00:08:11 +02:00
105 changed files with 6248 additions and 5662 deletions

No files matched your search

+1
View File
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := am_map.c \
m_cheat.c \
m_fixed.c \
m_menu.c \
m_textinput.c \
m_misc.c \
m_queue.c \
m_random.c \
+555 -551
View File
File diff suppressed because it is too large. Load diff
+11 -9
View File
@@ -213,9 +213,9 @@ DOSATURNSYNCH=1
ifndef NOSATURNJOIN
DOSATURNJOIN=1
endif
#ifndef NOSATURNPAK
#DOSATURNPAK=1
#endif
ifndef NOSATURNPAK
DOSATURNPAK=1
endif
endif
endif
@@ -293,7 +293,7 @@ ifdef NOHW
else
OPTS+=-DHWRENDER
OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o \
$(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o \
$(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_portal.o\
$(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o $(OBJDIR)/hw_shaders.o
endif
@@ -404,9 +404,9 @@ OPTS+=-DDOSATURNSYNCH
ifndef NOSATURNJOIN
OPTS+=-DDOSATURNJOIN
endif
#ifndef NOSATURNPAK
#OPTS+=-DDOSATURNPAK
#endif
ifndef NOSATURNPAK
OPTS+=-DDOSATURNPAK
endif
endif
endif
@@ -529,6 +529,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/m_fixed.o \
$(OBJDIR)/m_menu.o \
$(OBJDIR)/m_misc.o \
$(OBJDIR)/m_textinput.o \
$(OBJDIR)/m_perfstats.o \
$(OBJDIR)/m_random.o \
$(OBJDIR)/m_queue.o \
@@ -562,6 +563,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/r_splats.o \
$(OBJDIR)/r_patch.o \
$(OBJDIR)/r_things.o \
$(OBJDIR)/r_portal.o \
$(OBJDIR)/screen.o \
$(OBJDIR)/v_video.o \
$(OBJDIR)/s_sound.o \
@@ -737,7 +739,7 @@ ifdef MINGW
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \
hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h hardware/hw_portal.h\
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
@@ -746,7 +748,7 @@ else
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \
hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h hardware/hw_portal.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
+7 -17
View File
@@ -260,25 +260,15 @@ static inline void AM_restoreScaleAndLoc(void)
*/
static void AM_findMinMaxBoundaries(void)
{
size_t i;
fixed_t a;
fixed_t b;
fixed_t a, b;
min_x = min_y = +INT32_MAX;
max_x = max_y = -INT32_MAX;
min_x = minimapinfo.min_x << MAPBITS;
max_x = minimapinfo.max_x << MAPBITS;
min_y = minimapinfo.min_y << MAPBITS;
max_y = minimapinfo.max_y << MAPBITS;
for (i = 0; i < numvertexes; i++)
{
if (vertexes[i].x < min_x)
min_x = vertexes[i].x;
else if (vertexes[i].x > max_x)
max_x = vertexes[i].x;
if (vertexes[i].y < min_y)
min_y = vertexes[i].y;
else if (vertexes[i].y > max_y)
max_y = vertexes[i].y;
}
max_w = minimapinfo.map_w << MAPBITS;
max_h = minimapinfo.map_h << MAPBITS;
max_w = (max_x >>= FRACTOMAPBITS) - (min_x >>= FRACTOMAPBITS);
max_h = (max_y >>= FRACTOMAPBITS) - (min_y >>= FRACTOMAPBITS);
+1 -1
View File
@@ -628,7 +628,7 @@ static void COM_ExecuteString(char *ptext)
// check cvars
// Hurdler: added at Ebola's request ;)
// (don't flood the console in software mode with bad gr_xxx command)
// (don't flood the console in software mode with bad gl_xxx command)
if (!CV_Command() && con_destlines)
CONS_Printf(M_GetText("Unknown command '%s'\n"), COM_Argv(0));
}
+48 -348
View File
@@ -32,6 +32,7 @@
#include "i_threads.h"
#include "d_main.h"
#include "m_menu.h"
#include "m_textinput.h"
#include "filesrch.h"
#ifdef HWRENDER
@@ -97,9 +98,7 @@ static char inputlines[32][CON_MAXPROMPTCHARS]; // hold last 32 prompt lines
static INT32 inputline; // current input line number
static INT32 inputhist; // line number of history input line to restore
static size_t input_cur; // position of cursor in line
static size_t input_sel; // position of selection marker (I.E.: anything between this and input_cur is "selected")
static size_t input_len; // length of current line, used to bound cursor and such
static textinput_t input;
// notice: input does NOT include the "$" at the start of the line. - 11/3/16
// protos.
@@ -458,7 +457,8 @@ static void CON_InputInit(void)
// prepare the first prompt line
memset(inputlines, 0, sizeof (inputlines));
inputline = 0;
input_cur = input_sel = input_len = 0;
M_TextInputInit(&input, inputlines[inputline], CON_MAXPROMPTCHARS);
Unlock_state();
}
@@ -802,178 +802,6 @@ void CON_Ticker(void)
Unlock_state();
}
//
// ----
//
// Shortcuts for adding and deleting characters, strings, and sections
// Necessary due to moving cursor
//
static void CON_InputClear(void)
{
Lock_state();
memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS);
input_cur = input_sel = input_len = 0;
Unlock_state();
}
static void CON_InputSetString(const char *c)
{
Lock_state();
memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS);
strcpy(inputlines[inputline], c);
input_cur = input_sel = input_len = strlen(c);
Unlock_state();
}
static void CON_InputAddString(const char *c)
{
size_t csize = strlen(c);
Lock_state();
if (input_len + csize > CON_MAXPROMPTCHARS-1)
{
Unlock_state();
return;
}
if (input_cur != input_len)
memmove(&inputlines[inputline][input_cur+csize], &inputlines[inputline][input_cur], input_len-input_cur);
memcpy(&inputlines[inputline][input_cur], c, csize);
input_len += csize;
input_sel = (input_cur += csize);
Unlock_state();
}
static void CON_InputDel(size_t start, size_t end)
{
size_t len;
Lock_state();
len = (end - start);
if (end != input_len)
memmove(&inputlines[inputline][start], &inputlines[inputline][end], input_len-end);
memset(&inputlines[inputline][input_len - len], 0, len);
input_len -= len;
if (input_sel >= end)
input_sel -= len;
else if (input_sel > start)
input_sel = start;
if (input_cur >= end)
input_cur -= len;
else if (input_cur > start)
input_cur = start;
Unlock_state();
}
static void CON_InputDelSelection(void)
{
size_t start, end;
Lock_state();
if (input_cur > input_sel)
{
start = input_sel;
end = input_cur;
}
else
{
start = input_cur;
end = input_sel;
}
CON_InputDel(start, end);
input_sel = input_cur = start;
Unlock_state();
}
static void CON_ToWordEnd(boolean move_sel)
{
Lock_state();
// Skip spaces
while (input_cur < input_len && isspace(inputlines[inputline][input_cur]))
++input_cur;
// Skip word
while (input_cur < input_len && !isspace(inputlines[inputline][input_cur]))
++input_cur;
if (move_sel) input_sel = input_cur;
Unlock_state();
}
static void CON_ToWordBegin(boolean move_sel)
{
Lock_state();
// Hack, always move back 1 character if possible so if we press ctrl-left at a word beginning
// we move to previous word
if (input_cur) --input_cur;
// Skip spaces
while (input_cur && isspace(inputlines[inputline][input_cur]))
--input_cur;
// Skip word
while (input_cur && !isspace(inputlines[inputline][input_cur]))
--input_cur;
// Unless we reached beginning of line, we're pointing at a space before word, so move cursor
// forward to fix that
if (input_cur) ++input_cur;
if (move_sel) input_sel = input_cur;
Unlock_state();
}
static void CON_InputAddChar(char c)
{
if (input_len >= CON_MAXPROMPTCHARS-1)
return;
Lock_state();
if (input_cur != input_len)
memmove(&inputlines[inputline][input_cur+1], &inputlines[inputline][input_cur], input_len-input_cur);
inputlines[inputline][input_cur++] = c;
inputlines[inputline][++input_len] = 0;
input_sel = input_cur;
Unlock_state();
}
static void CON_InputDelChar(void)
{
if (!input_cur)
return;
Lock_state();
if (input_cur != input_len)
memmove(&inputlines[inputline][input_cur-1], &inputlines[inputline][input_cur], input_len-input_cur);
inputlines[inputline][--input_len] = 0;
input_sel = --input_cur;
Unlock_state();
}
//
// ----
//
@@ -1054,6 +882,10 @@ boolean CON_Responder(event_t *ev)
}
}
Lock_state();
M_TextInputHandle(&input, key);
Unlock_state();
// Always eat ctrl/shift/alt if console open, so the menu doesn't get ideas
if (key == KEY_LSHIFT || key == KEY_RSHIFT
|| key == KEY_LCTRL || key == KEY_RCTRL
@@ -1066,12 +898,11 @@ boolean CON_Responder(event_t *ev)
// show all cvars/commands that match what we have inputted
if (key == KEY_TAB)
{
if (!completion[0])
{
if (!input_len || input_len >= 40 || strchr(inputlines[inputline], ' '))
if (!input.length || input.length >= 40 || strchr(input.buffer, ' '))
return true;
strcpy(completion, inputlines[inputline]);
strcpy(completion, input.buffer);
comskips = varskips = 0;
}
@@ -1092,74 +923,9 @@ boolean CON_Responder(event_t *ev)
return true;
}
if (key == 'x' || key == 'X')
{
if (input_sel > input_cur)
I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur);
else
I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel);
CON_InputDelSelection();
// Those are already handled in M_TextInputHandle, but they do extra logic... Maybe textinput_t should have some sort of callbacks?
if (key == 'x' || key == 'X' || key == 'v' || key == 'V')
completion[0] = 0;
return true;
}
else if (key == 'c' || key == 'C')
{
if (input_sel > input_cur)
I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur);
else
I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel);
return true;
}
else if (key == 'v' || key == 'V')
{
const char *paste = I_ClipboardPaste();
if (input_sel != input_cur)
CON_InputDelSelection();
if (paste != NULL)
CON_InputAddString(paste);
completion[0] = 0;
return true;
}
else if (key == 'w' || key == 'W')
{
size_t word_start, word_end, i;
word_end = i = input_cur;
// Unless we're pointing at the beginning of line, decrement i so we only start
// removing symbols that come before the cursor
if (i) --i;
// We might be pointing to spaces, skip them first
while (i && isspace(inputlines[inputline][i]))
--i;
// Now skip the "word"
while (i && !isspace(inputlines[inputline][i]))
--i;
// Unless we reached beginning of line, i is pointing at first space that was found
// before word start, and we don't want to remove it
if (i) ++i;
word_start = i;
if (word_start != word_end)
CON_InputDel(word_start, word_end);
return true;
}
else if (key == KEY_RIGHTARROW)
CON_ToWordEnd(!shiftdown);
else if (key == KEY_LEFTARROW)
CON_ToWordBegin(!shiftdown);
// Select all
if (key == 'a' || key == 'A')
{
input_sel = 0;
input_cur = input_len;
return true;
}
// ...why shouldn't it eat the key? if it doesn't, it just means you
// can control Sonic from the console, which is silly
@@ -1174,9 +940,9 @@ boolean CON_Responder(event_t *ev)
// remember typing for several completions (a-la-4dos)
if (!completion[0])
{
if (!input_len || input_len >= 40 || strchr(inputlines[inputline], ' '))
if (!input.length || input.length >= 40 || strchr(input.buffer, ' '))
return true;
strcpy(completion, inputlines[inputline]);
strcpy(completion, input.buffer);
comskips = varskips = 0;
}
else
@@ -1207,7 +973,11 @@ boolean CON_Responder(event_t *ev)
cmd = CV_CompleteVar(completion, varskips);
if (cmd)
CON_InputSetString(va("%s ", cmd));
{
Lock_state();
M_TextInputSetString(&input, va("%s ", cmd));
Unlock_state();
}
else
{
if (comskips > 0)
@@ -1233,37 +1003,6 @@ boolean CON_Responder(event_t *ev)
return true;
}
if (key == KEY_LEFTARROW)
{
if (input_cur != 0)
--input_cur;
if (!shiftdown)
input_sel = input_cur;
return true;
}
else if (key == KEY_RIGHTARROW)
{
if (input_cur < input_len)
++input_cur;
if (!shiftdown)
input_sel = input_cur;
return true;
}
else if (key == KEY_HOME)
{
input_cur = 0;
if (!shiftdown)
input_sel = input_cur;
return true;
}
else if (key == KEY_END)
{
input_cur = input_len;
if (!shiftdown)
input_sel = input_cur;
return true;
}
// At this point we're messing with input
// Clear completion
completion[0] = 0;
@@ -1271,45 +1010,29 @@ boolean CON_Responder(event_t *ev)
// command enter
if (key == KEY_ENTER)
{
if (!input_len)
if (!input.length)
return true;
// push the command
COM_BufAddText(inputlines[inputline]);
COM_BufAddText(input.buffer);
COM_BufAddText("\n");
CONS_Printf("\x86""%c""\x80""%s\n", CON_PROMPTCHAR, inputlines[inputline]);
Lock_state();
// Only add command to history if it differs from previous one
if (strcmp(inputlines[inputline], inputlines[(inputline-1) & 31]))
if (strcmp(input.buffer, inputlines[(inputline-1) & 31]))
{
inputline = (inputline+1) & 31;
M_TextInputInit(&input, inputlines[inputline], CON_MAXPROMPTCHARS);
}
inputhist = inputline;
CON_InputClear();
M_TextInputClear(&input);
return true;
}
Unlock_state();
// backspace and delete command prompt
if (input_sel != input_cur)
{
if (key == KEY_BACKSPACE || key == KEY_DEL)
{
CON_InputDelSelection();
return true;
}
}
else if (key == KEY_BACKSPACE)
{
CON_InputDelChar();
return true;
}
else if (key == KEY_DEL)
{
if (input_cur == input_len)
return true;
++input_cur;
CON_InputDelChar();
return true;
}
@@ -1326,7 +1049,9 @@ boolean CON_Responder(event_t *ev)
if (inputhist == inputline)
inputhist = (inputline + 1) & 31;
CON_InputSetString(inputlines[inputhist]);
Lock_state();
M_TextInputSetString(&input, inputlines[inputhist]);
Unlock_state();
return true;
}
@@ -1340,41 +1065,16 @@ boolean CON_Responder(event_t *ev)
while (inputhist != inputline && !inputlines[inputhist][0]);
// back to currentline
Lock_state();
if (inputhist == inputline)
CON_InputClear();
M_TextInputClear(&input);
else
CON_InputSetString(inputlines[inputhist]);
M_TextInputSetString(&input, inputlines[inputhist]);
Unlock_state();
return true;
}
// allow people to use keypad in console (good for typing IP addresses) - Calum
if (key >= KEY_KEYPAD7 && key <= KEY_KPADDEL)
{
char keypad_translation[] = {'7','8','9','-',
'4','5','6','+',
'1','2','3',
'0','.'};
key = keypad_translation[key - KEY_KEYPAD7];
}
else if (key == KEY_KPADSLASH)
key = '/';
// same capslock code as hu_stuff.c's HU_responder. Check there for details.
key = CON_ShiftChar(key);
// enter a char into the command prompt
if (key < 32 || key > 127)
return true;
// add key to cmd line here
if (key >= 'A' && key <= 'Z' && !(shiftdown ^ capslock)) //this is only really necessary for dedicated servers
key = key + 'a' - 'A';
if (input_sel != input_cur)
CON_InputDelSelection();
CON_InputAddChar(key);
return true;
}
@@ -1656,16 +1356,16 @@ static void CON_DrawInput(void)
clen = con_width-13;
if (input_len <= clen)
if (input.length <= clen)
{
c = 0;
clen = input_len;
clen = input.length;
}
else // input line scrolls left if it gets too long
{
clen -= 2; // There will always be some extra truncation -- but where is what we'll find out
if (input_cur <= clen/2)
if (input.cursor <= clen/2)
{
// Close enough to right edge to show all
c = 0;
@@ -1676,15 +1376,15 @@ static void CON_DrawInput(void)
{
// Cursor in the middle (or right side) of input
// Move over for the ellipsis
c = input_cur - (clen/2) + 2;
c = input.cursor - (clen/2) + 2;
x += charwidth*2;
lellip = 1;
if (c + clen >= input_len)
if (c + clen >= input.length)
{
// Cursor in the right side of input
// We were too far over, so move back
c = input_len - clen;
c = input.length - clen;
}
else
{
@@ -1698,7 +1398,7 @@ static void CON_DrawInput(void)
if (lellip)
{
x -= charwidth*3;
if (input_sel < c)
if (input.select < c)
V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 107 | V_NOSCALESTART);
for (i = 0; i < 3; ++i, x += charwidth)
V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value);
@@ -1708,7 +1408,7 @@ static void CON_DrawInput(void)
for (cend = c + clen; c < cend; ++c, x += charwidth)
{
if ((input_sel > c && input_cur <= c) || (input_sel <= c && input_cur > c))
if ((input.select > c && input.cursor <= c) || (input.select <= c && input.cursor > c))
{
V_DrawFill(x, y, charwidth, (10 * con_scalefactor), 107 | V_NOSCALESTART);
V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_YELLOWMAP | V_NOSCALESTART, !cv_allcaps.value);
@@ -1716,14 +1416,14 @@ static void CON_DrawInput(void)
else
V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
if (c == input_cur && con_tick >= 4)
if (c == input.cursor && con_tick >= 4)
V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
}
if (cend == input_cur && con_tick >= 4)
if (cend == input.cursor && con_tick >= 4)
V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
if (rellip)
{
if (input_sel > cend)
if (input.select > cend)
V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 107 | V_NOSCALESTART);
for (i = 0; i < 3; ++i, x += charwidth)
V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value);
+108 -77
View File
@@ -136,7 +136,7 @@ static UINT8 gamestate_resend_counter[MAXNETNODES];
#endif
// kart, true when a player is connecting or disconnecting so that the gameplay has stopped in its tracks
UINT8 hu_stopped = 0;
boolean hu_stopped = false;
// Client specific
static ticcmd_t localcmds;
@@ -1790,6 +1790,18 @@ static boolean SV_SendServerConfig(INT32 node)
#ifdef JOININGAME
#define SAVEGAMESIZE (768*1024)
#ifdef SATURNSYNCH
static boolean SV_ResendingSavegameToAnyone(void)
{
INT32 i;
for (i = 0; i < MAXNETNODES; i++)
if (resendingsavegame[i])
return true;
return false;
}
#endif
static void SV_SendSaveGame(INT32 node, boolean resending)
{
size_t length, compressedlen;
@@ -1993,13 +2005,16 @@ static void CL_ReloadReceivedSavegame(void)
neededtic = gametic;
maketic = neededtic;
// set camera angle to somewhat match where your player is turning
// we dont have P_ForceLocalAngle so were setting it manually here
for (i = 0; i <= splitscreen; i++)
{
localangle[i] = players[displayplayers[i]].cmd.angleturn<<16;
localangle[i] = (angle_t)(players[displayplayers[i]].cmd.angleturn<<16);
}
camera->subsector = R_PointInSubsector(camera->x, camera->y);
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
camera[i].subsector = R_PointInSubsector(camera[i].x, camera[i].y);
}
cl_redownloadinggamestate = false;
@@ -2182,6 +2197,33 @@ void CL_TimeoutServerList(void)
}
#endif // ifndef NONET
static void CL_ConfirmConnect(void)
{
if (totalfilesrequestednum > 0)
{
#ifdef HAVE_CURL
if (http_source[0] == '\0' || curl_failedwebdownload)
#endif
{
if (CL_SendRequestFile())
{
cl_mode = CL_DOWNLOADFILES;
}
else
{
cl_mode = CL_LEGACYREQUESTFAILED;
}
}
#ifdef HAVE_CURL
else
cl_mode = CL_PREPAREHTTPFILES;
#endif
}
else
cl_mode = CL_LOADFILES;
}
static void M_ConfirmConnect(event_t *ev)
{
#ifndef NONET
@@ -2189,28 +2231,7 @@ static void M_ConfirmConnect(event_t *ev)
{
if (ev->data1 == ' ' || ev->data1 == 'y' || ev->data1 == KEY_ENTER || ev->data1 == gamecontrol[gc_accelerate][0] || ev->data1 == gamecontrol[gc_accelerate][1])
{
if (totalfilesrequestednum > 0)
{
#ifdef HAVE_CURL
if (http_source[0] == '\0' || curl_failedwebdownload)
#endif
{
if (CL_SendRequestFile())
{
cl_mode = CL_DOWNLOADFILES;
}
else
{
cl_mode = CL_LEGACYREQUESTFAILED;
}
}
#ifdef HAVE_CURL
else
cl_mode = CL_PREPAREHTTPFILES;
#endif
}
else
cl_mode = CL_LOADFILES;
CL_ConfirmConnect();
M_ClearMenus(true);
}
@@ -2340,24 +2361,30 @@ static boolean CL_FinishedFileList(void)
downloadsize = Z_StrDup(va("%uK",totalfilesrequestedsize>>10));
#endif
if (serverisfull)
M_StartMessage(va(M_GetText(
"This server is full!\n"
"Download of %s additional content is required to join.\n"
"\n"
"You may download, load server addons, and wait for a slot.\n"
"\n"
"Press ACCEL to continue or BRAKE to cancel.\n\n"
), downloadsize), M_ConfirmConnect, MM_EVENTHANDLER);
if (cv_showdownloadprompt.value)
{
if (serverisfull)
M_StartMessage(va(M_GetText(
"This server is full!\n"
"Download of %s additional content is required to join.\n"
"\n"
"You may download, load server addons, and wait for a slot.\n"
"\n"
"Press ACCEL to continue or BRAKE to cancel.\n\n"
), downloadsize), M_ConfirmConnect, MM_EVENTHANDLER);
else
M_StartMessage(va(M_GetText(
"Download of %s additional content is required to join.\n"
"\n"
"Press ACCEL to continue or BRAKE to cancel.\n\n"
), downloadsize), M_ConfirmConnect, MM_EVENTHANDLER);
cl_mode = CL_CONFIRMCONNECT;
}
else
M_StartMessage(va(M_GetText(
"Download of %s additional content is required to join.\n"
"\n"
"Press ACCEL to continue or BRAKE to cancel.\n\n"
), downloadsize), M_ConfirmConnect, MM_EVENTHANDLER);
CL_ConfirmConnect();
Z_Free(downloadsize);
cl_mode = CL_CONFIRMCONNECT;
}
#ifdef HAVE_CURL
else
@@ -3367,6 +3394,7 @@ void CL_Reset(void)
curl_running = false;
http_source[0] = '\0';
#endif
G_ResetAllDeviceRumbles();
// D_StartTitle should get done now, but the calling function will handle it
}
@@ -4219,6 +4247,7 @@ static void ResetNode(INT32 node)
resendingsavegame[node] = false;
can_receive_gamestate[node] = false;
savegameresendcooldown[node] = 0;
gamestate_resend_counter[node] = 0;
#endif
//
}
@@ -4435,7 +4464,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
if (server && multiplayer && motd[0] != '\0')
COM_BufAddText(va("sayto %d %s\n", newplayernum, motd));
D_AddAutoloadFiles();
D_AddPostloadFiles();
LUAh_PlayerJoin(newplayernum);
@@ -5354,15 +5383,21 @@ static void HandlePacketFromPlayer(SINT8 node)
}
#ifdef SATURNSYNCH
// this decreases by one point at twice the cooldown time (ex cooldown of 2 seconds means, this counter decreases by one every 4 seconds), pretty much there to prevent a resynch loop
if ((gamestate_resend_counter[node] != 0) && (I_GetTime() % ((max(cv_resynchcooldown.value, 1) * TICRATE) *2) == 0))
{
gamestate_resend_counter[node]--;
DEBFILE(va("gamestate counter %d for node %d\n", gamestate_resend_counter[node], netconsole));
}
// Check player consistancy during the level
if (((!can_receive_gamestate[node]) && realstart <= gametic && realstart > gametic - TICQUEUE+1 && gamestate == GS_LEVEL
&& consistancy[realstart%TICQUEUE] != SHORT(netbuffer->u.clientpak.consistancy)) || (can_receive_gamestate[node] && realstart <= gametic && realstart + TICQUEUE - 1 > gametic && gamestate == GS_LEVEL
&& consistancy[realstart%TICQUEUE] != SHORT(netbuffer->u.clientpak.consistancy)
&& !resendingsavegame[node] && savegameresendcooldown[node] <= I_GetTime()))
&& !resendingsavegame[node] && savegameresendcooldown[node] <= I_GetTime()
&& !SV_ResendingSavegameToAnyone()))
{
//#ifndef SATURNPAK // lug: keep this behaviour for v7.1 atleast
// we need to send this so the client can tell us if it can receive the savegame
netbuffer->packettype = PT_WILLRESENDGAMESTATE;
HSendPacket(node, true, 0, 0);
@@ -5374,13 +5409,28 @@ static void HandlePacketFromPlayer(SINT8 node)
SV_RequireResynch(node);
resendingsavegame[node] = false;
}
/*#else
if (can_receive_gamestate[node])
{
// Tell the client we are about to resend them the gamestate
netbuffer->packettype = PT_WILLRESENDGAMESTATE;
HSendPacket(node, true, 0, 0);
if ((!can_receive_gamestate[node] && cv_resynchattempts.value && resynch_score[node] <= (unsigned)cv_resynchattempts.value*250) || (can_receive_gamestate[node] && (gamestate_resend_counter[node] < cv_gamestateattempts.value)))
resendingsavegame[node] = true;
}
else
{
SV_RequireResynch(node);
resendingsavegame[node] = false;
}
#endif*/
if ((!can_receive_gamestate[node] && (cv_resynchattempts.value && resynch_score[node] <= (unsigned)cv_resynchattempts.value*250)) || (can_receive_gamestate[node] && (gamestate_resend_counter[node] < cv_gamestateattempts.value)))
{
if (can_receive_gamestate[node] && resendingsavegame[node])
{
gamestate_resend_counter[node]++;
DEBFILE(va("gamestate counter %d for player %d\n", gamestate_resend_counter[node], netconsole));
DEBFILE(va("gamestate counter %d for node %d\n", gamestate_resend_counter[node], netconsole));
}
if (cv_blamecfail.value)
@@ -5403,6 +5453,8 @@ static void HandlePacketFromPlayer(SINT8 node)
DEBFILE(va("player %d kicked (synch failure) [%u] %d!=%d\n",
netconsole, realstart, consistancy[realstart%TICQUEUE],
SHORT(netbuffer->u.clientpak.consistancy)));
gamestate_resend_counter[node] = 0;
DEBFILE(va("gamestate counter %d for node %d\n", gamestate_resend_counter[node], netconsole));
break;
}
}
@@ -5414,7 +5466,7 @@ static void HandlePacketFromPlayer(SINT8 node)
if (realstart <= gametic && realstart > gametic - TICQUEUE+1 && gamestate == GS_LEVEL
&& consistancy[realstart%TICQUEUE] != SHORT(netbuffer->u.clientpak.consistancy))
{
SV_RequireResynch(node);
SV_RequireResynch(node);
if (cv_resynchattempts.value && resynch_score[node] <= (unsigned)cv_resynchattempts.value*250)
{
@@ -5552,31 +5604,6 @@ static void HandlePacketFromPlayer(SINT8 node)
else
buf[1] = KICK_MSG_PLAYER_QUIT;
SendNetXCmd(XD_KICK, &buf, 2);
//nodetoplayer[node] = -1;
/*if (nodetoplayer2[node] != -1 && nodetoplayer2[node] >= 0
&& playeringame[(UINT8)nodetoplayer2[node]])
{
buf[0] = nodetoplayer2[node];
SendNetXCmd(XD_KICK, &buf, 2);
nodetoplayer2[node] = -1;
}
if (nodetoplayer3[node] != -1 && nodetoplayer3[node] >= 0
&& playeringame[(UINT8)nodetoplayer3[node]])
{
buf[0] = nodetoplayer3[node];
SendNetXCmd(XD_KICK, &buf, 2);
nodetoplayer3[node] = -1;
}
if (nodetoplayer4[node] != -1 && nodetoplayer4[node] >= 0
&& playeringame[(UINT8)nodetoplayer4[node]])
{
buf[0] = nodetoplayer4[node];
SendNetXCmd(XD_KICK, &buf, 2);
nodetoplayer4[node] = -1;
}*/
}
Net_CloseConnection(node);
nodeingame[node] = false;
@@ -5765,8 +5792,9 @@ static void HandlePacketFromPlayer(SINT8 node)
#endif
#ifdef SATURNPAK
case PT_ISSATURN:
//CONS_Printf("hi im on saturn%d\n", node);
DEBFILE(va("hi im on saturn! node = %d\n", node));
is_client_saturn[node] = true;
can_receive_gamestate[node] = true;
break;
#endif
default:
@@ -5790,9 +5818,12 @@ static void GetPackets(void)
{
node = (SINT8)doomcom->remotenode;
if (netbuffer->packettype == PT_CLIENTJOIN && server && !levelloading)
if (netbuffer->packettype == PT_CLIENTJOIN && server)
{
HandleConnect(node);
if (!levelloading) // Otherwise just ignore
{
HandleConnect(node);
}
continue;
}
if (node == servernode && client && cl_mode != CL_SEARCHING)
@@ -6350,7 +6381,7 @@ boolean TryRunTics(tic_t realtics)
if (demo.playback)
{
neededtic = gametic + realtics * (gamestate == GS_LEVEL ? cv_playbackspeed.value : 1);
neededtic = gametic + realtics;
// start a game after a demo
maketic += realtics;
firstticstosend = maketic;
@@ -6599,7 +6630,7 @@ void NetKeepAlive(void)
#ifdef MASTERSERVER
MasterClient_Ticker();
#endif
#ifdef HOLEPUNCH
if (netgame && serverrunning)
{
@@ -6710,7 +6741,7 @@ void NetUpdate(void)
CL_SendClientCmd(); // send it
GetPackets(); // get packet from client or from server
// client send the command after a receive of the server
// the server send before because in single player is beter
+1 -1
View File
@@ -656,7 +656,7 @@ extern UINT8 hu_resynching;
#ifdef SATURNSYNCH
extern UINT8 hu_redownloadinggamestate;
#endif
extern UINT8 hu_stopped; // kart, true when the game is stopped for players due to a disconnecting or connecting player
extern boolean hu_stopped; // kart, true when the game is stopped for players due to a disconnecting or connecting player
typedef struct rewind_s {
UINT8 savebuffer[(768*1024)];
+70 -100
View File
@@ -99,7 +99,6 @@ UINT8 window_notinfocus = false;
// DEMO LOOP
//
//static INT32 demosequence;
static const char *pagename = "MAP1PIC";
static char *startupwadfiles[MAX_WADFILES];
static char *startuppwads[MAX_WADFILES];
@@ -116,7 +115,6 @@ boolean devparm = false; // started game with -devparm
boolean singletics = false; // timedemo
boolean lastdraw = false;
postimg_t postimgtype[MAXSPLITSCREENPLAYERS];
INT32 postimgparam[MAXSPLITSCREENPLAYERS];
// These variables are only true if
@@ -513,15 +511,12 @@ static boolean D_Display(void)
if (rendermode == render_soft)
{
if (!splitscreen)
R_ApplyViewMorph();
if (!splitscreen)
R_ApplyViewMorph();
for (i = 0; i <= splitscreen; i++)
{
if (!postimgtype[i])
continue;
V_DoPostProcessor(i, postimgtype[i], postimgparam[i]);
V_DoPostProcessor(i, &players[displayplayers[i]], postimgparam[i]);
}
}
@@ -568,7 +563,7 @@ static boolean D_Display(void)
V_DrawScaledPatch(viewwindowx + (BASEVIDWIDTH - SHORT(patch->width))/2, py, V_SNAPTOTOP, patch);
}
if (demo.rewinding)
if (rendermode == render_soft && demo.rewinding)
V_DrawFadeScreen(TC_RAINBOW, (leveltime & 0x20) ? SKINCOLOR_PASTEL : SKINCOLOR_MOONSLAM);
// vid size change is now finished if it was on...
@@ -654,7 +649,7 @@ static boolean D_Display(void)
// =========================================================================
tic_t rendergametic;
static int menuInputDelayTimer = 0;
static SINT8 menuInputDelayTimer = 0;
void D_SRB2Loop(void)
{
@@ -780,6 +775,38 @@ void D_SRB2Loop(void)
doDisplay = true;
}
#define DPADSCROLLINPUT(INPUT)\
{\
myev.data1 = INPUT;\
M_Responder(&myev);\
}
// this is absolutely awful and i hate it lmao
if (menuactive && (DPADUPSCROLL || DPADDOWNSCROLL || DPADLEFTSCROLL || DPADRIGHTSCROLL))
{
event_t myev;
myev.type = ev_keydown;
if (menuInputDelayTimer < 19)
menuInputDelayTimer++;
if (menuInputDelayTimer == 19) // TICRATE * ( (k+2) (1 - [wz + h + j - q]^2 - [(gk + 2g + k + 1)(h + j) + h - z]^2 - [16(k + 1)^3(k + 2)(n + 1)^2 + 1 - f^2]^2 calculated by my butt
{
if (DPADUPSCROLL)
DPADSCROLLINPUT(KEY_UPARROW)
else if (DPADDOWNSCROLL)
DPADSCROLLINPUT(KEY_DOWNARROW)
else if (DPADLEFTSCROLL)
DPADSCROLLINPUT(KEY_LEFTARROW)
else if (DPADRIGHTSCROLL)
DPADSCROLLINPUT(KEY_RIGHTARROW)
}
}
else
menuInputDelayTimer = 0;
#undef DPADSCROLLINPUT
D_DeviceLEDTick();
}
if (interp)
@@ -794,11 +821,14 @@ void D_SRB2Loop(void)
{
rendertimefrac = FRACUNIT;
}
rendertimefrac_unpaused = g_time.timefrac;
}
else
{
renderdeltatics = realtics * FRACUNIT;
rendertimefrac = FRACUNIT;
rendertimefrac_unpaused = FRACUNIT;
}
if ((interp || doDisplay) && !frameskip)
@@ -828,47 +858,6 @@ void D_SRB2Loop(void)
}
#endif
// this is absolutely awful and i hate it lmao
if (menuactive && (DPADUPSCROLL || DPADDOWNSCROLL || DPADLEFTSCROLL || DPADRIGHTSCROLL))
{
event_t myev;
myev.type = ev_keydown;
if (renderisnewtic)
{
menuInputDelayTimer++;
if (menuInputDelayTimer >= 19) // TICRATE * ( (k+2) (1 - [wz + h + j - q]^2 - [(gk + 2g + k + 1)(h + j) + h - z]^2 - [16(k + 1)^3(k + 2)(n + 1)^2 + 1 - f^2]^2 calculated by my butt
{
if (DPADUPSCROLL)
{
myev.data1 = KEY_UPARROW;
M_Responder(&myev);
}
else if (DPADDOWNSCROLL)
{
myev.data1 = KEY_DOWNARROW;
M_Responder(&myev);
}
else if (DPADLEFTSCROLL)
{
myev.data1 = KEY_LEFTARROW;
M_Responder(&myev);
}
else if (DPADRIGHTSCROLL)
{
myev.data1 = KEY_RIGHTARROW;
M_Responder(&myev);
}
}
}
}
else
menuInputDelayTimer = 0;
if (!dedicated && renderisnewtic) // idk does this need dedi check??
D_DeviceLEDTick();
// Fully completed frame made.
finishprecise = I_GetPreciseTime();
@@ -1078,8 +1067,7 @@ static void D_FindAddonsToAutoload(void)
const char *autoloadpath;
boolean postload;
INT32 i, len;
boolean hasprefix = false;
INT32 i;
char wadsToAutoload[256] = "";
// does it exist tho
@@ -1101,7 +1089,8 @@ static void D_FindAddonsToAutoload(void)
|| (wadsToAutoload[0] == '#'))
continue;
// this marks it so that it loads after loading server addons
else if (fastncmp(wadsToAutoload, "postload ", 9)) {
else if (fastncmp(wadsToAutoload, "postload ", 9))
{
strremove(wadsToAutoload, "postload ");
postload = true;
}
@@ -1113,34 +1102,10 @@ static void D_FindAddonsToAutoload(void)
wadsToAutoload[i] = '\0';
}
len = strlen(wadsToAutoload);
hasprefix = false;
for (i = 0; i < len; ++i)
if (!postload && W_CheckPostLoadList(wadsToAutoload))
{
if (wadsToAutoload[i] == '_')
{
hasprefix = true;
break;
}
}
// Lets just hope no one adds bonuschars in autoload
if (hasprefix)
{
// We searching for c in prefix, which stands for "character" and doesn't work well with
// autoload atm, only fine for postload
for (i = 0; i < len; ++i)
{
if (wadsToAutoload[i] == '_') break; // Prefix end
if (wadsToAutoload[i] == 'c' || wadsToAutoload[i] == 'C')
{
CONS_Alert(CONS_WARNING, "forcing postload for %s as local skin\n", wadsToAutoload);
postload = true;
break; // Found it
}
}
CONS_Printf("forcing postload for file %s\n", wadsToAutoload);
postload = true;
}
// LOAD IT
@@ -1158,30 +1123,30 @@ static void D_FindAddonsToAutoload(void)
fclose(autoloadconfigfile);
}
void D_AddAutoloadFiles(void)
static void D_AddAutoloadFiles(void)
{
if (wasautoloaded && postautoloaded)
if (wasautoloaded)
return;
if (!wasautoloaded && !modeattacking)
{
CONS_Printf("D_AutoloadFile(): Loading autoloaded addons...\n");
if (W_AddAutoloadedLocalFiles(autoloadwadfiles) == 0)
CONS_Printf("D_AutoloadFile(): Are you sure you put in valid files or what?\n");
D_CleanFile(autoloadwadfiles);
CONS_Printf("D_AutoloadFile(): Loading autoloaded addons...\n");
if (W_AddAutoloadedLocalFiles(autoloadwadfiles) == 0)
CONS_Printf("D_AutoloadFile(): Are you sure you put in valid files or what?\n");
D_CleanFile(autoloadwadfiles);
wasautoloaded = true;
}
wasautoloaded = true;
}
if ((!postautoloaded) && netgame)
{
CONS_Printf("D_AutoloadFile(): Loading postloaded addons...\n");
if (W_AddAutoloadedLocalFiles(autoloadwadfilespost) == 0)
CONS_Printf("D_AutoloadFile(): Are you sure you put in valid files or what?\n");
D_CleanFile(autoloadwadfilespost);
void D_AddPostloadFiles(void)
{
if (postautoloaded || !netgame)
return;
postautoloaded = true;
}
CONS_Printf("D_AddPostloadFiles(): Loading postloaded addons...\n");
if (W_AddAutoloadedLocalFiles(autoloadwadfilespost) == 0)
CONS_Printf("D_AddPostloadFiles(): Are you sure you put in valid files or what?\n");
D_CleanFile(autoloadwadfilespost);
postautoloaded = true;
}
void D_CleanFile(char **filearray)
@@ -1677,6 +1642,10 @@ void D_SRB2Main(void)
#undef PUSHSPEEDO
memcpy(speedo_cons_t, speedo_cons_temp, sizeof(speedo_cons_t));
// Do it before P_InitMapData because PNG patch
// conversion sometimes needs the palette
V_ReloadPalette();
//
// search for maps
//
@@ -1872,6 +1841,8 @@ void D_SRB2Main(void)
CONS_Printf("ST_Init(): Init status bar.\n");
ST_Init();
D_AddAutoloadFiles();
// Set up splitscreen players before joining!
if (!dedicated && (M_CheckParm("-splitscreen") && M_IsNextParm()))
{
@@ -2073,7 +2044,6 @@ void D_SRB2Main(void)
if (dedicated && server)
{
pagename = "TITLESKY";
levelstarttic = gametic;
G_SetGamestate(GS_LEVEL);
if (!P_SetupLevel(false, false))
+3 -3
View File
@@ -45,12 +45,12 @@ extern boolean statdp; // stat display for extended player setup
extern boolean nametaggfx; // Nametag stuffs
extern boolean driftgaugegfx;
void D_AddAutoloadFiles(void);
// autoload stuff
extern boolean autoloading;
extern boolean autoloaded;
extern boolean postautoloaded;
extern boolean wasautoloaded;
void D_AddPostloadFiles(void);
extern char *autoloadwadfilespost[MAX_WADFILES];
extern char *autoloadwadfiles[MAX_WADFILES];
+4 -4
View File
@@ -1446,13 +1446,13 @@ void Command_Ping_f(void)
}
}
if (f_width < 10) f_width = 1;
if (f_width < 10) f_width = 1;
else if (f_width < 100) f_width = 2;
else f_width = 3;
else f_width = 3;
if (ms_width < 10) ms_width = 1;
if (ms_width < 10) ms_width = 1;
else if (ms_width < 100) ms_width = 2;
else ms_width = 3;
else ms_width = 3;
qsort(pingv, pingc, sizeof (struct pingcell), &pingcellcmp);
+80 -33
View File
@@ -493,6 +493,8 @@ consvar_t cv_showlapemblem = {"showlapemblem", "On", CV_SAVE, CV_OnOff, NULL, 0,
consvar_t cv_showviewpointtext = {"showviewpointtext", "On", CV_SAVE, CV_OnOff, 0, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_showdownloadprompt = {"showdownloadprompt", "On", CV_SAVE, CV_OnOff, 0, 0, NULL, NULL, 0, 0, NULL};
// Intermission time Tails 04-19-2002
static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}};
consvar_t cv_inttime = {"inttime", "20", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -567,7 +569,7 @@ consvar_t cv_ps_descriptor = {"ps_descriptor", "Average", 0, ps_descriptor_cons_
consvar_t cv_director = {"director", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugdirector = {"debugdirector", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_showdirectorhud = {"showdirectorhud", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_showdirectorhud = {"showdirectorhud", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_showtrackaddon = {"showtrackaddon", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -976,7 +978,6 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_audbuffersize);
// m_menu.c
//CV_RegisterVar(&cv_compactscoreboard);
CV_RegisterVar(&cv_chatheight);
CV_RegisterVar(&cv_chatwidth);
CV_RegisterVar(&cv_chattime);
@@ -994,6 +995,7 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_showtrackaddon);
CV_RegisterVar(&cv_showviewpointtext);
CV_RegisterVar(&cv_showdownloadprompt);
CV_RegisterVar(&cv_director);
CV_RegisterVar(&cv_kartdebugdirector);
@@ -1087,20 +1089,12 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_controlperkey);
CV_RegisterVar(&cv_turnsmooth);
CV_RegisterVar(&cv_rumble[0]);
CV_RegisterVar(&cv_rumble[1]);
CV_RegisterVar(&cv_rumble[2]);
CV_RegisterVar(&cv_rumble[3]);
CV_RegisterVar(&cv_gamepadled[0]);
CV_RegisterVar(&cv_gamepadled[1]);
CV_RegisterVar(&cv_gamepadled[2]);
CV_RegisterVar(&cv_gamepadled[3]);
CV_RegisterVar(&cv_ledpowerup[0]);
CV_RegisterVar(&cv_ledpowerup[1]);
CV_RegisterVar(&cv_ledpowerup[2]);
CV_RegisterVar(&cv_ledpowerup[3]);
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
CV_RegisterVar(&cv_rumble[i]);
CV_RegisterVar(&cv_gamepadled[i]);
CV_RegisterVar(&cv_ledpowerup[i]);
}
CV_RegisterVar(&cv_usemouse);
CV_RegisterVar(&cv_usemouse2);
@@ -1204,26 +1198,16 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_speed);
CV_RegisterVar(&cv_opflags);
CV_RegisterVar(&cv_mapthingnum);
//CV_RegisterVar(&cv_grid);
//CV_RegisterVar(&cv_snapto);
// add cheat commands
COM_AddCommand("noclip", Command_CheatNoClip_f);
COM_AddCommand("god", Command_CheatGod_f);
COM_AddCommand("notarget", Command_CheatNoTarget_f);
/*COM_AddCommand("getallemeralds", Command_Getallemeralds_f);
COM_AddCommand("resetemeralds", Command_Resetemeralds_f);
COM_AddCommand("setrings", Command_Setrings_f);
COM_AddCommand("setlives", Command_Setlives_f);
COM_AddCommand("setcontinues", Command_Setcontinues_f);*/
COM_AddCommand("devmode", Command_Devmode_f);
COM_AddCommand("savecheckpoint", Command_Savecheckpoint_f);
COM_AddCommand("scale", Command_Scale_f);
COM_AddCommand("gravflip", Command_Gravflip_f);
COM_AddCommand("hurtme", Command_Hurtme_f);
/*COM_AddCommand("jumptoaxis", Command_JumpToAxis_f);
COM_AddCommand("charability", Command_Charability_f);
COM_AddCommand("charspeed", Command_Charspeed_f);*/
COM_AddCommand("teleport", Command_Teleport_f);
COM_AddCommand("rteleport", Command_RTeleport_f);
COM_AddCommand("skynum", Command_Skynum_f);
@@ -1255,19 +1239,69 @@ void D_RegisterClientCommands(void)
*/
static void Skin_FindRealNameSkin(consvar_t *cvar)
{
// Not the best way to implements this but it will do.
INT32 matches[MAXSKINS] = {0}; // Skin numbers of matching skins
INT32 matches_pos[MAXSKINS] = {0}; // Index of matching substring
INT32 nummatches = 0;
int i;
INT32 i;
const char *value = cvar->string;
for (i = 0; i < numskins; i++)
{
if (strncmp(value, skins[i].realname, sizeof skins[i].realname) == 0)
{
// Change the cvar to be the value of the name.
CV_StealthSet(cvar, skins[i].name);
// Perfect match with some skin name, no need to find matching realname
if (strncasecmp(value, skins[i].name, sizeof skins[i].name) == 0)
return;
const char *match = strcasestr(skins[i].realname, value);
if (match != NULL)
{
matches[nummatches] = i;
matches_pos[nummatches] = match - skins[i].realname;
++nummatches;
}
}
if (nummatches == 1)
{
// Change the cvar to be the value of the name.
CV_StealthSet(cvar, skins[matches[0]].name);
}
else if (nummatches > 1)
{
size_t query_length = strlen(value);
char start[SKINNAMESIZE+1] = {0}; // Start of name, printed with normal color
char match[SKINNAMESIZE+1] = {0}; // Matching part of name, highlighted in red
const char *end = NULL; // End of the name, printed with normal color. Can be just a pointer into realname part
CONS_Printf("\x86Multiple matches found:\n");
for (i = 0; i < nummatches; ++i)
{
const char *realname = skins[matches[i]].realname;
if (matches_pos[i] == 0)
start[0] = 0;
else
{
memcpy(start, realname, matches_pos[i]);
start[matches_pos[i]] = 0;
}
memcpy(match, realname+matches_pos[i], query_length);
match[matches_pos[i] + query_length] = 0;
end = realname + matches_pos[i] + query_length;
CONS_Printf("%s\x85%s\x80%s (%s)\n", start, match, end, skins[matches[i]].name);
}
CONS_Printf("\x86Try be more specific\n");
}
else
{
CONS_Printf("\x86Skin not found\n");
}
}
@@ -2949,6 +2983,14 @@ static void Command_Map_f(void)
// G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer
else
{
if (!mapheaderinfo[newmapnum-1] || mapheaderinfo[newmapnum-1] == NULL)
{
CONS_Alert(CONS_WARNING, M_GetText("Invalid mapheaderinfo for Course %s (%s)\n"), realmapname, G_BuildMapName(newmapnum));
Z_Free(realmapname);
Z_Free(mapname);
return;
}
if (!(mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype)))
{
CONS_Alert(CONS_WARNING, M_GetText("Course %s (%s) doesn't support %s mode!\n(Use -force to override)\n"), realmapname, G_BuildMapName(newmapnum),
@@ -3175,6 +3217,8 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
else
S_ResumeAudio();
}
G_ResetAllDeviceRumbles();
}
static void Command_ReplayMarker(void)
@@ -3192,7 +3236,10 @@ static void Command_ReplayMarker(void)
demo.savemode = DSM_WILLAUTOSAVE;
if (adjustedleveltime < 0)
adjustedleveltime = 0;
snprintf(demo.titlename, 64, "%s [%i:%02d/%.5s]", G_BuildMapTitle(gamemap), G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername);
char *title = G_BuildMapTitle(gamemap);
snprintf(demo.titlename, 64, "%s [%i:%02d/%.5s]", title, G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername);
if (title)
Z_Free(title);
CONS_Printf("Replay will be saved!\n");
}
}
+1
View File
@@ -166,6 +166,7 @@ extern consvar_t cv_minihead;
extern consvar_t cv_showlapemblem;
extern consvar_t cv_showviewpointtext;
extern consvar_t cv_showdownloadprompt;
extern consvar_t cv_luaimmersion;
extern consvar_t cv_fakelocalskin;
extern consvar_t cv_showlocalskinmenus;
+34 -6
View File
@@ -65,10 +65,10 @@ static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid);
#ifdef HAVE_CURL
size_t curlwrite_data(void *ptr, size_t size, size_t nmemb, FILE *stream);
#if defined(CURL_AT_LEAST_VERSION) && CURL_AT_LEAST_VERSION(7, 35, 0)
int curlprogress_callbackx(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
static int curlprogress_callbackx(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
#define XFERINFOFUNCTION
#else
int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
static int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
#endif
#endif
@@ -1203,25 +1203,53 @@ size_t curlwrite_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
}
#ifdef XFERINFOFUNCTION
int curlprogress_callbackx(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
static int curlprogress_callbackx(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
{
time_t curtime;
(void)clientp;
(void)ultotal;
(void)ulnow; // Function prototype requires these but we won't use, so just discard
curtime = time(NULL);
curl_dlnow = dlnow;
curl_dltotal = dltotal;
getbytes = curl_dlnow / (time(NULL) - curl_starttime); // To-do: Make this more accurate???
if (curtime > curl_starttime)
{
getbytes = curl_dlnow / (curtime - curl_starttime); // To-do: Make this more accurate???
}
else
{
getbytes = 0;
}
return 0;
}
#else
int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
static int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
{
time_t curtime;
(void)clientp;
(void)ultotal;
(void)ulnow; // Function prototype requires these but we won't use, so just discard
curtime = time(NULL);
curl_dlnow = dlnow;
curl_dltotal = dltotal;
getbytes = curl_dlnow / (time(NULL) - curl_starttime); // To-do: Make this more accurate???
if (curtime > curl_starttime)
{
getbytes = curl_dlnow / (curtime - curl_starttime); // To-do: Make this more accurate???
}
else
{
getbytes = 0;
}
return 0;
}
#endif
+2
View File
@@ -413,6 +413,8 @@ typedef struct player_s
// See pflags_t, above.
pflags_t pflags;
UINT16 postimgflags;
// playing animation.
panim_t panim;
+10 -1
View File
@@ -9149,7 +9149,6 @@ int LUA_EnumLib(lua_State *L)
PUSHGETTER(globalweather, u8);
PUSHGETTER(levelskynum, i32);
PUSHGETTER(globallevelskynum, i32);
PUSHGETTER((*mapmusname), str);
PUSHGETTER(mapmusflags, u16);
PUSHGETTER(mapmusposition, u32);
PUSHGETTER(gravity, fxp);
@@ -9166,6 +9165,11 @@ int LUA_EnumLib(lua_State *L)
PUSHGETTER(racecountdown, u32);
PUSHGETTER(exitcountdown, u32);
lua_pushcfunction(L, lua_glib_new_getter);
lua_pushliteral(L, "mapmusname");
lua_glib_push_str_getter(L, mapmusname);
lua_call(L, 2, 0);
lua_pushcfunction(L, lua_glib_new_getter);
lua_pushliteral(L, "mariomode");
lua_pushcfunction(L, lua_enumlib_mariomode_get);
@@ -9216,6 +9220,11 @@ int LUA_EnumLib(lua_State *L)
lua_glib_push_bool_getter(L, &demo.playback);
lua_call(L, 2, 0);
lua_pushcfunction(L, lua_glib_new_getter);
lua_pushliteral(L, "replayfreecam");
lua_glib_push_bool_getter(L, &demo.freecam);
lua_call(L, 2, 0);
if (!mathlib)
{
lua_pushcfunction(L, lua_glib_new_getter);
+11 -11
View File
@@ -127,13 +127,8 @@ extern char logfilename[1024];
#else
#define VERSION 1 // Game version
#define SUBVERSION 6 // more precise version number
#ifndef USE_FBO_OGL
#define VERSIONSTRING "Saturn v7"
#define VERSIONSTRINGW L"Saturn v7"
#else
#define VERSIONSTRING "Saturn v7 - FBO "
#define VERSIONSTRINGW L"Saturn v7 - FBO"
#endif
#define VERSIONSTRING "Saturn v7.2"
#define VERSIONSTRINGW L"Saturn v7.2"
// 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!
// AND appveyor.yml, for the build bots!
@@ -474,7 +469,12 @@ void M_StartupLocale(void);
// M_GetText function that just returns the string.
#define M_GetText(x) (x)
#endif
void *M_Memcpy(void* dest, const void* src, size_t n);
FUNCINLINE static ATTRINLINE void *M_Memcpy(void *dest, const void *src, size_t n)
{
return memcpy(dest, src, n);
}
char *va(const char *format, ...) FUNCPRINTF;
char *M_GetToken(const char *inputString);
char *sizeu1(size_t num);
@@ -585,9 +585,9 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Server detection for if a connecting client is on Saturn.
/// For stuff like extra synching, etc.
//#ifdef DOSATURNPAK
//#define SATURNPAK
//#endif
#ifdef DOSATURNPAK
#define SATURNPAK
#endif
//-- <( ̄︶ ̄)> __
#endif
+1 -2
View File
@@ -112,7 +112,6 @@ extern UINT8 window_notinfocus; // are we in focus? (backend independant -- hand
extern boolean nodrawers;
extern boolean noblit;
extern boolean lastdraw;
extern postimg_t postimgtype[MAXSPLITSCREENPLAYERS];
extern INT32 postimgparam[MAXSPLITSCREENPLAYERS];
extern INT32 viewwindowx, viewwindowy;
@@ -192,7 +191,7 @@ extern struct quake
// camera offsets and duration
fixed_t x,y,z;
angle_t roll;
UINT16 time;
tic_t time;
// location, radius, and intensity...
mappoint_t *epicenter;
+6 -8
View File
@@ -344,14 +344,12 @@ typedef union FColorRGBA RGBA_t;
typedef enum
{
postimg_none,
postimg_water,
postimg_motion,
postimg_flip,
postimg_heat,
postimg_mirror,
postimg_mirrorflip
} postimg_t;
POSTIMG_WATER = 1, // Underwater screen effect.
POSTIMG_MOTION = 1<<1, // Unused motion blur effect.
POSTIMG_FLIP = 1<<2, // Flipcam screen effect.
POSTIMG_HEAT = 1<<3, // Heatwave screen effect.
POSTIMG_MIRROR = 1<<4, // encore screen effect.
} postimgflag_t;
typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num)
#define LUMPERROR UINT32_MAX
+5 -5
View File
@@ -170,8 +170,8 @@ static void F_SkyScroll(INT32 scrollspeed)
w = (vid.width / vid.dupx)<<FRACBITS;
// The scroll offset MUST be clamped before shifting by FRACBITS, or else it'll overflow in about 3 minutes
animtimer = ((((finalecount * scrollspeed) % (SHORT(pat->width)*16))<<FRACBITS) + (R_GetHudUncap() * scrollspeed))/16;
anim2 = (SHORT(pat2->width)<<FRACBITS) - ((((finalecount * scrollspeed) % (SHORT(pat2->width)*16))<<FRACBITS) + (R_GetHudUncap() * scrollspeed))/16;
animtimer = ((((finalecount * scrollspeed) % (SHORT(pat->width)*16))<<FRACBITS) + (R_GetMenuUncap() * scrollspeed))/16;
anim2 = (SHORT(pat2->width)<<FRACBITS) - ((((finalecount * scrollspeed) % (SHORT(pat2->width)*16))<<FRACBITS) + (R_GetMenuUncap() * scrollspeed))/16;
// SRB2Kart: F_DrawPatchCol is over-engineered; recoded to be less shitty and error-prone
if (rendermode != render_none)
@@ -996,7 +996,7 @@ void F_TitleScreenDrawer(void)
if (finalecount >= 20)
V_DrawSmallScaledPatch(84, 87, 0, ttkart);
else if (finalecount >= 10)
V_DrawSciencePatch((84<<FRACBITS) - 18*(((20 - finalecount)<<FRACBITS) - R_GetHudUncap()), 87<<FRACBITS, 0, ttkart, FRACUNIT/2);
V_DrawSciencePatch((84<<FRACBITS) - 18*(((20 - finalecount)<<FRACBITS) - R_GetMenuUncap()), 87<<FRACBITS, 0, ttkart, FRACUNIT/2);
}
else if (finalecount < 52)
{
@@ -1012,8 +1012,8 @@ void F_TitleScreenDrawer(void)
F_SkyScroll(titlescrollspeed);
V_DrawSciencePatch(0, -40*FixedDiv(((finalecount % 70)<<FRACBITS) + R_GetHudUncap(), 70<<FRACBITS), V_SNAPTOTOP|V_SNAPTOLEFT, ttcheckers, FRACUNIT);
V_DrawSciencePatch(280<<FRACBITS, -(40<<FRACBITS) + 40*FixedDiv(((finalecount % 70)<<FRACBITS) + R_GetHudUncap(), 70<<FRACBITS), V_SNAPTOTOP|V_SNAPTORIGHT, ttcheckers, FRACUNIT);
V_DrawSciencePatch(0, -40*FixedDiv(((finalecount % 70)<<FRACBITS) + R_GetMenuUncap(), 70<<FRACBITS), V_SNAPTOTOP|V_SNAPTOLEFT, ttcheckers, FRACUNIT);
V_DrawSciencePatch(280<<FRACBITS, -(40<<FRACBITS) + 40*FixedDiv(((finalecount % 70)<<FRACBITS) + R_GetMenuUncap(), 70<<FRACBITS), V_SNAPTOTOP|V_SNAPTORIGHT, ttcheckers, FRACUNIT);
if (transval)
V_DrawFadeScreen(120, 10 - transval);
+79 -196
View File
@@ -357,10 +357,6 @@ consvar_t cv_demochangemap = {"netdemo_savemapchange", "Disabled", CV_SAVE, demo
static UINT8 *savebuffer;
// Analog Control
static void UserAnalog_OnChange(void);
static void UserAnalog2_OnChange(void);
static void UserAnalog3_OnChange(void);
static void UserAnalog4_OnChange(void);
static void Analog_OnChange(void);
static void Analog2_OnChange(void);
static void Analog3_OnChange(void);
@@ -446,10 +442,10 @@ consvar_t cv_analog = {"analog", "Off", CV_CALL, CV_OnOff, Analog_OnChange, 0, N
consvar_t cv_analog2 = {"analog2", "Off", CV_CALL, CV_OnOff, Analog2_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_analog3 = {"analog3", "Off", CV_CALL, CV_OnOff, Analog3_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_analog4 = {"analog4", "Off", CV_CALL, CV_OnOff, Analog4_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_useranalog = {"useranalog", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_useranalog2 = {"useranalog2", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_useranalog3 = {"useranalog3", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog3_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_useranalog4 = {"useranalog4", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog4_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_useranalog = {"useranalog", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_useranalog2 = {"useranalog2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_useranalog3 = {"useranalog3", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_useranalog4 = {"useranalog4", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_turnaxis = {"joyaxis_turn", "Left X", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_moveaxis = {"joyaxis_move", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -511,8 +507,8 @@ static CV_PossibleValue_t driftsparkpulse_t[] = {{0, "MIN"}, {FRACUNIT*3, "MAX"}
consvar_t cv_driftsparkpulse = {"driftsparkpulse", "1.4", CV_FLOAT | CV_SAVE, driftsparkpulse_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t stretchfactor_t[] = {
{0, "Off"}, {FRACUNIT/8, "0.125"}, {FRACUNIT/4, "0.250"},
{3*FRACUNIT/8, "0.375"}, {FRACUNIT/2, "0.500"}, {5*FRACUNIT/8, "0.625"},
{0, "Off"}, {FRACUNIT/8, "0.125"}, {FRACUNIT/4, "0.250"},
{3*FRACUNIT/8, "0.375"}, {FRACUNIT/2, "0.500"}, {5*FRACUNIT/8, "0.625"},
{3*FRACUNIT/4, "0.750"}, {7*FRACUNIT/8, "0.875"}, {FRACUNIT, "Max"}, {0, NULL}};
consvar_t cv_gravstretch = {"gravstretch", "0", CV_SAVE, stretchfactor_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -596,15 +592,6 @@ void G_ClearRecords(void)
}
}
// For easy retrieval of records
/*UINT32 G_GetBestScore(INT16 map)
{
if (!mainrecords[map-1])
return 0;
return mainrecords[map-1]->score;
}*/
tic_t G_GetBestTime(INT16 map)
{
if (!mainrecords[map-1] || mainrecords[map-1]->time <= 0)
@@ -980,7 +967,7 @@ static INT32 Joy3Axis(axis_input_e axissel)
}
if (flp) retaxis = -retaxis; //flip it around
return retaxis;
}
else
{
@@ -1000,7 +987,7 @@ static INT32 Joy3Axis(axis_input_e axissel)
}
if (flp) retaxis = -retaxis; //flip it around
return retaxis;
}
}
@@ -1075,7 +1062,7 @@ static INT32 Joy4Axis(axis_input_e axissel)
}
if (flp) retaxis = -retaxis; //flip it around
return retaxis;
}
else
{
@@ -1095,7 +1082,7 @@ static INT32 Joy4Axis(axis_input_e axissel)
}
if (flp) retaxis = -retaxis; //flip it around
return retaxis;
}
}
@@ -1197,11 +1184,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
// why build a ticcmd if we're paused?
// Or, for that matter, if we're being reborn.
// Kart, don't build a ticcmd if someone is resynching or the server is stopped too so we don't fly off course in bad conditions
if (paused || P_AutoPause() || (gamestate == GS_LEVEL && player->playerstate == PST_REBORN) || hu_resynching
#ifdef SATURNSYNCH
|| hu_redownloadinggamestate
#endif
)
if (paused || P_AutoPause() || (gamestate == GS_LEVEL && player->playerstate == PST_REBORN) || hu_resynching)
{
cmd->angleturn = (INT16)(lang >> 16);
cmd->aiming = G_ClipAimingPitch(&laim);
@@ -1509,65 +1492,20 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
//Reset away view if a command is given.
if ((cmd->forwardmove || cmd->sidemove || cmd->buttons)
&& displayplayers[0] != consoleplayer && ssplayer == 1)
{
displayplayers[0] = consoleplayer;
// i dont like this lmao
if (cv_director.value)
CV_SetValue(&cv_director, 0);
}
}
// User has designated that they want
// analog ON, so tell the game to stop
// fudging with it.
static void UserAnalog_OnChange(void)
{
/*if (cv_useranalog.value)
CV_SetValue(&cv_analog, 1);
else
CV_SetValue(&cv_analog, 0);*/
}
static void UserAnalog2_OnChange(void)
{
if (botingame)
return;
/*if (cv_useranalog2.value)
CV_SetValue(&cv_analog2, 1);
else
CV_SetValue(&cv_analog2, 0);*/
}
static void UserAnalog3_OnChange(void)
{
if (botingame)
return;
/*if (cv_useranalog3.value)
CV_SetValue(&cv_analog3, 1);
else
CV_SetValue(&cv_analog3, 0);*/
}
static void UserAnalog4_OnChange(void)
{
if (botingame)
return;
/*if (cv_useranalog4.value)
CV_SetValue(&cv_analog4, 1);
else
CV_SetValue(&cv_analog4, 0);*/
}
static void Analog_OnChange(void)
{
if (!cv_cam_dist.string)
return;
// cameras are not initialized at this point
/*
if (!cv_chasecam.value && cv_analog.value) {
CV_SetValue(&cv_analog, 0);
return;
}
*/
SendWeaponPref();
}
@@ -1576,15 +1514,6 @@ static void Analog2_OnChange(void)
if (!(splitscreen || botingame) || !cv_cam2_dist.string)
return;
// cameras are not initialized at this point
/*
if (!cv_chasecam2.value && cv_analog2.value) {
CV_SetValue(&cv_analog2, 0);
return;
}
*/
SendWeaponPref2();
}
@@ -1593,15 +1522,6 @@ static void Analog3_OnChange(void)
if (splitscreen < 2 || !cv_cam3_dist.string)
return;
// cameras are not initialized at this point
/*
if (!cv_chasecam3.value && cv_analog3.value) {
CV_SetValue(&cv_analog3, 0);
return;
}
*/
SendWeaponPref3();
}
@@ -1610,15 +1530,6 @@ static void Analog4_OnChange(void)
if (splitscreen < 3 || !cv_cam4_dist.string)
return;
// cameras are not initialized at this point
/*
if (!cv_chasecam4.value && cv_analog4.value) {
CV_SetValue(&cv_analog4, 0);
return;
}
*/
SendWeaponPref4();
}
@@ -1694,6 +1605,8 @@ void G_DoLoadLevel(boolean resetplayer)
// clear hud messages remains (usually from game startup)
CON_ClearHUD();
G_ResetAllDeviceRumbles();
}
static INT32 pausedelay = 0;
@@ -1952,7 +1865,6 @@ boolean G_Responder(event_t *ev)
|| ev->data1 == gamecontrol[gc_director][1])
{
K_ToggleDirector();
directortoggletimer = 0;
}
return true;
@@ -2084,6 +1996,29 @@ INT32 G_CountPlayersPotentiallyViewable(boolean active)
return total;
}
//
// G_FixCamera
// Reset camera position, angle and interpolation on a view
// after changing state.
//
static void G_FixCamera(UINT8 view)
{
player_t *player = &players[displayplayers[view - 1]];
// The order of displayplayers can change, which would
// invalidate localangle.
localangle[view - 1] = player->cmd.angleturn;
P_ResetCamera(player, &camera[view - 1]);
// Make sure the viewport doesn't interpolate at all into
// its new position -- just snap instantly into place.
// Why does it need to be done twice?
R_ResetViewInterpolation(view);
R_ResetViewInterpolation(view);
}
//
// G_ResetView
// Correct a viewpoint to playernum or the next available, wraps forward.
@@ -2096,7 +2031,6 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive)
UINT8 viewd;
INT32 *displayplayerp;
camera_t *camerap;
INT32 olddisplayplayer;
INT32 playersviewable;
@@ -2133,31 +2067,20 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive)
/* Focus our target view first so that we don't take its player. */
(*displayplayerp) = playernum;
if ((*displayplayerp) != olddisplayplayer)
{
camerap = &camera[viewnum-1];
P_ResetCamera(&players[(*displayplayerp)], camerap);
// Make sure the viewport doesn't interpolate at all into
// its new position -- just snap instantly into place.
R_ResetViewInterpolation(viewnum);
}
/* If a viewpoint changes, reset the camera to clear uninitialized memory. */
if (viewnum > splits)
{
for (viewd = splits+1; viewd < viewnum; ++viewd)
for (viewd = splits+1; viewd <= viewnum; ++viewd)
{
displayplayerp = (&displayplayers[viewd-1]);
camerap = &camera[viewd];
(*displayplayerp) = G_FindView(0, viewd, onlyactive, false);
P_ResetCamera(&players[(*displayplayerp)], camerap);
// Make sure the viewport doesn't interpolate at all into
// its new position -- just snap instantly into place.
R_ResetViewInterpolation(viewd);
G_FixCamera(viewd);
}
}
else
{
if ((*displayplayerp) != olddisplayplayer)
{
G_FixCamera(viewnum);
}
}
@@ -2239,13 +2162,6 @@ void G_Ticker(boolean run)
if (!(netgame || multiplayer) && G_GetRetryFlag())
{
G_ClearRetryFlag();
// Costs a life to retry ... unless the player in question is dead already.
/*if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE)
players[consoleplayer].lives -= 1;
G_DoReborn(consoleplayer);*/
D_MapChange(gamemap, gametype, cv_kartencore.value, true, 1, false, false);
}
@@ -2558,21 +2474,6 @@ void G_PlayerReborn(INT32 player)
bot = players[player].bot;
pity = players[player].pity;
if (leveltime <= starttime) // man i really hope this crap works kek but need to reset this somehow at mapstart
{
for (i = 0; i < LAP__MAX; i++)
{
laptime[i] = 0;
}
}
else
{
for (i = 0; i < LAP__MAX; i++)
{
laptime[i] = players[player].laptime[i];
}
}
// SRB2kart
if (leveltime <= starttime || spectator == true)
{
@@ -2593,6 +2494,11 @@ void G_PlayerReborn(INT32 player)
starpostnum = 0;
respawnflip = 0;
starpostangle = 0;
for (i = 0; i < LAP__MAX; i++)
{
laptime[i] = 0;
}
}
else
{
@@ -2621,6 +2527,11 @@ void G_PlayerReborn(INT32 player)
bumper = players[player].kartstuff[k_bumper];
comebackpoints = players[player].kartstuff[k_comebackpoints];
wanted = players[player].kartstuff[k_wanted];
for (i = 0; i < LAP__MAX; i++)
{
laptime[i] = players[player].laptime[i];
}
}
spectatorreentry = players[player].spectatorreentry;
@@ -3139,6 +3050,8 @@ void G_AddPlayer(INT32 playernum)
void G_ExitLevel(void)
{
G_ResetAllDeviceRumbles();
if (gamestate == GS_LEVEL)
{
gameaction = ga_completed;
@@ -3167,13 +3080,6 @@ const char *Gametype_Names[NUMGAMETYPES] =
{
"Race", // GT_RACE
"Battle" // GT_MATCH
/*"Co-op", // GT_COOP
"Competition", // GT_COMPETITION
"Team Match", // GT_TEAMMATCH
"Tag", // GT_TAG
"Hide and Seek", // GT_HIDEANDSEEK
"CTF" // GT_CTF*/
};
//
@@ -3235,12 +3141,7 @@ boolean G_GametypeHasTeams(void)
//
boolean G_GametypeHasSpectators(void)
{
// SRB2Kart: We don't have any exceptions to not being able to spectate yet. Maybe when SP & bots roll around.
#if 0
return (gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE);
#else
return (netgame || (multiplayer && demo.playback)); //true
#endif
}
//
@@ -4275,14 +4176,11 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
Z_Free(savebuffer);
save_p = savebuffer = NULL;
// gameaction = ga_nothing;
// G_SetGamestate(GS_LEVEL);
displayplayers[0] = consoleplayer;
multiplayer = false;
splitscreen = 0;
SplitScreen_OnChange(); // not needed?
// G_DeferedInitNew(sk_medium, G_BuildMapName(1), 0, 0, 1);
if (setsizeneeded)
R_ExecuteSetViewSize();
@@ -4487,6 +4385,7 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool
else
{
LUAh_MapChange(gamemap);
S_CheckMap();
G_DoLoadLevel(resetplayer);
}
@@ -4648,8 +4547,7 @@ INT32 G_FindMap(const char *mapname, char **foundmapnamep,
break;
}
}
else
if (apromapnum == 0 || wanttable)
else if (apromapnum == 0 || wanttable)
{
/* LEVEL 1--match keywords verbatim */
if (( aprop = strcasestr(realmapname, mapname) ))
@@ -4740,6 +4638,8 @@ INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep)
{
if (mapname[0] == '*') // current map
return gamemap;
else if (mapname[0] == '?' && mapheaderinfo[gamemap-1])
return G_RandMap(G_TOLFlag(gametype), gamemap-1, false, 0, false, NULL)+1;
else if (mapname[0] == '+' && mapheaderinfo[gamemap-1]) // next map
{
newmapnum = mapheaderinfo[gamemap-1]->nextlevel;
@@ -6491,8 +6391,18 @@ void G_BeginRecording(void)
// Full replay title
demo_p += 64;
{
char demotitlename[65];
char *title = G_BuildMapTitle(gamemap);
snprintf(demo.titlename, 64, "%s - %s", title, modeattacking ? "Time Attack" : connectedservername);
// Print to a separate temp buffer instead of demo.titlename, so we can use it in M_TextInputSetString
snprintf(demotitlename, 64, "%s - %s", title, modeattacking ? "Time Attack" : connectedservername);
// Init just in case it isn't initialized already
M_TextInputInit(&demo.titlenameinput, demo.titlename, sizeof(demo.titlename));
// This will indirectly assign to demo.titlename too
M_TextInputSetString(&demo.titlenameinput, demotitlename);
Z_Free(title);
}
@@ -7862,9 +7772,6 @@ void G_AddGhost(char *defdemoname)
case ATTACKING_RECORD: // 1
p += 8; // demo time, lap
break;
/*case ATTACKING_NIGHTS: // 2
p += 8; // demo time left, score
break;*/
default: // 3
break;
}
@@ -8485,7 +8392,6 @@ void G_SaveDemo(void)
boolean G_DemoTitleResponder(event_t *ev)
{
size_t len;
INT32 ch;
if (ev->type != ev_keydown)
@@ -8506,28 +8412,7 @@ boolean G_DemoTitleResponder(event_t *ev)
return true;
}
if ((ch >= HU_FONTSTART && ch <= HU_FONTEND && hu_font[ch-HU_FONTSTART])
|| ch == ' ') // Allow spaces, of course
{
len = strlen(demo.titlename);
if (len < 64)
{
demo.titlename[len+1] = 0;
demo.titlename[len] = cv_keyboardlayout.value == 3 ? CON_ShitAndAltGrChar(ch) : CON_ShiftChar(ch);
}
}
else if (ch == KEY_BACKSPACE)
{
if (shiftdown)
memset(demo.titlename, 0, sizeof(demo.titlename));
else
{
len = strlen(demo.titlename);
if (len > 0)
demo.titlename[len-1] = 0;
}
}
M_TextInputHandle(&demo.titlenameinput, ch);
return true;
}
@@ -8540,7 +8425,6 @@ boolean G_DemoTitleResponder(event_t *ev)
void G_SetGamestate(gamestate_t newstate)
{
gamestate = newstate;
#ifdef HAVE_DISCORDRPC
DRPC_UpdatePresence();
#endif
@@ -8613,4 +8497,3 @@ INT32 G_TicsToMilliseconds(tic_t tics)
{
return (INT32)((tics%TICRATE) * (1000.00f/TICRATE));
}
+4 -10
View File
@@ -17,6 +17,7 @@
#include "doomdef.h"
#include "doomstat.h"
#include "d_event.h"
#include "m_textinput.h"
extern char gamedatafilename[64];
extern char timeattackfolder[64];
@@ -44,6 +45,7 @@ extern consvar_t cv_recordmultiplayerdemos, cv_netdemosyncquality, cv_maxdemosiz
// Publicly-accessible demo vars
struct demovars_s {
char titlename[65];
textinput_t titlenameinput;
boolean recording, playback, timing;
UINT16 version; // Current file format of the demo being played
boolean title; // Title Screen demo can be cancelled by any key
@@ -417,19 +419,9 @@ void G_SetGamestate(gamestate_t newstate);
// Gamedata record shit
void G_AllocMainRecordData(INT16 i);
//void G_AllocNightsRecordData(INT16 i);
void G_ClearRecords(void);
//UINT32 G_GetBestScore(INT16 map);
tic_t G_GetBestTime(INT16 map);
//tic_t G_GetBestLap(INT16 map);
//UINT16 G_GetBestRings(INT16 map);
//UINT32 G_GetBestNightsScore(INT16 map, UINT8 mare);
//tic_t G_GetBestNightsTime(INT16 map, UINT8 mare);
//UINT8 G_GetBestNightsGrade(INT16 map, UINT8 mare);
//void G_AddTempNightsRecords(UINT32 pscore, tic_t ptime, UINT8 mare);
//void G_SetNightsRecords(void);
FUNCMATH INT32 G_TicsToHours(tic_t tics);
FUNCMATH INT32 G_TicsToMinutes(tic_t tics, boolean full);
@@ -437,6 +429,8 @@ FUNCMATH INT32 G_TicsToSeconds(tic_t tics);
FUNCMATH INT32 G_TicsToCentiseconds(tic_t tics);
FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics);
boolean K_DirectorIsPlayerAlone(void); // idk where else to put this lol
// Don't split up TOL handling
INT16 G_TOLFlag(INT32 pgametype);
+15
View File
@@ -1013,6 +1013,21 @@ static void G_ResetPlayerDeviceRumble(INT32 player)
I_GamepadRumble(device_id, 0, 0, 0);
}
void G_ResetAllDeviceRumbles(void)
{
int i;
int devices;
devices = I_NumJoys();
for (i = 0; i < devices; i++)
{
INT32 device_id = G_GetDeviceForPlayer(i);
I_GamepadRumble(device_id, 0, 0, 0);
}
}
void G_PlayerDeviceRumble(INT32 player, UINT16 low_strength, UINT16 high_strength, UINT32 duration)
{
INT32 device_id;
+1
View File
@@ -138,6 +138,7 @@ UINT16 G_GetSkinColor(INT32 player);
INT32 G_GetDeviceForPlayer(INT32 player);
void G_SetPlayerGamepadIndicatorColor(INT32 player, UINT16 color);
void G_PlayerDeviceRumble(INT32 player, UINT16 low_strength, UINT16 high_strength, UINT32 duration);
void G_ResetAllDeviceRumbles(void);
// remaps the input event to a game control.
void G_MapEventsToControls(event_t *ev);
+23 -21
View File
@@ -46,12 +46,12 @@ int unsortedVertexArrayAllocSize = 65536;
// Call HWR_RenderBatches to render all the collected geometry.
void HWR_StartBatching(void)
{
if (currently_batching)
if (currently_batching)
{
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
}
// init arrays if that has not been done yet
// init arrays if that has not been done yet
if (!finalVertexArray)
{
finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector));
@@ -61,7 +61,7 @@ void HWR_StartBatching(void)
unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector));
}
currently_batching = true;
currently_batching = true;
}
// This replaces the direct calls to pfnSetTexture in cases where batching is available.
@@ -69,14 +69,14 @@ void HWR_StartBatching(void)
// Doing this was easier than getting a texture pointer to HWR_ProcessPolygon.
void HWR_SetCurrentTexture(GLMipmap_t *texture)
{
if (currently_batching)
{
current_texture = texture;
}
else
{
HWD.pfnSetTexture(texture);
}
if (currently_batching)
{
current_texture = texture;
}
else
{
HWD.pfnSetTexture(texture);
}
}
// If batching is enabled, this function collects the polygon data and the chosen texture
@@ -84,7 +84,7 @@ void HWR_SetCurrentTexture(GLMipmap_t *texture)
// render the polygon immediately.
void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader_target, boolean horizonSpecial)
{
if (currently_batching)
if (currently_batching)
{
if (!pSurf)
I_Error("Got a null FSurfaceInfo in batching");// nulls should not come in the stuff that batching currently applies to
@@ -220,7 +220,7 @@ static int comparePolygonsNoShaders(const void *p1, const void *p2)
// the rendering backend to draw them.
void HWR_RenderBatches(void)
{
int finalVertexWritePos = 0;// position in finalVertexArray
int finalVertexWritePos = 0;// position in finalVertexArray
int finalIndexWritePos = 0;// position in finalVertexIndexArray
int polygonReadPos = 0;// position in polygonArraySorted
@@ -236,7 +236,7 @@ void HWR_RenderBatches(void)
int i;
if (!currently_batching)
if (!currently_batching)
I_Error("HWR_RenderBatches called without starting batching");
nextSurfaceInfo.LightInfo.fade_end = 0;
@@ -256,6 +256,7 @@ void HWR_RenderBatches(void)
ps_hw_numcalls.value.i = ps_hw_numverts.value.i = 0;
ps_hw_numshaders.value.i = ps_hw_numtextures.value.i
= ps_hw_numpolyflags.value.i = ps_hw_numcolors.value.i = 1;
// init polygonArraySorted
for (i = 0; i < polygonArraySize; i++)
{
@@ -264,11 +265,12 @@ void HWR_RenderBatches(void)
// sort polygons
PS_START_TIMING(ps_hw_batchsorttime);
if (cv_grshaders.value && gr_shadersavailable)
if (cv_glshaders.value && gl_shadersavailable)
qs22j(polygonArraySorted, polygonArraySize, sizeof(PolygonArrayEntry *), comparePolygons);
else
qs22j(polygonArraySorted, polygonArraySize, sizeof(PolygonArrayEntry *), comparePolygonsNoShaders);
PS_STOP_TIMING(ps_hw_batchsorttime);
// sort order
// 1. shader
// 2. texture
@@ -287,14 +289,14 @@ void HWR_RenderBatches(void)
// set state for first batch
if (cv_grshaders.value && gr_shadersavailable)
if (cv_glshaders.value && gl_shadersavailable)
{
HWD.pfnSetShader(currentShader);
}
if (currentPolyFlags & PF_NoTexture)
currentTexture = NULL;
else
else
HWD.pfnSetTexture(currentTexture);
while (1)// note: remember handling notexture polyflag as having texture number 0 (also in comparePolygons)
@@ -369,7 +371,7 @@ void HWR_RenderBatches(void)
nextSurfaceInfo = nextEntry->surf;
if (nextPolyFlags & PF_NoTexture)
nextTexture = 0;
if (currentShader != nextShader && cv_grshaders.value && gr_shadersavailable)
if (currentShader != nextShader && cv_glshaders.value && gl_shadersavailable)
{
changeState = true;
changeShader = true;
@@ -384,7 +386,7 @@ void HWR_RenderBatches(void)
changeState = true;
changePolyFlags = true;
}
if (cv_grshaders.value && gr_shadersavailable)
if (cv_glshaders.value && gl_shadersavailable)
{
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba ||
currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba ||
@@ -457,6 +459,7 @@ void HWR_RenderBatches(void)
ps_hw_numcolors.value.i++;
}
// and that should be it?
}
}
// reset the arrays (set sizes to 0)
@@ -466,5 +469,4 @@ void HWR_RenderBatches(void)
PS_STOP_TIMING(ps_hw_batchdrawtime);
}
#endif // HWRENDER
+8 -8
View File
@@ -46,7 +46,7 @@ typedef struct
// when loading the map, this is set to true if portals are found.
// if no portals are found, the portal scanning phase can be skipped while rendering, saving a bit of time.
boolean gr_maphasportals = false;
boolean gl_maphasportals = false;
// ==========================================================================
// FLOOR & CEILING CONVEX POLYS GENERATION
@@ -371,14 +371,14 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly)
line_t *line = lseg->linedef;
// portal check
if (!gr_maphasportals && line->special == 40 && lseg->side == 0)
if (!gl_maphasportals && line->special == 40 && lseg->side == 0)
{
// Find the other side!
INT32 line2 = P_FindSpecialLineFromTag(40, line->tag, -1);
if (line == &lines[line2])
line2 = P_FindSpecialLineFromTag(40, line->tag, line2);
if (line2 >= 0) // found it!
gr_maphasportals = 1;
gl_maphasportals = 1;
}
p1.x = FIXED_TO_FLOAT(lseg->side ? line->v2->x : line->v1->x);
@@ -768,7 +768,7 @@ static INT32 SolveTProblem(void)
INT32 i;
size_t l;
if (cv_grsolvetjoin.value == 0)
if (cv_glsolvetjoin.value == 0)
return 0;
CONS_Debug(DBG_RENDER, "Solving T-joins. This may take a while. Please wait...\n");
@@ -905,7 +905,7 @@ void HWR_CreatePlanePolygons(INT32 bspnum)
#endif
// reset the portal flag
gr_maphasportals = 0;
gl_maphasportals = 0;
// find min/max boundaries of map
//CONS_Debug(DBG_RENDER, "Looking for boundaries of map...\n");
@@ -923,9 +923,9 @@ void HWR_CreatePlanePolygons(INT32 bspnum)
I_Error("couldn't malloc extrasubsectors totsubsectors %s\n", sizeu1(totsubsectors));
// allocate table for back to front drawing of subsectors
/*gr_drawsubsectors = (INT16 *)malloc(sizeof (*gr_drawsubsectors) * totsubsectors);
if (!gr_drawsubsectors)
I_Error("couldn't malloc gr_drawsubsectors\n");*/
/*gl_drawsubsectors = (INT16 *)malloc(sizeof (*gl_drawsubsectors) * totsubsectors);
if (!gl_drawsubsectors)
I_Error("couldn't malloc gl_drawsubsectors\n");*/
// number of the first new subsector that might be added
addsubsector = numsubsectors;
+132 -133
View File
@@ -166,7 +166,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
if (pwidth <= 0 || pheight <= 0)
return;
palette = HWR_GetTexturePalette();
ncols = pwidth;
@@ -216,7 +216,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
if (texture->width <= 0 || texture->height <= 0)
return;
palette = HWR_GetTexturePalette();
x1 = patch->originx;
@@ -275,15 +275,15 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
}
}
static UINT8 *MakeBlock(GLMipmap_t *grMipmap)
static UINT8 *MakeBlock(GLMipmap_t *glMipmap)
{
UINT8 *block;
INT32 bpp, i;
UINT16 bu16 = ((0x00 <<8) | HWR_PATCHES_CHROMAKEY_COLORINDEX);
INT32 blocksize = (grMipmap->width * grMipmap->height);
INT32 blocksize = (glMipmap->width * glMipmap->height);
bpp = format2bpp(grMipmap->format);
block = Z_Malloc(blocksize*bpp, PU_HWRCACHE, &(grMipmap->data));
bpp = format2bpp(glMipmap->format);
block = Z_Malloc(blocksize*bpp, PU_HWRCACHE, &(glMipmap->data));
switch (bpp)
{
@@ -303,7 +303,7 @@ static UINT8 *MakeBlock(GLMipmap_t *grMipmap)
// Create a composite texture from patches, adapt the texture size to a power of 2
// height and width for the hardware texture cache.
//
static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, boolean noencore)
static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *gltex, boolean noencore)
{
UINT8 *block;
texture_t *texture;
@@ -313,7 +313,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, boolean noe
INT32 i;
boolean skyspecial = false; //poor hack for Legacy large skies..
RGBA_t *palette;
palette = HWR_GetTexturePalette();
@@ -328,30 +328,30 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, boolean noe
)
{
skyspecial = true;
grtex->mipmap.flags = TF_WRAPXY; // don't use the chromakey for sky
gltex->mipmap.flags = TF_WRAPXY; // don't use the chromakey for sky
}
else
grtex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY;
gltex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY;
grtex->mipmap.width = (UINT16)texture->width;
grtex->mipmap.height = (UINT16)texture->height;
gltex->mipmap.width = (UINT16)texture->width;
gltex->mipmap.height = (UINT16)texture->height;
if (skyspecial)
grtex->mipmap.format = GL_TEXFMT_RGBA; // that skyspecial code below assumes this format ...
gltex->mipmap.format = GL_TEXFMT_RGBA; // that skyspecial code below assumes this format ...
else
grtex->mipmap.format = textureformat;
gltex->mipmap.format = textureformat;
grtex->mipmap.colormap = colormaps;
gltex->mipmap.colormap = colormaps;
#ifdef GLENCORE
if (encoremap && !noencore)
grtex->mipmap.colormap += COLORMAP_REMAPOFFSET;
gltex->mipmap.colormap += COLORMAP_REMAPOFFSET;
#endif
blockwidth = texture->width;
blockheight = texture->height;
blocksize = (blockwidth * blockheight);
block = MakeBlock(&grtex->mipmap);
block = MakeBlock(&gltex->mipmap);
if (skyspecial) //Hurdler: not efficient, but better than holes in the sky (and it's done only at level loading)
{
@@ -375,7 +375,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, boolean noe
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
{
realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE);
HWR_DrawTexturePatchInCache(&grtex->mipmap,
HWR_DrawTexturePatchInCache(&gltex->mipmap,
blockwidth, blockheight,
texture, patch,
realpatch);
@@ -383,78 +383,78 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, boolean noe
}
//Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :(
if (format2bpp(grtex->mipmap.format)==4)
if (format2bpp(gltex->mipmap.format)==4)
{
for (i = 3; i < blocksize*4; i += 4) // blocksize*4 because blocksize doesn't include the bpp
{
if (block[i] != 0)
continue;
grtex->mipmap.flags |= TF_TRANSPARENT;
gltex->mipmap.flags |= TF_TRANSPARENT;
break;
}
}
grtex->scaleX = 1.0f/(texture->width*FRACUNIT);
grtex->scaleY = 1.0f/(texture->height*FRACUNIT);
gltex->scaleX = 1.0f/(texture->width*FRACUNIT);
gltex->scaleY = 1.0f/(texture->height*FRACUNIT);
}
// patch may be NULL if grMipmap has been initialised already and makebitmap is false
void HWR_MakePatch (patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap)
// patch may be NULL if glMipmap has been initialised already and makebitmap is false
void HWR_MakePatch (patch_t *patch, GLPatch_t *glPatch, GLMipmap_t *glMipmap, boolean makebitmap)
{
// don't do it twice (like a cache)
if (grMipmap->width == 0)
if (glMipmap->width == 0)
{
// save the original patch header so that the GLPatch can be casted
// into a standard patch_t struct and the existing code can get the
// orginal patch dimensions and offsets.
grPatch->width = SHORT(patch->width);
grPatch->height = SHORT(patch->height);
grPatch->leftoffset = SHORT(patch->leftoffset);
grPatch->topoffset = SHORT(patch->topoffset);
glPatch->width = SHORT(patch->width);
glPatch->height = SHORT(patch->height);
glPatch->leftoffset = SHORT(patch->leftoffset);
glPatch->topoffset = SHORT(patch->topoffset);
//grMipmap->width = (UINT16)SHORT(patch->width);
//grMipmap->height = (UINT16)SHORT(patch->height);
grMipmap->width = grMipmap->height = 1;
while (grMipmap->width < grPatch->width) grMipmap->width <<= 1;
while (grMipmap->height < grPatch->height) grMipmap->height <<= 1;
//glMipmap->width = (UINT16)SHORT(patch->width);
//glMipmap->height = (UINT16)SHORT(patch->height);
glMipmap->width = glMipmap->height = 1;
while (glMipmap->width < glPatch->width) glMipmap->width <<= 1;
while (glMipmap->height < glPatch->height) glMipmap->height <<= 1;
// no wrap around, no chroma key
grMipmap->flags = 0;
glMipmap->flags = 0;
// setup the texture info
grMipmap->format = patchformat;
//grPatch->max_s = grPatch->max_t = 1.0f;
grPatch->max_s = (float)grPatch->width / (float)grMipmap->width;
grPatch->max_t = (float)grPatch->height / (float)grMipmap->height;
glMipmap->format = patchformat;
//glPatch->max_s = glPatch->max_t = 1.0f;
glPatch->max_s = (float)glPatch->width / (float)glMipmap->width;
glPatch->max_t = (float)glPatch->height / (float)glMipmap->height;
}
Z_Free(grMipmap->data);
grMipmap->data = NULL;
Z_Free(glMipmap->data);
glMipmap->data = NULL;
if (makebitmap)
{
MakeBlock(grMipmap);
HWR_DrawPatchInCache(grMipmap,
grMipmap->width, grMipmap->height,
grPatch->width, grPatch->height,
MakeBlock(glMipmap);
HWR_DrawPatchInCache(glMipmap,
glMipmap->width, glMipmap->height,
glPatch->width, glPatch->height,
patch);
}
//grPatch->max_s = grPatch->max_t = 1.0f;
//glPatch->max_s = glPatch->max_t = 1.0f;
}
// =================================================
// CACHING HANDLING
// =================================================
static size_t gr_numtextures;
static GLMapTexture_t *gr_textures; // For all textures
static size_t gl_numtextures;
static GLMapTexture_t *gl_textures; // For all textures
void HWR_InitTextureCache(void)
{
gr_numtextures = 0;
gr_textures = NULL;
gl_numtextures = 0;
gl_textures = NULL;
}
// Callback function for HWR_FreeTextureCache.
@@ -526,10 +526,10 @@ void HWR_FreeTextureCache(void)
// now the heap don't have any 'user' pointing to our
// texturecache info, we can free it
if (gr_textures)
free(gr_textures);
gr_textures = NULL;
gr_numtextures = 0;
if (gl_textures)
free(gl_textures);
gl_textures = NULL;
gl_numtextures = 0;
}
void HWR_LoadTextures(size_t pnumtextures)
@@ -537,13 +537,13 @@ void HWR_LoadTextures(size_t pnumtextures)
// we must free it since numtextures changed
HWR_FreeTextureCache();
gr_numtextures = pnumtextures;
gl_numtextures = pnumtextures;
#ifdef GLENCORE
gr_textures = calloc(pnumtextures, sizeof (*gr_textures)*2); // *2 - 1 for encore-remapped texture and another for noencore texture (unused when not in encore)
gl_textures = calloc(pnumtextures, sizeof (*gl_textures)*2); // *2 - 1 for encore-remapped texture and another for noencore texture (unused when not in encore)
#else
gr_textures = calloc(pnumtextures, sizeof (*gr_textures));
gl_textures = calloc(pnumtextures, sizeof (*gl_textures));
#endif
if (gr_textures == NULL)
if (gl_textures == NULL)
I_Error("HWR_LoadTextures: ran out of memory for OpenGL textures. Sad!");
}
@@ -552,9 +552,9 @@ void HWR_LoadTextures(size_t pnumtextures)
// --------------------------------------------------------------------------
GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean noencore)
{
GLMapTexture_t *grtex;
GLMapTexture_t *gltex;
if (tex < 0 || tex >= (signed)gr_numtextures)
if (tex < 0 || tex >= (signed)gl_numtextures)
{
#ifdef PARANOIA
I_Error("HWR_GetTexture: Invalid texture ID %d", tex);
@@ -563,25 +563,25 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean noencore)
#endif
}
#ifdef GLENCORE
grtex = &gr_textures[tex*2 + (encoremap && !noencore ? 0 : 1)];
gltex = &gl_textures[tex*2 + (encoremap && !noencore ? 0 : 1)];
#else
grtex = &gr_textures[tex];
gltex = &gl_textures[tex];
#endif
if (!grtex->mipmap.data && !grtex->mipmap.downloaded)
HWR_GenerateTexture(tex, grtex, noencore);
if (!gltex->mipmap.data && !gltex->mipmap.downloaded)
HWR_GenerateTexture(tex, gltex, noencore);
// If hardware does not have the texture, then call pfnSetTexture to upload it
if (!grtex->mipmap.downloaded)
HWD.pfnSetTexture(&grtex->mipmap);
HWR_SetCurrentTexture(&grtex->mipmap);
if (!gltex->mipmap.downloaded)
HWD.pfnSetTexture(&gltex->mipmap);
HWR_SetCurrentTexture(&gltex->mipmap);
// The system-memory data can be purged now.
Z_ChangeTag(grtex->mipmap.data, PU_HWRCACHE_UNLOCKED);
Z_ChangeTag(gltex->mipmap.data, PU_HWRCACHE_UNLOCKED);
return grtex;
return gltex;
}
static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
static void HWR_CacheFlat(GLMipmap_t *glMipmap, lumpnum_t flatlumpnum)
{
#ifdef GLENCORE
UINT8 *flat;
@@ -590,8 +590,8 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
size_t size, pflatsize;
// setup the texture info
grMipmap->format = GL_TEXFMT_P_8;
grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED;
glMipmap->format = GL_TEXFMT_P_8;
glMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED;
size = W_LumpLength(flatlumpnum);
@@ -619,21 +619,21 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
pflatsize = 64;
break;
}
grMipmap->width = (UINT16)pflatsize;
grMipmap->height = (UINT16)pflatsize;
glMipmap->width = (UINT16)pflatsize;
glMipmap->height = (UINT16)pflatsize;
// the flat raw data needn't be converted with palettized textures
W_ReadLump(flatlumpnum, Z_Malloc(W_LumpLength(flatlumpnum),
PU_HWRCACHE, &grMipmap->data));
PU_HWRCACHE, &glMipmap->data));
#ifdef GLENCORE
flat = grMipmap->data;
flat = glMipmap->data;
for (steppy = 0; steppy < size; steppy++)
{
if (flat[steppy] == HWR_PATCHES_CHROMAKEY_COLORINDEX)
continue;
flat[steppy] = grMipmap->colormap[flat[steppy]];
flat[steppy] = glMipmap->colormap[flat[steppy]];
}
#endif
}
@@ -641,44 +641,44 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
// Download a Doom 'flat' to the hardware cache and make it ready for use
void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencoremap)
{
GLMipmap_t *grmip;
GLMipmap_t *glmip;
if (flatlumpnum == LUMPERROR)
return;
grmip = HWR_GetCachedGLPatch(flatlumpnum)->mipmap;
glmip = HWR_GetCachedGLPatch(flatlumpnum)->mipmap;
grmip->colormap = colormaps;
glmip->colormap = colormaps;
#ifdef GLENCORE
if (!noencoremap && encoremap)
grmip->colormap += COLORMAP_REMAPOFFSET;
glmip->colormap += COLORMAP_REMAPOFFSET;
#endif
if (!grmip->downloaded && !grmip->data)
HWR_CacheFlat(grmip, flatlumpnum);
if (!glmip->downloaded && !glmip->data)
HWR_CacheFlat(glmip, flatlumpnum);
// If hardware does not have the texture, then call pfnSetTexture to upload it
if (!grmip->downloaded)
HWD.pfnSetTexture(grmip);
HWR_SetCurrentTexture(grmip);
if (!glmip->downloaded)
HWD.pfnSetTexture(glmip);
HWR_SetCurrentTexture(glmip);
// The system-memory data can be purged now.
Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED);
Z_ChangeTag(glmip->data, PU_HWRCACHE_UNLOCKED);
}
//
// HWR_LoadMappedPatch(): replace the skin color of the sprite in cache
// : load it first in doom cache if not already
//
static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch)
static void HWR_LoadMappedPatch(GLMipmap_t *glmip, GLPatch_t *gpatch)
{
if (!grmip->downloaded && !grmip->data)
if (!glmip->downloaded && !glmip->data)
{
patch_t *patch = gpatch->rawpatch;
if (!patch)
patch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
HWR_MakePatch(patch, gpatch, grmip, true);
HWR_MakePatch(patch, gpatch, glmip, true);
// You can't free rawpatch for some reason?
// (Obviously I can't, sprite rotation needs that...)
@@ -688,12 +688,12 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch)
}
// If hardware does not have the texture, then call pfnSetTexture to upload it
if (!grmip->downloaded)
HWD.pfnSetTexture(grmip);
HWR_SetCurrentTexture(grmip);
if (!glmip->downloaded)
HWD.pfnSetTexture(glmip);
HWR_SetCurrentTexture(glmip);
// The system-memory data can be purged now.
Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED);
Z_ChangeTag(glmip->data, PU_HWRCACHE_UNLOCKED);
}
// -----------------+
@@ -732,7 +732,7 @@ void HWR_GetPatch(GLPatch_t *gpatch)
// -------------------+
void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap)
{
GLMipmap_t *grmip, *newmip;
GLMipmap_t *glmip, *newmip;
// Blatant hack for encore colormapping aside...
if (colormap == colormaps || colormap == NULL || colormap == (const UINT8*)(COLORMAP_REMAPOFFSET))
@@ -744,14 +744,14 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap)
// search for the mimmap
// skip the first (no colormap translated)
for (grmip = gpatch->mipmap; grmip->nextcolormap; )
for (glmip = gpatch->mipmap; glmip->nextcolormap; )
{
grmip = grmip->nextcolormap;
glmip = glmip->nextcolormap;
if (grmip->colormap != colormap)
if (glmip->colormap != colormap)
continue;
HWR_LoadMappedPatch(grmip, gpatch);
HWR_LoadMappedPatch(glmip, gpatch);
return;
}
// not found, create it!
@@ -764,7 +764,7 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap)
newmip = calloc(1, sizeof (*newmip));
if (newmip == NULL)
I_Error("%s: Out of memory", "HWR_GetMappedPatch");
grmip->nextcolormap = newmip;
glmip->nextcolormap = newmip;
newmip->colormap = colormap;
HWR_LoadMappedPatch(newmip, gpatch);
@@ -781,18 +781,18 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch)
GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum)
{
aatree_t *hwrcache = wadfiles[wadnum]->hwrcache;
GLPatch_t *grpatch;
GLPatch_t *glpatch;
if (!(grpatch = M_AATreeGet(hwrcache, lumpnum)))
if (!(glpatch = M_AATreeGet(hwrcache, lumpnum)))
{
grpatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL);
grpatch->wadnum = wadnum;
grpatch->lumpnum = lumpnum;
grpatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL);
M_AATreeSet(hwrcache, lumpnum, grpatch);
glpatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL);
glpatch->wadnum = wadnum;
glpatch->lumpnum = lumpnum;
glpatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL);
M_AATreeSet(hwrcache, lumpnum, glpatch);
}
return grpatch;
return glpatch;
}
GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum)
@@ -840,14 +840,14 @@ static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32
Z_Free(flat);
}
static void HWR_CacheFadeMask(GLMipmap_t *grMipmap, lumpnum_t fademasklumpnum)
static void HWR_CacheFadeMask(GLMipmap_t *glMipmap, lumpnum_t fademasklumpnum)
{
size_t size;
UINT16 fmheight = 0, fmwidth = 0;
// setup the texture info
grMipmap->format = GL_TEXFMT_ALPHA_8; // put the correct alpha levels straight in so I don't need to convert it later
grMipmap->flags = 0;
glMipmap->format = GL_TEXFMT_ALPHA_8; // put the correct alpha levels straight in so I don't need to convert it later
glMipmap->flags = 0;
size = W_LumpLength(fademasklumpnum);
@@ -876,28 +876,28 @@ static void HWR_CacheFadeMask(GLMipmap_t *grMipmap, lumpnum_t fademasklumpnum)
}
// Thankfully, this will still work for this scenario
grMipmap->width = fmwidth;
grMipmap->height = fmheight;
glMipmap->width = fmwidth;
glMipmap->height = fmheight;
MakeBlock(grMipmap);
MakeBlock(glMipmap);
HWR_DrawFadeMaskInCache(grMipmap, fmwidth, fmheight, fademasklumpnum, fmwidth, fmheight);
HWR_DrawFadeMaskInCache(glMipmap, fmwidth, fmheight, fademasklumpnum, fmwidth, fmheight);
// I DO need to convert this because it isn't power of 2 and we need the alpha
}
void HWR_GetFadeMask(lumpnum_t fademasklumpnum)
{
GLMipmap_t *grmip;
GLMipmap_t *glmip;
grmip = HWR_GetCachedGLPatch(fademasklumpnum)->mipmap;
glmip = HWR_GetCachedGLPatch(fademasklumpnum)->mipmap;
if (!grmip->downloaded && !grmip->data)
HWR_CacheFadeMask(grmip, fademasklumpnum);
if (!glmip->downloaded && !glmip->data)
HWR_CacheFadeMask(glmip, fademasklumpnum);
HWD.pfnSetTexture(grmip);
HWD.pfnSetTexture(glmip);
// The system-memory data can be purged now.
Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED);
Z_ChangeTag(glmip->data, PU_HWRCACHE_UNLOCKED);
}
// =================================================
@@ -909,15 +909,15 @@ void HWR_SetPalette(RGBA_t *palette)
if (HWR_ShouldUsePaletteRendering())
{
// set the palette for palette postprocessing
if (cv_grpalettedepth.value == 16)
if (cv_glpalettedepth.value == 16)
{
// crush to 16-bit rgb565, like software currently does in the standard configuration
// Note: Software's screenshots have the 24-bit palette, but the screen gets
// the 16-bit version! For making comparison screenshots either use an external screenshot
// tool or set the palette depth to 24 bits.
RGBA_t crushed_palette[256];
int i;
for (i = 0; i < 256; i++)
for (int i = 0; i < 256; i++)
{
float fred = (float)(palette[i].s.red >> 3);
float fgreen = (float)(palette[i].s.green >> 2);
@@ -935,7 +935,7 @@ void HWR_SetPalette(RGBA_t *palette)
}
// this part is responsible for keeping track of the palette OUTSIDE of a level.
if ((!(gamestate == GS_LEVEL)) || (gamestate == GS_TITLESCREEN))
if (gamestate != GS_LEVEL || gamestate == GS_TITLESCREEN)
HWR_SetMapPalette();
}
else
@@ -987,11 +987,9 @@ void HWR_SetMapPalette(void)
RGBA_t *palette;
int i;
if ((!(gamestate == GS_LEVEL)) || (gamestate == GS_TITLESCREEN))
if (gamestate != GS_LEVEL || gamestate == GS_TITLESCREEN)
{
// outside of a level, pMasterPalette should have PLAYPAL ready for us
//palette = pMasterPalette; // we dont have this in kart so just use pLocalPalette as before
// outside of a level, pLocalPalette should have PLAYPAL ready for us
palette = pLocalPalette;
}
else
@@ -1001,8 +999,10 @@ void HWR_SetMapPalette(void)
lumpnum_t lumpnum = W_GetNumForName(GetPalette());
size_t palsize = W_LumpLength(lumpnum);
UINT8 *RGB_data;
if (palsize < 768) // 256 * 3
I_Error("HWR_SetMapPalette: A programmer assumed palette lumps are at least 768 bytes long, but apparently this was a wrong assumption!\n");
RGB_data = W_CacheLumpNum(lumpnum, PU_CACHE);
// we got the RGB palette now, but we need it in RGBA format.
for (i = 0; i < 256; i++)
@@ -1050,7 +1050,6 @@ UINT32 HWR_CreateLightTable(UINT8 *lighttable)
return id;
}
// get hwr lighttable id for colormap, create it if it doesn't already exist
UINT32 HWR_GetLightTableID(extracolormap_t *colormap)
{
+1 -6
View File
@@ -121,8 +121,6 @@ typedef struct
poly_t *planepoly; // the generated convex polygon
} extrasubsector_t;
//here lies gr_vissprite
// Kart features
#define USE_FTRANSFORM_ANGLEZ
#define USE_FTRANSFORM_MIRROR
@@ -156,7 +154,7 @@ typedef struct
boolean mirrorflip; // Encore Mode with Flipcam
#endif
boolean shearing; // 14042019
angle_t viewaiming; // 17052019
float viewaiming; // 17052019
} FTransform;
// Transformed vector, as passed to HWR API
@@ -289,9 +287,6 @@ typedef struct FSurfaceInfo FSurfaceInfo;
enum hwdsetspecialstate
{
#ifdef USE_FBO_OGL
HWD_SET_FRAMEBUFFER,
#endif
HWD_SET_SHADERS,
HWD_SET_TEXTUREFILTERMODE,
+10 -10
View File
@@ -569,7 +569,7 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength)
if (color & 0xFF00) // Do COLORMAP fade.
{
if (HWR_ShouldUsePaletteRendering() && cv_grscreentextures.value)
if (HWR_ShouldUsePaletteRendering() && cv_glscreentextures.value)
{
const hwdscreentexture_t scr_tex = HWD_SCREENTEXTURE_GENERIC2;
@@ -593,12 +593,12 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength)
{
RGBA_t *palette = HWR_GetTexturePalette();
Surf.PolyColor.rgba = palette[color&0xFF].rgba;
if (HWR_ShouldUsePaletteRendering())
Surf.PolyColor.s.alpha = softwaretranstogl[strength];
else
Surf.PolyColor.s.alpha = (UINT8)(strength*25.5f);
poly_flags |= PF_Translucent;
}
@@ -652,17 +652,17 @@ void HWR_DrawViewBorder(INT32 clearlines)
INT32 basewindowx, basewindowy;
GLPatch_t *patch;
// if (gr_viewwidth == vid.width)
// if (gl_viewwidth == vid.width)
// return;
if (!clearlines)
clearlines = BASEVIDHEIGHT; // refresh all
// calc view size based on original game resolution
baseviewwidth = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_viewwidth), vid.fdupx)); //(cv_viewsize.value * BASEVIDWIDTH/10)&~7;
baseviewheight = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_viewheight), vid.fdupy));
top = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_baseviewwindowy), vid.fdupy));
side = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_baseviewwindowx), vid.fdupx));
baseviewwidth = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewwidth), vid.fdupx)); //(cv_viewsize.value * BASEVIDWIDTH/10)&~7;
baseviewheight = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewheight), vid.fdupy));
top = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_baseviewwindowy), vid.fdupy));
side = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_baseviewwindowx), vid.fdupx));
// top
HWR_DrawFlatFill(0, 0,
@@ -776,9 +776,9 @@ void HWR_drawAMline(const fline_t *fl, INT32 color)
F2DCoord v1, v2;
RGBA_t color_rgba;
RGBA_t *palette = HWR_GetTexturePalette();
color_rgba = palette[color&0xFF];
v1.x = ((float)fl->a.x-(vid.width/2.0f))*(2.0f/vid.width);
v1.y = ((float)fl->a.y-(vid.height/2.0f))*(2.0f/vid.height);
+3 -12
View File
@@ -23,7 +23,7 @@
// needed for sprite rendering
// equivalent of the software renderer's vissprites
typedef struct gr_vissprite_s
typedef struct gl_vissprite_s
{
float x1, x2;
float z1, z2;
@@ -32,7 +32,6 @@ typedef struct gr_vissprite_s
float scale;
float spritexscale, spriteyscale;
float spritexoffset, spriteyoffset;
UINT32 renderflags;
GLPatch_t *gpatch;
boolean flip;
UINT8 translucency; //alpha level 0-255
@@ -42,7 +41,7 @@ typedef struct gr_vissprite_s
//Hurdler: 25/04/2000: now support colormap in hardware mode
UINT8 *colormap;
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
} gr_vissprite_t;
} gl_vissprite_t;
// --------
// hw_bsp.c
@@ -64,7 +63,7 @@ void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencoremap);
GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean noencore);
void HWR_GetPatch(GLPatch_t *gpatch);
void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap);
void HWR_MakePatch(patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap);
void HWR_MakePatch(patch_t *patch, GLPatch_t *glPatch, GLMipmap_t *glMipmap, boolean makebitmap);
void HWR_UnlockCachedPatch(GLPatch_t *gpatch);
void HWR_SetPalette(RGBA_t *palette);
@@ -82,14 +81,6 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
extern INT32 patchformat;
extern INT32 textureformat;
// --------
// hw_main.c // originally hw_drawnodes.c from HWPortal branch
// --------
void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, boolean noencore, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap);
void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap);
void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap);
// --------
// hw_shaders.c
// --------
+1014 -1385
View File
File diff suppressed because it is too large. Load diff
+63 -60
View File
@@ -23,6 +23,7 @@
#include "hw_glob.h"
#include "hw_data.h"
#include "hw_defs.h"
#include "hw_portal.h"
#include "../am_map.h"
#include "../d_player.h"
@@ -35,15 +36,32 @@
void HWR_Startup(void);
void HWR_Shutdown(void);
extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowx, gr_baseviewwindowy;
extern float gl_viewwidth, gl_viewheight, gl_baseviewwindowx, gl_baseviewwindowy;
extern float gr_basewindowcenterx, gr_basewindowcentery;
extern float gl_basewindowcenterx, gl_basewindowcentery;
extern unsigned msaa;
extern boolean a2c;
extern FTransform atransform;
extern float gr_viewsin, gr_viewcos;
extern float gl_viewsin, gl_viewcos;
extern boolean gl_drawing_stencil;
extern seg_t *gl_curline;
extern side_t *gl_sidedef;
extern line_t *gl_linedef;
extern sector_t *gl_frontsector;
extern sector_t *gl_backsector;
enum
{
HWR_STENCIL_NORMAL,
HWR_STENCIL_BEGIN,
HWR_STENCIL_REVERSE,
HWR_STENCIL_DEPTH,
HWR_STENCIL_SKY
};
// Performance stats
extern ps_metric_t ps_hw_nodesorttime;
@@ -62,7 +80,7 @@ extern ps_metric_t ps_hw_numcolors;
extern ps_metric_t ps_hw_batchsorttime;
extern ps_metric_t ps_hw_batchdrawtime;
extern boolean gr_shadersavailable;
extern boolean gl_shadersavailable;
// hw_draw.c
void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option);
@@ -81,24 +99,25 @@ UINT8 *HWR_GetScreenshot(void);
boolean HWR_Screenshot(const char *lbmname);
// hw_main.c
void HWR_RenderFrame(INT32 viewnumber, player_t *player, boolean skybox);
void HWR_RenderPlayerView(INT32 viewnumber, player_t *player);
void HWR_SetViewSize(void);
void HWR_AddCommands(void);
void HWR_RenderPlayerView(INT32 viewnumber, player_t *player);
void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, player_t *player, int stencil_level, boolean allow_portals);
void HWR_SetTransform(float fpov, player_t *player);
void HWR_ClearClipper(void);
void HWR_SetStencilState(int state, int level);
boolean HWR_UseShader(void);
boolean HWR_ShouldUsePaletteRendering(void);
boolean HWR_PalRenderFlashpal(void);
void HWR_TogglePaletteRendering(void);
// My original intention was to split hw_main.c
// into files like hw_bsp.c, hw_sprites.c...
// hw_main.c: Lighting and fog
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap);
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf);
@@ -106,7 +125,6 @@ FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf);
INT32 HWR_GetTextureUsed(void);
// hw_main.c: Post-rendering
void HWR_DoPostProcessor(player_t *player);
void HWR_StartScreenWipe(void);
void HWR_EndScreenWipe(void);
void HWR_DrawIntermissionBG(void);
@@ -115,70 +133,55 @@ void HWR_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT
void HWR_MakeScreenFinalTexture(void);
void HWR_DrawScreenFinalTexture(INT32 width, INT32 height);
// hw_main.c: Planes
void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap);
void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap);
void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap);
void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap);
// hw_main.c: Segs
void HWR_ProcessSeg(void); // Sort of like GLWall::Process in GZDoom
void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap);
void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap);
void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo * pSurf, INT32 texnum, boolean noencore, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap);
// moved HWR_SplitWall to hw_main.c
void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf);
void HWR_DrawSkyBackground(float fpov);
// hw_main.c: Sprites
void HWR_AddSprites(sector_t *sec);
void HWR_ProjectSprite(mobj_t *thing);
//void HWR_ProjectPrecipitationSprite(precipmobj_t *thing);
void HWR_DrawSprites(void);
// hw_bsp.c
void HWR_CreatePlanePolygons(INT32 bspnum);
extern boolean gr_maphasportals;
extern boolean gl_maphasportals;
// hw_cache.c
void HWR_LoadTextures(size_t pnumtextures);
RGBA_t *HWR_GetTexturePalette(void);
void HWR_SetShaderState(void);
// Console variables
extern consvar_t cv_grshaders;
extern CV_PossibleValue_t glanisotropicmode_cons_t[];
extern consvar_t cv_glscreentextures;
#ifdef USE_FBO_OGL
extern consvar_t cv_grframebuffer;
extern consvar_t cv_glframebuffer;
#endif
extern consvar_t cv_splitwallfix;
extern consvar_t cv_grshearing;
extern consvar_t cv_grfov;
extern consvar_t cv_grmdls;
extern consvar_t cv_grfog;
extern consvar_t cv_grfogdensity;
extern consvar_t cv_grfiltermode;
extern consvar_t cv_granisotropicmode;
extern consvar_t cv_grcorrecttricks;
extern consvar_t cv_grfovchange;
extern consvar_t cv_grsolvetjoin;
extern consvar_t cv_grspritebillboarding;
extern consvar_t cv_grfakecontrast;
extern consvar_t cv_grslopecontrast;
extern consvar_t cv_grhorizonlines;
extern consvar_t cv_grfallbackplayermodel;
extern consvar_t cv_grbatching;
extern consvar_t cv_grrenderdistance;
extern consvar_t cv_grpaletterendering;
extern consvar_t cv_grpalettedepth;
extern consvar_t cv_grflashpal;
extern consvar_t cv_lightdither;
extern consvar_t cv_grscreentextures;
extern consvar_t cv_grportals;
extern consvar_t cv_nostencil;
extern consvar_t cv_secbright;
extern CV_PossibleValue_t granisotropicmode_cons_t[];
extern consvar_t cv_glmdls;
extern consvar_t cv_glfallbackplayermodel;
extern consvar_t cv_glspritebillboarding;
extern consvar_t cv_glshearing;
extern consvar_t cv_glfakecontrast;
extern consvar_t cv_glslopecontrast;
extern consvar_t cv_glshaders;
extern consvar_t cv_gllightdither;
extern consvar_t cv_glsecbright;
extern consvar_t cv_glfiltermode;
extern consvar_t cv_glanisotropicmode;
extern consvar_t cv_glsolvetjoin;
extern consvar_t cv_glbatching;
extern consvar_t cv_glrenderdistance;
extern consvar_t cv_glhorizonlines;
extern consvar_t cv_glportals;
extern consvar_t cv_glfovchange;
extern consvar_t cv_glpaletterendering;
extern consvar_t cv_glpalettedepth;
extern consvar_t cv_glflashpal;
#endif
+83 -83
View File
@@ -147,7 +147,7 @@ static void PNG_warn(png_structp PNG, png_const_charp pngtext)
CONS_Debug(DBG_RENDER, "libpng warning at %p: %s", PNG, pngtext);
}
static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_t *grpatch)
static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_t *glpatch)
{
png_structp png_ptr;
png_infop png_info_ptr;
@@ -201,7 +201,7 @@ static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_
//CONS_Debug(DBG_RENDER, "libpng load error on %s\n", filename);
png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL);
fclose(png_FILE);
Z_Free(grpatch->mipmap->data);
Z_Free(glpatch->mipmap->data);
return 0;
}
#ifdef USE_FAR_KEYWORD
@@ -242,7 +242,7 @@ static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_
{
png_uint_32 i, pitch = png_get_rowbytes(png_ptr, png_info_ptr);
png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRCACHE, &grpatch->mipmap->data);
png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRCACHE, &glpatch->mipmap->data);
png_bytepp row_pointers = png_malloc(png_ptr, height * sizeof (png_bytep));
for (i = 0; i < height; i++)
row_pointers[i] = PNG_image + i*pitch;
@@ -282,7 +282,7 @@ typedef struct
} PcxHeader;
static GLTextureFormat_t PCX_Load(const char *filename, int *w, int *h,
GLPatch_t *grpatch)
GLPatch_t *glpatch)
{
PcxHeader header;
#define PALSIZE 768
@@ -322,7 +322,7 @@ static GLTextureFormat_t PCX_Load(const char *filename, int *w, int *h,
pw = *w = header.xmax - header.xmin + 1;
ph = *h = header.ymax - header.ymin + 1;
image = Z_Malloc(pw*ph*4, PU_HWRCACHE, &grpatch->mipmap->data);
image = Z_Malloc(pw*ph*4, PU_HWRCACHE, &glpatch->mipmap->data);
if (fread(palette, sizeof (UINT8), PALSIZE, file) != PALSIZE)
{
@@ -364,43 +364,43 @@ static GLTextureFormat_t PCX_Load(const char *filename, int *w, int *h,
// -----------------+
static void md2_loadTexture(md2_t *model)
{
GLPatch_t *grpatch;
GLPatch_t *glpatch;
const char *filename = model->filename;
if (model->grpatch)
if (model->glpatch)
{
grpatch = model->grpatch;
Z_Free(grpatch->mipmap->data);
glpatch = model->glpatch;
Z_Free(glpatch->mipmap->data);
}
else
{
grpatch = Z_Calloc(sizeof *grpatch, PU_HWRPATCHINFO,
&(model->grpatch));
grpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL);
glpatch = Z_Calloc(sizeof *glpatch, PU_HWRPATCHINFO,
&(model->glpatch));
glpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL);
}
if (!grpatch->mipmap->downloaded && !grpatch->mipmap->data)
if (!glpatch->mipmap->downloaded && !glpatch->mipmap->data)
{
int w = 0, h = 0;
#ifdef HAVE_PNG
grpatch->mipmap->format = PNG_Load(filename, &w, &h, grpatch);
if (grpatch->mipmap->format == 0)
glpatch->mipmap->format = PNG_Load(filename, &w, &h, glpatch);
if (glpatch->mipmap->format == 0)
#endif
grpatch->mipmap->format = PCX_Load(filename, &w, &h, grpatch);
if (grpatch->mipmap->format == 0)
glpatch->mipmap->format = PCX_Load(filename, &w, &h, glpatch);
if (glpatch->mipmap->format == 0)
{
grpatch->notfound = true;// mark it so its not searched for again repeatedly
glpatch->notfound = true;// mark it so its not searched for again repeatedly
return;
}
grpatch->mipmap->downloaded = 0;
grpatch->mipmap->flags = 0;
glpatch->mipmap->downloaded = 0;
glpatch->mipmap->flags = 0;
grpatch->width = (INT16)w;
grpatch->height = (INT16)h;
grpatch->mipmap->width = (UINT16)w;
grpatch->mipmap->height = (UINT16)h;
glpatch->width = (INT16)w;
glpatch->height = (INT16)h;
glpatch->mipmap->width = (UINT16)w;
glpatch->mipmap->height = (UINT16)h;
// for palette rendering, color cube is applied in post-processing instead of here
if (!HWR_ShouldUsePaletteRendering())
@@ -408,7 +408,7 @@ static void md2_loadTexture(md2_t *model)
UINT32 size;
RGBA_t *image;
// Lactozilla: Apply colour cube
image = grpatch->mipmap->data;
image = glpatch->mipmap->data;
size = w*h;
while (size--)
{
@@ -417,8 +417,8 @@ static void md2_loadTexture(md2_t *model)
}
}
}
HWD.pfnSetTexture(grpatch->mipmap);
HWR_UnlockCachedPatch(grpatch);
HWD.pfnSetTexture(glpatch->mipmap);
HWR_UnlockCachedPatch(glpatch);
}
// -----------------+
@@ -426,49 +426,49 @@ static void md2_loadTexture(md2_t *model)
// -----------------+
static void md2_loadBlendTexture(md2_t *model)
{
GLPatch_t *grpatch;
GLPatch_t *glpatch;
char *filename = Z_Malloc(strlen(model->filename)+7, PU_STATIC, NULL);
strcpy(filename, model->filename);
FIL_ForceExtension(filename, "_blend.png");
if (model->blendgrpatch)
if (model->blendglpatch)
{
grpatch = model->blendgrpatch;
Z_Free(grpatch->mipmap->data);
glpatch = model->blendglpatch;
Z_Free(glpatch->mipmap->data);
}
else
{
grpatch = Z_Calloc(sizeof *grpatch, PU_HWRPATCHINFO,
&(model->blendgrpatch));
grpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL);
glpatch = Z_Calloc(sizeof *glpatch, PU_HWRPATCHINFO,
&(model->blendglpatch));
glpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL);
}
if (!grpatch->mipmap->downloaded && !grpatch->mipmap->data)
if (!glpatch->mipmap->downloaded && !glpatch->mipmap->data)
{
int w = 0, h = 0;
#ifdef HAVE_PNG
grpatch->mipmap->format = PNG_Load(filename, &w, &h, grpatch);
if (grpatch->mipmap->format == 0)
glpatch->mipmap->format = PNG_Load(filename, &w, &h, glpatch);
if (glpatch->mipmap->format == 0)
#endif
grpatch->mipmap->format = PCX_Load(filename, &w, &h, grpatch);
if (grpatch->mipmap->format == 0)
glpatch->mipmap->format = PCX_Load(filename, &w, &h, glpatch);
if (glpatch->mipmap->format == 0)
{
grpatch->notfound = true;// mark it so its not searched for again repeatedly
glpatch->notfound = true;// mark it so its not searched for again repeatedly
Z_Free(filename);
return;
}
grpatch->mipmap->downloaded = 0;
grpatch->mipmap->flags = 0;
glpatch->mipmap->downloaded = 0;
glpatch->mipmap->flags = 0;
grpatch->width = (INT16)w;
grpatch->height = (INT16)h;
grpatch->mipmap->width = (UINT16)w;
grpatch->mipmap->height = (UINT16)h;
glpatch->width = (INT16)w;
glpatch->height = (INT16)h;
glpatch->mipmap->width = (UINT16)w;
glpatch->mipmap->height = (UINT16)h;
}
HWD.pfnSetTexture(grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary
HWR_UnlockCachedPatch(grpatch);
HWD.pfnSetTexture(glpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary
HWR_UnlockCachedPatch(glpatch);
Z_Free(filename);
}
@@ -489,7 +489,7 @@ void HWR_InitMD2(void)
{
md2_playermodels[s].scale = -1.0f;
md2_playermodels[s].model = NULL;
md2_playermodels[s].grpatch = NULL;
md2_playermodels[s].glpatch = NULL;
md2_playermodels[s].skin = -1;
md2_playermodels[s].notfound = true;
md2_playermodels[s].error = false;
@@ -498,7 +498,7 @@ void HWR_InitMD2(void)
{
md2_localplayermodels[s].scale = -1.0f;
md2_localplayermodels[s].model = NULL;
md2_localplayermodels[s].grpatch = NULL;
md2_localplayermodels[s].glpatch = NULL;
md2_localplayermodels[s].skin = -1;
md2_localplayermodels[s].notfound = true;
md2_localplayermodels[s].error = false;
@@ -507,7 +507,7 @@ void HWR_InitMD2(void)
{
md2_models[i].scale = -1.0f;
md2_models[i].model = NULL;
md2_models[i].grpatch = NULL;
md2_models[i].glpatch = NULL;
md2_models[i].skin = -1;
md2_models[i].notfound = true;
md2_models[i].error = false;
@@ -680,7 +680,7 @@ spritemd2found:
#define SETBRIGHTNESS(brightness,r,g,b) \
brightness = (UINT8)(((1063*(UINT32)(r))/5000) + ((3576*(UINT32)(g))/5000) + ((361*(UINT32)(b))/5000))
static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color)
static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *glmip, INT32 skinnum, skincolors_t color)
{
UINT16 w = gpatch->width, h = gpatch->height;
UINT32 size = w*h;
@@ -696,24 +696,24 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
memset(translation, 0, sizeof(translation));
memset(cutoff, 0, sizeof(cutoff));
if (grmip->width == 0)
if (glmip->width == 0)
{
grmip->width = gpatch->width;
grmip->height = gpatch->height;
glmip->width = gpatch->width;
glmip->height = gpatch->height;
// no wrap around, no chroma key
grmip->flags = 0;
glmip->flags = 0;
// setup the texture info
grmip->format = GL_TEXFMT_RGBA;
glmip->format = GL_TEXFMT_RGBA;
}
if (grmip->data)
if (glmip->data)
{
Z_Free(grmip->data);
grmip->data = NULL;
Z_Free(glmip->data);
glmip->data = NULL;
}
cur = Z_Malloc(size*4, PU_HWRCACHE, &grmip->data);
cur = Z_Malloc(size*4, PU_HWRCACHE, &glmip->data);
memset(cur, 0x00, size*4);
image = gpatch->mipmap->data;
@@ -1044,7 +1044,7 @@ skippixel:
static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT32 skinnum, const UINT8 *colormap, skincolors_t color)
{
// mostly copied from HWR_GetMappedPatch, hence the similarities and comment
GLMipmap_t *grmip, *newmip;
GLMipmap_t *glmip, *newmip;
if (colormap == colormaps || colormap == NULL)
{
@@ -1055,15 +1055,15 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT
// search for the mimmap
// skip the first (no colormap translated)
for (grmip = gpatch->mipmap; grmip->nextcolormap; )
for (glmip = gpatch->mipmap; glmip->nextcolormap; )
{
grmip = grmip->nextcolormap;
if (grmip->colormap == colormap)
glmip = glmip->nextcolormap;
if (glmip->colormap == colormap)
{
if (grmip->downloaded && grmip->data)
if (glmip->downloaded && glmip->data)
{
HWD.pfnSetTexture(grmip); // found the colormap, set it to the correct texture
Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED);
HWD.pfnSetTexture(glmip); // found the colormap, set it to the correct texture
Z_ChangeTag(glmip->data, PU_HWRCACHE_UNLOCKED);
return;
}
}
@@ -1079,7 +1079,7 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT
newmip = calloc(1, sizeof (*newmip));
if (newmip == NULL)
I_Error("%s: Out of memory", "HWR_GetMappedPatch");
grmip->nextcolormap = newmip;
glmip->nextcolormap = newmip;
newmip->colormap = colormap;
HWR_CreateBlendedTexture(gpatch, blendgpatch, newmip, skinnum, color);
@@ -1095,7 +1095,7 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT
// Returns :
// -----------------+
void HWR_DrawMD2(gr_vissprite_t *spr)
void HWR_DrawMD2(gl_vissprite_t *spr)
{
md2_t *md2;
@@ -1105,7 +1105,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
FTransform p;
FSurfaceInfo Surf;
if (!cv_grmdls.value)
if (!cv_glmdls.value)
return;
if (spr->precip)
@@ -1164,7 +1164,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
angle_t ang;
interpmobjstate_t interp;
if (R_UsingFrameInterpolation() && !paused && (!cv_grmaxinterpdist.value || R_QuickCamDist(spr->mobj->x, spr->mobj->y) < cv_grmaxinterpdist.value))
if (R_UsingFrameInterpolation() && !paused && (!cv_maxinterpdist.value || R_QuickCamDist(spr->mobj->x, spr->mobj->y) < cv_maxinterpdist.value))
{
R_InterpolateMobjState(spr->mobj, rendertimefrac, &interp);
}
@@ -1244,22 +1244,22 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
}
}
//Hurdler: arf, I don't like that implementation at all... too much crappy
gpatch = md2->grpatch;
gpatch = md2->glpatch;
if (!gpatch || ((!gpatch->mipmap->format || !gpatch->mipmap->downloaded) && !gpatch->notfound))
md2_loadTexture(md2);
gpatch = md2->grpatch; // Load it again, because it isn't being loaded into gpatch after md2_loadtexture...
gpatch = md2->glpatch; // Load it again, because it isn't being loaded into gpatch after md2_loadtexture...
if ((gpatch && gpatch->mipmap->format) // don't load the blend texture if the base texture isn't available
&& (!md2->blendgrpatch
|| ((!((GLPatch_t *)md2->blendgrpatch)->mipmap->format || !((GLPatch_t *)md2->blendgrpatch)->mipmap->downloaded)
&& !((GLPatch_t *)md2->blendgrpatch)->notfound)))
&& (!md2->blendglpatch
|| ((!((GLPatch_t *)md2->blendglpatch)->mipmap->format || !((GLPatch_t *)md2->blendglpatch)->mipmap->downloaded)
&& !((GLPatch_t *)md2->blendglpatch)->notfound)))
md2_loadBlendTexture(md2);
if (gpatch && gpatch->mipmap->format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture
{
if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE &&
md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap->format
&& gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height)
md2->blendglpatch && ((GLPatch_t *)md2->blendglpatch)->mipmap->format
&& gpatch->width == ((GLPatch_t *)md2->blendglpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendglpatch)->height)
{
INT32 tcskinnum = TC_DEFAULT;
if ((spr->mobj->flags & MF_BOSS) && (spr->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
@@ -1284,7 +1284,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
}
else tcskinnum = TC_DEFAULT;
}
HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, tcskinnum, spr->colormap, (skincolors_t)spr->mobj->color);
HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendglpatch, tcskinnum, spr->colormap, (skincolors_t)spr->mobj->color);
}
else
{
@@ -1313,7 +1313,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
// Interpolate the model interpolation. (lol)
tics -= FixedToFloat(rendertimefrac);
if (cv_grmdls.value == 1 && tics <= durs)
if (cv_glmdls.value == 1 && tics <= durs)
{
// frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation
if (spr->mobj->frame & FF_ANIMATE)
@@ -1478,8 +1478,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
float oy = ys * flipfactor*FIXED_TO_FLOAT(interp.spriteyoffset);
// offset perpendicular to the camera angle
p.x -= ox * gr_viewsin;
p.y += ox * gr_viewcos;
p.x -= ox * gl_viewsin;
p.y += ox * gl_viewcos;
p.z += oy;
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, md2->scale * xs, md2->scale * ys, flip, hflip, &Surf);
+3 -3
View File
@@ -28,8 +28,8 @@ typedef struct
float scale;
float offset;
model_t *model;
void *grpatch;
void *blendgrpatch;
void *glpatch;
void *blendglpatch;
boolean notfound;
INT32 skin;
boolean error;
@@ -40,7 +40,7 @@ extern md2_t md2_playermodels[MAXSKINS];
extern md2_t md2_localplayermodels[MAXLOCALSKINS];
void HWR_InitMD2(void);
void HWR_DrawMD2(gr_vissprite_t *spr);
void HWR_DrawMD2(gl_vissprite_t *spr);
void HWR_AddPlayerMD2(INT32 skin, boolean local);
void HWR_AddSpriteMD2(size_t spritenum);
+227
View File
@@ -0,0 +1,227 @@
// SONIC ROBO BLAST 2 KART
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
// Copyright (C) 2000 by DooM Legacy Team.
// Copyright (C) 1996 by id Software, Inc.
//
// 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 hw_portal.c
/// \brief OpenGL renderer portals.
// ==========================================================================
// Visual portals (attr. Hannu Hanhi)
// ==========================================================================
#ifdef HWRENDER
#include "../r_portal.h"
#include "../z_zone.h"
#include "hw_clip.h"
#include "hw_drv.h"
#include "hw_defs.h"
#include "hw_main.h"
#include "hw_portal.h"
SINT8 gl_portal_state = GLPORTAL_OFF;
gl_portallist_t *currentportallist;
// clip the area outside the portal destination window
void HWR_PortalClipping(gl_portal_t *portal)
{
gld_clipper_SafeAddClipRange(portal->angle1, portal->angle2);
}
static gl_portal_t* HWR_Portal_Add (seg_t *seg)
{
gl_portal_t *portal = Z_Malloc(sizeof(gl_portal_t), PU_STATIC, NULL);
// Linked list.
if (!currentportallist->base)
{
currentportallist->base = portal;
currentportallist->cap = portal;
}
else
{
currentportallist->cap->next = portal;
currentportallist->cap = portal;
}
portal->next = NULL;
portal->seg = seg;
return portal;
}
void HWR_FreePortalList(gl_portallist_t freelist)
{
portalcullsector = NULL;
// free memory from portal list allocated by calls to Add2Lines
gl_portal_t *gl_portal_temp = freelist.base;
while (gl_portal_temp)
{
gl_portal_t *nextportal = gl_portal_temp->next;
Z_Free(gl_portal_temp);
gl_portal_temp = nextportal;
}
}
void HWR_Portal_Add2Lines(const INT32 line1, const INT32 line2, seg_t *seg)
{
gl_portal_t *portal = HWR_Portal_Add(seg);
// Offset the portal view by the linedef centers
line_t* start = &lines[line1];
line_t* dest = &lines[line2];
angle_t dangle = R_PointToAngle2(0, 0, dest->dx, dest->dy) - R_PointToAngle2(start->dx, start->dy, 0, 0);
fixed_t disttopoint;
angle_t angtopoint;
vertex_t dest_c, start_c;
// looking glass center
start_c.x = start->v1->x/2 + start->v2->x/2;
start_c.y = start->v1->y/2 + start->v2->y/2;
// other side center
dest_c.x = dest->v1->x/2 + dest->v2->x/2;
dest_c.y = dest->v1->y/2 + dest->v2->y/2;
disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy);
angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy);
angtopoint += dangle;
portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight;
portal->viewangle = viewangle + dangle;
portal->angle1 = R_PointToAngle64(seg->v1->x, seg->v1->y) + dangle;
portal->angle2 = R_PointToAngle64(seg->v2->x, seg->v2->y) + dangle;
portal->clipline = line2;
}
void HWR_PortalFrame(gl_portal_t* portal)
{
viewx = portal->viewx;
viewy = portal->viewy;
viewz = portal->viewz;
viewangle = portal->viewangle;
//viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
//viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
if (portal->clipline != -1)
{
portalclipline = &lines[portal->clipline];
portalcullsector = portalclipline->frontsector;
viewsector = portalclipline->frontsector;
}
else
{
portalclipline = NULL;
portalcullsector = NULL;
viewsector = R_PointInSubsector(viewx, viewy)->sector;
}
}
// Renders a portal segment.
static void HWR_RenderPortalSeg(gl_portal_t* portal, SINT8 state)
{
gl_drawing_stencil = true; // do not draw outside of the stencil buffer, idiot.
// set our portal state and prepare to render the seg
HWR_SetPortalState(state);
gl_curline = portal->seg;
gl_frontsector = portal->seg->frontsector;
gl_backsector = portal->seg->backsector;
HWR_ProcessSeg();
gl_drawing_stencil = false;
// need to work around the r_opengl PF_Invisible bug with this call
// similarly as in the linkdraw hack in HWR_DrawSprites
HWD.pfnSetBlend(PF_Translucent|PF_Occlude|PF_Masked);
}
// Renders a single portal from the current viewpoint.
void HWR_RenderPortal(gl_portal_t* portal, gl_portal_t* rootportal, const float fpov, player_t *player, int stencil_level)
{
// draw portal seg to stencil buffer with increment
HWR_SetTransform(fpov, player);
HWR_ClearClipper();
HWR_SetStencilState(HWR_STENCIL_BEGIN, stencil_level);
HWR_RenderPortalSeg(portal, GLPORTAL_STENCIL);
// go to portal frame lmao
HWR_PortalFrame(portal);
// call HWR_RenderViewpoint
HWR_RenderViewpoint(portal, fpov, player, stencil_level + 1, true);
// return to current frame
if (rootportal)
HWR_PortalFrame(rootportal);
else // current frame is not a portal frame but the main view!
{
R_SetupFrame(player, false);
portalclipline = NULL;
}
// remove portal seg from stencil buffer
HWR_SetTransform(fpov, player);
HWR_ClearClipper();
HWR_SetStencilState(HWR_STENCIL_REVERSE, stencil_level);
HWR_RenderPortalSeg(portal, GLPORTAL_STENCIL);
// draw portal seg to depth buffer
HWR_ClearClipper();
HWR_SetStencilState(HWR_STENCIL_DEPTH, stencil_level);
HWR_RenderPortalSeg(portal, GLPORTAL_DEPTH);
}
// returns true if the point is on the correct (viewable) side of the
// portal destination line
boolean HWR_PortalCheckPointSide(fixed_t x, fixed_t y)
{
// we are checking if the point is on the viewable side of the portal exit.
// being exactly on the portal exit line is not enough to pass the test.
// P_PointOnLineSide could behave differently from this expectation on this case,
// so first check if the point is precisely on the line, and then if not, check the side.
vertex_t closest_point;
P_ClosestPointOnLine(x, y, portalclipline, &closest_point);
if (closest_point.x != x || closest_point.y != y)
{
if (P_PointOnLineSide(x, y, portalclipline) != 1)
return true;
}
return false;
}
boolean HWR_PortalCheckBBox(const fixed_t *bspcoord)
{
if (!portalclipline)
return true;
if (HWR_PortalCheckPointSide(bspcoord[BOXLEFT], bspcoord[BOXTOP]) ||
HWR_PortalCheckPointSide(bspcoord[BOXLEFT], bspcoord[BOXBOTTOM]) ||
HWR_PortalCheckPointSide(bspcoord[BOXRIGHT], bspcoord[BOXTOP]) ||
HWR_PortalCheckPointSide(bspcoord[BOXRIGHT], bspcoord[BOXBOTTOM]))
{
return true;
}
// we did not find any reason to pass the check, so return failure
return false;
}
#endif
+81
View File
@@ -0,0 +1,81 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-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 hw_portal.h
/// \brief OpenGL renderer portal struct, functions, linked list extern.
#ifndef __HW_PORTAL__
#define __HW_PORTAL__
#ifdef HWRENDER
#include "../doomstat.h"
#include "../r_data.h"
#include "../r_bsp.h"
/** Portal structure.
*/
enum
{
GLPORTAL_OFF,
GLPORTAL_SEARCH,
GLPORTAL_STENCIL,
GLPORTAL_DEPTH,
GLPORTAL_INSIDE,
};
typedef struct gl_portal_s
{
struct gl_portal_s *next;
// Viewport.
fixed_t viewx;
fixed_t viewy;
fixed_t viewz;
angle_t viewangle;
seg_t *seg; // seg that is used for drawing to the stencil buffer
INT32 clipline; // Optional clipline for line-based portals
// angles for the left and right edges of the portal
// relative to the viewpoint
angle_t angle1;
angle_t angle2;
} gl_portal_t;
typedef struct gl_portallist_s
{
gl_portal_t *base;
gl_portal_t *cap;
} gl_portallist_t;
extern SINT8 gl_portal_state;
// new thing
extern gl_portallist_t *currentportallist;
static inline void HWR_SetPortalState (SINT8 state)
{
gl_portal_state = state;
}
// Adds an entry to the clipper for portal rendering
void HWR_PortalClipping(gl_portal_t *portal);
void HWR_Portal_Add2Lines(const INT32 line1, const INT32 line2, seg_t *seg);
void HWR_PortalFrame(gl_portal_t* portal);
void HWR_RenderPortal(gl_portal_t* portal, gl_portal_t* rootportal, const float fpov, player_t *player, int stencil_level);
void HWR_FreePortalList(gl_portallist_t portallist);
boolean HWR_PortalCheckPointSide(fixed_t x, fixed_t y);
boolean HWR_PortalCheckBBox(const fixed_t *bspcoord);
#endif
#endif
+9 -9
View File
@@ -25,7 +25,7 @@ static struct {
const char *vertex;
const char *fragment;
} const gl_shadersources[] = {
// Floor shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_FLOOR_FRAGMENT_SHADER},
@@ -52,7 +52,7 @@ static struct {
// Palette postprocess shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_PALETTE_POSTPROCESS_FRAGMENT_SHADER},
// UI colormap fade shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_UI_COLORMAP_FADE_FRAGMENT_SHADER},
@@ -279,11 +279,11 @@ static char *HWR_PreprocessShader(char *original)
// Calculate length of modified shader.
new_len = original_len;
if (cv_grpaletterendering.value)
if (cv_glpaletterendering.value)
ADD_TO_LEN(PALETTE_RENDERING_DEFINE)
if (cv_lightdither.value)
if (cv_gllightdither.value)
ADD_TO_LEN(LIGHT_DITHERING_DEFINE)
#undef ADD_TO_LEN
@@ -324,10 +324,10 @@ static char *HWR_PreprocessShader(char *original)
}
// Write the defines.
if (cv_grpaletterendering.value)
if (cv_glpaletterendering.value)
WRITE_DEFINE(PALETTE_RENDERING_DEFINE)
if (cv_lightdither.value)
if (cv_gllightdither.value)
WRITE_DEFINE(LIGHT_DITHERING_DEFINE)
#undef WRITE_DEFINE
@@ -410,7 +410,7 @@ int HWR_GetShaderFromTarget(int shader_target)
// - custom shaders are enabled
// - custom shaders are allowed by the server
if (custom_shader != -1 && gl_shaders[custom_shader].compiled &&
cv_grshaders.value == 1)
cv_glshaders.value == 1)
return custom_shader;
else
return gl_shadertargets[shader_target].base_shader;
@@ -565,7 +565,7 @@ void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3)
int i;
boolean modified_shaders[NUMSHADERTARGETS] = {0};
if (!gr_shadersavailable)
if (!gl_shadersavailable)
return;
lump = HWR_FindShaderDefs(wadnum);
+2 -2
View File
@@ -171,7 +171,7 @@
"gl_FragColor = final_color;\n" \
"}\n" \
"#endif\0"
#define GLSL_SOFTWARE_FRAGMENT_SHADER_NOPAL \
"uniform sampler2D tex;\n" \
"uniform vec4 poly_color;\n" \
@@ -210,7 +210,7 @@
#define GLSL_WALL_FRAGMENT_SHADER \
GLSL_WALL_FUDGES \
GLSL_SOFTWARE_FRAGMENT_SHADER
#define GLSL_SHADOW_FRAGMENT_SHADER \
GLSL_FLOOR_FUDGES \
GLSL_SOFTWARE_FRAGMENT_SHADER_NOPAL
+38 -48
View File
@@ -24,6 +24,7 @@
#include <stdarg.h>
#include <math.h>
#include "../../r_local.h" // For rendertimefrac, used for the leveltime shader uniform
#include "../../i_video.h" // for UseScreenFBO
#include "r_opengl.h"
#include "r_vbo.h"
#include "../hw_shaders.h"
@@ -121,9 +122,9 @@ static GLint viewport[4];
#ifdef USE_FBO_OGL
GLuint FramebufferObject, FramebufferTexture, RenderbufferObject;
GLboolean FrameBufferEnabled = GL_FALSE, RenderToFramebuffer = GL_FALSE;
boolean supportFBO = false;
static boolean fboinit = false;
#endif
// Sryder: NextTexAvail is broken for these because palette changes or changes to the texture filter or antialiasing
@@ -706,7 +707,15 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF
static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
#ifdef USE_FBO_OGL
static boolean GLFramebuffer_IsFuncAvailible(void);
static boolean GLFramebuffer_CheckExt(void)
{
//this stuff needs atleast OGL 3.0
if (majorGL < 3)
return false;
// check if all needed gl extensions are available
return (isExtAvailable("GL_ARB_framebuffer_no_attachments", gl_extensions) && isExtAvailable("GL_ARB_framebuffer_object", gl_extensions) && isExtAvailable("GL_ARB_framebuffer_sRGB", gl_extensions));
}
#endif
void SetupGLFunc4(void)
@@ -753,7 +762,7 @@ void SetupGLFunc4(void)
pglGetUniformLocation = GetGLFunc("glGetUniformLocation");
#ifdef USE_FBO_OGL
if (GLFramebuffer_IsFuncAvailible())
if (GLFramebuffer_CheckExt())
{
pglGenFramebuffers = GetGLFunc("glGenFramebuffers");
pglBindFramebuffer = GetGLFunc("glBindFramebuffer");
@@ -766,24 +775,17 @@ void SetupGLFunc4(void)
pglRenderbufferStorage = GetGLFunc("glRenderbufferStorage");
pglFramebufferRenderbuffer = GetGLFunc("glFramebufferRenderbuffer");
// check if ALL functions are availible
if (pglGenFramebuffers && pglBindFramebuffer &&
pglDeleteFramebuffers && pglFramebufferTexture2D &&
pglCheckFramebufferStatus && pglGenRenderbuffers &&
pglBindRenderbuffer && pglDeleteRenderbuffers &&
pglRenderbufferStorage && pglFramebufferRenderbuffer)
supportFBO = true;
}
#endif
}
#ifdef USE_FBO_OGL
static boolean GLFramebuffer_IsFuncAvailible(void)
{
//this stuff needs atleast OGL 3.0
if (majorGL < 3)
return false;
return (isExtAvailable("GL_ARB_framebuffer_no_attachments",gl_extensions) && isExtAvailable("GL_ARB_framebuffer_object",gl_extensions) && isExtAvailable("GL_ARB_framebuffer_sRGB",gl_extensions));
return false;
}
#endif
EXPORT boolean HWRAPI(InitShaders) (void)
{
if (!pglUseProgram)
@@ -951,7 +953,6 @@ static void GLPerspective(GLfloat fovy, GLfloat aspect)
pglMultMatrixf(&m[0][0]);
}
// -----------------+
// SetModelView :
// -----------------+
@@ -1046,7 +1047,7 @@ EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *pTexInfo)
#ifdef USE_FBO_OGL
static void GLFramebuffer_GenerateAttachments(void)
{
if (!supportFBO)
if (!supportFBO || !UseScreenFBO())
return;
// Bind the framebuffer
@@ -1083,11 +1084,16 @@ static void GLFramebuffer_GenerateAttachments(void)
// Unbind the framebuffer
pglBindFramebuffer(GL_FRAMEBUFFER, 0);
fboinit = true;
}
void GLFramebuffer_DeleteAttachments(void)
{
if (!supportFBO)
if (!supportFBO || fboinit == false)
return;
if (FramebufferObject == 0 && RenderbufferObject == 0 && FramebufferTexture == 0)
return;
// Unbind the framebuffer
@@ -1102,11 +1108,12 @@ void GLFramebuffer_DeleteAttachments(void)
FramebufferTexture = 0;
RenderbufferObject = 0;
fboinit = false;
}
static void GLFramebuffer_Generate(void)
{
if (!supportFBO)
if (!supportFBO || !UseScreenFBO())
return;
// Generate the framebuffer
@@ -1119,7 +1126,7 @@ static void GLFramebuffer_Generate(void)
static void GLFramebuffer_Delete(void)
{
if (!supportFBO)
if (!supportFBO || fboinit == false)
return;
if (FramebufferObject)
@@ -1131,7 +1138,10 @@ static void GLFramebuffer_Delete(void)
inline void GLFramebuffer_Unbind(void)
{
if (!supportFBO)
if (!supportFBO || fboinit == false)
return;
if (FramebufferObject == 0 && RenderbufferObject == 0)
return;
pglBindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -1140,7 +1150,7 @@ inline void GLFramebuffer_Unbind(void)
inline void GLFramebuffer_Enable(void)
{
if (!supportFBO)
if (!supportFBO || !UseScreenFBO())
return;
if (FramebufferObject == 0)
@@ -1154,7 +1164,10 @@ inline void GLFramebuffer_Enable(void)
void GLFramebuffer_Disable(void)
{
if (!supportFBO)
if (!supportFBO || fboinit == false)
return;
if (FramebufferObject == 0 && RenderbufferObject == 0)
return;
pglBindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -1170,8 +1183,6 @@ void GLFramebuffer_Disable(void)
// -----------------+
void Flush(void)
{
//GL_DBG_Printf ("HWR_Flush()\n");
while (TexCacheHead)
{
FTextureInfo *pTexInfo = TexCacheHead;
@@ -1198,7 +1209,6 @@ void Flush(void)
textureBufferSize = 0;
}
// -----------------+
// isExtAvailable : Look if an OpenGL extension is available
// Returns : true if extension available
@@ -1226,7 +1236,6 @@ INT32 isExtAvailable(const char *extension, const GLubyte *start)
return 0;
}
// -----------------+
// Init : Initialise the OpenGL interface API
// Returns :
@@ -1236,7 +1245,6 @@ EXPORT boolean HWRAPI(Init) (void)
return LoadGL();
}
// -----------------+
// SetupGLInfo : Retreive and store currently loaded OpenGL version
// -----------------+
@@ -1398,7 +1406,6 @@ static void Clamp2D(GLenum pname)
#endif
}
// -----------------+
// SetBlend : Set render mode
// -----------------+
@@ -2247,12 +2254,6 @@ static void gld_BuildSky(int row_count, int col_count)
}
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
static void RenderDome(INT32 skytexnum)
{
int i, j;
@@ -2350,17 +2351,6 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
case HWD_SET_SHADERS:
gl_allowshaders = Value;
break;
#ifdef USE_FBO_OGL
case HWD_SET_FRAMEBUFFER:
FrameBufferEnabled = Value ? GL_TRUE : GL_FALSE;
if (!supportFBO)
{
FrameBufferEnabled = GL_FALSE;
CV_Set(&cv_grframebuffer, "Off");
}
break;
#endif
case HWD_SET_TEXTUREFILTERMODE:
switch (Value)
{
@@ -2984,7 +2974,7 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
// https://zdoom.org/wiki/Y-shearing
if (shearing)
{
float dy = FIXED_TO_FLOAT(AIMINGTODY((stransform->viewaiming)) * 2)* ((float)vid.width / vid.height) / ((float)BASEVIDWIDTH / BASEVIDHEIGHT); //screen_width/BASEVIDWIDTH;
float dy = stransform->viewaiming * 2;
if (stransform->flip || stransform->mirrorflip)
dy *= -1.0f;
pglTranslatef(0.0f, -dy/BASEVIDHEIGHT, 0.0f);
-4
View File
@@ -98,10 +98,6 @@ typedef void (APIENTRY * PFNglGetIntegerv) (GLenum pname, GLint *params);
extern PFNglGetIntegerv pglGetIntegerv;
typedef const GLubyte* (APIENTRY * PFNglGetString) (GLenum name);
extern PFNglGetString pglGetString;
#if 0
typedef void (APIENTRY * PFNglEnableClientState) (GLenum cap); // redefined in r_opengl.c
static PFNglEnableClientState pglEnableClientState;
#endif
#endif
#ifdef USE_FBO_OGL
+148 -275
View File
@@ -49,6 +49,8 @@
#include "s_sound.h" // song credits
#include "k_kart.h"
#include "m_textinput.h"
#ifdef HWRENDER
#include "hardware/hw_main.h"
#endif
@@ -86,8 +88,8 @@ patch_t *frameslash; // framerate stuff. Used in screen.c
static player_t *plr;
boolean chat_on; // entering a chat message?
static char w_chat[HU_MAXMSGLEN + 1];
static size_t c_input = 0; // let's try to make the chat input less shitty.
static char w_chat_buf[HU_MAXMSGLEN + 1];
static textinput_t w_chat;
static boolean headsupactive = false;
boolean hu_showscores; // draw rankings
static char hu_tick;
@@ -1143,71 +1145,6 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
#endif
}
// Handles key input and string input
//
static inline boolean HU_keyInChatString(char *s, char ch)
{
size_t l;
if ((ch >= HU_FONTSTART && ch <= HU_FONTEND && hu_font[ch-HU_FONTSTART])
|| ch == ' ') // Allow spaces, of course
{
l = strlen(s);
if (l < HU_MAXMSGLEN - 1)
{
if (c_input >= strlen(s)) // don't do anything complicated
{
s[l++] = ch;
s[l]=0;
}
else
{
// move everything past c_input for new characters:
size_t m = HU_MAXMSGLEN-1;
while (m>=c_input)
{
if (s[m])
s[m+1] = (s[m]);
if (m == 0) // prevent overflow
break;
m--;
}
s[c_input] = ch; // and replace this.
}
c_input++;
return true;
}
return false;
}
else if (ch == KEY_BACKSPACE)
{
size_t i = c_input;
if (c_input <= 0)
return false;
if (!s[i-1])
return false;
if (i >= strlen(s)-1)
{
s[strlen(s)-1] = 0;
c_input--;
return false;
}
for (; (i < HU_MAXMSGLEN); i++)
{
s[i-1] = s[i];
}
c_input--;
}
else if (ch != KEY_ENTER)
return false; // did not eat key
return true; // ate the key
}
#endif
//
@@ -1280,9 +1217,9 @@ static boolean HU_clearChatSpaces(void)
char c; // current character we're iterating.
boolean nothingbutspaces = true;
for (; i < strlen(w_chat); i++) // iterate through message and eradicate all spaces that don't belong.
for (; i < strlen(w_chat_buf); i++) // iterate through message and eradicate all spaces that don't belong.
{
c = w_chat[i];
c = w_chat_buf[i];
if (!c)
break; // if there's nothing, it's safe to assume our message has ended, so let's not waste any more time here.
@@ -1294,128 +1231,110 @@ static boolean HU_clearChatSpaces(void)
return nothingbutspaces;
}
//
//
static void HU_queueChatChar(INT32 c)
static void HU_SendChatMessage(void)
{
// send automaticly the message (no more chat char)
if (c == KEY_ENTER)
char buf[2 + HU_MAXMSGLEN + 1];
char *msg = &buf[2];
size_t ci = 2;
INT32 target = 0;
char c;
if (HU_clearChatSpaces()) // Avoids being able to send empty messages, or something.
return; // If this returns true, that means our message was NOTHING but spaces, so don't send it period.
do {
c = w_chat_buf[-2+ci++];
if (!c || (c >= ' ' && !(c & 0x80))) // copy printable characters and terminating '\0' only.
buf[ci-1]=c;
} while (c);
M_TextInputClear(&w_chat);
// last minute mute check
if (CHAT_MUTE)
{
char buf[2 + HU_MAXMSGLEN + 1];
char *msg = &buf[2];
size_t i;
size_t ci = 2;
INT32 target = 0;
HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85"), false);
return;
}
if (HU_clearChatSpaces()) // Avoids being able to send empty messages, or something.
return; // If this returns true, that means our message was NOTHING but spaces, so don't send it period.
if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
{
INT32 spc = 1; // used if nodenum[1] is a space.
char *nodenum = (char*) malloc(3);
const char *newmsg;
do {
c = w_chat[-2+ci++];
if (!c || (c >= ' ' && !(c & 0x80))) // copy printable characters and terminating '\0' only.
buf[ci-1]=c;
} while (c);
i = 0;
for (;(i<HU_MAXMSGLEN);i++)
w_chat[i] = 0; // reset this.
// what we're gonna do now is check if the node exists
// with that logic, characters 4 and 5 are our numbers:
c_input = 0;
for (;(i<HU_MAXMSGLEN);i++)
w_chat[i] = 0; // reset this.
c_input = 0;
// last minute mute check
if (CHAT_MUTE)
// teamtalk can't send PMs, just don't send it, else everyone would be able to see it, and no one wants to see your sex RP sicko.
if (teamtalk)
{
HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85"), false);
HU_AddChatText(va("%sCannot send sayto in Say-Team.", "\x85"), false);
return;
}
if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
memcpy(nodenum, msg+3, 2);
nodenum[2] = '\0';
// check for undesirable characters in our "number"
if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9')))
{
INT32 spc = 1; // used if nodenum[1] is a space.
char *nodenum = (char*) malloc(3);
const char *newmsg;
// what we're gonna do now is check if the node exists
// with that logic, characters 4 and 5 are our numbers:
// teamtalk can't send PMs, just don't send it, else everyone would be able to see it, and no one wants to see your sex RP sicko.
if (teamtalk)
{
HU_AddChatText(va("%sCannot send sayto in Say-Team.", "\x85"), false);
return;
}
memcpy(nodenum, msg+3, 2);
nodenum[2] = '\0';
// check for undesirable characters in our "number"
if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9')))
{
// check if nodenum[1] is a space
if (nodenum[1] == ' ')
spc = 0;
// let it slide
else
{
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'.", false);
free(nodenum);
return;
}
}
// I'm very bad at C, I swear I am, additional checks eww!
if (spc != 0)
{
if (msg[5] != ' ')
{
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'.", false);
free(nodenum);
return;
}
}
target = atoi((const char*) nodenum); // turn that into a number
free(nodenum);
//CONS_Printf("%d\n", target);
// check for target player, if it doesn't exist then we can't send the message!
if (target < MAXPLAYERS && playeringame[target]) // player exists
target++; // even though playernums are from 0 to 31, target is 1 to 32, so up that by 1 to have it work!
// check if nodenum[1] is a space
if (nodenum[1] == ' ')
spc = 0;
// let it slide
else
{
HU_AddChatText(va("\x82NOTICE: \x80Player %d does not exist.", target), false); // same
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'.", false);
free(nodenum);
return;
}
// we need to get rid of the /pm<node>
newmsg = msg+5+spc;
strlcpy(msg, newmsg, HU_MAXMSGLEN + 1);
}
if (ci > 3) // don't send target+flags+empty message.
// I'm very bad at C, I swear I am, additional checks eww!
if (spc != 0)
{
if (teamtalk)
buf[0] = -1; // target
else
buf[0] = target;
buf[1] = 0; // flags
SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1);
if (msg[5] != ' ')
{
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'.", false);
free(nodenum);
return;
}
}
return;
target = atoi((const char*) nodenum); // turn that into a number
free(nodenum);
//CONS_Printf("%d\n", target);
// check for target player, if it doesn't exist then we can't send the message!
if (target < MAXPLAYERS && playeringame[target]) // player exists
target++; // even though playernums are from 0 to 31, target is 1 to 32, so up that by 1 to have it work!
else
{
HU_AddChatText(va("\x82NOTICE: \x80Player %d does not exist.", target), false); // same
return;
}
// we need to get rid of the /pm<node>
newmsg = msg+5+spc;
strlcpy(msg, newmsg, HU_MAXMSGLEN + 1);
}
if (ci > 3) // don't send target+flags+empty message.
{
if (teamtalk)
buf[0] = -1; // target
else
buf[0] = target;
buf[1] = 0; // flags
SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1);
}
}
#endif
void HU_clearChatChars(void)
{
size_t i = 0;
for (;i<HU_MAXMSGLEN;i++)
w_chat[i] = 0; // reset this.
M_TextInputClear(&w_chat);
chat_on = false;
c_input = 0;
}
#ifndef NONET
@@ -1463,7 +1382,8 @@ boolean HU_Responder(event_t *ev)
&& netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise.
{
chat_on = true;
w_chat[0] = 0;
w_chat_buf[0] = 0;
M_TextInputInit(&w_chat, w_chat_buf, sizeof w_chat_buf);
teamtalk = false;
chat_scrollmedown = true;
typelines = 1;
@@ -1473,7 +1393,8 @@ boolean HU_Responder(event_t *ev)
&& netgame && !OLD_MUTE)
{
chat_on = true;
w_chat[0] = 0;
w_chat_buf[0] = 0;
M_TextInputInit(&w_chat, w_chat_buf, sizeof w_chat_buf);
teamtalk = G_GametypeHasTeams(); // Don't teamtalk if we don't have teams.
chat_scrollmedown = true;
typelines = 1;
@@ -1498,62 +1419,13 @@ boolean HU_Responder(event_t *ev)
&& ev->data1 != gamecontrol[gc_talkkey][1]))
return false;
c = cv_keyboardlayout.value == 3 ? CON_ShitAndAltGrChar(c) : CON_ShiftChar(c);
M_TextInputHandle(&w_chat, c);
// pasting. pasting is cool. chat is a bit limited, though :(
if (((c == 'v' || c == 'V') && ctrldown) && !CHAT_MUTE)
{
const char *paste = I_ClipboardPaste();
size_t chatlen;
size_t pastelen;
// create a dummy string real quickly
if (paste == NULL)
return true;
chatlen = strlen(w_chat);
pastelen = strlen(paste);
if (chatlen+pastelen > HU_MAXMSGLEN)
return true; // we can't paste this!!
if (c_input >= strlen(w_chat)) // add it at the end of the string.
{
memcpy(&w_chat[chatlen], paste, pastelen); // copy all of that.
c_input += pastelen;
/*size_t i = 0;
for (;i<pastelen;i++)
{
HU_queueChatChar(paste[i]); // queue it so that it's actually sent. (this chat write thing is REALLY messy.)
}*/
return true;
}
else // otherwise, we need to shift everything and make space, etc etc
{
size_t i = HU_MAXMSGLEN-1;
while (i >= c_input)
{
if (w_chat[i])
w_chat[i+pastelen] = w_chat[i];
if (i == 0) // prevent overflow
break;
i--;
}
memcpy(&w_chat[c_input], paste, pastelen); // copy all of that.
c_input += pastelen;
return true;
}
}
if (!CHAT_MUTE && HU_keyInChatString(w_chat,c))
{
HU_queueChatChar(c);
}
if (c == KEY_ENTER)
{
chat_on = false;
c_input = 0; // reset input cursor
chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :)
HU_SendChatMessage();
}
else if (c == KEY_ESCAPE
|| ((c == gamecontrol[gc_talkkey][0] || c == gamecontrol[gc_talkkey][1]
@@ -1561,7 +1433,6 @@ boolean HU_Responder(event_t *ev)
&& c >= KEY_MOUSE1)) // If it's not a keyboard key, then the chat button is used as a toggle.
{
chat_on = false;
c_input = 0; // reset input cursor
}
else if ((c == KEY_UPARROW || c == KEY_MOUSEWHEELUP) && chat_scroll > 0 && !OLDCHAT) // CHAT SCROLLING YAYS!
{
@@ -1575,10 +1446,6 @@ boolean HU_Responder(event_t *ev)
justscrolleddown = true;
chat_scrolltime = 4;
}
else if (c == KEY_LEFTARROW && c_input != 0 && !OLDCHAT) // i said go back
c_input--;
else if (c == KEY_RIGHTARROW && c_input < strlen(w_chat) && !OLDCHAT) // don't need to check for admin or w/e here since the chat won't ever contain anything if it's muted.
c_input++;
return true;
}
#endif
@@ -1932,8 +1799,9 @@ static void HU_DrawChat(void)
INT32 charwidth = 4, charheight = 6;
INT32 boxw = cv_chatwidth.value;
INT32 t = 0, c = 0, y = chaty - (typelines*charheight);
UINT32 i = 0, saylen = strlen(w_chat); // You learn new things everyday!
UINT32 i = 0, saylen = strlen(w_chat_buf); // You learn new things everyday!
INT32 cflag = 0;
size_t select_start = 0, select_end = 0;
const char *ntalk = "Say: ", *ttalk = "Team: ";
const char *talk = ntalk;
const char *mute = "Chat has been muted.";
@@ -1995,13 +1863,19 @@ static void HU_DrawChat(void)
i = 0;
typelines = 1;
if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4)
V_DrawChatCharacter(chatx + 2 + c, y+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
if ((w_chat.cursor == 0 || w_chat.length == 0) && hu_tick < 4)
V_DrawChatCharacter(chatx+2+c+charwidth*w_chat.cursor, y+1, '_'|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
while (w_chat[i])
if (w_chat.select != w_chat.cursor)
{
select_start = min(w_chat.select, w_chat.cursor);
select_end = max(w_chat.select, w_chat.cursor);
}
while (w_chat_buf[i])
{
boolean skippedline = false;
if (c_input == (i+1))
if (w_chat.cursor == (i+1))
{
INT32 cursorx = (c+charwidth < boxw-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down.
INT32 cursory = (cursorx != chatx+1) ? (y) : (y+charheight);
@@ -2016,10 +1890,14 @@ static void HU_DrawChat(void)
}
//Hurdler: isn't it better like that?
if (w_chat[i] < HU_FONTSTART)
++i;
else
V_DrawChatCharacter(chatx + c + 2, y, w_chat[i++] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL);
if (w_chat_buf[i] >= HU_FONTSTART)
V_DrawChatCharacter(chatx + c + 2, y, w_chat_buf[i] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL);
// Draw selection
if (i >= select_start && i < select_end)
V_DrawFill(chatx + c + 2, y-1, charwidth, charheight, 103|V_TRANSLUCENT|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t);
++i;
c += charwidth;
if (c > boxw-(charwidth*2) && !skippedline)
@@ -2031,7 +1909,7 @@ static void HU_DrawChat(void)
}
// handle /pm list. It's messy, horrible and I don't care.
if (strnicmp(w_chat, "/pm", 3) == 0 && vid.width >= 400 && !teamtalk) // 320x200 unsupported kthxbai
if (strnicmp(w_chat_buf, "/pm", 3) == 0 && vid.width >= 400 && !teamtalk) // 320x200 unsupported kthxbai
{
INT32 count = 0;
INT32 p_dispy = chaty - charheight -1;
@@ -2051,38 +1929,38 @@ static void HU_DrawChat(void)
{
// filter: (code needs optimization pls help I'm bad with C)
if (w_chat[3])
if (w_chat_buf[3])
{
char *nodenum;
UINT32 n;
// right, that's half important: (w_chat[4] may be a space since /pm0 msg is perfectly acceptable!)
if ( ( ((w_chat[3] != 0) && ((w_chat[3] < '0') || (w_chat[3] > '9'))) || ((w_chat[4] != 0) && (((w_chat[4] < '0') || (w_chat[4] > '9'))))) && (w_chat[4] != ' '))
// right, that's half important: (w_chat_buf[4] may be a space since /pm0 msg is perfectly acceptable!)
if ( ( ((w_chat_buf[3] != 0) && ((w_chat_buf[3] < '0') || (w_chat_buf[3] > '9'))) || ((w_chat_buf[4] != 0) && (((w_chat_buf[4] < '0') || (w_chat_buf[4] > '9'))))) && (w_chat_buf[4] != ' '))
break;
nodenum = (char*) malloc(3);
memcpy(nodenum, w_chat+3, 2);
memcpy(nodenum, w_chat_buf+3, 2);
nodenum[2] = '\0';
n = atoi((const char*) nodenum); // turn that into a number
free(nodenum);
// special cases:
if ((n == 0) && !(w_chat[4] == '0'))
if ((n == 0) && !(w_chat_buf[4] == '0'))
{
if (!(i<10))
continue;
}
else if ((n == 1) && !(w_chat[3] == '0'))
else if ((n == 1) && !(w_chat_buf[3] == '0'))
{
if (!((i == 1) || ((i >= 10) && (i <= 19))))
continue;
}
else if ((n == 2) && !(w_chat[3] == '0'))
else if ((n == 2) && !(w_chat_buf[3] == '0'))
{
if (!((i == 2) || ((i >= 20) && (i <= 29))))
continue;
}
else if ((n == 3) && !(w_chat[3] == '0'))
else if ((n == 3) && !(w_chat_buf[3] == '0'))
{
if (!((i == 3) || ((i >= 30) && (i <= 31))))
continue;
@@ -2121,6 +1999,7 @@ static void HU_DrawChat_Old(void)
size_t i = 0;
const char *ntalk = "Say: ", *ttalk = "Say-Team: ";
const char *talk = ntalk;
size_t select_start = 0, select_end = 0;
INT32 charwidth = 8 * con_scalefactor; //SHORT(hu_font['A'-HU_FONTSTART]->width) * con_scalefactor;
INT32 charheight = 8 * con_scalefactor; //SHORT(hu_font['A'-HU_FONTSTART]->height) * con_scalefactor;
if (teamtalk)
@@ -2149,14 +2028,19 @@ static void HU_DrawChat_Old(void)
c += charwidth;
}
if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4)
V_DrawCharacter(HU_INPUTX+c, y+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value);
if ((w_chat.cursor == 0 || w_chat.length == 0) && hu_tick < 4)
V_DrawCharacter(HU_INPUTX+c+charwidth*w_chat.cursor, y+2*con_scalefactor, '_'|cv_constextsize.value|V_NOSCALESTART|t, !cv_allcaps.value);
if (w_chat.select != w_chat.cursor)
{
select_start = min(w_chat.select, w_chat.cursor);
select_end = max(w_chat.select, w_chat.cursor);
}
i = 0;
while (w_chat[i])
while (w_chat_buf[i])
{
if (c_input == (i+1) && hu_tick < 4)
if (w_chat.cursor == (i+1) && hu_tick < 4)
{
INT32 cursorx = (HU_INPUTX+c+charwidth < vid.width) ? (HU_INPUTX + c + charwidth) : (HU_INPUTX); // we may have to go down.
INT32 cursory = (cursorx != HU_INPUTX) ? (y) : (y+charheight);
@@ -2164,17 +2048,18 @@ static void HU_DrawChat_Old(void)
}
//Hurdler: isn't it better like that?
if (w_chat[i] < HU_FONTSTART)
{
++i;
//charwidth = 4 * con_scalefactor;
}
else
if (w_chat_buf[i] >= HU_FONTSTART)
{
//charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor;
V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value);
V_DrawCharacter(HU_INPUTX + c, y, w_chat_buf[i] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value);
}
// Draw selection
if (i >= select_start && i < select_end)
V_DrawFill(HU_INPUTX + c, y, charwidth, charheight, 103|V_TRANSLUCENT|cv_constextsize.value|V_NOSCALESTART|t);
++i;
c += charwidth;
if (c >= vid.width)
{
@@ -2732,7 +2617,8 @@ static void HU_DrawRankings(void)
boolean completed[MAXPLAYERS];
UINT32 whiteplayer = MAXPLAYERS;
V_DrawFadeScreen(0xFF00, 16); // A little more readable, and prevents cheating the fades under other circumstances.
if (!automapactive)
V_DrawFadeScreen(0xFF00, 16); // A little more readable, and prevents cheating the fades under other circumstances.
if (cons_menuhighlight.value)
hilicol = cons_menuhighlight.value;
@@ -2748,10 +2634,14 @@ static void HU_DrawRankings(void)
//V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, gametype_cons_t[gametype].strvalue);
// draw the current map in the lower right if theres none just say its unknown
if (!G_BuildMapTitle(gamemap))
char *maptitle = G_BuildMapTitle(gamemap);
if (!maptitle)
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, "UNKNOWN");
else
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, G_BuildMapTitle(gamemap));
{
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, maptitle);
Z_Free(maptitle);
}
if (G_GametypeHasTeams())
{
@@ -2801,18 +2691,6 @@ static void HU_DrawRankings(void)
V_DrawCenteredString(256, 16, hilicol, va("%d", cv_pointlimit.value));
}
}
/*else if (gametype == GT_COOP)
{
INT32 totalscore = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i])
totalscore += players[i].score;
}
V_DrawCenteredString(256, 8, 0, "TOTAL SCORE");
V_DrawCenteredString(256, 16, 0, va("%u", totalscore));
}*/
else
{
if (circuitmap)
@@ -2885,12 +2763,7 @@ static void HU_DrawRankings(void)
#endif
}
/*if (G_GametypeHasTeams())
HU_DrawTeamTabRankings(tab, whiteplayer); //separate function for Spazzo's silly request -- gotta fix this up later
else if (scorelines > 10)*/
HU_DrawTabRankings(((scorelines > 8) ? 32 : 40), 33, tab, scorelines, whiteplayer, hilicol);
/*else
HU_DrawDualTabRankings(32, 32, tab, scorelines, whiteplayer);*/
// draw spectators in a ticker across the bottom
if (netgame && G_GametypeHasSpectators())
+22 -3
View File
@@ -100,6 +100,14 @@
#undef ETIMEDOUT
#endif
#define ETIMEDOUT WSAETIMEDOUT
#ifdef EHOSTUNREACH
#undef EHOSTUNREACH
#endif
#define EHOSTUNREACH WSAEHOSTUNREACH
#ifdef ENETUNREACH
#undef ENETUNREACH
#endif
#define ENETUNREACH WSAENETUNREACH
#ifndef IOC_VENDOR
#define IOC_VENDOR 0x18000000
#endif
@@ -816,6 +824,8 @@ static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr
return sendto(socket, (char *)&doomcom->data, doomcom->datalength, 0, &sockaddr->any, d);
}
#define ALLOWEDERROR(x) ((x) == ECONNREFUSED || (x) == EWOULDBLOCK || (x) == EHOSTUNREACH || (x) == ENETUNREACH)
static void SOCK_Send(void)
{
ssize_t c = ERRSOCKET;
@@ -831,7 +841,11 @@ static void SOCK_Send(void)
for (j = 0; j < broadcastaddresses; j++)
{
if (myfamily[i] == broadcastaddress[j].any.sa_family)
SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]);
{
c = SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]);
if (c == ERRSOCKET && !ALLOWEDERROR(errno))
break;
}
}
}
return;
@@ -841,7 +855,11 @@ static void SOCK_Send(void)
for (i = 0; i < mysocketses; i++)
{
if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family)
SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]);
{
c = SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]);
if (c == ERRSOCKET && !ALLOWEDERROR(errno))
break;
}
}
return;
}
@@ -853,11 +871,12 @@ static void SOCK_Send(void)
if (c == ERRSOCKET)
{
int e = errno; // save error code so it can't be modified later
if (e != ECONNREFUSED && e != EWOULDBLOCK)
if (!ALLOWEDERROR(e))
I_Error("SOCK_Send, error sending to node %d (%s) #%u: %s", doomcom->remotenode,
SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e));
}
}
#undef ALLOWEDERROR
#endif
#ifndef NONET
+1
View File
@@ -146,6 +146,7 @@ extern boolean xwaylandcrap;
void RefreshOGLSDLSurface(void);
void I_DownSample(void);
boolean UseScreenFBO(void);
extern boolean downsample;
#endif
+33 -2
View File
@@ -17,12 +17,13 @@
#include "k_director.h"
#include "d_netcmd.h"
#include "p_local.h"
#include "st_stuff.h"
#define SWITCHTIME TICRATE * 5 // cooldown between unforced switches
#define BOREDOMTIME 3 * TICRATE / 2 // how long until players considered far apart?
#define TRANSFERTIME TICRATE // how long to delay reaction shots?
#define BREAKAWAYDIST 2000 // how *far* until players considered far apart?
#define WALKBACKDIST 600 // how close should a trailing player be before we switch?
#define WALKBACKDIST 400 // how close should a trailing player be before we switch?
#define PINCHDIST 20000 // how close should the leader be to be considered "end of race"?
struct directorinfo
@@ -37,6 +38,25 @@ struct directorinfo
INT32 boredom[MAXPLAYERS]; // how long has a given position had no credible attackers?
} directorinfo;
boolean K_DirectorIsPlayerAlone(void)
{
UINT8 pingame = 0;
// Gotta check how many players are active at this moment.
for (UINT8 i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
pingame++;
if (pingame >= 2) // we dont need to check further
break;
}
return (pingame <= 1);
}
static inline boolean race_rules(void)
{
return gametype == GT_RACE;
@@ -49,7 +69,7 @@ static fixed_t ScaleFromMap(fixed_t n, fixed_t scale)
static boolean K_DirectorIsEnabled(void)
{
return cv_director.value && !splitscreen && (gamestate == GS_LEVEL && (!playeringame[consoleplayer] || players[consoleplayer].spectator || (demo.playback && (!demo.title || !modeattacking))));
return cv_director.value && !splitscreen && (gamestate == GS_LEVEL && (((!playeringame[consoleplayer] || players[consoleplayer].spectator)) || (demo.playback && !demo.freecam && (!demo.title || !modeattacking))) && !K_DirectorIsPlayerAlone());
}
void K_InitDirector(void)
@@ -376,6 +396,12 @@ void K_UpdateDirector(void)
break;
}
// if this is a splitscreen player, try next pair
if (P_IsDisplayPlayer(&players[target]))
{
continue;
}
// if we're certain the back half of the pair is actually in this position, try to switch
if (!players[target].kartstuff[k_positiondelay])
{
@@ -394,10 +420,15 @@ void K_UpdateDirector(void)
void K_ToggleDirector(void)
{
if (!directortextactive)
return;
if (!K_DirectorIsEnabled())
{
directorinfo.cooldown = 0; // switch immediately
}
directortoggletimer = 0;
COM_ImmedExecute("add director 1");
}
+173 -232
View File
@@ -725,34 +725,34 @@ void K_RegisterKartStuff(void)
CV_RegisterVar(&cv_showinput);
CV_RegisterVar(&cv_showlaptimes);
CV_RegisterVar(&cv_newspeedometer);
CV_RegisterVar(&cv_battlespeedo);
CV_RegisterVar(&cv_saltyhop);
CV_RegisterVar(&cv_saltyhopsfx);
CV_RegisterVar(&cv_saltysquish);
//Colourized HUD
CV_RegisterVar(&cv_colorizedhud);
CV_RegisterVar(&cv_colorizedhudcolor);
CV_RegisterVar(&cv_colorizeditembox);
CV_RegisterVar(&cv_darkitembox);
CV_RegisterVar(&cv_biglaps);
CV_RegisterVar(&cv_highresportrait);
CV_RegisterVar(&cv_slamsound);
CV_RegisterVar(&cv_minihead);
CV_RegisterVar(&cv_showminimapnames);
CV_RegisterVar(&cv_showlapemblem);
CV_RegisterVar(&cv_stagetitle);
CV_RegisterVar(&cv_stagetitle);
CV_RegisterVar(&cv_lessflicker);
CV_RegisterVar(&cv_mouseturn);
}
@@ -2686,8 +2686,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b
if (P_IsLocalPlayer(player))
{
quake.intensity = 64*FRACUNIT;
quake.time = 5;
P_StartQuake(5, 64<<FRACBITS, 0);
}
player->kartstuff[k_instashield] = 15;
@@ -2780,16 +2779,9 @@ void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32
TVector v;
TVector *res;
fixed_t finalx, finaly, finalz, dist;
//mobj_t hoopcenter;
angle_t degrees, fa, closestangle;
fixed_t mobjx, mobjy, mobjz;
//hoopcenter.x = x;
//hoopcenter.y = y;
//hoopcenter.z = z;
//hoopcenter.z = z - mobjinfo[type].height/2;
degrees = FINEANGLES/number;
closestangle = 0;
@@ -3175,17 +3167,19 @@ static void K_SpawnAIZDust(player_t *player)
static void K_StretchPlayerGravity(player_t *p)
{
fixed_t mos = FRACUNIT;
fixed_t rzs = abs(p->mo->momz);
fixed_t zspd = abs(rzs/mos);
I_Assert(p != NULL);
I_Assert(p->mo != NULL);
I_Assert(!P_MobjWasRemoved(p->mo));
fixed_t mos = FRACUNIT;
fixed_t rzs = abs(p->mo->momz);
fixed_t zspd = abs(rzs/mos);
fixed_t stretchScaleFactor = 0;
fixed_t rzsDiv = 1;
fixed_t slamDiv = 1;
fixed_t dxs = p->mo->realxscale;
fixed_t dys = p->mo->realyscale;
//boolean gravSlamming = false;
//fixed_t impactFactor = 0;
fixed_t dxs = p->mo->realxscale;
fixed_t dys = p->mo->realyscale;
stretchScaleFactor = FixedDiv(FRACUNIT*60, cv_gravstretch.value);
if (stretchScaleFactor > 17476977)
@@ -3195,10 +3189,6 @@ static void K_StretchPlayerGravity(player_t *p)
//CONS_Printf(M_GetText("div: %d, scale factor: %d, stretch value: %d\n"), rzsDiv, stretchScaleFactor, cv_gravstretch.value);
I_Assert(p != NULL);
I_Assert(p->mo != NULL);
I_Assert(!P_MobjWasRemoved(p->mo));
if (p->mo->slamsoundtimer)
p->mo->slamsoundtimer--;
@@ -3208,43 +3198,43 @@ static void K_StretchPlayerGravity(player_t *p)
p->mo->slamsoundtimer = TICRATE;
}
if (!P_IsObjectOnGround(p->mo))
{
if (zspd != 0)
{
if (((dxs-(rzsDiv))) > (dxs/5))
{
p->mo->spritexscale = ((dxs-(rzsDiv)));
p->mo->stretchslam = rzs;
}
else
p->mo->spritexscale = (dxs/5);
if (!P_IsObjectOnGround(p->mo))
{
if (zspd != 0)
{
if (((dxs-(rzsDiv))) > (dxs/5))
{
p->mo->spritexscale = ((dxs-(rzsDiv)));
p->mo->stretchslam = rzs;
}
else
p->mo->spritexscale = (dxs/5);
p->mo->spriteyscale = (dys+((rzsDiv*2)/3));
}
else
{
p->mo->spritexscale = (dxs);
p->mo->spriteyscale = (dys);
}
}
else
{
p->mo->spriteyscale = (dys+((rzsDiv*2)/3));
}
else
{
p->mo->spritexscale = (dxs);
p->mo->spriteyscale = (dys);
}
}
else
{
if (stretchScaleFactor > 17476977)
slamDiv = 0;
else
slamDiv = FixedDiv(p->mo->stretchslam, stretchScaleFactor);
p->mo->spritexscale = (dxs+(((slamDiv*2)/3)*2));
p->mo->spriteyscale = (dys-(slamDiv));
if (p->mo->stretchslam > 0)
p->mo->stretchslam -= (4*mos);
else
p->mo->stretchslam = 0;
}
p->mo->spritexscale = (dxs+(((slamDiv*2)/3)*2));
p->mo->spriteyscale = (dys-(slamDiv));
if (p->mo->stretchslam > 0)
p->mo->stretchslam -= (4*mos);
else
p->mo->stretchslam = 0;
}
}
static void K_QuiteSaltyHop(player_t *p)
static void K_QuiteSaltyHop(player_t *p)
{
// what the fuck is this haya
fixed_t mos = FRACUNIT; // doesnt work correctly if it isnt :/
@@ -3266,7 +3256,7 @@ static void K_QuiteSaltyHop(player_t *p)
p->mo->salty_zoffset = 0;
p->mo->salty_momz = 0;
p->mo->init_salty = true;
}
}
else if ((p->mo->salty_jump)) {
if (p->mo->eflags & MFE_JUSTHITFLOOR) {
p->mo->salty_zoffset = 0;
@@ -3300,7 +3290,7 @@ static void K_QuiteSaltyHop(player_t *p)
p->mo->salty_jump = true;
p->mo->salty_zoffset = 0;
p->mo->salty_momz = 6*mos;
if (cv_saltyhopsfx.value)
if (cv_saltyhopsfx.value)
S_StartSound(p->mo, sfx_s25a);
}
}
@@ -3309,56 +3299,55 @@ static void K_QuiteSaltyHop(player_t *p)
void K_RollMobjBySlopes(mobj_t* mo, boolean usedistance)
{
I_Assert(mo->subsector != NULL);
I_Assert(mo->subsector->sector != NULL);
I_Assert(mo->subsector != NULL);
I_Assert(mo->subsector->sector != NULL);
angle_t an;
boolean flip = mo->eflags & MFE_VERTICALFLIP;
fixed_t m_dist = R_PointToDist(mo->x, mo->y);
fixed_t rolldist = cv_sloperolldist.value * mapobjectscale;
angle_t an;
const boolean flip = mo->eflags & MFE_VERTICALFLIP;
const fixed_t m_dist = usedistance ? R_PointToDist(mo->x, mo->y) : 0;
const fixed_t rolldist = cv_sloperolldist.value * mapobjectscale;
// lifted from hw_md2
if (mo->standingslope)
{
fixed_t tempz = mo->standingslope->normal.z;
fixed_t tempy = mo->standingslope->normal.y;
fixed_t tempx = mo->standingslope->normal.x;
fixed_t tempangle = -(R_PointToAngle2(
0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx));
// lifted from hw_md2
if (mo->standingslope)
{
fixed_t tempz = mo->standingslope->normal.z;
fixed_t tempy = mo->standingslope->normal.y;
fixed_t tempx = mo->standingslope->normal.x;
fixed_t tempangle = -(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx));
// admittedly this is a very hacky way to do the pitch and roll easing
// admittedly this is a very hacky way to do the pitch and roll easing
// pitch
if ((!usedistance) || (m_dist <= (rolldist)))
{
an = (INT32)((angle_t)tempangle - mo->pitch_sprite) / SLOPEROLL_DIV;
// pitch
if ((!usedistance) || (m_dist <= (rolldist)))
{
an = (INT32)((angle_t)tempangle - mo->pitch_sprite) / SLOPEROLL_DIV;
mo->pitch_sprite = an ? mo->pitch_sprite + an : (angle_t)tempangle;
}
else
mo->pitch_sprite = FixedAngle(0);
mo->pitch_sprite = an ? mo->pitch_sprite + an : (angle_t)tempangle;
}
else
mo->pitch_sprite = FixedAngle(0);
mo->slopepitch = flip ? InvAngle(mo->pitch_sprite) : mo->pitch_sprite;
mo->slopepitch = flip ? InvAngle(mo->pitch_sprite) : mo->pitch_sprite;
// roll
tempangle = (R_PointToAngle2(0, 0, tempz, tempy));
// roll
tempangle = (R_PointToAngle2(0, 0, tempz, tempy));
if ((!usedistance) || (m_dist <= (rolldist)))
{
an = (INT32)((angle_t)tempangle - mo->roll_sprite) / SLOPEROLL_DIV;
if (!usedistance || (m_dist <= (rolldist)))
{
an = (INT32)((angle_t)tempangle - mo->roll_sprite) / SLOPEROLL_DIV;
mo->roll_sprite = an ? mo->roll_sprite + an : (angle_t)tempangle;
}
else
mo->roll_sprite = FixedAngle(0);
mo->roll_sprite = an ? mo->roll_sprite + an : (angle_t)tempangle;
}
else
mo->roll_sprite = FixedAngle(0);
mo->sloperoll = flip ? InvAngle(mo->roll_sprite) : mo->roll_sprite;
}
else if (P_IsObjectOnGround(mo))
{
mo->sloperoll = FixedAngle(0);
mo->slopepitch = FixedAngle(0);
}
mo->sloperoll = flip ? InvAngle(mo->roll_sprite) : mo->roll_sprite;
}
else if (P_IsObjectOnGround(mo))
{
mo->sloperoll = FixedAngle(0);
mo->slopepitch = FixedAngle(0);
}
}
void K_SpawnBoostTrail(player_t *player)
@@ -4461,7 +4450,6 @@ void K_RepairOrbitChain(mobj_t *orbit)
if (orbit->target && orbit->target->player)
{
player_t *player = orbit->target->player;
INT32 num = 0;
mobj_t *cur = orbit->target->hnext;
@@ -5360,12 +5348,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
// Handle invincibility sfx
K_UpdateInvincibilitySounds(player); // Also thanks, VAda!
// Plays the music after the starting countdown.
if (P_IsLocalPlayer(player) && leveltime == (starttime + (TICRATE/2)))
{
S_ChangeMusic(mapmusname, mapmusflags, true);
S_ShowMusicCredit();
}
// Plays the music during and after the starting countdown.
if (P_IsLocalPlayer(player))
S_StartMapMusic(false);
}
void K_KartPlayerAfterThink(player_t *player)
@@ -6508,14 +6493,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->mo->spriteyscale = player->mo->realyscale;
}
boolean usedist = false;
if (cv_sloperolldist.value > 0)
usedist = true;
if ((cv_spriteroll.value) && (cv_sloperoll.value))
if (cv_spriteroll.value && cv_sloperoll.value)
{
if ((!player->mo->salty_jump)) // seeing a character rotate mid-hop looks really janky
K_RollMobjBySlopes(player->mo, usedist);
K_RollMobjBySlopes(player->mo, (cv_sloperolldist.value && !splitscreen));
}
else
{
@@ -6553,10 +6534,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if ((leveltime == starttime-(3*TICRATE)) || (leveltime == starttime-(2*TICRATE)) || (leveltime == starttime-TICRATE))
S_StartSound(NULL, sfx_s3ka7);
if (leveltime == starttime)
{
S_StartSound(NULL, sfx_s3kad);
S_StopMusic(); // The GO! sound stops the level start ambience
}
}
// Start charging once you're given the opportunity.
@@ -7118,7 +7096,7 @@ void K_LoadKartHUDGraphics(void)
kp_karmasticker = W_CachePatchName("K_STKARM", PU_HUDGFX);
kp_splitkarmabomb = W_CachePatchName("K_SPTKRM", PU_HUDGFX);
kp_timeoutsticker = W_CachePatchName("K_STTOUT", PU_HUDGFX);
if (xtra_speedo) // snowy speedometer
{
skp_smallsticker = W_CachePatchName("SP_SMSTC", PU_HUDGFX);
@@ -7133,8 +7111,8 @@ void K_LoadKartHUDGraphics(void)
{
skp_smallsticker3 = W_CachePatchName("SP_SM3TC", PU_HUDGFX);
}
if (achi_speedo)
if (achi_speedo)
{
skp_smallstickerachi = W_CachePatchName("SP_AMSTC", PU_HUDGFX);
skp_speedpatchesachi[0] = W_CachePatchName("K_TRNULL", PU_HUDGFX); // lolxd
@@ -7144,7 +7122,7 @@ void K_LoadKartHUDGraphics(void)
skp_speedpatchesachi[4] = W_CachePatchName("SP_APERC", PU_HUDGFX);
}
if (big_lap){
if (big_lap){
kp_lapstickerbig = W_CachePatchName("K_STLAPB", PU_HUDGFX);
kp_lapstickerbig2 = W_CachePatchName("K_STLA2B", PU_HUDGFX);
}
@@ -7166,8 +7144,8 @@ void K_LoadKartHUDGraphics(void)
kp_itembgclr[3] = W_CachePatchName("K_ISBCD", PU_HUDGFX);
kp_itemmulstickerclr[1] = W_CachePatchName("K_ISMULC", PU_HUDGFX);
kp_itemmulstickerclr[0] = W_CachePatchName("K_ITMULC", PU_HUDGFX);
if (big_lap_color){
if (big_lap_color){
kp_lapstickerbigclr = W_CachePatchName("K_SCLAPB", PU_HUDGFX);
kp_lapstickerbig2clr = W_CachePatchName("K_SCLA2B", PU_HUDGFX);
}
@@ -7177,8 +7155,8 @@ void K_LoadKartHUDGraphics(void)
if (xtra_speedo3 && xtra_speedo_clr3) // 80x11 patch scaled to size
skp_smallstickerclr3 = W_CachePatchName("SC_SM3TC", PU_HUDGFX);
if (achi_speedo && achi_speedo_clr)
if (achi_speedo && achi_speedo_clr)
{
skp_smallstickerachiclr = W_CachePatchName("SC_AMSTC", PU_HUDGFX);
skp_speedpatchesachiclr[0] = W_CachePatchName("K_TRNULL", PU_HUDGFX); // lolxd
@@ -7209,13 +7187,13 @@ void K_LoadKartHUDGraphics(void)
// Nametags
if (nametaggfx)
{
nametagpic = W_CachePatchName("NTLINE", PU_HUDGFX);
nametagline = W_CachePatchName("NTLINEV", PU_HUDGFX);
nametagspeed = W_CachePatchName("NTSP", PU_HUDGFX);
nametagweight = W_CachePatchName("NTWH", PU_HUDGFX);
}
if (driftgaugegfx){
driftgauge = W_CachePatchName("K_DGAU", PU_HUDGFX);
driftgaugecolor = W_CachePatchName("K_DCAU", PU_HUDGFX);
@@ -7782,7 +7760,7 @@ static void K_drawKartStats(void)
flags = V_SNAPTOBOTTOM|V_SNAPTOLEFT;
UINT8 splitnum = 0;
for (; splitnum < MAXSPLITSCREENPLAYERS; ++splitnum)
{
if (stplyr == &players[displayplayers[splitnum]])
@@ -7791,7 +7769,7 @@ static void K_drawKartStats(void)
if (!LUA_HudEnabled(hud_statdisplay))
return;
//Internal offset for speedometer
if (cv_kartspeedometer.value)
{
@@ -8355,7 +8333,7 @@ static void K_DrawKartPositionNum(INT32 num)
scale *= 2;
overtake = true; // this is used for splitscreen stuff in conjunction with flipdraw.
}
if (splitscreen || (cv_showinput.value && !splitscreen))
scale /= 2;
@@ -8647,7 +8625,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
p = &players[tab[i].num];
if (cv_highresportrait.value)
V_DrawSmallMappedPatch(x, y-4, 0, R_GetSkinFaceWant(p), colormap);
else
else
V_DrawMappedPatch(x, y-4, 0, R_GetSkinFaceRank(p), colormap);
}
/*if (G_BattleGametype() && players[tab[i].num].kartstuff[k_bumper] > 0) -- not enough space for this
@@ -8789,7 +8767,7 @@ static void K_drawKartSpeedometer(void)
//KartZ speedo
fixed_t fuspeed = 0;
INT32 spdpatch = 0;
INT32 speedtype = 0;
INT32 splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM|V_SNAPTOLEFT);
@@ -8817,7 +8795,7 @@ static void K_drawKartSpeedometer(void)
}
// man.
if ((cv_newspeedometer.value == 1) || (cv_newspeedometer.value == 2 && !xtra_speedo) || (cv_newspeedometer.value == 3 && !achi_speedo) || (cv_newspeedometer.value == 4 && !kartzspeedo) || (cv_newspeedometer.value == 5 && !xtra_speedo3))
if ((cv_newspeedometer.value == 1) || (cv_newspeedometer.value == 2 && !xtra_speedo) || (cv_newspeedometer.value == 3 && !achi_speedo) || (cv_newspeedometer.value == 4 && !kartzspeedo) || (cv_newspeedometer.value == 5 && !xtra_speedo3))
{
switch (speedtype) {
case 1:
@@ -8866,8 +8844,8 @@ static void K_drawKartSpeedometer(void)
V_DrawScaledPatch(SPDM_X + 1, SPDM_Y + 4, (V_HUDTRANS|splitflags), (skp_smallstickerachi));
V_DrawRankNum(SPDM_X + 26, SPDM_Y + 4, V_HUDTRANS|splitflags, convSpeed, 3, NULL);
V_DrawScaledPatch(SPDM_X + 31, SPDM_Y + 4, V_HUDTRANS|splitflags, skp_speedpatchesachi[cv_kartspeedometer.value]);
}
}
}
}
else if (cv_newspeedometer.value == 5 && xtra_speedo3) // why bother if we dont?
{
if (K_UseColorHud() && xtra_speedo_clr3) //Colourized hud
@@ -8881,19 +8859,19 @@ static void K_drawKartSpeedometer(void)
V_DrawRankNum(SPDM_X + 26, SPDM_Y + 4, V_HUDTRANS|splitflags, convSpeed, 3, NULL);
V_DrawScaledPatch(SPDM_X + 31, SPDM_Y + 4, V_HUDTRANS|splitflags, skp_speedpatches[cv_kartspeedometer.value]);
}
// Kart Z speedo bullshit...
// Draw the Speed counter.
else if (cv_newspeedometer.value == 4 && kartzspeedo)
{
fuspeed = FixedDiv(stplyr->speed, mapobjectscale)/FRACUNIT;
#define NUM_INTERVALS 22
const int speedIntervals[NUM_INTERVALS] = {2, 5, 7, 10, 12, 15, 17, 20, 22, 25, 27, 30, 32, 35, 37, 40, 42, 45, 47, 50, 52, 55};
for (int i = 0; i < NUM_INTERVALS; ++i)
for (int i = 0; i < NUM_INTERVALS; ++i)
{
if (fuspeed < speedIntervals[i])
if (fuspeed < speedIntervals[i])
{
spdpatch = i;
break;
@@ -9037,7 +9015,7 @@ static boolean K_GetScreenCoords(vector2_t *vec, player_t *player, mobj_t *targe
#ifdef HWRENDER
// NOW we can get the angle differnce
if (rendermode == render_opengl && cv_grshearing.value == 0)
if (rendermode == render_opengl && cv_glshearing.value == 0)
{
angle_t yang = R_PointToAngle2(0, 0, dist, y); // not perspective
x = FixedMul(x, FINECOSINE((yang>>ANGLETOFINESHIFT) & FINEMASK)); // perspective
@@ -9083,9 +9061,9 @@ static boolean K_GetScreenCoords(vector2_t *vec, player_t *player, mobj_t *targe
// project the angle to get our final X coordinate
x = FixedMul(FINETANGENT(((x+ANGLE_90)>>ANGLETOFINESHIFT) & 4095), fov);
if (splitscreen == 1) // divide by 320/200 (1.6) on 2P splitscreen
x = (x/2) + (x/8);
x = (x/2) + (x/8);
x = x + xres;
// now clip in screen-space
if (!dontclip && (x < 0 || x > xres*2 || y < 0 || y > yres*2))
return false;
@@ -9148,7 +9126,7 @@ static void K_drawNameTags(void)
fixed_t maxdistance = (10*cv_nametagdist.value)* mapobjectscale;
flipped = 0;
fixed_t z;
if (i > PLAYERSMASK)
continue;
if (!players[i].mo || P_MobjWasRemoved(players[i].mo) || players[i].spectator || !playeringame[i])
@@ -9187,7 +9165,7 @@ static void K_drawNameTags(void)
trans = V_40TRANS;
else if (distance > (maxdistance*3/5))
trans = V_20TRANS;
else
else
trans = 0;
break;
case 3:
@@ -9370,6 +9348,9 @@ static void K_drawDriftGauge(void)
0, 31, 47, 63, 79, 95, 111, 119, 127, 143, 159, 175, 183, 191, 199, 207, 223, 247
};
if (demo.playback && demo.freecam)
return;
if (!stplyr->mo || (!splitscreen && !camera->chase))
return;
@@ -9384,7 +9365,7 @@ skipcrap:
if (!K_GetScreenCoords(&pos, stplyr, stplyr->mo, FixedMul(cv_driftgaugeofs.value, cv_driftgaugeofs.value > 0 ? stplyr->mo->scale : mapobjectscale), false))
return;
basex = pos.x>>FRACBITS;
basex = pos.x>>FRACBITS;
basey = pos.y>>FRACBITS;
fixed_t barx;
@@ -9622,7 +9603,7 @@ static void K_drawKartPlayerCheck(void)
}
}
static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags, patch_t *AutomapPic)
static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags)
{
// amnum xpos & ypos are the icon's speed around the HUD.
// The number being divided by is for how fast it moves.
@@ -9635,65 +9616,40 @@ static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags, pat
boolean skinlocal = mo->skinlocal;
fixed_t amnumxpos, amnumypos;
INT32 amxpos, amypos;
node_t *bsp = &nodes[numnodes-1];
fixed_t maxx, minx, maxy, miny;
fixed_t mapwidth, mapheight;
fixed_t xoffset, yoffset;
fixed_t xscale, yscale, zoom;
INT32 amxpos, amypos, wntdamxpos, wntdamypos;
fixed_t scale = FRACUNIT;
if (mo->skin)
skin = ((skin_t*)((mo->localskin) ? mo->localskin : mo->skin))-((skinlocal) ? localskins : skins);
skin = ((skin_t*)(mo->localskin ? mo->localskin : mo->skin))-(skinlocal ? localskins : skins);
maxx = maxy = INT32_MAX;
minx = miny = INT32_MIN;
minx = bsp->bbox[0][BOXLEFT];
maxx = bsp->bbox[0][BOXRIGHT];
miny = bsp->bbox[0][BOXBOTTOM];
maxy = bsp->bbox[0][BOXTOP];
if (bsp->bbox[1][BOXLEFT] < minx)
minx = bsp->bbox[1][BOXLEFT];
if (bsp->bbox[1][BOXRIGHT] > maxx)
maxx = bsp->bbox[1][BOXRIGHT];
if (bsp->bbox[1][BOXBOTTOM] < miny)
miny = bsp->bbox[1][BOXBOTTOM];
if (bsp->bbox[1][BOXTOP] > maxy)
maxy = bsp->bbox[1][BOXTOP];
// You might be wondering why these are being bitshift here
// it's because mapwidth and height would otherwise overflow for maps larger than half the size possible...
// map boundaries and sizes will ALWAYS be whole numbers thankfully
// later calculations take into consideration that these are actually not in terms of FRACUNIT though
minx >>= FRACBITS;
maxx >>= FRACBITS;
miny >>= FRACBITS;
maxy >>= FRACBITS;
mapwidth = maxx - minx;
mapheight = maxy - miny;
// These should always be small enough to be bitshift back right now
xoffset = (minx + mapwidth/2)<<FRACBITS;
yoffset = (miny + mapheight/2)<<FRACBITS;
xscale = FixedDiv(AutomapPic->width, mapwidth);
yscale = FixedDiv(AutomapPic->height, mapheight);
zoom = FixedMul(min(xscale, yscale), FRACUNIT-FRACUNIT/20);
amnumxpos = (FixedMul(lerp(mo->old_x, mo->x), zoom) - FixedMul(xoffset, zoom));
amnumypos = -(FixedMul(lerp(mo->old_y, mo->y), zoom) - FixedMul(yoffset, zoom));
amnumxpos = (FixedMul(lerp(mo->old_x, mo->x), minimapinfo.zoom) - minimapinfo.offs_x);
amnumypos = -(FixedMul(lerp(mo->old_y, mo->y), minimapinfo.zoom) - minimapinfo.offs_y);
if (encoremode)
amnumxpos = -amnumxpos;
amxpos = amnumxpos + ((x + AutomapPic->width/2 - (((skinlocal) ? localfacemmapprefix : facemmapprefix)[skin]->width/2))<<FRACBITS);
amypos = amnumypos + ((y + AutomapPic->height/2 - (((skinlocal) ? localfacemmapprefix : facemmapprefix)[skin]->height/2))<<FRACBITS);
amxpos = amnumxpos + ((x + (SHORT(minimapinfo.minimap_pic->width)-SHORT((skinlocal ? localfacemmapprefix : facemmapprefix)[skin]->width)) / 2)<<FRACBITS);
amypos = amnumypos + ((y + (SHORT(minimapinfo.minimap_pic->height)-SHORT((skinlocal ? localfacemmapprefix : facemmapprefix)[skin]->height)) / 2)<<FRACBITS);
if (cv_showminimapnames.value && mo->player && !(modeattacking || gamestate == GS_TIMEATTACK))
{
const char *player_name = va("%c%s", (mo->color) ? V_GetSkincolorChar(mo->color) : 0, player_names[mo->player - players]);
V_DrawCenteredSmallStringAtFixed(amxpos + (4*FRACUNIT), amypos - (3*FRACUNIT), V_ALLOWLOWERCASE|flags, player_name);
}
// thx wanted reticle for having weird offsets very cool
wntdamxpos = cv_minihead.value ? amxpos + (1<<FRACBITS) : amxpos - (4<<FRACBITS);
wntdamypos = cv_minihead.value ? amypos + (1<<FRACBITS) : amypos - (4<<FRACBITS);
if (cv_minihead.value)
{
amxpos += (SHORT((skinlocal ? localfacemmapprefix : facemmapprefix)[skin]->width) / 4)<<FRACBITS;
amypos += (SHORT((skinlocal ? localfacemmapprefix : facemmapprefix)[skin]->height) / 4)<<FRACBITS;
scale /= 2;
}
if (!mo->color) // 'default' color
V_DrawSciencePatch(amxpos, amypos, flags, ( (skinlocal) ? localfacemmapprefix : facemmapprefix )[skin], FRACUNIT);
V_DrawSciencePatch(amxpos, amypos, flags, ((skinlocal) ? localfacemmapprefix : facemmapprefix)[skin], scale);
else
{
UINT8 *colormap;
@@ -9701,25 +9657,14 @@ static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags, pat
colormap = R_GetTranslationColormap(TC_RAINBOW, mo->color, GTC_CACHE);
else
colormap = R_GetLocalTranslationColormap(mo->skin, mo->localskin, mo->color, GTC_CACHE, skinlocal);
if (cv_minihead.value)
V_DrawFixedPatch(amxpos + (2*FRACUNIT), amypos + (2*FRACUNIT), FRACUNIT/2, flags, ((skinlocal) ? localfacemmapprefix : facemmapprefix)[skin], colormap);
else
V_DrawFixedPatch(amxpos, amypos, FRACUNIT, flags, ((skinlocal) ? localfacemmapprefix : facemmapprefix)[skin], colormap);
if (cv_showminimapnames.value && !(modeattacking || gamestate == GS_TIMEATTACK))
{
const char *player_name = va("%c%s", V_GetSkincolorChar(mo->color), player_names[mo->player - players]);
V_DrawCenteredSmallStringAtFixed(amxpos + (4*FRACUNIT), amypos - (3*FRACUNIT), V_ALLOWLOWERCASE|flags, player_name);
}
V_DrawFixedPatch(amxpos, amypos, scale, flags, ((skinlocal) ? localfacemmapprefix : facemmapprefix)[skin], colormap);
if (mo->player
&& ((G_RaceGametype() && mo->player->kartstuff[k_position] == spbplace)
|| (G_BattleGametype() && K_IsPlayerWanted(mo->player))))
{
if (cv_minihead.value)
V_DrawFixedPatch(amxpos, amypos, FRACUNIT/2, flags, kp_wantedreticle, NULL);
else
V_DrawFixedPatch(amxpos - (4<<FRACBITS), amypos - (4<<FRACBITS), FRACUNIT, flags, kp_wantedreticle, NULL);
V_DrawFixedPatch(wntdamxpos, wntdamypos, scale, flags, kp_wantedreticle, NULL);
}
}
}
@@ -9728,8 +9673,6 @@ static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags, pat
static void K_drawKartMinimap(void)
{
INT32 lumpnum;
patch_t *AutomapPic;
INT32 i = 0;
INT32 x, y;
INT32 minimaptrans, splitflags;
@@ -9744,17 +9687,15 @@ static void K_drawKartMinimap(void)
if (stplyr != &players[displayplayers[0]])
return;
lumpnum = W_CheckNumForName(va("%sR", G_BuildMapName(gamemap)));
if (lumpnum != -1)
AutomapPic = W_CachePatchName(va("%sR", G_BuildMapName(gamemap)), PU_HUDGFX);
else
if (minimapinfo.minimap_pic == NULL)
{
return; // no pic, just get outta here
}
drawinfo_t info;
K_getMinimapDrawinfo(&info);
x = info.x - (AutomapPic->width/2);
y = info.y - (AutomapPic->height/2);
x = info.x - (SHORT(minimapinfo.minimap_pic->width)/2);
y = info.y - (SHORT(minimapinfo.minimap_pic->height)/2);
splitflags = info.flags;
@@ -9775,9 +9716,9 @@ static void K_drawKartMinimap(void)
splitflags |= minimaptrans;
if (encoremode)
V_DrawScaledPatch(x+(AutomapPic->width), y, splitflags|V_FLIP, AutomapPic);
V_DrawScaledPatch(x+SHORT(minimapinfo.minimap_pic->width), y, splitflags|V_FLIP, minimapinfo.minimap_pic);
else
V_DrawScaledPatch(x, y, splitflags, AutomapPic);
V_DrawScaledPatch(x, y, splitflags, minimapinfo.minimap_pic);
if (!(splitscreen == 2))
{
@@ -9787,10 +9728,10 @@ static void K_drawKartMinimap(void)
// let offsets transfer to the heads, too!
if (encoremode)
x += SHORT(AutomapPic->leftoffset);
x += SHORT(minimapinfo.minimap_pic->leftoffset);
else
x -= SHORT(AutomapPic->leftoffset);
y -= SHORT(AutomapPic->topoffset);
x -= SHORT(minimapinfo.minimap_pic->leftoffset);
y -= SHORT(minimapinfo.minimap_pic->topoffset);
// initialize
for (i = 0; i < 4; i++)
@@ -9802,7 +9743,7 @@ static void K_drawKartMinimap(void)
demoghost *g = ghosts;
while (g)
{
K_drawKartMinimapHead(g->mo, x, y, splitflags, AutomapPic);
K_drawKartMinimapHead(g->mo, x, y, splitflags);
g = g->next;
}
@@ -9843,7 +9784,7 @@ static void K_drawKartMinimap(void)
continue;
}
K_drawKartMinimapHead(players[i].mo, x, y, splitflags, AutomapPic);
K_drawKartMinimapHead(players[i].mo, x, y, splitflags);
}
}
@@ -9855,7 +9796,7 @@ static void K_drawKartMinimap(void)
{
if (i == -1)
continue; // this doesn't interest us
K_drawKartMinimapHead(players[localplayers[i]].mo, x, y, splitflags, AutomapPic);
K_drawKartMinimapHead(players[localplayers[i]].mo, x, y, splitflags);
}
}
@@ -10556,7 +10497,7 @@ void K_drawKartHUD(void)
// Draw the item window
if (LUA_HudEnabled(hud_item) && !freecam)
K_drawKartItem();
K_drawKartItem();
if (cv_driftgauge.value && !modeattacking)
{
+3 -5
View File
@@ -1553,8 +1553,9 @@ static int lib_pSetSkyboxMobj(lua_State *L)
// Shhh, neither does P_StartQuake.
static int lib_pStartQuake(lua_State *L)
{
tic_t q_time = (tic_t)luaL_checkinteger(L, 2);
fixed_t q_intensity = luaL_checkinteger(L, 1);
UINT16 q_time = (UINT16)luaL_checkinteger(L, 2);
fixed_t q_radius = luaL_optinteger(L, 4, 512<<FRACBITS);
static mappoint_t q_epicenter = {0,0,0};
NOHUD
@@ -1606,11 +1607,8 @@ static int lib_pStartQuake(lua_State *L)
}
else
quake.epicenter = NULL;
quake.radius = luaL_optinteger(L, 4, 512*FRACUNIT);
// These things are actually used in 2.1.
quake.intensity = q_intensity;
quake.time = q_time;
P_StartQuake(q_time, q_intensity, q_radius);
return 0;
}
+6 -1
View File
@@ -81,6 +81,9 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum)
lua_pushstring(gL, buf);
}
LUA_Call(gL, (int)argc, 0, 1); // argc is 1-based, so this will cover the player we passed too.
lua_pop(gL, 1); // Pop LUA_GetErrorMessage (lua_pcall doesn't pop it)
return;
deny:
@@ -143,7 +146,7 @@ void COM_Lua_f(void)
if (netgame && !( flags & COM_LOCAL ))/* don't send local commands */
{ // Send the command through the network
UINT8 argc;
lua_pop(gL, 1); // pop command info table
lua_pop(gL, 2); // pop command info table and LUA_GetErrorMessage
if (flags & COM_ADMIN && !server && !IsPlayerAdmin(playernum)) // flag 1: only server/admin can use this command.
{
@@ -182,6 +185,8 @@ void COM_Lua_f(void)
for (i = 1; i < COM_Argc(); i++)
lua_pushstring(gL, COM_Argv(i));
LUA_Call(gL, (int)COM_Argc(), 0, 1); // COM_Argc is 1-based, so this will cover the player we passed too.
lua_pop(gL, 1); // Pop LUA_GetErrorMessage (lua_pcall doesn't pop it)
}
// Wrapper for COM_AddCommand
+47 -87
View File
@@ -591,26 +591,16 @@ static int libd_drawOnMinimap(lua_State *L)
UINT8 *colormap = NULL; // do we want to colormap this patch?
boolean centered; // the patch is centered and doesn't need readjusting on x/y coordinates.
huddrawlist_h list;
// variables used to replicate k_kart's mmap drawer:
INT32 lumpnum;
patch_t *AutomapPic;
INT32 mx, my;
INT32 splitflags, minimaptrans;
patch_t *AutomapPic = NULL;
// base position of the minimap which also takes splits into account:
INT32 MM_X, MM_Y;
// variables used for actually drawing the icon:
INT32 splitflags, minimaptrans;
fixed_t amnumxpos, amnumypos;
INT32 amxpos, amypos;
node_t *bsp = &nodes[numnodes-1];
fixed_t maxx, minx, maxy, miny;
fixed_t mapwidth, mapheight;
fixed_t xoffset, yoffset;
fixed_t xscale, yscale, zoom;
fixed_t amxpos, amypos;
INT32 mm_x, mm_y;
fixed_t patchw, patchh;
HUDONLY // only run this function in hud hooks
@@ -622,8 +612,6 @@ static int libd_drawOnMinimap(lua_State *L)
colormap = *((UINT8 **)luaL_checkudata(L, 5, META_COLORMAP));
centered = lua_optboolean(L, 6);
// replicate exactly what source does for its minimap drawer; AKA hardcoded garbo.
// first, check what position the mmap is supposed to be in (pasted from k_kart.c):
MM_X = BASEVIDWIDTH - 50 + cv_mini_xoffset.value; // 270
MM_Y = (BASEVIDHEIGHT/2)-16 + cv_mini_yoffset.value; // 84
@@ -658,7 +646,6 @@ static int libd_drawOnMinimap(lua_State *L)
else
return 0;
minimaptrans = ((10-minimaptrans)<<FF_TRANSSHIFT);
splitflags |= minimaptrans;
@@ -679,97 +666,70 @@ static int libd_drawOnMinimap(lua_State *L)
if (stplyr != &players[displayplayers[0]])
return 0;
lumpnum = W_CheckNumForName(va("%sR", G_BuildMapName(gamemap)));
AutomapPic = minimapinfo.minimap_pic;
if (lumpnum != -1)
AutomapPic = W_CachePatchName(va("%sR", G_BuildMapName(gamemap)), PU_HUDGFX);
else
if (!AutomapPic)
{
return 0; // no pic, just get outta here
}
mx = MM_X - (AutomapPic->width/2);
my = MM_Y - (AutomapPic->height/2);
// Handle offsets and stuff.
mm_x = MM_X - (SHORT(AutomapPic->width)/2);
mm_y = MM_Y - (SHORT(AutomapPic->height)/2);
// let offsets transfer to the heads, too!
if (encoremode)
mx += SHORT(AutomapPic->leftoffset);
{
mm_x += SHORT(AutomapPic->leftoffset);
}
else
mx -= SHORT(AutomapPic->leftoffset);
my -= SHORT(AutomapPic->topoffset);
{
mm_x -= SHORT(AutomapPic->leftoffset);
}
// now that we have replicated this behavior, we can draw an icon from our supplied x, y coordinates by replicating k_kart.c's totally understandable uncommented code!!!
// get map boundaries using nodes
maxx = maxy = INT32_MAX;
minx = miny = INT32_MIN;
minx = bsp->bbox[0][BOXLEFT];
maxx = bsp->bbox[0][BOXRIGHT];
miny = bsp->bbox[0][BOXBOTTOM];
maxy = bsp->bbox[0][BOXTOP];
if (bsp->bbox[1][BOXLEFT] < minx)
minx = bsp->bbox[1][BOXLEFT];
if (bsp->bbox[1][BOXRIGHT] > maxx)
maxx = bsp->bbox[1][BOXRIGHT];
if (bsp->bbox[1][BOXBOTTOM] < miny)
miny = bsp->bbox[1][BOXBOTTOM];
if (bsp->bbox[1][BOXTOP] > maxy)
maxy = bsp->bbox[1][BOXTOP];
// You might be wondering why these are being bitshift here
// it's because mapwidth and height would otherwise overflow for maps larger than half the size possible...
// map boundaries and sizes will ALWAYS be whole numbers thankfully
// later calculations take into consideration that these are actually not in terms of FRACUNIT though
minx >>= FRACBITS;
maxx >>= FRACBITS;
miny >>= FRACBITS;
maxy >>= FRACBITS;
// these are our final map boundaries:
mapwidth = maxx - minx;
mapheight = maxy - miny;
// These should always be small enough to be bitshift back right now
xoffset = (minx + mapwidth/2)<<FRACBITS;
yoffset = (miny + mapheight/2)<<FRACBITS;
xscale = FixedDiv(AutomapPic->width, mapwidth);
yscale = FixedDiv(AutomapPic->height, mapheight);
zoom = FixedMul(min(xscale, yscale), FRACUNIT-FRACUNIT/20);
amnumxpos = (FixedMul(x, zoom) - FixedMul(xoffset, zoom));
amnumypos = -(FixedMul(y, zoom) - FixedMul(yoffset, zoom));
if (encoremode)
amnumxpos = -amnumxpos;
mm_y -= SHORT(AutomapPic->topoffset);
// scale patch coords
patchw = patch->width*scale /2;
patchh = patch->height*scale /2;
patchw = (SHORT(patch->width) * scale / 2);
patchh = (SHORT(patch->height) * scale / 2);
if (centered)
{
patchw = patchh = 0; // patch is supposedly already centered, don't butt in.
}
amxpos = amnumxpos + ((mx + AutomapPic->width/2)<<FRACBITS) - patchw;
amypos = amnumypos + ((my + AutomapPic->height/2)<<FRACBITS) - patchh;
amnumxpos = (FixedMul(x, minimapinfo.zoom) - minimapinfo.offs_x);
amnumypos = -(FixedMul(y, minimapinfo.zoom) - minimapinfo.offs_y);
if (encoremode)
{
amnumxpos = -amnumxpos;
}
amxpos = amnumxpos + ((mm_x + SHORT(AutomapPic->width) / 2)<<FRACBITS) - patchw;
amypos = amnumypos + ((mm_y + SHORT(AutomapPic->height) / 2)<<FRACBITS) - patchh;
// and NOW we can FINALLY DRAW OUR GOD DAMN PATCH :V
lua_getfield(L, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
list = (huddrawlist_h) lua_touserdata(L, -1);
lua_pop(L, 1);
if (LUA_HUD_IsDrawListValid(list)){
if (cv_minihead.value)
LUA_HUD_AddDrawScaled(list, amxpos, amypos, scale/2, patch, splitflags, colormap);
else
LUA_HUD_AddDrawScaled(list, amxpos, amypos, scale, patch, splitflags, colormap);
}else{
if (cv_minihead.value)
V_DrawFixedPatch(amxpos, amypos, scale/2, splitflags, patch, colormap);
else
V_DrawFixedPatch(amxpos, amypos, scale, splitflags, patch, colormap);
if (cv_minihead.value)
{
amxpos += patchw / 2;
amypos += patchh / 2;
scale /= 2;
}
if (LUA_HUD_IsDrawListValid(list))
{
LUA_HUD_AddDrawScaled(list, amxpos, amypos, scale, patch, splitflags, colormap);
}
else
{
V_DrawFixedPatch(amxpos, amypos, scale, splitflags, patch, colormap);
}
return 0;
}
@@ -1612,4 +1572,4 @@ void LUAh_VoteHUD(huddrawlist_h list)
lua_pushlightuserdata(gL, NULL);
lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
}
}
+6
View File
@@ -632,12 +632,18 @@ void LUA_HUD_DrawList(huddrawlist_h list)
switch (item->type)
{
case DI_Draw:
if (!item->patch || item->patch == NULL)
return;
V_DrawFixedPatch(LERPS(x), LERPS(y), FRACUNIT, item->flags, item->patch, item->colormap);
break;
case DI_DrawScaled:
if (!item->patch || item->patch == NULL)
return;
V_DrawFixedPatch(LERPS(x), LERPS(y), LERP(scale), item->flags, item->patch, item->colormap);
break;
case DI_DrawStretched:
if (!item->patch || item->patch == NULL)
return;
V_DrawStretchyFixedPatch(LERPS(x), LERPS(y), LERP(hscale), LERP(vscale), item->flags, item->patch, item->colormap);
break;
case DI_DrawNum:
+3 -1
View File
@@ -111,6 +111,8 @@ static void A_Lua(mobj_t *actor)
lua_pushinteger(gL, var2);
LUA_Call(gL, 3, 0, 1);
lua_pop(gL, 1); // pop error handler
if (found)
{
--superstack;
@@ -940,7 +942,7 @@ static int lib_setSfxInfo(lua_State *L)
if (lua_isnumber(L, 2))
{
int j = lua_tointeger(L, 2) - 1;
int j = lua_tointeger(L, 2);
// Read and Write enums were combined, need to do this switch now
switch (j)
+1 -1
View File
@@ -281,7 +281,7 @@ static int lib_iterateSectorThinglist(lua_State *L)
if (!lua_isnil(L, 1))
{
thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
if (P_MobjWasRemoved(thing))
if (!thing)
return luaL_error(L, "current entry in thinglist was removed; avoid calling P_RemoveMobj on entries!");
thing = thing->snext;
}
+40 -4
View File
@@ -22,6 +22,8 @@
#include "p_saveg.h"
#include "p_local.h"
#include "p_slopes.h" // for P_SlopeById
#include "s_sound.h"
#include "m_menu.h"
#ifdef LUA_ALLOW_BYTECODE
#include "d_netfil.h" // for LUA_DumpFile
#endif
@@ -1333,6 +1335,12 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
break;
case ARCH_TEND:
return 1;
default:
CONS_Alert(CONS_ERROR, "Unknown value type unarchived, save is corrupted!\n");
G_SetExitGameFlag();
S_StartSound(NULL, sfx_syfail); // he he he
M_StartMessage(M_GetText("Corrupted save received\nPress ESC\n"), NULL, MM_NOTHING);
return 1;
}
return 0;
}
@@ -1460,7 +1468,13 @@ static void UnArchiveExtVars(void *pointer)
for (i = 0; i < field_count; i++)
{
READSTRING(save_p, field);
UnArchiveValue(TABLESINDEX);
if (UnArchiveValue(TABLESINDEX) == 1)
{
CONS_Alert(CONS_ERROR, "Unexpected end marker when reading ExtVars (field '%s')\n", field);
break;
}
lua_setfield(gL, -2, field);
}
@@ -1524,12 +1538,29 @@ static void UnArchiveTables(void)
for (i = 1; i <= n; i++)
{
lua_rawgeti(gL, TABLESINDEX, i);
if (!lua_istable(gL, -1))
{
CONS_Alert(CONS_ERROR, "Value in tables list #%d is not a table! (corrupted save?)\n", i);
continue;
}
while (true)
{
if (UnArchiveValue(TABLESINDEX) == 1) // read key
break;
if (UnArchiveValue(TABLESINDEX) == 2) // read value
UINT8 ret = UnArchiveValue(TABLESINDEX);
if (ret == 1)
{
CONS_Alert(CONS_ERROR, "Unexpected end of save reached (Corrupted save?)\n");
lua_pop(gL, 1); // Pop key
break;
}
else if (ret == 2) // read value
n++;
if (lua_isnil(gL, -2)) // if key is nil (if a function etc was accidentally saved)
{
CONS_Alert(CONS_ERROR, "A nil key in table %d was found! (Invalid key type or corrupted save?)\n", i);
@@ -1589,8 +1620,13 @@ void LUA_Step(void)
{
if (!gL)
return;
lua_settop(gL, 0);
lua_gc(gL, LUA_GCSTEP, 1);
if (lua_gettop(gL) != 0)
{
CONS_Alert(CONS_WARNING, "Eek, there is garbage on lua stack!\n");
lua_settop(gL, 0);
lua_gc(gL, LUA_GCSTEP, 1);
}
}
void LUA_Archive(void)
+366 -334
View File
File diff suppressed because it is too large. Load diff
+8
View File
@@ -64,6 +64,10 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines);
// Same but with extra flags applied
void M_DrawTextBoxFlags(INT32 x, INT32 y, INT32 width, INT32 boxlines, INT32 flags);
// Draw text input
typedef struct textinput_s textinput_t;
void M_DrawTextInput(INT32 x, INT32 y, textinput_t *input, INT32 flags);
// Used in d_netcmd to restart time attack
void M_ModeAttackRetry(INT32 choice);
@@ -295,6 +299,10 @@ void Bird_menu_Onchange(void);
// Saturn Hud menu updating
void SaturnHud_menu_Onchange(void);
#ifdef HWRENDER
void M_UpdateOGLMenu(void);
#endif
void M_ReplayHut(INT32 choice);
void M_SetPlaybackMenuPointer(void);
-5
View File
@@ -1987,11 +1987,6 @@ char *sizeu5(size_t num)
return sizeu5_buf;
}
FUNCINLINE ATTRINLINE void *M_Memcpy(void *dest, const void *src, size_t n)
{
return memcpy(dest, src, n);
}
/** Return the appropriate message for a file error or end of file.
*/
const char *M_FileError(FILE *fp)
+13 -5
View File
@@ -10,6 +10,7 @@
/// \brief Performance measurement tools.
#include "m_perfstats.h"
#include "p_mobj.h"
#include "v_video.h"
#include "i_video.h"
#include "d_netcmd.h"
@@ -58,6 +59,7 @@ static ps_metric_t ps_regularcount = {0};
static ps_metric_t ps_scenerycount = {0};
static ps_metric_t ps_nothinkcount = {0};
static ps_metric_t ps_otherthcount = {0};
static ps_metric_t ps_precipcount = {0};
static ps_metric_t ps_removecount = {0};
ps_metric_t ps_checkposition_calls = {0};
@@ -171,6 +173,7 @@ perfstatrow_t thinkercount_rows[] = {
{" regular", " Regular: ", &ps_regularcount, PS_LEVEL},
{" scenery", " Scenery: ", &ps_scenerycount, PS_LEVEL},
{" nothink", " Nothink: ", &ps_nothinkcount, PS_HIDE_ZERO|PS_LEVEL},
{" precip ", " Precipitation: ", &ps_precipcount, PS_LEVEL},
{" other ", " Other: ", &ps_otherthcount, PS_LEVEL},
{" remove ", " Pending removal:", &ps_removecount, PS_LEVEL},
{0}
@@ -298,7 +301,7 @@ static boolean PS_IsRowValid(perfstatrow_t *row)
|| (row->flags & PS_SW && rendermode != render_soft)
|| (row->flags & PS_HW && rendermode != render_opengl)
#ifdef HWRENDER
|| (row->flags & PS_BATCHING && !cv_grbatching.value)
|| (row->flags & PS_BATCHING && !cv_glbatching.value)
#endif
);
}
@@ -515,7 +518,7 @@ static void PS_UpdateFrameStats(void)
ps_hw_spritesorttime.value.p +
ps_hw_spritedrawtime.value.p;
if (cv_grbatching.value)
if (cv_glbatching.value)
{
ps_otherrendertime.value.p -=
ps_hw_batchsorttime.value.p +
@@ -544,7 +547,7 @@ static void PS_UpdateFrameStats(void)
PS_UpdateRowHistories(interpolation_rows, true);*/
#ifdef HWRENDER
if (rendermode == render_opengl && cv_grbatching.value)
if (rendermode == render_opengl && cv_glbatching.value)
{
PS_UpdateRowHistories(batchcount_rows, true);
PS_UpdateRowHistories(batchcalls_rows, true);
@@ -569,11 +572,14 @@ static void PS_CountThinkers(void)
ps_regularcount.value.i = 0;
ps_scenerycount.value.i = 0;
ps_nothinkcount.value.i = 0;
ps_precipcount.value.i = 0;
ps_otherthcount.value.i = 0;
ps_removecount.value.i = 0;
for (thinker = thinkercap.next; thinker != &thinkercap; thinker = thinker->next)
{
ps_thinkercount.value.i++;
if (thinker->function.acp1 != (actionf_p1)P_NullPrecipThinker)
ps_thinkercount.value.i++;
if (thinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
ps_removecount.value.i++;
else if (thinker->function.acp1 == (actionf_p1)P_MobjThinker)
@@ -587,6 +593,8 @@ static void PS_CountThinkers(void)
else
ps_regularcount.value.i++;
}
else if (thinker->function.acp1 == (actionf_p1)P_NullPrecipThinker)
ps_precipcount.value.i++;
else
ps_otherthcount.value.i++;
}
@@ -752,7 +760,7 @@ static void PS_DrawRenderStats(void)
/*cy = */PS_DrawPerfRows(x, 10, V_BLUEMAP, commoncounter_rows);// + half_row;
#ifdef HWRENDER
if (rendermode == render_opengl && cv_grbatching.value)
if (rendermode == render_opengl && cv_glbatching.value)
{
x = hires ? 200 : 155;
y = PS_DrawPerfRows(x, 10, V_PURPLEMAP, batchcount_rows);
+314
View File
@@ -0,0 +1,314 @@
#include "m_textinput.h"
#include "i_system.h"
#include "keys.h"
#include "console.h"
static void M_TextInputDel(textinput_t *input, size_t start, size_t end)
{
size_t len;
len = (end - start);
if (end != input->length)
memmove(&input->buffer[start], &input->buffer[end], input->length-end);
memset(&input->buffer[input->length - len], 0, len);
input->length -= len;
if (input->select >= end)
input->select -= len;
else if (input->select > start)
input->select = start;
if (input->cursor >= end)
input->cursor -= len;
else if (input->cursor > start)
input->cursor = start;
}
static void M_TextInputDelSelection(textinput_t *input)
{
size_t start, end;
if (input->cursor > input->select)
{
start = input->select;
end = input->cursor;
}
else
{
start = input->cursor;
end = input->select;
}
M_TextInputDel(input, start, end);
input->select = input->cursor = start;
}
static void M_TextInputAddString(textinput_t *input, const char *c)
{
size_t csize = strlen(c);
if (input->length + csize > input->buffer_size-1)
return;
if (input->cursor != input->length)
memmove(&input->buffer[input->cursor+csize], &input->buffer[input->cursor], input->length-input->cursor);
memcpy(&input->buffer[input->cursor], c, csize);
input->length += csize;
input->select = (input->cursor += csize);
input->buffer[input->length] = 0;
}
static void M_TextInputAddChar(textinput_t *input, char c)
{
if (input->length >= input->buffer_size-1)
return;
if (input->cursor != input->length)
memmove(&input->buffer[input->cursor+1], &input->buffer[input->cursor], input->length-input->cursor);
input->buffer[input->cursor++] = c;
input->buffer[++input->length] = 0;
input->select = input->cursor;
}
static void M_TextInputDelChar(textinput_t *input)
{
if (!input->cursor)
return;
if (input->cursor != input->length)
memmove(&input->buffer[input->cursor-1], &input->buffer[input->cursor], input->length-input->cursor);
input->buffer[--input->length] = 0;
input->select = --input->cursor;
}
static void M_TextInputToWordEnd(textinput_t *input, boolean move_sel)
{
// Skip spaces
while (input->cursor < input->length && isspace(input->buffer[input->cursor]))
++input->cursor;
// Skip word
while (input->cursor < input->length && !isspace(input->buffer[input->cursor]))
++input->cursor;
if (move_sel) input->select = input->cursor;
}
static void M_TextInputToWordBegin(textinput_t *input, boolean move_sel)
{
// Hack, always move back 1 character if possible so if we press ctrl-left at a word beginning
// we move to previous word
if (input->cursor) --input->cursor;
// Skip spaces
while (input->cursor && isspace(input->buffer[input->cursor]))
--input->cursor;
// Skip word
while (input->cursor && !isspace(input->buffer[input->cursor]))
--input->cursor;
// Unless we reached beginning of line, we're pointing at a space before word, so move cursor
// forward to fix that
if (input->cursor) ++input->cursor;
if (move_sel) input->select = input->cursor;
}
static void M_TextInputPaste(textinput_t *input)
{
const char *paste = I_ClipboardPaste();
if (input->select != input->cursor)
M_TextInputDelSelection(input);
if (paste != NULL)
M_TextInputAddString(input, paste);
}
void M_TextInputInit(textinput_t *input, char *buffer, size_t buffer_size)
{
input->buffer = buffer;
input->buffer_size = buffer_size;
M_TextInputClear(input);
}
void M_TextInputClear(textinput_t *input)
{
input->cursor = 0;
input->select = 0;
input->length = 0;
}
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);
}
boolean M_TextInputHandle(textinput_t *input, INT32 key)
{
if (key == KEY_LSHIFT || key == KEY_RSHIFT
|| key == KEY_LCTRL || key == KEY_RCTRL
|| key == KEY_LALT || key == KEY_RALT)
return false;
if (shiftdown && key == KEY_INS)
{
M_TextInputPaste(input);
return true;
}
if ((cv_keyboardlayout.value != 3 && ctrldown) || (cv_keyboardlayout.value == 3 && ctrldown && !altdown))
{
if (key == 'x' || key == 'X')
{
if (input->select > input->cursor)
I_ClipboardCopy(&input->buffer[input->cursor], input->select-input->cursor);
else
I_ClipboardCopy(&input->buffer[input->select], input->cursor-input->select);
M_TextInputDelSelection(input);
return true;
}
else if (key == 'c' || key == 'C')
{
if (input->select > input->cursor)
I_ClipboardCopy(&input->buffer[input->cursor], input->select-input->cursor);
else
I_ClipboardCopy(&input->buffer[input->select], input->cursor-input->select);
return true;
}
else if (key == 'v' || key == 'V')
{
M_TextInputPaste(input);
return true;
}
else if (key == 'w' || key == 'W')
{
size_t word_start, word_end, i;
word_end = i = input->cursor;
// Unless we're pointing at the beginning of line, decrement i so we only start
// removing symbols that come before the cursor
if (i) --i;
// We might be pointing to spaces, skip them first
while (i && isspace(input->buffer[i]))
--i;
// Now skip the "word"
while (i && !isspace(input->buffer[i]))
--i;
// Unless we reached beginning of line, i is pointing at first space that was found
// before word start, and we don't want to remove it
if (i) ++i;
word_start = i;
if (word_start != word_end)
M_TextInputDel(input, word_start, word_end);
return true;
}
else if (key == KEY_RIGHTARROW)
M_TextInputToWordEnd(input, !shiftdown);
else if (key == KEY_LEFTARROW)
M_TextInputToWordBegin(input, !shiftdown);
// Select all
if (key == 'a' || key == 'A')
{
input->select = 0;
input->cursor = input->length;
return true;
}
// ...why shouldn't it eat the key? if it doesn't, it just means you
// can control Sonic from the console, which is silly
return true;
}
if (key == KEY_LEFTARROW)
{
if (input->cursor != 0)
--input->cursor;
if (!shiftdown)
input->select = input->cursor;
return true;
}
else if (key == KEY_RIGHTARROW)
{
if (input->cursor < input->length)
++input->cursor;
if (!shiftdown)
input->select = input->cursor;
return true;
}
else if (key == KEY_HOME)
{
input->cursor = 0;
if (!shiftdown)
input->select = input->cursor;
return true;
}
else if (key == KEY_END)
{
input->cursor = input->length;
if (!shiftdown)
input->select = input->cursor;
return true;
}
// backspace and delete command prompt
if (input->select != input->cursor)
{
if (key == KEY_BACKSPACE || key == KEY_DEL)
{
M_TextInputDelSelection(input);
return true;
}
}
else if (key == KEY_BACKSPACE)
{
M_TextInputDelChar(input);
return true;
}
else if (key == KEY_DEL)
{
if (input->cursor == input->length)
return true;
++input->cursor;
M_TextInputDelChar(input);
return true;
}
// allow people to use keypad in console (good for typing IP addresses) - Calum
if (key >= KEY_KEYPAD7 && key <= KEY_KPADDEL)
{
char keypad_translation[] = {'7','8','9','-',
'4','5','6','+',
'1','2','3',
'0','.'};
key = keypad_translation[key - KEY_KEYPAD7];
}
else if (key == KEY_KPADSLASH)
key = '/';
// same capslock code as hu_stuff.c's HU_responder. Check there for details.
key = cv_keyboardlayout.value == 3 ? CON_ShitAndAltGrChar(key) : CON_ShiftChar(key);
// enter a char into the command prompt
if (key < 32 || key > 127)
return false;
if (input->select != input->cursor)
M_TextInputDelSelection(input);
M_TextInputAddChar(input, key);
return true;
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef __M_TEXTINPUT__
#define __M_TEXTINPUT__
#include "doomtype.h"
typedef struct textinput_s {
size_t cursor;
size_t select;
size_t length;
char *buffer;
size_t buffer_size;
} textinput_t;
void M_TextInputInit(textinput_t *input, char *buffer, size_t buffer_size);
void M_TextInputClear(textinput_t *input);
void M_TextInputSetString(textinput_t *input, const char *c);
boolean M_TextInputHandle(textinput_t *input, INT32 key);
#endif
+3 -7
View File
@@ -2400,8 +2400,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage);
if (P_MobjWasRemoved(target))
return (shouldForce == 1); // mobj was removed
if (P_MobjWasRemoved(source))
source = NULL;
if (shouldForce == 1)
force = true;
else if (shouldForce == 2)
@@ -2564,8 +2562,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
P_PlayerRingBurst(player, 5);
if (P_IsLocalPlayer(player))
{
quake.intensity = 32*FRACUNIT;
quake.time = 5;
P_StartQuake(5, 32<<FRACBITS, 0);
}
}
else
@@ -2639,6 +2636,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
P_ResetPlayer(target->player);
}
else
{
switch (target->type)
{
case MT_EGGMOBILE2: // egg slimer
@@ -2652,9 +2650,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
P_SetMobjState(target, target->info->painstate);
break;
}
if (P_MobjWasRemoved(target))
return false;
}
if (!P_MobjWasRemoved(target))
{
+30 -4
View File
@@ -164,8 +164,9 @@ void P_InitCameraCmd(void);
boolean P_PlayerInPain(player_t *player);
void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor);
void P_ResetPlayer(player_t *player);
boolean P_IsLocalPlayer(player_t *player);
boolean P_IsDisplayPlayer(player_t *player);
boolean P_IsLocalPlayer(const player_t *player);
boolean P_IsDisplayPlayer(const player_t *player);
boolean P_SpectatorJoinGame(player_t *player);
boolean P_IsObjectInGoop(mobj_t *mo);
@@ -248,7 +249,7 @@ void P_RecalcPrecipInSector(sector_t *sector);
void P_PrecipitationEffects(void);
void P_RemoveMobj(mobj_t *th);
boolean P_MobjWasRemoved(const mobj_t *th);
void P_RemoveSavegameMobj(mobj_t *th);
boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state);
boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
@@ -260,6 +261,12 @@ boolean P_RailThinker(mobj_t *mobj);
void P_PushableThinker(mobj_t *mobj);
void P_SceneryThinker(mobj_t *mobj);
// This does not need to be added to Lua.
// To test it in Lua, check mobj.valid
FUNCINLINE static ATTRINLINE boolean P_MobjWasRemoved(const mobj_t *mobj)
{
return !(mobj && mobj->thinker.function.acp1 == (actionf_p1)P_MobjThinker);
}
fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
@@ -291,7 +298,14 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 aimtype
#define P_SpawnNameFinder(s,t) P_SPMAngle(s,t,s->angle,true,0)
#endif
void P_ColorTeamMissile(mobj_t *missile, player_t *source);
SINT8 P_MobjFlip(const mobj_t *mobj);
// P_MobjFlip
// Special utility to return +1 or -1 depending on mobj's gravity
FUNCINLINE static ATTRINLINE SINT8 P_MobjFlip(const mobj_t *mobj)
{
return (mobj && mobj->eflags & MFE_VERTICALFLIP) ? -1 : 1;
}
fixed_t P_GetMobjGravity(mobj_t *mo);
FUNCMATH boolean P_WeaponOrPanel(mobjtype_t type);
@@ -392,6 +406,18 @@ extern fixed_t bmaporgy; // origin of block map
extern mobj_t **blocklinks; // for thing chains
extern precipmobj_t **precipblocklinks; // special blockmap for precip rendering
extern struct minimapinfo
{
patch_t *minimap_pic;
UINT8 mapthingcount;
INT32 min_x, min_y;
INT32 max_x, max_y;
INT32 map_w, map_h;
INT32 minimap_w, minimap_h;
fixed_t offs_x, offs_y;
fixed_t zoom;
} minimapinfo;
//
// P_INTER
//
+191 -207
View File
@@ -91,6 +91,7 @@ FUNCINLINE static ATTRINLINE void P_CycleStateAnimation(mobj_t *mobj)
// var2 determines delay between animation frames
if (!(mobj->frame & FF_ANIMATE) || --mobj->anim_duration != 0)
return;
mobj->anim_duration = (UINT16)mobj->state->var2;
// compare the current sprite frame to the one we started from
@@ -351,18 +352,6 @@ static boolean P_SetPrecipMobjState(precipmobj_t *mobj, statenum_t state)
return true;
}
//
// P_MobjFlip
//
// Special utility to return +1 or -1 depending on mobj's gravity
//
SINT8 P_MobjFlip(const mobj_t *mobj)
{
if (mobj && mobj->eflags & MFE_VERTICALFLIP)
return -1;
return 1;
}
//
// P_WeaponOrPanel
//
@@ -408,7 +397,7 @@ void P_ExplodeMissile(mobj_t *mo)
P_RadiusAttack(mo, mo, 96*FRACUNIT);
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
if (!P_MobjWasRemoved(explodemo))
if (explodemo)
{
P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale;
@@ -417,7 +406,7 @@ void P_ExplodeMissile(mobj_t *mo)
S_StartSound(explodemo, sfx_pop);
}
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
if (!P_MobjWasRemoved(explodemo))
if (explodemo)
{
P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale;
@@ -426,7 +415,7 @@ void P_ExplodeMissile(mobj_t *mo)
S_StartSound(explodemo, sfx_dmpain);
}
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
if (!P_MobjWasRemoved(explodemo))
if (explodemo)
{
P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale;
@@ -435,7 +424,7 @@ void P_ExplodeMissile(mobj_t *mo)
S_StartSound(explodemo, sfx_pop);
}
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
if (!P_MobjWasRemoved(explodemo))
if (explodemo)
{
P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale;
@@ -592,7 +581,8 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t
{
I_Assert(mobj != NULL);
I_Assert(sector != NULL);
if (sector->f_slope) {
if (sector->f_slope)
{
fixed_t testx, testy;
pslope_t *slope = sector->f_slope;
@@ -607,7 +597,8 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t
else
testy = -mobj->radius;
if ((slope->zdelta > 0) ^ !!(lowest)) {
if ((slope->zdelta > 0) ^ !!(lowest))
{
testx = -testx;
testy = -testy;
}
@@ -620,22 +611,21 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t
return P_GetZAt(slope, testx, testy);
// If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point
if (perfect) {
if (perfect)
{
size_t i;
line_t *ld;
fixed_t bbox[4];
fixed_t finalheight;
if (lowest)
finalheight = INT32_MAX;
else
finalheight = INT32_MIN;
finalheight = lowest ? INT32_MAX : INT32_MIN;
bbox[BOXLEFT] = x-mobj->radius;
bbox[BOXRIGHT] = x+mobj->radius;
bbox[BOXTOP] = y+mobj->radius;
bbox[BOXBOTTOM] = y-mobj->radius;
for (i = 0; i < boundsec->linecount; i++) {
for (i = 0; i < boundsec->linecount; i++)
{
ld = boundsec->lines[i];
if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT]
@@ -668,7 +658,8 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed
{
I_Assert(mobj != NULL);
I_Assert(sector != NULL);
if (sector->c_slope) {
if (sector->c_slope)
{
fixed_t testx, testy;
pslope_t *slope = sector->c_slope;
@@ -683,7 +674,8 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed
else
testy = -mobj->radius;
if ((slope->zdelta > 0) ^ !!(lowest)) {
if ((slope->zdelta > 0) ^ !!(lowest))
{
testx = -testx;
testy = -testy;
}
@@ -696,22 +688,21 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed
return P_GetZAt(slope, testx, testy);
// If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point
if (perfect) {
if (perfect)
{
size_t i;
line_t *ld;
fixed_t bbox[4];
fixed_t finalheight;
if (lowest)
finalheight = INT32_MAX;
else
finalheight = INT32_MIN;
finalheight = lowest ? INT32_MAX : INT32_MIN;
bbox[BOXLEFT] = x-mobj->radius;
bbox[BOXRIGHT] = x+mobj->radius;
bbox[BOXTOP] = y+mobj->radius;
bbox[BOXBOTTOM] = y-mobj->radius;
for (i = 0; i < boundsec->linecount; i++) {
for (i = 0; i < boundsec->linecount; i++)
{
ld = boundsec->lines[i];
if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT]
@@ -746,7 +737,8 @@ fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fix
I_Assert(mobj != NULL);
I_Assert(sector != NULL);
if (sector->f_slope) {
if (sector->f_slope)
{
fixed_t testx, testy;
pslope_t *slope = sector->f_slope;
@@ -761,7 +753,8 @@ fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fix
else
testy = -mobj->radius;
if ((slope->zdelta > 0) ^ !!(lowest)) {
if ((slope->zdelta > 0) ^ !!(lowest))
{
testx = -testx;
testy = -testy;
}
@@ -774,22 +767,21 @@ fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fix
return P_GetZAt(slope, testx, testy);
// If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point
if (perfect) {
if (perfect)
{
size_t i;
line_t *ld;
fixed_t bbox[4];
fixed_t finalheight;
if (lowest)
finalheight = INT32_MAX;
else
finalheight = INT32_MIN;
finalheight = lowest ? INT32_MAX : INT32_MIN;
bbox[BOXLEFT] = x-mobj->radius;
bbox[BOXRIGHT] = x+mobj->radius;
bbox[BOXTOP] = y+mobj->radius;
bbox[BOXBOTTOM] = y-mobj->radius;
for (i = 0; i < boundsec->linecount; i++) {
for (i = 0; i < boundsec->linecount; i++)
{
ld = boundsec->lines[i];
if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT]
@@ -823,7 +815,8 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f
I_Assert(mobj != NULL);
I_Assert(sector != NULL);
if (sector->c_slope) {
if (sector->c_slope)
{
fixed_t testx, testy;
pslope_t *slope = sector->c_slope;
@@ -838,7 +831,8 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f
else
testy = -mobj->radius;
if ((slope->zdelta > 0) ^ !!(lowest)) {
if ((slope->zdelta > 0) ^ !!(lowest))
{
testx = -testx;
testy = -testy;
}
@@ -851,22 +845,21 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f
return P_GetZAt(slope, testx, testy);
// If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point
if (perfect) {
if (perfect)
{
size_t i;
line_t *ld;
fixed_t bbox[4];
fixed_t finalheight;
if (lowest)
finalheight = INT32_MAX;
else
finalheight = INT32_MIN;
finalheight = lowest ? INT32_MAX : INT32_MIN;
bbox[BOXLEFT] = x-mobj->radius;
bbox[BOXRIGHT] = x+mobj->radius;
bbox[BOXTOP] = y+mobj->radius;
bbox[BOXBOTTOM] = y-mobj->radius;
for (i = 0; i < boundsec->linecount; i++) {
for (i = 0; i < boundsec->linecount; i++)
{
ld = boundsec->lines[i];
if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT]
@@ -3238,100 +3231,92 @@ void P_DestroyRobots(void)
}
}
// P_CameraThinker
//
// Process the mobj-ish required functions of the camera
boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled)
// the below is chasecam only, if you're curious. check out P_CalcPostImg in p_user.c for first person
static void P_CalcChasePostImg(player_t *player, camera_t *thiscam)
{
boolean itsatwodlevel = false;
boolean flipcam = (player->pflags & PF_FLIPCAM && !(player->pflags & PF_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP);
postimg_t postimg = postimg_none;
const boolean flipcam = (player->pflags & PF_FLIPCAM && !(player->pflags & PF_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP);
UINT16 postimgflags = 0;
UINT8 i;
// This can happen when joining
if (thiscam->subsector == NULL || thiscam->subsector->sector == NULL)
return true;
if (encoremode)
postimgflags |= POSTIMG_MIRROR;
if (flipcam)
postimgflags |= POSTIMG_FLIP;
if (twodlevel)
itsatwodlevel = true;
else
{
for (i = 0; i <= splitscreen; i++)
{
if (thiscam == &camera[i] && players[displayplayers[i]].mo
&& (players[displayplayers[i]].mo->flags2 & MF2_TWOD))
{
itsatwodlevel = true;
break;
}
}
}
if (encoremode && !flipcam)
postimg = postimg_mirror;
else if (!encoremode && flipcam)
postimg = postimg_flip;
else if (encoremode && flipcam)
postimg = postimg_mirrorflip;
else if (player->awayviewtics && player->awayviewmobj && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist
if (player->awayviewtics && player->awayviewmobj && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist
{
camera_t dummycam;
dummycam.subsector = player->awayviewmobj->subsector;
dummycam.x = player->awayviewmobj->x;
dummycam.y = player->awayviewmobj->y;
dummycam.z = player->awayviewmobj->z;
//dummycam.height = 40*FRACUNIT; // alt view height is 20*FRACUNIT
dummycam.height = 0; // Why? Remote viewpoint cameras have no height.
// Are we in water?
if (P_CameraCheckWater(&dummycam))
postimg = postimg_water;
else if (P_CameraCheckHeat(&dummycam))
postimg = postimg_heat;
postimgflags |= POSTIMG_WATER;
if (P_CameraCheckHeat(&dummycam))
postimgflags |= POSTIMG_HEAT;
}
else
{
// Are we in water?
if (P_CameraCheckWater(thiscam))
postimg = postimg_water;
else if (P_CameraCheckHeat(thiscam))
postimg = postimg_heat;
postimgflags |= POSTIMG_WATER;
if (P_CameraCheckHeat(thiscam))
postimgflags |= POSTIMG_HEAT;
}
if (postimg != postimg_none)
for (i = 0; i <= splitscreen; i++)
{
for (i = 0; i <= splitscreen; i++)
{
if (player != &players[displayplayers[i]])
continue;
if (player != &players[displayplayers[i]])
continue;
postimgtype[i] = postimg;
}
players[displayplayers[i]].postimgflags = postimgflags;
break;
}
}
// P_CameraThinker
//
// Process the mobj-ish required functions of the camera
boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled)
{
// This can happen when joining
if (thiscam->subsector == NULL || thiscam->subsector->sector == NULL)
return true;
P_CalcChasePostImg(player, thiscam);
if (thiscam->momx || thiscam->momy)
{
if (!P_TryCameraMove(thiscam->x + thiscam->momx, thiscam->y + thiscam->momy, thiscam))
{ // Never fails for 2D mode.
if (!P_TryCameraMove(thiscam->x + thiscam->momx, thiscam->y + thiscam->momy, thiscam)) // Never fails for 2D mode.
{
mobj_t dummy;
dummy.thinker.function.acp1 = (actionf_p1)P_MobjThinker;
dummy.subsector = thiscam->subsector;
dummy.x = thiscam->x;
dummy.y = thiscam->y;
dummy.z = thiscam->z;
dummy.height = thiscam->height;
if (player->pflags & PF_TIMEOVER)
player->kartstuff[k_timeovercam] = (2*TICRATE)+1;
if (!resetcalled && !(player->pflags & PF_NOCLIP || leveltime < introtime) && !P_CheckSight(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead.
P_ResetCamera(player, thiscam);
else
P_SlideCameraMove(thiscam);
if (resetcalled) // Okay this means the camera is fully reset.
return true;
}
}
if (!itsatwodlevel)
P_CheckCameraPosition(thiscam->x, thiscam->y, thiscam);
P_CheckCameraPosition(thiscam->x, thiscam->y, thiscam);
thiscam->subsector = R_PointInSubsector(thiscam->x, thiscam->y);
thiscam->floorz = tmfloorz;
@@ -3343,7 +3328,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
thiscam->z += thiscam->momz + player->mo->pmomz;
#ifndef NOCLIPCAM
if (!itsatwodlevel && !(player->pflags & PF_NOCLIP || leveltime < introtime))
if (!(player->pflags & PF_NOCLIP || leveltime < introtime))
{
// clip movement
if (thiscam->z <= thiscam->floorz) // hit the floor
@@ -3386,13 +3371,13 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
#endif
}
if (itsatwodlevel
|| (thiscam->ceilingz - thiscam->z < thiscam->height
&& thiscam->ceilingz >= thiscam->z))
if (thiscam->ceilingz - thiscam->z < thiscam->height
&& thiscam->ceilingz >= thiscam->z)
{
thiscam->ceilingz = thiscam->z + thiscam->height;
thiscam->floorz = thiscam->z;
}
return false;
}
@@ -3406,8 +3391,8 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
I_Assert(mobj != NULL);
I_Assert(mobj->player != NULL);
I_Assert(!P_MobjWasRemoved(mobj));
if (P_MobjWasRemoved(mobj))
if (!mobj)
return;
P_MobjCheckWater(mobj);
@@ -6026,41 +6011,36 @@ static void P_KoopaThinker(mobj_t *koopa)
//
void P_RollPitchMobj(mobj_t* mobj)
{
boolean usedist = false;
if (P_MobjWasRemoved(mobj))
return;
if (!mobj || P_MobjWasRemoved(mobj))
return;
if (cv_sloperolldist.value > 0)
usedist = true;
if ((cv_spriteroll.value) && (cv_sloperoll.value == 2))
{
K_RollMobjBySlopes(mobj, usedist);
}
else
{
mobj->sloperoll = FixedAngle(0);
mobj->slopepitch = FixedAngle(0);
}
if (cv_spriteroll.value && cv_sloperoll.value == 2)
{
K_RollMobjBySlopes(mobj, cv_sloperolldist.value && !splitscreen);
}
else
{
mobj->sloperoll = FixedAngle(0);
mobj->slopepitch = FixedAngle(0);
}
}
angle_t P_MobjPitchAndRoll(mobj_t *mobj)
{
spritedef_t *sprdef;
spriteframe_t *sprframe;
angle_t ang = 0;
spritedef_t *sprdef;
spriteframe_t *sprframe;
angle_t ang = 0;
angle_t camang = 0;
angle_t return_angle = 0;
if (!cv_spriteroll.value)
return 0;
if (P_MobjWasRemoved(mobj))
return 0;
if (P_MobjWasRemoved(mobj))
return 0;
size_t rot = mobj->frame & FF_FRAMEMASK;
boolean papersprite = (mobj->frame & FF_PAPERSPRITE);
size_t rot = mobj->frame & FF_FRAMEMASK;
boolean papersprite = (mobj->frame & FF_PAPERSPRITE);
if (mobj->skin && mobj->sprite == SPR_PLAY)
{
@@ -6091,12 +6071,12 @@ angle_t P_MobjPitchAndRoll(mobj_t *mobj)
camang = R_PointToAngle(mobj->x, mobj->y);
}
return_angle = FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), mobj->roll)
return_angle = FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), mobj->roll)
+ FixedMul(FINESINE((ang) >> ANGLETOFINESHIFT), mobj->pitch);
if (cv_sloperoll.value)
{
return_angle += FixedMul(FINECOSINE((camang) >> ANGLETOFINESHIFT), mobj->sloperoll)
return_angle += FixedMul(FINECOSINE((camang) >> ANGLETOFINESHIFT), mobj->sloperoll)
+ FixedMul(FINESINE((camang) >> ANGLETOFINESHIFT), mobj->slopepitch);
}
@@ -6259,8 +6239,8 @@ void P_MobjThinker(mobj_t *mobj)
P_RemoveMobj(mobj);
return;
}
if (mobj->state == &states[S_SHADOW] && cv_sloperoll.value == 2)
if (cv_sloperoll.value == 2 && mobj->state == &states[S_SHADOW])
{
mobj->slopepitch = mobj->target->slopepitch;
mobj->sloperoll = mobj->target->sloperoll;
@@ -6282,6 +6262,7 @@ void P_MobjThinker(mobj_t *mobj)
P_RemoveMobj(mobj);
return;
}
P_RollPitchMobj(mobj);
break;
case MT_SMOLDERING:
@@ -6912,7 +6893,7 @@ void P_MobjThinker(mobj_t *mobj)
// separate thinker
if (mobj->flags & MF_PUSHABLE || (mobj->info->flags & MF_PUSHABLE && mobj->fuse))
{
if (P_MobjWasRemoved(mobj))
if (!mobj)
return;
P_MobjCheckWater(mobj);
@@ -9430,11 +9411,11 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
mobj->destscale = mapobjectscale;
mobj->scalespeed = mapobjectscale/12;
}
// Sprite rendering
mobj->realxscale = mobj->realyscale = mobj->scale;
mobj->realxscale = mobj->realyscale = mobj->scale;
mobj->spritexscale = mobj->realxscale;
mobj->spriteyscale = mobj->realyscale;
mobj->spriteyscale = mobj->realyscale;
mobj->spritexoffset = mobj->spriteyoffset = 0;
// Funni slam sound when landing
@@ -9888,11 +9869,11 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster)
mobj->destscale = mapobjectscale;
mobj->scalespeed = mapobjectscale/12;
}
// Sprite rendering
mobj->spritexscale = mobj->spriteyscale = mobj->scale;
mobj->spritexscale = mobj->spriteyscale = mobj->scale;
mobj->spritexoffset = mobj->spriteyoffset = 0;
// set subsector and/or block links
P_SetThingPosition(mobj);
I_Assert(mobj->subsector != NULL);
@@ -9990,10 +9971,13 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
if (mobj->floorz != starting_floorz)
mobj->precipflags |= PCF_FOF;
else if (GETSECSPECIAL(mobj->subsector->sector->special, 1) == 7
|| GETSECSPECIAL(mobj->subsector->sector->special, 1) == 6
|| mobj->subsector->sector->floorpic == skyflatnum)
mobj->precipflags |= PCF_PIT;
else
{
INT32 special = GETSECSPECIAL(mobj->subsector->sector->special, 1);
if (special == 7 || special == 6 || mobj->subsector->sector->floorpic == skyflatnum)
mobj->precipflags |= PCF_PIT;
}
R_ResetPrecipitationMobjInterpolationState(mobj);
@@ -10096,7 +10080,7 @@ void P_RemoveMobj(mobj_t *mobj)
P_SetTarget(&mobj->hprev->hnext, cachenext);
P_SetTarget(&mobj->hprev, NULL);
}
// clear the reference from the mapthing
if (mobj->spawnpoint)
mobj->spawnpoint->mobj = NULL;
@@ -10136,13 +10120,6 @@ void P_RemoveMobj(mobj_t *mobj)
}
}
// This does not need to be added to Lua.
// To test it in Lua, check mobj.valid
FUNCINLINE ATTRINLINE boolean P_MobjWasRemoved(const mobj_t *mobj)
{
return !(mobj && mobj->thinker.function.acp1 == (actionf_p1)P_MobjThinker);
}
void P_FreePrecipMobj(precipmobj_t *mobj)
{
// unlink from sector and block lists
@@ -10205,9 +10182,8 @@ consvar_t cv_suddendeath = {"suddendeath", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHE
void P_SpawnPrecipitation(void)
{
INT32 i, j, k, mrand;
fixed_t basex, basey, x, y, z, height;
fixed_t precipscale = cv_mobjscaleprecip.value ? mapobjectscale : FRACUNIT;
INT32 i, mrand;
fixed_t basex, basey, j, x, y, z;
subsector_t *precipsector = NULL;
precipmobj_t *rainmo = NULL;
@@ -10220,9 +10196,10 @@ void P_SpawnPrecipitation(void)
basex = bmaporgx + (i % bmapwidth) * MAPBLOCKSIZE;
basey = bmaporgy + (i / bmapwidth) * MAPBLOCKSIZE;
for (j = 0; j < FRACUNIT; j += precipscale)
for (j = 0; j < FRACUNIT; j += cv_mobjscaleprecip.value ? mapobjectscale : FRACUNIT)
{
UINT16 numparticles = 0;
INT32 floorz;
INT32 ceilingz;
x = ((cv_lessprecip.value ? basex*1.5 : basex) + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3));
y = ((cv_lessprecip.value ? basey*1.5 : basey) + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3));
@@ -10238,49 +10215,37 @@ void P_SpawnPrecipitation(void)
if (precipsector->sector->ceilingpic != skyflatnum)
continue;
height = precipsector->sector->ceilingheight - precipsector->sector->floorheight;
height = FixedDiv(height, precipscale);
// Exists, but is too small for reasonable precipitation.
if (height < 64<<FRACBITS)
if (!(precipsector->sector->floorheight <= precipsector->sector->ceilingheight - (32<<FRACBITS)))
continue;
// Hack around a quirk of this entire system, where taller sectors look like they get less precipitation.
numparticles = 1 + (height / (MAPBLOCKUNITS<<4<<FRACBITS));
// Don't set z properly yet...
z = precipsector->sector->ceilingheight;
for (k = 0; k < numparticles; k++)
if (curWeather == PRECIP_SNOW)
{
INT32 floorz;
INT32 ceilingz;
rainmo = P_SpawnPrecipMobj(x, y, z, MT_SNOWFLAKE);
mrand = M_RandomByte();
if (mrand < 64)
P_SetPrecipMobjState(rainmo, S_SNOW3);
else if (mrand < 144)
P_SetPrecipMobjState(rainmo, S_SNOW2);
}
else // everything else.
rainmo = P_SpawnPrecipMobj(x, y, z, MT_RAIN);
if (curWeather == PRECIP_SNOW)
{
rainmo = P_SpawnPrecipMobj(x, y, z, MT_SNOWFLAKE);
mrand = M_RandomByte();
if (mrand < 64)
P_SetPrecipMobjState(rainmo, S_SNOW3);
else if (mrand < 144)
P_SetPrecipMobjState(rainmo, S_SNOW2);
}
else // everything else.
rainmo = P_SpawnPrecipMobj(x, y, z, MT_RAIN);
floorz = rainmo->floorz >> FRACBITS;
ceilingz = rainmo->ceilingz >> FRACBITS;
floorz = rainmo->floorz >> FRACBITS;
ceilingz = rainmo->ceilingz >> FRACBITS;
if (floorz < ceilingz)
{
// Randomly assign a height, now that floorz is set.
rainmo->z = M_RandomRange(floorz, ceilingz) << FRACBITS;
}
else
{
// ...except if the floor is above the ceiling.
rainmo->z = ceilingz << FRACBITS;
}
if (floorz < ceilingz)
{
// Randomly assign a height, now that floorz is set.
rainmo->z = M_RandomRange(floorz, ceilingz) << FRACBITS;
}
else
{
// ...except if the floor is above the ceiling.
rainmo->z = ceilingz << FRACBITS;
}
}
}
@@ -10306,7 +10271,7 @@ void P_PrecipitationEffects(void)
INT32 volume;
size_t i;
boolean sounds_rain = true;
boolean rainsfx = true;
boolean sounds_thunder = true;
boolean effects_lightning = true;
boolean lightningStrike = false;
@@ -10339,7 +10304,7 @@ void P_PrecipitationEffects(void)
effects_lightning = false;
break;
case PRECIP_STORM_NORAIN: // no rain, lightning and thunder allowed
sounds_rain = false;
rainsfx = false;
case PRECIP_STORM: // everything.
break;
default:
@@ -10347,6 +10312,8 @@ void P_PrecipitationEffects(void)
return;
}
boolean sounds_rain = ((cv_drawdist_precip.value != 0) && rainsfx && (!leveltime || leveltime % 80 == 1));
// Currently thunderstorming with lightning, and we're sounding the thunder...
// and where there's thunder, there's gotta be lightning!
if (effects_lightning && lightningStrike)
@@ -10366,41 +10333,57 @@ void P_PrecipitationEffects(void)
if (sound_disabled)
return; // Sound off? D'aw, no fun.
if (!sounds_rain && !sounds_thunder)
return; // no need to calculate volume at ALL
if (players[displayplayers[0]].mo->subsector->sector->ceilingpic == skyflatnum)
volume = 255; // Sky above? We get it full blast.
else
{
/* GCC is optimizing away y >= yl, FUCK YOU */
volatile fixed_t x, y, yl, yh, xl, xh;
INT64 x, y, yl, yh, xl, xh;
fixed_t closedist, newdist;
// Essentially check in a 1024 unit radius of the player for an outdoor area.
yl = players[displayplayers[0]].mo->y - 1024*FRACUNIT;
yh = players[displayplayers[0]].mo->y + 1024*FRACUNIT;
xl = players[displayplayers[0]].mo->x - 1024*FRACUNIT;
xh = players[displayplayers[0]].mo->x + 1024*FRACUNIT;
closedist = 2048*FRACUNIT;
#define RADIUSSTEP (64*FRACUNIT)
#define SEARCHRADIUS (16*RADIUSSTEP)
yl = yh = players[displayplayers[0]].mo->y;
yl -= SEARCHRADIUS;
while (yl < INT32_MIN)
yl += RADIUSSTEP;
yh += SEARCHRADIUS;
while (yh > INT32_MAX)
yh -= RADIUSSTEP;
for (y = yl; y >= yl && y <= yh; y += FRACUNIT*64)
for (x = xl; x >= xl && x <= xh; x += FRACUNIT*64)
xl = xh = players[displayplayers[0]].mo->x;
xl -= SEARCHRADIUS;
while (xl < INT32_MIN)
xl += RADIUSSTEP;
xh += SEARCHRADIUS;
while (xh > INT32_MAX)
xh -= RADIUSSTEP;
closedist = SEARCHRADIUS*2;
#undef SEARCHRADIUS
for (y = yl; y <= yh; y += RADIUSSTEP)
for (x = xl; x <= xh; x += RADIUSSTEP)
{
if (R_PointInSubsector(x, y)->sector->ceilingpic != skyflatnum) // Found the outdoors!
if (R_PointInSubsector((fixed_t)x, (fixed_t)y)->sector->ceilingpic != skyflatnum) // Found the outdoors!
continue;
newdist = S_CalculateSoundDistance(players[displayplayers[0]].mo->x, players[displayplayers[0]].mo->y, 0, x, y, 0);
newdist = S_CalculateSoundDistance(players[displayplayers[0]].mo->x, players[displayplayers[0]].mo->y, 0, (fixed_t)x, (fixed_t)y, 0);
if (newdist < closedist)
closedist = newdist;
}
volume = 255 - (closedist>>(FRACBITS+2));
}
#undef RADIUSSTEP
if (volume < 0)
volume = 0;
else if (volume > 255)
volume = 255;
volume = CLAMP(volume, 0, 255);
if (sounds_rain && (!leveltime || leveltime % 80 == 1))
if (sounds_rain)
S_StartSoundAtVolume(players[displayplayers[0]].mo, sfx_rainin, volume);
if (!sounds_thunder)
@@ -11268,7 +11251,8 @@ void P_SpawnMapThing(mapthing_t *mthing)
mobj = P_SpawnMobj(x, y, z, i);
if (!mobj || P_MobjWasRemoved(mobj)) {
if (!mobj || P_MobjWasRemoved(mobj))
{
CONS_Alert(CONS_ERROR, "Failed to spawn map thing #%d at %d, %d. This will crash vanilla clients!\n", mthing->type, x>>FRACBITS, y>>FRACBITS);
return;
}
+10 -11
View File
@@ -261,20 +261,21 @@ typedef enum {
PCF_SPLASH = 1<<4, // Splashed on the ground, return to the ceiling after the animation's over
PCF_THUNK = 1<<5, // Ran the thinker this tic.
} precipflag_t;
// Map Object definition.
typedef struct mobj_s
{
// List: thinker links.
thinker_t thinker;
mobjtype_t type;
const mobjinfo_t *info; // &mobjinfo[mobj->type]
// Info for drawing: position.
fixed_t x, y, z;
fixed_t old_x, old_y, old_z; // position interpolation
fixed_t old_x2, old_y2, old_z2;
mobjtype_t type;
const mobjinfo_t *info; // &mobjinfo[mobj->type]
// More list: links in sector (if needed)
struct mobj_s *bnext;
struct mobj_s **bprev; // killough 8/11/98: change to ptr-to-ptr
@@ -287,8 +288,7 @@ typedef struct mobj_s
spritenum_t sprite; // used to find patch_t and flip value
UINT32 frame; // frame number, plus bits see p_pspr.h
UINT16 anim_duration; // for FF_ANIMATE states
UINT32 renderflags; // render flags
fixed_t spritexscale, spriteyscale;
fixed_t spritexoffset, spriteyoffset;
fixed_t old_spritexscale, old_spriteyscale;
@@ -420,14 +420,14 @@ typedef struct precipmobj_s
// List: thinker links.
thinker_t thinker;
mobjtype_t type;
const mobjinfo_t *info; // &mobjinfo[mobj->type]
// Info for drawing: position.
fixed_t x, y, z;
fixed_t old_x, old_y, old_z; // position interpolation
fixed_t old_x2, old_y2, old_z2;
mobjtype_t type;
const mobjinfo_t *info; // &mobjinfo[mobj->type]
// More list: links in sector (if needed)
struct precipmobj_s *bnext;
struct precipmobj_s **bprev; // killough 8/11/98: change to ptr-to-ptr
@@ -440,8 +440,7 @@ typedef struct precipmobj_s
spritenum_t sprite; // used to find patch_t and flip value
UINT32 frame; // frame number, plus bits see p_pspr.h
UINT16 anim_duration; // for FF_ANIMATE states
UINT32 renderflags; // render flags
fixed_t spritexscale, spriteyscale;
fixed_t spritexoffset, spriteyoffset;
fixed_t old_spritexscale, old_spriteyscale;
@@ -450,7 +449,7 @@ typedef struct precipmobj_s
fixed_t realxscale, realyscale; // funn-E streeetch
fixed_t stretchslam; // "squish" effect when you land
//sloperollangle
angle_t sloperoll, slopepitch;
angle_t old_sloperoll, old_slopepitch;
+2 -1
View File
@@ -28,6 +28,7 @@
#include "r_main.h"
#include "r_state.h"
#include "r_defs.h"
#include "qs22j.h"
/*
@@ -580,7 +581,7 @@ static void Polyobj_findExplicit(polyobj_t *po)
// sort the array if necessary
if (numSegItems >= 2)
qsort(segitems, numSegItems, sizeof(segitem_t), Polyobj_segCompare);
qs22j(segitems, numSegItems, sizeof(segitem_t), Polyobj_segCompare);
// second loop: put the sorted segs into the polyobject
for (i = 0; i < numSegItems; ++i)
+15 -25
View File
@@ -3031,11 +3031,17 @@ static inline void P_FinishMobjs(void)
}
}
static inline mobj_t *RelinkMobj(mobj_t **ptr)
{
UINT32 temp = (UINT32)(size_t)*ptr;
*ptr = NULL;
return P_SetTarget(ptr, P_FindNewPosition(temp));
}
static void P_RelinkPointers(void)
{
thinker_t *currentthinker;
mobj_t *mobj;
UINT32 temp;
// use info field (value = oldposition) to relink mobjs
for (currentthinker = thinkercap.next; currentthinker != &thinkercap;
@@ -3051,58 +3057,42 @@ static void P_RelinkPointers(void)
if (mobj->tracer)
{
temp = (UINT32)(size_t)mobj->tracer;
mobj->tracer = NULL;
if (!P_SetTarget(&mobj->tracer, P_FindNewPosition(temp)))
if (!RelinkMobj(&mobj->tracer))
CONS_Debug(DBG_GAMELOGIC, "tracer not found on %d\n", mobj->type);
}
if (mobj->target)
{
temp = (UINT32)(size_t)mobj->target;
mobj->target = NULL;
if (!P_SetTarget(&mobj->target, P_FindNewPosition(temp)))
if (!RelinkMobj(&mobj->target))
CONS_Debug(DBG_GAMELOGIC, "target not found on %d\n", mobj->type);
}
if (mobj->hnext)
{
temp = (UINT32)(size_t)mobj->hnext;
mobj->hnext = NULL;
if (!P_SetTarget(&mobj->hnext, P_FindNewPosition(temp)))
if (!RelinkMobj(&mobj->hnext))
CONS_Debug(DBG_GAMELOGIC, "hnext not found on %d\n", mobj->type);
}
if (mobj->hprev)
{
temp = (UINT32)(size_t)mobj->hprev;
mobj->hprev = NULL;
if (!P_SetTarget(&mobj->hprev, P_FindNewPosition(temp)))
if (!RelinkMobj(&mobj->hprev))
CONS_Debug(DBG_GAMELOGIC, "hprev not found on %d\n", mobj->type);
}
if (mobj->player && mobj->player->capsule)
{
temp = (UINT32)(size_t)mobj->player->capsule;
mobj->player->capsule = NULL;
if (!P_SetTarget(&mobj->player->capsule, P_FindNewPosition(temp)))
if (!RelinkMobj(&mobj->player->capsule))
CONS_Debug(DBG_GAMELOGIC, "capsule not found on %d\n", mobj->type);
}
if (mobj->player && mobj->player->axis1)
{
temp = (UINT32)(size_t)mobj->player->axis1;
mobj->player->axis1 = NULL;
if (!P_SetTarget(&mobj->player->axis1, P_FindNewPosition(temp)))
if (!RelinkMobj(&mobj->player->axis1))
CONS_Debug(DBG_GAMELOGIC, "axis1 not found on %d\n", mobj->type);
}
if (mobj->player && mobj->player->axis2)
{
temp = (UINT32)(size_t)mobj->player->axis2;
mobj->player->axis2 = NULL;
if (!P_SetTarget(&mobj->player->axis2, P_FindNewPosition(temp)))
if (!RelinkMobj(&mobj->player->axis2))
CONS_Debug(DBG_GAMELOGIC, "axis2 not found on %d\n", mobj->type);
}
if (mobj->player && mobj->player->awayviewmobj)
{
temp = (UINT32)(size_t)mobj->player->awayviewmobj;
mobj->player->awayviewmobj = NULL;
if (!P_SetTarget(&mobj->player->awayviewmobj, P_FindNewPosition(temp)))
if (!RelinkMobj(&mobj->player->awayviewmobj))
CONS_Debug(DBG_GAMELOGIC, "awayviewmobj not found on %d\n", mobj->type);
}
}
+77 -12
View File
@@ -510,7 +510,7 @@ void P_UpdateSegLightOffset(seg_t *li)
// Loads the SEGS resource from a level.
static void P_LoadRawSegs(UINT8 *data)
{
INT32 linedef, side;
INT32 rawlinedef, rawside;
mapseg_t *ml = (mapseg_t*)data;
seg_t *li = segs;
line_t *ldef;
@@ -530,14 +530,14 @@ static void P_LoadRawSegs(UINT8 *data)
li->angle = (SHORT(ml->angle))<<FRACBITS;
li->offset = (SHORT(ml->offset))<<FRACBITS;
linedef = SHORT(ml->linedef);
ldef = &lines[linedef];
rawlinedef = SHORT(ml->linedef);
ldef = &lines[rawlinedef];
li->linedef = ldef;
li->side = side = SHORT(ml->side);
li->sidedef = &sides[ldef->sidenum[side]];
li->frontsector = sides[ldef->sidenum[side]].sector;
li->side = rawside = SHORT(ml->side);
li->sidedef = &sides[ldef->sidenum[rawside]];
li->frontsector = sides[ldef->sidenum[rawside]].sector;
if (ldef->flags & ML_TWOSIDED)
li->backsector = sides[ldef->sidenum[side^1]].sector;
li->backsector = sides[ldef->sidenum[rawside^1]].sector;
else
li->backsector = 0;
@@ -2487,6 +2487,71 @@ static boolean P_CanSave(void)
return false; // SRB2Kart: no SP, no saving.
}
struct minimapinfo minimapinfo;
static void P_InitMinimapInfo(void)
{
INT32 lumpnum;
fixed_t a;
fixed_t b;
node_t *bsp = &nodes[numnodes-1];
minimapinfo.minimap_pic = NULL;
lumpnum = W_CheckNumForName(va("%sR", G_BuildMapName(gamemap)));
if (lumpnum != -1)
minimapinfo.minimap_pic = W_CachePatchName(va("%sR", G_BuildMapName(gamemap)), PU_HUDGFX);
minimapinfo.mapthingcount = 0;
// TODO iterate over mapthings to look for possible user-defined bounds
minimapinfo.min_x = bsp->bbox[0][BOXLEFT];
minimapinfo.max_x = bsp->bbox[0][BOXRIGHT];
minimapinfo.min_y = bsp->bbox[0][BOXBOTTOM];
minimapinfo.max_y = bsp->bbox[0][BOXTOP];
if (bsp->bbox[1][BOXLEFT] < minimapinfo.min_x)
minimapinfo.min_x = bsp->bbox[1][BOXLEFT];
if (bsp->bbox[1][BOXRIGHT] > minimapinfo.max_x)
minimapinfo.max_x = bsp->bbox[1][BOXRIGHT];
if (bsp->bbox[1][BOXBOTTOM] < minimapinfo.min_y)
minimapinfo.min_y = bsp->bbox[1][BOXBOTTOM];
if (bsp->bbox[1][BOXTOP] > minimapinfo.max_y)
minimapinfo.max_y = bsp->bbox[1][BOXTOP];
// You might be wondering why these are being bitshift here
// it's because mapwidth and height would otherwise overflow for maps larger than half the size possible...
// map boundaries and sizes will ALWAYS be whole numbers thankfully
// later calculations take into consideration that these are actually not in terms of FRACUNIT though
minimapinfo.map_w = (minimapinfo.max_x >>= FRACBITS) - (minimapinfo.min_x >>= FRACBITS);
minimapinfo.map_h = (minimapinfo.max_y >>= FRACBITS) - (minimapinfo.min_y >>= FRACBITS);
minimapinfo.minimap_w = minimapinfo.minimap_h = 100;
a = FixedDiv(minimapinfo.minimap_w<<FRACBITS, minimapinfo.map_w<<4);
b = FixedDiv(minimapinfo.minimap_h<<FRACBITS, minimapinfo.map_h<<4);
if (a < b)
{
minimapinfo.minimap_h = FixedMul(a, minimapinfo.map_h)>>(FRACBITS-4);
minimapinfo.zoom = a;
}
else
{
if (a != b)
{
minimapinfo.minimap_w = FixedMul(b, minimapinfo.map_w)>>(FRACBITS-4);
}
minimapinfo.zoom = b;
}
minimapinfo.zoom >>= (FRACBITS-4);
minimapinfo.zoom -= (minimapinfo.zoom/20);
// These should always be small enough to be bitshift back right now
minimapinfo.offs_x = FixedMul((minimapinfo.min_x + minimapinfo.map_w/2) << FRACBITS, minimapinfo.zoom);
minimapinfo.offs_y = FixedMul((minimapinfo.min_y + minimapinfo.map_h/2) << FRACBITS, minimapinfo.zoom);
}
/** Loads a level from a lump or external wad.
*
* \param skipprecip If true, don't spawn precipitation.
@@ -2532,9 +2597,6 @@ boolean P_SetupLevel(boolean skipprecip, boolean reloadinggamestate)
P_LevelInitStuff(reloadinggamestate);
for (i = 0; i <= splitscreen; i++)
postimgtype[i] = postimg_none;
if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0'
&& atoi(mapheaderinfo[gamemap-1]->forcecharacter) != 255)
P_ForceCharacter(mapheaderinfo[gamemap-1]->forcecharacter);
@@ -2628,7 +2690,7 @@ boolean P_SetupLevel(boolean skipprecip, boolean reloadinggamestate)
// As oddly named as this is, this handles music only.
// We should be fine starting it here.
if (!reloadinggamestate)
S_Start();
S_InitMapMusic();
levelfadecol = (encoremode && !ranspecialwipe ? 122 : 120);
@@ -2738,6 +2800,8 @@ boolean P_SetupLevel(boolean skipprecip, boolean reloadinggamestate)
P_SpawnSecretItems(loademblems);
P_InitMinimapInfo();
for (numcoopstarts = 0; numcoopstarts < MAXPLAYERS; numcoopstarts++)
if (!playerstarts[numcoopstarts])
break;
@@ -2948,7 +3012,8 @@ boolean P_SetupLevel(boolean skipprecip, boolean reloadinggamestate)
G_CopyTiccmd(&players[i].cmd, &netcmds[buf][i], 1);
}
P_PreTicker(2);
LUAh_MapLoad();
if (!reloadinggamestate)
LUAh_MapLoad();
}
if (rendermode != render_none && !reloadinggamestate)
+60 -13
View File
@@ -99,6 +99,8 @@ typedef struct
thinker_t **thinkers;
} thinkerlist_t;
//static boolean fromlapexec = false;
static void P_SearchForDisableLinedefs(void);
static void P_SpawnScrollers(void);
static void P_SpawnFriction(void);
@@ -1340,6 +1342,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
fixed_t dist = P_AproxDistance(triggerline->dx, triggerline->dy)>>FRACBITS;
size_t i, linecnt, sectori;
INT16 specialtype = triggerline->special;
//fromlapexec = false;
/////////////////////////////////////////////////
// Distance-checking/sector trigger conditions //
@@ -1461,6 +1464,8 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
if (lap != (sides[triggerline->sidenum[0]].textureoffset >> FRACBITS))
return false;
}
//fromlapexec = true;
}
// If we were not triggered by a sector type especially for the purpose,
// a Linedef Executor linedef trigger is not handling sector triggers properly, return.
@@ -2113,12 +2118,12 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
return;
if (bot)
P_Teleport(bot, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, (line->flags & ML_BLOCKMONSTERS) == 0, (line->flags & ML_EFFECT4) == ML_EFFECT4);
P_Teleport(bot, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, (line->flags & ML_BLOCKMONSTERS) == 0, (line->flags & ML_EFFECT4) == ML_EFFECT4);
if (line->flags & ML_BLOCKMONSTERS)
P_Teleport(mo, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, false, (line->flags & ML_EFFECT4) == ML_EFFECT4);
P_Teleport(mo, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, false, (line->flags & ML_EFFECT4) == ML_EFFECT4);
else
{
P_Teleport(mo, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, true, (line->flags & ML_EFFECT4) == ML_EFFECT4);
P_Teleport(mo, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, true, (line->flags & ML_EFFECT4) == ML_EFFECT4);
// Play the 'bowrwoosh!' sound
S_StartSound(dest, sfx_mixup);
}
@@ -2127,6 +2132,12 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
break;
case 413: // Change music
if (keepmusic && (leveltime <= MUSICSTARTTIME)) //why check for starttime? cause encore music Zzz...
return;
//if (cv_ignoremusicchanges.value && (leveltime >= MUSICSTARTTIME) && !fromlapexec) // keep lap music intanct tho
//return;
// console player only unless NOCLIMB is set
if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player)))
{
@@ -2179,9 +2190,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
mapmusflags |= MUSIC_FORCERESET;
mapmusposition = position;
if (cv_birdmusic.value)
mapmusresume = 0;
mapmusresume = 0;
S_ChangeMusicEx(mapmusname, mapmusflags, !(line->flags & ML_EFFECT4), position,
!(line->flags & ML_EFFECT2) ? prefadems : 0,
@@ -2209,6 +2218,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
{
INT32 sfxnum;
//dont play any funky sound intros that may interfere with the music
if (skipintromus && (leveltime < MUSICSTARTTIME))
return;
sfxnum = sides[line->sidenum[0]].toptexture; //P_AproxDistance(line->dx, line->dy)>>FRACBITS;
if (sfxnum == sfx_None)
@@ -2485,6 +2498,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
case 422: // Cut away to another view
{
mobj_t *altview;
INT32 i;
if (!mo || !mo->player) // only players have views
return;
@@ -2499,6 +2513,18 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
P_SetTarget(&mo->player->awayviewmobj, altview);
mo->player->awayviewtics = P_AproxDistance(line->dx, line->dy)>>FRACBITS;
if (gamestate == GS_LEVEL)
{
for (i = 0; i <= splitscreen; i++)
{
if (displayplayers[i] == (mo->player - players))
{
R_ResetViewInterpolation(i + 1);
R_ResetViewInterpolation(i + 1);
}
}
}
if (line->flags & ML_NOCLIMB) // lets you specify a vertical angle
{
INT32 aim;
@@ -2836,17 +2862,19 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
case 444: // Earthquake camera
{
quake.intensity = sides[line->sidenum[0]].textureoffset;
quake.radius = sides[line->sidenum[0]].rowoffset;
quake.time = P_AproxDistance(line->dx, line->dy)>>FRACBITS;
fixed_t intensity = sides[line->sidenum[0]].textureoffset;
fixed_t radius = sides[line->sidenum[0]].rowoffset;
tic_t time = P_AproxDistance(line->dx, line->dy)>>FRACBITS;
quake.epicenter = NULL; /// \todo
// reasonable defaults.
if (!quake.intensity)
quake.intensity = 8<<FRACBITS;
if (!quake.radius)
quake.radius = 512<<FRACBITS;
if (intensity <= 0)
intensity = 8<<FRACBITS;
if (radius <= 0)
radius = 512<<FRACBITS;
P_StartQuake(time, intensity, radius);
break;
}
@@ -5308,6 +5336,8 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
curWeather = PRECIP_STORM_NORAIN;
else if (mapheaderinfo[gamemap-1]->weather == 6) // storm w/o lightning
curWeather = PRECIP_STORM_NOSTRIKES;
else if (mapheaderinfo[gamemap-1]->weather == 4) // blank
curWeather = PRECIP_BLANK;
else
curWeather = PRECIP_NONE;
@@ -7544,6 +7574,23 @@ static void P_SpawnPushers(void)
}
}
void P_StartQuake(tic_t time, fixed_t intensity, fixed_t radius)
{
if (time <= 0 || intensity <= 0)
{
// Invalid parameters
return;
}
quake.time = time;
quake.intensity = FixedMul(intensity, mapobjectscale);
if (radius > 0)
{
quake.radius = FixedMul(radius, mapobjectscale);
}
}
static void P_SearchForDisableLinedefs(void)
{
size_t i;
+2
View File
@@ -454,4 +454,6 @@ void P_CalcHeight(player_t *player);
sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo);
void P_StartQuake(tic_t time, fixed_t intensity, fixed_t radius);
#endif
+1
View File
@@ -166,6 +166,7 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle
P_ResetCamera(thing->player, &camera[i]);
R_ResetViewInterpolation(i + 1);
break;
}
// don't run in place after a teleport
+42 -29
View File
@@ -287,7 +287,7 @@ mobj_t *P_SetTarget(mobj_t **mop, mobj_t *targ)
{
if (*mop) // If there was a target already, decrease its refcount
(*mop)->thinker.references--;
if ((*mop = targ) != NULL) // Set new target and if non-NULL, increase its counter
if ((*mop = targ) != NULL) // Set new target and if non-NULL, increase its counter
targ->thinker.references++;
return targ;
}
@@ -318,8 +318,12 @@ static inline void P_RunThinkers(void)
{
for (currentthinker = thinkercap.next; currentthinker != &thinkercap; currentthinker = currentthinker->next)
{
if (currentthinker->function.acp1)
currentthinker->function.acp1(currentthinker);
if (currentthinker->function.acp1 == (actionf_p1)P_NullPrecipThinker)
continue;
#ifdef PARANOIA
I_Assert(currentthinker->function.acp1 != NULL)
#endif
currentthinker->function.acp1(currentthinker);
}
}
@@ -393,6 +397,36 @@ void P_RunChaseCameras(void)
}
}
static inline void P_RunQuakes(void)
{
fixed_t ir;
if (quake.time <= 0)
{
quake.x = quake.y = quake.z = quake.roll = 0;
return;
}
ir = quake.intensity>>1;
/// \todo Calculate distance from epicenter if set and modulate the intensity accordingly based on radius.
quake.x = M_RandomRange(-ir,ir);
quake.y = M_RandomRange(-ir,ir);
quake.z = M_RandomRange(-ir,ir);
ir >>= 2;
ir = M_RandomRange(-ir,ir);
if (ir < 0)
ir = ANGLE_MAX - FixedAngle(-ir);
else
ir = FixedAngle(ir);
quake.roll = ir;
--quake.time;
}
//
// P_Ticker
//
@@ -425,6 +459,8 @@ void P_Ticker(boolean run)
if (demo.rewinding && leveltime > 0)
{
leveltime = (leveltime-1) & ~3;
if (timeinmap > 0)
timeinmap = (timeinmap-1) & ~3;
G_PreviewRewind(leveltime);
}
else if (demo.freecam && democam.cam) // special case: allow freecam to MOVE during pause!
@@ -433,9 +469,6 @@ void P_Ticker(boolean run)
return;
}
for (i = 0; i <= splitscreen; i++)
postimgtype[i] = postimg_none;
P_MapStart();
if (run)
@@ -583,24 +616,7 @@ void P_Ticker(boolean run)
K_CalculateBattleWanted();
}
if (quake.time)
{
fixed_t ir = quake.intensity>>1;
/// \todo Calculate distance from epicenter if set and modulate the intensity accordingly based on radius.
quake.x = M_RandomRange(-ir,ir);
quake.y = M_RandomRange(-ir,ir);
quake.z = M_RandomRange(-ir,ir);
ir >>= 2;
ir = M_RandomRange(-ir,ir);
if (ir < 0)
ir = ANGLE_MAX - FixedAngle(-ir);
else
ir = FixedAngle(ir);
quake.roll = ir;
--quake.time;
}
else
quake.x = quake.y = quake.z = quake.roll = 0;
P_RunQuakes();
if (metalplayback)
G_ReadMetalTic(metalplayback);
@@ -664,8 +680,10 @@ void P_Ticker(boolean run)
{
player_t *player = &players[displayplayers[i]];
boolean isSkyVisibleForPlayer = skyVisiblePerPlayer[i];
if (!player->mo)
continue;
if (isSkyVisibleForPlayer && skyboxmo[0] && cv_skybox.value)
{
R_SkyboxFrame(player);
@@ -679,8 +697,6 @@ void P_Ticker(boolean run)
if (demo.playback)
G_StoreRewindInfo();
// Z_CheckMemCleanup();
}
// Abbreviated ticker for pre-loading, calls thinkers and assorted things
@@ -689,9 +705,6 @@ void P_PreTicker(INT32 frames)
INT32 i;
ticcmd_t temptic;
for (i = 0; i <= splitscreen; i++)
postimgtype[i] = postimg_none;
hook_defrosting = frames;
while (hook_defrosting)
+38 -44
View File
@@ -742,9 +742,8 @@ void P_RestoreMusic(player_t *player)
if (P_EndingMusic(player))
return;
// Event - Level Start
if (leveltime < (starttime + (TICRATE/2)))
S_ChangeMusicInternal((encoremode ? "estart" : "kstart"), false); //S_StopMusic();
if (leveltime < MUSICSTARTTIME)
S_StartMapMusic(true);
else // see also where time overs are handled - search for "lives = 2" in this file
{
INT32 wantedmus = 0; // 0 is level music, 1 is invincibility, 2 is grow
@@ -800,19 +799,13 @@ void P_RestoreMusic(player_t *player)
if (G_RaceGametype() && player->laps >= (UINT8)(cv_numlaps.value - 1))
S_SpeedMusic(1.2f);
#endif
if (cv_birdmusic.value)
{
if (mapmusresume && cv_resume.value)
position = mapmusresume;
else
position = mapmusposition;
S_ChangeMusicEx(mapmusname, mapmusflags, true, position, 0, S_GetRestoreMusicFadeIn());
S_ClearRestoreMusicFadeInCvar();
}
if (mapmusresume && cv_resume.value) // mapmusresume will be 0 anyways when birdmusic stuff is disabled
position = mapmusresume;
else
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
position = mapmusposition;
S_ChangeMusicEx(mapmusname, mapmusflags, true, position, 0, S_GetRestoreMusicFadeIn());
S_ClearRestoreMusicFadeInCvar();
mapmusresume = 0;
}
}
@@ -1041,7 +1034,7 @@ fixed_t P_GetPlayerSpinHeight(player_t *player)
// Returns true if player is
// on the local machine.
//
boolean P_IsLocalPlayer(player_t *player)
boolean P_IsLocalPlayer(const player_t *player)
{
UINT8 i;
@@ -1065,7 +1058,7 @@ boolean P_IsLocalPlayer(player_t *player)
// Returns true if player is
// currently being watched.
//
boolean P_IsDisplayPlayer(player_t *player)
boolean P_IsDisplayPlayer(const player_t *player)
{
UINT8 i;
@@ -1179,6 +1172,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
ghost = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_GHOST);
P_SetScale(ghost, mobj->scale);
ghost->scalespeed = mobj->scalespeed;
ghost->destscale = mobj->scale;
if (mobj->eflags & MFE_VERTICALFLIP)
@@ -1230,6 +1224,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
ghost->old_roll = mobj->old_roll2;
ghost->old_sloperoll = mobj->old_sloperoll2;
ghost->old_slopepitch = mobj->old_slopepitch2;
ghost->old_scale = mobj->old_scale2;
return ghost;
}
@@ -1254,7 +1249,7 @@ void P_DoPlayerExit(player_t *player)
player->exiting = raceexittime+2;
K_KartUpdatePosition(player);
if (cv_kartvoices.value)
if (!P_MobjWasRemoved(player->mo) && cv_kartvoices.value)
{
if (P_IsLocalPlayer(player))
{
@@ -2503,7 +2498,7 @@ static void P_MovePlayer(player_t *player)
}
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none && cv_grfovchange.value)
if (rendermode == render_opengl && cv_glfovchange.value)
{
fixed_t speed;
const fixed_t runnyspeed = 20*FRACUNIT;
@@ -4108,11 +4103,12 @@ boolean P_SpectatorJoinGame(player_t *player)
return false;
}
// the below is first person only, if you're curious. check out P_CalcChasePostImg in p_mobj.c for chasecam
static void P_CalcPostImg(player_t *player)
{
sector_t *sector = player->mo->subsector->sector;
postimg_t *type = NULL;
INT32 *param;
INT16 typeflag = 0;
//INT32 *param;
fixed_t pviewheight;
UINT8 i;
@@ -4127,20 +4123,19 @@ static void P_CalcPostImg(player_t *player)
pviewheight = player->awayviewmobj->z + 20*FRACUNIT;
}
for (i = 0; i <= splitscreen; i++)
/*for (i = 0; i <= splitscreen; i++)
{
if (player == &players[displayplayers[i]])
{
type = &postimgtype[i];
param = &postimgparam[i];
break;
}
}
}*/
// see if we are in heat (no, not THAT kind of heat...)
if (P_FindSpecialLineFromTag(13, sector->tag, -1) != -1)
*type = postimg_heat;
typeflag |= POSTIMG_HEAT;
else if (sector->ffloors)
{
ffloor_t *rover;
@@ -4159,7 +4154,7 @@ static void P_CalcPostImg(player_t *player)
continue;
if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1)
*type = postimg_heat;
typeflag |= POSTIMG_HEAT;
}
}
@@ -4181,36 +4176,35 @@ static void P_CalcPostImg(player_t *player)
if (pviewheight >= topheight || pviewheight <= bottomheight)
continue;
*type = postimg_water;
typeflag |= POSTIMG_WATER;
}
}
if (!encoremode) // srb2kart
{
if (player->mo->eflags & MFE_VERTICALFLIP)
*type = postimg_flip;
}
else
{
if (player->mo->eflags & MFE_VERTICALFLIP)
*type = postimg_mirrorflip;
else
*type = postimg_mirror;
}
if (encoremode) // srb2kart
typeflag |= POSTIMG_MIRROR;
if (player->mo->eflags & MFE_VERTICALFLIP)
typeflag |= POSTIMG_FLIP;
#if 1
(void)param;
#else
// Motion blur
if (player->speed > (35<<FRACBITS))
// unused
/*if (player->speed > (35<<FRACBITS))
{
*type = postimg_motion;
typeflag |= POSTIMG_MOTION;
*param = (player->speed - 32)/4;
if (*param > 5)
*param = 5;
}*/
for (i = 0; i <= splitscreen; i++)
{
if (player != &players[displayplayers[i]])
continue;
players[displayplayers[i]].postimgflags = typeflag;
break;
}
#endif
}
void P_DoTimeOver(player_t *player)
+138 -138
View File
@@ -18,13 +18,15 @@
#include <stdint.h>
#include "qs22j.h"
#define INSORTTHRESH 5 // if n < this use insertion sort
// MUST be >= 2
#define MIDTHRESH 20 // < this use middle as pivot
#define MEDOF3THRESH 50 // < this use median-of-3 as pivot
// larger subfiles use med-of-3-medians
#define INSORTTHRESH 5 // if n < this use insertion sort
// MUST be >= 2
#define MIDTHRESH 20 // < this use middle as pivot
#define MEDOF3THRESH 50 // < this use median-of-3 as pivot
// larger subfiles use med-of-3-medians
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
typedef int32_t WORD;
typedef int64_t DWORD;
@@ -37,242 +39,240 @@ typedef void *pref_typ;
#define ASWAP(a, b, t) ((void)(t = a, a = b, b = t))
#define SWAP(a, b) if (swap_type) swapf(a, b, size);\
else do {pref_typ t; ASWAP(*(pref_typ*)(a), *(pref_typ*)(b), t);} while (0)
else do {pref_typ t; ASWAP(*(pref_typ*)(a), *(pref_typ*)(b), t);} while (0)
#define COMP(a, b) ((*compar)((void *)(a), (void *)(b)))
#define COMP(a, b) ((*compar)((void *)(a), (void *)(b)))
static inline void swapbytes(void *a0, void *b0, size_t n)
{
char *a = a0, *b = b0, t;
do {ASWAP(*a, *b, t); a++; b++;} while (--n);
char *a = a0, *b = b0, t;
do {ASWAP(*a, *b, t); a++; b++;} while (--n);
}
static inline void swapdword(void *a0, void *b0, size_t n)
{
DWORD *a = a0, *b = b0, t;
ASWAP(*a, *b, t);
(void)n;
(void)n;
DWORD *a = a0, *b = b0, t;
ASWAP(*a, *b, t);
}
static inline void swapdwords(void *a0, void *b0, size_t n)
{
DWORD *a = a0, *b = b0, t;
do {ASWAP(*a, *b, t); a++; b++;} while (n -= sizeof(DWORD));
DWORD *a = a0, *b = b0, t;
do {ASWAP(*a, *b, t); a++; b++;} while (n -= sizeof(DWORD));
}
static inline void swapword(void *a0, void *b0, size_t n)
{
WORD *a = a0, *b = b0, t;
ASWAP(*a, *b, t);
(void)n;
(void)n;
WORD *a = a0, *b = b0, t;
ASWAP(*a, *b, t);
}
static inline void swapwords(void *a0, void *b0, size_t n)
{
WORD *a = a0, *b = b0, t;
do {ASWAP(*a, *b, t); a++; b++;} while (n -= sizeof(WORD));
WORD *a = a0, *b = b0, t;
do {ASWAP(*a, *b, t); a++; b++;} while (n -= sizeof(WORD));
}
typedef void (*swapf_typ)(void *, void *, size_t);
static inline char *med3(char *a, char *b, char *c, int (*compar)(const void *, const void *))
{
return COMP(a, b) < 0 ?
(COMP(b, c) < 0 ? b : COMP(a, c) < 0 ? c : a) :
(COMP(b, c) > 0 ? b : COMP(a, c) > 0 ? c : a);
return COMP(a, b) < 0 ?
(COMP(b, c) < 0 ? b : COMP(a, c) < 0 ? c : a) :
(COMP(b, c) > 0 ? b : COMP(a, c) > 0 ? c : a);
}
void qs22j(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *))
{
char *stack[2*8*sizeof(size_t)], **sp = stack; // stack and stack pointer
char *left = base; // set up char * base pointer
char *limit = left + nmemb * size; // pointer past end of array
char *i, *ii, *j, *jj; // scan pointers
int ki = 0, kj = 0;
int swap_type = 1;
swapf_typ swapf, vecswapf;
char *stack[2*8*sizeof(size_t)], **sp = stack; // stack and stack pointer
char *left = base; // set up char * base pointer
char *limit = left + nmemb * size; // pointer past end of array
char *i, *ii, *j, *jj; // scan pointers
int ki = 0, kj = 0;
int swap_type = 1;
swapf_typ swapf, vecswapf;
vecswapf = swapf = swapbytes;
if ((ptr_to_int(left) | size) % sizeof(WORD))
vecswapf = swapf = swapbytes;
if ((ptr_to_int(left) | size) % sizeof(WORD))
{
; // unaligned or not multple of WORD size; swap bytes
}
; // unaligned or not multple of WORD size; swap bytes
}
else if (size == sizeof(DWORD))
{
swapf = swapdword;
vecswapf = swapdwords;
if (size == sizeof(pref_typ))
swap_type = 0;
}
swapf = swapdword;
vecswapf = swapdwords;
if (size == sizeof(pref_typ))
swap_type = 0;
}
else if (size == sizeof(WORD))
{
swapf = swapword;
vecswapf = swapwords;
if (size == sizeof(pref_typ))
swap_type = 0;
swapf = swapword;
vecswapf = swapwords;
if (size == sizeof(pref_typ))
swap_type = 0;
}
else if ((size % sizeof(DWORD)) == 0)
{
swapf = vecswapf = swapdwords;
}
swapf = vecswapf = swapdwords;
}
else if ((size % sizeof(WORD)) == 0)
{
swapf = vecswapf = swapwords;
}
for (;;)
swapf = vecswapf = swapwords;
}
for (;;)
{
nmemb = (limit - left) / size;
for (i = left + size; i < limit && COMP(i - size, i) <= 0; i += size)
;
nmemb = (limit - left) / size;
for (i = left + size; i < limit && COMP(i - size, i) <= 0; i += size)
;
if (i == limit) // if already in order
goto pop;
if (i == limit) // if already in order
goto pop;
if (nmemb >= INSORTTHRESH) // otherwise use insertion sort
if (nmemb >= INSORTTHRESH) // otherwise use insertion sort
{
char *right = limit - size;
// best so far? fewer compares, a few more swaps
char *p = left + (nmemb / 2) * size;
if (nmemb >= MIDTHRESH)
char *right = limit - size;
// best so far? fewer compares, a few more swaps
char *p = left + (nmemb / 2) * size;
if (nmemb >= MIDTHRESH)
{
char *pleft = left + size;
char *pright = right - size;
char *pleft = left + size;
char *pright = right - size;
if (nmemb >= MEDOF3THRESH)
if (nmemb >= MEDOF3THRESH)
{
size_t k = (nmemb / 8) * size;
pleft = med3(pleft, left + k, left + k * 2, compar);
p = med3(p - k, p, p + k, compar);
pright = med3(right - k * 2, right - k, pright, compar);
}
size_t k = (nmemb / 8) * size;
pleft = med3(pleft, left + k, left + k * 2, compar);
p = med3(p - k, p, p + k, compar);
pright = med3(right - k * 2, right - k, pright, compar);
}
p = med3(pleft, p, pright, compar);
}
p = med3(pleft, p, pright, compar);
}
i = ii = left; // i scans left to right
j = jj = right; // j scans right to left
i = ii = left; // i scans left to right
j = jj = right; // j scans right to left
for (;;)
{
while (i <= j)
{
if (i != p && ((ki = COMP(i, p)) >= 0))
{
if (ki)
break;
if (ki)
break;
if (ii == p)
{
p = i;
p = i;
}
else if (i != ii)
{
SWAP(i, ii);
SWAP(i, ii);
}
ii += size;
}
i += size;
}
ii += size;
}
i += size;
}
while (i < j)
while (i < j)
{
if (j != p && ((kj = COMP(j, p)) <= 0))
if (j != p && ((kj = COMP(j, p)) <= 0))
{
if (kj)
break;
if (kj)
break;
if (jj == p)
if (jj == p)
{
p = j;
p = j;
}
else if (j != jj)
else if (j != jj)
{
SWAP(j, jj);
SWAP(j, jj);
}
jj -= size;
}
j -= size;
}
jj -= size;
}
j -= size;
}
if (i >= j)
break;
if (i >= j)
break;
SWAP(i, j);
i += size;
j -= size;
}
SWAP(i, j);
i += size;
j -= size;
}
if (p < i)
i -= size;
if (p < i)
i -= size;
if (p != i)
{
SWAP(p, i);
}
ptrdiff_t lessthan = i - ii;
size_t k = min(lessthan, ii - left);
ptrdiff_t lessthan = i - ii;
size_t k = min(lessthan, ii - left);
if (k)
vecswapf(left, i - k, k);
if (k)
vecswapf(left, i - k, k);
ptrdiff_t morethan = jj - i;
k = min(morethan, right - jj);
ptrdiff_t morethan = jj - i;
k = min(morethan, right - jj);
if (k)
vecswapf(i + size, limit - k, k);
if (k)
vecswapf(i + size, limit - k, k);
if (lessthan > morethan)
if (lessthan > morethan)
{
if (lessthan > 1)
if (lessthan > 1)
{
sp[0] = left;
sp[1] = left + lessthan;
sp += 2; // increment stack pointer
}
sp[0] = left;
sp[1] = left + lessthan;
sp += 2; // increment stack pointer
}
if (morethan <= 1)
goto pop;
if (morethan <= 1)
goto pop;
left = limit - morethan;
left = limit - morethan;
}
else
{
if (morethan > 1)
if (morethan > 1)
{
sp[0] = limit - morethan;
sp[1] = limit;
sp += 2; // increment stack pointer
}
sp[0] = limit - morethan;
sp[1] = limit;
sp += 2; // increment stack pointer
}
if (lessthan <= 1)
goto pop;
if (lessthan <= 1)
goto pop;
limit = left + lessthan;
}
}
limit = left + lessthan;
}
}
else // else subfile is small, use insertion sort
{
for (i = left + size; i < limit; i += size)
for (i = left + size; i < limit; i += size)
{
for (j = i; j != left && COMP(j - size, j) > 0; j -= size)
for (j = i; j != left && COMP(j - size, j) > 0; j -= size)
{
SWAP(j - size, j);
}
}
SWAP(j - size, j);
}
}
pop:
if (sp != stack) // if any entries on stack
if (sp != stack) // if any entries on stack
{
sp -= 2; // pop the left and limit
left = sp[0];
limit = sp[1];
}
else // else stack empty, done
break;
sp -= 2; // pop the left and limit
left = sp[0];
limit = sp[1];
}
else // else stack empty, done
break;
}
}
}
+16 -2
View File
@@ -1,7 +1,21 @@
// License: 0BSD
//
// Copyright 2022 Raymond Gardner
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
#ifndef __QS22J__
#define __QS22J__
void qs22j(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
#endif
+5 -5
View File
@@ -15,6 +15,8 @@
#include "g_game.h"
#include "r_local.h"
#include "r_state.h"
#include "r_portal.h" // Add seg portals
#include "r_splats.h"
#include "p_local.h" // camera
@@ -28,7 +30,6 @@ side_t *sidedef;
line_t *linedef;
sector_t *frontsector;
sector_t *backsector;
boolean portalline; // is curline a portal seg?
// very ugly realloc() of drawsegs at run-time, I upped it to 512
// instead of 256.. and someone managed to send me a level with
@@ -417,7 +418,7 @@ static void R_AddLine(seg_t *line)
angle_t angle1, angle2, span, tspan;
static sector_t tempsec;
portalline = false;
g_portal = NULL;
if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES))
return;
@@ -486,7 +487,7 @@ static void R_AddLine(seg_t *line)
line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, line2);
if (line2 >= 0) // found it!
{
R_AddPortal(line->linedef-lines, line2, x1, x2); // Remember the lines for later rendering
Portal_Add2Lines(line->linedef-lines, line2, x1, x2); // Remember the lines for later rendering
//return; // Don't fill in that space now!
goto clipsolid;
}
@@ -1333,8 +1334,7 @@ void R_RenderBSPNode(INT32 bspnum)
// PORTAL CULLING
if (portalcullsector)
{
sector_t *sect = subsectors[bspnum & ~NF_SUBSECTOR].sector;
if (sect != portalcullsector)
if (subsectors[bspnum & ~NF_SUBSECTOR].sector != portalcullsector)
return;
portalcullsector = NULL;
}
+4 -2
View File
@@ -18,12 +18,15 @@
#pragma interface
#endif
#include "r_main.h"
extern seg_t *curline;
extern side_t *sidedef;
extern line_t *linedef;
extern sector_t *frontsector;
extern sector_t *backsector;
extern boolean portalline; // is curline a portal seg?
typedef struct portal_s portal_t;
extern portal_t *g_portal; // is curline a portal seg?
// drawsegs are allocated on the fly... see r_segs.c
@@ -39,7 +42,6 @@ void R_ClearClipSegs(void);
void R_PortalClearClipSegs(INT32 start, INT32 end);
void R_ClearDrawSegs(void);
void R_RenderBSPNode(INT32 bspnum);
void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2);
// determines when a given sector shouldn't abide by the encoremap's palette.
// no longer a static since this is used for encore in hw_main.c as well now:
-8
View File
@@ -687,14 +687,6 @@ typedef struct
#pragma pack()
#endif
typedef enum // trimmed since its only real use here is for xscale/yscale
{
RF_HORIZONTALFLIP = 0x0001, // Flip sprite horizontally
RF_VERTICALFLIP = 0x0002, // Flip sprite vertically
RF_ABSOLUTEOFFSETS = 0x0004, // Sprite uses the object's offsets absolutely, instead of relatively
RF_FLIPOFFSETS = 0x0008, // Relative object offsets are flipped with the sprite
} renderflags_t;
typedef enum
{
SRF_SINGLE = 0, // 0-angle for all rotations
+1
View File
@@ -78,6 +78,7 @@ fixed_t dc_iscale, dc_texturemid;
UINT8 dc_hires; // under MSVC boolean is a byte, while on other systems, it a bit,
// soo lets make it a byte on all system for the ASM code
UINT8 *dc_source;
INT32 dc_sourcelength;
// -----------------------
// translucency stuff here
+1
View File
@@ -62,6 +62,7 @@ extern lighttable_t *ds_colormap;
extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
extern INT32 ds_waterofs, ds_bgofs;
extern UINT8 *ds_source; // start of a 64*64 tile image
extern INT32 dc_sourcelength;
extern UINT8 *ds_transmap;
extern INT32 ds_bgofs;
+288 -267
View File
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -129,7 +129,7 @@ static void R_SetupFreelook(void)
// (lmps, network and use F12...)
if (rendermode == render_soft
#ifdef HWRENDER
|| cv_grshearing.value
|| cv_glshearing.value
#endif
)
{
@@ -323,7 +323,7 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out)
out->angle = mobj->resetinterp ? mobj->angle : R_LerpAngle(mobj->old_angle, mobj->angle, frac);
#ifdef HWRENDER
if (cv_grmdls.value)
if (cv_glmdls.value)
{
// pitch roll stuff
out->pitch = mobj->resetinterp ? mobj->pitch : R_LerpAngle(mobj->old_pitch, mobj->pitch, frac);
+86 -253
View File
@@ -31,6 +31,7 @@
#include "p_spec.h" // skyboxmo
#include "z_zone.h"
#include "m_random.h" // quake camera shake
#include "r_portal.h"
#include "doomstat.h" // MAXSPLITSCREENPLAYERS
#include "r_fps.h" // Frame interpolation/uncapped
#include "tables.h"
@@ -66,33 +67,8 @@ boolean skyVisiblePerPlayer[MAXSPLITSCREENPLAYERS]; // saved values of skyVisibl
sector_t *viewsector;
player_t *viewplayer;
// PORTALS!
// You can thank and/or curse JTE for these.
UINT8 portalrender;
sector_t *portalcullsector;
typedef struct portal_pair
{
INT32 line1;
INT32 line2;
UINT8 pass;
struct portal_pair *next;
fixed_t viewx;
fixed_t viewy;
fixed_t viewz;
angle_t viewangle;
INT32 start;
INT32 end;
INT16 *ceilingclip;
INT16 *floorclip;
fixed_t *frontscale;
} portal_pair;
portal_pair *portal_base, *portal_cap;
line_t *portalclipline;
INT32 portalclipstart, portalclipend;
fixed_t rendertimefrac;
fixed_t rendertimefrac_unpaused;
fixed_t renderdeltatics;
boolean renderisnewtic;
@@ -173,10 +149,6 @@ static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NU
static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}};
static void Fov_OnChange(void);
static void ChaseCam_OnChange(void);
static void ChaseCam2_OnChange(void);
static void ChaseCam3_OnChange(void);
static void ChaseCam4_OnChange(void);
static void FlipCam_OnChange(void);
static void FlipCam2_OnChange(void);
static void FlipCam3_OnChange(void);
@@ -189,10 +161,10 @@ void SendWeaponPref4(void);
static void Precipstuff_OnChange(void);
consvar_t cv_tailspickup = {"tailspickup", "On", CV_NETVAR|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chasecam = {"chasecam", "On", CV_CALL, CV_OnOff, ChaseCam_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chasecam2 = {"chasecam2", "On", CV_CALL, CV_OnOff, ChaseCam2_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chasecam3 = {"chasecam3", "On", CV_CALL, CV_OnOff, ChaseCam3_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chasecam4 = {"chasecam4", "On", CV_CALL, CV_OnOff, ChaseCam4_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chasecam = {"chasecam", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chasecam2 = {"chasecam2", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chasecam3 = {"chasecam3", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chasecam4 = {"chasecam4", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_flipcam = {"flipcam", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_flipcam2 = {"flipcam2", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam2_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_flipcam3 = {"flipcam3", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam3_OnChange, 0, NULL, NULL, 0, 0, NULL};
@@ -215,7 +187,9 @@ consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE|CV_CALL|CV_NO
consvar_t cv_lessprecip = {"lessweathereffects", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, Precipstuff_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mobjscaleprecip = {"scaleprecipmobjscale", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, Precipstuff_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grmaxinterpdist = {"gr_maxinterpdist", "Infinite", CV_SAVE, maxinterpdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_maxinterpdist = {"maxinterpdist", "Infinite", CV_SAVE, maxinterpdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_ripplewater = {"waterripples", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
// cap fov, fov too high tears software apart.
consvar_t cv_fov = {"fov", "90", CV_FLOAT|CV_CALL|CV_SAVE, fov_cons_t, Fov_OnChange, 0, NULL, NULL, 0, 0, NULL};
@@ -272,47 +246,9 @@ void SplitScreen_OnChange(void)
}
static void Fov_OnChange(void)
{
// Shouldn't be needed with render parity?
//if ((netgame || multiplayer) && !cv_debug && cv_fov.value != 90*FRACUNIT)
// CV_Set(&cv_fov, cv_fov.defaultvalue);
R_SetViewSize();
}
static void ChaseCam_OnChange(void)
{
/*if (!cv_chasecam.value || !cv_useranalog.value)
CV_SetValue(&cv_analog, 0);
else
CV_SetValue(&cv_analog, 1);*/
}
static void ChaseCam2_OnChange(void)
{
if (botingame)
return;
/*if (!cv_chasecam2.value || !cv_useranalog2.value)
CV_SetValue(&cv_analog2, 0);
else
CV_SetValue(&cv_analog2, 1);*/
}
static void ChaseCam3_OnChange(void)
{
/*if (!cv_chasecam3.value || !cv_useranalog3.value)
CV_SetValue(&cv_analog3, 0);
else
CV_SetValue(&cv_analog3, 1);*/
}
static void ChaseCam4_OnChange(void)
{
/*if (!cv_chasecam4.value || !cv_useranalog4.value)
CV_SetValue(&cv_analog4, 0);
else
CV_SetValue(&cv_analog4, 1);*/
}
static void FlipCam_OnChange(void)
{
SendWeaponPref();
@@ -382,29 +318,6 @@ PUREFUNC INT32 R_PointOnSide(fixed_t x, fixed_t y, const node_t *restrict node)
(~mask & (FixedMul(y, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, x)));
}
// killough 5/2/98: reformatted
PUREFUNC INT32 R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line)
{
fixed_t lx = line->v1->x;
fixed_t ly = line->v1->y;
fixed_t ldx = line->v2->x - lx;
fixed_t ldy = line->v2->y - ly;
if (!ldx)
return x <= lx ? ldy > 0 : ldy < 0;
if (!ldy)
return y <= ly ? ldx < 0 : ldx > 0;
x -= lx;
y -= ly;
// Try to quickly decide by looking at sign bits.
if ((ldy ^ ldx ^ x ^ y) < 0)
return (ldy ^ x) < 0; // (left is negative)
return FixedMul(y, ldx>>FRACBITS) >= FixedMul(ldy>>FRACBITS, x);
}
//
// R_PointToAngle
// To get a global angle from cartesian coordinates,
@@ -516,6 +429,11 @@ INT32 R_GetHudUncap(void)
return cv_uncappedhud.value ? rendertimefrac & FRACMASK : 0;
}
INT32 R_GetMenuUncap(void)
{
return cv_uncappedhud.value ? rendertimefrac_unpaused & FRACMASK : 0;
}
//
// R_ScaleFromGlobalAngle
// Returns the texture mapping scale for the current line (horizontal span)
@@ -1037,6 +955,16 @@ void R_ExecuteSetViewSize(void)
R_InitTextureMapping();
// why did we calc all the software crap?
#ifdef HWRENDER
if (rendermode == render_opengl)
{
HWR_SetViewSize();
am_recalc = true;
return;
}
#endif
// thing clipping
for (i = 0; i < viewwidth; i++)
screenheightarray[i] = (INT16)viewheight;
@@ -1045,27 +973,24 @@ void R_ExecuteSetViewSize(void)
R_SetSkyScale();
// planes
if (rendermode == render_soft)
// this is only used for planes rendering in software mode
j = viewheight*16;
for (i = 0; i < j; i++)
{
// this is only used for planes rendering in software mode
j = viewheight*16;
for (i = 0; i < j; i++)
{
dy = (i - viewheight*8)<<FRACBITS;
dy = FixedMul(abs(dy), fovtan);
yslopetab[i] = FixedDiv(centerx*FRACUNIT, dy);
}
if (ds_su)
Z_Free(ds_su);
if (ds_sv)
Z_Free(ds_sv);
if (ds_sz)
Z_Free(ds_sz);
ds_su = ds_sv = ds_sz = NULL;
ds_sup = ds_svp = ds_szp = NULL;
dy = (i - viewheight*8)<<FRACBITS;
dy = FixedMul(abs(dy), fovtan);
yslopetab[i] = FixedDiv(centerx*FRACUNIT, dy);
}
if (ds_su)
Z_Free(ds_su);
if (ds_sv)
Z_Free(ds_sv);
if (ds_sz)
Z_Free(ds_sz);
ds_su = ds_sv = ds_sz = NULL;
ds_sup = ds_svp = ds_szp = NULL;
memset(scalelight, 0xFF, sizeof(scalelight));
@@ -1087,12 +1012,6 @@ void R_ExecuteSetViewSize(void)
}
}
// continue to do the software setviewsize as long as we use the reference software view
#ifdef HWRENDER
if (rendermode != render_soft)
HWR_SetViewSize();
#endif
am_recalc = true;
}
@@ -1407,10 +1326,7 @@ void R_SkyboxFrame(player_t *player)
else
newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
// newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT);
// newview->cos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
R_InterpolateView(R_UsingFrameInterpolation() ? rendertimefrac : FRACUNIT, false);
R_InterpolateView(R_UsingFrameInterpolation() ? (demo.playback && demo.freecam) ? rendertimefrac_unpaused : rendertimefrac : FRACUNIT, false);
}
void R_SetupFrame(player_t *player, boolean skybox)
@@ -1477,25 +1393,23 @@ void R_SetupFrame(player_t *player, boolean skybox)
thiscam->chase = false;
newview->sky = !skybox;
if (player->awayviewtics)
if (player->awayviewtics) // cut-away view stuff
{
// cut-away view stuff
viewmobj = player->awayviewmobj; // should be a MT_ALTVIEWMAN
I_Assert(viewmobj != NULL);
newview->z = viewmobj->z + 20*FRACUNIT;
newview->aim = player->awayviewaiming;
newview->angle = viewmobj->angle;
}
else if (!player->spectator && (thiscam && chasecam))
// use outside cam view
else if (!player->spectator && (thiscam && chasecam)) // use outside cam view
{
viewmobj = NULL;
newview->z = thiscam->z + (thiscam->height>>1);
newview->aim = thiscam->aiming;
newview->angle = thiscam->angle;
}
else
// use the player's eyes view
else // use the player's eyes view
{
newview->z = player->viewz;
@@ -1557,118 +1471,33 @@ void R_SetupFrame(player_t *player, boolean skybox)
newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
}
// newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT);
// newview->cos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
R_InterpolateView(R_UsingFrameInterpolation() ? rendertimefrac : FRACUNIT, false);
R_InterpolateView(R_UsingFrameInterpolation() ? (demo.playback && demo.freecam) ? rendertimefrac_unpaused : rendertimefrac : FRACUNIT, false);
}
#define ANGLED_PORTALS
static void R_PortalFrame(line_t *start, line_t *dest, portal_pair *portal)
static void R_PortalFrame(portal_t *portal)
{
vertex_t dest_c, start_c;
#ifdef ANGLED_PORTALS
// delta angle
angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0);
#endif
//R_SetupFrame(player, false);
viewx = portal->viewx;
viewy = portal->viewy;
viewz = portal->viewz;
viewangle = portal->viewangle;
// newview->sin = FINESINE(newview->angle>>ANGLETOFINESHIFT);
// newview->cos = FINECOSINE(newview->angle>>ANGLETOFINESHIFT);
// viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
// viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
portalcullsector = dest->frontsector;
viewsector = dest->frontsector;
portalclipline = dest;
portalclipstart = portal->start;
portalclipend = portal->end;
// Offset the portal view by the linedef centers
// looking glass center
start_c.x = (start->v1->x + start->v2->x) / 2;
start_c.y = (start->v1->y + start->v2->y) / 2;
// other side center
dest_c.x = (dest->v1->x + dest->v2->x) / 2;
dest_c.y = (dest->v1->y + dest->v2->y) / 2;
// Heights!
viewz += dest->frontsector->floorheight - start->frontsector->floorheight;
// calculate the difference in position and rotation!
#ifdef ANGLED_PORTALS
if (dangle == 0)
#endif
{ // the entrance goes straight opposite the exit, so we just need to mess with the offset.
viewx += dest_c.x - start_c.x;
viewy += dest_c.y - start_c.y;
return;
}
#ifdef ANGLED_PORTALS
viewangle += dangle;
// newview->sin = FINESINE(newview->angle>>ANGLETOFINESHIFT);
// newview->cos = FINECOSINE(newview->angle>>ANGLETOFINESHIFT);
//CONS_Printf("dangle == %u\n", AngleFixed(dangle)>>FRACBITS);
// ????
if (portal->clipline != -1)
{
fixed_t disttopoint;
angle_t angtopoint;
disttopoint = R_PointToDist2(start_c.x, start_c.y, newview->x, newview->y);
angtopoint = R_PointToAngle2(start_c.x, start_c.y, newview->x, newview->y);
angtopoint += dangle;
viewx = dest_c.x+FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
viewy = dest_c.y+FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
}
#endif
}
void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2)
{
portal_pair *portal = Z_Malloc(sizeof(portal_pair), PU_LEVEL, NULL);
INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL);
INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL);
fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1), PU_LEVEL, NULL);
portal->line1 = line1;
portal->line2 = line2;
portal->pass = portalrender+1;
portal->next = NULL;
R_PortalStoreClipValues(x1, x2, ceilingclipsave, floorclipsave, frontscalesave);
portal->ceilingclip = ceilingclipsave;
portal->floorclip = floorclipsave;
portal->frontscale = frontscalesave;
portal->start = x1;
portal->end = x2;
portalline = true; // this tells R_StoreWallRange that curline is a portal seg
portal->viewx = viewx;
portal->viewy = viewy;
portal->viewz = viewz;
portal->viewangle = viewangle;
if (!portal_base)
{
portal_base = portal;
portal_cap = portal;
portalclipline = &lines[portal->clipline];
portalcullsector = portalclipline->frontsector;
viewsector = portalclipline->frontsector;
}
else
{
portal_cap->next = portal;
portal_cap = portal;
portalclipline = NULL;
portalcullsector = NULL;
viewsector = R_PointInSubsector(viewx, viewy)->sector;
}
}
@@ -1684,7 +1513,6 @@ void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2)
void R_RenderPlayerView(player_t *player)
{
portal_pair *portal;
const boolean skybox = (skyboxmo[0] && cv_skybox.value);
UINT8 i;
@@ -1721,8 +1549,7 @@ void R_RenderPlayerView(player_t *player)
break;
}
portalrender = 0;
portal_base = portal_cap = NULL;
Portal_InitList();
PS_START_TIMING(ps_skyboxtime);
if (skybox && skyVisible)
@@ -1765,7 +1592,7 @@ void R_RenderPlayerView(player_t *player)
else
{
portalclipstart = 0;
portalclipend = viewwidth-1;
portalclipend = viewwidth;
R_ClearClipSegs();
}
R_ClearDrawSegs();
@@ -1787,37 +1614,41 @@ void R_RenderPlayerView(player_t *player)
ps_numsprites.value.i = numvisiblesprites;
// PORTAL RENDERING
PS_START_TIMING(ps_sw_portaltime);
for(portal = portal_base; portal; portal = portal_base)
// Portal rendering. Hijacks the BSP traversal.
if (portal_base)
{
// render the portal
CONS_Debug(DBG_RENDER, "Rendering portal from line %d to %d\n", portal->line1, portal->line2);
portalrender = portal->pass;
portal_t *portal;
R_PortalFrame(&lines[portal->line1], &lines[portal->line2], portal);
for (portal = portal_base; portal; portal = portal_base)
{
portalrender = portal->pass; // Recursiveness depth.
R_PortalClearClipSegs(portal->start, portal->end);
R_ClearFFloorClips();
R_PortalRestoreClipValues(portal->start, portal->end, portal->ceilingclip, portal->floorclip, portal->frontscale);
// Apply the viewpoint stored for the portal.
R_PortalFrame(portal);
validcount++;
// Hack in the clipsegs to delimit the starting
// clipping for sprites and possibly other similar
// future items.
R_PortalClearClipSegs(portal->start, portal->end);
R_RenderBSPNode((INT32)numnodes - 1);
R_ClipSprites();
//R_DrawPlanes();
//R_DrawMasked();
// Hack in the top/bottom clip values for the window
// that were previously stored.
Portal_ClipApply(portal);
// okay done. free it.
portalcullsector = NULL; // Just in case...
portal_base = portal->next;
Z_Free(portal->ceilingclip);
Z_Free(portal->floorclip);
Z_Free(portal->frontscale);
Z_Free(portal);
// Render the BSP from the new viewpoint, and clip
// any sprites with the new clipsegs and window.
R_RenderBSPNode((INT32)numnodes - 1);
R_ClipSprites();
Portal_Remove(portal);
validcount++;
}
}
PS_STOP_TIMING(ps_sw_portaltime);
// END PORTAL RENDERING
PS_START_TIMING(ps_sw_planetime);
R_DrawPlanes();
@@ -1929,7 +1760,9 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_maxportals);
CV_RegisterVar(&cv_grmaxinterpdist);
CV_RegisterVar(&cv_maxinterpdist);
CV_RegisterVar(&cv_ripplewater);
// Default viewheight is changeable,
// initialized to standard viewheight
+18 -2
View File
@@ -33,6 +33,8 @@ extern size_t validcount, linecount, loopcount, framecount;
// The fraction of a tic being drawn (for interpolation between two tics)
extern fixed_t rendertimefrac;
// Same as rendertimefrac but not suspended when the game is paused
extern fixed_t rendertimefrac_unpaused;
// Evaluated delta tics for this frame (how many tics since the last frame)
extern fixed_t renderdeltatics;
// The current render is a new logical tic
@@ -71,7 +73,18 @@ extern lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
// Utility functions.
INT32 R_PointOnSide(fixed_t x, fixed_t y, const node_t *node);
INT32 R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line);
FUNCINLINE static ATTRINLINE PUREFUNC INT32 R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line)
{
fixed_t lx = line->v1->x;
fixed_t ly = line->v1->y;
fixed_t ldx = line->v2->x - lx;
fixed_t ldy = line->v2->y - ly;
// use cross product to determine side quickly
return (INT64)(y - ly) * ldx - (INT64)(x - lx) * ldy > 0;
}
angle_t R_PointToAngle(fixed_t x, fixed_t y);
angle_t R_PointToAngle64(INT64 x, INT64 y);
angle_t R_PointToAngle2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1);
@@ -123,7 +136,8 @@ extern consvar_t cv_drawdist, cv_drawdist_precip, cv_lessprecip, cv_mobjscalepre
extern consvar_t cv_fov;
extern consvar_t cv_skybox;
extern consvar_t cv_tailspickup;
extern consvar_t cv_grmaxinterpdist;
extern consvar_t cv_maxinterpdist;
extern consvar_t cv_ripplewater;
// Called by startup code.
void R_Init(void);
@@ -150,4 +164,6 @@ void R_RegisterEngineStuff(void);
// return multiplier for HUD uncap
INT32 R_GetHudUncap(void);
// same as above but keeps interpolation during pause
INT32 R_GetMenuUncap(void);
#endif
+5 -5
View File
@@ -775,11 +775,11 @@ static UINT16 GetPatchPixel(patch_t *patch, INT32 x, INT32 y, boolean flip)
#ifdef HWRENDER
static patch_t *R_CreateHardwarePatch(patch_t *patch)
{
GLPatch_t *grPatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL);
grPatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL);
grPatch->rawpatch = patch;
HWR_MakePatch(patch, grPatch, grPatch->mipmap, false);
return (patch_t *)grPatch;
GLPatch_t *glPatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL);
glPatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL);
glPatch->rawpatch = patch;
HWR_MakePatch(patch, glPatch, glPatch->mipmap, false);
return (patch_t *)glPatch;
}
#endif
+48 -73
View File
@@ -28,6 +28,7 @@
#include "z_zone.h"
#include "p_tick.h"
#include "r_fps.h"
#include "r_portal.h"
//
// opening
@@ -39,12 +40,6 @@
// good night sweet prince
//#define SHITPLANESPARENCY
//SoM: 3/23/2000: Use Boom visplane hashing.
#define VISPLANEHASHBITS 9
#define VISPLANEHASHMASK ((1<<VISPLANEHASHBITS)-1)
// the last visplane list is outside of the hash table and is used for fof planes
#define MAXVISPLANES ((1<<VISPLANEHASHBITS)+1)
static visplane_t *visplanes[MAXVISPLANES];
static visplane_t *freetail;
static visplane_t **freehead = &freetail;
@@ -112,50 +107,6 @@ void R_InitPlanes(void)
// FIXME: unused
}
// R_PortalStoreClipValues
// Saves clipping values for later. -Red
void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale)
{
INT32 i;
for (i = 0; i < end-start; i++)
{
*ceil = ceilingclip[start+i];
ceil++;
*floor = floorclip[start+i];
floor++;
*scale = frontscale[start+i];
scale++;
}
}
// R_PortalRestoreClipValues
// Inverse of the above. Restores the old value!
void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale)
{
INT32 i;
for (i = 0; i < end-start; i++)
{
ceilingclip[start+i] = *ceil;
ceil++;
floorclip[start+i] = *floor;
floor++;
frontscale[start+i] = *scale;
scale++;
}
// HACKS FOLLOW
for (i = 0; i < start; i++)
{
floorclip[i] = -1;
ceilingclip[i] = (INT16)viewheight;
}
for (i = end; i < vid.width; i++)
{
floorclip[i] = -1;
ceilingclip[i] = (INT16)viewheight;
}
}
//
// Water ripple effect!!
// Needs the height of the plane, and the vertical position of the span.
@@ -307,6 +258,23 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
spanfunc();
}
void R_ClearFFloorClips (void)
{
INT32 i, p;
// opening / clipping determination
for (i = 0; i < viewwidth; i++)
{
for (p = 0; p < MAXFFLOORS; p++)
{
ffloor[p].f_clip[i] = (INT16)viewheight;
ffloor[p].c_clip[i] = -1;
}
}
numffloors = 0;
}
//
// R_ClearPlanes
// At begining of frame.
@@ -910,34 +878,41 @@ void R_DrawSinglePlane(visplane_t *pl)
INT32 top, bottom;
UINT8 *scr;
planeripple.active = true;
if (spanfunc == R_DrawTranslucentSpan_8)
if (cv_ripplewater.value)
{
spanfunc = R_DrawTranslucentWaterSpan_8;
planeripple.active = true;
// Copy the current scene, ugh
top = pl->high-8;
bottom = pl->low+8;
if (spanfunc == R_DrawTranslucentSpan_8)
{
spanfunc = R_DrawTranslucentWaterSpan_8;
if (top < 0)
top = 0;
if (bottom > vid.height)
bottom = vid.height;
// Copy the current scene, ugh
top = pl->high-8;
bottom = pl->low+8;
if (splitscreen > 2 && viewplayer == &players[displayplayers[3]]) // Only copy the part of the screen we need
scr = (screens[0] + (top+(viewheight))*vid.width + viewwidth);
else if ((splitscreen == 1 && viewplayer == &players[displayplayers[1]])
|| (splitscreen > 1 && viewplayer == &players[displayplayers[2]]))
scr = (screens[0] + (top+(viewheight))*vid.width);
else if (splitscreen > 1 && viewplayer == &players[displayplayers[1]])
scr = (screens[0] + ((top)*vid.width) + viewwidth);
else
scr = (screens[0] + ((top)*vid.width));
if (top < 0)
top = 0;
if (bottom > vid.height)
bottom = vid.height;
VID_BlitLinearScreen(scr, screens[1]+((top)*vid.width),
vid.width, bottom-top,
vid.width, vid.width);
if (splitscreen > 2 && viewplayer == &players[displayplayers[3]]) // Only copy the part of the screen we need
scr = (screens[0] + (top+(viewheight))*vid.width + viewwidth);
else if ((splitscreen == 1 && viewplayer == &players[displayplayers[1]])
|| (splitscreen > 1 && viewplayer == &players[displayplayers[2]]))
scr = (screens[0] + (top+(viewheight))*vid.width);
else if (splitscreen > 1 && viewplayer == &players[displayplayers[1]])
scr = (screens[0] + ((top)*vid.width) + viewwidth);
else
scr = (screens[0] + ((top)*vid.width));
VID_BlitLinearScreen(scr, screens[1]+((top)*vid.width),
vid.width, bottom-top,
vid.width, vid.width);
}
}
else
{
planeripple.active = false;
}
}
#endif
+2 -2
View File
@@ -18,6 +18,7 @@
#include "r_data.h"
#include "p_polyobj.h"
//SoM: 3/23/2000: Use Boom visplane hashing.
#define VISPLANEHASHBITS 9
#define VISPLANEHASHMASK ((1<<VISPLANEHASHBITS)-1)
// the last visplane list is outside of the hash table and is used for fof planes
@@ -75,9 +76,8 @@ extern fixed_t *yslope;
extern lighttable_t **planezlight;
void R_InitPlanes(void);
void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale);
void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale);
void R_ClearPlanes(void);
void R_ClearFFloorClips (void);
void R_MapPlane(INT32 y, INT32 x1, INT32 x2);
void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2);
+193
View File
@@ -0,0 +1,193 @@
// SONIC ROBO BLAST 2 KART
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
// Copyright (C) 2000 by DooM Legacy Team.
// Copyright (C) 1996 by id Software, Inc.
//
// 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_portal.c
/// \brief Software renderer portals.
#include "r_portal.h"
#include "r_plane.h"
#include "r_main.h" // viewheight, viewwidth
#include "z_zone.h"
#include "r_things.h"
#include "r_sky.h"
UINT8 portalrender; /**< When rendering a portal, it establishes the depth of the current BSP traversal. */
// Linked list for portals.
portal_t *portal_base, *portal_cap;
line_t *portalclipline;
sector_t *portalcullsector;
INT32 portalclipstart, portalclipend;
portal_t *g_portal; // is curline a portal seg?
void Portal_InitList (void)
{
portalrender = 0;
portal_base = portal_cap = NULL;
}
/** Store the clipping window for a portal in its given range.
*
* The window is copied from the current window at the time
* the function is called, so it is useful for converting one-sided
* lines into portals.
*/
static void Portal_ClipRange (portal_t* portal)
{
INT32 start = portal->start;
INT32 end = portal->end;
INT16 *ceil = portal->ceilingclip;
INT16 *floor = portal->floorclip;
fixed_t *scale = portal->frontscale;
INT32 i;
for (i = 0; i < end-start; i++)
{
*ceil = ceilingclip[start+i];
ceil++;
*floor = floorclip[start+i];
floor++;
*scale = frontscale[start+i];
scale++;
}
}
/** Apply the clipping window from a portal.
*/
void Portal_ClipApply (const portal_t* portal)
{
INT32 i;
INT32 start = portal->start;
INT32 end = portal->end;
INT16 *ceil = portal->ceilingclip;
INT16 *floor = portal->floorclip;
fixed_t *scale = portal->frontscale;
for (i = 0; i < end-start; i++)
{
ceilingclip[start+i] = *ceil;
ceil++;
floorclip[start+i] = *floor;
floor++;
frontscale[start+i] = *scale;
scale++;
}
// HACKS FOLLOW
for (i = 0; i < start; i++)
{
floorclip[i] = -1;
ceilingclip[i] = (INT16)viewheight;
}
for (i = end; i < vid.width; i++)
{
floorclip[i] = -1;
ceilingclip[i] = (INT16)viewheight;
}
}
static portal_t* Portal_Add (const INT16 x1, const INT16 x2)
{
portal_t *portal = Z_Malloc(sizeof(portal_t), PU_LEVEL, NULL);
INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL);
INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL);
fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1 + 1), PU_LEVEL, NULL);
// Linked list.
if (!portal_base)
{
portal_base = portal;
portal_cap = portal;
}
else
{
portal_cap->next = portal;
portal_cap = portal;
}
portal->next = NULL;
// Store clipping values so they can be restored once the portal is rendered.
portal->ceilingclip = ceilingclipsave;
portal->floorclip = floorclipsave;
portal->frontscale = frontscalesave;
portal->start = x1;
portal->end = x2;
// Increase recursion level.
portal->pass = portalrender+1;
return portal;
}
void Portal_Remove (portal_t* portal)
{
portalcullsector = NULL;
portal_base = portal->next;
Z_Free(portal->ceilingclip);
Z_Free(portal->floorclip);
Z_Free(portal->frontscale);
Z_Free(portal);
}
/** Creates a portal out of two lines and a determined screen range.
*
* line1 determines the entrance, and line2 the exit.
* x1 and x2 determine the screen's column bounds.
* The view's offset from the entry line center is obtained,
* and then rotated&translated to the exit line's center.
* When the portal renders, it will create the illusion of
* the two lines being seamed together.
*/
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2)
{
portal_t* portal = Portal_Add(x1, x2);
// Offset the portal view by the linedef centers
line_t* start = &lines[line1];
line_t* dest = &lines[line2];
angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0);
fixed_t disttopoint;
angle_t angtopoint;
vertex_t dest_c, start_c;
// looking glass center
start_c.x = (start->v1->x + start->v2->x) / 2;
start_c.y = (start->v1->y + start->v2->y) / 2;
// other side center
dest_c.x = (dest->v1->x + dest->v2->x) / 2;
dest_c.y = (dest->v1->y + dest->v2->y) / 2;
disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy);
angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy);
angtopoint += dangle;
portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight;
portal->viewangle = viewangle + dangle;
portal->clipline = line2;
Portal_ClipRange(portal);
g_portal = portal; // this tells R_StoreWallRange that curline is a portal seg
}
+57
View File
@@ -0,0 +1,57 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-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 r_portal.h
/// \brief Software renderer portal struct, functions, linked list extern.
#ifndef __R_PORTAL__
#define __R_PORTAL__
#include "r_data.h"
/** Portal structure.
*/
typedef struct portal_s
{
struct portal_s *next;
// Viewport.
fixed_t viewx;
fixed_t viewy;
fixed_t viewz;
angle_t viewangle;
UINT8 pass; /**< Keeps track of the portal's recursion depth. */
INT32 clipline; /**< Optional clipline for line-based portals. */
// Clipping information.
INT32 start; /**< First horizontal pixel coordinate to draw at. */
INT32 end; /**< Last horizontal pixel coordinate to draw at. */
INT16 *ceilingclip; /**< Temporary screen top clipping array. */
INT16 *floorclip; /**< Temporary screen bottom clipping array. */
fixed_t *frontscale;/**< Temporary screen bottom clipping array. */
} portal_t;
extern portal_t* portal_base;
extern portal_t* portal_cap;
extern UINT8 portalrender;
extern line_t *portalclipline;
extern sector_t *portalcullsector;
extern INT32 portalclipstart, portalclipend;
void Portal_InitList (void);
void Portal_Remove (portal_t* portal);
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2);
void Portal_ClipApply (const portal_t* portal);
#endif
+17 -6
View File
@@ -15,6 +15,7 @@
#include "r_local.h"
#include "r_sky.h"
#include "r_portal.h"
#include "r_splats.h"
#include "w_wad.h"
@@ -275,6 +276,7 @@ static void R_Render2sidedMultiPatchColumn(column_t *column)
if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0)
{
dc_source = (UINT8 *)column + 3;
dc_sourcelength = 0;
if (colfunc == wallcolfunc)
twosmultipatchfunc();
@@ -1446,6 +1448,7 @@ static void R_RenderSegLoop (void)
dc_texturemid = rw_midtexturemid;
dc_source = R_GetColumn(midtexture,texturecolumn);
dc_texheight = textureheight[midtexture]>>FRACBITS;
dc_sourcelength = 0;
colfunc();
// dont draw anything more for this column, since
@@ -1493,6 +1496,7 @@ static void R_RenderSegLoop (void)
dc_texturemid = rw_toptexturemid;
dc_source = R_GetColumn(toptexture,texturecolumn);
dc_texheight = textureheight[toptexture]>>FRACBITS;
dc_sourcelength = 0;
colfunc();
ceilingclip[rw_x] = (INT16)mid;
}
@@ -1530,6 +1534,7 @@ static void R_RenderSegLoop (void)
dc_source = R_GetColumn(bottomtexture,
texturecolumn);
dc_texheight = textureheight[bottomtexture]>>FRACBITS;
dc_sourcelength = 0;
colfunc();
floorclip[rw_x] = (INT16)mid;
}
@@ -1605,6 +1610,12 @@ static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2)
}
}
static inline INT32 get_flat_tex (INT32 texnum)
{
texnum = R_GetTextureNum(texnum);
return textures[texnum]->holes ? 0 : texnum; // R_DrawWallColumn cannot render holey textures
}
//
// R_StoreWallRange
// A wall segment will be drawn
@@ -1862,7 +1873,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
fixed_t texheight;
// single sided line
midtexture = R_GetTextureNum(sidedef->midtexture);
midtexture = get_flat_tex(sidedef->midtexture);
texheight = textureheight[midtexture];
// a single sided line is terminal, so it must mark ends
markfloor = markceiling = true;
@@ -2045,15 +2056,15 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
// Special case... use offsets from 2nd side but only if it has a texture.
side_t *def = &sides[linedef->sidenum[1]];
toptexture = R_GetTextureNum(def->toptexture);
toptexture = get_flat_tex(def->toptexture);
if (!toptexture) //Second side has no texture, use the first side's instead.
toptexture = R_GetTextureNum(sidedef->toptexture);
toptexture = get_flat_tex(sidedef->toptexture);
texheight = textureheight[toptexture];
}
else
{
toptexture = R_GetTextureNum(sidedef->toptexture);
toptexture = get_flat_tex(sidedef->toptexture);
texheight = textureheight[toptexture];
}
if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked
@@ -2078,7 +2089,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (worldlow > worldbottom || worldlowslope > worldbottomslope) // Only if VISIBLE!!!
{
// bottom texture
bottomtexture = R_GetTextureNum(sidedef->bottomtexture);
bottomtexture = get_flat_tex(sidedef->bottomtexture);
if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked
if (linedef->flags & ML_DONTPEGBOTTOM)
@@ -2840,7 +2851,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
R_RenderSegLoop();
colfunc = wallcolfunc;
if (portalline) // if curline is a portal, set portalrender for drawseg
if (g_portal) // if curline is a portal, set portalrender for drawseg
ds_p->portalpass = portalrender+1;
else
ds_p->portalpass = 0;
-4
View File
@@ -94,10 +94,6 @@ extern boolean viewsky, skyVisible;
extern boolean skyVisiblePerPlayer[MAXSPLITSCREENPLAYERS]; // saved values of skyVisible of each splitscreen player
extern sector_t *viewsector;
extern player_t *viewplayer;
extern UINT8 portalrender;
extern sector_t *portalcullsector;
extern line_t *portalclipline;
extern INT32 portalclipstart, portalclipend;
extern consvar_t cv_allowmlook;
extern consvar_t cv_maxportals;
+72 -93
View File
@@ -31,6 +31,7 @@
#include "dehacked.h" // get_number (for thok)
#include "d_netfil.h" // blargh. for nameonly().
#include "m_cheat.h" // objectplace
#include "r_portal.h"
#include "k_kart.h" // SRB2kart
#include "p_local.h" // stplyr
#ifdef HWRENDER
@@ -43,7 +44,7 @@ CV_PossibleValue_t Forceskin_cons_t[MAXSKINS+2];
static void R_InitSkins(void);
#define MINZ (FRACUNIT*4)
#define MINZ (FRACUNIT*16)
#define BASEYCENTER (BASEVIDHEIGHT/2)
typedef struct
@@ -522,7 +523,7 @@ void R_InitSprites(void)
// it can be is do before loading config for skin cvar possible value
R_InitSkins();
for (i = 0; i < numwadfiles; i++)
for (i = 0; i < numwadfiles; i++)
{
R_AddSkins((UINT16)i, false);
R_LoadSpriteInfoLumps(i, wadfiles[i]->numlumps);
@@ -583,6 +584,9 @@ void R_DrawMaskedColumn(column_t *column)
basetexturemid = dc_texturemid;
if (!column || column == 0)
return;
for (; column->topdelta != 0xff ;)
{
// calculate unclipped screen coordinates
@@ -609,14 +613,16 @@ void R_DrawMaskedColumn(column_t *column)
dc_yh = mfloorclip[dc_x]-1;
if (dc_yl <= mceilingclip[dc_x])
dc_yl = mceilingclip[dc_x]+1;
if (dc_yl < 0)
dc_yl = 0;
if (dc_yh >= vid.height)
dc_yh = vid.height - 1;
if (dc_yl <= dc_yh && dc_yh > 0)
if (dc_yl <= dc_yh && dc_yh > 0 && column->length != 0)
{
dc_source = (UINT8 *)column + 3;
dc_sourcelength = column->length;
dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
// Drawn by R_DrawColumn.
@@ -625,6 +631,10 @@ void R_DrawMaskedColumn(column_t *column)
// quick fix... something more proper should be done!!!
if (ylookup[dc_yl])
colfunc();
#ifdef PARANOIA
else
I_Error("R_DrawMaskedColumn: Invalid ylookup for dc_yl %d", dc->yl);
#endif
}
column = (column_t *)((UINT8 *)column + column->length + 4);
}
@@ -674,9 +684,10 @@ static void R_DrawFlippedMaskedColumn(column_t *column)
if (dc_yh >= vid.height)
dc_yh = vid.height - 1;
if (dc_yl <= dc_yh && dc_yh > 0)
if (dc_yl <= dc_yh && dc_yh > 0 && column->length != 0)
{
dc_source = ZZ_Alloc(column->length);
dc_sourcelength = column->length;
for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s)
*d++ = *s;
dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
@@ -722,7 +733,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
if (overflow_test < 0) overflow_test = -overflow_test;
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // ditto
}
// TODO This check should not be necessary. But Papersprites near to the camera will sometimes create invalid values
// for the vissprite's startfrac. This happens because they are not depth culled like other sprites.
// Someone who is more familiar with papersprites pls check and try to fix <3
@@ -794,7 +805,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
dc_colormap += COLORMAP_REMAPOFFSET;
dc_texturemid = vis->texturemid;
dc_texheight = 0;
dc_texheight = SHORT(patch->height);
frac = vis->startfrac;
windowtop = windowbottom = sprbotscreen = INT32_MAX;
@@ -803,8 +814,10 @@ static void R_DrawVisSprite(vissprite_t *vis)
this_scale = FixedMul(this_scale, ((skin_t *)vis->mobj->localskin)->highresscale);
else if (vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES)
this_scale = FixedMul(this_scale, ((skin_t *)vis->mobj->skin)->highresscale);
if (this_scale <= 0)
this_scale = 1;
if (this_scale != FRACUNIT)
{
if (!vis->isScaled)
@@ -837,22 +850,15 @@ static void R_DrawVisSprite(vissprite_t *vis)
if (vis->x2 >= vid.width)
vis->x2 = vid.width-1;
// Something is occasionally setting 1px-wide sprites whose frac is exactly the width of the sprite, causing crashes due to
// accessing invalid column info. Until the cause is found, let's try to correct those manually...
{
fixed_t temp = ((frac + vis->xiscale*(vis->x2-vis->x1))>>FRACBITS) - SHORT(patch->width);
if (temp > 0)
vis->x2 -= temp;
}
localcolfunc = (vis->vflip) ? R_DrawFlippedMaskedColumn : R_DrawMaskedColumn;
lengthcol = patch->height;
lengthcol = SHORT(patch->height);
// Split drawing loops for paper and non-paper to reduce conditional checks per sprite
if (vis->scalestep)
{
fixed_t horzscale = FixedMul(vis->spritexscale, this_scale);
fixed_t scalestep = FixedMul(vis->scalestep, vis->spriteyscale);
pwidth = SHORT(patch->width);
// Papersprite drawing loop
@@ -877,12 +883,10 @@ static void R_DrawVisSprite(vissprite_t *vis)
}
else
{
pwidth = SHORT(patch->width);
// Non-paper drawing loop
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale)
{
texturecolumn = CLAMP(frac >> FRACBITS, 0, pwidth - 1);
{
texturecolumn = CLAMP(frac >> FRACBITS, 0, SHORT(patch->width) - 1);
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
localcolfunc (column);
@@ -928,7 +932,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
dc_iscale = FixedDiv(FRACUNIT, vis->scale);
dc_texturemid = FixedDiv(vis->texturemid, this_scale);
dc_texheight = 0;
dc_texheight = SHORT(patch->height);
frac = vis->startfrac;
spryscale = vis->scale;
@@ -943,7 +947,14 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale)
{
texturecolumn = CLAMP(frac >> FRACBITS, 0, SHORT(patch->width) - 1);
texturecolumn = frac>>FRACBITS;
if (texturecolumn < 0 || texturecolumn >= patch->width)
{
CONS_Debug(DBG_RENDER, "R_DrawPrecipitationSpriteRange: bad texturecolumn\n");
break;
}
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
R_DrawMaskedColumn(column);
@@ -1156,17 +1167,17 @@ static void R_ProjectSprite(mobj_t *thing)
angle_t pitchnroll = 0;
angle_t sliptiderollangle = 0;
#endif
INT32 dist = -1;
if (cv_grmaxinterpdist.value)
if (cv_maxinterpdist.value)
dist = R_QuickCamDist(thing->x, thing->y);
// uncapped/interpolation
interpmobjstate_t interp = {0};
// do interpolation
if (R_UsingFrameInterpolation() && !paused && (!cv_grmaxinterpdist.value || dist < cv_grmaxinterpdist.value))
if (R_UsingFrameInterpolation() && !paused && (!cv_maxinterpdist.value || dist < cv_maxinterpdist.value))
{
R_InterpolateMobjState(oldthing, rendertimefrac, &interp);
}
@@ -1258,7 +1269,7 @@ static void R_ProjectSprite(mobj_t *thing)
{
ang = R_PointToAngle (interp.x, interp.y) - interp.angle;
camang = R_PointToAngle (interp.x, interp.y);
if (mirrored)
ang = InvAngle(ang);
}
@@ -1275,9 +1286,9 @@ static void R_ProjectSprite(mobj_t *thing)
// choose a different rotation based on player view
//ang = R_PointToAngle (interp.x, interp.y) - interpangle;
if ((ang < ANGLE_180) && (sprframe->rotate & SRF_RIGHT)) // See from right
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
rot = 6; // F7 slot
else if ((ang >= ANGLE_180) && (sprframe->rotate & SRF_LEFT)) // See from left
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
rot = 2; // F3 slot
else // Normal behaviour
rot = (ang+ANGLE_202h)>>29;
@@ -1288,7 +1299,7 @@ static void R_ProjectSprite(mobj_t *thing)
}
I_Assert(lump < max_spritelumps);
if (thing->localskin && ((skin_t *)thing->localskin)->flags & SF_HIRES)
this_scale = FixedMul(this_scale, ((skin_t *)thing->localskin)->highresscale);
else if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
@@ -1301,7 +1312,7 @@ static void R_ProjectSprite(mobj_t *thing)
#ifdef ROTSPRITE
pitchnroll = 0; // set this to 0, non-paper sprites will affect this value
if (cv_spriteroll.value)
{
if (papersprite)
@@ -1347,10 +1358,10 @@ static void R_ProjectSprite(mobj_t *thing)
if (rotsprite != NULL)
{
spr_width = rotsprite->width << FRACBITS;
spr_height = rotsprite->height << FRACBITS;
spr_offset = rotsprite->leftoffset << FRACBITS;
spr_topoffset = rotsprite->topoffset << FRACBITS;
spr_width = SHORT(rotsprite->width) << FRACBITS;
spr_height = SHORT(rotsprite->height) << FRACBITS;
spr_offset = SHORT(rotsprite->leftoffset) << FRACBITS;
spr_topoffset = SHORT(rotsprite->topoffset) << FRACBITS;
spr_topoffset += FEETADJUST;
// flip -> rotate, not rotate -> flip
@@ -1368,21 +1379,8 @@ static void R_ProjectSprite(mobj_t *thing)
if (spritexscale < 1 || spriteyscale < 1)
return;
if (thing->renderflags & RF_ABSOLUTEOFFSETS)
{
spr_offset = interp.spritexoffset;
spr_topoffset = interp.spriteyoffset;
}
else
{
SINT8 flipoffset = 1;
if ((thing->renderflags & RF_FLIPOFFSETS) && flip)
flipoffset = -1;
spr_offset += interp.spritexoffset * flipoffset;
spr_topoffset += interp.spriteyoffset * flipoffset;
}
spr_offset += interp.spritexoffset;
spr_topoffset += interp.spriteyoffset;
if (flip)
offset = spr_offset - spr_width;
@@ -1459,7 +1457,7 @@ static void R_ProjectSprite(mobj_t *thing)
tx2 += FixedDiv(tx-tx2, div);
tz2 = FixedMul(MINZ, this_scale);
}
if ((tx2 / 4) < -(FixedMul(tz2, fovtan)) || (tx / 4) > FixedMul(tz, fovtan)) // too far off the side?
return;
@@ -1487,7 +1485,7 @@ static void R_ProjectSprite(mobj_t *thing)
return;
range++; // fencepost problem
if (range > 32767)
{
// If the range happens to be too large for fixed_t,
@@ -1530,7 +1528,7 @@ static void R_ProjectSprite(mobj_t *thing)
// PORTAL SPRITE CLIPPING
if (portalrender && portalclipline)
{
if (x2 < portalclipstart || x1 > portalclipend)
if (x2 < portalclipstart || x1 >= portalclipend)
return;
if (P_PointOnLineSide(interp.x, interp.y, portalclipline) != 0)
@@ -1602,7 +1600,6 @@ static void R_ProjectSprite(mobj_t *thing)
// store information in a vissprite
vis = R_NewVisSprite();
vis->renderflags = thing->renderflags;
vis->heightsec = heightsec; //SoM: 3/17/2000
vis->mobjflags = thing->flags;
vis->scale = yscale; //<<detailshift;
@@ -1623,17 +1620,8 @@ static void R_ProjectSprite(mobj_t *thing)
vis->mobj = thing; // Easy access! Tails 06-07-2002
vis->x1 = x1 < 0 ? 0 : x1;
vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
// PORTAL SEMI-CLIPPING
if (portalrender && portalclipline)
{
if (vis->x1 < portalclipstart)
vis->x1 = portalclipstart;
if (vis->x2 > portalclipend)
vis->x2 = portalclipend;
}
vis->x1 = x1 < portalclipstart ? portalclipstart : x1;
vis->x2 = x2 >= portalclipend ? portalclipend-1 : x2;
vis->sector = thing->subsector->sector;
vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS);
@@ -1751,7 +1739,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
INT32 dist = 1;
if (cv_grmaxinterpdist.value)
if (cv_maxinterpdist.value)
dist = R_QuickCamDist(thing->x, thing->y);
// uncapped/interpolation
@@ -1764,7 +1752,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
}
// do interpolation
if (R_UsingFrameInterpolation() && !paused && (!cv_grmaxinterpdist.value || dist < cv_grmaxinterpdist.value))
if (R_UsingFrameInterpolation() && !paused && (!cv_maxinterpdist.value || dist < cv_maxinterpdist.value))
{
R_InterpolatePrecipMobjState(thing, rendertimefrac, &interp);
}
@@ -1843,7 +1831,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
// PORTAL SPRITE CLIPPING
if (portalrender && portalclipline)
{
if (x2 < portalclipstart || x1 > portalclipend)
if (x2 < portalclipstart || x1 >= portalclipend)
return;
if (P_PointOnLineSide(interp.x, interp.y, portalclipline) != 0)
@@ -1877,17 +1865,8 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->scalestep = 0;
vis->paperdistance = 0;
vis->x1 = x1 < 0 ? 0 : x1;
vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
// PORTAL SEMI-CLIPPING
if (portalrender && portalclipline)
{
if (vis->x1 < portalclipstart)
vis->x1 = portalclipstart;
if (vis->x2 > portalclipend)
vis->x2 = portalclipend;
}
vis->x1 = x1 < portalclipstart ? portalclipstart : x1;
vis->x2 = x2 >= portalclipend ? portalclipend-1 : x2;
vis->xscale = xscale; //SoM: 4/17/2000
vis->sector = thing->subsector->sector;
@@ -1987,7 +1966,7 @@ void R_AddPrecipitationSprites(void)
precipmobj_t *th, *next;
// no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off
if (drawdist == 0)
if (drawdist == 0 || curWeather == PRECIP_BLANK || curWeather == PRECIP_STORM_NORAIN)
{
return;
}
@@ -2391,7 +2370,7 @@ static drawnode_t *R_CreateDrawNode(drawnode_t *link)
node->thickseg = NULL;
node->ffloor = NULL;
node->sprite = NULL;
ps_numdrawnodes.value.i++;
return node;
}
@@ -2450,8 +2429,8 @@ static boolean R_CheckSpriteVisible(vissprite_t *spr, INT32 x1, INT32 x2)
INT16 sz = spr->sz;
INT16 szt = spr->szt;
fixed_t texturemid, yscale, scalestep = spr->scalestep;
INT32 height;
fixed_t texturemid = 0, yscale = 0, scalestep = spr->scalestep; // "= 0" pleases the compiler
INT32 height = 0;
if (scalestep)
{
@@ -2668,7 +2647,7 @@ static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2)
if (spr->cliptop[x] == -2)
spr->cliptop[x] = -1;
}
// Check if it'll be visible
// Not done for floorsprites.
if (cv_spriteclip.value)
@@ -2743,7 +2722,7 @@ void R_ClipSprites(void)
for (; clippedvissprites < visspritecount; clippedvissprites++)
{
vissprite_t *spr = R_GetVisSprite(clippedvissprites);
if (cv_spriteclip.value
&& (spr->szt > vid.height || spr->sz < 0))
{
@@ -2768,7 +2747,7 @@ void R_ClipSprites(void)
}
R_ClipVisSprite(spr, spr->x1, spr->x2);
if ((spr->cut & SC_NOTVISIBLE) == 0)
numvisiblesprites++;
}
@@ -2785,10 +2764,10 @@ boolean R_ThingVisible (mobj_t *thing)
if (splitscreen)
{
if ((viewssnum == 0 && (thing->renderflags & MFE_DRAWONLYFORP1))
|| (viewssnum == 1 && (thing->renderflags & MFE_DRAWONLYFORP2))
|| (viewssnum == 2 && (thing->renderflags & MFE_DRAWONLYFORP2))
|| (viewssnum == 3 && (thing->renderflags & MFE_DRAWONLYFORP4)))
if ((viewssnum == 0 && (thing->eflags & MFE_DRAWONLYFORP1))
|| (viewssnum == 1 && (thing->eflags & MFE_DRAWONLYFORP2))
|| (viewssnum == 2 && (thing->eflags & MFE_DRAWONLYFORP2))
|| (viewssnum == 3 && (thing->eflags & MFE_DRAWONLYFORP4)))
return true;
}
@@ -3295,7 +3274,7 @@ static int skinSortFunc(const void *a, const void *b) //tbh i have no clue what
void sortSkinGrid(void)
{
//CONS_Printf("Sorting skin list (%d)...\n", cv_skinselectgridsort.value);
qs22j(skinsorted, numskins, sizeof(UINT8), skinSortFunc);
qs22j(skinsorted, numskins, sizeof(UINT8), skinSortFunc);
}
//
@@ -3321,12 +3300,12 @@ void R_AddSkins(UINT16 wadnum, boolean local)
// advance by default
lastlump = lump + 1;
if (numskins >= MAXSKINS)
if (!local && numskins >= MAXSKINS)
{
CONS_Alert(CONS_WARNING, M_GetText("Unable to add skin, too many characters are loaded (%d maximum)\n"), MAXSKINS);
continue; // so we know how many skins couldn't be added
}
if (numlocalskins >= MAXLOCALSKINS)
if (local && numlocalskins >= MAXLOCALSKINS)
{
CONS_Alert(CONS_WARNING, M_GetText("Unable to add localskin, too many localskins are loaded (%d maximum)\n"), MAXLOCALSKINS);
continue; // so we know how many skins couldn't be added
@@ -3579,7 +3558,7 @@ next_token:
Forceskin_cons_t[numskins+1].value = numskins;
Forceskin_cons_t[numskins+1].strvalue = skins[numskins].name;
}
skin->localskin = local;
// so we dont have to guess
@@ -3606,7 +3585,7 @@ next_token:
CONS_Debug(DBG_SETUP, M_GetText("Incremented %d, %d to %d\n"), skin->kartspeed, skin->kartweight, skinstatscount[skin->kartspeed - 1][skin->kartweight - 1]);
skinsorted[numskins] = numskins;
}
allskins[numallskins] = ( (local) ? localskins : skins )[( (local) ? numlocalskins : numskins )];
local ? numlocalskins++ : numskins++;
+1
View File
@@ -55,6 +55,7 @@ extern fixed_t sprtopscreen;
extern fixed_t sprbotscreen;
extern fixed_t windowtop;
extern fixed_t windowbottom;
extern INT32 lengthcol;
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
+154 -47
View File
@@ -11,6 +11,7 @@
/// \file s_sound.c
/// \brief System-independent sound and music routines
#include "d_netcmd.h"
#include "doomdef.h"
#include "doomstat.h"
#include "command.h"
@@ -85,7 +86,6 @@ consvar_t cv_midimusicvolume = {"midimusicvolume", "18", CV_SAVE, soundvolume_co
// number of channels available
consvar_t cv_numChannels = {"snd_channels", "64", CV_SAVE|CV_CALL, CV_Unsigned, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL};
consvar_t surround = {"surround", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
//consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE|CV_NOSHOWHELP, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
// Sound system toggles, saved into the config
@@ -108,6 +108,7 @@ static CV_PossibleValue_t music_resync_threshold_cons_t[] = {
{0}
};
consvar_t cv_music_resync_threshold = {"music_resync_threshold", "0", CV_SAVE|CV_CALL, music_resync_threshold_cons_t, I_UpdateSongLagThreshold, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_music_resync_powerups_only = {"music_resync_powerups_only", "No", CV_SAVE|CV_CALL, CV_YesNo, I_UpdateSongLagThreshold, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_invincmusicfade = {"invincmusicfade", "300", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_growmusicfade = {"growmusicfade", "500", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -118,6 +119,14 @@ consvar_t cv_resume = {"resume", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0
consvar_t cv_fading = {"fading", "Off", CV_SAVE|CV_CALL, CV_OnOff, Bird_menu_Onchange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_birdmusic = {"birdmusicstuff", "No", CV_SAVE|CV_CALL, CV_YesNo, Bird_menu_Onchange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_keepmusic = {"keepmusic", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_skipintromusic = {"skipintromusic", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
//consvar_t cv_ignoremusicchanges = {"ignoremusicchanges", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
boolean keepmusic = false;
static void S_CheckEventMus(const char *newmus);
#ifdef HAVE_OPENMPT
openmpt_module *openmpt_mhandle = NULL;
@@ -163,10 +172,6 @@ consvar_t cv_amigatype = {"amigatype", "0", CV_SAVE|CV_CALL|CV_NOINIT, amigatype
#define S_PITCH_PERTURB 1
#define S_STEREO_SWING (96*0x10000)
#ifdef SURROUND
#define SURROUND_SEP -128
#endif
// percent attenuation from front to back
#define S_IFRACVOL 30
@@ -272,7 +277,6 @@ void S_RegisterSoundStuff(void)
CV_RegisterVar(&stereoreverse);
CV_RegisterVar(&precachesound);
CV_RegisterVar(&surround);
CV_RegisterVar(&cv_samplerate);
//CV_RegisterVar(&cv_resetmusic);
CV_RegisterVar(&cv_gamesounds);
@@ -281,13 +285,14 @@ void S_RegisterSoundStuff(void)
CV_RegisterVar(&cv_gamemidimusic);
#endif
//bird music stuff
// bird music stuff
CV_RegisterVar(&cv_playmusicifunfocused);
CV_RegisterVar(&cv_playsoundifunfocused);
CV_RegisterVar(&cv_pausemusic);
CV_RegisterVar(&cv_music_resync_threshold);
CV_RegisterVar(&cv_music_resync_powerups_only);
CV_RegisterVar(&cv_invincmusicfade);
CV_RegisterVar(&cv_growmusicfade);
@@ -299,6 +304,11 @@ void S_RegisterSoundStuff(void)
CV_RegisterVar(&cv_resume);
CV_RegisterVar(&cv_fading);
CV_RegisterVar(&cv_birdmusic);
// bird music stuff end
CV_RegisterVar(&cv_keepmusic);
CV_RegisterVar(&cv_skipintromusic);
//CV_RegisterVar(&cv_ignoremusicchanges);
COM_AddCommand("tunes", Command_Tunes_f);
COM_AddCommand("restartaudio", Command_RestartAudio_f);
@@ -616,11 +626,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
}
// Avoid channel reverse if surround
if (reverse
#ifdef SURROUND
&& sep != SURROUND_SEP
#endif
)
if (reverse)
{
sep = (~sep) & 255;
}
@@ -1102,18 +1108,10 @@ boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32
if (reverse)
angle = InvAngle(angle);
#ifdef SURROUND
// Produce a surround sound for angle from 105 till 255
if (surround.value == 1 && (angle > ANG105 && angle < ANG255 ))
*sep = SURROUND_SEP;
else
#endif
{
angle >>= ANGLETOFINESHIFT;
angle >>= ANGLETOFINESHIFT;
// stereo separation
*sep = 128 - (FixedMul(S_STEREO_SWING, FINESINE(angle))>>FRACBITS);
}
// stereo separation
*sep = 128 - (FixedMul(S_STEREO_SWING, FINESINE(angle))>>FRACBITS);
}
// volume calculation
@@ -1260,7 +1258,7 @@ void S_InitSfxChannels(INT32 sfxVolume)
if (S_PrecacheSound())
{
// Initialize external data (all sounds) at start, keep static.
CONS_Printf(M_GetText("Loading sounds... "));
CONS_Printf(M_GetText("Pre-caching sounds..."));
for (i = 1; i < sfx_freeslot0; i++)
if (S_sfx[i].name && !S_sfx[i].data)
@@ -1270,7 +1268,7 @@ void S_InitSfxChannels(INT32 sfxVolume)
if (S_sfx[i].priority && !S_sfx[i].data)
S_sfx[i].data = I_GetSfx(&S_sfx[i]);
CONS_Printf(M_GetText(" pre-cached all sound data\n"));
CONS_Printf(M_GetText("...pre-cached all sound data\n"));
}
}
@@ -1786,9 +1784,7 @@ boolean S_MusicPaused(void)
boolean S_MusicNotInFocus(void)
{
return (
( window_notinfocus && ! cv_playmusicifunfocused.value )
);
return (window_notinfocus && !cv_playmusicifunfocused.value);
}
musictype_t S_MusicType(void)
@@ -1816,10 +1812,8 @@ boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping)
boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi)
{
return (
(checkDigi ? W_CheckNumForName(va("O_%s", mname)) != LUMPERROR : false)
|| (checkMIDI ? W_CheckNumForName(va("D_%s", mname)) != LUMPERROR : false)
);
return (checkDigi ? W_CheckNumForName(va("O_%s", mname)) != LUMPERROR : false)
|| (checkMIDI ? W_CheckNumForName(va("D_%s", mname)) != LUMPERROR : false);
}
/// ------------------------
@@ -1979,6 +1973,8 @@ void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32
strncpy(newmusic, mmusic, 6);
S_CheckEventMus(newmusic);
if (LUAh_MusicChange(music_name, newmusic, &mflags, &looping, &position, &prefadems, &fadeinms))
return;
@@ -2052,8 +2048,10 @@ void S_StopMusic(void)
|| demo.title) // SRB2Kart: Demos don't interrupt title screen music
return;
if ((cv_birdmusic.value) && (strcasecmp(music_name, mapmusname) == 0))
if (cv_birdmusic.value && (strcasecmp(music_name, mapmusname) == 0))
mapmusresume = I_GetSongPosition();
else
mapmusresume = 0;
if (I_SongPaused())
I_ResumeSong();
@@ -2126,10 +2124,7 @@ void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume)
void S_SetRestoreMusicFadeInCvar (consvar_t *cv)
{
if (!cv_birdmusic.value)
return;
music_refade_cv = cv;
music_refade_cv = cv_birdmusic.value ? cv : 0;
}
int S_GetRestoreMusicFadeIn (void)
@@ -2171,13 +2166,92 @@ boolean S_FadeOutStopMusic(UINT32 ms)
/// Init & Others
/// ------------------------
/*static boolean S_KeepMusic(void)
{
//if (!cv_keepmusic.value)
//return false;
// should i compare songs or maps?
static char oldmusname[7] = "";
if (strcmp(music_name, mapmusname) != 0)
return false;
if (strcmp(oldmusname, mapmusname) == 0)
return true;
strncpy(oldmusname, mapmusname, 7);
oldmusname[6] = '\0';
return false;
}*/
static INT16 oldmap = 0;
static boolean oldencore = false;
static boolean skipmusic = false;
boolean skipintromus = false;
static const char *musicexception_list[16] = {
"vote", "voteea", "voteeb", "racent", "krwin",
"krok", "krlose", "krfail", "kbwin", "kbok",
"kblose", "kstart", "estart", "wait2j", "CHRSHP",
"CHRSHF"
};
//checks for any kind of event music like intermission, vote etc.
//always runs when musicchange gets invoked
static void S_CheckEventMus(const char *newmus)
{
skipmusic = false;
if (!cv_keepmusic.value)
return;
for (int i = 0; i < 16; i++)
if (stricmp(music_name, musicexception_list[i]) == 0 || stricmp(newmus, musicexception_list[i]) == 0) // weird? sure! but were lucky enough newmus reflects whats being replaced
{
skipmusic = true;
break;
}
//CONS_Printf("musname = %s\n", music_name);
//CONS_Printf("newmus = %s\n", newmus);
//CONS_Printf("newmus = %d\n", skipmusic);
}
//this one compares map and encoremode instead of the music itself
//makes tunes work and stuff
void S_CheckMap(void)
{
if (!cv_keepmusic.value)
{
keepmusic = false;
return;
}
keepmusic = (!skipmusic && gamestate == GS_LEVEL && oldmap == gamemap && oldencore == encoremode);
oldencore = encoremode;
oldmap = gamemap;
}
//
// Per level startup code.
// Kills playing sounds at start of level,
// determines music if any, changes music.
//
void S_Start(void)
void S_InitMapMusic(void)
{
if (!cv_skipintromusic.value)
skipintromus = false;
else
{
char *maptitle = G_BuildMapTitle(gamemap);
skipintromus = cv_skipintromusic.value && stricmp(maptitle, "Wandering Falls") != 0; // thanks diggle!
if (maptitle)
Z_Free(maptitle);
}
if (mapmusflags & MUSIC_RELOADRESET)
{
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
@@ -2187,13 +2261,48 @@ void S_Start(void)
mapmusresume = 0;
}
//if (cv_resetmusic.value) // Starting ambience should always be restarted
S_StopMusic();
if (keepmusic)
return;
if (leveltime < (starttime + (TICRATE/2))) // SRB2Kart
S_ChangeMusicEx((encoremode ? "estart" : "kstart"), 0, false, mapmusposition, 0, 0);
else
// Starting ambience should always be restarted
// lug: but not when we keep the map music lol
S_StopMusic();
if (skipintromus)
return;
if (leveltime < MUSICSTARTTIME) // SRB2Kart
S_ChangeMusicInternal((encoremode ? "estart" : "kstart"), false); //S_StopMusic();
//S_ChangeMusicEx((encoremode ? "estart" : "kstart"), 0, false, mapmusposition, 0, 0);
}
void S_StartMapMusic(boolean restore)
{
//no need to constantly run this after race has started
if (leveltime > MUSICSTARTTIME)
return;
if (keepmusic && !restore) // make sure this doesent kill the music when its called from P_RestoreMusic in some cases
return;
if (skipintromus)
{
if (leveltime < starttime)
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
if (leveltime == MUSICSTARTTIME)
S_ShowMusicCredit();
return;
}
if (leveltime < starttime) // SRB2Kart
S_ChangeMusicInternal((encoremode ? "estart" : "kstart"), false); // yes this will be spammed otherwise encore and some stuff WILL overwrite it
else if (leveltime == starttime) // The GO! sound stops the level start ambience
S_StopMusic();
else if (leveltime == MUSICSTARTTIME) // Plays the music after the starting countdown.
{
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
S_ShowMusicCredit();
}
}
void S_RestartMusic(void)
@@ -2388,7 +2497,7 @@ static void GameDigiMusic_OnChange(void)
digital_disabled = false;
I_StartupSound(); // will return early if initialised
I_InitMusic();
if (Playing())
P_RestoreMusic(&players[consoleplayer]);
else
@@ -2425,14 +2534,12 @@ static void ModFilter_OnChange(void)
{
if (openmpt_mhandle)
openmpt_module_set_render_param(openmpt_mhandle, OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH, cv_modfilter.value);
}
static void StereoSep_OnChange(void)
{
if (openmpt_mhandle)
openmpt_module_set_render_param(openmpt_mhandle, OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT, cv_stereosep.value);
}
static void AmigaFilter_OnChange(void)
+13 -2
View File
@@ -32,7 +32,6 @@ extern consvar_t stereoreverse;
extern consvar_t cv_soundvolume, cv_digmusicvolume;//, cv_midimusicvolume;
extern consvar_t cv_numChannels;
extern consvar_t surround;
extern consvar_t cv_audbuffersize;
//extern consvar_t cv_resetmusic;
extern consvar_t cv_gamedigimusic;
@@ -55,6 +54,7 @@ extern consvar_t cv_amigatype;
//bird music stuff
extern consvar_t cv_music_resync_threshold;
extern consvar_t cv_music_resync_powerups_only;
extern consvar_t cv_invincmusicfade;
extern consvar_t cv_growmusicfade;
@@ -68,6 +68,13 @@ extern consvar_t cv_resume;
extern consvar_t cv_fading;
extern consvar_t cv_birdmusic;
extern consvar_t cv_keepmusic;
extern consvar_t cv_skipintromusic;
//extern consvar_t cv_ignoremusicchanges;
extern boolean keepmusic;
extern boolean skipintromus;
#define MUSICSTARTTIME (starttime + (TICRATE/2))
extern consvar_t precachesound;
typedef enum
@@ -101,7 +108,11 @@ void S_InitSfxChannels(INT32 sfxVolume);
//
void S_StopSounds(void);
void S_ClearSfx(void);
void S_Start(void);
void S_InitMapMusic(void);
void S_StartMapMusic(boolean restore);
void S_CheckMap(void);
// Stops music and restarts it from same position. Used for instant applying changes to amiga filters.
void S_RestartMusic(void);
+33 -20
View File
@@ -82,7 +82,8 @@ static void SCR_ChangeFullscreen (void);
consvar_t cv_fullscreen = {"fullscreen", "Yes", CV_SAVE|CV_CALL, CV_YesNo, SCR_ChangeFullscreen, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_accuratefps = {"accuratefpscounter", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t accuratefps_cons_t[] = {{0, "Inaccurate"}, {1, "Accurate"}, {0, NULL}};
consvar_t cv_accuratefps = {"fpssampling", "1", CV_SAVE, accuratefps_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// =========================================================================
// SCREEN VARIABLES
@@ -354,11 +355,7 @@ void SCR_ChangeFullscreen(void)
boolean SCR_IsAspectCorrect(INT32 width, INT32 height)
{
return
( width % BASEVIDWIDTH == 0
&& height % BASEVIDHEIGHT == 0
&& width / BASEVIDWIDTH == height / BASEVIDHEIGHT
);
return (width % BASEVIDWIDTH == 0 && height % BASEVIDHEIGHT == 0 && width / BASEVIDWIDTH == height / BASEVIDHEIGHT);
}
double averageFPS = 0.0f;
@@ -366,15 +363,13 @@ double averageFPS = 0.0f;
#define USE_FPS_SAMPLES
#ifdef USE_FPS_SAMPLES
#define MAX_FRAME_TIME 0.05
#define MAX_FRAME_TIME (0.05)
#define NUM_FPS_SAMPLES (16) // Number of samples to store
#define NUM_FPS_SAMPLES2 (32) // Number of samples to store for inaccurate counter
static double total_frame_time = 0.0;
static int frame_index;
static double fps_samples[NUM_FPS_SAMPLES2];
static int fps_index;
static double fps_samples[NUM_FPS_SAMPLES];
#endif
static boolean fps_init = false;
@@ -383,7 +378,6 @@ static precise_t fps_enter = 0;
void SCR_CalculateFPS(void)
{
precise_t fps_finish = 0;
int i;
double frameElapsed = 0.0;
@@ -398,10 +392,10 @@ void SCR_CalculateFPS(void)
fps_enter = fps_finish;
#ifdef USE_FPS_SAMPLES
total_frame_time += frameElapsed;
if (cv_accuratefps.value)
{
total_frame_time += frameElapsed;
if (frame_index++ >= NUM_FPS_SAMPLES || total_frame_time >= MAX_FRAME_TIME)
{
averageFPS = 1.0 / (total_frame_time / frame_index);
@@ -411,13 +405,32 @@ void SCR_CalculateFPS(void)
}
else
{
fps_samples[fps_index] = frameElapsed / NUM_FPS_SAMPLES2;
fps_index = (fps_index + 1) % NUM_FPS_SAMPLES2;
if (total_frame_time >= MAX_FRAME_TIME)
{
static int sampleIndex = 0;
averageFPS = 0.0;
for (i = 0; i < NUM_FPS_SAMPLES2; i++)
averageFPS += fps_samples[i];
averageFPS = 1.0 / averageFPS;
fps_samples[sampleIndex] = frameElapsed;
sampleIndex++;
if (sampleIndex >= NUM_FPS_SAMPLES)
sampleIndex = 0;
averageFPS = 0.0;
for (int i = 0; i < NUM_FPS_SAMPLES; i++)
{
averageFPS += fps_samples[i];
}
if (averageFPS > 0.0)
{
averageFPS = 1.0 / (averageFPS / NUM_FPS_SAMPLES);
}
}
while (total_frame_time >= MAX_FRAME_TIME)
{
total_frame_time -= MAX_FRAME_TIME;
}
}
#else
// Direct, unsampled counter.
@@ -441,7 +454,7 @@ void SCR_DisplayTicRate(void)
return;
// new kart counter
if ((cv_ticrate.value == 1) || (cv_ticrate.value == 2))
if (cv_ticrate.value == 1 || cv_ticrate.value == 2)
{
// draw "FPS"
if (cv_ticrate.value == 1)
@@ -475,7 +488,7 @@ void SCR_DisplayTicRate(void)
// draw our actual framerate
V_DrawPingNum(x, 190, fpsflags, fps, ticcntcolor);
}
else if ((cv_ticrate.value == 3)||(cv_ticrate.value == 4)) // kart v1.0/srb2 counter
else if (cv_ticrate.value == 3 || cv_ticrate.value == 4) // kart v1.0/srb2 counter
{
if (fps > (benchmark - 5))
ticcntcolor2 = V_GREENMAP;
+3 -3
View File
@@ -39,12 +39,12 @@
// we try to re-allocate a minimum of buffers for stability of the memory,
// so all the small-enough tables based on screen size, are allocated once
// and for all at the maximum size.
#define MAXVIDWIDTH 2560 // don't set this too high because actually
#define MAXVIDHEIGHT 1440 // lots of tables are allocated with the MAX size.
#define MAXVIDWIDTH 5120 // don't set this too high because actually
#define MAXVIDHEIGHT 2880 // lots of tables are allocated with the MAX size.
#define BASEVIDWIDTH 320 // NEVER CHANGE THIS! This is the original
#define BASEVIDHEIGHT 200 // resolution of the graphics.
// max res for png capture; seperated it so both MAXVID values can be lower for software performance reasons; OpenGL does not care about those anyways
// max res for png capture; just here to prevent some crashes on very high resoltions; tho you should never go this high cause ogl allocs certain things with MAXVIDWIDTH and MAXVIDHEIGHT too Zzz...
#define MAXPNGWIDTH 7680
#define MAXPNGHEIGHT 4320
+93 -92
View File
@@ -47,11 +47,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
// May be incorrect for other platforms, but we don't currently have a way to
// query the scheduler granularity. SDL will do what's needed to make this as
// low as possible though.
#if defined(_WIN32)
#define MIN_SLEEP_DURATION_MS 1.6
#else
#define MIN_SLEEP_DURATION_MS 2.1
#endif
#include <stdio.h>
#include <time.h>
@@ -115,6 +111,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#endif
#if defined (__unix__) || (defined (UNIXCOMMON) && !defined (__APPLE__))
#include <poll.h>
#include <errno.h>
#include <sys/wait.h>
#define NEWSIGNALHANDLER
@@ -548,10 +545,9 @@ typedef struct
feild_t tty_con;
// when printing general stuff to stdout stderr (Sys_Printf)
// we need to disable the tty console stuff
// this increments so we can recursively disable
static INT32 ttycon_hide = 0;
// lock to prevent clearing partial lines, since not everything
// printed ends on a newline.
static boolean ttycon_ateol = true;
// some key codes that the terminal may be using
// TTimo NOTE: I'm not sure how relevant this is
static INT32 tty_erase;
@@ -579,63 +575,31 @@ static inline void tty_FlushIn(void)
// TTimo NOTE: it seems on some terminals just sending '\b' is not enough
// so for now, in any case we send "\b \b" .. yeah well ..
// (there may be a way to find out if '\b' alone would work though)
// Hanicef NOTE: using \b this way is unreliable because of terminal state,
// it's better to use \r to reset the cursor to the beginning of the
// line and clear from there.
static void tty_Back(void)
{
char key;
ssize_t d;
key = '\b';
d = write(STDOUT_FILENO, &key, 1);
key = ' ';
d = write(STDOUT_FILENO, &key, 1);
key = '\b';
d = write(STDOUT_FILENO, &key, 1);
(void)d;
write(STDOUT_FILENO, "\r", 1);
if (tty_con.cursor>0)
{
write(STDOUT_FILENO, tty_con.buffer, tty_con.cursor);
}
write(STDOUT_FILENO, " \b", 2);
}
static void tty_Clear(void)
{
size_t i;
write(STDOUT_FILENO, "\r", 1);
if (tty_con.cursor>0)
{
for (i=0; i<tty_con.cursor; i++)
{
tty_Back();
write(STDOUT_FILENO, " ", 1);
}
write(STDOUT_FILENO, "\r", 1);
}
}
// clear the display of the line currently edited
// bring cursor back to beginning of line
static inline void tty_Hide(void)
{
//I_Assert(consolevent);
if (ttycon_hide)
{
ttycon_hide++;
return;
}
tty_Clear();
ttycon_hide++;
}
// show the current line
// FIXME TTimo need to position the cursor if needed??
static inline void tty_Show(void)
{
size_t i;
ssize_t d;
//I_Assert(consolevent);
I_Assert(ttycon_hide>0);
ttycon_hide--;
if (ttycon_hide == 0 && tty_con.cursor)
{
for (i=0; i<tty_con.cursor; i++)
{
d = write(STDOUT_FILENO, tty_con.buffer+i, 1);
}
}
(void)d;
}
// never exit without calling this, or your terminal will be left in a pretty bad state
@@ -702,50 +666,65 @@ void I_GetConsoleEvents(void)
// we use this when sending back commands
event_t ev = {0,0,0,0};
char key = 0;
ssize_t d;
struct pollfd pfd =
{
.fd = STDIN_FILENO,
.events = POLLIN,
.revents = 0,
};
if (!consolevent)
return;
ev.type = ev_console;
ev.data1 = 0;
if (read(STDIN_FILENO, &key, 1) == -1 || !key)
return;
for (;;)
{
if (poll(&pfd, 1, 0) < 1 || !(pfd.revents & POLLIN))
return;
// we have something
// backspace?
// NOTE TTimo testing a lot of values .. seems it's the only way to get it to work everywhere
if ((key == tty_erase) || (key == 127) || (key == 8))
{
if (tty_con.cursor > 0)
ev.type = ev_console;
ev.data1 = 0;
if (read(STDIN_FILENO, &key, 1) == -1 || !key)
return;
// we have something
// backspace?
// NOTE TTimo testing a lot of values .. seems it's the only way to get it to work everywhere
if ((key == tty_erase) || (key == 127) || (key == 8))
{
tty_con.cursor--;
tty_con.buffer[tty_con.cursor] = '\0';
tty_Back();
if (tty_con.cursor > 0)
{
tty_con.cursor--;
tty_con.buffer[tty_con.cursor] = '\0';
tty_Back();
}
ev.data1 = KEY_BACKSPACE;
}
ev.data1 = KEY_BACKSPACE;
}
else if (key < ' ') // check if this is a control char
{
if (key == '\n')
else if (key < ' ') // check if this is a control char
{
tty_Clear();
tty_con.cursor = 0;
ev.data1 = KEY_ENTER;
if (key == '\n')
{
tty_Clear();
tty_con.cursor = 0;
ev.data1 = KEY_ENTER;
}
else if (key == 0x4) // ^D, aka EOF
{
// shut down, most unix programs behave this way
I_Quit();
}
else continue;
}
else return;
else if (tty_con.cursor < sizeof(tty_con.buffer))
{
// push regular character
ev.data1 = tty_con.buffer[tty_con.cursor] = key;
tty_con.cursor++;
// print the current line (this is differential)
write(STDOUT_FILENO, &key, 1);
}
if (ev.data1) D_PostEvent(&ev);
//tty_FlushIn();
}
else if (tty_con.cursor < sizeof (tty_con.buffer))
{
// push regular character
ev.data1 = tty_con.buffer[tty_con.cursor] = key;
tty_con.cursor++;
// print the current line (this is differential)
d = write(STDOUT_FILENO, &key, 1);
}
if (ev.data1) D_PostEvent(&ev);
//tty_FlushIn();
(void)d;
}
#elif defined (_WIN32)
@@ -941,9 +920,16 @@ static void I_RegisterChildSignals(void)
void I_OutputMsg(const char *fmt, ...)
{
size_t len;
char txt[8192];
char *txt;
va_list argptr;
va_start(argptr,fmt);
len = vsnprintf(NULL, 0, fmt, argptr);
va_end(argptr);
if (len == 0)
return;
txt = malloc(len+1);
va_start(argptr,fmt);
vsprintf(txt, fmt, argptr);
va_end(argptr);
@@ -977,7 +963,10 @@ void I_OutputMsg(const char *fmt, ...)
DWORD bytesWritten;
if (co == INVALID_HANDLE_VALUE)
{
free(txt);
return;
}
if (GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &bytesWritten))
{
@@ -993,11 +982,16 @@ void I_OutputMsg(const char *fmt, ...)
if (oldLength > 0)
{
LPVOID blank = malloc(oldLength);
if (!blank) return;
if (!blank)
{
free(txt);
return;
}
memset(blank, ' ', oldLength); // Blank out.
oldLines = malloc(oldLength*sizeof(TCHAR));
if (!oldLines)
{
free(txt);
free(blank);
return;
}
@@ -1032,18 +1026,20 @@ void I_OutputMsg(const char *fmt, ...)
}
#else
#ifdef HAVE_TERMIOS
if (consolevent)
if (consolevent && ttycon_ateol)
{
tty_Hide();
tty_Clear();
ttycon_ateol = false;
}
#endif
if (!framebuffer)
fprintf(stderr, "%s", txt);
#ifdef HAVE_TERMIOS
if (consolevent)
if (consolevent && txt[len-1] == '\n')
{
tty_Show();
write(STDOUT_FILENO, tty_con.buffer, tty_con.cursor);
ttycon_ateol = true;
}
#endif
@@ -1052,6 +1048,7 @@ void I_OutputMsg(const char *fmt, ...)
fflush(stderr);
#endif
free(txt);
}
//
@@ -2672,6 +2669,7 @@ void I_GamepadRumble(INT32 device_id, UINT16 low_strength, UINT16 high_strength,
(void)device_id;
(void)low_strength;
(void)high_strength;
(void)duration;
#else
I_Assert(device_id > 0); // Gamepad devices are always ID 1 or higher
@@ -2689,6 +2687,9 @@ void I_SetGamepadIndicatorColor(INT32 device_id, UINT8 red, UINT8 green, UINT8 b
{
#if !(SDL_VERSION_ATLEAST(2,0,14))
(void)device_id;
(void)red;
(void)green;
(void)blue;
#else
I_Assert(device_id > 0); // Gamepad devices are always ID 1 or higher
+6 -3
View File
@@ -758,7 +758,7 @@ static INT32 SDLJoyAxis(const Sint16 axis, evtype_t which)
#ifdef USE_FBO_OGL
void I_DownSample(void)
{
if (!cv_grframebuffer.value || !supportFBO) //no sense to do this crap if we cant benefit from it
if (!cv_glframebuffer.value || !supportFBO) //no sense to do this crap if we cant benefit from it
{
downsample = false;
return;
@@ -781,8 +781,11 @@ void I_DownSample(void)
}
else
{
downsample = false; // its not so no need to do crap
RefreshOGLSDLSurface();
if (downsample == true)
{
downsample = false; // its not so no need to do crap
RefreshOGLSDLSurface();
}
}
}
+7 -7
View File
@@ -93,6 +93,7 @@ static UINT16 SAMPLERATE = 44100;
/// ------------------------
UINT8 sound_started = false;
static UINT32 stutter_threshold;
static Mix_Music *music;
@@ -592,6 +593,9 @@ Countstutter (int len)
{
UINT32 bytes;
if (!cv_birdmusic.value || gamestate != GS_LEVEL)
return;
if (hu_stopped)
{
music_stutter_bytes += len;
@@ -627,8 +631,7 @@ static void count_music_bytes(int chan, void *stream, int len, void *udata)
music_bytes += len;
if (cv_birdmusic.value && gamestate == GS_LEVEL)
Countstutter(len);
Countstutter(len);
}
static void music_loop(void)
@@ -1041,12 +1044,9 @@ UINT32 I_GetSongPosition(void)
// 8M: 1 | 8S: 2 | 16M: 2 | 16S: 4
}
void I_UpdateSongLagThreshold (void)
void I_UpdateSongLagThreshold(void)
{
if (!cv_birdmusic.value)
return;
stutter_threshold = cv_music_resync_threshold.value/1000.0*(4*44100);
stutter_threshold = cv_music_resync_powerups_only.value ? 0 : (cv_music_resync_threshold.value/1000.0*(4*44100));
}
/// ------------------------
+26 -19
View File
@@ -68,10 +68,19 @@ PFNglGetIntegerv pglGetIntegerv;
PFNglGetString pglGetString;
#endif
#if defined (__unix__)
#ifdef USE_FBO_OGL
#if defined (__unix__)
static boolean isnvidiagpu = false;
#endif
boolean UseScreenFBO(void)
{
return ((supportFBO && cv_glframebuffer.value && downsample)
#if defined (__unix__)
|| (supportFBO && isnvidiagpu && xwaylandcrap)
#endif
);
}
#endif
/** \brief SDL video display surface
@@ -112,10 +121,11 @@ boolean LoadGL(void)
\return if true, changed video mode
*/
static boolean first_init = false;
boolean OglSdlSurface(INT32 w, INT32 h)
{
INT32 cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value;
static boolean first_init = false;
const char *gllogdir = NULL;
oglflags = 0;
@@ -171,7 +181,7 @@ boolean OglSdlSurface(INT32 w, INT32 h)
else
maximumAnisotropy = 1;
granisotropicmode_cons_t[1].value = maximumAnisotropy;
glanisotropicmode_cons_t[1].value = maximumAnisotropy;
#if defined (__unix__)
#ifdef USE_FBO_OGL
@@ -180,7 +190,6 @@ boolean OglSdlSurface(INT32 w, INT32 h)
#endif
#endif
}
first_init = true;
SDL_GL_SetSwapInterval(cv_vidwait.value ? 1 : 0);
@@ -202,21 +211,25 @@ boolean OglSdlSurface(INT32 w, INT32 h)
pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
#ifdef USE_FBO_OGL
RenderToFramebuffer = ((FrameBufferEnabled && supportFBO && downsample)
#if defined (__unix__)
|| (isnvidiagpu && xwaylandcrap)
#endif
);
if (RenderToFramebuffer)
if (!supportFBO)
{
if (cv_glframebuffer.value)
CV_SetValue(&cv_glframebuffer, 0);
}
if (UseScreenFBO())
GLFramebuffer_Enable();
else
GLFramebuffer_Disable();
#endif
HWR_Startup();
if (!first_init)
HWR_Startup();
textureformatGL = cbpp > 16 ? GL_RGBA : GL_RGB5_A1;
first_init = true;
return true;
}
@@ -241,20 +254,14 @@ void OglSdlFinishUpdate(boolean waitvbl)
HWR_MakeScreenFinalTexture();
#ifdef USE_FBO_OGL
RenderToFramebuffer = ((FrameBufferEnabled && supportFBO && downsample)
#if defined (__unix__)
|| (isnvidiagpu && xwaylandcrap)
#endif
);
if (RenderToFramebuffer)
if (UseScreenFBO())
GLFramebuffer_Unbind();
#endif
HWR_DrawScreenFinalTexture(sdlw, sdlh);
#ifdef USE_FBO_OGL
if (RenderToFramebuffer)
if (UseScreenFBO())
GLFramebuffer_Enable();
#endif
+110 -20
View File
@@ -15,6 +15,7 @@
#include "doomdef.h"
#include "g_game.h"
#include "g_input.h"
#include "r_local.h"
#include "p_local.h"
#include "f_finale.h"
@@ -155,6 +156,8 @@ static patch_t *envelope;
player_t *stplyr;
UINT8 stplyrnum;
boolean directortextactive = false;
// SRB2kart
hudinfo_t hudinfo[NUMHUDITEMS] =
@@ -662,23 +665,30 @@ static void ST_overlayDrawer(void)
if (!hu_showscores) // hide the following if TAB is held
{
if (cv_showdirectorhud.value && ((demo.playback && (!demo.title || !modeattacking)) || !P_IsLocalPlayer(stplyr)) && !splitscreen)
if (cv_showdirectorhud.value && !splitscreen && ((demo.playback && !demo.freecam && (!demo.title || !modeattacking)) || !P_IsLocalPlayer(stplyr)) && !K_DirectorIsPlayerAlone())
{
char directortext[20] = {0};
snprintf(directortext, 20, "Director: %s", cv_director.value ? "On" : "Off");
if (directortoggletimer < 4*TICRATE)
directortextactive = true;
if ((!demo.playback && directortoggletimer < 13*TICRATE) || (demo.playback && directortoggletimer < 4*TICRATE))
{
V_DrawString(1, BASEVIDHEIGHT-8-1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANSHALF|V_ALLOWLOWERCASE, directortext);
if (renderisnewtic)
directortoggletimer++;
if (directortoggletimer < 4*TICRATE)
V_DrawString(1, BASEVIDHEIGHT-8-1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANSHALF|V_ALLOWLOWERCASE, directortext);
else if (cv_translucenthud.value != 0)
V_DrawString(1, BASEVIDHEIGHT-8-1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_80TRANS|V_ALLOWLOWERCASE, directortext); // idk if V_80TRANS is good?
}
else if (cv_translucenthud.value != 0)
V_DrawString(1, BASEVIDHEIGHT-8-1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_80TRANS|V_ALLOWLOWERCASE, directortext); // idk if V_80TRANS is good?
}
else
{
directortoggletimer = 0;
directortextactive = false;
}
if (cv_showviewpointtext.value)
{
@@ -695,7 +705,7 @@ static void ST_overlayDrawer(void)
V_DrawCenteredString((BASEVIDWIDTH/2), BASEVIDHEIGHT-32, V_SNAPTOBOTTOM|V_HUDTRANS|V_ALLOWLOWERCASE, player_names[stplyr-players]);
}
}
else if (!demo.title)
else if (!demo.title && !demo.freecam)
{
if (!splitscreen)
{
@@ -764,10 +774,33 @@ static void ST_overlayDrawer(void)
}
else
{
V_DrawString(2, BASEVIDHEIGHT-40, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF|V_YELLOWMAP, M_GetText("- SPECTATING -"));
V_DrawString(2, BASEVIDHEIGHT-30, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, itemtxt);
V_DrawString(2, BASEVIDHEIGHT-20, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, M_GetText("Accelerate - Float"));
V_DrawString(2, BASEVIDHEIGHT-10, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, M_GetText("Brake - Sink"));
if (cv_showdirectorhud.value)
{
V_DrawString(2, BASEVIDHEIGHT-50, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF|V_YELLOWMAP, M_GetText("- SPECTATING -"));
V_DrawString(2, BASEVIDHEIGHT-40, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, itemtxt);
V_DrawString(2, BASEVIDHEIGHT-30, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, M_GetText("Accelerate - Float"));
V_DrawString(2, BASEVIDHEIGHT-20, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, M_GetText("Brake - Sink"));
char directortoggle[32] = {0};
const char *item1 = gamecontrol[gc_director][0] != 0 ? G_KeynumToString(gamecontrol[gc_director][0]) : NULL;
const char *item2 = gamecontrol[gc_director][1] != 0 ? G_KeynumToString(gamecontrol[gc_director][1]) : NULL;
if (item1 != NULL && item2 != NULL)
snprintf(directortoggle, 32, "%s/%s - Toggle Director", item1, item2);
else
snprintf(directortoggle, 32, "%s - Toggle Director", item1 != NULL ? item1 : item2 != NULL ? item2 : "Not Bound");
V_DrawString(2, BASEVIDHEIGHT-10, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, directortoggle);
directortextactive = true;
}
else
{
V_DrawString(2, BASEVIDHEIGHT-40, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF|V_YELLOWMAP, M_GetText("- SPECTATING -"));
V_DrawString(2, BASEVIDHEIGHT-30, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, itemtxt);
V_DrawString(2, BASEVIDHEIGHT-20, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, M_GetText("Accelerate - Float"));
V_DrawString(2, BASEVIDHEIGHT-10, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, M_GetText("Brake - Sink"));
}
}
}
}
@@ -799,25 +832,82 @@ static void ST_overlayDrawer(void)
}
}
void ST_DrawDemoTitleEntry(void)
static void ST_DrawTextInput(INT32 x, INT32 y, textinput_t *input, INT32 flags)
{
static UINT8 skullAnimCounter = 0;
char *nametodraw;
static const INT32 MAXINPUTWIDTH = (MAXSTRINGLENGTH-1)*8;
skullAnimCounter++;
if (renderisnewtic)
skullAnimCounter++;
skullAnimCounter %= 8;
nametodraw = demo.titlename;
while (V_StringWidth(nametodraw, 0) > MAXSTRINGLENGTH*8 - 8)
nametodraw++;
char nametodraw[MAXSTRINGLENGTH*2+1] = {0};
size_t drawstart = 0;
size_t drawend = 0; // Only used for selection
INT32 skullx = x;
while (V_SubStringWidth(input->buffer+drawstart, input->cursor-drawstart, V_ALLOWLOWERCASE) > MAXINPUTWIDTH)
++drawstart;
size_t drawlength = V_SubStringLengthToFit(input->buffer+drawstart, MAXINPUTWIDTH+8, V_ALLOWLOWERCASE)+1;
drawend = drawstart + drawlength;
memcpy(nametodraw, input->buffer+drawstart, drawlength);
if (input->length)
skullx += V_SubStringWidth(nametodraw, input->cursor-drawstart, V_ALLOWLOWERCASE);
V_DrawString(x, y, V_ALLOWLOWERCASE|flags, nametodraw);
// draw text cursor for name
if (skullAnimCounter < 4) // blink cursor
V_DrawCharacter(skullx, y+3, '_'|flags, false);
// draw selection
if (input->select != input->cursor)
{
size_t start = min(input->select, input->cursor);
size_t end = max(input->select, input->cursor);
INT32 startx = 0;
INT32 width = 0;
// I couldn't figure out one formula so here's bunch of separate cases
if (start < drawstart && end > drawend) // Selection covers whole visible portion of demo name
{
startx = -2;
width = V_StringWidth(nametodraw, V_ALLOWLOWERCASE)+4;
}
else if (start < drawstart) // Only left side of selection is off visible part
{
startx = -2;
size_t len = (end - start) - (drawstart - start);
width = V_SubStringWidth(nametodraw, len, V_ALLOWLOWERCASE)+2;
}
else if (end > drawend) // Only right side of selection is off visible part
{
startx = V_SubStringWidth(nametodraw, start-drawstart, V_ALLOWLOWERCASE);
width = V_StringWidth(nametodraw+(start-drawstart), V_ALLOWLOWERCASE)+2;
}
else // All selection is on visible part
{
startx = V_SubStringWidth(nametodraw, start-drawstart, V_ALLOWLOWERCASE);
width = V_SubStringWidth(nametodraw+(start-drawstart), end-start, V_ALLOWLOWERCASE);
}
V_DrawFill(x+startx, y, width, 8, 103|V_TRANSLUCENT|flags);
}
}
void ST_DrawDemoTitleEntry(void)
{
#define x (BASEVIDWIDTH/2 - 139)
#define y (BASEVIDHEIGHT/2)
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, nametodraw);
if (skullAnimCounter < 4)
V_DrawCharacter(x + 8 + V_StringWidth(nametodraw, 0), y + 12,
'_' | 0x80, false);
ST_DrawTextInput(x + 8, y + 12, &demo.titlenameinput, 0);
M_DrawTextBox(x + 30, y - 24, 26, 1);
V_DrawString(x + 38, y - 16, V_ALLOWLOWERCASE, "Enter the name of the replay.");
+2
View File
@@ -146,4 +146,6 @@ extern UINT16 objectsdrawn;
extern consvar_t cv_lessflicker;
extern consvar_t cv_stagetitle;
extern boolean directortextactive;
#endif
Loaded 100 of 105 files, more files were not shown because too many files have changed in this diff. Show more